Struct canrun::core::State

source ·
pub struct State { /* private fields */ }
Expand description

The core struct used to contain and manage Value bindings.

An open State can be updated in a few different ways. Most update methods return an Option<State> to reflect the fact each new constraint can invalidate the state. This gives you the ability to quickly short circuit with the ? operator as soon the state hits a dead end.

A State is designed to be cheap to clone(), so make a copy if you want to try multiple paths.

In general, it is most ergonomic to manipulate a state inside a function that returns an Option<State> to allow the use of the question mark operator (Note that the .apply() function makes it easy to do this).

use canrun::{State, Value};

fn my_fn() -> Option<State> {
    let x = Value::var();
    let y = Value::var();
    let state = State::new();
    let maybe: Option<State> = state.unify(&x, &Value::new(1));
    maybe?.unify(&x, &y)
}
assert!(my_fn().is_some());

Implementations§

source§

impl State

source

pub fn new() -> Self

Create a new, empty state.

This often does not need to be used directly as you can .query() a Goal directly, which handles the state creation internally.

However, there are use cases for creating and managing a state independently of any goals.

Example:
use canrun::{State};
let state = State::new();
source

pub fn apply<F>(self, func: F) -> Option<Self>where F: Fn(Self) -> Option<Self>,

Apply an arbitrary function to a state.

This is primarily a helper to make it easier to get into a function where you can use the question mark operator while applying multiple updates to a state.

Example:
use canrun::{State, Query, Value};

let state = State::new();
let x = Value::var();
let state = state.apply(|s| {
    s.unify(&x, &Value::new(1))?
     .unify(&Value::new(1), &x)
});
let results: Vec<_> = state.query(x).collect();
assert_eq!(results, vec![1]);
source

pub fn resolve<T: Unify>(&self, val: &Value<T>) -> Value<T>

Recursively resolve a Value as far as the currently known variable bindings allow.

This will return either the final Value::Resolved (if found) or the last Value::Var it attempted to resolve. It will not force forks to enumerate all potential states, so potential bindings that may eventually become confirmed are not considered. Use StateIterator::into_states if you want to attempt resolving against all (known) possible states.

Example:
use canrun::{State, Query, Value};

let state = State::new();

let x = Value::var();
assert_eq!(state.resolve(&x), x);

let state = state.unify(&x, &Value::new(1))?;
assert_eq!(state.resolve(&x), Value::new(1));
source

pub fn unify<T: Unify>(self, a: &Value<T>, b: &Value<T>) -> Option<Self>

Attempt to unify two values with each other.

If the unification fails, None will be returned. Value::Vars will be checked against relevant constraints, which can also cause a state to fail.

Examples:
use canrun::{State, Query, Value};

let x = Value::var();

let state = State::new();
let state = state.unify(&x, &Value::new(1));
assert!(state.is_some());
let state = State::new();
let state = state.unify(&Value::new(1), &Value::new(2));
assert!(state.is_none());
source

pub fn constrain(self, constraint: Rc<dyn Constraint>) -> Option<Self>

Add a constraint to the store that can be reevaluated as variables are resolved.

Some logic is not easy or even possible to express until the resolved values are available. .constrain() provides a low level way to run custom imperative code whenever certain bindings are updated.

See the Constraint trait for more usage information.

source

pub fn fork(self, fork: impl Fork) -> Option<Self>

Add a potential fork point to the state.

If there are many possibilities for a certain value or set of values, this method allows you to add a Fork object that can enumerate those possible alternate states.

While this is not quite as finicky as Constraints, you still probably want to use the any or either goals.

Unification is performed eagerly as soon as it is called. Constraints are run as variables are resolved. Forking is executed lazily at the end, when StateIterator::into_states or .query() is called.

source

pub fn vars(&self) -> LVarList

Generate a list of LVars in this state. This takes into account bound variables and constraint watches.

source

pub fn is_ready(&self) -> bool

Returns true if the State has no open forks or constraints.

If ready, then a ReadyState can be derived with State::ready().

source

pub fn ready(self) -> Option<ReadyState>

Returns a ReadyState if the State has no open forks or constraints.

Trait Implementations§

source§

impl Clone for State

source§

fn clone(&self) -> State

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Default for State

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl StateIterator for State

source§

fn into_states(self) -> StateIter

Iterate over States by applying all pending Forks and checking Constraints.

Auto Trait Implementations§

§

impl !RefUnwindSafe for State

§

impl !Send for State

§

impl !Sync for State

§

impl Unpin for State

§

impl !UnwindSafe for State

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<'a, S> Query<'a> for Swhere S: StateIterator + 'a,

source§

fn query<Q>( self, query: Q ) -> Box<dyn Iterator<Item = <Q as Reify>::Reified> + 'a, Global>where Q: Reify + 'a,

Get reified results from things that can produce StateIters. Read more
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.