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
@type constraint_node() :: {Guesswork.Constraint.t(), nil | Guesswork.Constraint.Result.t()}
@type key() :: Guesswork.Ast.Variable.t() | :stop_conditions
@type t() :: %Guesswork.Constraint.Store{ children: %{required(key()) => t()}, constraints: [constraint_node()] }
Functions
@spec constraints(t()) :: [Guesswork.Constraint.t()]
Pulls all stored constraints.
Pulls all valid descriptions of the containted constraints.
@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.
@spec insert(t(), Guesswork.Constraint.t()) :: t()
@spec insert_stop_condition(t(), Guesswork.Constraint.t()) :: t()
Merges two constraint stores.
@spec new() :: t()
@spec remove_inputs(t(), MapSet.t(Guesswork.Ast.Variable.t())) :: t() | nil
Removes all inputs that are not in the supplied set.
@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.
@spec variables(t()) :: [Guesswork.Ast.Variable.t()]
Returns all variables that the store is aware of. May return duplicates.