simple_semantics/language/mutations/
samplers.rs

1use ahash::HashMap;
2use std::{
3    borrow::Cow,
4    collections::{BTreeMap, btree_map::Entry as BTEntry, hash_map::Entry},
5};
6
7use super::{
8    ActorOrEvent, BinOp, Context, Debug, Expr, ExprRef, LambdaExpr, LambdaExprRef,
9    LambdaLanguageOfThought, MonOp, Quantifier,
10};
11use crate::{Actor, PropertyLabel, lambda::types::LambdaType};
12
13///A struct which defines a `HashMap` of all types and expressions.
14///The outer `HashMap` is for the return types of expressions and the inner `HashMap` is for their
15///arguments. Then there is a vector of all possible lambda expressions with that output type and
16///input arguments.
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct PossibleExpressions<'src, T> {
19    expressions: HashMap<LambdaType, BTreeMap<Vec<LambdaType>, Vec<LambdaExpr<'src, T>>>>,
20}
21
22impl<'src, T> From<HashMap<LambdaType, BTreeMap<Vec<LambdaType>, Vec<LambdaExpr<'src, T>>>>>
23    for PossibleExpressions<'src, T>
24{
25    fn from(
26        value: HashMap<LambdaType, BTreeMap<Vec<LambdaType>, Vec<LambdaExpr<'src, T>>>>,
27    ) -> Self {
28        PossibleExpressions { expressions: value }
29    }
30}
31
32impl<'src> PossibleExpressions<'src, Expr<'src>> {
33    ///Create a new [`PossibleExpressions`] for [`Expr`].
34    #[must_use]
35    pub fn new(
36        actors: &[Actor<'src>],
37        actor_properties: &[PropertyLabel<'src>],
38        event_properties: &[PropertyLabel<'src>],
39    ) -> Self {
40        let bad_ref = ExprRef(0);
41        let mut all_expressions: Vec<_> = [
42            Expr::Unary(MonOp::Not, bad_ref),
43            Expr::Binary(BinOp::And, bad_ref, bad_ref),
44            Expr::Binary(BinOp::Or, bad_ref, bad_ref),
45            Expr::Quantifier {
46                quantifier: Quantifier::Existential,
47                var_type: ActorOrEvent::Actor,
48                subformula: bad_ref,
49                restrictor: bad_ref,
50            },
51            Expr::Quantifier {
52                quantifier: Quantifier::Universal,
53                var_type: ActorOrEvent::Actor,
54                subformula: bad_ref,
55                restrictor: bad_ref,
56            },
57            Expr::Quantifier {
58                quantifier: Quantifier::Existential,
59                var_type: ActorOrEvent::Event,
60                subformula: bad_ref,
61                restrictor: bad_ref,
62            },
63            Expr::Quantifier {
64                quantifier: Quantifier::Universal,
65                var_type: ActorOrEvent::Event,
66                subformula: bad_ref,
67                restrictor: bad_ref,
68            },
69            Expr::Binary(BinOp::AgentOf, bad_ref, bad_ref),
70            Expr::Binary(BinOp::PatientOf, bad_ref, bad_ref),
71            Expr::Unary(MonOp::Iota(ActorOrEvent::Actor), bad_ref),
72            Expr::Unary(MonOp::Iota(ActorOrEvent::Event), bad_ref),
73        ]
74        .to_vec();
75
76        all_expressions.extend(actors.iter().map(|x| Expr::Actor(x)));
77
78        all_expressions.extend(actor_properties.iter().flat_map(|i| {
79            [Expr::Unary(
80                MonOp::Property(i, ActorOrEvent::Actor),
81                bad_ref,
82            )]
83        }));
84        all_expressions.extend(event_properties.iter().flat_map(|i| {
85            [Expr::Unary(
86                MonOp::Property(i, ActorOrEvent::Event),
87                bad_ref,
88            )]
89        }));
90
91        let mut expressions: HashMap<LambdaType, BTreeMap<_, Vec<_>>> = HashMap::default();
92        for expr in all_expressions {
93            let output = expr.get_type();
94            let arguments = expr.get_arguments().collect();
95            let expr = LambdaExpr::LanguageOfThoughtExpr(expr);
96            //Annoying match to avoid cloning arguments
97            match expressions.entry(output.clone()) {
98                Entry::Occupied(mut occupied) => {
99                    let inner_h: &mut BTreeMap<_, _> = occupied.get_mut();
100                    match inner_h.entry(arguments) {
101                        BTEntry::Occupied(mut occupied) => occupied.get_mut().push(expr),
102                        BTEntry::Vacant(vacant) => {
103                            vacant.insert(vec![expr]);
104                        }
105                    }
106                }
107                Entry::Vacant(vacant) => {
108                    vacant.insert([(arguments, vec![expr])].into_iter().collect());
109                }
110            }
111        }
112
113        PossibleExpressions { expressions }
114    }
115}
116
117#[derive(Debug, Clone, PartialEq, Eq)]
118pub(crate) struct PossibleExpr<'a, 'src, T: LambdaLanguageOfThought + Clone> {
119    expr: Cow<'a, LambdaExpr<'src, T>>,
120    app_details: Option<(LambdaType, LambdaType)>,
121}
122
123impl<'a, 'src, T: LambdaLanguageOfThought + Clone> PossibleExpr<'a, 'src, T> {
124    pub fn into_expr(self) -> (LambdaExpr<'src, T>, Option<(LambdaType, LambdaType)>) {
125        (self.expr.into_owned(), self.app_details)
126    }
127
128    pub fn expr(&self) -> &LambdaExpr<'src, T> {
129        &self.expr
130    }
131
132    pub fn new_borrowed(expr: &'a LambdaExpr<'src, T>) -> Self {
133        PossibleExpr {
134            expr: Cow::Borrowed(expr),
135            app_details: None,
136        }
137    }
138
139    fn new_owned(expr: LambdaExpr<'src, T>) -> Self {
140        PossibleExpr {
141            expr: Cow::Owned(expr),
142            app_details: None,
143        }
144    }
145
146    fn new_application(subformula: LambdaType, argument: LambdaType) -> Self {
147        PossibleExpr {
148            expr: Cow::Owned(LambdaExpr::Application {
149                subformula: LambdaExprRef(0),
150                argument: LambdaExprRef(0),
151            }),
152            app_details: Some((subformula, argument)),
153        }
154    }
155}
156impl<'src, T: LambdaLanguageOfThought + Clone> PossibleExpressions<'src, T> {
157    pub(crate) fn terms<'a>(
158        &'a self,
159        lambda_type: &LambdaType,
160        include_lambdas: bool,
161        variables: impl Iterator<Item = LambdaExpr<'src, T>>,
162        applications: impl Iterator<Item = (LambdaType, LambdaType)>,
163    ) -> Vec<PossibleExpr<'a, 'src, T>> {
164        let mut possibilities = vec![];
165        if let Some(x) = self.expressions.get(lambda_type).map(|x| {
166            x.iter()
167                .flat_map(|(_, v)| v.iter().map(PossibleExpr::new_borrowed))
168        }) {
169            possibilities.extend(x);
170        }
171        if include_lambdas && let Ok((lhs, _)) = lambda_type.split() {
172            let e = PossibleExpr::new_owned(LambdaExpr::Lambda(LambdaExprRef(0), lhs.clone()));
173            possibilities.push(e);
174        }
175        possibilities.extend(variables.map(PossibleExpr::new_owned));
176        possibilities.extend(
177            applications
178                .map(|(subformula, argument)| PossibleExpr::new_application(subformula, argument)),
179        );
180
181        possibilities
182    }
183}
184
185impl<'src, T: LambdaLanguageOfThought + Clone + Debug> PossibleExpressions<'src, T> {
186    pub(super) fn possibilities<'a>(
187        &'a self,
188        lambda_type: &LambdaType,
189        is_subformula: bool,
190        context: &Context,
191    ) -> Vec<PossibleExpr<'a, 'src, T>> {
192        let mut possibilities = vec![];
193        if !is_subformula {
194            if let Some(x) = self.expressions.get(lambda_type).map(|x| {
195                x.iter()
196                    .flat_map(|(_, v)| v.iter().map(PossibleExpr::new_borrowed))
197            }) {
198                possibilities.extend(x);
199            }
200
201            if let Ok((lhs, _)) = lambda_type.split() {
202                let e = PossibleExpr::new_owned(LambdaExpr::Lambda(LambdaExprRef(0), lhs.clone()));
203                possibilities.push(e);
204            }
205        }
206        possibilities.extend(context.variables(lambda_type).map(PossibleExpr::new_owned));
207        possibilities.extend(
208            context
209                .applications(lambda_type)
210                .map(|(subformula, argument)| PossibleExpr::new_application(subformula, argument)),
211        );
212
213        possibilities
214    }
215
216    pub(super) fn possiblities_fixed_children<'a>(
217        &'a self,
218        lambda_type: &LambdaType,
219        arguments: &[LambdaType],
220        var_type: Option<&LambdaType>,
221        context: &Context,
222    ) -> Vec<Cow<'a, LambdaExpr<'src, T>>> {
223        let mut possibilities: Vec<Cow<'a, LambdaExpr<'src, T>>> = self
224            .expressions
225            .get(lambda_type)
226            .map(|x| {
227                x.get(arguments)
228                    .map(|x| x.iter().map(Cow::Borrowed).collect::<Vec<_>>())
229                    .unwrap_or_default()
230            })
231            .unwrap_or_default();
232
233        if arguments.len() == 2
234            && let Ok((arg_type, return_type)) = arguments.first().unwrap().split()
235            && return_type == lambda_type
236            && arg_type == arguments.last().unwrap()
237        {
238            possibilities.push(Cow::Owned(LambdaExpr::Application {
239                subformula: LambdaExprRef(0),
240                argument: LambdaExprRef(0),
241            }));
242        } else if arguments.len() == 1
243            && let Ok((lhs, rhs)) = lambda_type.split()
244            && rhs == arguments.first().unwrap()
245        {
246            possibilities.push(Cow::Owned(LambdaExpr::Lambda(
247                LambdaExprRef(0),
248                lhs.clone(),
249            )));
250        } else if arguments.is_empty() {
251            possibilities.extend(context.variables(lambda_type).map(Cow::Owned));
252        }
253
254        possibilities.retain(|x| x.var_type() == var_type);
255
256        possibilities
257    }
258}