1use serde::{Deserialize, Deserializer, Serialize};
2
3use crate::{
4 lambda::{FreeVar, LambdaExpr, LambdaExprRef, RootedLambdaPool, types::LambdaType},
5 language::{
6 ActorOrEvent, BinOp, Expr, MonOp,
7 lambda_implementation::{AssociativityData, add_parenthesis_for_bin_op},
8 },
9};
10
11use crate::language::lambda_implementation::VarContext;
12
13impl Serialize for LambdaType {
14 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
15 where
16 S: serde::Serializer,
17 {
18 serializer.serialize_str(self.to_string().as_str())
19 }
20}
21
22impl<'de> Deserialize<'de> for LambdaType {
23 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
24 where
25 D: Deserializer<'de>,
26 {
27 let s = String::deserialize(deserializer)?;
28 LambdaType::from_string(&s).map_err(serde::de::Error::custom)
29 }
30}
31impl<'src> Serialize for RootedLambdaPool<'src, Expr<'src>> {
32 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
33 where
34 S: serde::Serializer,
35 {
36 serializer.serialize_str(self.to_string().as_str())
37 }
38}
39impl<'de, 'a> Deserialize<'de> for RootedLambdaPool<'a, Expr<'a>>
40where
41 'de: 'a,
42{
43 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
44 where
45 D: Deserializer<'de>,
46 {
47 let s = <&'de str>::deserialize(deserializer)?;
48 RootedLambdaPool::parse(s).map_err(serde::de::Error::custom)
49 }
50}
51
52impl RootedLambdaPool<'_, Expr<'_>> {
53 pub(super) fn tokens<'a, 'b: 'a>(
54 &'a self,
55 expr: LambdaExprRef,
56 c: VarContext,
57 v: &mut Vec<Token<'a>>,
58 parent_is_app: bool,
59 ) -> AssociativityData {
60 match self.get(expr) {
61 LambdaExpr::Lambda(child, lambda_type) => {
62 let (c, var) = c.inc_depth(lambda_type);
63 v.push(Token::Lambda {
64 t: lambda_type,
65 var: TokenVar::Bound(var),
66 });
67
68 self.tokens(*child, c, v, false);
69 AssociativityData::Lambda
70 }
71 LambdaExpr::BoundVariable(bvar, lambda_type) => {
72 v.push(Token::Var(TokenVar::Bound(
73 c.lambda_var(*bvar, lambda_type),
74 )));
75 AssociativityData::Monop
76 }
77 LambdaExpr::FreeVariable(fvar, t) => {
78 v.push(Token::Var(TokenVar::Free {
79 label: fvar.to_string(),
80 t,
81 anon: match fvar {
82 FreeVar::Named(_) => false,
83 FreeVar::Anonymous(_) => true,
84 },
85 }));
86 AssociativityData::Monop
87 }
88
89 LambdaExpr::Application {
90 subformula,
91 argument,
92 } => {
93 let mut new_v = vec![];
94
95 match self.tokens(*subformula, c.clone(), &mut new_v, true) {
96 AssociativityData::Binom(_) | AssociativityData::Lambda => {
97 v.push(Token::OpenDelim);
98 v.extend(new_v);
99 v.push(Token::CloseDelim);
100 v.push(Token::OpenDelim);
101 }
102 AssociativityData::Monop => {
103 v.extend(new_v);
104 v.push(Token::OpenDelim);
105 }
106 AssociativityData::App => {
107 v.extend(new_v);
108 }
109 }
110 self.tokens(*argument, c.clone(), v, false);
111
112 if parent_is_app {
113 v.push(Token::ArgSep);
114 } else {
115 v.push(Token::CloseDelim);
116 }
117 AssociativityData::App
118 }
119 LambdaExpr::LanguageOfThoughtExpr(x) => match x {
120 Expr::Quantifier {
121 quantifier,
122 var_type,
123 restrictor,
124 subformula,
125 } => {
126 let (c, var_string) = c.inc_depth_q(*var_type);
127
128 v.push(Token::Quantifier {
129 q: quantifier.to_string(),
130 t: match var_type {
131 ActorOrEvent::Actor => LambdaType::a(),
132 ActorOrEvent::Event => LambdaType::e(),
133 },
134 var: TokenVar::Bound(var_string),
135 });
136 v.push(Token::OpenDelim);
137 self.tokens(LambdaExprRef(restrictor.0), c.clone(), v, false);
138 v.push(Token::ArgSep);
139 self.tokens(LambdaExprRef(subformula.0), c, v, false);
140 v.push(Token::CloseDelim);
141 AssociativityData::Monop
142 }
143 Expr::Unary(MonOp::Iota(var_type), subformula) => {
144 let (c, var_string) = c.inc_depth_q(*var_type);
145
146 v.push(Token::Iota {
147 t: match var_type {
148 ActorOrEvent::Actor => LambdaType::a(),
149 ActorOrEvent::Event => LambdaType::e(),
150 },
151 var: TokenVar::Bound(var_string),
152 });
153 v.push(Token::OpenDelim);
154 self.tokens(LambdaExprRef(subformula.0), c, v, false);
155 v.push(Token::CloseDelim);
156 AssociativityData::Monop
157 }
158 Expr::Variable(variable) => {
159 v.push(Token::Var(TokenVar::Bound(c.lambda_var(
160 variable.id() as usize,
161 variable.as_lambda_type(),
162 ))));
163 AssociativityData::Monop
164 }
165 Expr::Actor(a) => {
166 v.push(Token::Actor(a.to_string()));
167 AssociativityData::Monop
168 }
169 Expr::Event(e) => {
170 v.push(Token::Event(e.to_string()));
171 AssociativityData::Monop
172 }
173 Expr::Binary(bin_op, x, y) => match bin_op {
174 BinOp::AgentOf | BinOp::PatientOf => {
175 v.push(Token::Func(bin_op.to_string()));
176 v.push(Token::OpenDelim);
177 self.tokens(LambdaExprRef(x.0), c.clone(), v, false);
178 v.push(Token::ArgSep);
179 self.tokens(LambdaExprRef(y.0), c, v, false);
180 v.push(Token::CloseDelim);
181 AssociativityData::Monop
182 }
183
184 BinOp::And | BinOp::Or => {
185 let mut x_v = vec![];
186 let x_a = self.tokens(LambdaExprRef(x.0), c.clone(), &mut x_v, false);
187 let mut y_v = vec![];
188 let y_a = self.tokens(LambdaExprRef(y.0), c.clone(), &mut y_v, false);
189
190 if add_parenthesis_for_bin_op(*bin_op, x_a) {
191 v.push(Token::OpenDelim);
192 v.extend(x_v);
193 v.push(Token::CloseDelim);
194 } else {
195 v.extend(x_v);
196 }
197 v.push(Token::Func(bin_op.to_string()));
198 if add_parenthesis_for_bin_op(*bin_op, y_a) {
199 v.push(Token::OpenDelim);
200 v.extend(y_v);
201 v.push(Token::CloseDelim);
202 } else {
203 v.extend(y_v);
204 }
205 AssociativityData::Binom(*bin_op)
206 }
207 },
208 Expr::Unary(mon_op, arg) => {
209 let s = match mon_op {
210 super::MonOp::Property(s, _) => s.to_string(),
211 super::MonOp::Iota(_) | super::MonOp::Not => mon_op.to_string(),
212 };
213 v.push(Token::Func(s));
214
215 let mut new_v = vec![];
216 let child_asso = self.tokens(LambdaExprRef(arg.0), c, &mut new_v, false);
217
218 if mon_op == &MonOp::Not {
219 match child_asso {
220 AssociativityData::Binom(BinOp::And | BinOp::Or) => {
221 v.push(Token::OpenDelim);
222 v.extend(new_v);
223 v.push(Token::CloseDelim);
224 }
225 AssociativityData::Binom(_)
226 | AssociativityData::Lambda
227 | AssociativityData::App
228 | AssociativityData::Monop => {
229 v.extend(new_v);
230 }
231 }
232 } else {
233 v.push(Token::OpenDelim);
234 v.extend(new_v);
235 v.push(Token::CloseDelim);
236 }
237
238 AssociativityData::Monop
239 }
240 Expr::Constant(constant) => {
241 let s = match constant {
242 super::Constant::Everyone
243 | super::Constant::EveryEvent
244 | super::Constant::Tautology
245 | super::Constant::Contradiction => constant.to_string(),
246 super::Constant::Property(s, _) => s.to_string(),
247 };
248 v.push(Token::Const(s));
249 AssociativityData::Monop
250 }
251 },
252 }
253 }
254}
255
256#[derive(Debug, Clone, Serialize)]
257pub(super) enum TokenVar<'a> {
258 Bound(String),
259 Free {
260 label: String,
261 t: &'a LambdaType,
262 anon: bool,
263 },
264}
265
266#[derive(Debug, Clone, Serialize)]
267pub(super) enum Token<'a> {
268 Lambda {
269 t: &'a LambdaType,
270 var: TokenVar<'a>,
271 },
272 Var(TokenVar<'a>),
273 Actor(String),
274 Event(String),
275 Func(String),
276 Const(String),
277 Iota {
278 t: &'a LambdaType,
279 var: TokenVar<'a>,
280 },
281 Quantifier {
282 q: String,
283 var: TokenVar<'a>,
284 t: &'a LambdaType,
285 },
286 OpenDelim,
287 ArgSep,
288 CloseDelim,
289}
290
291pub struct MathModeExpression<'a>(Vec<Token<'a>>);
294
295impl<'src> RootedLambdaPool<'src, Expr<'src>> {
296 #[must_use]
298 pub fn for_document(&self) -> MathModeExpression<'_> {
299 let mut v: Vec<Token> = vec![];
300 self.tokens(self.root, VarContext::default(), &mut v, false);
301 MathModeExpression(v)
302 }
303}
304
305impl Serialize for MathModeExpression<'_> {
306 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
307 where
308 S: serde::Serializer,
309 {
310 self.0.serialize(serializer)
311 }
312}
313
314#[cfg(test)]
315mod test {
316
317 use crate::lambda::{RootedLambdaPool, types::LambdaType};
318
319 #[test]
320 fn type_serializing() -> anyhow::Result<()> {
321 for s in ["a", "<a,t>", "<<e,<e,<<a,t>,t>>>, t>"] {
322 let t = LambdaType::from_string(s)?;
323 let t_str = serde_json::to_string(&t)?;
324 let t_json: LambdaType = serde_json::from_str(t_str.as_str())?;
325 assert_eq!(t, t_json);
326 }
327
328 Ok(())
329 }
330
331 #[test]
332 fn serializing() -> anyhow::Result<()> {
333 for (statement, json) in [
334 (
335 "~(AgentOf(a_John,e_0))",
336 "[{\"Func\":\"~\"},{\"Func\":\"AgentOf\"},\"OpenDelim\",{\"Actor\":\"John\"},\"ArgSep\",{\"Event\":\"0\"},\"CloseDelim\"]",
337 ),
338 (
339 "(pa_Red(a_John) & ~(pa_Red(a_Mary)))",
340 "[{\"Func\":\"Red\"},\"OpenDelim\",{\"Actor\":\"John\"},\"CloseDelim\",{\"Func\":\"&\"},{\"Func\":\"~\"},{\"Func\":\"Red\"},\"OpenDelim\",{\"Actor\":\"Mary\"},\"CloseDelim\"]",
341 ),
342 (
343 "every(x,all_a,pa_Blue(x))",
344 "[{\"Quantifier\":{\"q\":\"every\",\"var\":{\"Bound\":\"x\"},\"t\":\"a\"}},\"OpenDelim\",{\"Const\":\"all_a\"},\"ArgSep\",{\"Func\":\"Blue\"},\"OpenDelim\",{\"Var\":{\"Bound\":\"x\"}},\"CloseDelim\",\"CloseDelim\"]",
345 ),
346 (
347 "every(x,pa_Blue,pa_Blue(x))",
348 "[{\"Quantifier\":{\"q\":\"every\",\"var\":{\"Bound\":\"x\"},\"t\":\"a\"}},\"OpenDelim\",{\"Const\":\"Blue\"},\"ArgSep\",{\"Func\":\"Blue\"},\"OpenDelim\",{\"Var\":{\"Bound\":\"x\"}},\"CloseDelim\",\"CloseDelim\"]",
349 ),
350 (
351 "every(x,pa_5,pa_10(a_59))",
352 "[{\"Quantifier\":{\"q\":\"every\",\"var\":{\"Bound\":\"x\"},\"t\":\"a\"}},\"OpenDelim\",{\"Const\":\"5\"},\"ArgSep\",{\"Func\":\"10\"},\"OpenDelim\",{\"Actor\":\"59\"},\"CloseDelim\",\"CloseDelim\"]",
353 ),
354 (
355 "every_e(x,all_e,PatientOf(a_Mary,x))",
356 "[{\"Quantifier\":{\"q\":\"every\",\"var\":{\"Bound\":\"x\"},\"t\":\"e\"}},\"OpenDelim\",{\"Const\":\"all_e\"},\"ArgSep\",{\"Func\":\"PatientOf\"},\"OpenDelim\",{\"Actor\":\"Mary\"},\"ArgSep\",{\"Var\":{\"Bound\":\"x\"}},\"CloseDelim\",\"CloseDelim\"]",
357 ),
358 (
359 "(cool#<a,t>)(a_John)",
360 "[{\"Var\":{\"Free\":{\"label\":\"cool\",\"t\":\"<a,t>\",\"anon\":false}}},\"OpenDelim\",{\"Actor\":\"John\"},\"CloseDelim\"]",
361 ),
362 (
363 "(bad#<a,t>)(man#a)",
364 "[{\"Var\":{\"Free\":{\"label\":\"bad\",\"t\":\"<a,t>\",\"anon\":false}}},\"OpenDelim\",{\"Var\":{\"Free\":{\"label\":\"man\",\"t\":\"a\",\"anon\":false}}},\"CloseDelim\"]",
365 ),
366 (
367 "((loves#<a,<a,t>>)(a_mary))(a_john)",
368 "[{\"Var\":{\"Free\":{\"label\":\"loves\",\"t\":\"<a,<a,t>>\",\"anon\":false}}},\"OpenDelim\",{\"Actor\":\"mary\"},\"ArgSep\",{\"Actor\":\"john\"},\"CloseDelim\"]",
369 ),
370 (
371 "True | (True & False)",
372 "[{\"Const\":\"True\"},{\"Func\":\"|\"},\"OpenDelim\",{\"Const\":\"True\"},{\"Func\":\"&\"},{\"Const\":\"False\"},\"CloseDelim\"]",
373 ),
374 (
375 "(True | True) & False",
376 "[\"OpenDelim\",{\"Const\":\"True\"},{\"Func\":\"|\"},{\"Const\":\"True\"},\"CloseDelim\",{\"Func\":\"&\"},{\"Const\":\"False\"}]",
377 ),
378 (
379 "lambda a x (lambda a y (likes#<a,<a,t>>(x))(y))",
380 "[{\"Lambda\":{\"t\":\"a\",\"var\":{\"Bound\":\"x\"}}},{\"Lambda\":{\"t\":\"a\",\"var\":{\"Bound\":\"y\"}}},{\"Var\":{\"Free\":{\"label\":\"likes\",\"t\":\"<a,<a,t>>\",\"anon\":false}}},\"OpenDelim\",{\"Var\":{\"Bound\":\"x\"}},\"ArgSep\",{\"Var\":{\"Bound\":\"y\"}},\"CloseDelim\"]",
381 ),
382 (
383 "lambda <a,t> P iota(x, P(x))",
384 "[{\"Lambda\":{\"t\":\"<a,t>\",\"var\":{\"Bound\":\"P\"}}},{\"Iota\":{\"t\":\"a\",\"var\":{\"Bound\":\"x\"}}},\"OpenDelim\",{\"Var\":{\"Bound\":\"P\"}},\"OpenDelim\",{\"Var\":{\"Bound\":\"x\"}},\"CloseDelim\",\"CloseDelim\"]",
385 ),
386 ] {
387 let expression = RootedLambdaPool::parse(statement)?;
388 assert_eq!(json, serde_json::to_string(&expression.for_document())?);
389 }
390
391 Ok(())
392 }
393}