]>
Witch of Git - mukan/blob - src/lib.rs
1 use dyn_clone
::{self, DynClone
};
2 use im
::{HashMap
, Vector
};
3 use std
::{fmt
, sync
::Arc
};
5 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
8 #[derive(Clone, PartialEq)]
11 Pair(Arc
<Term
>, Arc
<Term
>),
15 impl From
<&Term
> for Term
{
16 fn from(term
: &Term
) -> Term
{
21 impl From
<i32> for Term
{
22 fn from(i
: i32) -> Term
{
27 impl From
<Var
> for Term
{
28 fn from(var
: Var
) -> Term
{
33 impl fmt
::Display
for Term
{
34 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
36 Term
::Var(v
) => write
!(fmt
, "{:?}", v
),
37 Term
::Pair(l
, r
) => write
!(fmt
, "({}, {})", *l
, *r
),
38 Term
::Lit(i
) => write
!(fmt
, "{}", i
),
43 impl fmt
::Debug
for Term
{
44 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
45 write
!(fmt
, "{}", self)
49 impl fmt
::Debug
for Var
{
50 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
51 write
!(fmt
, "x{}", self.0)
55 impl<T
, U
> From
<(T
, U
)> for Term
60 fn from((t
, u
): (T
, U
)) -> Term
{
61 Term
::Pair(Arc
::new(t
.into
()), Arc
::new(u
.into
()))
65 #[derive(Debug, Clone, Default)]
71 impl fmt
::Display
for Subst
{
72 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
73 let mut entries
= self.0.iter
();
75 if let Some((k
, v
)) = entries
.next() {
76 write
!(fmt
, "{:?}: {:?}", k
, v
)?
;
78 for (k
, v
) in entries
{
79 write
!(fmt
, ", {:?}: {:?}", k
, v
)?
;
85 impl fmt
::Display
for State
{
86 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
87 write
!(fmt
, "#{} {}", self.fresh
, self.subst
)
91 pub fn delay
<G
: Goal
>(thunk
: impl Clone
+ Fn() -> G
+ '
static) -> BoxedGoal
{
92 BoxedGoal
::new(move |state
: State
| thunk().search(state
))
96 pub struct BoxedGoal
{
97 inner
: Box
<dyn Goal
<Stream
= Box
<dyn Iterator
<Item
= State
>>>>,
101 fn new(goal
: impl Goal
+ Clone
+ '
static) -> Self {
103 inner
: Box
::new(BoxGoalInner(goal
)),
108 impl Goal
for BoxedGoal
{
109 type Stream
= Box
<dyn Iterator
<Item
= State
>>;
110 fn search(&self, state
: State
) -> Self::Stream
{
111 self.inner
.search(state
)
116 struct BoxGoalInner
<G
>(G
);
118 impl<G
> Goal
for BoxGoalInner
<G
>
123 type Stream
= Box
<dyn Iterator
<Item
= State
>>;
124 fn search(&self, state
: State
) -> Self::Stream
{
125 Box
::new(self.0.search(state
))
129 pub trait Goal
: DynClone
{
130 type Stream
: Iterator
<Item
= State
>;
131 fn search(&self, state
: State
) -> Self::Stream
;
134 dyn_clone
::clone_trait_object
!(Goal
<Stream
= Box
<dyn Iterator
<Item
= State
>>>);
136 pub fn call_fresh
<G
: Goal
>(block
: impl Clone
+ Fn(Var
) -> G
) -> impl Goal
+ Clone
{
137 move |mut state
: State
| {
138 let var
= Var(state
.fresh
);
140 block(var
).search(state
)
146 (() => $e
:expr
) => { $e
};
147 (($v
:ident $
(, $vs
:ident
)* $
(,)?
) => $e
:expr
) => {
148 call_fresh(move |$v
| $
crate::fresh
!(($
($vs
),*) => $e
))
154 () => { |state
: State
| std
::iter
::once(state
) };
156 ($e
:expr $
(, $es
:expr
)* $
(,)?
) => {
157 and($e
, all
!($
($es
),*))
163 () => { |state
: State
| std
::iter
::empty() };
165 ($e
:expr $
(, $es
:expr
)* $
(,)?
) => {
166 or($e
, any
!($
($es
),*))
170 pub fn eq(u
: impl Into
<Term
>, v
: impl Into
<Term
>) -> impl Goal
+ Clone
{
173 move |state
: State
| state
.un
ify
(u
.clone(), v
.clone()).into
_iter
()
176 pub fn and(u
: impl Goal
+ Clone
, v
: impl Goal
+ Clone
) -> impl Goal
+ Clone
{
177 move |state
: State
| Bind
{
185 pub fn or(u
: impl Goal
+ Clone
, v
: impl Goal
+ Clone
) -> impl Goal
+ Clone
{
186 move |state
: State
| Plus
{
187 a
: u
.search(state
.clone()),
194 pub fn new() -> Self {
198 pub fn with_vars(n
: u32) -> (Vec
<Var
>, Self) {
199 let vars
= (0..n
).map(|v
| Var(v
)).collect();
209 pub fn unify(&self, u
: Term
, v
: Term
) -> Option
<State
> {
210 self.subst
.un
ify
(u
, v
).map(|subst
| State
{
216 pub fn eval(&self, term
: Term
) -> Term
{
217 match self.subst
.walk(term
) {
218 Term
::Pair(u
, v
) => Term
::from((self.eval((*u
).clone()), self.eval((*v
).clone()))),
224 #[derive(Debug, Clone, Default)]
225 struct Subst(HashMap
<Var
, Vector
<Term
>>);
228 fn walk(&self, mut term
: Term
) -> Term
{
229 let mut subst
= self.clone();
232 Term
::Var(var
) => match subst
.0.get_mut(&var
) {
234 term
= vec
.pop_back().unwrap
();
236 subst
.0.remove(&var
);
246 fn extend(&mut self, var
: Var
, term
: Term
) {
247 self.0.entry(var
).or_default().push_back(term
);
250 fn extended(&self, var
: Var
, term
: Term
) -> Self {
251 let mut subst
= self.clone();
252 subst
.extend(var
, term
);
256 fn unify(&self, u
: Term
, v
: Term
) -> Option
<Subst
> {
257 let u
= self.walk(u
);
258 let v
= self.walk(v
);
260 (u
, v
) if u
== v
=> Some(self.clone()),
261 (Term
::Var(u
), term
) => Some(self.clone().extended(u
, term
)),
262 (term
, Term
::Var(v
)) => Some(self.clone().extended(v
, term
)),
263 (Term
::Pair(u0
, u1
), Term
::Pair(v0
, v1
)) => self
264 .un
ify
((*u0
).clone(), (*v0
).clone())
265 .and_then(|s
| s
.un
ify
((*u1
).clone(), (*v1
).clone())),
271 pub fn reify(state
: State
) -> HashMap
<Var
, Term
> {
272 let mut result
= HashMap
::new();
273 for &v
in state
.subst
.0.keys() {
274 let term
= state
.subst
.walk(Term
::Var(v
));
275 result
.insert
(v
, state
.eval(term
));
280 pub fn reify_vars(vars
: &[Var
], state
: State
) -> HashMap
<Var
, Term
> {
281 let mut result
= HashMap
::new();
283 let term
= state
.subst
.walk(Term
::Var(v
));
284 result
.insert
(v
, state
.eval(term
));
289 impl<F
, S
> Goal
for F
291 F
: Clone
+ Fn(State
) -> S
,
292 S
: Iterator
<Item
= State
>,
295 fn search(&self, state
: State
) -> S
{
314 impl<S
, R
, T
> Iterator
for Plus
<S
, R
>
316 S
: Iterator
<Item
= T
>,
317 R
: Iterator
<Item
= T
>,
321 fn next(&mut self) -> Option
<T
> {
323 Which
::A
=> match self.a
.next() {
325 self.which
= Which
::OnlyB
;
329 self.which
= Which
::B
;
333 Which
::B
=> match self.b
.next() {
335 self.which
= Which
::OnlyA
;
339 self.which
= Which
::A
;
343 Which
::OnlyA
=> match self.a
.next() {
345 self.which
= Which
::Done
;
350 Which
::OnlyB
=> match self.b
.next() {
352 self.which
= Which
::Done
;
362 struct Bind
<S
: Iterator
<Item
= State
>, R
: Goal
> {
365 current
: Option
<R
::Stream
>,
369 impl<S
, R
> Iterator
for Bind
<S
, R
>
371 S
: Iterator
<Item
= State
>,
376 fn next(&mut self) -> Option
<Self::Item
> {
380 match &mut self.current
{
382 if let Some(state
) = self.a
.next() {
383 self.current
= Some(self.b
.search(state
));
390 Some(stream
) => match stream
.next() {