simple_semantics/
lib.rs

1//! # Simple semantics
2//! This crate defines a simple language of thought with a lambda calculus and a randomization
3//! procedure to learn simple montagovian grammars.
4#![warn(missing_docs)]
5use ahash::HashSet;
6use chumsky::prelude::*;
7use lambda::RootedLambdaPool;
8use language::{Expr, LambdaParseError};
9use serde::{Deserialize, Serialize};
10use std::{collections::BTreeMap, fmt::Display};
11use thiserror::Error;
12
13///The representation of an entity that can receive theta roles (e.g. a human, a cup, a thought).
14pub type Actor<'a> = &'a str;
15///The representation of an entity that can assign theta roles (e.g. a runnning even, when its raining, etc.)
16///They are representated as indices to the relevant [`ThetaRoles`] in a given [`Scenario`].
17pub type Event = u8;
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
20///The union of [`Actor`] and [`Event`]
21pub enum Entity<'a> {
22    ///See [`Actor`]
23    #[serde(borrow)]
24    Actor(Actor<'a>),
25    ///See [`Event`]
26    Event(Event),
27}
28
29impl Display for Entity<'_> {
30    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31        match self {
32            Entity::Actor(a) => write!(f, "a_{a}"),
33            Entity::Event(a) => write!(f, "e_{a}"),
34        }
35    }
36}
37
38///The representation of the theta roles of a given event.
39#[derive(Debug, Clone, Copy, PartialEq, Default, Eq, Hash, Serialize, Deserialize)]
40pub struct ThetaRoles<'a> {
41    ///The agent of the event.
42    #[serde(borrow)]
43    pub agent: Option<Actor<'a>>,
44    ///The patient of the event.
45    pub patient: Option<Actor<'a>>,
46}
47
48type PropertyLabel<'a> = &'a str;
49
50///The representation of a scenario. A moment consisting of various events, the present actors and
51///any predicates that apply to either.
52#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
53pub struct Scenario<'a> {
54    #[serde(borrow)]
55    actors: Vec<Actor<'a>>,
56    thematic_relations: Vec<ThetaRoles<'a>>,
57    properties: BTreeMap<PropertyLabel<'a>, Vec<Entity<'a>>>,
58    question: Vec<RootedLambdaPool<'a, Expr<'a>>>,
59}
60
61impl<'a> Scenario<'a> {
62    ///Create a new scenario.
63    #[must_use]
64    pub fn new(
65        actors: Vec<Actor<'a>>,
66        thematic_relations: Vec<ThetaRoles<'a>>,
67        properties: BTreeMap<PropertyLabel<'a>, Vec<Entity<'a>>>,
68    ) -> Scenario<'a> {
69        Scenario {
70            actors,
71            thematic_relations,
72            properties,
73            question: vec![],
74        }
75    }
76
77    ///Get the representation of all events as a slice of [`ThetaRoles`].
78    #[must_use]
79    pub fn thematic_relations(&self) -> &[ThetaRoles<'a>] {
80        &self.thematic_relations
81    }
82
83    ///Get the properties (e.g. what predicates apply) of the entities in a scenario.
84    #[must_use]
85    pub fn properties(&self) -> &BTreeMap<PropertyLabel<'a>, Vec<Entity<'a>>> {
86        &self.properties
87    }
88
89    ///Get a slice of all [`Actor`]s in the [`Scenario`]
90    #[must_use]
91    pub fn actors(&self) -> &[Actor<'_>] {
92        &self.actors
93    }
94
95    ///Get the questions associated with a scenario (which may be empty if there are no questions).
96    ///Questions are representated as [`RootedLambdaPool`] which return a truth value.
97    #[must_use]
98    pub fn questions(&self) -> &[RootedLambdaPool<'a, Expr<'a>>] {
99        &self.question
100    }
101
102    ///Get a mutable reference to the questions of a scenario.
103    ///See [`Scenario::questions`]
104    pub fn question_mut(&mut self) -> &mut Vec<RootedLambdaPool<'a, Expr<'a>>> {
105        &mut self.question
106    }
107
108    fn events(&self) -> impl Iterator<Item = Event> {
109        0..(self.thematic_relations.len() as Event)
110    }
111}
112
113///A struct defining a dataset of different [`Scenario`]s as well as their associated sentences all
114///lemmas in the dataset.
115#[derive(Debug, Default, Clone, Eq, PartialEq, Serialize, Deserialize)]
116pub struct ScenarioDataset<'a> {
117    #[serde(borrow)]
118    scenarios: Vec<Scenario<'a>>,
119    sentences: Vec<Vec<&'a str>>,
120    lemmas: Vec<&'a str>,
121}
122
123///Error for creating a dataset without equal sentences and scenarios.
124#[derive(Debug, Default, Clone, Eq, PartialEq, Error)]
125pub struct DatasetError {}
126
127impl Display for DatasetError {
128    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129        write!(f, "Scenario and sentences not of equal length!")
130    }
131}
132
133impl<'a> ScenarioDataset<'a> {
134    ///Create a new [`ScenarioDataset`]
135    pub fn new(
136        scenarios: Vec<Scenario<'a>>,
137        sentences: Vec<Vec<&'a str>>,
138        lemmas: HashSet<&'a str>,
139    ) -> Result<Self, DatasetError> {
140        if scenarios.len() != sentences.len() {
141            return Err(DatasetError {});
142        }
143
144        let mut lemmas: Vec<_> = lemmas.into_iter().collect();
145        lemmas.sort_unstable();
146        Ok(ScenarioDataset {
147            scenarios,
148            sentences,
149            lemmas,
150        })
151    }
152
153    ///Is the dataset empty?
154    #[must_use]
155    pub fn is_empty(&self) -> bool {
156        self.scenarios.is_empty()
157    }
158
159    ///The number of scenarios in the [`ScenarioDataset`].
160    #[must_use]
161    pub fn len(&self) -> usize {
162        self.scenarios.len()
163    }
164
165    ///Iterate over all scenarios with a mutable reference.
166    pub fn iter_scenarios_mut(&mut self) -> impl Iterator<Item = &mut Scenario<'a>> {
167        self.scenarios.iter_mut()
168    }
169
170    ///Iterate over all scenarios
171    pub fn iter_scenarios(&self) -> impl Iterator<Item = &Scenario<'a>> {
172        self.scenarios.iter()
173    }
174
175    ///Iterate over all scenarios and sentences with a mutable reference.
176    pub fn iter_mut(&mut self) -> impl Iterator<Item = (&mut Scenario<'a>, &mut Vec<&'a str>)> {
177        self.scenarios.iter_mut().zip(self.sentences.iter_mut())
178    }
179
180    ///Iterate over all scenarios and sentences
181    pub fn iter(&self) -> impl Iterator<Item = (&Scenario<'a>, &Vec<&'a str>)> {
182        self.scenarios.iter().zip(self.sentences.iter())
183    }
184
185    ///Get the available lemmas of a dataset.
186    #[must_use]
187    pub fn lemmas(&self) -> &[&'a str] {
188        &self.lemmas
189    }
190
191    ///Parse a list of sentences and scenarios and return the dataset.
192    pub fn parse(s: &'a str) -> Result<Self, LambdaParseError> {
193        let parser = scenario::scenario_parser();
194        let parse = parser.parse(s).into_result();
195        parse?
196    }
197}
198
199pub mod lambda;
200pub mod language;
201mod utils;
202pub use language::{LanguageExpression, LanguageResult, parse_executable};
203mod scenario;