pub fn and(u: impl Goal + Clone, v: impl Goal + Clone) -> impl Goal + Clone {
move |state: State| Bind {
- a: u.search(state),
+ a: u.search(state).fuse(),
b: v.clone(),
- current: None,
- done: false,
+ streams: Vec::new(),
+ index: 0,
}
}
where
S::Item: Into<Step>,
{
- a: S,
+ a: std::iter::Fuse<S>,
b: R,
- current: Option<R::Stream>,
- done: bool,
+ streams: Vec<R::Stream>,
+ index: usize,
}
impl<S, R> Iterator for Bind<S, R>
type Item = Step;
fn next(&mut self) -> Option<Self::Item> {
- if self.done {
- return None;
+ if self.index == 0 {
+ match self.a.next().map(Into::into) {
+ Some(Step::Working) => return Some(Step::Working),
+ Some(Step::Soln(state)) => self.streams.push(self.b.search(state)),
+ None => (),
+ }
}
- match &mut self.current {
- None => {
- if let Some(step) = self.a.next() {
- match step.into() {
- Step::Soln(state) => {
- self.current = Some(self.b.search(state));
- self.next()
- }
- Step::Working => Some(Step::Working),
- }
- } else {
- self.done = true;
- None
- }
+
+ loop {
+ self.index += 1;
+ if self.streams.is_empty() {
+ return None;
+ } else if self.index >= self.streams.len() {
+ self.index = 0;
}
- Some(stream) => match stream.next() {
+
+ match self.streams[self.index].next() {
None => {
- self.current = None;
- self.next()
+ self.streams.swap_remove(self.index);
}
- item => item,
- },
+ step => {
+ return step;
+ }
+ }
}
}
}
-use mukan::{all, and, call_fresh, delay, eq, fresh, or, reify, Goal, State, Term};
+use mukan::{all, and, call_fresh, delay, eq, fresh, or, reify, Goal, State, Term, Var};
use std::io::Write;
fn main() {
for soln in goal.solve(state).take(5) {
println!("peano {}", term_to_nat(&soln.eval_var(vars[0])).unwrap());
}
+
+ fn infinite(x: Var) -> impl Goal + Clone {
+ or(eq(x, x), delay(move || infinite(x)))
+ }
+
+ println!("And Fairness");
+ let goal = fresh!((x) => all! {
+ peano(x),
+ infinite(x),
+ });
+ for soln in goal.solve(State::new()).take(5) {
+ println!("{}", soln);
+ }
}