1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use super::GoalEnum;
use crate::domains::Domain;
use crate::state::{Fork, State};
use std::iter::repeat;
#[derive(Debug)]
pub(super) struct Any<'a, D>
where
D: Domain<'a>,
{
pub(super) goals: Vec<GoalEnum<'a, D>>,
}
impl<'a, D> Fork<'a, D> for Any<'a, D>
where
D: Domain<'a>,
{
fn fork(&self, state: State<'a, D>) -> crate::state::StateIter<'a, D> {
let goals = self.goals.clone().into_iter();
let states = repeat(state);
Box::new(goals.zip(states).flat_map(|(g, s)| g.apply(s).into_iter()))
}
}
#[macro_export]
macro_rules! any {
($($item:expr),* $(,)?) => {
canrun::Goal::any(vec![$($item),*])
};
}
pub use any;
#[cfg(test)]
mod tests {
use super::any;
use crate as canrun;
use crate::example::I32;
use crate::goals::unify::unify;
use crate::goals::Goal;
use crate::util;
use crate::value::var;
#[test]
fn both_succeeds() {
let x = var();
let goal: Goal<I32> = any![unify(x, 5), unify(x, 7)];
let results = util::goal_resolves_to(goal, x);
assert_eq!(results, vec![5, 7]);
}
#[test]
fn one_succeeds() {
let x = var();
let bad: Goal<I32> = unify(6, 5);
let first = util::goal_resolves_to(any![unify(x, 1), bad.clone()], x);
assert_eq!(first, vec![1]);
let second = util::goal_resolves_to(any![bad, unify(x, 2)], x);
assert_eq!(second, vec![2]);
}
#[test]
fn both_fail() {
let x = var();
let goal: Goal<I32> = any![unify(6, 5), unify(1, 2)];
let results = util::goal_resolves_to(goal, x);
assert_eq!(results, vec![] as Vec<i32>);
}
}