1use crate::{ScenarioParsingError, lambda::RootedLambdaPool};
2use chumsky::{prelude::*, text::inline_whitespace};
3use itertools::{Itertools, MultiProduct};
4use serde::{Deserialize, Serialize};
5use std::{collections::BTreeMap, fmt::Display};
6
7use crate::{Actor, Entity, Event, PropertyLabel, Scenario, ScenarioDataset, ThetaRoles};
8
9impl Display for Scenario<'_> {
10 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11 write!(f, "<")?;
12 let mut first = true;
13 for actor in &self.actors {
14 if !first {
15 write!(f, ", ")?;
16 }
17
18 write!(f, "{actor}")?;
19 let mut first_property = true;
20 for (property, prop_actors) in &self.properties {
21 if prop_actors.contains(&Entity::Actor(actor)) {
22 if first_property {
23 first_property = false;
24 write!(f, " (")?;
25 } else {
26 write!(f, ", ")?;
27 }
28 write!(f, "{property}")?;
29 }
30 }
31 if !first_property {
32 write!(f, ")")?;
33 }
34
35 first = false;
36 }
37 if self.thematic_relations.is_empty() {
38 return write!(f, ">");
39 }
40
41 write!(f, ";")?;
42 let mut first = true;
43
44 for (i, e) in self.thematic_relations.iter().enumerate() {
45 if first {
46 write!(f, " ")?;
47 } else {
48 write!(f, ", ")?;
49 }
50 first = false;
51
52 write!(f, "{{")?;
53
54 if let Some(a) = e.agent {
55 write!(f, "A: {a}")?;
56 if e.patient.is_some() {
57 write!(f, ", ")?;
58 }
59 }
60
61 if let Some(p) = e.patient {
62 write!(f, "P: {p}")?;
63 }
64
65 let mut first_property = true;
66 for (property, prop_actors) in &self.properties {
67 if prop_actors.contains(&Entity::Event(u8::try_from(i).unwrap())) {
68 if first_property {
69 first_property = false;
70 if e.agent.is_some() || e.patient.is_some() {
71 write!(f, " (")?;
72 } else {
73 write!(f, "(")?;
74 }
75 } else {
76 write!(f, ", ")?;
77 }
78 write!(f, "{property}")?;
79 }
80 }
81 if !first_property {
82 write!(f, ")")?;
83 }
84
85 write!(f, "}}")?;
86 }
87
88 write!(f, ">")?;
89
90 let mut first = true;
91 for q in self.questions() {
92 if first {
93 write!(f, " {q}")?;
94 } else {
95 write!(f, "; {q}")?;
96 }
97 first = false;
98 }
99 Ok(())
100 }
101}
102
103impl<'a> Scenario<'a> {
104 pub fn parse(s: &'a str) -> Result<Self, ScenarioParsingError> {
115 Ok(scenario_parser()
116 .padded()
117 .then_ignore(end())
118 .parse(s)
119 .into_result()?)
120 }
121}
122
123pub fn theta_role_parser<'a>()
124-> impl Parser<'a, &'a str, ThetaRoles<'a>, extra::Err<Rich<'a, char>>> + Copy {
125 let theta_role = |c: char| {
126 just(c)
127 .padded()
128 .ignore_then(just(':'))
129 .ignore_then(text::ident().padded())
130 .padded()
131 };
132
133 choice((
134 theta_role('A')
135 .then_ignore(just(','))
136 .then(theta_role('P'))
137 .map(|(a, p)| ThetaRoles {
138 agent: Some(a),
139 patient: Some(p),
140 }),
141 theta_role('P')
142 .then_ignore(just(','))
143 .then(theta_role('A'))
144 .map(|(p, a)| ThetaRoles {
145 agent: Some(a),
146 patient: Some(p),
147 }),
148 theta_role('P').map(|n| ThetaRoles {
149 agent: None,
150 patient: Some(n),
151 }),
152 theta_role('A').map(|n| ThetaRoles {
153 agent: Some(n),
154 patient: None,
155 }),
156 empty().map(|()| ThetaRoles {
157 agent: None,
158 patient: None,
159 }),
160 ))
161}
162
163pub fn scenario_parser<'a>() -> impl Parser<'a, &'a str, Scenario<'a>, extra::Err<Rich<'a, char>>> {
164 let properties = text::ident()
165 .padded()
166 .separated_by(just(','))
167 .collect::<Vec<&str>>()
168 .delimited_by(just('('), just(')'))
169 .padded();
170
171 let actor = text::ident().padded().then(properties.or_not());
172
173 let actors = actor
174 .map(|(a, p)| {
175 let mut properties: BTreeMap<&str, Vec<_>> = BTreeMap::default();
176 if let Some(property_labels) = p {
177 for property in property_labels {
178 properties.insert(property, vec![a]);
179 }
180 }
181 (vec![a], properties)
182 })
183 .foldl(
184 just(',').ignore_then(actor).repeated(),
185 |(mut actors, mut properties), (actor, actor_props)| {
186 if let Some(property_labels) = actor_props {
187 for property in property_labels {
188 properties
189 .entry(property)
190 .and_modify(|x| x.push(actor))
191 .or_insert(vec![actor]);
192 }
193 }
194
195 actors.push(actor);
196 (actors, properties)
197 },
198 );
199
200 let event = theta_role_parser()
201 .then(properties.or_not())
202 .delimited_by(just('{'), just('}'))
203 .padded();
204
205 let events = event
206 .or_not()
207 .map(|event_data| {
208 let mut properties: BTreeMap<&str, Vec<Entity>> = BTreeMap::default();
209
210 let events = match event_data {
211 Some((e, None)) => {
212 vec![e]
213 }
214 Some((e, Some(p))) => {
215 for property_label in p {
216 properties.insert(property_label, vec![Entity::Event(0)]);
217 }
218
219 vec![e]
220 }
221 None => vec![],
222 };
223
224 (events, properties)
225 })
226 .foldl(
227 just(',').ignore_then(event).repeated().enumerate(),
228 |(mut acc_event, mut acc_props), (i, (event, event_props))| {
229 acc_event.push(event);
230 if let Some(event_props) = event_props {
231 for property_label in event_props {
232 let e = Entity::Event(Event::try_from(i + 1).unwrap());
233 acc_props
234 .entry(property_label)
235 .and_modify(|x| x.push(e))
236 .or_insert_with(|| vec![e]);
237 }
238 }
239 (acc_event, acc_props)
240 },
241 );
242
243 let scenario = actors
244 .then((just(';')).ignore_then(events).or_not())
245 .padded()
246 .delimited_by(just('<'), just('>'))
247 .map(|((actors, actor_props), events)| new_scenario(actors, actor_props, events));
248
249 let scenario = scenario.then(
250 inline_whitespace()
251 .at_least(1)
252 .ignore_then(
253 none_of("\n;")
254 .repeated()
255 .to_slice()
256 .try_map(|x, s| {
257 RootedLambdaPool::parse(x).map_err(|e| Rich::custom(s, e.to_string()))
258 })
259 .separated_by(just(';'))
260 .collect::<Vec<_>>(),
261 )
262 .or_not(),
263 );
264
265 scenario.map(|(mut scenario, questions)| {
266 if let Some(question) = questions {
267 scenario.question = question;
268 }
269 scenario
270 })
271}
272
273pub fn string_scenario_parser<'a>()
274-> impl Parser<'a, &'a str, (Vec<&'a str>, Scenario<'a>), extra::Err<Rich<'a, char>>> {
275 none_of("\"")
276 .repeated()
277 .to_slice()
278 .delimited_by(just('"'), just('"'))
279 .map(|x: &str| x.split(' ').collect::<Vec<_>>())
280 .then_ignore(inline_whitespace().at_least(1))
281 .then(scenario_parser())
282}
283
284pub fn scenario_dataset_parser<'a>()
285-> impl Parser<'a, &'a str, ScenarioDataset<'a>, extra::Err<Rich<'a, char>>> {
286 string_scenario_parser()
287 .separated_by(text::newline().repeated().at_least(1))
289 .at_least(1)
290 .collect::<Vec<_>>()
291 .map(|v| {
292 let mut scenarios = vec![];
293 let mut sentences = vec![];
294 for (a, b) in v {
295 sentences.push(a);
296 scenarios.push(b);
297 }
298 ScenarioDataset::new(scenarios, sentences).unwrap()
299 })
300 .padded()
301 .then_ignore(end())
302}
303
304type EventParseType<'a> = Option<(Vec<ThetaRoles<'a>>, BTreeMap<&'a str, Vec<Entity<'a>>>)>;
305
306fn new_scenario<'a>(
307 actors: Vec<Actor<'a>>,
308 actor_props: BTreeMap<&'a str, Vec<&'a str>>,
309 events: EventParseType<'a>,
310) -> Scenario<'a> {
311 let (events, event_props) = events.unwrap_or_else(|| (Vec::default(), BTreeMap::default()));
312
313 let mut properties: BTreeMap<&str, Vec<Entity>> = actor_props
314 .into_iter()
315 .map(|(k, v)| (k, v.into_iter().map(Entity::Actor).collect()))
316 .collect();
317
318 for (k, mut v) in event_props {
319 properties
320 .entry(k)
321 .and_modify(|value| value.append(&mut v))
322 .or_insert(v);
323 }
324
325 Scenario {
326 question: vec![],
327 actors,
328 thematic_relations: events,
329 properties,
330 }
331}
332
333mod utilities;
334use utilities::SetCounter;
335
336#[derive(Debug, Clone)]
338pub struct ScenarioIterator<'a> {
339 actors: ActorSetGenerator<'a>,
340 current_actors: Vec<Actor<'a>>,
341 current_props: BTreeMap<PropertyLabel<'a>, Vec<Entity<'a>>>,
342 current_event_set: Vec<(ThetaRoles<'a>, PropertyLabel<'a>)>,
343 event_kinds: Vec<PossibleEvent<'a>>,
344 counter: SetCounter,
345 max_number_of_events: Option<usize>,
346}
347
348#[derive(Debug, Clone, Eq, PartialEq, Copy, Ord, PartialOrd, Hash, Serialize, Deserialize)]
350pub enum EventType {
351 Unergative,
353
354 Unaccusative,
356
357 TransitiveNonReflexive,
359
360 Transitive,
362
363 Avalent,
365}
366
367#[derive(Debug, Clone, Eq, PartialEq, Copy, Ord, PartialOrd, Hash, Serialize, Deserialize)]
369pub struct PossibleEvent<'a> {
370 #[serde(borrow)]
372 pub label: PropertyLabel<'a>,
373 pub event_type: EventType,
375}
376
377impl<'a> Scenario<'a> {
378 #[must_use]
385 pub fn all_scenarios(
386 actors: &[Actor<'a>],
387 event_kinds: &[PossibleEvent<'a>],
388 actor_properties: &[PropertyLabel<'a>],
389 max_number_of_events: Option<usize>,
390 max_number_of_actors: Option<usize>,
391 max_number_of_properties: Option<usize>,
392 ) -> ScenarioIterator<'a> {
393 let mut actors = ActorSetGenerator::new(
394 actors,
395 actor_properties,
396 max_number_of_actors,
397 max_number_of_properties,
398 );
399 let (current_actors, current_props) = actors.next().unwrap();
400 let current_event_set = generate_all_events(¤t_actors, event_kinds);
401 let counter = SetCounter::new(current_event_set.len(), max_number_of_events);
402
403 ScenarioIterator {
404 actors,
405 current_actors,
406 current_event_set,
407 current_props,
408 event_kinds: event_kinds.to_vec(),
409 counter,
410 max_number_of_events,
411 }
412 }
413}
414
415impl<'a> Iterator for ScenarioIterator<'a> {
416 type Item = Scenario<'a>;
417
418 fn next(&mut self) -> Option<Self::Item> {
419 if self.counter.done() {
420 if let Some((new_actors, new_props)) = self.actors.next() {
421 self.current_actors = new_actors;
422 self.current_props = new_props;
423 self.current_event_set =
424 generate_all_events(&self.current_actors, &self.event_kinds);
425 self.counter =
426 SetCounter::new(self.current_event_set.len(), self.max_number_of_events);
427 } else {
428 return None;
429 }
430 }
431
432 let mut properties = self.current_props.clone();
433 let mut thematic_relations = vec![];
434 for (i, (theta, label)) in self
435 .counter
436 .as_set(self.current_event_set.iter().copied())
437 .enumerate()
438 {
439 properties
440 .entry(label)
441 .or_default()
442 .push(Entity::Event(Event::try_from(i).expect("Too many events!")));
443 thematic_relations.push(theta);
444 }
445 self.counter.increment();
446 Some(Scenario::new(
447 self.current_actors.clone(),
448 thematic_relations,
449 properties,
450 ))
451 }
452}
453
454fn generate_all_events<'a>(
455 actors: &[Actor<'a>],
456 event_kinds: &[PossibleEvent<'a>],
457) -> Vec<(ThetaRoles<'a>, PropertyLabel<'a>)> {
458 let mut all_events = vec![];
459 for e in event_kinds {
460 match e.event_type {
461 EventType::Unergative => all_events.extend(actors.iter().copied().map(|x| {
462 (
463 ThetaRoles {
464 agent: Some(x),
465 patient: None,
466 },
467 e.label,
468 )
469 })),
470 EventType::Unaccusative => all_events.extend(actors.iter().copied().map(|x| {
471 (
472 ThetaRoles {
473 agent: None,
474 patient: Some(x),
475 },
476 e.label,
477 )
478 })),
479 EventType::TransitiveNonReflexive => {
480 all_events.extend(actors.iter().copied().permutations(2).map(|mut x| {
481 let a = x.pop().unwrap();
482 let b = x.pop().unwrap();
483 (
484 ThetaRoles {
485 agent: Some(a),
486 patient: Some(b),
487 },
488 e.label,
489 )
490 }));
491 }
492 EventType::Transitive => all_events.extend(
493 itertools::repeat_n(actors.iter().copied(), 2)
494 .multi_cartesian_product()
495 .map(|mut x| {
496 let a = x.pop().unwrap();
497 let b = x.pop().unwrap();
498 (
499 ThetaRoles {
500 agent: Some(a),
501 patient: Some(b),
502 },
503 e.label,
504 )
505 }),
506 ),
507 EventType::Avalent => {
508 all_events.push((
509 ThetaRoles {
510 agent: None,
511 patient: None,
512 },
513 e.label,
514 ));
515 }
516 }
517 }
518
519 all_events
520}
521
522#[derive(Debug, Clone)]
523struct ActorSetGenerator<'a> {
524 actors: Vec<Actor<'a>>,
525 actor_properties: Vec<PropertyLabel<'a>>,
526 property_counter: MultiProduct<SetCounter>,
527 max_number_of_properties: Option<usize>,
528 included: SetCounter,
529}
530
531impl<'a> ActorSetGenerator<'a> {
532 fn new(
533 actors: &[Actor<'a>],
534 actor_properties: &[PropertyLabel<'a>],
535 max_number_of_actors: Option<usize>,
536 max_number_of_properties: Option<usize>,
537 ) -> Self {
538 ActorSetGenerator {
539 property_counter: std::iter::empty::<SetCounter>().multi_cartesian_product(),
540 included: SetCounter::new(actors.len(), max_number_of_actors),
541 actors: actors.to_vec(),
542 max_number_of_properties,
543 actor_properties: actor_properties.to_vec(),
544 }
545 }
546}
547
548impl<'a> Iterator for ActorSetGenerator<'a> {
549 type Item = (Vec<Actor<'a>>, BTreeMap<PropertyLabel<'a>, Vec<Entity<'a>>>);
550
551 fn next(&mut self) -> Option<Self::Item> {
552 let props = self.property_counter.next().unwrap_or_else(|| {
553 self.included.increment();
554 let n_actors = self.included.current_size();
555 self.property_counter = (0..n_actors)
556 .map(|_| {
557 SetCounter::new(self.actor_properties.len(), self.max_number_of_properties)
558 })
559 .multi_cartesian_product();
560 self.property_counter.next().unwrap()
561 });
562
563 if self.included.done() {
564 return None;
565 }
566
567 let mut actor_properties: BTreeMap<_, Vec<_>> = BTreeMap::new();
568
569 let actors: Vec<Actor<'a>> = self
570 .included
571 .included()
572 .as_set(&self.actors)
573 .copied()
574 .zip(props)
575 .map(|(x, props)| {
576 for prop in props.as_set(&self.actor_properties) {
577 actor_properties
578 .entry(*prop)
579 .or_default()
580 .push(Entity::Actor(x));
581 }
582 x
583 })
584 .collect();
585
586 Some((actors, actor_properties))
587 }
588}
589
590#[cfg(test)]
591mod test {
592 use crate::scenario::generate_all_events;
593
594 use super::*;
595 use ahash::HashSet;
596
597 #[test]
598 fn generate_all_actors() {
599 let s = ActorSetGenerator::new(&["John", "Mary"], &["man", "woman"], None, None);
600
601 let mut set = HashSet::default();
602 for p in s {
603 println!("{p:?}");
604 assert!(!set.contains(&p));
605 set.insert(p);
606 }
607 assert_eq!(set.len(), 25);
608 }
609
610 #[test]
611 fn generate_all_scenarios() {
612 let actors = ["John", "Mary"];
613 let event_kinds = [
614 PossibleEvent {
615 label: "rain",
616 event_type: EventType::Avalent,
617 },
618 PossibleEvent {
619 label: "runs",
620 event_type: EventType::Unergative,
621 },
622 PossibleEvent {
623 label: "falls",
624 event_type: EventType::Unaccusative,
625 },
626 PossibleEvent {
627 label: "loves",
628 event_type: EventType::TransitiveNonReflexive,
629 },
630 ];
631
632 let mut scenarios = HashSet::default();
633 for x in Scenario::all_scenarios(&actors, &event_kinds, &["man", "woman"], None, None, None)
634 {
635 assert!(!scenarios.contains(&x));
636 scenarios.insert(x);
637 }
638 assert_eq!(scenarios.len(), 2114);
639
640 let mut scenarios = HashSet::default();
641 let mut at_least_1 = false;
642 let mut at_least_2 = false;
643 for x in Scenario::all_scenarios(
644 &actors,
645 &event_kinds,
646 &["man", "woman"],
647 Some(2),
648 Some(1),
649 None,
650 ) {
651 assert!(!scenarios.contains(&x));
652 assert!(x.actors.len() <= 1);
653 if x.actors.len() == 1 {
654 at_least_1 = true;
655 }
656
657 if x.events().count() == 2 {
658 at_least_2 = true;
659 }
660 assert!(x.events().count() <= 2);
661 scenarios.insert(x);
662 }
663
664 assert!(at_least_1);
665 assert!(at_least_2);
666 assert_eq!(scenarios.len(), 58);
667 }
668
669 #[test]
670 fn generate_event_test() {
671 let actors = ["John", "Mary", "Phil"];
672 let event_kinds = [
673 PossibleEvent {
674 label: "rain",
675 event_type: EventType::Avalent,
676 },
677 PossibleEvent {
678 label: "runs",
679 event_type: EventType::Unergative,
680 },
681 PossibleEvent {
682 label: "falls",
683 event_type: EventType::Unaccusative,
684 },
685 PossibleEvent {
686 label: "likes",
687 event_type: EventType::Transitive,
688 },
689 PossibleEvent {
690 label: "loves",
691 event_type: EventType::TransitiveNonReflexive,
692 },
693 ];
694
695 let e = generate_all_events(&actors, &event_kinds);
696
697 assert_eq!(
698 e,
699 [
700 (
701 ThetaRoles {
702 agent: None,
703 patient: None
704 },
705 "rain"
706 ),
707 (
708 ThetaRoles {
709 agent: Some("John"),
710 patient: None
711 },
712 "runs"
713 ),
714 (
715 ThetaRoles {
716 agent: Some("Mary"),
717 patient: None
718 },
719 "runs"
720 ),
721 (
722 ThetaRoles {
723 agent: Some("Phil"),
724 patient: None
725 },
726 "runs"
727 ),
728 (
729 ThetaRoles {
730 agent: None,
731 patient: Some("John")
732 },
733 "falls"
734 ),
735 (
736 ThetaRoles {
737 agent: None,
738 patient: Some("Mary")
739 },
740 "falls"
741 ),
742 (
743 ThetaRoles {
744 agent: None,
745 patient: Some("Phil")
746 },
747 "falls"
748 ),
749 (
750 ThetaRoles {
751 agent: Some("John"),
752 patient: Some("John")
753 },
754 "likes"
755 ),
756 (
757 ThetaRoles {
758 agent: Some("Mary"),
759 patient: Some("John")
760 },
761 "likes"
762 ),
763 (
764 ThetaRoles {
765 agent: Some("Phil"),
766 patient: Some("John")
767 },
768 "likes"
769 ),
770 (
771 ThetaRoles {
772 agent: Some("John"),
773 patient: Some("Mary")
774 },
775 "likes"
776 ),
777 (
778 ThetaRoles {
779 agent: Some("Mary"),
780 patient: Some("Mary")
781 },
782 "likes"
783 ),
784 (
785 ThetaRoles {
786 agent: Some("Phil"),
787 patient: Some("Mary")
788 },
789 "likes"
790 ),
791 (
792 ThetaRoles {
793 agent: Some("John"),
794 patient: Some("Phil")
795 },
796 "likes"
797 ),
798 (
799 ThetaRoles {
800 agent: Some("Mary"),
801 patient: Some("Phil")
802 },
803 "likes"
804 ),
805 (
806 ThetaRoles {
807 agent: Some("Phil"),
808 patient: Some("Phil")
809 },
810 "likes"
811 ),
812 (
813 ThetaRoles {
814 agent: Some("Mary"),
815 patient: Some("John")
816 },
817 "loves"
818 ),
819 (
820 ThetaRoles {
821 agent: Some("Phil"),
822 patient: Some("John")
823 },
824 "loves"
825 ),
826 (
827 ThetaRoles {
828 agent: Some("John"),
829 patient: Some("Mary")
830 },
831 "loves"
832 ),
833 (
834 ThetaRoles {
835 agent: Some("Phil"),
836 patient: Some("Mary")
837 },
838 "loves"
839 ),
840 (
841 ThetaRoles {
842 agent: Some("John"),
843 patient: Some("Phil")
844 },
845 "loves"
846 ),
847 (
848 ThetaRoles {
849 agent: Some("Mary"),
850 patient: Some("Phil")
851 },
852 "loves"
853 )
854 ]
855 );
856 }
857
858 #[test]
859 #[should_panic]
860 fn parse_trailing() {
861 scenario_dataset_parser().parse("<John>trailing").unwrap();
862 }
863
864 #[test]
865 fn white_space_shenanigans() -> anyhow::Result<()> {
866 scenario_dataset_parser()
867 .parse("\"blah\" <John; {A: John (run)}>")
868 .unwrap();
869 scenario_dataset_parser()
870 .parse("\" s\" <John ; {A: John (run)}>")
871 .unwrap();
872 scenario_dataset_parser()
873 .parse("\"\" < John ; { A : John (run)}>")
874 .unwrap();
875 scenario_dataset_parser()
876 .parse("\"aaa\" < John ; { A : John ( run ) } >")
877 .unwrap();
878 scenario_dataset_parser()
879 .parse("\"aaa\" < John; {A: John ( run)}>")
880 .unwrap();
881 Ok(())
882 }
883
884 #[test]
885 fn parse_multiple_scenarios() -> anyhow::Result<()> {
886 let scenarios = vec![
887 Scenario {
888 question: vec![],
889 actors: vec!["John"],
890 thematic_relations: vec![],
891 properties: BTreeMap::default(),
892 },
893 Scenario {
894 question: vec![],
895 actors: vec!["Mary"],
896 thematic_relations: vec![],
897 properties: BTreeMap::default(),
898 },
899 Scenario {
900 question: vec![],
901 actors: vec!["John"],
902 thematic_relations: vec![],
903 properties: BTreeMap::default(),
904 },
905 ];
906
907 assert_eq!(
908 scenarios,
909 *scenario_dataset_parser()
910 .parse("\"John\" <John>\n\"Mary\" <Mary>\n\"John\" <John>")
911 .unwrap()
912 .scenarios
913 );
914
915 let scenarios = vec![
916 Scenario {
917 question: vec![],
918 actors: vec!["John"],
919 thematic_relations: vec![ThetaRoles {
920 agent: Some("John"),
921 patient: None,
922 }],
923 properties: BTreeMap::from_iter([("run", vec![Entity::Event(0)])]),
924 },
925 Scenario {
926 question: vec![],
927 actors: vec!["Mary"],
928 thematic_relations: vec![ThetaRoles {
929 agent: Some("Mary"),
930 patient: None,
931 }],
932 properties: BTreeMap::from_iter([("run", vec![Entity::Event(0)])]),
933 },
934 Scenario {
935 question: vec![],
936 actors: vec!["Mary", "John"],
937 thematic_relations: vec![ThetaRoles {
938 agent: Some("John"),
939 patient: Some("Mary"),
940 }],
941 properties: BTreeMap::from_iter([("see", vec![Entity::Event(0)])]),
942 },
943 ];
944
945 assert_eq!(
946 scenarios,
947 *scenario_dataset_parser()
948 .parse("\"John runs\" <John; {A: John (run)}>\n\"Mary runs\" <Mary; {A: Mary (run)}>\n\"John sees Mary\" <Mary, John; {A: John, P: Mary (see)}>")
949 .unwrap()
950 .scenarios
951 );
952 Ok(())
953 }
954
955 #[test]
956 fn parse_scenarios_with_questions() -> anyhow::Result<()> {
957 let scenarios = scenario_dataset_parser()
958 .parse("\"John runs\" <John; {A: John (run)}> lambda a x (x)\n\"Mary runs\" <Mary; {A: Mary (run)}>\n\"John sees Mary\" <Mary, John; {A: John, P: Mary (see)}> a_0")
959 .unwrap();
960
961 assert_eq!(
962 scenarios.scenarios[0].question.first().unwrap().to_string(),
963 "lambda a x x"
964 );
965 assert_eq!(scenarios.scenarios[1].question, vec![]);
966 assert_eq!(
967 scenarios.scenarios[2].question.first().unwrap().to_string(),
968 "a_0"
969 );
970
971 let scenarios = scenario_dataset_parser()
972 .parse("\"John runs\" <John; {A: John (run)}> lambda a x (x)\n\"Mary runs\" <Mary; {A: Mary (run)}>\n\"John sees Mary\" <Mary, John; {A: John, P: Mary (see)}> a_0; a_1; a_3")
973 .unwrap();
974 assert_eq!(scenarios.scenarios[2].question.len(), 3);
975
976 assert_eq!(
977 scenarios.scenarios[2].question.last().unwrap().to_string(),
978 "a_3"
979 );
980 Ok(())
981 }
982
983 #[test]
984 fn parse_scenario() -> anyhow::Result<()> {
985 let scenario = Scenario {
986 question: vec![],
987 actors: vec!["John"],
988 thematic_relations: vec![],
989 properties: BTreeMap::default(),
990 };
991
992 assert_eq!(
993 scenario,
994 *scenario_dataset_parser()
995 .parse("\"John\" <John>")
996 .unwrap()
997 .scenarios
998 .first()
999 .unwrap()
1000 );
1001 assert_eq!(
1002 scenario,
1003 *scenario_dataset_parser()
1004 .parse("\"John\" <John;>")
1005 .unwrap()
1006 .scenarios
1007 .first()
1008 .unwrap()
1009 );
1010 assert_eq!(
1011 scenario,
1012 *scenario_dataset_parser()
1013 .parse("\"John\" < John; >")
1014 .unwrap()
1015 .scenarios
1016 .first()
1017 .unwrap()
1018 );
1019
1020 let scenario = Scenario {
1021 question: vec![],
1022 actors: vec!["john"],
1023 thematic_relations: vec![ThetaRoles {
1024 agent: None,
1025 patient: None,
1026 }],
1027 properties: BTreeMap::default(),
1028 };
1029 assert_eq!(
1030 scenario,
1031 *scenario_dataset_parser()
1032 .parse("\"john\" <john;{}>")
1033 .unwrap()
1034 .scenarios
1035 .first()
1036 .unwrap()
1037 );
1038
1039 let scenario = Scenario {
1040 question: vec![],
1041 actors: vec!["john", "mary", "phil"],
1042 thematic_relations: vec![
1043 ThetaRoles {
1044 agent: Some("john"),
1045 patient: Some("mary"),
1046 },
1047 ThetaRoles {
1048 agent: Some("mary"),
1049 patient: None,
1050 },
1051 ThetaRoles {
1052 agent: None,
1053 patient: Some("phil"),
1054 },
1055 ],
1056 properties: BTreeMap::default(),
1057 };
1058
1059 assert_eq!(
1060 scenario,
1061 *scenario_dataset_parser()
1062 .parse("\"john sees mary\" <john,mary,phil;{A: john,P: mary},{A: mary},{P: phil}>")
1063 .unwrap()
1064 .scenarios
1065 .first()
1066 .unwrap()
1067 );
1068
1069 let scenario = Scenario {
1070 question: vec![],
1071 actors: vec!["a", "b", "c"],
1072 thematic_relations: vec![
1073 ThetaRoles {
1074 agent: None,
1075 patient: None,
1076 },
1077 ThetaRoles {
1078 agent: Some("a"),
1079 patient: None,
1080 },
1081 ThetaRoles {
1082 agent: None,
1083 patient: Some("c"),
1084 },
1085 ],
1086 properties: BTreeMap::from_iter([
1087 ("Red", vec![Entity::Actor("a"), Entity::Actor("c")]),
1088 ("Green", vec![Entity::Event(0)]),
1089 ("Blue", vec![Entity::Actor("c"), Entity::Event(2)]),
1090 ]),
1091 };
1092
1093 assert_eq!(
1094 scenario,
1095 *scenario_dataset_parser()
1096 .parse("\"blue is blued\" <a (Red),b,c (Blue, Red);{(Green)},{A: a},{P: c (Blue)}>")
1097 .unwrap()
1098 .scenarios
1099 .first()
1100 .unwrap()
1101 );
1102 let s = serde_json::to_string(&scenario)?;
1103 let scenario_2: Scenario = serde_json::from_str(s.as_str())?;
1104 assert_eq!(scenario, scenario_2);
1105
1106 Ok(())
1107 }
1108}