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)
}
}