docs: expand package READMEs and add double integrator example#26
docs: expand package READMEs and add double integrator example#26rororowyourboat merged 5 commits intomainfrom
Conversation
This reverts commit e9bee2d.
Classical state-space control model using the gds-control DSL. Demonstrates compile_model/compile_to_system, (A,B,C,D) ↔ (X,U,g,f) correspondence, multi-state entities, and temporal loops. 43 tests covering model declaration, DSL verification, canonical projection, SystemIR compilation, GDS verification, and query API.
There was a problem hiding this comment.
Pull request overview
This PR expands package-level documentation across the GDS ecosystem and adds a new gds-control-DSL-based “Double Integrator” tutorial example in gds-examples, including visualization output and tests.
Changes:
- Expanded READMEs for
gds-stockflow,gds-control,gds-games, andgds-exampleswith architecture/verification details and usage examples. - Added the Double Integrator control example (model, views generator, committed
VIEWS.md, and a comprehensive test suite). - Added
gds-controlas a dependency ofgds-examplesand updated example tooling/configuration.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/gds-stockflow/README.md | Expanded stock-flow DSL documentation (architecture, elements, verification, examples). |
| packages/gds-games/README.md | Expanded game DSL documentation (IR layers, composition, helpers, verification, CLI). |
| packages/gds-control/README.md | Expanded control DSL documentation (state-space mapping, composition, verification, examples). |
| packages/gds-examples/README.md | Updated examples docs to include domain organization and updated commands/links. |
| packages/gds-examples/pyproject.toml | Added gds-control dependency and updated build/mypy include lists for the new example. |
| packages/gds-examples/visualize_examples.py | Added Double Integrator to the visualization batch runner. |
| packages/gds-examples/control/double_integrator/model.py | New Double Integrator model built with gds-control DSL + canonical projection helper. |
| packages/gds-examples/control/double_integrator/test_model.py | New tests covering DSL model, compiled spec, canonical projection, SystemIR, verification, and query API. |
| packages/gds-examples/control/double_integrator/generate_views.py | New script to generate 6 visualization views for the example. |
| packages/gds-examples/control/double_integrator/VIEWS.md | Generated Mermaid views checked into the repo for the new example. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "insurance", | ||
| "lotka_volterra", | ||
| "prisoners_dilemma", | ||
| "sir_epidemic", | ||
| "thermostat", | ||
| "double_integrator", | ||
| ] |
There was a problem hiding this comment.
only-include and the mypy files list add double_integrator, but the new example directory is control/double_integrator/. As written, the wheel build and type-check configuration may omit the new example (or point at a non-existent path). Update these entries to match the actual on-disk layout.
| from double_integrator.model import ( | ||
| build_canonical, | ||
| build_model, | ||
| build_spec, | ||
| build_system, |
There was a problem hiding this comment.
pytest and project_canonical are imported but never used in this test module; with the repo-wide Ruff config selecting F rules, this will fail lint (F401). Please remove the unused imports (or use them if intended).
| U = force — exogenous reference: cols of B | ||
| g = (pos_sensor, vel_sensor, PD) — observation + control law: C and K | ||
| f = (position Dynamics, velocity Dynamics) — state transition: A | ||
| Θ = {} — no explicit parameters in this model |
There was a problem hiding this comment.
The module docstring claims Θ = {} / "no explicit parameters", but gds_control.dsl.compile.compile_model() registers every Input as a ParameterDef in the spec's parameter_schema. For this model that means force will appear in Θ, so the decomposition text should be updated to avoid contradicting the generated canonical view.
| Θ = {} — no explicit parameters in this model | |
| Θ = {force} — single input parameter registered from `force` |
| X_t(["X_t<br/>position.value, velocity.value"]):::state | ||
| X_next(["X_{t+1}<br/>position.value, velocity.value"]):::state | ||
| Theta{{"Θ<br/>force"}}:::param | ||
| subgraph U ["Boundary (U)"] | ||
| force[force]:::boundary |
There was a problem hiding this comment.
The narrative says there are no explicit parameters, but the canonical view in this checked-in output includes Θ with force (line 56). Please regenerate or edit the view content so the written explanation and diagrams are consistent.
| Six complete domain models demonstrating every [gds-framework](https://github.com/BlockScience/gds-core/tree/main/packages/gds-framework) feature. Each `model.py` is written as a tutorial chapter with inline GDS theory commentary — read them in order. | ||
|
|
||
| Examples are organized by domain and built using the GDS framework primitives directly. For higher-level domain DSLs that compile to GDS automatically, see the individual packages: | ||
|
|
||
| | Domain | DSL Package | Examples Here | | ||
| |--------|-------------|---------------| | ||
| | System dynamics | [gds-stockflow](https://github.com/BlockScience/gds-core/tree/main/packages/gds-stockflow) | SIR Epidemic, Lotka-Volterra | | ||
| | Control theory | [gds-control](https://github.com/BlockScience/gds-core/tree/main/packages/gds-control) | Thermostat PID | | ||
| | Game theory | [gds-games](https://github.com/BlockScience/gds-core/tree/main/packages/gds-games) | Prisoner's Dilemma, Insurance, Crosswalk | |
There was a problem hiding this comment.
The intro still says "Six" models, but this PR adds a new Double Integrator example (and the PR description/test plan references 211 tests / 6 views generated). Please update the count and any nearby wording so the README reflects the actual number of examples shipped.
| ```bash | ||
| # Run all example tests (168 tests) | ||
| uv run pytest examples/ -v | ||
| uv run --package gds-examples pytest packages/gds-examples -v | ||
|
|
||
| # Run a specific example | ||
| uv run pytest examples/sir_epidemic/ -v | ||
| uv run --package gds-examples pytest packages/gds-examples/stockflow/sir_epidemic/ -v | ||
|
|
||
| # Generate all structural diagrams | ||
| uv run python examples/visualize_examples.py | ||
| uv run python packages/gds-examples/visualize_examples.py |
There was a problem hiding this comment.
The test command section still references an outdated total ("168 tests") even though this PR adds a substantial new test suite and the PR description cites 211 tests. Please update the number (or remove it) to avoid it going stale again.
| files = [ | ||
| "crosswalk", | ||
| "insurance", | ||
| "lotka_volterra", | ||
| "prisoners_dilemma", | ||
| "sir_epidemic", | ||
| "thermostat", | ||
| "double_integrator", | ||
| "visualize_examples.py", | ||
| ] | ||
|
|
||
| [[tool.mypy.overrides]] | ||
| module = ["gds_viz.*", "pytest"] | ||
| module = ["gds_viz.*", "gds_control.*", "pytest"] | ||
| ignore_missing_imports = true |
There was a problem hiding this comment.
The mypy files list adds double_integrator, but the example is located at control/double_integrator/ (and similarly other examples are under domain subdirectories). Point the files entries at the real paths so mypy actually checks the example code and doesn't silently skip it.
| from double_integrator.model import build_spec, build_system | ||
| from gds.canonical import project_canonical | ||
| from gds_viz import ( | ||
| canonical_to_mermaid, | ||
| params_to_mermaid, | ||
| spec_to_mermaid, | ||
| system_to_mermaid, | ||
| trace_to_mermaid, | ||
| ) | ||
|
|
There was a problem hiding this comment.
from double_integrator.model import ... will not resolve when this script is run by file path (as suggested in the Usage block) because Python adds the script directory to sys.path, not its parent. Use a relative import (from .model ...) or an absolute import that matches the installed package layout (e.g., control.double_integrator.model) so the script works consistently.
| "Θ → blocks → entities causal map. This model has no explicit\n" | ||
| "parameters — the DSL focuses on structural topology, not gains.\n" |
There was a problem hiding this comment.
This section says the model has no explicit parameters, but the generated canonical view in the same file shows Θ containing force (and the gds-control compiler registers inputs into parameter_schema). Update the wording to reflect that Θ includes the exogenous input parameter (or adjust the generator/output so the narrative and diagram agree).
| "Θ → blocks → entities causal map. This model has no explicit\n" | |
| "parameters — the DSL focuses on structural topology, not gains.\n" | |
| "Θ → blocks → entities causal map. Here Θ contains the exogenous\n" | |
| "input parameter force; beyond this, the DSL focuses on structural\n" | |
| "topology rather than explicit gain parameters.\n" |
| ("Lotka-Volterra", "lotka_volterra.model"), | ||
| ("Prisoner's Dilemma", "prisoners_dilemma.model"), | ||
| ("Crosswalk Problem", "crosswalk.model"), | ||
| ("Double Integrator", "double_integrator.model"), |
There was a problem hiding this comment.
The new entry imports double_integrator.model, but the example lives under control/double_integrator/ in this package. Unless the package layout intentionally installs double_integrator as a top-level module, this import_module() will fail at runtime. Consider using the correct dotted path (e.g., control.double_integrator.model) consistent with the on-disk structure.
| ("Double Integrator", "double_integrator.model"), | |
| ("Double Integrator", "control.double_integrator.model"), |
Summary
Test plan
uv run --package gds-examples pytest control/double_integrator/test_model.py -v)