Skip to content

Commit 1c41253

Browse files
Merge pull request #79 from BlockScience/dev
docs: expand documentation site and add llms.txt generation
2 parents 210b0a9 + af1a4a1 commit 1c41253

62 files changed

Lines changed: 3396 additions & 26 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/control/api/checks.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# gds_control.verification.checks
2+
3+
Control system verification checks (CS-001..CS-006).
4+
5+
::: gds_control.verification.checks.check_cs001_undriven_states
6+
7+
::: gds_control.verification.checks.check_cs002_unobserved_states
8+
9+
::: gds_control.verification.checks.check_cs003_unused_inputs
10+
11+
::: gds_control.verification.checks.check_cs004_controller_read_validity
12+
13+
::: gds_control.verification.checks.check_cs005_controller_drive_validity
14+
15+
::: gds_control.verification.checks.check_cs006_sensor_observe_validity

docs/control/api/compile.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# gds_control.dsl.compile
2+
3+
Compiler: ControlModel -> GDSSpec / SystemIR.
4+
5+
## Semantic Types
6+
7+
::: gds_control.dsl.compile.StateType
8+
9+
::: gds_control.dsl.compile.StateSpace
10+
11+
::: gds_control.dsl.compile.ReferenceType
12+
13+
::: gds_control.dsl.compile.ReferenceSpace
14+
15+
::: gds_control.dsl.compile.MeasurementType
16+
17+
::: gds_control.dsl.compile.MeasurementSpace
18+
19+
::: gds_control.dsl.compile.ControlType
20+
21+
::: gds_control.dsl.compile.ControlSpace
22+
23+
## Public Functions
24+
25+
::: gds_control.dsl.compile.compile_model
26+
27+
::: gds_control.dsl.compile.compile_to_system

docs/control/api/elements.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# gds_control.dsl.elements
2+
3+
Control system element declarations -- frozen Pydantic models for user-facing declarations.
4+
5+
::: gds_control.dsl.elements.State
6+
7+
::: gds_control.dsl.elements.Input
8+
9+
::: gds_control.dsl.elements.Sensor
10+
11+
::: gds_control.dsl.elements.Controller

docs/control/api/init.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# gds_control
2+
3+
Public API -- top-level exports.
4+
5+
::: gds_control
6+
options:
7+
show_submodules: false
8+
members: false

docs/control/api/model.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# gds_control.dsl.model
2+
3+
ControlModel -- declarative container for control system specifications.
4+
5+
::: gds_control.dsl.model.ControlModel

docs/control/api/verification.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# gds_control.verification
2+
3+
Verification engine -- runs domain checks with optional GDS structural checks.
4+
5+
::: gds_control.verification.engine.verify

docs/control/getting-started.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Getting Started
2+
3+
## Installation
4+
5+
```bash
6+
uv add gds-control
7+
# or: pip install gds-control
8+
```
9+
10+
For development (monorepo):
11+
12+
```bash
13+
git clone https://github.com/BlockScience/gds-core.git
14+
cd gds-core
15+
uv sync --all-packages
16+
```
17+
18+
## Your First Control Model
19+
20+
A control model describes a feedback control system: states represent the plant, inputs provide reference signals, sensors observe state, and controllers compute control actions.
21+
22+
```python
23+
from gds_control import (
24+
State, Input, Sensor, Controller,
25+
ControlModel, compile_model, compile_to_system, verify,
26+
)
27+
28+
# Declare a thermostat control system
29+
model = ControlModel(
30+
name="Thermostat",
31+
states=[State(name="temperature", initial=20.0)],
32+
inputs=[Input(name="setpoint")],
33+
sensors=[Sensor(name="thermometer", observes=["temperature"])],
34+
controllers=[
35+
Controller(
36+
name="PID",
37+
reads=["thermometer", "setpoint"],
38+
drives=["temperature"],
39+
)
40+
],
41+
)
42+
43+
# Compile to GDS
44+
spec = compile_model(model)
45+
print(f"Blocks: {len(spec.blocks)}") # 4 blocks
46+
print(f"Entities: {len(spec.entities)}") # 1 (temperature state)
47+
48+
# Compile to SystemIR for verification
49+
ir = compile_to_system(model)
50+
print(f"{len(ir.blocks)} blocks, {len(ir.wirings)} wirings")
51+
52+
# Verify — domain checks + GDS structural checks
53+
report = verify(model, include_gds_checks=True)
54+
print(f"{report.checks_passed}/{report.checks_total} checks passed")
55+
```
56+
57+
## A Multi-State Model
58+
59+
Control models support multiple states with multiple sensors and controllers:
60+
61+
```python
62+
from gds_control import (
63+
State, Input, Sensor, Controller,
64+
ControlModel, verify,
65+
)
66+
67+
model = ControlModel(
68+
name="HVAC System",
69+
states=[
70+
State(name="temperature", initial=22.0),
71+
State(name="humidity", initial=45.0),
72+
],
73+
inputs=[
74+
Input(name="temp_setpoint"),
75+
Input(name="humidity_setpoint"),
76+
],
77+
sensors=[
78+
Sensor(name="temp_sensor", observes=["temperature"]),
79+
Sensor(name="humidity_sensor", observes=["humidity"]),
80+
],
81+
controllers=[
82+
Controller(
83+
name="heater",
84+
reads=["temp_sensor", "temp_setpoint"],
85+
drives=["temperature"],
86+
),
87+
Controller(
88+
name="humidifier",
89+
reads=["humidity_sensor", "humidity_setpoint"],
90+
drives=["humidity"],
91+
),
92+
],
93+
)
94+
95+
# Verify
96+
report = verify(model, include_gds_checks=False)
97+
for f in report.findings:
98+
print(f" [{f.check_id}] {'PASS' if f.passed else 'FAIL'} {f.message}")
99+
```
100+
101+
## Next Steps
102+
103+
- [Elements & GDS Mapping](guide/elements.md) -- detailed element reference and how each maps to GDS
104+
- [Verification Guide](guide/verification.md) -- all 6 domain checks explained
105+
- [API Reference](api/init.md) -- complete auto-generated API docs

docs/control/guide/elements.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Elements & GDS Mapping
2+
3+
`gds-control` provides four element types, each mapping to a specific GDS role and corresponding to the standard state-space representation.
4+
5+
## State
6+
7+
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.
8+
9+
```python
10+
State(name="temperature", initial=20.0)
11+
```
12+
13+
**GDS mapping:** `Mechanism` (state update *f*) + `Entity` (state *X*)
14+
15+
**State-space:** x (state vector)
16+
17+
| Field | Type | Default | Description |
18+
|-------|------|---------|-------------|
19+
| `name` | str | required | State name (becomes entity name) |
20+
| `initial` | float \| None | None | Initial value |
21+
22+
### Port Convention
23+
24+
- Output: `"{Name} State"` (temporal feedback to sensors)
25+
- Input: `"{ControllerName} Control"` (incoming control signals)
26+
27+
---
28+
29+
## Input
30+
31+
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.
32+
33+
```python
34+
Input(name="setpoint")
35+
```
36+
37+
**GDS mapping:** `BoundaryAction` (exogenous input *U*)
38+
39+
**State-space:** r (reference signal)
40+
41+
| Field | Type | Default | Description |
42+
|-------|------|---------|-------------|
43+
| `name` | str | required | Input name |
44+
45+
### Port Convention
46+
47+
- Output: `"{Name} Reference"`
48+
49+
---
50+
51+
## Sensor
52+
53+
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.
54+
55+
```python
56+
Sensor(name="thermometer", observes=["temperature"])
57+
```
58+
59+
**GDS mapping:** `Policy` (observation *g*)
60+
61+
**State-space:** y = Cx + Du (sensor output)
62+
63+
| Field | Type | Default | Description |
64+
|-------|------|---------|-------------|
65+
| `name` | str | required | Sensor name |
66+
| `observes` | list[str] | [] | Names of states this sensor reads |
67+
68+
### Port Convention
69+
70+
- Input: `"{StateName} State"`
71+
- Output: `"{Name} Measurement"`
72+
73+
---
74+
75+
## Controller
76+
77+
A controller reads sensor measurements and/or reference inputs, then emits control signals to drive state variables.
78+
79+
```python
80+
Controller(name="PID", reads=["thermometer", "setpoint"], drives=["temperature"])
81+
```
82+
83+
**GDS mapping:** `Policy` (decision logic *g*)
84+
85+
**State-space:** u = K(y, r) (control law)
86+
87+
| Field | Type | Default | Description |
88+
|-------|------|---------|-------------|
89+
| `name` | str | required | Controller name |
90+
| `reads` | list[str] | [] | Names of sensors/inputs this controller reads |
91+
| `drives` | list[str] | [] | Names of states this controller drives |
92+
93+
### Port Convention
94+
95+
- Input: `"{ReadName} Measurement"` or `"{ReadName} Reference"`
96+
- Output: `"{Name} Control"`
97+
98+
---
99+
100+
## Semantic Type System
101+
102+
Four distinct semantic spaces, all `float`-backed but structurally separate -- this prevents accidentally wiring a measurement where a control signal is expected:
103+
104+
| Type | Space | Used By | Description |
105+
|------|-------|---------|-------------|
106+
| `StateType` | `StateSpace` | States | Plant state variables |
107+
| `ReferenceType` | `ReferenceSpace` | Inputs | Exogenous reference/disturbance signals |
108+
| `MeasurementType` | `MeasurementSpace` | Sensors | Sensor output measurements |
109+
| `ControlType` | `ControlSpace` | Controllers | Controller output signals |
110+
111+
## Composition Structure
112+
113+
The compiler builds a tiered composition tree:
114+
115+
```
116+
(inputs | sensors) >> (controllers) >> (state dynamics)
117+
.loop([state dynamics forward_out -> sensor forward_in])
118+
```
119+
120+
This maps to the GDS canonical form `h = f . g` where states carry state (X), dynamics provide f, and sensors + controllers contribute to g.

0 commit comments

Comments
 (0)