How to Configure ReteEngine Rules for Compliance Workflows in Semantica

Use ReteEngine from semantica/reasoning/rete_engine.py to build a Rete network of Alpha and Beta nodes, inject compliance facts, and run pattern matching to trigger rule-based actions.

Overview of Rete Algorithm Implementation

Semantica implements a classic Rete algorithm through the ReteEngine class located in semantica/reasoning/rete_engine.py. The engine constructs a network where Alpha nodes filter single conditions, Beta nodes perform joins across conditions, and Terminal nodes fire when all rule conditions are satisfied. This architecture delivers efficient forward-chaining inference ideal for real-time compliance monitoring.

The ReteEngine operates independently from the high-level Reasoner façade, giving you fine-grained control over rule compilation, fact propagation, and match execution.

Instantiating and Configuring ReteEngine

Create a ReteEngine instance by passing an optional configuration dictionary that controls logging and progress tracking:

from semantica.reasoning import ReteEngine

engine = ReteEngine(config={"max_facts": 1000, "verbose": True})

The constructor at lines 32-44 in semantica/reasoning/rete_engine.py initializes internal components including a progress tracker via get_progress_tracker() and a logger via get_logger() from semantica/utils/logging.py. These utilities emit structured status updates throughout the compliance workflow.

Defining Compliance Rules

Rules in Semantica use the Rule dataclass defined in semantica/reasoning/reasoner.py (lines 24-33). Each rule requires:

  • rule_id: Unique identifier for audit trails
  • name: Human-readable description
  • conditions: List of predicate strings with variable bindings
  • conclusion: The derived fact when conditions match

For compliance workflows, conditions typically express regulatory requirements:

from semantica.reasoning import Rule

gdpr_retention_rule = Rule(
    rule_id="gdpr_001",
    name="Data Retention Limit Exceeded",
    conditions=[
        "CustomerData(?d)",
        "CollectionDate(?d, ?date)",
        "CurrentDate(?now)",
        "days_elapsed(?date, ?now, ?days)",
        "?days > 2555"  # 7 years in days

    ],
    conclusion="RequireDataDeletion(?d)"
)

Building the Rete Network

Add rules to the network using ReteEngine.add_rule():

engine.add_rule(gdpr_retention_rule)

This method forwards to _add_rule_to_network() (lines 55-74 in rete_engine.py), which:

  1. Creates an Alpha node for each condition to filter incoming facts
  2. Chains Beta nodes to perform joins between condition matches
  3. Attaches a Terminal node containing the original Rule object

The network structure minimizes redundant matching—a critical optimization when processing high-volume compliance events.

Injecting Compliance Facts

Facts represent compliance events, entity attributes, or system states. The Fact dataclass in semantica/reasoning/reasoner.py stores:

  • fact_id: Unique identifier
  • predicate: The fact type
  • arguments: Variable bindings

Insert facts and trigger immediate Alpha node propagation:

from semantica.reasoning import Fact

# Insert a customer data record

engine.add_fact(Fact("f_001", "CustomerData", ["record_4732"]))
engine.add_fact(Fact("f_002", "CollectionDate", ["record_4732", "2015-06-01"]))
engine.add_fact(Fact("f_003", "CurrentDate", ["2024-01-15"]))

# Derived fact from external calculation

engine.add_fact(Fact("f_004", "days_elapsed", ["2015-06-01", "2024-01-15", "3165"]))

The add_fact() implementation at lines 24-36 stores facts in working memory and pushes them through the Alpha network without waiting for explicit matching calls.

Pattern Matching and Rule Execution

Trigger the matcher to collect all rule activations:

matches = engine.match_patterns()

match_patterns() (lines 66-78) traverses the network, gathers activations from Terminal nodes, and returns Match objects containing:

  • The matched Rule
  • Contributing Fact instances
  • Optional confidence score for probabilistic compliance

Execute matched rules to generate compliance actions:

results = engine.execute_matches(matches)

The execute_matches() method at lines 84-94 iterates over matches and returns conclusion payloads. For compliance workflows, these payloads typically trigger alerts, audit logging, or remediation workflows:

for match in matches:
    print(f"COMPLIANCE ALERT: {match.rule.name}")
    print(f"Entities: {match.facts}")
    print(f"Action required: {match.rule.conclusion}")

Complete Compliance Workflow Example

from semantica.reasoning import ReteEngine, Fact, Rule

# Initialize engine with compliance-tuned configuration

engine = ReteEngine(config={"max_facts": 5000})

# Define SOX-compliant financial transaction rule

sox_rule = Rule(
    rule_id="sox_402_001",
    name="Segregation of Duties Violation",
    conditions=[
        "PurchaseOrder(?po)",
        "CreatedBy(?po, ?user1)",
        "ApprovedBy(?po, ?user2)",
        "?user1 == ?user2"
    ],
    conclusion="SoxViolation(?po, ?user1)"
)

engine.add_rule(sox_rule)

# Inject transaction events

engine.add_fact(Fact("e_001", "PurchaseOrder", ["PO-2024-0892"]))
engine.add_fact(Fact("e_002", "CreatedBy", ["PO-2024-0892", "jdoe"]))
engine.add_fact(Fact("e_003", "ApprovedBy", ["PO-2024-0892", "jdoe"]))

# Detect violations

violations = engine.match_patterns()
if violations:
    actions = engine.execute_matches(violations)
    notify_audit_team(actions)

# Reset for next batch processing

engine.reset()

Using the High-Level Reasoner Façade

For simpler compliance scenarios, delegate to the Reasoner class (lines 57-70 in semantica/reasoning/reasoner.py), which internally instantiates ReteEngine:

from semantica.reasoning import Reasoner

reasoner = Reasoner()  # Creates internal ReteEngine

# Parse rule from string

reasoner.add_rule(
    "IF PurchaseOrder(?po) AND HighValue(?po, true) AND MissingApproval(?po) "
    "THEN EscalateToManager(?po)"
)

# Add facts as strings (auto-parsed)

reasoner.add_fact("PurchaseOrder(PO-2024-0892)")
reasoner.add_fact("HighValue(PO-2024-0892, true)")
reasoner.add_fact("MissingApproval(PO-2024-0892)")

# Run forward-chaining inference

new_facts = reasoner.infer_facts()
print("Compliance actions triggered:", new_facts)

The _parse_rule_definition() method in Reasoner converts string rules to Rule objects compatible with the underlying ReteEngine.

Engine Lifecycle Management

After processing a compliance batch, reset the engine state:

engine.reset()

The reset() implementation at lines 62-72 clears:

  • Working memory facts
  • Node activation states
  • Partial match buffers

This prepares the engine for the next compliance cycle without rebuilding the rule network—significant optimization for long-running compliance services.

Key Source Files

File Purpose
semantica/reasoning/rete_engine.py Core Rete implementation: ReteEngine class, Alpha/Beta/Terminal nodes, add_rule(), add_fact(), match_patterns(), execute_matches(), reset()
semantica/reasoning/reasoner.py High-level façade: Rule and Fact dataclasses, Reasoner class with string parsing
semantica/utils/logging.py get_logger() used throughout Rete engine
semantica/utils/progress_tracker.py get_progress_tracker() for structured status updates

Summary

  • Instantiate ReteEngine with optional configuration for logging and limits
  • Define rules using the Rule dataclass with predicate conditions and conclusions
  • Build networks via add_rule(), which compiles conditions to Alpha/Beta/Terminal nodes
  • Inject facts with add_fact() for immediate network propagation
  • Match patterns using match_patterns() to collect rule activations
  • Execute actions through execute_matches() to deliver compliance payloads
  • Reset state with reset() between workflow batches without network reconstruction
  • Choose abstraction: direct ReteEngine control for performance, Reasoner façade for convenience

Frequently Asked Questions

How does the Rete algorithm improve compliance detection performance?

The Rete algorithm eliminates redundant condition evaluation by sharing Alpha nodes across rules and caching partial matches in Beta nodes. In semantica/reasoning/rete_engine.py, the network structure persists across fact insertions, so adding new compliance events only evaluates changed conditions rather than re-running complete rules.

Can I modify rules dynamically without restarting the engine?

Yes. Call engine.add_rule() at any time to compile new rules into the existing network. The _add_rule_to_network() method extends the Alpha/Beta structure incrementally. However, removing rules requires engine reset and rebuild—there is no remove_rule() method in the current implementation.

What data types can facts contain?

Facts store arguments as lists of strings in the Fact dataclass. The Rete engine performs string matching on predicates and unification on variables. For numeric comparisons like ?amt > 10000, the engine relies on external preprocessing or derived facts injected via add_fact().

How do I integrate ReteEngine with external compliance systems?

Use execute_matches() to bridge to downstream services. The method returns conclusion strings that you can map to REST API calls, message queue publications, or database inserts. The example above demonstrates notifying audit teams—the actions output serves as your integration point.

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 →