1#[macro_use]
4mod macros;
5pub mod core;
6pub mod database;
7#[macro_use]
8pub mod goals;
9pub mod prelude;
10pub mod testing;
11
12pub use prelude::*;
13
14#[cfg(test)]
15mod tests {
16 use crate::core::goal::RawGoal;
17 use crate::core::logic_variable::{ReifiedVar, Var};
18 use crate::core::stream::Stream;
19 use crate::core::substitution::Substitution;
20 use crate::core::value::Value;
21 use crate::goals::combinators::{conj2, disj2, ifte};
22 use crate::goals::primitive::{alwayso, eq, fail, succeed};
23 use crate::{defrel, disj, fresh, run, substitution};
24 use std::borrow::Cow;
25 use std::collections::HashMap;
26
27 #[test]
28 fn it_works() {
29 let u = Var::new("u");
30 let v = Var::new("v");
31 let w = Var::new("w");
32 let x = Var::new("x");
33 let y = Var::new("y");
34 let z = Var::new("z");
35
36 assert!(Substitution::empty().occurs(&x, &Value::var(x.clone())));
37 assert!(substitution! {y: x}.occurs(&x, &Value::cons(Value::var(y), ())));
38 assert!(substitution! {y: x}.occurs(&x, &vec![Value::var(y)].into()));
39 assert!(Substitution::empty()
40 .extend(x.clone(), vec![Value::var(x.clone())].into())
41 .is_none());
42 assert!(substitution! {y: x}
43 .extend(x.clone(), vec![Value::var(y.clone())].into())
44 .is_none());
45
46 assert_eq!(
47 Substitution::empty().unify(
48 &Value::new(Some(Value::var(x.clone()))),
49 &Value::new(Some(Value::var(y.clone())))
50 ),
51 Some(substitution!(x: y)),
52 );
53
54 assert_eq!(
55 Substitution::empty()
56 .unify(
57 &Value::new(Some(Value::var(x.clone()))),
58 &Value::new(Some(Value::var(y.clone())))
59 )
60 .unwrap()
61 .unify(
62 &Value::new(Some(Value::var(x.clone()))),
63 &Value::new(Some(Value::new(42)))
64 ),
65 Some(substitution!(x: y, y: 42)),
66 );
67
68 assert_eq!(
69 eq(x, Value::var(u.clone())).apply(Substitution::empty()),
70 Stream::singleton(substitution!(x: u))
71 );
72 assert_eq!(
73 eq(x, 42).apply(Substitution::empty()),
74 Stream::singleton(substitution!(x: 42))
75 );
76 assert_eq!(
77 eq(42, 42).apply(Substitution::empty()),
78 Stream::singleton(substitution!())
79 );
80 assert_eq!(eq(42, 123).apply(Substitution::empty()), Stream::empty());
81
82 assert_eq!(fail().apply(Substitution::empty()), Stream::Empty);
83 assert_eq!(eq(true, false).apply(Substitution::empty()), Stream::Empty);
84 assert_eq!(
85 eq(x, y).apply(Substitution::empty()),
86 Stream::singleton(substitution! {x: y})
87 );
88
89 assert_eq!(
90 disj2(eq("olive", x), eq("oil", x)).apply(Substitution::empty()),
91 Stream::cons(
92 substitution! {x: "olive"},
93 Stream::cons(substitution! {x: "oil"}, Stream::empty())
94 )
95 );
96
97 assert_eq!(
101 alwayso().apply(Substitution::empty()).take_inf(3),
102 Stream::from_iter(
103 vec![
104 Substitution::empty(),
105 Substitution::empty(),
106 Substitution::empty()
107 ]
108 .into_iter()
109 )
110 );
111
112 assert_eq!(
113 disj2(eq("olive", x), eq("oil", x))
114 .apply(Substitution::empty())
115 .take_inf(5)
116 .len(),
117 Some(2)
118 );
119
120 assert_eq!(
121 conj2(eq("olive", x), eq("oil", x)).apply(Substitution::empty()),
122 Stream::empty()
123 );
124
125 assert_eq!(
126 conj2(eq("olive", x), eq(y.clone(), x.clone())).apply(Substitution::empty()),
127 Stream::singleton(substitution! {y: "olive", x: "olive"})
128 );
129
130 let a1 = Value::from(vec![
131 Value::from(u),
132 Value::from(w),
133 Value::from(y),
134 Value::from(z),
135 Value::from(Some(Value::from(vec![Value::from("ice"), Value::from(z)]))),
136 ]);
137 let a2 = Value::from("corn");
138 let a3 = Value::from(vec![Value::from(v), Value::from(u)]);
139 let s = substitution! {x: a1, y: a2, w: a3};
140 assert_eq!(
142 s.reify(&x.into()),
143 Value::from(vec![
144 Value::from(ReifiedVar(0)),
145 Value::from(vec![Value::from(ReifiedVar(1)), Value::from(ReifiedVar(0))]),
146 Value::from("corn"),
147 Value::from(ReifiedVar(2)),
148 Value::from(vec![Value::from("ice"), Value::from(ReifiedVar(2))])
149 ])
150 );
151
152 assert_eq!(
153 disj2(eq("olive", x), eq("oil", x))
154 .run(5)
155 .into_iter()
156 .map(|s| s.reify(&x.into()))
157 .collect::<Vec<_>>(),
158 vec![Value::from("olive"), Value::from("oil")],
159 );
160
161 assert_eq!(
162 ifte(succeed(), eq(false, y.clone()), eq(true, y.clone())).apply(Substitution::empty()),
163 Stream::singleton(substitution!(y: false))
164 );
165
166 assert_eq!(
167 ifte(fail(), eq(false, y.clone()), eq(true, y.clone())).apply(Substitution::empty()),
168 Stream::singleton(substitution!(y: true))
169 );
170
171 assert_eq!(
172 disj!(eq("virgin", x); eq("olive", x); eq("oil", x)).apply(Substitution::empty()),
173 Stream::from_iter(
174 vec![
175 substitution! {x: "virgin"},
176 substitution! {x: "olive"},
177 substitution! {x: "oil"},
178 ]
179 .into_iter()
180 )
181 );
182
183 defrel! {
184 teacup(t) {
185 disj!(eq("tea", t.clone()); eq("cup", t))
186 }
187 }
188
189 assert_eq!(
190 teacup(x.clone())
191 .apply(Substitution::empty())
192 .into_iter()
193 .collect::<Vec<_>>(),
194 vec![substitution!(x: "tea"), substitution!(x: "cup")]
195 );
196
197 assert_eq!(
198 format!(
199 "{:?}",
200 fresh!((x, y), eq(x, y)).apply(Substitution::empty())
201 ),
202 "({x: y})"
203 );
204
205 assert_eq!(run!(1, x,), Stream::singleton(Value::from(ReifiedVar(0))));
206 assert_eq!(run!(1, x, eq(x, 42)), Stream::singleton(Value::new(42)));
207 assert_eq!(
208 run!(1, (x, y),),
209 Stream::singleton(Value::new(vec![
210 Value::from(ReifiedVar(0)),
211 Value::from(ReifiedVar(1))
212 ]))
213 );
214 assert_eq!(
215 run!(1, (x, y), eq(x, 42)),
216 Stream::singleton(Value::new(vec![Value::new(42), Value::from(ReifiedVar(0))]))
217 );
218
219 defrel! {
220 conso(a, d, p) {
221 eq(vec![a, d], p)
222 }
223 }
224
225 assert_eq!(
226 run!(*, x, conso(1, 2, x)),
227 Stream::singleton(Value::new(vec![Value::new(1), Value::new(2)]))
228 );
229 assert_eq!(
230 run!(*, x, conso(1, x, vec![Value::new(1), Value::new(2)])),
231 Stream::singleton(Value::new(2))
232 );
233 assert_eq!(
234 run!(*, x, conso(x, 2, vec![Value::new(1), Value::new(2)])),
235 Stream::singleton(Value::new(1))
236 );
237 assert_eq!(
238 run!(*, x, conso(x.clone(), x, vec![Value::new(1), Value::new(2)])),
239 Stream::empty()
240 );
241 assert_eq!(
242 run!(*, x, conso(x.clone(), x, vec![Value::new(3), Value::new(3)])),
243 Stream::singleton(Value::new(3))
244 );
245
246 assert_eq!(
247 run!(5, q, eq(q, "onion")),
248 Stream::singleton(Value::new("onion"))
249 );
250
251 assert_eq!(
252 run!(5, q, eq(q, "onion"), alwayso(),),
253 Stream::from_iter(std::iter::repeat(Value::new("onion")).take(5))
254 );
255 }
256}