biscuit_auth/datalog/
expression.rs

1/*
2 * Copyright (c) 2019 Geoffroy Couprie <contact@geoffroycouprie.com> and Contributors to the Eclipse Foundation.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5use crate::{builder, error};
6
7use super::{MapKey, SymbolIndex, Term};
8use super::{SymbolTable, TemporarySymbolTable};
9use regex::Regex;
10use std::sync::Arc;
11use std::{
12    collections::{HashMap, HashSet},
13    convert::TryFrom,
14};
15
16#[derive(Clone)]
17pub struct ExternFunc(
18    pub  Arc<
19        dyn Fn(builder::Term, Option<builder::Term>) -> Result<builder::Term, String> + Send + Sync,
20    >,
21);
22
23impl std::fmt::Debug for ExternFunc {
24    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25        write!(f, "<function>")
26    }
27}
28
29impl ExternFunc {
30    pub fn new(
31        f: Arc<
32            dyn Fn(builder::Term, Option<builder::Term>) -> Result<builder::Term, String>
33                + Send
34                + Sync,
35        >,
36    ) -> Self {
37        Self(f)
38    }
39
40    pub fn call(
41        &self,
42        symbols: &mut TemporarySymbolTable,
43        name: &str,
44        left: Term,
45        right: Option<Term>,
46    ) -> Result<Term, error::Expression> {
47        let left = builder::Term::from_datalog(left, symbols)?;
48        let right = right
49            .map(|right| builder::Term::from_datalog(right, symbols))
50            .transpose()?;
51        match self.0(left, right) {
52            Ok(t) => Ok(t.to_datalog(symbols)),
53            Err(e) => Err(error::Expression::ExternEvalError(name.to_string(), e)),
54        }
55    }
56}
57
58#[derive(Debug, Clone, PartialEq, Hash, Eq)]
59pub struct Expression {
60    pub ops: Vec<Op>,
61}
62
63#[derive(Debug, Clone, PartialEq, Hash, Eq)]
64pub enum Op {
65    Value(Term),
66    Unary(Unary),
67    Binary(Binary),
68    Closure(Vec<u32>, Vec<Op>),
69}
70
71/// Unary operation code
72#[derive(Debug, Clone, PartialEq, Hash, Eq)]
73pub enum Unary {
74    Negate,
75    Parens,
76    Length,
77    TypeOf,
78    Ffi(SymbolIndex),
79}
80
81impl Unary {
82    fn evaluate(
83        &self,
84        value: Term,
85        symbols: &mut TemporarySymbolTable,
86        extern_funcs: &HashMap<String, ExternFunc>,
87    ) -> Result<Term, error::Expression> {
88        match (self, value) {
89            (Unary::Negate, Term::Bool(b)) => Ok(Term::Bool(!b)),
90            (Unary::Parens, i) => Ok(i),
91            (Unary::Length, Term::Str(i)) => symbols
92                .get_symbol(i)
93                .map(|s| Term::Integer(s.len() as i64))
94                .ok_or(error::Expression::UnknownSymbol(i)),
95            (Unary::Length, Term::Bytes(s)) => Ok(Term::Integer(s.len() as i64)),
96            (Unary::Length, Term::Set(s)) => Ok(Term::Integer(s.len() as i64)),
97            (Unary::Length, Term::Array(a)) => Ok(Term::Integer(a.len() as i64)),
98            (Unary::Length, Term::Map(m)) => Ok(Term::Integer(m.len() as i64)),
99            (Unary::TypeOf, t) => {
100                let type_string = match t {
101                    Term::Variable(_) => return Err(error::Expression::InvalidType),
102                    Term::Integer(_) => "integer",
103                    Term::Str(_) => "string",
104                    Term::Date(_) => "date",
105                    Term::Bytes(_) => "bytes",
106                    Term::Bool(_) => "bool",
107                    Term::Set(_) => "set",
108                    Term::Null => "null",
109                    Term::Array(_) => "array",
110                    Term::Map(_) => "map",
111                };
112                let sym = symbols.insert(type_string);
113                Ok(Term::Str(sym))
114            }
115            (Unary::Ffi(name), i) => {
116                let name = symbols
117                    .get_symbol(*name)
118                    .ok_or(error::Expression::UnknownSymbol(*name))?
119                    .to_owned();
120                let fun = extern_funcs
121                    .get(&name)
122                    .ok_or(error::Expression::UndefinedExtern(name.to_owned()))?;
123                fun.call(symbols, &name, i, None)
124            }
125            _ => {
126                //println!("unexpected value type on the stack");
127                Err(error::Expression::InvalidType)
128            }
129        }
130    }
131
132    pub fn print(&self, value: String, symbols: &SymbolTable) -> String {
133        match self {
134            Unary::Negate => format!("!{}", value),
135            Unary::Parens => format!("({})", value),
136            Unary::Length => format!("{}.length()", value),
137            Unary::TypeOf => format!("{}.type()", value),
138            Unary::Ffi(name) => {
139                format!("{value}.extern::{}()", symbols.print_symbol_default(*name))
140            }
141        }
142    }
143}
144
145/// Binary operation code
146#[derive(Debug, Clone, PartialEq, Hash, Eq)]
147pub enum Binary {
148    LessThan,
149    GreaterThan,
150    LessOrEqual,
151    GreaterOrEqual,
152    Equal,
153    Contains,
154    Prefix,
155    Suffix,
156    Regex,
157    Add,
158    Sub,
159    Mul,
160    Div,
161    And,
162    Or,
163    Intersection,
164    Union,
165    BitwiseAnd,
166    BitwiseOr,
167    BitwiseXor,
168    NotEqual,
169    HeterogeneousEqual,
170    HeterogeneousNotEqual,
171    LazyAnd,
172    LazyOr,
173    All,
174    Any,
175    Get,
176    Ffi(SymbolIndex),
177    TryOr,
178}
179
180impl Binary {
181    fn evaluate_with_closure(
182        &self,
183        left: Term,
184        right: Vec<Op>,
185        params: &[u32],
186        values: &mut HashMap<u32, Term>,
187        symbols: &mut TemporarySymbolTable,
188        extern_func: &HashMap<String, ExternFunc>,
189    ) -> Result<Term, error::Expression> {
190        match (self, left, params) {
191            // try
192            (Binary::TryOr, fallback, []) => {
193                let e = Expression { ops: right.clone() };
194                match e.evaluate(values, symbols, extern_func) {
195                    Ok(v) => Ok(v),
196                    Err(_) => Ok(fallback),
197                }
198            }
199            // boolean
200            (Binary::LazyOr, Term::Bool(true), []) => Ok(Term::Bool(true)),
201            (Binary::LazyOr, Term::Bool(false), []) => {
202                let e = Expression { ops: right.clone() };
203                e.evaluate(values, symbols, extern_func)
204            }
205            (Binary::LazyAnd, Term::Bool(false), []) => Ok(Term::Bool(false)),
206            (Binary::LazyAnd, Term::Bool(true), []) => {
207                let e = Expression { ops: right.clone() };
208                e.evaluate(values, symbols, extern_func)
209            }
210
211            // set
212            (Binary::All, Term::Set(set_values), [param]) => {
213                for value in set_values.iter() {
214                    values.insert(*param, value.clone());
215                    let e = Expression { ops: right.clone() };
216                    let result = e.evaluate(values, symbols, extern_func);
217                    values.remove(param);
218                    match result? {
219                        Term::Bool(true) => {}
220                        Term::Bool(false) => return Ok(Term::Bool(false)),
221                        _ => return Err(error::Expression::InvalidType),
222                    };
223                }
224                Ok(Term::Bool(true))
225            }
226            (Binary::Any, Term::Set(set_values), [param]) => {
227                for value in set_values.iter() {
228                    values.insert(*param, value.clone());
229                    let e = Expression { ops: right.clone() };
230                    let result = e.evaluate(values, symbols, extern_func);
231                    values.remove(param);
232                    match result? {
233                        Term::Bool(false) => {}
234                        Term::Bool(true) => return Ok(Term::Bool(true)),
235                        _ => return Err(error::Expression::InvalidType),
236                    };
237                }
238                Ok(Term::Bool(false))
239            }
240
241            // array
242            (Binary::All, Term::Array(array), [param]) => {
243                for value in array.iter() {
244                    values.insert(*param, value.clone());
245                    let e = Expression { ops: right.clone() };
246                    let result = e.evaluate(values, symbols, extern_func);
247                    values.remove(param);
248                    match result? {
249                        Term::Bool(true) => {}
250                        Term::Bool(false) => return Ok(Term::Bool(false)),
251                        _ => return Err(error::Expression::InvalidType),
252                    };
253                }
254                Ok(Term::Bool(true))
255            }
256            (Binary::Any, Term::Array(array), [param]) => {
257                for value in array.iter() {
258                    values.insert(*param, value.clone());
259                    let e = Expression { ops: right.clone() };
260                    let result = e.evaluate(values, symbols, extern_func);
261                    values.remove(param);
262                    match result? {
263                        Term::Bool(false) => {}
264                        Term::Bool(true) => return Ok(Term::Bool(true)),
265                        _ => return Err(error::Expression::InvalidType),
266                    };
267                }
268                Ok(Term::Bool(false))
269            }
270
271            //map
272            (Binary::All, Term::Map(map), [param]) => {
273                for (key, value) in map.iter() {
274                    let key = match key {
275                        MapKey::Integer(i) => Term::Integer(*i),
276                        MapKey::Str(i) => Term::Str(*i),
277                    };
278                    values.insert(*param, Term::Array(vec![key, value.clone()]));
279
280                    let e = Expression { ops: right.clone() };
281                    let result = e.evaluate(values, symbols, extern_func);
282                    values.remove(param);
283                    match result? {
284                        Term::Bool(true) => {}
285                        Term::Bool(false) => return Ok(Term::Bool(false)),
286                        _ => return Err(error::Expression::InvalidType),
287                    };
288                }
289                Ok(Term::Bool(true))
290            }
291            (Binary::Any, Term::Map(map), [param]) => {
292                for (key, value) in map.iter() {
293                    let key = match key {
294                        MapKey::Integer(i) => Term::Integer(*i),
295                        MapKey::Str(i) => Term::Str(*i),
296                    };
297                    values.insert(*param, Term::Array(vec![key, value.clone()]));
298
299                    let e = Expression { ops: right.clone() };
300                    let result = e.evaluate(values, symbols, extern_func);
301                    values.remove(param);
302                    match result? {
303                        Term::Bool(false) => {}
304                        Term::Bool(true) => return Ok(Term::Bool(true)),
305                        _ => return Err(error::Expression::InvalidType),
306                    };
307                }
308                Ok(Term::Bool(false))
309            }
310            (_, _, _) => Err(error::Expression::InvalidType),
311        }
312    }
313    fn evaluate(
314        &self,
315        left: Term,
316        right: Term,
317        symbols: &mut TemporarySymbolTable,
318        extern_funcs: &HashMap<String, ExternFunc>,
319    ) -> Result<Term, error::Expression> {
320        match (self, left, right) {
321            // integer
322            (Binary::LessThan, Term::Integer(i), Term::Integer(j)) => Ok(Term::Bool(i < j)),
323            (Binary::GreaterThan, Term::Integer(i), Term::Integer(j)) => Ok(Term::Bool(i > j)),
324            (Binary::LessOrEqual, Term::Integer(i), Term::Integer(j)) => Ok(Term::Bool(i <= j)),
325            (Binary::GreaterOrEqual, Term::Integer(i), Term::Integer(j)) => Ok(Term::Bool(i >= j)),
326            (Binary::Equal | Binary::HeterogeneousEqual, Term::Integer(i), Term::Integer(j)) => {
327                Ok(Term::Bool(i == j))
328            }
329            (
330                Binary::NotEqual | Binary::HeterogeneousNotEqual,
331                Term::Integer(i),
332                Term::Integer(j),
333            ) => Ok(Term::Bool(i != j)),
334            (Binary::Add, Term::Integer(i), Term::Integer(j)) => i
335                .checked_add(j)
336                .map(Term::Integer)
337                .ok_or(error::Expression::Overflow),
338            (Binary::Sub, Term::Integer(i), Term::Integer(j)) => i
339                .checked_sub(j)
340                .map(Term::Integer)
341                .ok_or(error::Expression::Overflow),
342            (Binary::Mul, Term::Integer(i), Term::Integer(j)) => i
343                .checked_mul(j)
344                .map(Term::Integer)
345                .ok_or(error::Expression::Overflow),
346            (Binary::Div, Term::Integer(i), Term::Integer(j)) => i
347                .checked_div(j)
348                .map(Term::Integer)
349                .ok_or(error::Expression::DivideByZero),
350            (Binary::BitwiseAnd, Term::Integer(i), Term::Integer(j)) => Ok(Term::Integer(i & j)),
351            (Binary::BitwiseOr, Term::Integer(i), Term::Integer(j)) => Ok(Term::Integer(i | j)),
352            (Binary::BitwiseXor, Term::Integer(i), Term::Integer(j)) => Ok(Term::Integer(i ^ j)),
353
354            // string
355            (Binary::Prefix, Term::Str(s), Term::Str(pref)) => {
356                match (symbols.get_symbol(s), symbols.get_symbol(pref)) {
357                    (Some(s), Some(pref)) => Ok(Term::Bool(s.starts_with(pref))),
358                    (Some(_), None) => Err(error::Expression::UnknownSymbol(pref)),
359                    _ => Err(error::Expression::UnknownSymbol(s)),
360                }
361            }
362            (Binary::Suffix, Term::Str(s), Term::Str(suff)) => {
363                match (symbols.get_symbol(s), symbols.get_symbol(suff)) {
364                    (Some(s), Some(suff)) => Ok(Term::Bool(s.ends_with(suff))),
365                    (Some(_), None) => Err(error::Expression::UnknownSymbol(suff)),
366                    _ => Err(error::Expression::UnknownSymbol(s)),
367                }
368            }
369            (Binary::Regex, Term::Str(s), Term::Str(r)) => {
370                match (symbols.get_symbol(s), symbols.get_symbol(r)) {
371                    (Some(s), Some(r)) => Ok(Term::Bool(
372                        Regex::new(r).map(|re| re.is_match(s)).unwrap_or(false),
373                    )),
374                    (Some(_), None) => Err(error::Expression::UnknownSymbol(r)),
375                    _ => Err(error::Expression::UnknownSymbol(s)),
376                }
377            }
378            (Binary::Contains, Term::Str(s), Term::Str(pattern)) => {
379                match (symbols.get_symbol(s), symbols.get_symbol(pattern)) {
380                    (Some(s), Some(pattern)) => Ok(Term::Bool(s.contains(pattern))),
381                    (Some(_), None) => Err(error::Expression::UnknownSymbol(pattern)),
382                    _ => Err(error::Expression::UnknownSymbol(s)),
383                }
384            }
385            (Binary::Add, Term::Str(s1), Term::Str(s2)) => {
386                match (symbols.get_symbol(s1), symbols.get_symbol(s2)) {
387                    (Some(s1), Some(s2)) => {
388                        let s = format!("{}{}", s1, s2);
389                        let sym = symbols.insert(&s);
390                        Ok(Term::Str(sym))
391                    }
392                    (Some(_), None) => Err(error::Expression::UnknownSymbol(s2)),
393                    _ => Err(error::Expression::UnknownSymbol(s1)),
394                }
395            }
396            (Binary::Equal | Binary::HeterogeneousEqual, Term::Str(i), Term::Str(j)) => {
397                Ok(Term::Bool(i == j))
398            }
399            (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Str(i), Term::Str(j)) => {
400                Ok(Term::Bool(i != j))
401            }
402
403            // date
404            (Binary::LessThan, Term::Date(i), Term::Date(j)) => Ok(Term::Bool(i < j)),
405            (Binary::GreaterThan, Term::Date(i), Term::Date(j)) => Ok(Term::Bool(i > j)),
406            (Binary::LessOrEqual, Term::Date(i), Term::Date(j)) => Ok(Term::Bool(i <= j)),
407            (Binary::GreaterOrEqual, Term::Date(i), Term::Date(j)) => Ok(Term::Bool(i >= j)),
408            (Binary::Equal | Binary::HeterogeneousEqual, Term::Date(i), Term::Date(j)) => {
409                Ok(Term::Bool(i == j))
410            }
411            (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Date(i), Term::Date(j)) => {
412                Ok(Term::Bool(i != j))
413            }
414
415            // symbol
416
417            // byte array
418            (Binary::Equal | Binary::HeterogeneousEqual, Term::Bytes(i), Term::Bytes(j)) => {
419                Ok(Term::Bool(i == j))
420            }
421            (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Bytes(i), Term::Bytes(j)) => {
422                Ok(Term::Bool(i != j))
423            }
424
425            // set
426            (Binary::Equal | Binary::HeterogeneousEqual, Term::Set(set), Term::Set(s)) => {
427                Ok(Term::Bool(set == s))
428            } // Strict equal support heterogeneous equal for Set to avoid introducing a breaking change
429            (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Set(set), Term::Set(s)) => {
430                Ok(Term::Bool(set != s))
431            } // Strict not equal support heterogeneous not equal for Set to avoid introducing a breaking change
432            (Binary::Intersection, Term::Set(set), Term::Set(s)) => {
433                Ok(Term::Set(set.intersection(&s).cloned().collect()))
434            }
435            (Binary::Union, Term::Set(set), Term::Set(s)) => {
436                Ok(Term::Set(set.union(&s).cloned().collect()))
437            }
438            (Binary::Contains, Term::Set(set), Term::Set(s)) => Ok(Term::Bool(set.is_superset(&s))),
439            (Binary::Contains, Term::Set(set), Term::Integer(i)) => {
440                Ok(Term::Bool(set.contains(&Term::Integer(i))))
441            }
442            (Binary::Contains, Term::Set(set), Term::Date(i)) => {
443                Ok(Term::Bool(set.contains(&Term::Date(i))))
444            }
445            (Binary::Contains, Term::Set(set), Term::Bool(i)) => {
446                Ok(Term::Bool(set.contains(&Term::Bool(i))))
447            }
448            (Binary::Contains, Term::Set(set), Term::Str(i)) => {
449                Ok(Term::Bool(set.contains(&Term::Str(i))))
450            }
451            (Binary::Contains, Term::Set(set), Term::Bytes(i)) => {
452                Ok(Term::Bool(set.contains(&Term::Bytes(i))))
453            }
454
455            // boolean
456            (Binary::And, Term::Bool(i), Term::Bool(j)) => Ok(Term::Bool(i & j)),
457            (Binary::Or, Term::Bool(i), Term::Bool(j)) => Ok(Term::Bool(i | j)),
458            (Binary::Equal | Binary::HeterogeneousEqual, Term::Bool(i), Term::Bool(j)) => {
459                Ok(Term::Bool(i == j))
460            }
461            (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Bool(i), Term::Bool(j)) => {
462                Ok(Term::Bool(i != j))
463            }
464
465            // null
466            (Binary::Equal | Binary::HeterogeneousEqual, Term::Null, Term::Null) => {
467                Ok(Term::Bool(true))
468            }
469            (Binary::HeterogeneousEqual, Term::Null, _) => Ok(Term::Bool(false)),
470            (Binary::HeterogeneousEqual, _, Term::Null) => Ok(Term::Bool(false)),
471            (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Null, Term::Null) => {
472                Ok(Term::Bool(false))
473            }
474            (Binary::HeterogeneousNotEqual, Term::Null, _) => Ok(Term::Bool(true)),
475            (Binary::HeterogeneousNotEqual, _, Term::Null) => Ok(Term::Bool(true)),
476
477            // array
478            (Binary::Equal | Binary::HeterogeneousEqual, Term::Array(i), Term::Array(j)) => {
479                Ok(Term::Bool(i == j))
480            }
481            (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Array(i), Term::Array(j)) => {
482                Ok(Term::Bool(i != j))
483            }
484            (Binary::Contains, Term::Array(i), j) => {
485                Ok(Term::Bool(i.iter().any(|elem| elem == &j)))
486            }
487            (Binary::Prefix, Term::Array(i), Term::Array(j)) => Ok(Term::Bool(i.starts_with(&j))),
488            (Binary::Suffix, Term::Array(i), Term::Array(j)) => Ok(Term::Bool(i.ends_with(&j))),
489            (Binary::Get, Term::Array(i), Term::Integer(index)) => Ok(TryFrom::try_from(index)
490                .ok()
491                .and_then(|index: usize| i.get(index).cloned())
492                .unwrap_or(Term::Null)),
493
494            // map
495            (Binary::Equal | Binary::HeterogeneousEqual, Term::Map(i), Term::Map(j)) => {
496                Ok(Term::Bool(i == j))
497            }
498            (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Map(i), Term::Map(j)) => {
499                Ok(Term::Bool(i != j))
500            }
501            (Binary::Contains, Term::Map(i), j) => {
502                Ok(Term::Bool(i.iter().any(|elem| match (elem.0, &j) {
503                    (super::MapKey::Integer(k), Term::Integer(l)) => k == l,
504                    (super::MapKey::Str(k), Term::Str(l)) => k == l,
505                    _ => false,
506                })))
507            }
508            (Binary::Get, Term::Map(m), Term::Integer(i)) => match m.get(&MapKey::Integer(i)) {
509                Some(term) => Ok(term.clone()),
510                None => Ok(Term::Null),
511            },
512            (Binary::Get, Term::Map(m), Term::Str(i)) => match m.get(&MapKey::Str(i)) {
513                Some(term) => Ok(term.clone()),
514                None => Ok(Term::Null),
515            },
516
517            // heterogeneous equals catch all
518            (Binary::HeterogeneousEqual, _, _) => Ok(Term::Bool(false)),
519            (Binary::HeterogeneousNotEqual, _, _) => Ok(Term::Bool(true)),
520
521            // FFI
522            (Binary::Ffi(name), left, right) => {
523                let name = symbols
524                    .get_symbol(*name)
525                    .ok_or(error::Expression::UnknownSymbol(*name))?
526                    .to_owned();
527                let fun = extern_funcs
528                    .get(&name)
529                    .ok_or(error::Expression::UndefinedExtern(name.to_owned()))?;
530                fun.call(symbols, &name, left, Some(right))
531            }
532
533            _ => {
534                //println!("unexpected value type on the stack");
535                Err(error::Expression::InvalidType)
536            }
537        }
538    }
539
540    pub fn print(&self, left: String, right: String, symbols: &SymbolTable) -> String {
541        match self {
542            Binary::LessThan => format!("{} < {}", left, right),
543            Binary::GreaterThan => format!("{} > {}", left, right),
544            Binary::LessOrEqual => format!("{} <= {}", left, right),
545            Binary::GreaterOrEqual => format!("{} >= {}", left, right),
546            Binary::Equal => format!("{} === {}", left, right),
547            Binary::HeterogeneousEqual => format!("{} == {}", left, right),
548            Binary::NotEqual => format!("{} !== {}", left, right),
549            Binary::HeterogeneousNotEqual => format!("{} != {}", left, right),
550            Binary::Contains => format!("{}.contains({})", left, right),
551            Binary::Prefix => format!("{}.starts_with({})", left, right),
552            Binary::Suffix => format!("{}.ends_with({})", left, right),
553            Binary::Regex => format!("{}.matches({})", left, right),
554            Binary::Add => format!("{} + {}", left, right),
555            Binary::Sub => format!("{} - {}", left, right),
556            Binary::Mul => format!("{} * {}", left, right),
557            Binary::Div => format!("{} / {}", left, right),
558            Binary::And => format!("{} &&! {}", left, right),
559            Binary::Or => format!("{} ||! {}", left, right),
560            Binary::Intersection => format!("{}.intersection({})", left, right),
561            Binary::Union => format!("{}.union({})", left, right),
562            Binary::BitwiseAnd => format!("{} & {}", left, right),
563            Binary::BitwiseOr => format!("{} | {}", left, right),
564            Binary::BitwiseXor => format!("{} ^ {}", left, right),
565            Binary::LazyAnd => format!("{left} && {right}"),
566            Binary::LazyOr => format!("{left} || {right}"),
567            Binary::All => format!("{left}.all({right})"),
568            Binary::Any => format!("{left}.any({right})"),
569            Binary::Get => format!("{left}.get({right})"),
570            Binary::Ffi(name) => format!(
571                "{left}.extern::{}({right})",
572                symbols.print_symbol_default(*name)
573            ),
574            Binary::TryOr => format!("{left}.try_or({right})"),
575        }
576    }
577}
578
579#[derive(Clone, Debug)]
580enum StackElem {
581    Closure(Vec<u32>, Vec<Op>),
582    Term(Term),
583}
584
585impl Expression {
586    pub fn evaluate(
587        &self,
588        values: &HashMap<u32, Term>,
589        symbols: &mut TemporarySymbolTable,
590        extern_funcs: &HashMap<String, ExternFunc>,
591    ) -> Result<Term, error::Expression> {
592        let mut stack: Vec<StackElem> = Vec::new();
593
594        for op in self.ops.iter() {
595            // println!("op: {:?}\t| stack: {:?}", op, stack);
596
597            match op {
598                Op::Value(Term::Variable(i)) => match values.get(i) {
599                    Some(term) => stack.push(StackElem::Term(term.clone())),
600                    None => {
601                        //println!("unknown variable {}", i);
602                        return Err(error::Expression::UnknownVariable(*i));
603                    }
604                },
605                Op::Value(term) => stack.push(StackElem::Term(term.clone())),
606                Op::Unary(unary) => {
607                    match stack.pop() {
608                        Some(StackElem::Term(term)) => stack.push(StackElem::Term(
609                            unary.evaluate(term, symbols, extern_funcs)?,
610                        )),
611                        _ => {
612                            return Err(error::Expression::InvalidStack);
613                        }
614                    }
615                }
616                Op::Binary(binary) => match (stack.pop(), stack.pop()) {
617                    (Some(StackElem::Term(right_term)), Some(StackElem::Term(left_term))) => stack
618                        .push(StackElem::Term(binary.evaluate(
619                            left_term,
620                            right_term,
621                            symbols,
622                            extern_funcs,
623                        )?)),
624                    (
625                        Some(StackElem::Closure(params, right_ops)),
626                        Some(StackElem::Term(left_term)),
627                    ) => {
628                        if values
629                            .keys()
630                            .collect::<HashSet<_>>()
631                            .intersection(&params.iter().collect())
632                            .next()
633                            .is_some()
634                        {
635                            return Err(error::Expression::ShadowedVariable);
636                        }
637                        let mut values = values.clone();
638                        stack.push(StackElem::Term(binary.evaluate_with_closure(
639                            left_term,
640                            right_ops,
641                            &params,
642                            &mut values,
643                            symbols,
644                            extern_funcs,
645                        )?))
646                    }
647                    (
648                        Some(StackElem::Term(right_term)),
649                        Some(StackElem::Closure(params, left_ops)),
650                    ) => {
651                        if values
652                            .keys()
653                            .collect::<HashSet<_>>()
654                            .intersection(&params.iter().collect())
655                            .next()
656                            .is_some()
657                        {
658                            return Err(error::Expression::ShadowedVariable);
659                        }
660                        let mut values = values.clone();
661                        stack.push(StackElem::Term(binary.evaluate_with_closure(
662                            right_term,
663                            left_ops,
664                            &params,
665                            &mut values,
666                            symbols,
667                            extern_funcs,
668                        )?))
669                    }
670
671                    _ => {
672                        return Err(error::Expression::InvalidStack);
673                    }
674                },
675                Op::Closure(params, ops) => {
676                    stack.push(StackElem::Closure(params.clone(), ops.clone()));
677                }
678            }
679        }
680
681        if stack.len() == 1 {
682            match stack.remove(0) {
683                StackElem::Term(t) => Ok(t),
684                _ => Err(error::Expression::InvalidStack),
685            }
686        } else {
687            Err(error::Expression::InvalidStack)
688        }
689    }
690
691    pub fn print(&self, symbols: &SymbolTable) -> Option<String> {
692        let mut stack: Vec<String> = Vec::new();
693
694        for op in self.ops.iter() {
695            //println!("op: {:?}\t| stack: {:?}", op, stack);
696            match op {
697                Op::Value(i) => stack.push(symbols.print_term(i)),
698                Op::Unary(unary) => match stack.pop() {
699                    None => return None,
700                    Some(s) => stack.push(unary.print(s, symbols)),
701                },
702                Op::Binary(binary) => match (stack.pop(), stack.pop()) {
703                    (Some(right), Some(left)) => stack.push(binary.print(left, right, symbols)),
704                    _ => return None,
705                },
706                Op::Closure(params, ops) => {
707                    let exp_body = Expression { ops: ops.clone() };
708                    let body = match exp_body.print(symbols) {
709                        Some(c) => c,
710                        _ => return None,
711                    };
712
713                    if params.is_empty() {
714                        stack.push(body);
715                    } else {
716                        let param_group = params
717                            .iter()
718                            .map(|s| symbols.print_term(&Term::Variable(*s)))
719                            .collect::<Vec<_>>()
720                            .join(", ");
721                        stack.push(format!("{param_group} -> {body}"));
722                    }
723                }
724            }
725        }
726
727        if stack.len() == 1 {
728            Some(stack.remove(0))
729        } else {
730            None
731        }
732    }
733}
734
735#[cfg(test)]
736mod tests {
737    use std::collections::{BTreeMap, BTreeSet};
738
739    use super::*;
740    use crate::datalog::{MapKey, SymbolTable, TemporarySymbolTable};
741
742    #[test]
743    fn negate() {
744        let mut symbols = SymbolTable::new();
745        symbols.insert("test1");
746        symbols.insert("test2");
747        symbols.insert("var1");
748        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
749
750        let ops = vec![
751            Op::Value(Term::Integer(1)),
752            Op::Value(Term::Variable(2)),
753            Op::Binary(Binary::LessThan),
754            Op::Unary(Unary::Parens),
755            Op::Unary(Unary::Negate),
756        ];
757
758        let values: HashMap<u32, Term> = [(2, Term::Integer(0))].iter().cloned().collect();
759
760        println!("ops: {:?}", ops);
761
762        let e = Expression { ops };
763        println!("print: {}", e.print(&symbols).unwrap());
764
765        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
766        assert_eq!(res, Ok(Term::Bool(true)));
767    }
768
769    #[test]
770    fn bitwise() {
771        for (op, v1, v2, expected) in [
772            (Binary::BitwiseAnd, 9, 10, 8),
773            (Binary::BitwiseAnd, 9, 1, 1),
774            (Binary::BitwiseAnd, 9, 0, 0),
775            (Binary::BitwiseOr, 1, 2, 3),
776            (Binary::BitwiseOr, 2, 2, 2),
777            (Binary::BitwiseOr, 2, 0, 2),
778            (Binary::BitwiseXor, 1, 0, 1),
779            (Binary::BitwiseXor, 1, 1, 0),
780        ] {
781            let symbols = SymbolTable::new();
782            let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
783
784            let ops = vec![
785                Op::Value(Term::Integer(v1)),
786                Op::Value(Term::Integer(v2)),
787                Op::Binary(op),
788            ];
789
790            println!("ops: {:?}", ops);
791
792            let e = Expression { ops };
793            println!("print: {}", e.print(&symbols).unwrap());
794
795            let res = e.evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default());
796            assert_eq!(res, Ok(Term::Integer(expected)));
797        }
798    }
799
800    #[test]
801    fn checked() {
802        let symbols = SymbolTable::new();
803        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
804        let ops = vec![
805            Op::Value(Term::Integer(1)),
806            Op::Value(Term::Integer(0)),
807            Op::Binary(Binary::Div),
808        ];
809
810        let values = HashMap::new();
811        let e = Expression { ops };
812        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
813        assert_eq!(res, Err(error::Expression::DivideByZero));
814
815        let ops = vec![
816            Op::Value(Term::Integer(1)),
817            Op::Value(Term::Integer(i64::MAX)),
818            Op::Binary(Binary::Add),
819        ];
820
821        let values = HashMap::new();
822        let e = Expression { ops };
823        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
824        assert_eq!(res, Err(error::Expression::Overflow));
825
826        let ops = vec![
827            Op::Value(Term::Integer(-10)),
828            Op::Value(Term::Integer(i64::MAX)),
829            Op::Binary(Binary::Sub),
830        ];
831
832        let values = HashMap::new();
833        let e = Expression { ops };
834        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
835        assert_eq!(res, Err(error::Expression::Overflow));
836
837        let ops = vec![
838            Op::Value(Term::Integer(2)),
839            Op::Value(Term::Integer(i64::MAX)),
840            Op::Binary(Binary::Mul),
841        ];
842
843        let values = HashMap::new();
844        let e = Expression { ops };
845        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
846        assert_eq!(res, Err(error::Expression::Overflow));
847    }
848
849    #[test]
850    fn printer() {
851        let mut symbols = SymbolTable::new();
852        symbols.insert("test1");
853        symbols.insert("test2");
854        symbols.insert("var1");
855
856        let ops1 = vec![
857            Op::Value(Term::Integer(-1)),
858            Op::Value(Term::Variable(1026)),
859            Op::Binary(Binary::LessThan),
860        ];
861
862        let ops2 = vec![
863            Op::Value(Term::Integer(1)),
864            Op::Value(Term::Integer(2)),
865            Op::Value(Term::Integer(3)),
866            Op::Binary(Binary::Add),
867            Op::Binary(Binary::LessThan),
868        ];
869
870        let ops3 = vec![
871            Op::Value(Term::Integer(1)),
872            Op::Value(Term::Integer(2)),
873            Op::Binary(Binary::Add),
874            Op::Value(Term::Integer(3)),
875            Op::Binary(Binary::LessThan),
876        ];
877
878        println!("ops1: {:?}", ops1);
879        println!("ops2: {:?}", ops2);
880        println!("ops3: {:?}", ops3);
881        let e1 = Expression { ops: ops1 };
882        let e2 = Expression { ops: ops2 };
883        let e3 = Expression { ops: ops3 };
884
885        assert_eq!(e1.print(&symbols).unwrap(), "-1 < $var1");
886
887        assert_eq!(e2.print(&symbols).unwrap(), "1 < 2 + 3");
888
889        assert_eq!(e3.print(&symbols).unwrap(), "1 + 2 < 3");
890        //panic!();
891    }
892
893    #[test]
894    fn null_equal() {
895        let symbols = SymbolTable::new();
896        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
897        let values: HashMap<u32, Term> = HashMap::new();
898        let operands = vec![Op::Value(Term::Null), Op::Value(Term::Null)];
899        let operators = vec![
900            Op::Binary(Binary::Equal),
901            Op::Binary(Binary::HeterogeneousEqual),
902        ];
903
904        for op in operators {
905            let mut ops = operands.clone();
906            ops.push(op);
907            println!("ops: {:?}", ops);
908
909            let e = Expression { ops };
910            println!("print: {}", e.print(&symbols).unwrap());
911
912            let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
913            assert_eq!(res, Ok(Term::Bool(true)));
914        }
915    }
916
917    #[test]
918    fn null_not_equal() {
919        let symbols = SymbolTable::new();
920        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
921        let values: HashMap<u32, Term> = HashMap::new();
922        let operands = vec![Op::Value(Term::Null), Op::Value(Term::Null)];
923        let operators = vec![
924            Op::Binary(Binary::NotEqual),
925            Op::Binary(Binary::HeterogeneousNotEqual),
926        ];
927
928        for op in operators {
929            let mut ops = operands.clone();
930            ops.push(op);
931            println!("ops: {:?}", ops);
932
933            let e = Expression { ops };
934            println!("print: {}", e.print(&symbols).unwrap());
935
936            let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
937            assert_eq!(res, Ok(Term::Bool(false)));
938        }
939    }
940
941    #[test]
942    fn null_heterogeneous() {
943        let symbols = SymbolTable::new();
944        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
945        let values: HashMap<u32, Term> = HashMap::new();
946        let operands = vec![Op::Value(Term::Null), Op::Value(Term::Integer(1))];
947        let operators = HashMap::from([
948            (Op::Binary(Binary::HeterogeneousNotEqual), true),
949            (Op::Binary(Binary::HeterogeneousEqual), false),
950        ]);
951
952        for (op, result) in operators {
953            let mut ops = operands.clone();
954            ops.push(op);
955            println!("ops: {:?}", ops);
956
957            let e = Expression { ops };
958            println!("print: {}", e.print(&symbols).unwrap());
959
960            let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
961            assert_eq!(res, Ok(Term::Bool(result)));
962        }
963    }
964
965    #[test]
966    fn equal_heterogeneous() {
967        let symbols = SymbolTable::new();
968        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
969        let values: HashMap<u32, Term> = HashMap::new();
970        let operands_samples = [
971            vec![Op::Value(Term::Bool(true)), Op::Value(Term::Integer(1))],
972            vec![Op::Value(Term::Bool(true)), Op::Value(Term::Str(1))],
973            vec![Op::Value(Term::Integer(1)), Op::Value(Term::Str(1))],
974            vec![
975                Op::Value(Term::Set(BTreeSet::from([Term::Integer(1)]))),
976                Op::Value(Term::Set(BTreeSet::from([Term::Str(1)]))),
977            ],
978            vec![
979                Op::Value(Term::Bytes(Vec::new())),
980                Op::Value(Term::Integer(1)),
981            ],
982            vec![
983                Op::Value(Term::Bytes(Vec::new())),
984                Op::Value(Term::Str(1025)),
985            ],
986            vec![Op::Value(Term::Date(12)), Op::Value(Term::Integer(1))],
987        ];
988        let operators = HashMap::from([
989            (Op::Binary(Binary::HeterogeneousNotEqual), true),
990            (Op::Binary(Binary::HeterogeneousEqual), false),
991        ]);
992
993        for operands in operands_samples {
994            let operands_reversed: Vec<_> = operands.iter().cloned().rev().collect();
995            for operand in [operands, operands_reversed] {
996                for (op, result) in &operators {
997                    let mut ops = operand.clone();
998                    ops.push(op.clone());
999                    println!("ops: {:?}", ops);
1000
1001                    let e = Expression { ops };
1002                    println!("print: {}", e.print(&symbols).unwrap());
1003
1004                    let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1005                    assert_eq!(res, Ok(Term::Bool(*result)));
1006                }
1007            }
1008        }
1009    }
1010
1011    #[test]
1012    fn strict_equal_heterogeneous() {
1013        let symbols = SymbolTable::new();
1014        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1015        let values: HashMap<u32, Term> = HashMap::new();
1016        let operands_samples = [
1017            vec![Op::Value(Term::Bool(true)), Op::Value(Term::Integer(1))],
1018            vec![Op::Value(Term::Bool(true)), Op::Value(Term::Str(1))],
1019            vec![Op::Value(Term::Integer(1)), Op::Value(Term::Str(1))],
1020            vec![
1021                Op::Value(Term::Bytes(Vec::new())),
1022                Op::Value(Term::Integer(1)),
1023            ],
1024            vec![
1025                Op::Value(Term::Bytes(Vec::new())),
1026                Op::Value(Term::Str(1025)),
1027            ],
1028            vec![Op::Value(Term::Date(12)), Op::Value(Term::Integer(1))],
1029        ];
1030        let operators = vec![Op::Binary(Binary::NotEqual), Op::Binary(Binary::Equal)];
1031
1032        for operands in operands_samples {
1033            let operands_reversed: Vec<_> = operands.iter().cloned().rev().collect();
1034            for operand in [operands, operands_reversed] {
1035                for op in &operators {
1036                    let mut ops = operand.clone();
1037                    ops.push(op.clone());
1038                    println!("ops: {:?}", ops);
1039
1040                    let e = Expression { ops };
1041                    println!("print: {}", e.print(&symbols).unwrap());
1042
1043                    e.evaluate(&values, &mut tmp_symbols, &Default::default())
1044                        .unwrap_err();
1045                }
1046            }
1047        }
1048    }
1049
1050    #[test]
1051    fn laziness() {
1052        let symbols = SymbolTable::new();
1053        let mut symbols = TemporarySymbolTable::new(&symbols);
1054
1055        let ops1 = vec![
1056            Op::Value(Term::Bool(false)),
1057            Op::Closure(
1058                vec![],
1059                vec![
1060                    Op::Value(Term::Bool(true)),
1061                    Op::Closure(vec![], vec![Op::Value(Term::Bool(true))]),
1062                    Op::Binary(Binary::LazyAnd),
1063                ],
1064            ),
1065            Op::Binary(Binary::LazyOr),
1066        ];
1067        let e2 = Expression { ops: ops1 };
1068
1069        let res2 = e2
1070            .evaluate(&HashMap::new(), &mut symbols, &Default::default())
1071            .unwrap();
1072        assert_eq!(res2, Term::Bool(true));
1073    }
1074
1075    #[test]
1076    fn any() {
1077        let mut symbols = SymbolTable::new();
1078        let p = symbols.insert("param") as u32;
1079        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1080
1081        let ops1 = vec![
1082            Op::Value(Term::Set([Term::Bool(false), Term::Bool(true)].into())),
1083            Op::Closure(vec![p], vec![Op::Value(Term::Variable(p))]),
1084            Op::Binary(Binary::Any),
1085        ];
1086        let e1 = Expression { ops: ops1 };
1087        println!("{:?}", e1.print(&symbols));
1088
1089        let res1 = e1
1090            .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1091            .unwrap();
1092        assert_eq!(res1, Term::Bool(true));
1093
1094        let ops2 = vec![
1095            Op::Value(Term::Set([Term::Integer(1), Term::Integer(2)].into())),
1096            Op::Closure(
1097                vec![p],
1098                vec![
1099                    Op::Value(Term::Variable(p)),
1100                    Op::Value(Term::Integer(0)),
1101                    Op::Binary(Binary::LessThan),
1102                ],
1103            ),
1104            Op::Binary(Binary::Any),
1105        ];
1106        let e2 = Expression { ops: ops2 };
1107        println!("{:?}", e2.print(&symbols));
1108
1109        let res2 = e2
1110            .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1111            .unwrap();
1112        assert_eq!(res2, Term::Bool(false));
1113
1114        let ops3 = vec![
1115            Op::Value(Term::Set([Term::Integer(1), Term::Integer(2)].into())),
1116            Op::Closure(vec![p], vec![Op::Value(Term::Integer(0))]),
1117            Op::Binary(Binary::Any),
1118        ];
1119        let e3 = Expression { ops: ops3 };
1120        println!("{:?}", e3.print(&symbols));
1121
1122        let err3 = e3
1123            .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1124            .unwrap_err();
1125        assert_eq!(err3, error::Expression::InvalidType);
1126    }
1127
1128    #[test]
1129    fn all() {
1130        let mut symbols = SymbolTable::new();
1131        let p = symbols.insert("param") as u32;
1132        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1133
1134        let ops1 = vec![
1135            Op::Value(Term::Set([Term::Integer(1), Term::Integer(2)].into())),
1136            Op::Closure(
1137                vec![p],
1138                vec![
1139                    Op::Value(Term::Variable(p)),
1140                    Op::Value(Term::Integer(0)),
1141                    Op::Binary(Binary::GreaterThan),
1142                ],
1143            ),
1144            Op::Binary(Binary::All),
1145        ];
1146        let e1 = Expression { ops: ops1 };
1147        println!("{:?}", e1.print(&symbols));
1148
1149        let res1 = e1
1150            .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1151            .unwrap();
1152        assert_eq!(res1, Term::Bool(true));
1153
1154        let ops2 = vec![
1155            Op::Value(Term::Set([Term::Integer(1), Term::Integer(2)].into())),
1156            Op::Closure(
1157                vec![p],
1158                vec![
1159                    Op::Value(Term::Variable(p)),
1160                    Op::Value(Term::Integer(0)),
1161                    Op::Binary(Binary::LessThan),
1162                ],
1163            ),
1164            Op::Binary(Binary::All),
1165        ];
1166        let e2 = Expression { ops: ops2 };
1167        println!("{:?}", e2.print(&symbols));
1168
1169        let res2 = e2
1170            .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1171            .unwrap();
1172        assert_eq!(res2, Term::Bool(false));
1173
1174        let ops3 = vec![
1175            Op::Value(Term::Set([Term::Integer(1), Term::Integer(2)].into())),
1176            Op::Closure(vec![p], vec![Op::Value(Term::Integer(0))]),
1177            Op::Binary(Binary::All),
1178        ];
1179        let e3 = Expression { ops: ops3 };
1180        println!("{:?}", e3.print(&symbols));
1181
1182        let err3 = e3
1183            .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1184            .unwrap_err();
1185        assert_eq!(err3, error::Expression::InvalidType);
1186    }
1187
1188    #[test]
1189    fn nested_closures() {
1190        let mut symbols = SymbolTable::new();
1191        let p = symbols.insert("p") as u32;
1192        let q = symbols.insert("q") as u32;
1193        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1194
1195        let ops1 = vec![
1196            Op::Value(Term::Set(
1197                [Term::Integer(1), Term::Integer(2), Term::Integer(3)].into(),
1198            )),
1199            Op::Closure(
1200                vec![p],
1201                vec![
1202                    Op::Value(Term::Variable(p)),
1203                    Op::Value(Term::Integer(1)),
1204                    Op::Binary(Binary::GreaterThan),
1205                    Op::Closure(
1206                        vec![],
1207                        vec![
1208                            Op::Value(Term::Set(
1209                                [Term::Integer(3), Term::Integer(4), Term::Integer(5)].into(),
1210                            )),
1211                            Op::Closure(
1212                                vec![q],
1213                                vec![
1214                                    Op::Value(Term::Variable(p)),
1215                                    Op::Value(Term::Variable(q)),
1216                                    Op::Binary(Binary::Equal),
1217                                ],
1218                            ),
1219                            Op::Binary(Binary::Any),
1220                        ],
1221                    ),
1222                    Op::Binary(Binary::LazyAnd),
1223                ],
1224            ),
1225            Op::Binary(Binary::Any),
1226        ];
1227        let e1 = Expression { ops: ops1 };
1228        println!("{}", e1.print(&symbols).unwrap());
1229
1230        let res1 = e1
1231            .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1232            .unwrap();
1233        assert_eq!(res1, Term::Bool(true));
1234    }
1235
1236    #[test]
1237    fn variable_shadowing() {
1238        let mut symbols = SymbolTable::new();
1239        let p = symbols.insert("param") as u32;
1240        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1241
1242        let ops1 = vec![
1243            Op::Value(Term::Set([Term::Integer(1), Term::Integer(2)].into())),
1244            Op::Closure(
1245                vec![p],
1246                vec![
1247                    Op::Value(Term::Variable(p)),
1248                    Op::Value(Term::Integer(0)),
1249                    Op::Binary(Binary::GreaterThan),
1250                ],
1251            ),
1252            Op::Binary(Binary::All),
1253        ];
1254        let e1 = Expression { ops: ops1 };
1255        println!("{:?}", e1.print(&symbols));
1256
1257        let mut values = HashMap::new();
1258        values.insert(p, Term::Null);
1259        let res1 = e1.evaluate(&values, &mut tmp_symbols, &Default::default());
1260        assert_eq!(res1, Err(error::Expression::ShadowedVariable));
1261
1262        let mut symbols = SymbolTable::new();
1263        let p = symbols.insert("p") as u32;
1264        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1265
1266        let ops2 = vec![
1267            Op::Value(Term::Set(
1268                [Term::Integer(1), Term::Integer(2), Term::Integer(3)].into(),
1269            )),
1270            Op::Closure(
1271                vec![p],
1272                vec![
1273                    Op::Value(Term::Variable(p)),
1274                    Op::Value(Term::Integer(1)),
1275                    Op::Binary(Binary::GreaterThan),
1276                    Op::Closure(
1277                        vec![],
1278                        vec![
1279                            Op::Value(Term::Set(
1280                                [Term::Integer(3), Term::Integer(4), Term::Integer(5)].into(),
1281                            )),
1282                            Op::Closure(
1283                                vec![p],
1284                                vec![
1285                                    Op::Value(Term::Variable(p)),
1286                                    Op::Value(Term::Variable(p)),
1287                                    Op::Binary(Binary::Equal),
1288                                ],
1289                            ),
1290                            Op::Binary(Binary::Any),
1291                        ],
1292                    ),
1293                    Op::Binary(Binary::LazyAnd),
1294                ],
1295            ),
1296            Op::Binary(Binary::Any),
1297        ];
1298        let e2 = Expression { ops: ops2 };
1299        println!("{}", e2.print(&symbols).unwrap());
1300
1301        let res2 = e2.evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default());
1302        assert_eq!(res2, Err(error::Expression::ShadowedVariable));
1303    }
1304
1305    #[test]
1306    fn array() {
1307        let symbols = SymbolTable::new();
1308        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1309        let ops = vec![
1310            Op::Value(Term::Array(vec![Term::Integer(0), Term::Integer(1)])),
1311            Op::Value(Term::Array(vec![Term::Integer(0), Term::Integer(1)])),
1312            Op::Binary(Binary::Equal),
1313        ];
1314
1315        let values = HashMap::new();
1316        let e = Expression { ops };
1317        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1318        assert_eq!(res, Ok(Term::Bool(true)));
1319
1320        let ops = vec![
1321            Op::Value(Term::Array(vec![Term::Integer(0), Term::Integer(1)])),
1322            Op::Value(Term::Array(vec![Term::Integer(0)])),
1323            Op::Binary(Binary::Equal),
1324        ];
1325
1326        let values = HashMap::new();
1327        let e = Expression { ops };
1328        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1329        assert_eq!(res, Ok(Term::Bool(false)));
1330
1331        let ops = vec![
1332            Op::Value(Term::Array(vec![Term::Integer(0), Term::Integer(1)])),
1333            Op::Value(Term::Integer(1)),
1334            Op::Binary(Binary::Contains),
1335        ];
1336
1337        let values = HashMap::new();
1338        let e = Expression { ops };
1339        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1340        assert_eq!(res, Ok(Term::Bool(true)));
1341
1342        let ops = vec![
1343            Op::Value(Term::Array(vec![Term::Integer(0), Term::Integer(1)])),
1344            Op::Value(Term::Integer(2)),
1345            Op::Binary(Binary::Contains),
1346        ];
1347
1348        let values = HashMap::new();
1349        let e = Expression { ops };
1350        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1351        assert_eq!(res, Ok(Term::Bool(false)));
1352
1353        let ops = vec![
1354            Op::Value(Term::Array(vec![
1355                Term::Integer(0),
1356                Term::Integer(1),
1357                Term::Integer(2),
1358            ])),
1359            Op::Value(Term::Array(vec![Term::Integer(0), Term::Integer(1)])),
1360            Op::Binary(Binary::Prefix),
1361        ];
1362
1363        let values = HashMap::new();
1364        let e = Expression { ops };
1365        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1366        assert_eq!(res, Ok(Term::Bool(true)));
1367
1368        let ops = vec![
1369            Op::Value(Term::Array(vec![
1370                Term::Integer(0),
1371                Term::Integer(1),
1372                Term::Integer(2),
1373            ])),
1374            Op::Value(Term::Array(vec![Term::Integer(2), Term::Integer(1)])),
1375            Op::Binary(Binary::Prefix),
1376        ];
1377
1378        let values = HashMap::new();
1379        let e = Expression { ops };
1380        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1381        assert_eq!(res, Ok(Term::Bool(false)));
1382
1383        let ops = vec![
1384            Op::Value(Term::Array(vec![
1385                Term::Integer(0),
1386                Term::Integer(1),
1387                Term::Integer(2),
1388            ])),
1389            Op::Value(Term::Array(vec![Term::Integer(1), Term::Integer(2)])),
1390            Op::Binary(Binary::Suffix),
1391        ];
1392
1393        let values = HashMap::new();
1394        let e = Expression { ops };
1395        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1396        assert_eq!(res, Ok(Term::Bool(true)));
1397
1398        let ops = vec![
1399            Op::Value(Term::Array(vec![
1400                Term::Integer(0),
1401                Term::Integer(1),
1402                Term::Integer(2),
1403            ])),
1404            Op::Value(Term::Array(vec![Term::Integer(0), Term::Integer(2)])),
1405            Op::Binary(Binary::Suffix),
1406        ];
1407
1408        let values = HashMap::new();
1409        let e = Expression { ops };
1410        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1411        assert_eq!(res, Ok(Term::Bool(false)));
1412
1413        // get
1414        let ops = vec![
1415            Op::Value(Term::Array(vec![
1416                Term::Integer(0),
1417                Term::Integer(1),
1418                Term::Integer(2),
1419            ])),
1420            Op::Value(Term::Integer(1)),
1421            Op::Binary(Binary::Get),
1422        ];
1423
1424        let values = HashMap::new();
1425        let e = Expression { ops };
1426        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1427        assert_eq!(res, Ok(Term::Integer(1)));
1428
1429        // get out of bounds
1430        let ops = vec![
1431            Op::Value(Term::Array(vec![
1432                Term::Integer(0),
1433                Term::Integer(1),
1434                Term::Integer(2),
1435            ])),
1436            Op::Value(Term::Integer(3)),
1437            Op::Binary(Binary::Get),
1438        ];
1439
1440        let values = HashMap::new();
1441        let e = Expression { ops };
1442        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1443        assert_eq!(res, Ok(Term::Null));
1444
1445        // all
1446        let p = tmp_symbols.insert("param") as u32;
1447        let ops1 = vec![
1448            Op::Value(Term::Array([Term::Integer(1), Term::Integer(2)].into())),
1449            Op::Closure(
1450                vec![p],
1451                vec![
1452                    Op::Value(Term::Variable(p)),
1453                    Op::Value(Term::Integer(0)),
1454                    Op::Binary(Binary::GreaterThan),
1455                ],
1456            ),
1457            Op::Binary(Binary::All),
1458        ];
1459        let e1 = Expression { ops: ops1 };
1460        println!("{:?}", e1.print(&symbols));
1461
1462        let res1 = e1
1463            .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1464            .unwrap();
1465        assert_eq!(res1, Term::Bool(true));
1466
1467        // any
1468        let ops1 = vec![
1469            Op::Value(Term::Array([Term::Integer(1), Term::Integer(2)].into())),
1470            Op::Closure(
1471                vec![p],
1472                vec![
1473                    Op::Value(Term::Variable(p)),
1474                    Op::Value(Term::Integer(0)),
1475                    Op::Binary(Binary::Equal),
1476                ],
1477            ),
1478            Op::Binary(Binary::Any),
1479        ];
1480        let e1 = Expression { ops: ops1 };
1481        println!("{:?}", e1.print(&symbols));
1482
1483        let res1 = e1
1484            .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1485            .unwrap();
1486        assert_eq!(res1, Term::Bool(false));
1487    }
1488
1489    #[test]
1490    fn map() {
1491        let mut symbols = SymbolTable::new();
1492        let p = symbols.insert("param") as u32;
1493        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1494
1495        let ops = vec![
1496            Op::Value(Term::Map(
1497                [
1498                    (MapKey::Str(1), Term::Integer(0)),
1499                    (MapKey::Str(2), Term::Integer(1)),
1500                ]
1501                .iter()
1502                .cloned()
1503                .collect(),
1504            )),
1505            Op::Value(Term::Map(
1506                [
1507                    (MapKey::Str(2), Term::Integer(1)),
1508                    (MapKey::Str(1), Term::Integer(0)),
1509                ]
1510                .iter()
1511                .cloned()
1512                .collect(),
1513            )),
1514            Op::Binary(Binary::Equal),
1515        ];
1516
1517        let values = HashMap::new();
1518        let e = Expression { ops };
1519        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1520        assert_eq!(res, Ok(Term::Bool(true)));
1521
1522        let ops = vec![
1523            Op::Value(Term::Map(
1524                [
1525                    (MapKey::Str(1), Term::Integer(0)),
1526                    (MapKey::Str(2), Term::Integer(1)),
1527                ]
1528                .iter()
1529                .cloned()
1530                .collect(),
1531            )),
1532            Op::Value(Term::Map(
1533                [(MapKey::Str(1), Term::Integer(0))]
1534                    .iter()
1535                    .cloned()
1536                    .collect(),
1537            )),
1538            Op::Binary(Binary::Equal),
1539        ];
1540
1541        let values = HashMap::new();
1542        let e = Expression { ops };
1543        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1544        assert_eq!(res, Ok(Term::Bool(false)));
1545
1546        let ops = vec![
1547            Op::Value(Term::Map(
1548                [
1549                    (MapKey::Str(1), Term::Integer(0)),
1550                    (MapKey::Str(2), Term::Integer(1)),
1551                ]
1552                .iter()
1553                .cloned()
1554                .collect(),
1555            )),
1556            Op::Value(Term::Str(1)),
1557            Op::Binary(Binary::Contains),
1558        ];
1559
1560        let values = HashMap::new();
1561        let e = Expression { ops };
1562        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1563        assert_eq!(res, Ok(Term::Bool(true)));
1564
1565        let ops = vec![
1566            Op::Value(Term::Map(
1567                [
1568                    (MapKey::Str(1), Term::Integer(0)),
1569                    (MapKey::Str(2), Term::Integer(1)),
1570                ]
1571                .iter()
1572                .cloned()
1573                .collect(),
1574            )),
1575            Op::Value(Term::Integer(0)),
1576            Op::Binary(Binary::Contains),
1577        ];
1578
1579        let values = HashMap::new();
1580        let e = Expression { ops };
1581        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1582        assert_eq!(res, Ok(Term::Bool(false)));
1583
1584        // get
1585        let ops = vec![
1586            Op::Value(Term::Map(
1587                [
1588                    (MapKey::Str(1), Term::Integer(0)),
1589                    (MapKey::Integer(2), Term::Integer(1)),
1590                ]
1591                .iter()
1592                .cloned()
1593                .collect(),
1594            )),
1595            Op::Value(Term::Str(1)),
1596            Op::Binary(Binary::Get),
1597        ];
1598
1599        let values = HashMap::new();
1600        let e = Expression { ops };
1601        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1602        assert_eq!(res, Ok(Term::Integer(0)));
1603
1604        let ops = vec![
1605            Op::Value(Term::Map(
1606                [
1607                    (MapKey::Str(1), Term::Integer(0)),
1608                    (MapKey::Integer(2), Term::Integer(1)),
1609                ]
1610                .iter()
1611                .cloned()
1612                .collect(),
1613            )),
1614            Op::Value(Term::Integer(2)),
1615            Op::Binary(Binary::Get),
1616        ];
1617
1618        let values = HashMap::new();
1619        let e = Expression { ops };
1620        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1621        assert_eq!(res, Ok(Term::Integer(1)));
1622
1623        // get non existing key
1624        let ops = vec![
1625            Op::Value(Term::Map(
1626                [
1627                    (MapKey::Str(1), Term::Integer(0)),
1628                    (MapKey::Str(2), Term::Integer(1)),
1629                ]
1630                .iter()
1631                .cloned()
1632                .collect(),
1633            )),
1634            Op::Value(Term::Integer(0)),
1635            Op::Binary(Binary::Get),
1636        ];
1637
1638        let values = HashMap::new();
1639        let e = Expression { ops };
1640        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1641        assert_eq!(res, Ok(Term::Null));
1642
1643        let ops = vec![
1644            Op::Value(Term::Map(
1645                [
1646                    (MapKey::Str(1), Term::Integer(0)),
1647                    (MapKey::Str(2), Term::Integer(1)),
1648                ]
1649                .iter()
1650                .cloned()
1651                .collect(),
1652            )),
1653            Op::Value(Term::Str(3)),
1654            Op::Binary(Binary::Get),
1655        ];
1656
1657        let values = HashMap::new();
1658        let e = Expression { ops };
1659        let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1660        assert_eq!(res, Ok(Term::Null));
1661
1662        // all
1663        let ops1 = vec![
1664            Op::Value(Term::Map(
1665                [
1666                    (MapKey::Str(1), Term::Integer(0)),
1667                    (MapKey::Str(2), Term::Integer(1)),
1668                ]
1669                .iter()
1670                .cloned()
1671                .collect(),
1672            )),
1673            Op::Closure(
1674                vec![p],
1675                vec![
1676                    Op::Value(Term::Variable(p)),
1677                    Op::Value(Term::Integer(1)),
1678                    Op::Binary(Binary::Get),
1679                    Op::Value(Term::Integer(2)),
1680                    Op::Binary(Binary::LessThan),
1681                ],
1682            ),
1683            Op::Binary(Binary::All),
1684        ];
1685        let e1 = Expression { ops: ops1 };
1686        println!("{:?}", e1.print(&symbols));
1687
1688        let res1 = e1
1689            .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1690            .unwrap();
1691        assert_eq!(res1, Term::Bool(true));
1692
1693        // any
1694        let ops1 = vec![
1695            Op::Value(Term::Map(
1696                [
1697                    (MapKey::Str(1), Term::Integer(0)),
1698                    (MapKey::Str(2), Term::Integer(1)),
1699                ]
1700                .iter()
1701                .cloned()
1702                .collect(),
1703            )),
1704            Op::Closure(
1705                vec![p],
1706                vec![
1707                    Op::Value(Term::Variable(p)),
1708                    Op::Value(Term::Integer(0)),
1709                    Op::Binary(Binary::Get),
1710                    Op::Value(Term::Str(1)),
1711                    Op::Binary(Binary::Equal),
1712                ],
1713            ),
1714            Op::Binary(Binary::Any),
1715        ];
1716        let e1 = Expression { ops: ops1 };
1717        println!("{:?}", e1.print(&symbols));
1718
1719        let res1 = e1
1720            .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1721            .unwrap();
1722        assert_eq!(res1, Term::Bool(true));
1723    }
1724    #[test]
1725    fn ffi() {
1726        let mut symbols = SymbolTable::new();
1727        let i = symbols.insert("test");
1728        let j = symbols.insert("TeSt");
1729        let test_bin = symbols.insert("test_bin");
1730        let test_un = symbols.insert("test_un");
1731        let test_closure = symbols.insert("test_closure");
1732        let test_fn = symbols.insert("test_fn");
1733        let id_fn = symbols.insert("id");
1734        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1735        let ops = vec![
1736            Op::Value(Term::Integer(60)),
1737            Op::Value(Term::Integer(0)),
1738            Op::Binary(Binary::Ffi(test_bin)),
1739            Op::Value(Term::Str(i)),
1740            Op::Value(Term::Str(j)),
1741            Op::Binary(Binary::Ffi(test_bin)),
1742            Op::Binary(Binary::And),
1743            Op::Value(Term::Integer(42)),
1744            Op::Unary(Unary::Ffi(test_un)),
1745            Op::Binary(Binary::And),
1746            Op::Value(Term::Integer(42)),
1747            Op::Unary(Unary::Ffi(test_closure)),
1748            Op::Binary(Binary::And),
1749            Op::Value(Term::Str(i)),
1750            Op::Unary(Unary::Ffi(test_closure)),
1751            Op::Binary(Binary::And),
1752            Op::Value(Term::Integer(42)),
1753            Op::Unary(Unary::Ffi(test_fn)),
1754            Op::Binary(Binary::And),
1755            Op::Value(Term::Integer(42)),
1756            Op::Unary(Unary::Ffi(id_fn)),
1757            Op::Value(Term::Integer(42)),
1758            Op::Binary(Binary::HeterogeneousEqual),
1759            Op::Binary(Binary::And),
1760            Op::Value(Term::Str(i)),
1761            Op::Unary(Unary::Ffi(id_fn)),
1762            Op::Value(Term::Str(i)),
1763            Op::Binary(Binary::HeterogeneousEqual),
1764            Op::Binary(Binary::And),
1765            Op::Value(Term::Bool(true)),
1766            Op::Unary(Unary::Ffi(id_fn)),
1767            Op::Value(Term::Bool(true)),
1768            Op::Binary(Binary::HeterogeneousEqual),
1769            Op::Binary(Binary::And),
1770            Op::Value(Term::Date(0)),
1771            Op::Unary(Unary::Ffi(id_fn)),
1772            Op::Value(Term::Date(0)),
1773            Op::Binary(Binary::HeterogeneousEqual),
1774            Op::Binary(Binary::And),
1775            Op::Value(Term::Bytes(vec![42])),
1776            Op::Unary(Unary::Ffi(id_fn)),
1777            Op::Value(Term::Bytes(vec![42])),
1778            Op::Binary(Binary::HeterogeneousEqual),
1779            Op::Binary(Binary::And),
1780            Op::Value(Term::Null),
1781            Op::Unary(Unary::Ffi(id_fn)),
1782            Op::Value(Term::Null),
1783            Op::Binary(Binary::HeterogeneousEqual),
1784            Op::Binary(Binary::And),
1785            Op::Value(Term::Array(vec![Term::Null])),
1786            Op::Unary(Unary::Ffi(id_fn)),
1787            Op::Value(Term::Array(vec![Term::Null])),
1788            Op::Binary(Binary::HeterogeneousEqual),
1789            Op::Binary(Binary::And),
1790            Op::Value(Term::Set(BTreeSet::from([Term::Null]))),
1791            Op::Unary(Unary::Ffi(id_fn)),
1792            Op::Value(Term::Set(BTreeSet::from([Term::Null]))),
1793            Op::Binary(Binary::HeterogeneousEqual),
1794            Op::Binary(Binary::And),
1795            Op::Value(Term::Map(BTreeMap::from([
1796                (MapKey::Integer(42), Term::Null),
1797                (MapKey::Str(i), Term::Null),
1798            ]))),
1799            Op::Unary(Unary::Ffi(id_fn)),
1800            Op::Value(Term::Map(BTreeMap::from([
1801                (MapKey::Integer(42), Term::Null),
1802                (MapKey::Str(i), Term::Null),
1803            ]))),
1804            Op::Binary(Binary::HeterogeneousEqual),
1805            Op::Binary(Binary::And),
1806        ];
1807
1808        let values = HashMap::new();
1809        let e = Expression { ops };
1810        let mut extern_funcs: HashMap<String, ExternFunc> = Default::default();
1811        extern_funcs.insert(
1812            "test_bin".to_owned(),
1813            ExternFunc::new(Arc::new(|left, right| match (left, right) {
1814                (builder::Term::Integer(left), Some(builder::Term::Integer(right))) => {
1815                    println!("{left} {right}");
1816                    Ok(builder::Term::Bool((left % 60) == (right % 60)))
1817                }
1818                (builder::Term::Str(left), Some(builder::Term::Str(right))) => {
1819                    println!("{left} {right}");
1820                    Ok(builder::Term::Bool(
1821                        left.to_lowercase() == right.to_lowercase(),
1822                    ))
1823                }
1824                _ => Err("Expected two strings or two integers".to_string()),
1825            })),
1826        );
1827        extern_funcs.insert(
1828            "test_un".to_owned(),
1829            ExternFunc::new(Arc::new(|left, right| match (&left, &right) {
1830                (builder::Term::Integer(left), None) => Ok(builder::boolean(*left == 42)),
1831                _ => {
1832                    println!("{left:?}, {right:?}");
1833                    Err("expecting a single integer".to_string())
1834                }
1835            })),
1836        );
1837        extern_funcs.insert(
1838            "id".to_string(),
1839            ExternFunc::new(Arc::new(|left, right| match (left, right) {
1840                (a, None) => Ok(a),
1841                _ => Err("expecting a single value".to_string()),
1842            })),
1843        );
1844        let closed_over_int = 42;
1845        let closed_over_string = "test".to_string();
1846        extern_funcs.insert(
1847            "test_closure".to_owned(),
1848            ExternFunc::new(Arc::new(move |left, right| match (&left, &right) {
1849                (builder::Term::Integer(left), None) => {
1850                    Ok(builder::boolean(*left == closed_over_int))
1851                }
1852                (builder::Term::Str(left), None) => {
1853                    Ok(builder::boolean(left == &closed_over_string))
1854                }
1855                _ => {
1856                    println!("{left:?}, {right:?}");
1857                    Err("expecting a single integer".to_string())
1858                }
1859            })),
1860        );
1861        extern_funcs.insert("test_fn".to_owned(), ExternFunc::new(Arc::new(toto)));
1862        let res = e.evaluate(&values, &mut tmp_symbols, &extern_funcs);
1863        assert_eq!(res, Ok(Term::Bool(true)));
1864    }
1865
1866    fn toto(_left: builder::Term, _right: Option<builder::Term>) -> Result<builder::Term, String> {
1867        Ok(builder::Term::Bool(true))
1868    }
1869
1870    #[test]
1871    fn try_op() {
1872        let symbols = SymbolTable::new();
1873        let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1874
1875        let ops1 = vec![
1876            Op::Closure(
1877                vec![],
1878                vec![
1879                    Op::Value(Term::Bool(true)),
1880                    Op::Value(Term::Integer(0)),
1881                    Op::Binary(Binary::GreaterThan),
1882                    Op::Unary(Unary::Parens),
1883                ],
1884            ),
1885            Op::Value(Term::Bool(false)),
1886            Op::Binary(Binary::TryOr),
1887        ];
1888        let e1 = Expression { ops: ops1 };
1889        println!("{:?}", e1.print(&symbols));
1890
1891        let res1 = e1
1892            .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1893            .unwrap();
1894        assert_eq!(res1, Term::Bool(false));
1895
1896        let ops2 = vec![
1897            Op::Closure(
1898                vec![],
1899                vec![
1900                    Op::Value(Term::Integer(0)),
1901                    Op::Value(Term::Integer(0)),
1902                    Op::Binary(Binary::Equal),
1903                    Op::Unary(Unary::Parens),
1904                ],
1905            ),
1906            Op::Value(Term::Bool(false)),
1907            Op::Binary(Binary::TryOr),
1908        ];
1909        let e2 = Expression { ops: ops2 };
1910        println!("{:?}", e2.print(&symbols));
1911
1912        let res2 = e2
1913            .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1914            .unwrap();
1915        assert_eq!(res2, Term::Bool(true));
1916    }
1917}