fuzzy_expert/
dsl.rs

1use crate::variable::{Variable, VariableKey};
2
3// TODO: Support modifiers
4// TODO: Return to And(Vec<Expr<T>>), Or(Vec<Expr<T>>),
5// for simplicity and possibly cache friendliness
6pub 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}