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
use super::resolved::ResolvedState;
use super::State;
use crate::domains::Domain;

/** An Iterator of [`ResolvedStates`](crate::state::ResolvedState).

Typically obtained through the
[`.iter_resolved()`](IterResolved::iter_resolved()) trait.
*/
pub type ResolvedStateIter<'s, D> = Box<dyn Iterator<Item = ResolvedState<D>> + 's>;

/** Iterate over [`ResolvedStates`](crate::state::ResolvedState).

This trait is implemented on the typical values that contain or represent an
open state, such as [`Goal`](crate::goals::Goal) and of course
[`State`](crate::state::State) itself.
*/
pub trait IterResolved<'a, D: Domain<'a> + 'a> {
    /** Get an iterator of all valid, [resolved
    states](crate::state::ResolvedState) that can be derived.

    Typically used indirectly through the
    [`Query`](crate::Query) interface.

    This will iterate through all pending
    [forks](crate::state::State::fork()), discarding any that fail. Any
    unsatisfied [constraints](crate::state::State::constrain()) will also
    cause a potential resolved state to fail.

    # Example:
    ```
    use canrun::{State, ResolvedState, IterResolved, val, var};
    use canrun::example::I32;

    let x = var();

    let state = State::new()
        .unify(&val!(x), &val!(1));
    let results: Vec<ResolvedState<I32>> = state.iter_resolved().collect();
    ```
    */
    fn iter_resolved(self) -> ResolvedStateIter<'a, D>;
}

impl<'a, D: Domain<'a> + 'a> IterResolved<'a, D> for State<'a, D> {
    fn iter_resolved(self) -> ResolvedStateIter<'a, D> {
        Box::new(self.iter_forks().filter_map(|s: State<'a, D>| {
            if s.constraints.is_empty() {
                Some(ResolvedState { domain: s.domain })
            } else {
                None
            }
        }))
    }
}

impl<'a, D: Domain<'a> + 'a> IterResolved<'a, D> for Option<State<'a, D>> {
    fn iter_resolved(self) -> ResolvedStateIter<'a, D> {
        Box::new(self.into_iter().flat_map(State::iter_resolved))
    }
}