How to Use Temporal Intelligence with Allen Interval Algebra in Knowledge Graphs

Semantica implements a fully deterministic temporal reasoning engine based on Allen interval algebra, exposing 13 precise interval relations through both Python API and CLI without any LLM dependency.

The semantica-agi/semantica repository provides native temporal intelligence capabilities for knowledge graphs, built directly on James F. Allen's foundational interval algebra from 1970. This article explains how to leverage these features for deterministic temporal reasoning in your knowledge graph applications.


Understanding Allen Interval Algebra in Semantica

Allen interval algebra defines 13 possible relations between two time intervals: BEFORE, MEETS, OVERLAPS, DURING, STARTS, FINISHES, EQUALS, plus their inverses. The semantica implementation encodes these relations in pure Python, making temporal queries fully reproducible and explainable.

The core implementation lives in semantica/kg/temporal_reasoning.py, specifically the TemporalReasoningEngine class (lines 44-79). This engine operates on the TemporalInterval data class, which stores:

  • start: A concrete datetime object
  • end: Either a datetime or TemporalBound.OPEN sentinel for unbounded intervals

When you call engine.relation(a, b), the method normalizes interval endings via _end_value (converting OPEN to datetime.max) and evaluates a cascade of comparisons that mirror the original Allen paper's logical ordering.


Core Components of the Temporal Engine

TemporalReasoningEngine

The TemporalReasoningEngine class provides the primary interface for Allen algebra operations. Its relation() method returns an IntervalRelation enum value representing how two intervals relate.

from semantica.kg.temporal_reasoning import (
    TemporalReasoningEngine,
    TemporalInterval,
)

engine = TemporalReasoningEngine()

TemporalInterval and TemporalBound

Intervals are immutable objects supporting both bounded and open-ended ranges:

from datetime import datetime
from semantica.kg.temporal_reasoning import TemporalInterval, TemporalBound

# Bounded interval

bounded = TemporalInterval(
    start=datetime(2022, 1, 1),
    end=datetime(2022, 1, 10)
)

# Open-ended interval (valid indefinitely)

open_ended = TemporalInterval(
    start=datetime(2022, 1, 1),
    end=TemporalBound.OPEN
)

Higher-Level Helper Methods

Beyond the raw relation() method, the engine provides convenient predicates for common queries:

Method Purpose Allen Relations Covered
overlaps(a, b) Check if intervals share any time OVERLAPS, DURING, STARTS, FINISHES, EQUALS
contains(a, b) Check if a fully contains b CONTAINS (inverse of DURING)
active_at(a, point) Check if point falls within interval Derived from DURING with zero-width interval
gap_analysis(a, b) Calculate temporal distance between intervals Used for scheduling and sequencing

Using the Temporal Engine in Python

Basic Interval Comparison

from semantica.kg.temporal_reasoning import (
    TemporalReasoningEngine,
    TemporalInterval,
)

engine = TemporalReasoningEngine()

# Define two intervals using ISO-8601 strings

interval_a = TemporalInterval(
    start=engine._coerce_datetime("2022-01-01T00:00:00Z"),
    end=engine._coerce_datetime("2022-01-10T00:00:00Z"),
)

interval_b = TemporalInterval(
    start=engine._coerce_datetime("2022-01-05T00:00:00Z"),
    end=engine._coerce_datetime("2022-01-15T00:00:00Z"),
)

relation = engine.relation(interval_a, interval_b)
print(f"Relation: {relation.name}")   # → Relation: OVERLAPS

Working with Open-Ended Intervals

from semantica.kg.temporal_reasoning import TemporalBound

# Current employment (open-ended)

current_role = TemporalInterval(
    start=engine._coerce_datetime("2020-03-15T00:00:00Z"),
    end=TemporalBound.OPEN
)

# Project period

project = TemporalInterval(
    start=engine._coerce_datetime("2021-06-01T00:00:00Z"),
    end=engine._coerce_datetime("2021-12-31T00:00:00Z")
)

# Check if project occurred during employment

relation = engine.relation(current_role, project)
print(f"Employment relation to project: {relation.name}")  # → CONTAINS

CLI Interface for Temporal Queries

The semantica temporal allen command (implemented in semantica/cli.py, lines 58-66) provides direct access to Allen algebra without writing Python code.

Human-Readable Output

semantica temporal allen \
    --interval1 "2022-01-01T00:00:00Z/2022-01-10T00:00:00Z" \
    --interval2 "2022-01-05T00:00:00Z/2022-01-15T00:00:00Z"

Output:


2022-01-01T00:00:00Z/2022-01-10T00:00:00Z ── OVERLAPS ──► 2022-01-05T00:00:00Z/2022-01-15T00:00:00Z

Machine-Readable JSON Output

semantica temporal allen \
    --interval1 "2022-01-01T00:00:00Z/2022-01-10T00:00:00Z" \
    --interval2 "2022-01-05T00:00:00Z/2022-01-15T00:00:00Z" \
    --json

Result:

{
  "interval1": "2022-01-01T00:00:00Z/2022-01-10T00:00:00Z",
  "interval2": "2022-01-05T00:00:00Z/2022-01-15T00:00:00Z",
  "relation": "OVERLAPS"
}

Integrating Temporal Intelligence with Knowledge Graph Queries

The TemporalGraphQuery class leverages the same engine for filtering entities based on temporal constraints.

from semantica.kg import TemporalGraphQuery

tgq = TemporalGraphQuery(config={})

# Find events that contain a specific time window

events = tgq.query(
    "MATCH (e) WHERE e.valid_from <= '2022-03-01' AND e.valid_until >= '2022-04-01' RETURN e"
)

Under the hood, this translates to Allen's CONTAINS relation between the entity's validity interval and the query interval. The engine's deterministic logic ensures consistent results across all temporal graph operations.


Parsing and Serialization Utilities

The semantica/kg/temporal_model.py file provides helper functions for converting between string representations and internal datetime objects:

  • parse_temporal_value(): Handles ISO-8601 strings, Unix timestamps, and datetime objects
  • parse_temporal_bound(): Specifically handles the OPEN sentinel and bounded endpoints
  • BiTemporalFact: Wrapper class combining valid-time and transaction-time dimensions

These utilities ensure consistent temporal value handling across the entire knowledge graph stack.


Summary

  • Allen interval algebra provides 13 precise relations for temporal reasoning, fully implemented in TemporalReasoningEngine at semantica/kg/temporal_reasoning.py
  • Pure Python implementation means deterministic, explainable results without LLM dependency or external service calls
  • TemporalInterval supports both bounded and open-ended ranges via TemporalBound.OPEN
  • CLI access via semantica temporal allen enables quick interval testing with human or JSON output
  • Integration points include TemporalGraphQuery for KG filtering and extension points for version management and retroactive analysis

Frequently Asked Questions

What are the 13 Allen interval relations supported by Semantica?

The complete set includes: BEFORE, MEETS, OVERLAPS, DURING, STARTS, FINISHES, EQUALS, and their inverses (AFTER, MET_BY, OVERLAPPED_BY, CONTAINS, STARTED_BY, FINISHED_BY). The TemporalReasoningEngine.relation() method returns the most specific applicable relation as an IntervalRelation enum value.

How does Semantica handle unbounded or ongoing time intervals?

Open-ended intervals use TemporalBound.OPEN as the end value. The engine's _end_value() helper converts this to datetime.max during comparison, effectively treating ongoing intervals as extending to the maximum representable time. This allows CONTAINS and other relations to evaluate correctly against fixed-date intervals.

Can I use temporal reasoning without the full knowledge graph?

Yes. The TemporalReasoningEngine has no dependencies on other semantica components. Import directly from semantica.kg.temporal_reasoning and use it for any interval comparison logic, or use the semantica temporal allen CLI command for standalone queries.

Where are the Allen algebra test cases located?

Comprehensive unit tests verifying all 13 interval relations are in semantica/tests/kg/test_temporal_reasoning.py. These tests exercise edge cases including equal endpoints, adjacent intervals (MEETS), and open-ended comparisons.

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 →