Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

README.md

gds-control

PyPI Python License

State-space control DSL over GDS semantics — control theory with formal guarantees.

Table of Contents

Quick Start

pip install gds-control
from gds_control import (
    State, Input, Sensor, Controller,
    ControlModel, compile_model, compile_to_system, verify,
)

# Declare a thermostat control system
model = ControlModel(
    name="Thermostat",
    states=[State(name="temperature", initial=20.0)],
    inputs=[Input(name="setpoint")],
    sensors=[Sensor(name="thermometer", observes=["temperature"])],
    controllers=[
        Controller(
            name="PID",
            reads=["thermometer", "setpoint"],
            drives=["temperature"],
        )
    ],
)

# Compile to GDS — produces a real GDSSpec with role blocks, entities, wirings
spec = compile_model(model)
ir = compile_to_system(model)
print(f"{len(ir.blocks)} blocks, {len(ir.wirings)} wirings")

# Verify — domain checks + optional GDS structural checks
report = verify(model, include_gds_checks=True)
print(f"{report.checks_passed}/{report.checks_total} checks passed")

What is this?

gds-control is a domain DSL that compiles state-space control systems to GDS specifications. You declare states, inputs, sensors, and controllers as plain data models — the compiler handles the mapping to GDS role blocks, entities, composition trees, and wirings.

Your declaration                    What the compiler produces
────────────────                    ─────────────────────────
State("temperature")         →     Mechanism + Entity (state update f + state X)
Input("setpoint")            →     BoundaryAction (exogenous input U)
Sensor("thermometer")        →     Policy (observation g)
Controller("PID")            →     Policy (decision logic g)
ControlModel(...)            →     GDSSpec + SystemIR (full GDS specification)

This maps directly to the standard state-space representation:

ẋ = Ax + Bu    (state dynamics → Mechanism)
y = Cx + Du    (sensor output → Policy)
u = K(y, r)    (control law  → Policy)
r              (reference    → BoundaryAction)

Once compiled, all downstream GDS tooling works immediately — canonical projection (h = f ∘ g), semantic checks, SpecQuery dependency analysis, JSON serialization, and gds-viz diagram generation.

Architecture

DSL over GDS

ControlModel (user-facing declarations)
       │
       ▼  compile_model()
GDSSpec (entities, blocks, wirings, parameters)
       │
       ▼  compile_to_system()
SystemIR (flat IR for verification + visualization)

No parallel IR stack. The compiler produces a real GDSSpec with real GDS role blocks. This means control models are first-class GDS citizens — they compose with other GDS models, share the same verification engine, and render with the same visualization tools.

Composition Tree

The compiler builds a tiered composition tree:

(inputs | sensors) >> (controllers) >> (state dynamics)
    .loop([state dynamics forward_out → sensor forward_in])
  • Within each tier: parallel composition (|) — independent inputs and sensors run side-by-side
  • Across tiers: sequential composition (>>) — sensors feed controllers, controllers feed state dynamics
  • Temporal recurrence: .loop() — state outputs at timestep t feed back to sensors at timestep t+1

Design decision: All non-state-updating blocks use Policy. ControlAction is deliberately not used — it sits outside the canonical g partition, which would break the clean (A, B, C, D) ↔ (X, U, g, f) mapping.

Elements

Four declaration types, each mapping to a specific GDS role:

State

State(name="temperature", initial=20.0)

GDS mapping: Mechanism (state update f) + Entity (state X)

A state variable in the plant. Each state becomes a GDS entity with a value state variable, and a dynamics block that applies incoming control signals. States emit a State port for temporal feedback.

Field Type Default Description
name str required State name (becomes entity name)
initial float | None None Initial value

Input

Input(name="setpoint")

GDS mapping: BoundaryAction (exogenous input U)

An exogenous reference signal or disturbance entering the system from outside. Inputs have no internal sources — they represent the boundary between the system and its environment.

Field Type Default Description
name str required Input name

Sensor

Sensor(name="thermometer", observes=["temperature"])

GDS mapping: Policy (observation g)

A sensor reads state variables and emits a measurement signal. The observes list declares which states the sensor can read — validated at model construction time.

Field Type Default Description
name str required Sensor name
observes list[str] [] Names of states this sensor reads

Controller

Controller(name="PID", reads=["thermometer", "setpoint"], drives=["temperature"])

GDS mapping: Policy (decision logic g)

A controller reads sensor measurements and/or reference inputs, then emits control signals to drive state variables. The reads list references sensors or inputs; the drives list references states.

Field Type Default Description
name str required Controller name
reads list[str] [] Names of sensors/inputs this controller reads
drives list[str] [] Names of states this controller drives

Semantic Type System

Four distinct semantic spaces, all float-backed but structurally separate — this prevents accidentally wiring a measurement where a control signal is expected:

Type Space Used By Description
StateType StateSpace States Plant state variables
ReferenceType ReferenceSpace Inputs Exogenous reference/disturbance signals
MeasurementType MeasurementSpace Sensors Sensor output measurements
ControlType ControlSpace Controllers Controller output signals

Verification

Six domain-specific checks validate the control model structure before compilation:

ID Name Severity What It Checks
CS-001 Undriven states WARNING Every state driven by ≥ 1 controller
CS-002 Unobserved states WARNING Every state observed by ≥ 1 sensor
CS-003 Unused inputs WARNING Every input read by ≥ 1 controller
CS-004 Controller read validity ERROR Controller reads reference declared sensors/inputs
CS-005 Controller drive validity ERROR Controller drives reference declared states
CS-006 Sensor observe validity ERROR Sensor observes reference declared states
from gds_control import verify

# Domain checks only
report = verify(model)

# Domain checks + GDS structural checks (G-001..G-006)
report = verify(model, include_gds_checks=True)

Examples

One tutorial example in gds-examples demonstrates control system modeling using the GDS framework primitives:

Example Domain What It Teaches
Thermostat PID Control theory .feedback() composition, CONTRAVARIANT backward flow, ControlAction role, multi-variable entities
Thermostat structural view — feedback arrow shows CONTRAVARIANT energy cost flow
%%{init:{"theme":"neutral"}}%%
flowchart TD
    classDef boundary fill:#93c5fd,stroke:#2563eb,stroke-width:2px,color:#1e3a5f
    classDef policy fill:#fcd34d,stroke:#d97706,stroke-width:2px,color:#78350f
    classDef mechanism fill:#86efac,stroke:#16a34a,stroke-width:2px,color:#14532d
    classDef control fill:#d8b4fe,stroke:#9333ea,stroke-width:2px,color:#3b0764
    classDef generic fill:#cbd5e1,stroke:#64748b,stroke-width:1px,color:#1e293b
    Temperature_Sensor([Temperature Sensor]):::boundary
    PID_Controller[PID Controller]:::generic
    Room_Plant[Room Plant]:::generic
    Update_Room[[Update Room]]:::mechanism
    Temperature_Sensor --Measured Temperature--> PID_Controller
    PID_Controller --Heater Command--> Room_Plant
    Room_Plant --Room State--> Update_Room
    Room_Plant ==Energy Cost==> PID_Controller
Loading

Status

v0.1.0 — Alpha. Complete DSL with 6 verification checks and full GDS compilation. 117 tests.

License

Apache-2.0


Built with Claude Code. All code is test-driven and human-reviewed.

Credits & Attribution

Author: Rohan MehtaBlockScience

Theoretical foundation: Dr. Michael Zargham and Dr. Jamsheed ShorishGeneralized Dynamical Systems, Part I: Foundations (2021).

Architectural inspiration: Sean McOwenMSML and bdp-lib.

Contributors:

  • Michael Zargham — Project direction, GDS theory guidance, and technical review (BlockScience).
  • Peter Hacker — Code auditing and review (BlockScience).

Lineage: Part of the cadCAD ecosystem for Complex Adaptive Dynamics.