Skip to main content

logic_eval/parse/
repr.rs

1use super::text::Name;
2use std::{
3    fmt::{self, Debug, Display, 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: AsRef<str>> 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<T: AsRef<str>> Term<Name<T>> {
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: AsRef<str>> Display for Term<T> {
126    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127        let functor: &str = self.functor.as_ref();
128        f.write_str(functor)?;
129        if !self.args.is_empty() {
130            f.write_char('(')?;
131            for (i, arg) in self.args.iter().enumerate() {
132                arg.fmt(f)?;
133                if i + 1 < self.args.len() {
134                    f.write_str(", ")?;
135                }
136            }
137            f.write_char(')')?;
138        }
139        Ok(())
140    }
141}
142
143impl<T: AsRef<str>> Debug for Term<Name<T>> {
144    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145        let functor: &str = self.functor.as_ref();
146        if self.args.is_empty() {
147            f.write_str(functor)
148        } else {
149            let mut d = f.debug_tuple(functor);
150            for arg in &self.args {
151                d.field(&arg);
152            }
153            d.finish()
154        }
155    }
156}
157
158#[derive(Clone, PartialEq, Eq)]
159pub enum Expr<T> {
160    Term(Term<T>),
161    Not(Box<Expr<T>>),
162    And(Vec<Expr<T>>),
163    Or(Vec<Expr<T>>),
164}
165
166impl<T> Expr<T> {
167    pub(crate) fn map<U, F: FnMut(T) -> U>(self, f: &mut F) -> Expr<U> {
168        match self {
169            Self::Term(v) => Expr::Term(v.map(f)),
170            Self::Not(v) => Expr::Not(Box::new(v.map(f))),
171            Self::And(v) => Expr::And(v.into_iter().map(|expr| expr.map(f)).collect()),
172            Self::Or(v) => Expr::Or(v.into_iter().map(|expr| expr.map(f)).collect()),
173        }
174    }
175
176    pub(crate) fn replace_term<F>(&mut self, f: &mut F)
177    where
178        F: FnMut(&Term<T>) -> Option<Term<T>>,
179    {
180        match self {
181            Self::Term(term) => {
182                term.replace_all(f);
183            }
184            Self::Not(inner) => inner.replace_term(f),
185            Self::And(args) | Self::Or(args) => {
186                for arg in args {
187                    arg.replace_term(f);
188                }
189            }
190        }
191    }
192}
193
194impl<T: AsRef<str>> Display for Expr<T> {
195    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
196        match self {
197            Self::Term(term) => term.fmt(f)?,
198            Self::Not(inner) => {
199                f.write_str("\\+ ")?;
200                if matches!(**inner, Self::And(_) | Self::Or(_)) {
201                    f.write_char('(')?;
202                    inner.fmt(f)?;
203                    f.write_char(')')?;
204                } else {
205                    inner.fmt(f)?;
206                }
207            }
208            Self::And(args) => {
209                for (i, arg) in args.iter().enumerate() {
210                    if matches!(arg, Self::Or(_)) {
211                        f.write_char('(')?;
212                        arg.fmt(f)?;
213                        f.write_char(')')?;
214                    } else {
215                        arg.fmt(f)?;
216                    }
217                    if i + 1 < args.len() {
218                        f.write_str(", ")?;
219                    }
220                }
221            }
222            Self::Or(args) => {
223                for (i, arg) in args.iter().enumerate() {
224                    arg.fmt(f)?;
225                    if i + 1 < args.len() {
226                        f.write_str("; ")?;
227                    }
228                }
229            }
230        }
231        Ok(())
232    }
233}
234
235impl<T: AsRef<str>> Debug for Expr<Name<T>> {
236    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
237        match self {
238            Self::Term(term) => fmt::Debug::fmt(term, f),
239            Self::Not(inner) => f.debug_tuple("Not").field(inner).finish(),
240            Self::And(args) => {
241                let mut d = f.debug_tuple("And");
242                for arg in args {
243                    d.field(arg);
244                }
245                d.finish()
246            }
247            Self::Or(args) => {
248                let mut d = f.debug_tuple("Or");
249                for arg in args {
250                    d.field(arg);
251                }
252                d.finish()
253            }
254        }
255    }
256}
257
258#[derive(Debug, PartialEq, Eq, Hash)]
259pub struct Predicate<T> {
260    pub functor: T,
261    pub arity: u32,
262}