llms.md: - Only Groq/OpenAI/LiteLLM/HuggingFaceLLM are exported — remove non-exported Anthropic/Ollama/Gemini/DeepSeek/Novita as direct imports - Rename HuggingFace -> HuggingFaceLLM (correct class name) - Remove non-existent create_provider() — replace with LiteLLM provider/model pattern - Add LiteLLM 100+ providers section with provider/model string examples - Add Exported Classes table (class -> provider -> API key) - Update Provider Comparison table to show correct import per provider ontology.md: - Remove non-existent OntologyManager — replace with OntologyEngine facade - Remove non-existent start_explorer() — replace with CLI: semantica-explorer - SHACLValidator -> OntologyValidator (correct exported name) - OWLExporter -> OWLGenerator (correct exported name) - Add Exported Classes block with all 15+ exported symbols - Add LLMOntologyGenerator section, NamespaceManager section - Add OntologyEvaluator section with coverage/completeness metrics - Add ingest_ontology() section - Add versioning moved-to note (change_management module) kg.md: - TemporalKnowledgeGraph does not exist — replace with TemporalGraphQuery - DistanceCalculator does not exist — replace with SimilarityCalculator - Add Exported Classes block with all 20+ exported symbols - Fix temporal example to use TemporalGraphQuery + TemporalVersionManager correctly - Add SimilarityCalculator section with NodeEmbedder integration example provenance.md: - ActivityTracker not exported — remove; ProvenanceManager handles tracking - Fix track_entity() signature: add source_location, source_quote params - Fix GraphBuilderWithProvenance import: from semantica.kg, not semantica.provenance - Add Exported Classes block with storage backends and checksum utilities - Add SourceReference section with DOI/page/quote fields - Add tamper-evident checksum section (compute_checksum/verify_checksum) - Add Enable Provenance in Extractors section - Fix duplicate heading (W3C PROV-O Export appeared twice) reasoning.md: - Add Exported Classes block with all engines + data types + explanation types - Add Quick Start section - Add Choosing an Engine comparison table - Add InferenceResult/Explanation/ReasoningStep type annotations in examples - Add Tip: use DatalogReasoner for recursive rules semantic_extract.md: - Add Exported Classes block with NamedEntityRecognizer, EventDetector, Entity, Relation, Event, CoreferenceChain, EntityClassifier, TemporalEventProcessor - Add Quick Start section (one-liner extraction pipeline) - Rename EventExtractor -> EventDetector (correct exported name) - Clarify NERExtractor vs NamedEntityRecognizer distinction - Add return type annotations to EventDetector example core.md: - Add Exported Classes block - Add When to Use Core vs. Individual Modules decision table - Add Tip: LifecycleManager only for long-running apps - Fix MethodRegistry example to import build_knowledge_base correctly parse.md: - Add Exported Classes block with all format-specific parsers + data types - Add DoclingParser optional import note utils.md: - Add Exported Classes block with logging/validation/progress/helpers/exceptions deduplication.md: - Add Exported Classes block with PropertyMergeRule, MergeStrategyManager, method_registry, and all convenience functions export.md: - Add Exported Classes block with all exporters, NamespaceManager, SemanticNetworkYAMLExporter, and all convenience functions
10 KiB
title, description, icon
| title | description | icon |
|---|---|---|
| Reasoning Module | Forward chaining, Rete, deductive, abductive, SPARQL, Datalog, and temporal reasoning with explainable inference paths. | microchip |
semantica.reasoning derives new knowledge from existing facts using logical rules. Every engine produces explainable inference paths — traceable chains of rules and facts, not black-box conclusions.
Exported Classes
from semantica.reasoning import (
# Engines
Reasoner, # IF/THEN forward-chaining facade
GraphReasoner, # inference over full KG structure
ReteEngine, # high-performance Rete pattern matching
SPARQLReasoner, # SPARQL-based RDF inference
DatalogReasoner, # recursive Horn clause fixpoint evaluation
TemporalReasoningEngine, # Allen interval algebra (13 relations)
ExplanationGenerator, # structured step-by-step explanations
# Data types
Rule, # IF/THEN rule definition
Fact, # base fact (subject, predicate, obj)
RuleType, # enum: FORWARD_CHAIN, BACKWARD_CHAIN, ...
InferenceResult, # result of infer() — contains derived_facts list
DatalogFact, # Datalog base fact (predicate, args tuple)
DatalogRule, # Datalog Horn clause ("head :- body.")
TemporalInterval, # time interval with start/end
IntervalRelation, # enum of 13 Allen relations
# Explanation types
Explanation, # conclusion + confidence + reasoning_path
ReasoningPath, # ordered list of ReasoningSteps
ReasoningStep, # single step: fact + rule_name + depth
Justification, # full justification record
)
What You Get
Reasoner— main facade for IF/THEN forward-chaining with variable substitutionGraphReasoner— inference over full knowledge graph structure (transitivity, symmetry, inverses)ReteEngine— high-performance pattern matching via the Rete algorithm for large rule setsSPARQLReasoner— query expansion and property chain inference over RDF graphsDatalogReasoner— recursive Horn clause rules with guaranteed fixpoint termination (v0.4.0)TemporalReasoningEngine— all 13 Allen interval algebra relations for time-aware inferenceExplanationGenerator— structured explanation paths for every derived conclusion
Quick Start
The most common pattern: add facts + rules, run inference, explain a conclusion:
from semantica.reasoning import Reasoner, Rule, Fact, RuleType, InferenceResult
reasoner = Reasoner()
reasoner.add_fact(Fact(subject="Alice", predicate="is_a", obj="Manager"))
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"},
))
result: InferenceResult = reasoner.infer()
for fact in result.derived_facts:
print(f"{fact.subject} {fact.predicate} {fact.obj}")
print(f" via: {fact.explanation}")
<img src="/assets/img/diagrams/reasoning-chain.svg" alt="Forward chaining inference: known facts + IF/THEN rules produce derived facts with a full traceable explanation path" style={{ width: '100%', borderRadius: '12px', margin: '0 0 24px' }} />
Reasoner (Main Facade)
The unified entry point for rule-based forward-chaining inference:
from semantica.reasoning import Reasoner, Rule, Fact, RuleType
reasoner = Reasoner()
# Add base facts
reasoner.add_fact(Fact(subject="John", predicate="is_a", obj="Manager"))
reasoner.add_fact(Fact(subject="John", predicate="is_a", obj="Employee"))
# Add an IF/THEN rule
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}")
Built-In Rule Templates
engine = Reasoner()
# Transitive closure: A→B, B→C ⟹ A→C
engine.apply_transitivity("located_in")
# Symmetry: A knows B ⟹ B knows A
engine.apply_symmetry("knows")
# Inverse: A parent_of B ⟹ B child_of A
engine.apply_inverse("parent_of", "child_of")
GraphReasoner
Inference over the full knowledge graph structure:
from semantica.reasoning import GraphReasoner
graph_reasoner = GraphReasoner(kg)
# Define a transitive ancestor rule
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 across iterations:
from semantica.reasoning import ReteEngine
engine = ReteEngine()
engine.load_rules("rules/domain_rules.json")
results = engine.run(kg)
# Inspect the Rete network
root = engine.get_root()
alpha_nodes = engine.get_alpha_nodes() # single-condition filters
beta_nodes = engine.get_beta_nodes() # join nodes
Rule format (JSON):
{
"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 with property chain support:
from semantica.reasoning import SPARQLReasoner
reasoner = SPARQLReasoner(graph=rdf_graph)
result = 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: A knows B, B colleague_of C ⟹ 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 — the engine detects fixpoint convergence and stops:
from semantica.reasoning import DatalogReasoner, DatalogFact, DatalogRule
datalog = DatalogReasoner()
# Base facts
datalog.add_fact(DatalogFact("parent", ("alice", "bob")))
datalog.add_fact(DatalogFact("parent", ("bob", "charlie")))
# 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"}]
TemporalReasoningEngine
Reason about time intervals using all 13 Allen interval algebra relations:
from semantica.reasoning import TemporalReasoningEngine, TemporalInterval, IntervalRelation
engine = TemporalReasoningEngine()
ceo_tenure = TemporalInterval(start="1997-09-16", end="2011-08-24")
board_member = TemporalInterval(start="2000-01-01", end="2012-06-01")
relation = engine.get_relation(ceo_tenure, board_member)
# → IntervalRelation.DURING (ceo_tenure is fully inside board_member)
All 13 Allen interval algebra relations are supported:
| Relation | Meaning |
|---|---|
BEFORE |
A ends before B starts |
MEETS |
A ends exactly when B starts |
OVERLAPS |
A starts before B, ends inside B |
DURING |
A is fully inside B |
STARTS |
A and B start together, A ends first |
FINISHES |
A and B end together, A starts later |
EQUALS |
Identical intervals |
| + 6 inverses | AFTER, MET_BY, OVERLAPPED_BY, CONTAINS, STARTED_BY, FINISHED_BY |
ExplanationGenerator
Generate structured step-by-step explanations for any derived conclusion:
from semantica.reasoning import ExplanationGenerator, Explanation, ReasoningStep
generator = ExplanationGenerator(reasoner)
explanation: Explanation = generator.explain(
conclusion={"subject": "John", "predicate": "has_authority", "object": "true"}
)
print(f"Conclusion: {explanation.conclusion}")
print(f"Confidence: {explanation.confidence:.2f}")
step: ReasoningStep
for step in explanation.reasoning_path.steps:
print(f" Step {step.depth}: {step.fact}")
print(f" via rule: '{step.rule_name}'")
Choosing an Engine
| Engine | Best For | Termination | Complexity |
|---|---|---|---|
Reasoner |
Simple IF/THEN rules, templates | Always | Low |
GraphReasoner |
KG-wide structural inference | Always | Medium |
ReteEngine |
Large rule sets (100+ rules) | Always | Low per-match |
SPARQLReasoner |
RDF graphs with SPARQL endpoint | Always | Low |
DatalogReasoner |
Recursive rules (ancestry, reachability) | Guaranteed fixpoint | Medium |
TemporalReasoningEngine |
Time interval relationships | Always | Low |