How to Set Up Rete Engine Forward Chaining for Rule-Based Compliance Inference in Semantica

You set up Rete engine forward chaining for rule-based compliance inference in Semantica by defining compliance Rule objects, building a ReteEngine network, inserting Fact instances into working memory, and invoking match_patterns() or the high-level Reasoner.forward_chain() method to derive conclusions until no new facts are produced.

Setting up Rete engine forward chaining for rule-based compliance inference starts with the ReteEngine class located in semantica/reasoning/rete_engine.py. The semantica-agi/semantica repository implements a complete Rete algorithm that compiles compliance rules into a directed network of Alpha, Beta, and Terminal nodes. Once facts are inserted, the engine propagates them through these nodes to activate rules and return Match objects containing violations or verdicts.

Core Rete Network Architecture

The Semantica Rete implementation is structured around four primary node types defined in semantica/reasoning/rete_engine.py. Each node handles a distinct phase of pattern matching during forward chaining.

  • AlphaNode — Single-condition filters that evaluate individual predicates against incoming facts.
  • BetaNode — Join nodes that combine partial matches from multiple Alpha nodes to satisfy composite rule conditions.
  • TerminalNode — The final network node that fires when all conditions for a specific Rule are satisfied.
  • ReteEngine — Orchestrates network construction, fact propagation, and match extraction via build_network(), add_fact(), and match_patterns().

When engine.build_network(rules) is called, the engine internally constructs these nodes and stores the resulting graph in engine.network. Facts inserted with engine.add_fact() flow from Alpha nodes through Beta nodes, ultimately reaching Terminal nodes that represent activated compliance rules.

Step-by-Step: Rete Forward Chaining for Compliance Inference

Define Compliance Rules as Rule Objects

Compliance logic is expressed through the Rule dataclass defined in semantica/reasoning/reasoner.py. Each rule specifies a set of conditions that must hold and a conclusion representing a compliance verdict. IF-THEN strings are automatically parsed by _parse_rule_definition into structured Rule instances.

from semantica.reasoning import Rule

compliance_rules = [
    "IF employee(age < 18) AND employee(role = 'driver') THEN violation('Underage driver')",
    "IF data(access_level = 'confidential') AND NOT user(clearance = 'high') THEN violation('Insufficient clearance')",
]

rules = [
    Rule(rule_id=f"c{i}", name=f"Compliance {i}", conditions=[], conclusion=r)
    for i, r in enumerate(compliance_rules)
]

Build the Rete Network

Initialize ReteEngine and compile the rules into the Rete network. This step creates the underlying Alpha, Beta, and Terminal nodes required for forward chaining.

from semantica.reasoning import ReteEngine

engine = ReteEngine()
engine.build_network(rules)

After construction, the network resides in engine.network and is ready to accept facts.

Insert Facts into Working Memory

Facts represent the current state of the system and are defined by the Fact dataclass in semantica/reasoning/reasoner.py. Each Fact carries a predicate and arguments that the Alpha nodes match against rule conditions.

from semantica.reasoning import Fact

engine.add_fact(Fact("f1", "employee", ["John", "age", 16]))
engine.add_fact(Fact("f2", "employee", ["John", "role", "driver"]))
engine.add_fact(Fact("f3", "user", ["Alice", "clearance", "medium"]))
engine.add_fact(Fact("f4", "data", ["ProjectX", "access_level", "confidential"]))

Each fact is propagated through the network immediately upon insertion. Matching facts traverse Beta joins and activate Terminal nodes when all rule conditions are met.

Execute Forward Chaining and Retrieve Matches

To extract compliance conclusions, call engine.match_patterns(). This method returns a list of Match objects, each containing the fired rule, the matched facts, and optional confidence scores. Alternatively, engine.execute_matches() retrieves the raw conclusions directly.

matches = engine.match_patterns()
violations = [m.rule.conclusion for m in matches]

print("Detected compliance violations:", violations)

The output contains every conclusion whose conditions were satisfied by the current working memory.

High-Level Forward Chaining with the Reasoner Class

For production workflows, the Reasoner class in semantica/reasoning/reasoner.py provides a façade around the raw ReteEngine. Its forward_chain() method repeatedly invokes the Rete network until the working memory reaches a fixed point or a configurable iteration limit is reached.

from semantica.reasoning import Reasoner

reasoner = Reasoner()

for rule_str in compliance_rules:
    reasoner.add_rule(rule_str)

reasoner.add_fact("employee(John, age, 16)")
reasoner.add_fact("employee(John, role, driver)")
reasoner.add_fact("user(Alice, clearance, medium)")
reasoner.add_fact("data(ProjectX, access_level, confidential)")

inferred = reasoner.forward_chain()
print([res.conclusion for res in inferred])

This high-level loop guarantees that all derivable compliance violations are inferred in a single pass without manually managing the engine’s iteration cycle.

Instrumentation and Logging

Long-running compliance jobs can be instrumented with ProgressTracker and the centralized logger from semantica/utils/progress_tracker.py and semantica/utils/logging.py. The engine accesses these utilities through get_logger("rete_engine"). While optional, adding instrumentation is recommended when processing large rule sets or high-volume fact streams.

Summary

  • The Semantica Rete engine lives in semantica/reasoning/rete_engine.py and implements Alpha, Beta, and Terminal nodes for efficient pattern matching.
  • Compliance rules are modeled as Rule objects in semantica/reasoning/reasoner.py, with optional automatic parsing of IF-THEN strings.
  • Call ReteEngine.build_network(rules) to compile rules, then add_fact(Fact(...)) to propagate system state through the network.
  • Invoke match_patterns() for detailed Match results or execute_matches() for raw conclusions.
  • Use Reasoner.forward_chain() as a high-level, fixed-point forward-chaining loop that drives the Rete engine automatically.

Frequently Asked Questions

What is the difference between match_patterns() and execute_matches()?

match_patterns() returns a list of Match objects that include the fired rule, the matching facts, and any confidence scores. execute_matches() provides a lower-level interface that returns the raw conclusions directly without the surrounding match metadata.

When should I use the Reasoner class instead of ReteEngine directly?

Use Reasoner when you need a managed forward-chaining loop that automatically re-evaluates the Rete network until no new facts are derived. Use ReteEngine directly when you require fine-grained control over fact insertion, network construction, or incremental pattern matching.

How are IF-THEN compliance rule strings converted into structured objects?

IF-THEN strings are parsed by _parse_rule_definition inside semantica/reasoning/reasoner.py. The resulting structure populates the conditions and conclusion fields of a Rule dataclass that the ReteEngine can compile into Alpha and Beta nodes.

What tools does Semantica provide for monitoring long-running inference?

The repository includes ProgressTracker in semantica/utils/progress_tracker.py and a centralized logger in semantica/utils/logging.py. The Rete engine uses get_logger("rete_engine") to emit diagnostic events, making these utilities suitable for tracking performance and progress on large compliance rule sets.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →