Spaxiom Logo
Spaxiom Technical Series - Part 2

Type System and Composition

Composable Primitives for Spatiotemporal Reasoning

Joe Scanlin

November 2025

About This Section

This section explores Spaxiom's type system and composition model. Unlike ad-hoc sensor integration scripts, Spaxiom enforces type safety at DSL construction time and provides algebraic composition operators that enable complex spatiotemporal queries to be built from simple building blocks.

You'll learn about the core type hierarchy (Sensor, Condition, Zone, Entity, Quantity), composition operators (logical, temporal, spatial), and how these primitives combine to express complex behaviors concisely. The section concludes with formal semantics and performance characteristics of the composition model.

2.3 Type System and Composition

Spaxiom's expressiveness comes from a small set of composable primitives with a well-defined type system. Unlike ad-hoc sensor integration scripts, Spaxiom enforces type safety at DSL construction time and provides algebraic composition operators that enable complex spatiotemporal queries to be built from simple building blocks.

Core type hierarchy

The DSL defines the following fundamental types:

Condition composition operators

Conditions form a boolean algebra with standard operators:

from spaxiom import Condition

# Logical operators
c1 = Condition(lambda: temp.read() > 25.0)
c2 = Condition(lambda: humidity.read() > 60.0)

hot_and_humid = c1 & c2    # conjunction (AND)
hot_or_humid  = c1 | c2    # disjunction (OR)
not_hot       = ~c1        # negation (NOT)

# Temporal chaining
humid_then_hot = c2.before(c1, within_seconds=300)  # c2 before c1, within 5 min

Importantly, these operators are not evaluated eagerly. They construct a lazy evaluation graph that the runtime optimizes.

Temporal operators

Spaxiom provides temporal logic operators inspired by Linear Temporal Logic (LTL) but adapted for continuous real-time systems:

These operators enable expressive temporal patterns without manually managing timers or state machines.

Spatial operators

Spatial queries are first-class in Spaxiom. Common patterns:

Type checking and unit validation

Spaxiom performs compile-time validation where possible:

Runtime validation handles cases that cannot be checked statically:

Composition example: complex spatiotemporal query

Combining these primitives enables concise expression of complex behaviors. Example: detect a "loitering near exit" pattern.

from spaxiom import Sensor, Zone, Entity, Condition, within, inside, near
from spaxiom.units import meters

# Spatial setup
exit_zone = Zone(x=10, y=20, width=3, height=2)
exit_vicinity = exit_zone.buffer(5 * meters)  # 5m buffer around exit

# Entity tracking
person = Entity(id="person_42")

# Conditions
near_exit = inside(person, exit_vicinity)
not_exiting = ~inside(person, exit_zone)
stationary = Condition(lambda: person.velocity.magnitude() < 0.1)  # < 0.1 m/s

# Composite pattern: near exit, not moving, for 30+ seconds
loitering = within(30.0, near_exit & not_exiting & stationary)

@on(loitering)
def alert_security():
    print(f"Person {person.id} loitering near exit at {person.position}")

This single composite condition would require dozens of lines of manual state tracking, timers, and geometric computations in a traditional imperative approach.

Formal semantics and denotational interpretation

For verification purposes (see Section 7.3), we can give Spaxiom conditions a denotational semantics as functions from time to truth values:

⟦c⟧ : ℝ → {true, false}

Where ⟦c⟧(t) is the truth value of condition c at time t. Composition operators have natural interpretations:

This formal interpretation enables model checking and equivalence proofs between Spaxiom programs and temporal logic formulas.

Performance characteristics of composition

Lazy evaluation and operator fusion are critical for performance:

These optimizations make Spaxiom practical even on resource-constrained edge devices with hundreds of sensors and conditions.