1use crate::variable::{Variable, VariableKey};
2
3pub enum Expr<T> {
7 Is(VariableKey, T),
8 And(Box<Expr<T>>, Box<Expr<T>>),
9 Or(Box<Expr<T>>, Box<Expr<T>>),
10}
11
12impl<T> Expr<T> {
13 pub fn or(self, rhs: Expr<T>) -> Self {
14 Expr::Or(Box::new(self), Box::new(rhs))
15 }
16
17 pub fn and(self, rhs: Expr<T>) -> Self {
18 Expr::And(Box::new(self), Box::new(rhs))
19 }
20
21 pub fn and2(self, rhs: Expr<T>, rhs2: Expr<T>) -> Self {
22 self.and(rhs.and(rhs2))
23 }
24
25 pub(crate) fn propositions(&self) -> Vec<(VariableKey, &T, &[()])> {
26 let mut props = Vec::new();
27
28 fn parse<'p, T>(expr: &'p Expr<T>, out: &mut Vec<(VariableKey, &'p T, &'p [()])>) {
29 match expr {
30 Expr::Is(var_key, term) => out.push((*var_key, term, &[])),
31 Expr::And(expr, expr2) | Expr::Or(expr, expr2) => {
32 parse(expr, out);
33 parse(expr2, out)
34 },
35 }
36 }
37
38 parse(self, &mut props);
39
40 props
41 }
42}
43
44impl<I> Variable<I> {
45 pub fn is<T>(self, rhs: I) -> Expr<T>
46 where
47 I: Into<T>,
48 {
49 Expr::Is(self.0, rhs.into())
50 }
51}