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

> Leverage Allen interval algebra for deterministic temporal reasoning in knowledge graphs. Semantica offers precise interval relations via Python API and CLI without LLM dependence.

- Repository: [Semantica /semantica](https://github.com/semantica-agi/semantica)
- Tags: how-to-guide
- Published: 2026-08-14

---

**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`](https://github.com/semantica-agi/semantica/blob/main/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.

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

engine = TemporalReasoningEngine()

```

### TemporalInterval and TemporalBound

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

```python
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

```python
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

```python
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`](https://github.com/semantica-agi/semantica/blob/main/semantica/cli.py), lines 58-66) provides direct access to Allen algebra without writing Python code.

### Human-Readable Output

```bash
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

```bash
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:

```json
{
  "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.

```python
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`](https://github.com/semantica-agi/semantica/blob/main/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`](https://github.com/semantica-agi/semantica/blob/main/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`](https://github.com/semantica-agi/semantica/blob/main/semantica/tests/kg/test_temporal_reasoning.py). These tests exercise edge cases including equal endpoints, adjacent intervals (MEETS), and open-ended comparisons.