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
use crate::{
    core::{AnyVal, Unify, Value, VarId},
    resolve_any, Reify,
};

/**
Derives from a [`State`](crate::State) that has been confirmed to have no open forks or constraints.
A `ReadyState` can have [`Value`]s [reified](ReadyState::reify).
 */
#[derive(Clone)]
pub struct ReadyState {
    pub(crate) values: im_rc::HashMap<VarId, AnyVal>,
}

impl ReadyState {
    pub(crate) fn new(values: im_rc::HashMap<VarId, AnyVal>) -> Self {
        ReadyState { values }
    }

    /** Recursively resolve a [`Value`] as far as the currently
    known variable bindings allow.

    See [`crate::State::resolve`] for more details.
    */
    pub fn resolve<T: Unify>(&self, val: &Value<T>) -> Value<T> {
        resolve_any(&self.values, &val.to_anyval())
            .to_value()
            // I think this should be safe, so long as we are careful to only
            // store a var with the correct type internally.
            .expect("AnyVal resolved to unexpected Value<T>")
    }

    /** Attempt to [reify](crate::core::Reify) the value of a [logic
    variable](crate::core::LVar) in a [`ReadyState`].

    # Example:
    ```
    use canrun::{State, StateIterator, Value, LVar};

    let x = LVar::new();

    let state = State::new()
        .unify(&x.into(), &Value::new(1));

    let results: Vec<_> = state.into_states()
        .filter_map(|s| s.ready())
        .map(|resolved| resolved.reify(&x))
        .collect();

    assert_eq!(results, vec![Some(1)]);
    ```
    */
    pub fn reify<T, R>(&self, value: &T) -> Option<R>
    where
        T: Reify<Reified = R>,
    {
        value.reify_in(self)
    }
}