bool_logic/
ast.rs

1use std::fmt;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub enum Expr<T> {
5    Any(Any<T>),
6    All(All<T>),
7    Not(Not<T>),
8    Var(Var<T>),
9    Const(bool),
10}
11
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct Any<T>(pub Vec<Expr<T>>);
14
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct All<T>(pub Vec<Expr<T>>);
17
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct Not<T>(pub Box<Expr<T>>);
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
22pub struct Var<T>(pub T);
23
24pub fn expr<T>(x: impl Into<Expr<T>>) -> Expr<T> {
25    x.into()
26}
27
28pub fn any<T>(x: impl Into<Any<T>>) -> Any<T> {
29    x.into()
30}
31
32pub fn all<T>(x: impl Into<All<T>>) -> All<T> {
33    x.into()
34}
35
36pub fn not<T>(x: impl Into<Expr<T>>) -> Not<T> {
37    x.into().into()
38}
39
40pub fn var<T>(x: impl Into<Var<T>>) -> Var<T> {
41    x.into()
42}
43
44pub fn const_<T>(x: bool) -> Expr<T> {
45    x.into()
46}
47
48impl<T> From<Any<T>> for Expr<T> {
49    fn from(any: Any<T>) -> Self {
50        Expr::Any(any)
51    }
52}
53
54impl<T> From<All<T>> for Expr<T> {
55    fn from(all: All<T>) -> Self {
56        Expr::All(all)
57    }
58}
59
60impl<T> From<Not<T>> for Expr<T> {
61    fn from(not: Not<T>) -> Self {
62        Expr::Not(not)
63    }
64}
65
66impl<T> From<Var<T>> for Expr<T> {
67    fn from(var: Var<T>) -> Self {
68        Expr::Var(var)
69    }
70}
71
72impl<T> From<bool> for Expr<T> {
73    fn from(b: bool) -> Self {
74        Expr::Const(b)
75    }
76}
77
78impl<T> From<Vec<Expr<T>>> for Any<T> {
79    fn from(exprs: Vec<Expr<T>>) -> Self {
80        Any(exprs)
81    }
82}
83
84impl<T> From<Vec<Expr<T>>> for All<T> {
85    fn from(exprs: Vec<Expr<T>>) -> Self {
86        All(exprs)
87    }
88}
89
90impl<T> From<Box<Expr<T>>> for Not<T> {
91    fn from(expr: Box<Expr<T>>) -> Self {
92        Not(expr)
93    }
94}
95
96impl<T> From<Expr<T>> for Not<T> {
97    fn from(expr: Expr<T>) -> Self {
98        Not(Box::new(expr))
99    }
100}
101
102impl<T> From<Any<T>> for Not<T> {
103    fn from(any: Any<T>) -> Self {
104        Not(Box::new(any.into()))
105    }
106}
107
108impl<T> From<All<T>> for Not<T> {
109    fn from(all: All<T>) -> Self {
110        Not(Box::new(all.into()))
111    }
112}
113
114impl<T> From<Var<T>> for Not<T> {
115    fn from(var: Var<T>) -> Self {
116        Not(Box::new(var.into()))
117    }
118}
119
120impl<T> From<T> for Not<T> {
121    fn from(var: T) -> Self {
122        Self::from(Var(var))
123    }
124}
125
126impl<T> From<T> for Var<T> {
127    fn from(var: T) -> Self {
128        Var(var)
129    }
130}
131
132macro_rules! impl_from_tuple {
133    ($ty:ident, ()) => {
134        impl_from_tuple!(@expand $ty, ());
135    };
136    ($ty:ident, ($x:tt, $($xs:tt,)*)) => {
137        impl_from_tuple!($ty, ($($xs,)*));
138        impl_from_tuple!(@expand $ty, ($x, $($xs,)*));
139    };
140    (@expand $ty:ident, ($($tt:tt,)*)) => {
141        #[doc(hidden)] // too ugly
142        #[allow(non_camel_case_types)]
143        impl<T, $($tt),*> From<($($tt,)*)>  for $ty<T>
144        where
145            $($tt: Into<Expr<T>>,)*
146        {
147            fn from(($($tt,)*): ($($tt,)*)) -> Self {
148                Self::from(vec![$(Into::into($tt)),*])
149            }
150        }
151    };
152}
153
154impl_from_tuple!(
155    Any,
156    (
157        x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, //
158        x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, //
159        x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35,
160    )
161);
162
163impl_from_tuple!(
164    All,
165    (
166        x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, //
167        x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, //
168        x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35,
169    )
170);
171
172impl<T> fmt::Display for Expr<T>
173where
174    T: fmt::Display,
175{
176    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177        match self {
178            Expr::Any(Any(any)) => fmt_list(f, "any", any),
179            Expr::All(All(all)) => fmt_list(f, "all", all),
180            Expr::Not(Not(not)) => write!(f, "not({not})"),
181            Expr::Var(Var(x)) => write!(f, "{x}"),
182            Expr::Const(b) => write!(f, "{b}"),
183        }
184    }
185}
186
187fn fmt_list<T>(f: &mut fmt::Formatter<'_>, name: &str, list: &[Expr<T>]) -> fmt::Result
188where
189    T: fmt::Display,
190{
191    write!(f, "{name}(")?;
192    for (i, e) in list.iter().enumerate() {
193        if i != 0 {
194            write!(f, ", ")?;
195        }
196        write!(f, "{e}")?;
197    }
198    write!(f, ")")
199}
200
201impl<T> Expr<T> {
202    pub fn as_mut_expr_list(&mut self) -> Option<&mut Vec<Expr<T>>> {
203        match self {
204            Expr::Any(Any(list)) | Expr::All(All(list)) => Some(list),
205            _ => None,
206        }
207    }
208
209    pub fn is_any(&self) -> bool {
210        matches!(self, Self::Any(_))
211    }
212
213    pub fn is_all(&self) -> bool {
214        matches!(self, Self::All(_))
215    }
216
217    pub fn is_not(&self) -> bool {
218        matches!(self, Self::Not(_))
219    }
220
221    pub fn is_var(&self) -> bool {
222        matches!(self, Self::Var(_))
223    }
224
225    pub fn is_const(&self) -> bool {
226        matches!(self, Self::Const(_))
227    }
228
229    pub fn is_const_true(&self) -> bool {
230        matches!(self, Self::Const(true))
231    }
232
233    pub fn is_const_false(&self) -> bool {
234        matches!(self, Self::Const(false))
235    }
236
237    pub fn as_var(&self) -> Option<&Var<T>> {
238        match self {
239            Expr::Var(var) => Some(var),
240            _ => None,
241        }
242    }
243
244    pub fn as_mut_any(&mut self) -> Option<&mut Any<T>> {
245        match self {
246            Expr::Any(any) => Some(any),
247            _ => None,
248        }
249    }
250
251    pub fn as_mut_all(&mut self) -> Option<&mut All<T>> {
252        match self {
253            Expr::All(all) => Some(all),
254            _ => None,
255        }
256    }
257
258    pub fn as_mut_not(&mut self) -> Option<&mut Not<T>> {
259        match self {
260            Expr::Not(not) => Some(not),
261            _ => None,
262        }
263    }
264
265    pub fn is_expr_not_var(&self) -> bool {
266        if let Expr::Not(Not(not)) = self {
267            return not.is_var();
268        }
269        false
270    }
271
272    pub fn as_mut_not_any(&mut self) -> Option<&mut Any<T>> {
273        if let Expr::Not(Not(not)) = self {
274            if let Expr::Any(any) = &mut **not {
275                return Some(any);
276            }
277        }
278        None
279    }
280
281    pub fn as_mut_not_all(&mut self) -> Option<&mut All<T>> {
282        if let Expr::Not(Not(not)) = self {
283            if let Expr::All(any) = &mut **not {
284                return Some(any);
285            }
286        }
287        None
288    }
289
290    pub fn is_empty_not_any(&self) -> bool {
291        if let Expr::Not(Not(not)) = self {
292            if let Expr::Any(Any(list)) = &**not {
293                return list.is_empty();
294            }
295        }
296        false
297    }
298
299    pub fn is_empty_not_all(&self) -> bool {
300        if let Expr::Not(Not(not)) = self {
301            if let Expr::All(All(list)) = &**not {
302                return list.is_empty();
303            }
304        }
305        false
306    }
307}