Everything that changes while rules fire, as one value threaded through the loop.
Internal. A node is a function of state that returns the state plus the work it
produced. The loop does the walking, which keeps propagation flat and leaves one place
where listener events are emitted. See docs/design/engine.md §1.
:listeners is [{module, state}] rather than a map, so listeners see events in
attachment order and one module can be attached twice with different state.
Summary
Functions
Takes the next unit of work, or :empty.
Appends propagation work.
A state over a network, with empty memory and nothing pending.
Types
@type op() :: {:left | :left_retract, term(), [Rete.Token.t()]} | {:right | :right_retract, term(), [Rete.Element.t()]} | {:retract_facts, term(), [term()]} | {:event, Rete.Listener.event()}
A unit of pending propagation.
:left carries tokens from a parent, :right carries elements from an alpha.
The last two are work a node produces but cannot carry out where it happens. A retraction has to re-enter the alpha network, and telling a listener is not a node's business.
@type t() :: %Rete.Engine.State{ agenda: Rete.Agenda.t(), fired: non_neg_integer(), listeners: [{module(), term()}], memory: Rete.Memory.t(), network: Rete.Network.t(), order: %{required(term()) => non_neg_integer()}, queue: :queue.queue(op()) }
Functions
Takes the next unit of work, or :empty.
Appends propagation work.
@spec new(Rete.Network.t()) :: t()
A state over a network, with empty memory and nothing pending.
:order is the compile position of each production, so two activations of equal
salience fire in the order the rules were written.