The beta side of the network: a graph of Rete.Network.Node descriptions.
Internal. Each production's sorted left hand side is walked in order, adding one
node per condition under the nodes the previous condition produced. Node 0 is an
artificial root, so the graph has a single entry point.
Parents are a list. A disjunction adds each branch as its own chain and hands the union of the branch terminals to the next condition, so the branches re-converge on it. That is why the LHS is never flattened to disjunctive normal form: whole-LHS DNF is exponential in the number of disjunctions, and fanning out per condition is linear.
Sharing requires equality and the same parent set. Equality alone is a correctness
bug: in a({:customer, cid}, {:order, cid, amt}) and b({:vendor, cid}, {:order, cid, amt}) the two order conditions are equal but sit under different parents, and sharing
them would let a :vendor token join a :customer's elements. A terminal keys on the
production's identity, so two rules with an identical LHS fire independently.
{:or, []} is false, and nothing is built for a path through one. A keyless
condition after a false element would otherwise become an entry point the alpha index
feeds, and an unsatisfiable rule would fire on every fact. See
docs/design/network.md ยง4.
Summary
Functions
Adds one production, sharing nodes with everything already in the graph.
Adds every production to a new graph, in order.
The children of a node, in the order they were added.
Every node satisfying a predicate, by ascending id.
An empty graph containing only the root.
The node under an id, or nil.
The parents of a node.
The id of the artificial root every rule hangs from.
Every node whose only parent is the root: the entry points of the beta side.
Types
@type id() :: non_neg_integer()
Node ids, allocated in insertion order.
Functions
@spec add_production(t(), Rete.IR.Production.t()) :: t()
Adds one production, sharing nodes with everything already in the graph.
A production whose left hand side is unsatisfiable โ one that contains a
{:or, []} outside every branch that could avoid it โ adds nothing at all.
@spec build([Rete.IR.Production.t()]) :: t()
Adds every production to a new graph, in order.
Order matters only for id allocation, and therefore only for readability: the same productions in the same order always produce the same ids.
The children of a node, in the order they were added.
@spec filter(t(), (Rete.Network.Node.t() -> boolean())) :: [Rete.Network.Node.t()]
Every node satisfying a predicate, by ascending id.
@spec new() :: t()
An empty graph containing only the root.
@spec node(t(), id()) :: Rete.Network.Node.t() | nil
The node under an id, or nil.
The parents of a node.
@spec root_id() :: id()
The id of the artificial root every rule hangs from.
Every node whose only parent is the root: the entry points of the beta side.