Files
semantica/docs/reference/reasoning.md
T
KaifAhmad1 3b637ea140 docs(reference): fix class names and expand API coverage across 8 modules
- normalize: replace non-existent DataNormalizer with correct classes (TextNormalizer, EntityNormalizer, DateNormalizer, NumberNormalizer, DataCleaner)
- deduplication: replace non-existent EntityResolver with correct API (DuplicateDetector, EntityMerger, SimilarityCalculator, ClusterBuilder)
- reasoning: replace non-existent ReasoningEngine/DeductiveEngine/AbductiveEngine with correct classes (Reasoner, GraphReasoner, ReteEngine, SPARQLReasoner, DatalogReasoner, TemporalReasoningEngine, ExplanationGenerator)
- export: fix ArangoExporter->ArangoAQLExporter, GraphMLExporter->GraphExporter; add ArrowExporter, DistanceExporter, ReportGenerator
- conflicts: fix ResolutionStrategy enum values and add SourceTracker, ConflictAnalyzer, InvestigationGuideGenerator
- change_management: add OntologyVersionManager, VersionStorage backends, compute_checksum/verify_checksum
- embeddings: add TextEmbedder, GraphEmbeddingManager, VectorEmbeddingManager, all provider stores, all pooling strategies
- visualization: fix broken See Also href from evals to explorer
2026-05-22 22:03:30 +05:30

7.5 KiB

title, description, icon
title description icon
Reasoning Module Forward chaining, Rete, deductive, abductive, SPARQL, Datalog, and temporal reasoning with explainable inference paths. microchip

Logical inference engine supporting rule-based, SPARQL, Rete, Datalog, and temporal reasoning — all with explainable paths.


Overview

The Reasoning Module derives new knowledge from existing facts using logical rules. Every engine produces explainable inference paths — not black-box conclusions.

Main facade — forward chaining with IF/THEN rules and variable substitution. High-performance pattern matching for large rule sets via the Rete algorithm. Query expansion and property chain inference over RDF graphs. Recursive Horn clause rules with bottom-up fixpoint semantics (v0.4.0). All 13 Allen interval algebra relations for time-aware inference. Structured explanation paths — how each conclusion was derived.

Reasoner (Main Facade)

The unified entry point for rule-based forward-chaining inference:

from semantica.reasoning import Reasoner, Rule, Fact, RuleType

reasoner = Reasoner()

# Add facts
reasoner.add_fact(Fact(subject="John", predicate="is_a", obj="Manager"))
reasoner.add_fact(Fact(subject="John", predicate="is_a", obj="Employee"))

# Add rules
reasoner.add_rule(Rule(
    rule_type=RuleType.FORWARD_CHAIN,
    conditions=[
        {"subject": "?x", "predicate": "is_a", "object": "Manager"}
    ],
    conclusion={"subject": "?x", "predicate": "has_authority", "object": "true"}
))

# Run inference
result = reasoner.infer()
for inference in result.derived_facts:
    print(f"{inference.subject} {inference.predicate} {inference.obj}")
    print(f"  Derived via: {inference.explanation}")

GraphReasoner

Inference over the full knowledge graph structure:

from semantica.reasoning import GraphReasoner

graph_reasoner = GraphReasoner(kg)

# Infer transitive closure
graph_reasoner.add_rule({
    "if": [
        {"subject": "?a", "predicate": "parent_of", "object": "?b"},
        {"subject": "?b", "predicate": "parent_of", "object": "?c"}
    ],
    "then": {"subject": "?a", "predicate": "ancestor_of", "object": "?c"}
})

inferences = graph_reasoner.infer(kg)
for inf in inferences:
    print(f"{inf['subject']} {inf['predicate']} {inf['object']}")

ReteEngine

High-performance pattern matching using the Rete algorithm — far faster than naive forward chaining for large rule sets because it caches partial matches:

from semantica.reasoning import ReteEngine, ReteNode, AlphaNode, BetaNode

engine = ReteEngine()
engine.load_rules("rules/domain_rules.json")
results = engine.run(kg)

# Inspect the network
root: ReteNode = engine.get_root()
alpha_nodes = engine.get_alpha_nodes()   # single-condition filters
beta_nodes  = engine.get_beta_nodes()    # join nodes

Rule format for Rete:

{
  "rules": [
    {
      "name": "manager_authority",
      "conditions": [
        { "subject": "?x", "predicate": "role", "object": "Manager" }
      ],
      "action": { "subject": "?x", "predicate": "has_authority", "object": "true" }
    }
  ]
}

SPARQLReasoner

Query-based inference over RDF graphs:

from semantica.reasoning import SPARQLReasoner, SPARQLQueryResult

reasoner = SPARQLReasoner(graph=rdf_graph)

result: SPARQLQueryResult = reasoner.query("""
    PREFIX ex: <http://example.org/>
    SELECT ?person ?company WHERE {
        ?person ex:founded ?company .
        ?company ex:located_in ex:SiliconValley .
    }
""")

for row in result.bindings:
    print(row["person"], row["company"])

Property chain inference:

# Infer: if A knows B and B is colleague_of C, then A knows C
reasoner.add_property_chain("knows", ["knows", "colleague_of"])
inferences = reasoner.infer_property_chains()

DatalogReasoner (v0.4.0)

Pure-Python bottom-up semi-naive fixpoint evaluation for recursive Horn clause rules. Termination is guaranteed:

from semantica.reasoning import DatalogReasoner, DatalogFact, DatalogRule

datalog = DatalogReasoner()

# Add base facts
datalog.add_fact(DatalogFact("parent", ("alice", "bob")))
datalog.add_fact(DatalogFact("parent", ("bob",  "charlie")))

# Add recursive rules (Horn clauses)
datalog.add_rule(DatalogRule("ancestor(?X, ?Y) :- parent(?X, ?Y)."))
datalog.add_rule(DatalogRule("ancestor(?X, ?Z) :- parent(?X, ?Y), ancestor(?Y, ?Z)."))

# Evaluate to fixpoint
datalog.evaluate()

# Query
results = datalog.query("ancestor(alice, ?Z)")
# → [{"Z": "bob"}, {"Z": "charlie"}]
Datalog termination is guaranteed — the engine detects fixpoint convergence and stops automatically. No infinite loops.

TemporalReasoningEngine

Reason about time intervals using all 13 Allen interval algebra relations:

from semantica.reasoning import TemporalReasoningEngine, TemporalInterval, IntervalRelation

engine = TemporalReasoningEngine()

# Define intervals
ceo_tenure = TemporalInterval(start="1997-09-16", end="2011-08-24")
board_member = TemporalInterval(start="2000-01-01", end="2012-06-01")

# Check interval relations (all 13 Allen relations supported)
relation = engine.get_relation(ceo_tenure, board_member)
# → IntervalRelation.DURING  (ceo_tenure is during board_member)

# Named relations
IntervalRelation.BEFORE       # a ends before b starts
IntervalRelation.MEETS        # a ends exactly when b starts
IntervalRelation.OVERLAPS     # a starts before b, ends inside b
IntervalRelation.DURING       # a is fully inside b
IntervalRelation.STARTS       # a and b start together, a ends first
IntervalRelation.FINISHES     # a and b end together, a starts later
IntervalRelation.EQUALS       # identical intervals
# + 6 inverse relations (AFTER, MET_BY, OVERLAPPED_BY, CONTAINS, STARTED_BY, FINISHED_BY)

ExplanationGenerator

Generate structured explanations for inferences:

from semantica.reasoning import ExplanationGenerator, Explanation, ReasoningPath

generator = ExplanationGenerator(reasoner)

explanation: Explanation = generator.explain(
    conclusion={"subject": "John", "predicate": "has_authority", "object": "true"}
)

print(explanation.conclusion)
print(explanation.confidence)

for step in explanation.reasoning_path.steps:
    print(f"  Step {step.depth}: {step.fact} via rule '{step.rule_name}'")

Built-In Rule Templates

from semantica.reasoning import Reasoner

engine = Reasoner()

# Apply common logical patterns
engine.apply_transitivity("located_in")   # A→B, B→C ⟹ A→C
engine.apply_symmetry("knows")            # A knows B ⟹ B knows A
engine.apply_inverse("parent_of", "child_of")  # A parent_of B ⟹ B child_of A

See Also

The knowledge graph being reasoned over. Ontology axioms and SHACL constraints. RDF backend for SPARQL reasoning. Reasoning integrated into agent intelligence.