logic_eval/parse/
repr.rs

1use super::text::Name;
2use std::{
3    fmt::{self, Write},
4    ops,
5    vec::IntoIter,
6};
7
8#[derive(Clone)]
9pub struct ClauseDataset<T>(pub Vec<Clause<T>>);
10
11impl<T> IntoIterator for ClauseDataset<T> {
12    type Item = Clause<T>;
13    type IntoIter = IntoIter<Self::Item>;
14
15    fn into_iter(self) -> Self::IntoIter {
16        self.0.into_iter()
17    }
18}
19
20impl<T> ops::Deref for ClauseDataset<T> {
21    type Target = Vec<Clause<T>>;
22
23    fn deref(&self) -> &Self::Target {
24        &self.0
25    }
26}
27
28#[derive(Clone, PartialEq, Eq)]
29pub struct Clause<T> {
30    pub head: Term<T>,
31    pub body: Option<Expr<T>>,
32}
33
34impl<T> Clause<T> {
35    pub(crate) fn map<U, F: FnMut(T) -> U>(self, f: &mut F) -> Clause<U> {
36        Clause {
37            head: self.head.map(f),
38            body: self.body.map(|expr| expr.map(f)),
39        }
40    }
41
42    pub(crate) fn replace_term<F>(&mut self, f: &mut F)
43    where
44        F: FnMut(&Term<T>) -> Option<Term<T>>,
45    {
46        self.head.replace_all(f);
47        if let Some(body) = &mut self.body {
48            body.replace_term(f);
49        }
50    }
51}
52
53impl<T: fmt::Display> fmt::Display for Clause<T> {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        self.head.fmt(f)?;
56        if let Some(body) = &self.body {
57            f.write_str(" :- ")?;
58            body.fmt(f)?;
59        }
60        f.write_char('.')
61    }
62}
63
64#[derive(Default, Clone, PartialEq, Eq)]
65pub struct Term<T> {
66    pub functor: T,
67    pub args: Box<[Term<T>]>,
68}
69
70impl<T> Term<T> {
71    pub(crate) fn map<U, F: FnMut(T) -> U>(self, f: &mut F) -> Term<U> {
72        Term {
73            functor: f(self.functor),
74            args: self.args.into_iter().map(|arg| arg.map(f)).collect(),
75        }
76    }
77
78    pub fn replace_all<F>(&mut self, f: &mut F) -> bool
79    where
80        F: FnMut(&Term<T>) -> Option<Term<T>>,
81    {
82        if let Some(new) = f(self) {
83            *self = new;
84            true
85        } else {
86            let mut replaced = false;
87            for arg in &mut self.args {
88                replaced |= arg.replace_all(f);
89            }
90            replaced
91        }
92    }
93}
94
95impl<T: Clone> Term<T> {
96    pub fn predicate(&self) -> Predicate<T> {
97        Predicate {
98            functor: self.functor.clone(),
99            arity: self.args.len() as u32,
100        }
101    }
102}
103
104impl Term<Name> {
105    pub fn is_variable(&self) -> bool {
106        let is_variable = self.functor.is_variable();
107
108        #[cfg(debug_assertions)]
109        if is_variable {
110            assert!(self.args.is_empty());
111        }
112
113        is_variable
114    }
115
116    pub fn contains_variable(&self) -> bool {
117        if self.is_variable() {
118            return true;
119        }
120
121        self.args.iter().any(|arg| arg.contains_variable())
122    }
123}
124
125impl<T: fmt::Display> fmt::Display for Term<T> {
126    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127        self.functor.fmt(f)?;
128        if !self.args.is_empty() {
129            f.write_char('(')?;
130            for (i, arg) in self.args.iter().enumerate() {
131                arg.fmt(f)?;
132                if i + 1 < self.args.len() {
133                    f.write_str(", ")?;
134                }
135            }
136            f.write_char(')')?;
137        }
138        Ok(())
139    }
140}
141
142impl fmt::Debug for Term<Name> {
143    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144        if self.args.is_empty() {
145            self.functor.fmt(f)
146        } else {
147            let mut d = f.debug_tuple(&self.functor);
148            for arg in &self.args {
149                d.field(&arg);
150            }
151            d.finish()
152        }
153    }
154}
155
156#[derive(Clone, PartialEq, Eq)]
157pub enum Expr<T> {
158    Term(Term<T>),
159    Not(Box<Expr<T>>),
160    And(Vec<Expr<T>>),
161    Or(Vec<Expr<T>>),
162}
163
164impl<T> Expr<T> {
165    pub(crate) fn map<U, F: FnMut(T) -> U>(self, f: &mut F) -> Expr<U> {
166        match self {
167            Self::Term(v) => Expr::Term(v.map(f)),
168            Self::Not(v) => Expr::Not(Box::new(v.map(f))),
169            Self::And(v) => Expr::And(v.into_iter().map(|expr| expr.map(f)).collect()),
170            Self::Or(v) => Expr::Or(v.into_iter().map(|expr| expr.map(f)).collect()),
171        }
172    }
173
174    pub(crate) fn replace_term<F>(&mut self, f: &mut F)
175    where
176        F: FnMut(&Term<T>) -> Option<Term<T>>,
177    {
178        match self {
179            Self::Term(term) => {
180                term.replace_all(f);
181            }
182            Self::Not(inner) => inner.replace_term(f),
183            Self::And(args) | Self::Or(args) => {
184                for arg in args {
185                    arg.replace_term(f);
186                }
187            }
188        }
189    }
190}
191
192impl<T: fmt::Display> fmt::Display for Expr<T> {
193    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
194        match self {
195            Self::Term(term) => term.fmt(f)?,
196            Self::Not(inner) => {
197                f.write_str("\\+ ")?;
198                if matches!(**inner, Self::And(_) | Self::Or(_)) {
199                    f.write_char('(')?;
200                    inner.fmt(f)?;
201                    f.write_char(')')?;
202                } else {
203                    inner.fmt(f)?;
204                }
205            }
206            Self::And(args) => {
207                for (i, arg) in args.iter().enumerate() {
208                    if matches!(arg, Self::Or(_)) {
209                        f.write_char('(')?;
210                        arg.fmt(f)?;
211                        f.write_char(')')?;
212                    } else {
213                        arg.fmt(f)?;
214                    }
215                    if i + 1 < args.len() {
216                        f.write_str(", ")?;
217                    }
218                }
219            }
220            Self::Or(args) => {
221                for (i, arg) in args.iter().enumerate() {
222                    arg.fmt(f)?;
223                    if i + 1 < args.len() {
224                        f.write_str("; ")?;
225                    }
226                }
227            }
228        }
229        Ok(())
230    }
231}
232
233impl fmt::Debug for Expr<Name> {
234    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235        match self {
236            Self::Term(term) => fmt::Debug::fmt(term, f),
237            Self::Not(inner) => f.debug_tuple("Not").field(inner).finish(),
238            Self::And(args) => {
239                let mut d = f.debug_tuple("And");
240                for arg in args {
241                    d.field(arg);
242                }
243                d.finish()
244            }
245            Self::Or(args) => {
246                let mut d = f.debug_tuple("Or");
247                for arg in args {
248                    d.field(arg);
249                }
250                d.finish()
251            }
252        }
253    }
254}
255
256#[derive(Debug, PartialEq, Eq, Hash)]
257pub struct Predicate<T> {
258    pub functor: T,
259    pub arity: u32,
260}