View Source Guesswork.Constraint.Store (Guesswork v0.8.0)

The constraint store is just a trie that uses the input variables as keys to the constraint, allowing for faster look up of constraints that can be resolved. Note that a single constraint can be listed multiple times since constraints can have multiple 'directions' (if a = b then the constraint can be resolved by knowing either a or b).

Stop Conditions

To allow stop conditions to be handled by this constraint store, the top level node has a special child with the key stop_conditions. Should any constraint under that child return :error the store converts it to :halt. To ensure this happens before a conflict is created in the answer set, when searching the tree stop_conditions is always searched before other children.

Plural Results

When a constraint returns a plural result the constraint needs to be kept for a more exact result. To handle this, all constraints are stored with the last result, which is checked. If the two values are equal, the search continues. If they are not, the result is returned but the constraint is retained if the returned value is plural.

Memory Performance

This data structure prizes search effiency over memory efficiency, meaning passing tests (constraints that evaluate to :ok) that could be dropped sometimes are not when it is easier to just keep searching the tree.

Summary

Functions

Pulls all stored constraints.

Pulls all valid descriptions of the containted constraints.

Takes the constraint store and an env, then returns the result of the first valid constraint reached.

Merges two constraint stores.

Removes all inputs that are not in the supplied set.

Walks the trie removing any constraints for which all inputs are in the env and not plural. No constraints are resolved, only removed.

Returns all variables that the store is aware of. May return duplicates.

Types

constraint_node()

@type constraint_node() ::
  {Guesswork.Constraint.t(), nil | Guesswork.Constraint.Result.t()}

key()

@type key() :: Guesswork.Ast.Variable.t() | :stop_conditions

t()

@type t() :: %Guesswork.Constraint.Store{
  children: %{required(key()) => t()},
  constraints: [constraint_node()]
}

Functions

constraints(store)

@spec constraints(t()) :: [Guesswork.Constraint.t()]

Pulls all stored constraints.

describe(store)

@spec describe(t() | nil) :: [String.t(), ...] | nil

Pulls all valid descriptions of the containted constraints.

eval_first(store, env, query_id)

@spec eval_first(t(), Guesswork.Ast.Statement.env(), String.t()) ::
  :noanswer | :halt | :error | {:ok, Guesswork.Constraint.Result.t(), t() | nil}

Takes the constraint store and an env, then returns the result of the first valid constraint reached.

insert(store, constraint)

@spec insert(t(), Guesswork.Constraint.t()) :: t()

insert_stop_condition(store, constraint)

@spec insert_stop_condition(t(), Guesswork.Constraint.t()) :: t()

merge(store1, store2)

@spec merge(t(), t()) :: t()

Merges two constraint stores.

new()

@spec new() :: t()

remove_inputs(store, vars)

@spec remove_inputs(t(), MapSet.t(Guesswork.Ast.Variable.t())) :: t() | nil

Removes all inputs that are not in the supplied set.

remove_resolvable_constraints(store, env)

@spec remove_resolvable_constraints(t(), Guesswork.Ast.Statement.env()) :: t() | nil

Walks the trie removing any constraints for which all inputs are in the env and not plural. No constraints are resolved, only removed.

variables(store)

@spec variables(t()) :: [Guesswork.Ast.Variable.t()]

Returns all variables that the store is aware of. May return duplicates.