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}