How Semantica's TemporalReasoningEngine Handles Time-Aware Inference

The TemporalReasoningEngine in Semantica enables time-aware inference by filtering knowledge graphs using dual-timestamped facts and reconstructing consistent temporal slices for standard reasoning operations.

Semantica is an open-source knowledge graph framework designed for temporal reasoning available at semantica-agi/semantica. The TemporalReasoningEngine leverages specific data structures and query utilities found in the semantica/kg module to distinguish between when facts are true in the real world and when they were recorded, enabling precise inference over time-varying data.

Core Temporal Data Structures

The engine's time-aware capabilities rely on explicit temporal modeling defined in semantica/kg/temporal_model.py.

BiTemporalFact for Dual-Timestamp Storage

A BiTemporalFact represents statements using two distinct time dimensions. The valid time indicates when a fact holds true in reality, while the transaction time records when the fact was inserted into the system. This separation allows the engine to handle retroactive corrections and historical queries without ambiguity.

Facts can express open-ended validity using TemporalBound, a sentinel value that creates unclosed intervals. When valid_end is set to TemporalBound.OPEN, the fact remains valid indefinitely from its start time.

Version Management and Snapshotting

Found in semantica/kg/temporal_query.py, the TemporalVersionManager provides the versioning backbone for the reasoning engine.

Tracking Graph Evolution

The manager persists graph states through methods like tag_version(), which assigns labels to current snapshots, and list_tags(), which retrieves available historical versions. The format_version() helper standardizes version identifiers across the system. By maintaining these version tags, the engine can reconstruct the exact state of the knowledge graph at any specific transaction time.

Time-Aware Query Operations

The TemporalGraphQuery class in semantica/kg/temporal_query.py exposes the primary API for temporal reasoning.

Reconstructing Temporal Slices

The reconstruct_at_time(t) method builds a self-consistent subgraph containing only facts whose valid time interval covers timestamp t and whose transaction time precedes the current version. This filtering produces a static graph slice upon which standard inference rules—such as transitive closure or RDFS reasoning—can be applied directly.

Validating Temporal Consistency

Before inference, validate_temporal_consistency() checks for logical contradictions in the temporal data. This includes verifying that valid start times precede end times, ensuring transaction times advance monotonically, and detecting overlapping validity intervals for identical subject-predicate pairs that might indicate conflicts.

Analyzing Temporal Patterns

Additional methods support temporal meta-reasoning: analyze_evolution() computes metrics like added or removed facts over a time window, while query_temporal_pattern() identifies recurring structures such as periodic events or monotonic growth trends.

Practical Implementation: Time-Aware Inference Workflow

The following example demonstrates the complete workflow from ingesting temporal facts to performing inference on a historical snapshot.

from semantica.kg.temporal_model import BiTemporalFact, TemporalBound
from semantica.kg.temporal_query import TemporalVersionManager, TemporalGraphQuery
from semantica.visualization.temporal_visualizer import TemporalVisualizer

# 1. Create a fact with open-ended validity

fact = BiTemporalFact.from_relationship({
    "subject": "ex:Earthquake2023",
    "predicate": "rdf:type", 
    "object": "ex:SeismicEvent",
    "valid_start": "2023-05-01T00:00:00Z",
    "valid_end": TemporalBound.OPEN,
})

# 2. Version the graph state

v_manager = TemporalVersionManager()
v_manager.tag_version(label="v1.0")

# 3. Reconstruct graph at specific historical moment

tgq = TemporalGraphQuery()
snapshot = tgq.reconstruct_at_time("2023-06-15T12:00:00Z")

# 4. Perform inference on the temporal slice

inferred = tgq.infer_transitive_closure(snapshot)

# 5. Validate before committing results

errors = tgq.validate_temporal_consistency()
assert not errors, "Temporal conflicts detected"

# 6. Visualize the temporal slice

viz = TemporalVisualizer()
viz.render(snapshot, title="Graph State on 2023-06-15")

Summary

  • BiTemporalFact stores facts with separate valid and transaction timestamps in semantica/kg/temporal_model.py, enabling precise temporal discrimination.
  • TemporalVersionManager handles snapshot persistence and versioning through tag_version() and related methods in semantica/kg/temporal_query.py.
  • TemporalGraphQuery provides reconstruct_at_time() for filtering facts into consistent slices suitable for standard reasoning algorithms.
  • The engine validates temporal consistency using validate_temporal_consistency() to prevent logical contradictions before inference.
  • TemporalVisualizer in semantica/visualization/temporal_visualizer.py supports debugging by rendering specific temporal snapshots.

Frequently Asked Questions

How does reconstruct_at_time determine which facts to include in a slice?

The method selects BiTemporalFact objects where the query timestamp falls within the fact's valid time interval and the fact's transaction time is less than or equal to the current version timestamp. This dual filtering ensures the resulting snapshot contains only assertions that were both true at the specified moment and known to the system at that version.

What is the difference between valid time and transaction time in Semantica?

Valid time represents when a statement accurately describes reality, while transaction time records when the system stored that statement. This bitemporal model allows the engine to answer questions like "What did we know on Monday about events that occurred last Friday?" by independently filtering on both dimensions.

Where is the TemporalVersionManager implemented?

The TemporalVersionManager class is defined in semantica/kg/temporal_query.py alongside TemporalGraphQuery. It provides the versioning infrastructure that tags graph states and enables historical reconstruction through methods like list_tags() and format_version().

Can standard reasoning algorithms work directly with temporal data?

Standard algorithms operate on the static subgraphs produced by reconstruct_at_time(). The TemporalReasoningEngine first filters the temporal graph into a conventional snapshot, then applies existing inference rules such as transitive closure or OWL reasoning. Inferred results inherit the temporal bounds of their source premises.

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 →