State-space control DSL over GDS semantics — control theory with formal guarantees
Project description
gds-control
State-space control DSL over GDS semantics — control theory with formal guarantees.
Table of Contents
- Quick Start
- What is this?
- Architecture
- Elements
- Semantic Type System
- Verification
- Examples
- Status
- Credits & Attribution
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
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 Mehta — BlockScience
Theoretical foundation: Dr. Michael Zargham and Dr. Jamsheed Shorish — Generalized Dynamical Systems, Part I: Foundations (2021).
Architectural inspiration: Sean McOwen — MSML 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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gds_control-0.99.0.tar.gz.
File metadata
- Download URL: gds_control-0.99.0.tar.gz
- Upload date:
- Size: 14.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b8acce0ff6cf5077119f9db5df853c595c48de536b5579e2ab9b351119745c5
|
|
| MD5 |
237abbab8d6d2c27d1a285cad85900ab
|
|
| BLAKE2b-256 |
f82a911df6cf9a078acf3b17a22d47165402ac8558acfc836efb9badd2c08ad8
|
File details
Details for the file gds_control-0.99.0-py3-none-any.whl.
File metadata
- Download URL: gds_control-0.99.0-py3-none-any.whl
- Upload date:
- Size: 5.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0fd3636b95728cc29452325caf6102b997699e42fee0db1c7bd709cfc40d60d
|
|
| MD5 |
14bbb0e4b8cee1fe42bfa1bcc7ab2558
|
|
| BLAKE2b-256 |
366397776aecb9c83a5a8c5404f07d788f15afca9bf25444e34daa13f98dd685
|