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