Turns ruleset modules into a Rete.Network.
Internal. The DSL front end already ran at compile time inside each defrule.
What is left at build time is the part that depends on the whole set of rules:
Rete.Compiler.Negation rewrite compound negations into helper productions
disambiguate_codes/1 qualify an expression code two modules disagree on
Rete.Compiler.BetaGraph build the beta nodes, sharing them where possible
Rete.Network group conditions into alpha nodes, index the taxonomyNode sharing is why this cannot happen per rule. Whether two conditions collapse onto one node depends on what every other rule already put in the graph.
Cross-module expression codes. A code is equal exactly when two expressions behave
the same — with one hole. An unqualified call hashes as the bare name. So two modules
that each define ok?/1 differently produce the same code for
{:bar, amt} when ok?(amt). The compiler qualifies a code more than one module
contributed as <code>@<module>, before building anything from it. Sharing within a
module is untouched. Sharing across modules is only an optimisation, and getting it
wrong is silent corruption. See docs/design/ir.md §5.
Summary
Functions
Builds a network from ruleset modules.
Builds a network from productions directly, bypassing module aggregation.
Qualifies every expression code that more than one module contributed.
The beta graph of a network, for inspection.
Functions
@spec build( [module()], keyword() ) :: Rete.Network.t()
Builds a network from ruleset modules.
Options go to Rete.Taxonomy.new/2. :fact_type_fn is the one that matters, and it
defaults to struct, tagged tuple and tagged map.
Rete.Compiler.build([MyRuleset])
Rete.Compiler.build([MyRuleset, OtherRuleset], fact_type_fn: &MyApp.type/1)
@spec build_productions([Rete.IR.Production.t()], [tuple()], keyword()) :: Rete.Network.t()
Builds a network from productions directly, bypassing module aggregation.
Useful for testing a set of productions without a ruleset module per case.
@spec disambiguate_codes([Rete.IR.Production.t()]) :: [Rete.IR.Production.t()]
Qualifies every expression code that more than one module contributed.
If only one module produces an expression's code, this leaves it alone. So nothing changes for a single-module network. See the module doc for why a shared code cannot be trusted across modules.
This is exposed so a test can check the disambiguation, without building a network.
@spec graph(Rete.Network.t()) :: Rete.Compiler.BetaGraph.t()
The beta graph of a network, for inspection.