]>
Witch of Git - mukan/blob - src/lib.rs
20c39610f0778c07bda34c030851ac74833308c6
1 use dyn_clone
::{self, DynClone
};
6 pub use term
::{Term
, Var
};
8 #[derive(Debug, Clone, Default)]
14 #[derive(Debug, Clone)]
20 impl From
<State
> for Step
{
21 fn from(state
: State
) -> Step
{
26 pub fn delay
<G
: Goal
>(thunk
: impl Clone
+ Fn() -> G
+ '
static) -> BoxedGoal
{
27 BoxedGoal
::new(move |state
: State
| thunk().search(state
))
31 pub struct BoxedGoal
{
32 inner
: Box
<dyn Goal
<Stream
= Box
<dyn Iterator
<Item
= Step
>>>>,
36 fn new(goal
: impl Goal
+ Clone
+ '
static) -> Self {
38 inner
: Box
::new(BoxGoalInner(goal
)) as Box
<dyn Goal
<Stream
= _
>>,
43 impl Goal
for BoxedGoal
{
44 type Stream
= Box
<dyn Iterator
<Item
= Step
>>;
45 fn search(&self, state
: State
) -> Self::Stream
{
46 self.inner
.search(state
)
51 struct BoxGoalInner
<G
>(G
);
53 impl<G
> Goal
for BoxGoalInner
<G
>
55 G
: Goal
+ Clone
+ '
static,
57 type Stream
= Box
<dyn Iterator
<Item
= Step
>>;
58 fn search(&self, state
: State
) -> Self::Stream
{
59 Box
::new(BoxedGoalIter
{
68 struct BoxedGoalIter
<G
: Goal
> {
72 iter
: Option
<G
::Stream
>,
75 impl<G
> Iterator
for BoxedGoalIter
<G
>
81 fn next(&mut self) -> Option
<Step
> {
84 return Some(Step
::Working
);
86 match &mut self.iter
{
87 Some(iter
) => iter
.next(),
89 let mut iter
= self.goal
.search(self.state
.take().unwrap
());
90 let result
= iter
.next();
91 self.iter
= Some(iter
);
98 pub trait Goal
: DynClone
{
99 type Stream
: Iterator
<Item
= Step
>;
100 fn search(&self, state
: State
) -> Self::Stream
;
101 fn solve(&self, state
: State
) -> std
::iter
::FilterMap
<Self::Stream
, fn(Step
) -> Option
<State
>> {
102 self.search(state
).filter
_map
(|step
| match step
{
103 Step
::Working
=> None
,
104 Step
::Soln(state
) => Some(state
),
109 dyn_clone
::clone_trait_object
!(Goal
<Stream
= Box
<dyn Iterator
<Item
= Step
>>>);
111 pub fn call_fresh
<G
: Goal
>(block
: impl Clone
+ Fn(Var
) -> G
) -> impl Goal
+ Clone
{
112 move |mut state
: State
| {
113 let var
= Var(state
.fresh
);
115 block(var
).search(state
)
121 (() => $e
:expr
) => { $e
};
122 (($v
:ident $
(, $vs
:ident
)* $
(,)?
) => $e
:expr
) => {
123 call_fresh(move |$v
| $
crate::fresh
!(($
($vs
),*) => $e
))
129 () => { |state
: State
| std
::iter
::once(state
) };
131 ($e
:expr $
(, $es
:expr
)* $
(,)?
) => {
132 and($e
, all
!($
($es
),*))
138 () => { |state
: State
| std
::iter
::empty() };
140 ($e
:expr $
(, $es
:expr
)* $
(,)?
) => {
141 or($e
, any
!($
($es
),*))
145 pub fn eq(u
: impl Into
<Term
>, v
: impl Into
<Term
>) -> impl Goal
+ Clone
{
148 move |state
: State
| state
.un
ify
(&u
, &v
).into
_iter
()
151 pub fn and(u
: impl Goal
+ Clone
, v
: impl Goal
+ Clone
) -> impl Goal
+ Clone
{
152 move |state
: State
| Bind
{
160 pub fn or(u
: impl Goal
+ Clone
, v
: impl Goal
+ Clone
) -> impl Goal
+ Clone
{
161 move |state
: State
| Plus
{
162 a
: u
.search(state
.clone()),
169 pub fn new() -> Self {
173 pub fn with_vars(n
: u32) -> (Vec
<Var
>, Self) {
174 let vars
= (0..n
).map(|v
| Var(v
)).collect();
184 pub fn unify(&self, u
: &Term
, v
: &Term
) -> Option
<State
> {
185 self.subst
.un
ify
(u
, v
).map(|subst
| State
{
191 pub fn eval_var(&self, var
: Var
) -> Term
{
192 let var
= Term
::Var(var
);
196 pub fn eval(&self, term
: &Term
) -> Term
{
197 match self.subst
.walk(&term
) {
198 Term
::Pair(u
, v
) => Term
::from((self.eval(&*u
), self.eval(&*v
))),
199 term
=> term
.clone(),
204 #[derive(Debug, Clone, Default)]
205 struct Subst(HashMap
<Var
, Term
>);
208 fn walk
<'a
>(&'a
self, mut term
: &'a Term
) -> &'a Term
{
209 while let Term
::Var(var
) = term
{
210 match self.0.get(&var
) {
218 fn extended(&self, var
: Var
, term
: Term
) -> Self {
219 Subst(self.0.update
(var
, term
))
222 fn unify(&self, u
: &Term
, v
: &Term
) -> Option
<Subst
> {
223 let u
= self.walk(&u
);
224 let v
= self.walk(&v
);
226 (u
, v
) if u
== v
=> Some(self.clone()),
227 (Term
::Var(u
), term
) => Some(self.clone().extended(*u
, term
.clone())),
228 (term
, Term
::Var(v
)) => Some(self.clone().extended(*v
, term
.clone())),
229 (Term
::Pair(u0
, u1
), Term
::Pair(v0
, v1
)) => {
230 self.un
ify
(&*u0
, &*v0
).and_then(|s
| s
.un
ify
(&*u1
, &*v1
))
237 pub fn reify(state
: State
) -> HashMap
<Var
, Term
> {
238 let mut result
= HashMap
::new();
239 for &v
in state
.subst
.0.keys() {
240 let var
= Term
::Var(v
);
241 let term
= state
.subst
.walk(&var
);
242 result
.insert
(v
, state
.eval(term
));
247 pub fn reify_vars(vars
: &[Var
], state
: State
) -> HashMap
<Var
, Term
> {
248 let mut result
= HashMap
::new();
250 let var
= Term
::Var(v
);
251 let term
= state
.subst
.walk(&var
);
252 result
.insert
(v
, state
.eval(term
));
257 impl<F
, S
, St
> Goal
for F
259 F
: Clone
+ Fn(State
) -> S
,
260 S
: Iterator
<Item
= St
>,
263 type Stream
= std
::iter
::Map
<S
, fn(St
) -> Step
>;
264 fn search(&self, state
: State
) -> Self::Stream
{
265 self(state
).map(Into
::into
)
283 impl<S
, R
, T
> Iterator
for Plus
<S
, R
>
285 S
: Iterator
<Item
= T
>,
286 R
: Iterator
<Item
= T
>,
289 fn next(&mut self) -> Option
<T
> {
291 Which
::A
=> match self.a
.next() {
293 self.which
= Which
::OnlyB
;
297 self.which
= Which
::B
;
301 Which
::B
=> match self.b
.next() {
303 self.which
= Which
::OnlyA
;
307 self.which
= Which
::A
;
311 Which
::OnlyA
=> match self.a
.next() {
313 self.which
= Which
::Done
;
318 Which
::OnlyB
=> match self.b
.next() {
320 self.which
= Which
::Done
;
330 struct Bind
<S
: Iterator
, R
: Goal
>
336 current
: Option
<R
::Stream
>,
340 impl<S
, R
> Iterator
for Bind
<S
, R
>
348 fn next(&mut self) -> Option
<Self::Item
> {
352 match &mut self.current
{
354 if let Some(step
) = self.a
.next() {
356 Step
::Soln(state
) => {
357 self.current
= Some(self.b
.search(state
));
360 Step
::Working
=> Some(Step
::Working
),
367 Some(stream
) => match stream
.next() {
378 impl fmt
::Display
for Subst
{
379 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
381 .entries(self.0.iter
().map(|x
| (&x
.0, &x
.1)))
386 impl fmt
::Display
for State
{
387 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
388 write
!(fmt
, "#{} {}", self.fresh
, self.subst
)