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}