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| RootedLambdaPool::parse(x).map_err(|e| Rich::custom(s, e)))
257 .separated_by(just(';'))
258 .collect::<Vec<_>>(),
259 )
260 .or_not(),
261 );
262
263 scenario.map(|(mut scenario, questions)| {
264 if let Some(question) = questions {
265 scenario.question = question;
266 }
267 scenario
268 })
269}
270
271#[allow(clippy::too_many_lines)]
272pub fn scenario_dataset_parser<'a>()
273-> impl Parser<'a, &'a str, ScenarioDataset<'a>, extra::Err<Rich<'a, char>>> {
274 let string_scenario_pair = none_of("\"")
275 .repeated()
276 .to_slice()
277 .delimited_by(just('"'), just('"'))
278 .map(|x: &str| x.split(' '))
279 .then_ignore(inline_whitespace().at_least(1))
280 .then(scenario_parser());
281
282 string_scenario_pair
283 .separated_by(text::newline())
284 .at_least(1)
285 .collect::<Vec<_>>()
286 .map(|v| {
287 let mut scenarios = vec![];
288 let mut sentences = vec![];
289 for (a, b) in v {
290 sentences.push(a.collect());
291 scenarios.push(b);
292 }
293 ScenarioDataset::new(scenarios, sentences).unwrap()
294 })
295 .padded()
296 .then_ignore(end())
297}
298
299type EventParseType<'a> = Option<(Vec<ThetaRoles<'a>>, BTreeMap<&'a str, Vec<Entity<'a>>>)>;
300
301fn new_scenario<'a>(
302 actors: Vec<Actor<'a>>,
303 actor_props: BTreeMap<&'a str, Vec<&'a str>>,
304 events: EventParseType<'a>,
305) -> Scenario<'a> {
306 let (events, event_props) = events.unwrap_or_else(|| (Vec::default(), BTreeMap::default()));
307
308 let mut properties: BTreeMap<&str, Vec<Entity>> = actor_props
309 .into_iter()
310 .map(|(k, v)| (k, v.into_iter().map(Entity::Actor).collect()))
311 .collect();
312
313 for (k, mut v) in event_props {
314 properties
315 .entry(k)
316 .and_modify(|value| value.append(&mut v))
317 .or_insert(v);
318 }
319
320 Scenario {
321 question: vec![],
322 actors,
323 thematic_relations: events,
324 properties,
325 }
326}
327
328mod utilities;
329use utilities::SetCounter;
330
331#[derive(Debug, Clone)]
333pub struct ScenarioIterator<'a> {
334 actors: ActorSetGenerator<'a>,
335 current_actors: Vec<Actor<'a>>,
336 current_props: BTreeMap<PropertyLabel<'a>, Vec<Entity<'a>>>,
337 current_event_set: Vec<(ThetaRoles<'a>, PropertyLabel<'a>)>,
338 event_kinds: Vec<PossibleEvent<'a>>,
339 counter: SetCounter,
340 max_number_of_events: Option<usize>,
341}
342
343#[derive(Debug, Clone, Eq, PartialEq, Copy, Ord, PartialOrd, Hash, Serialize, Deserialize)]
345pub enum EventType {
346 Unergative,
348
349 Unaccusative,
351
352 TransitiveNonReflexive,
354
355 Transitive,
357
358 Avalent,
360}
361
362#[derive(Debug, Clone, Eq, PartialEq, Copy, Ord, PartialOrd, Hash, Serialize, Deserialize)]
364pub struct PossibleEvent<'a> {
365 #[serde(borrow)]
367 pub label: PropertyLabel<'a>,
368 pub event_type: EventType,
370}
371
372impl<'a> Scenario<'a> {
373 #[must_use]
377 pub fn all_scenarios(
378 actors: &[Actor<'a>],
379 event_kinds: &[PossibleEvent<'a>],
380 actor_properties: &[PropertyLabel<'a>],
381 max_number_of_events: Option<usize>,
382 max_number_of_actors: Option<usize>,
383 max_number_of_properties: Option<usize>,
384 ) -> ScenarioIterator<'a> {
385 let mut actors = ActorSetGenerator::new(
386 actors,
387 actor_properties,
388 max_number_of_actors,
389 max_number_of_properties,
390 );
391 let (current_actors, current_props) = actors.next().unwrap();
392 let current_event_set = generate_all_events(¤t_actors, event_kinds);
393 let counter = SetCounter::new(current_event_set.len(), max_number_of_events);
394
395 ScenarioIterator {
396 actors,
397 current_actors,
398 current_event_set,
399 current_props,
400 event_kinds: event_kinds.to_vec(),
401 counter,
402 max_number_of_events,
403 }
404 }
405}
406
407impl<'a> Iterator for ScenarioIterator<'a> {
408 type Item = Scenario<'a>;
409
410 fn next(&mut self) -> Option<Self::Item> {
411 if self.counter.done() {
412 if let Some((new_actors, new_props)) = self.actors.next() {
413 self.current_actors = new_actors;
414 self.current_props = new_props;
415 self.current_event_set =
416 generate_all_events(&self.current_actors, &self.event_kinds);
417 self.counter =
418 SetCounter::new(self.current_event_set.len(), self.max_number_of_events);
419 } else {
420 return None;
421 }
422 }
423
424 let mut properties = self.current_props.clone();
425 let mut thematic_relations = vec![];
426 for (i, (theta, label)) in self
427 .counter
428 .as_set(self.current_event_set.iter().copied())
429 .enumerate()
430 {
431 properties
432 .entry(label)
433 .or_default()
434 .push(Entity::Event(Event::try_from(i).expect("Too many events!")));
435 thematic_relations.push(theta);
436 }
437 self.counter.increment();
438 Some(Scenario::new(
439 self.current_actors.clone(),
440 thematic_relations,
441 properties,
442 ))
443 }
444}
445
446fn generate_all_events<'a>(
447 actors: &[Actor<'a>],
448 event_kinds: &[PossibleEvent<'a>],
449) -> Vec<(ThetaRoles<'a>, PropertyLabel<'a>)> {
450 let mut all_events = vec![];
451 for e in event_kinds {
452 match e.event_type {
453 EventType::Unergative => all_events.extend(actors.iter().copied().map(|x| {
454 (
455 ThetaRoles {
456 agent: Some(x),
457 patient: None,
458 },
459 e.label,
460 )
461 })),
462 EventType::Unaccusative => all_events.extend(actors.iter().copied().map(|x| {
463 (
464 ThetaRoles {
465 agent: None,
466 patient: Some(x),
467 },
468 e.label,
469 )
470 })),
471 EventType::TransitiveNonReflexive => {
472 all_events.extend(actors.iter().copied().permutations(2).map(|mut x| {
473 let a = x.pop().unwrap();
474 let b = x.pop().unwrap();
475 (
476 ThetaRoles {
477 agent: Some(a),
478 patient: Some(b),
479 },
480 e.label,
481 )
482 }));
483 }
484 EventType::Transitive => all_events.extend(
485 itertools::repeat_n(actors.iter().copied(), 2)
486 .multi_cartesian_product()
487 .map(|mut x| {
488 let a = x.pop().unwrap();
489 let b = x.pop().unwrap();
490 (
491 ThetaRoles {
492 agent: Some(a),
493 patient: Some(b),
494 },
495 e.label,
496 )
497 }),
498 ),
499 EventType::Avalent => {
500 all_events.push((
501 ThetaRoles {
502 agent: None,
503 patient: None,
504 },
505 e.label,
506 ));
507 }
508 }
509 }
510
511 all_events
512}
513
514#[derive(Debug, Clone)]
515struct ActorSetGenerator<'a> {
516 actors: Vec<Actor<'a>>,
517 actor_properties: Vec<PropertyLabel<'a>>,
518 property_counter: MultiProduct<SetCounter>,
519 max_number_of_properties: Option<usize>,
520 included: SetCounter,
521}
522
523impl<'a> ActorSetGenerator<'a> {
524 fn new(
525 actors: &[Actor<'a>],
526 actor_properties: &[PropertyLabel<'a>],
527 max_number_of_actors: Option<usize>,
528 max_number_of_properties: Option<usize>,
529 ) -> Self {
530 ActorSetGenerator {
531 property_counter: std::iter::empty::<SetCounter>().multi_cartesian_product(),
532 included: SetCounter::new(actors.len(), max_number_of_actors),
533 actors: actors.to_vec(),
534 max_number_of_properties,
535 actor_properties: actor_properties.to_vec(),
536 }
537 }
538}
539
540impl<'a> Iterator for ActorSetGenerator<'a> {
541 type Item = (Vec<Actor<'a>>, BTreeMap<PropertyLabel<'a>, Vec<Entity<'a>>>);
542
543 fn next(&mut self) -> Option<Self::Item> {
544 let props = self.property_counter.next().unwrap_or_else(|| {
545 self.included.increment();
546 let n_actors = self.included.current_size();
547 self.property_counter = (0..n_actors)
548 .map(|_| {
549 SetCounter::new(self.actor_properties.len(), self.max_number_of_properties)
550 })
551 .multi_cartesian_product();
552 self.property_counter.next().unwrap()
553 });
554
555 if self.included.done() {
556 return None;
557 }
558
559 let mut actor_properties: BTreeMap<_, Vec<_>> = BTreeMap::new();
560
561 let actors: Vec<Actor<'a>> = self
562 .included
563 .included()
564 .as_set(&self.actors)
565 .copied()
566 .zip(props)
567 .map(|(x, props)| {
568 for prop in props.as_set(&self.actor_properties) {
569 actor_properties
570 .entry(*prop)
571 .or_default()
572 .push(Entity::Actor(x));
573 }
574 x
575 })
576 .collect();
577
578 Some((actors, actor_properties))
579 }
580}
581
582#[cfg(test)]
583mod test {
584 use crate::scenario::generate_all_events;
585
586 use super::*;
587 use ahash::HashSet;
588
589 #[test]
590 fn generate_all_actors() {
591 let s = ActorSetGenerator::new(&["John", "Mary"], &["man", "woman"], None, None);
592
593 let mut set = HashSet::default();
594 for p in s {
595 println!("{p:?}");
596 assert!(!set.contains(&p));
597 set.insert(p);
598 }
599 assert_eq!(set.len(), 25);
600 }
601
602 #[test]
603 fn generate_all_scenarios() {
604 let actors = ["John", "Mary"];
605 let event_kinds = [
606 PossibleEvent {
607 label: "rain",
608 event_type: EventType::Avalent,
609 },
610 PossibleEvent {
611 label: "runs",
612 event_type: EventType::Unergative,
613 },
614 PossibleEvent {
615 label: "falls",
616 event_type: EventType::Unaccusative,
617 },
618 PossibleEvent {
619 label: "loves",
620 event_type: EventType::TransitiveNonReflexive,
621 },
622 ];
623
624 let mut scenarios = HashSet::default();
625 for x in Scenario::all_scenarios(&actors, &event_kinds, &["man", "woman"], None, None, None)
626 {
627 assert!(!scenarios.contains(&x));
628 scenarios.insert(x);
629 }
630 assert_eq!(scenarios.len(), 2114);
631
632 let mut scenarios = HashSet::default();
633 let mut at_least_1 = false;
634 let mut at_least_2 = false;
635 for x in Scenario::all_scenarios(
636 &actors,
637 &event_kinds,
638 &["man", "woman"],
639 Some(2),
640 Some(1),
641 None,
642 ) {
643 assert!(!scenarios.contains(&x));
644 assert!(x.actors.len() <= 1);
645 if x.actors.len() == 1 {
646 at_least_1 = true;
647 }
648
649 if x.events().count() == 2 {
650 at_least_2 = true;
651 }
652 assert!(x.events().count() <= 2);
653 scenarios.insert(x);
654 }
655
656 assert!(at_least_1);
657 assert!(at_least_2);
658 assert_eq!(scenarios.len(), 58);
659 }
660
661 #[test]
662 fn generate_event_test() {
663 let actors = ["John", "Mary", "Phil"];
664 let event_kinds = [
665 PossibleEvent {
666 label: "rain",
667 event_type: EventType::Avalent,
668 },
669 PossibleEvent {
670 label: "runs",
671 event_type: EventType::Unergative,
672 },
673 PossibleEvent {
674 label: "falls",
675 event_type: EventType::Unaccusative,
676 },
677 PossibleEvent {
678 label: "likes",
679 event_type: EventType::Transitive,
680 },
681 PossibleEvent {
682 label: "loves",
683 event_type: EventType::TransitiveNonReflexive,
684 },
685 ];
686
687 let e = generate_all_events(&actors, &event_kinds);
688
689 assert_eq!(
690 e,
691 [
692 (
693 ThetaRoles {
694 agent: None,
695 patient: None
696 },
697 "rain"
698 ),
699 (
700 ThetaRoles {
701 agent: Some("John"),
702 patient: None
703 },
704 "runs"
705 ),
706 (
707 ThetaRoles {
708 agent: Some("Mary"),
709 patient: None
710 },
711 "runs"
712 ),
713 (
714 ThetaRoles {
715 agent: Some("Phil"),
716 patient: None
717 },
718 "runs"
719 ),
720 (
721 ThetaRoles {
722 agent: None,
723 patient: Some("John")
724 },
725 "falls"
726 ),
727 (
728 ThetaRoles {
729 agent: None,
730 patient: Some("Mary")
731 },
732 "falls"
733 ),
734 (
735 ThetaRoles {
736 agent: None,
737 patient: Some("Phil")
738 },
739 "falls"
740 ),
741 (
742 ThetaRoles {
743 agent: Some("John"),
744 patient: Some("John")
745 },
746 "likes"
747 ),
748 (
749 ThetaRoles {
750 agent: Some("Mary"),
751 patient: Some("John")
752 },
753 "likes"
754 ),
755 (
756 ThetaRoles {
757 agent: Some("Phil"),
758 patient: Some("John")
759 },
760 "likes"
761 ),
762 (
763 ThetaRoles {
764 agent: Some("John"),
765 patient: Some("Mary")
766 },
767 "likes"
768 ),
769 (
770 ThetaRoles {
771 agent: Some("Mary"),
772 patient: Some("Mary")
773 },
774 "likes"
775 ),
776 (
777 ThetaRoles {
778 agent: Some("Phil"),
779 patient: Some("Mary")
780 },
781 "likes"
782 ),
783 (
784 ThetaRoles {
785 agent: Some("John"),
786 patient: Some("Phil")
787 },
788 "likes"
789 ),
790 (
791 ThetaRoles {
792 agent: Some("Mary"),
793 patient: Some("Phil")
794 },
795 "likes"
796 ),
797 (
798 ThetaRoles {
799 agent: Some("Phil"),
800 patient: Some("Phil")
801 },
802 "likes"
803 ),
804 (
805 ThetaRoles {
806 agent: Some("Mary"),
807 patient: Some("John")
808 },
809 "loves"
810 ),
811 (
812 ThetaRoles {
813 agent: Some("Phil"),
814 patient: Some("John")
815 },
816 "loves"
817 ),
818 (
819 ThetaRoles {
820 agent: Some("John"),
821 patient: Some("Mary")
822 },
823 "loves"
824 ),
825 (
826 ThetaRoles {
827 agent: Some("Phil"),
828 patient: Some("Mary")
829 },
830 "loves"
831 ),
832 (
833 ThetaRoles {
834 agent: Some("John"),
835 patient: Some("Phil")
836 },
837 "loves"
838 ),
839 (
840 ThetaRoles {
841 agent: Some("Mary"),
842 patient: Some("Phil")
843 },
844 "loves"
845 )
846 ]
847 );
848 }
849
850 #[test]
851 #[should_panic]
852 fn parse_trailing() {
853 scenario_dataset_parser().parse("<John>trailing").unwrap();
854 }
855
856 #[test]
857 fn white_space_shenanigans() -> anyhow::Result<()> {
858 scenario_dataset_parser()
859 .parse("\"blah\" <John; {A: John (run)}>")
860 .unwrap();
861 scenario_dataset_parser()
862 .parse("\" s\" <John ; {A: John (run)}>")
863 .unwrap();
864 scenario_dataset_parser()
865 .parse("\"\" < John ; { A : John (run)}>")
866 .unwrap();
867 scenario_dataset_parser()
868 .parse("\"aaa\" < John ; { A : John ( run ) } >")
869 .unwrap();
870 scenario_dataset_parser()
871 .parse("\"aaa\" < John; {A: John ( run)}>")
872 .unwrap();
873 Ok(())
874 }
875
876 #[test]
877 fn parse_multiple_scenarios() -> anyhow::Result<()> {
878 let scenarios = vec![
879 Scenario {
880 question: vec![],
881 actors: vec!["John"],
882 thematic_relations: vec![],
883 properties: BTreeMap::default(),
884 },
885 Scenario {
886 question: vec![],
887 actors: vec!["Mary"],
888 thematic_relations: vec![],
889 properties: BTreeMap::default(),
890 },
891 Scenario {
892 question: vec![],
893 actors: vec!["John"],
894 thematic_relations: vec![],
895 properties: BTreeMap::default(),
896 },
897 ];
898
899 assert_eq!(
900 scenarios,
901 *scenario_dataset_parser()
902 .parse("\"John\" <John>\n\"Mary\" <Mary>\n\"John\" <John>")
903 .unwrap()
904 .scenarios
905 );
906
907 let scenarios = vec![
908 Scenario {
909 question: vec![],
910 actors: vec!["John"],
911 thematic_relations: vec![ThetaRoles {
912 agent: Some("John"),
913 patient: None,
914 }],
915 properties: BTreeMap::from_iter([("run", vec![Entity::Event(0)])]),
916 },
917 Scenario {
918 question: vec![],
919 actors: vec!["Mary"],
920 thematic_relations: vec![ThetaRoles {
921 agent: Some("Mary"),
922 patient: None,
923 }],
924 properties: BTreeMap::from_iter([("run", vec![Entity::Event(0)])]),
925 },
926 Scenario {
927 question: vec![],
928 actors: vec!["Mary", "John"],
929 thematic_relations: vec![ThetaRoles {
930 agent: Some("John"),
931 patient: Some("Mary"),
932 }],
933 properties: BTreeMap::from_iter([("see", vec![Entity::Event(0)])]),
934 },
935 ];
936
937 assert_eq!(
938 scenarios,
939 *scenario_dataset_parser()
940 .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)}>")
941 .unwrap()
942 .scenarios
943 );
944 Ok(())
945 }
946
947 #[test]
948 fn parse_scenarios_with_questions() -> anyhow::Result<()> {
949 let scenarios = scenario_dataset_parser()
950 .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")
951 .unwrap();
952
953 assert_eq!(
954 scenarios.scenarios[0].question.first().unwrap().to_string(),
955 "lambda a x x"
956 );
957 assert_eq!(scenarios.scenarios[1].question, vec![]);
958 assert_eq!(
959 scenarios.scenarios[2].question.first().unwrap().to_string(),
960 "a_0"
961 );
962
963 let scenarios = scenario_dataset_parser()
964 .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")
965 .unwrap();
966 assert_eq!(scenarios.scenarios[2].question.len(), 3);
967
968 assert_eq!(
969 scenarios.scenarios[2].question.last().unwrap().to_string(),
970 "a_3"
971 );
972 Ok(())
973 }
974
975 #[test]
976 fn parse_scenario() -> anyhow::Result<()> {
977 let scenario = Scenario {
978 question: vec![],
979 actors: vec!["John"],
980 thematic_relations: vec![],
981 properties: BTreeMap::default(),
982 };
983
984 assert_eq!(
985 scenario,
986 *scenario_dataset_parser()
987 .parse("\"John\" <John>")
988 .unwrap()
989 .scenarios
990 .first()
991 .unwrap()
992 );
993 assert_eq!(
994 scenario,
995 *scenario_dataset_parser()
996 .parse("\"John\" <John;>")
997 .unwrap()
998 .scenarios
999 .first()
1000 .unwrap()
1001 );
1002 assert_eq!(
1003 scenario,
1004 *scenario_dataset_parser()
1005 .parse("\"John\" < John; >")
1006 .unwrap()
1007 .scenarios
1008 .first()
1009 .unwrap()
1010 );
1011
1012 let scenario = Scenario {
1013 question: vec![],
1014 actors: vec!["john"],
1015 thematic_relations: vec![ThetaRoles {
1016 agent: None,
1017 patient: None,
1018 }],
1019 properties: BTreeMap::default(),
1020 };
1021 assert_eq!(
1022 scenario,
1023 *scenario_dataset_parser()
1024 .parse("\"john\" <john;{}>")
1025 .unwrap()
1026 .scenarios
1027 .first()
1028 .unwrap()
1029 );
1030
1031 let scenario = Scenario {
1032 question: vec![],
1033 actors: vec!["john", "mary", "phil"],
1034 thematic_relations: vec![
1035 ThetaRoles {
1036 agent: Some("john"),
1037 patient: Some("mary"),
1038 },
1039 ThetaRoles {
1040 agent: Some("mary"),
1041 patient: None,
1042 },
1043 ThetaRoles {
1044 agent: None,
1045 patient: Some("phil"),
1046 },
1047 ],
1048 properties: BTreeMap::default(),
1049 };
1050
1051 assert_eq!(
1052 scenario,
1053 *scenario_dataset_parser()
1054 .parse("\"john sees mary\" <john,mary,phil;{A: john,P: mary},{A: mary},{P: phil}>")
1055 .unwrap()
1056 .scenarios
1057 .first()
1058 .unwrap()
1059 );
1060
1061 let scenario = Scenario {
1062 question: vec![],
1063 actors: vec!["a", "b", "c"],
1064 thematic_relations: vec![
1065 ThetaRoles {
1066 agent: None,
1067 patient: None,
1068 },
1069 ThetaRoles {
1070 agent: Some("a"),
1071 patient: None,
1072 },
1073 ThetaRoles {
1074 agent: None,
1075 patient: Some("c"),
1076 },
1077 ],
1078 properties: BTreeMap::from_iter([
1079 ("Red", vec![Entity::Actor("a"), Entity::Actor("c")]),
1080 ("Green", vec![Entity::Event(0)]),
1081 ("Blue", vec![Entity::Actor("c"), Entity::Event(2)]),
1082 ]),
1083 };
1084
1085 assert_eq!(
1086 scenario,
1087 *scenario_dataset_parser()
1088 .parse("\"blue is blued\" <a (Red),b,c (Blue, Red);{(Green)},{A: a},{P: c (Blue)}>")
1089 .unwrap()
1090 .scenarios
1091 .first()
1092 .unwrap()
1093 );
1094 let s = serde_json::to_string(&scenario)?;
1095 let scenario_2: Scenario = serde_json::from_str(s.as_str())?;
1096 assert_eq!(scenario, scenario_2);
1097
1098 Ok(())
1099 }
1100}