Skip to main content

Tutorial examples for gds-framework — six complete domain models demonstrating every framework feature

Project description

GDS Framework Examples

PyPI Python License

Six complete domain models demonstrating every gds-framework feature. Each model.py is written as a tutorial chapter with inline GDS theory commentary — read them in order.

Table of Contents

Learning Path

Start with SIR Epidemic and work down. Each example introduces one new concept.

# Example New Concept Composition Roles
1 SIR Epidemic Fundamentals — TypeDef, Entity, Space, blocks >> | BA, P, M
2 Thermostat PID .feedback(), CONTRAVARIANT backward flow >> .feedback() BA, P, CA, M
3 Lotka-Volterra .loop(), COVARIANT temporal iteration >> | .loop() BA, P, M
4 Prisoner's Dilemma Nested |, multi-entity X, complex trees | >> .loop() BA, P, M
5 Insurance Contract ControlAction role, complete 4-role taxonomy >> BA, P, CA, M
6 Crosswalk Problem Mechanism design, discrete Markov transitions >> BA, P, CA, M

Roles: BA = BoundaryAction, P = Policy, CA = ControlAction, M = Mechanism

Quick Start

# Run all example tests (168 tests)
uv run pytest examples/ -v

# Run a specific example
uv run pytest examples/sir_epidemic/ -v

# Generate all structural diagrams
uv run python examples/visualize_examples.py

# Generate all 6 views for one example
uv run python examples/sir_epidemic/generate_views.py          # print to stdout
uv run python examples/sir_epidemic/generate_views.py --save   # write VIEWS.md

File Structure

Each example follows the same layout:

examples/sir_epidemic/
├── __init__.py          # empty
├── model.py             # types, entities, spaces, blocks, build_spec(), build_system()
├── test_model.py        # comprehensive tests for every layer
├── generate_views.py    # generates all 6 visualization views with commentary
└── VIEWS.md             # generated output — 6 Mermaid diagrams with explanations

Examples

SIR Epidemic

Start here. 3 compartments (Susceptible, Infected, Recovered) with contact-driven infection dynamics.

X = (S, I, R)    U = contact_rate    g = infection_policy    f = (update_s, update_i, update_r)    Θ = {beta, gamma, contact_rate}
contact >> infection_policy >> (update_s | update_i | update_r)
What you'll learn
  • TypeDef with runtime constraints (non-negative counts, positive rates)
  • Entity and StateVariable for defining state space X
  • Space for typed inter-block communication channels
  • BoundaryAction (exogenous input), Policy (decision logic), Mechanism (state update)
  • >> sequential composition with token-based auto-wiring
  • | parallel composition for independent mechanisms
  • GDSSpec registration and SpecWiring
  • compile_system() to produce SystemIR

Files: model.py · tests · views


Thermostat PID

Adds feedback — backward information flow within a single timestep.

X = (T, E)    U = measured_temp    g = pid_controller    f = update_room    Θ = {setpoint, Kp, Ki, Kd}
(sensor >> controller >> plant >> update).feedback([Energy Cost: plant -> controller CONTRAVARIANT])
What you'll learn
  • .feedback() composition for within-timestep backward flow
  • CONTRAVARIANT flow direction (backward_out → backward_in)
  • ControlAction role — reads state and emits control signals (vs Mechanism which writes state)
  • backward_in / backward_out ports on block interfaces
  • Multi-variable Entity (Room has both temperature and energy_consumed)

Key distinction: Room Plant is ControlAction (not Mechanism) because it has backward_out. Mechanisms cannot have backward ports.

Files: model.py · tests · views


Lotka-Volterra

Adds temporal loops — forward iteration across timesteps.

X = (x, y)    U = population_signal    g = compute_rates    f = (update_prey, update_predator)    Θ = {prey_birth_rate, ...}
(observe >> compute >> (update_prey | update_pred)).loop([Population Signal -> Compute Rates COVARIANT])
What you'll learn
  • .loop() composition for cross-timestep temporal feedback
  • COVARIANT flow direction — mandatory for .loop() (CONTRAVARIANT raises GDSTypeError)
  • Mechanism with forward_out — emitting signals after state update
  • exit_condition parameter for loop termination
  • Contrast with .feedback(): within-timestep (thermostat) vs across-timestep (here)

Key distinction: Temporal wirings must be COVARIANT — .loop() enforces this at construction time.

Files: model.py · tests · views


Prisoner's Dilemma

Most complex composition — nested parallel + sequential + temporal loop.

X = (s_A, U_A, s_B, U_B, t)    U = game_config    g = (alice, bob)    f = (payoff, world_models)    Θ = {}
pipeline = (payoff_setting | (alice | bob)) >> payoff_realization >> (alice_world | bob_world)
system = pipeline.loop([world models -> decisions])
What you'll learn
  • Nested parallel composition: (A | B) | C for logical grouping
  • Multi-entity state space X with 3 entities (5 state variables total)
  • Mechanism with forward_out for temporal feedback
  • Complex composition tree combining all operators except .feedback()
  • Design choice: parameter vs exogenous input (payoff matrix is U, not Θ)

Files: model.py · tests · views · architecture viz


Insurance Contract

Completes the role taxonomy — the only example using all 4 block roles.

X = (R, P, C, H)    U = claim_event    g = risk_assessment    d = premium_calculation    f = (claim_payout, reserve_update)    Θ = {base_premium_rate, deductible, coverage_limit}
claim >> risk >> premium >> payout >> reserve_update
What you'll learn
  • ControlAction role — the 4th block role, for admissibility/control decisions
  • Complete 4-role taxonomy: BoundaryAction → Policy → ControlAction → Mechanism
  • ControlAction vs Policy: Policy is core decision logic (g), ControlAction constrains the action space (d)
  • params_used on ControlAction — parameterized admissibility rules

Key distinction: Premium Calculation is ControlAction because it enforces admissibility constraints — it decides what's allowed, not what to do.

Files: model.py · tests · views


Crosswalk Problem

Mechanism design — the canonical GDS example from BlockScience. A pedestrian decides whether to cross a one-way street while traffic evolves as a discrete Markov chain. A governance body chooses crosswalk placement to minimize accident probability.

X = traffic_state ∈ {-1, 0, +1}    U = (luck, crossing_position)    g = pedestrian_decision    d = safety_check    f = traffic_transition    Θ = {crosswalk_location}
observe >> decide >> check >> transition
What you'll learn
  • Discrete Markov state transitions as GDS
  • Mechanism design: governance parameter (crosswalk location) constraining agent behavior
  • ControlAction for admissibility enforcement (safety check)
  • Complete 4-role taxonomy in a minimal model
  • Design parameter Θ as a governance lever

Files: model.py · tests · views · README

Visualization Views

Each example includes a generate_views.py script that produces 6 complementary views via gds-viz:

View Input What It Shows
1. Structural SystemIR Compiled block graph — role shapes, wiring arrows
2. Canonical GDS CanonicalGDS Mathematical decomposition: X_t → U → g → f → X_{t+1}
3. Architecture by Role GDSSpec Blocks grouped by GDS role
4. Architecture by Domain GDSSpec Blocks grouped by domain tag
5. Parameter Influence GDSSpec Θ → blocks → entities causal map
6. Traceability GDSSpec Backwards trace from one state variable to all influencing blocks
Sample diagrams

Architecture by domain (Thermostat PID) — blocks grouped by physical subsystem:

%%{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
    classDef entity fill:#e2e8f0,stroke:#475569,stroke-width:2px,color:#0f172a
    classDef param fill:#fdba74,stroke:#ea580c,stroke-width:2px,color:#7c2d12
    classDef state fill:#5eead4,stroke:#0d9488,stroke-width:2px,color:#134e4a
    classDef target fill:#fca5a5,stroke:#dc2626,stroke-width:2px,color:#7f1d1d
    classDef empty fill:#e2e8f0,stroke:#94a3b8,stroke-width:1px,color:#475569
    subgraph Sensor ["Sensor"]
        Temperature_Sensor([Temperature Sensor]):::boundary
    end
    subgraph Controller ["Controller"]
        PID_Controller[PID Controller]:::policy
    end
    subgraph Plant ["Plant"]
        Room_Plant[Room Plant]:::control
        Update_Room[[Update Room]]:::mechanism
    end
    entity_Room[("Room<br/>temperature: T, energy_consumed: E")]:::entity
    Update_Room -.-> entity_Room
    Temperature_Sensor --TemperatureSpace--> PID_Controller
    PID_Controller --CommandSpace--> Room_Plant
    Room_Plant --EnergyCostSpace--> PID_Controller
    Room_Plant --RoomStateSpace--> Update_Room

Structural view (Thermostat PID) — thick feedback arrow (==>) shows CONTRAVARIANT 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

Parameter influence (SIR Epidemic) — Θ → blocks → entities causal map:

%%{init:{"theme":"neutral"}}%%
flowchart LR
    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
    classDef entity fill:#e2e8f0,stroke:#475569,stroke-width:2px,color:#0f172a
    classDef param fill:#fdba74,stroke:#ea580c,stroke-width:2px,color:#7c2d12
    classDef state fill:#5eead4,stroke:#0d9488,stroke-width:2px,color:#134e4a
    classDef target fill:#fca5a5,stroke:#dc2626,stroke-width:2px,color:#7f1d1d
    classDef empty fill:#e2e8f0,stroke:#94a3b8,stroke-width:1px,color:#475569
    param_beta{{"beta"}}:::param
    param_contact_rate{{"contact_rate"}}:::param
    param_gamma{{"gamma"}}:::param
    Contact_Process[Contact Process]
    Infection_Policy[Infection Policy]
    entity_Infected[("Infected<br/>I")]:::entity
    entity_Recovered[("Recovered<br/>R")]:::entity
    entity_Susceptible[("Susceptible<br/>S")]:::entity
    param_beta -.-> Infection_Policy
    param_contact_rate -.-> Contact_Process
    param_gamma -.-> Infection_Policy
    Update_Recovered -.-> entity_Recovered
    Update_Susceptible -.-> entity_Susceptible
    Update_Infected -.-> entity_Infected
    Contact_Process --> Infection_Policy
    Infection_Policy --> Update_Infected
    Infection_Policy --> Update_Recovered
    Infection_Policy --> Update_Susceptible

Each example's VIEWS.md contains all 6 views with commentary. Output is Mermaid markdown — renders in GitHub, GitLab, VS Code, Obsidian, and mermaid.live.

# Generate views for one example
uv run python examples/sir_epidemic/generate_views.py --save

# Generate views for all examples
for d in sir_epidemic thermostat lotka_volterra prisoners_dilemma insurance crosswalk; do
    uv run python examples/$d/generate_views.py --save
done

Feature Coverage Matrix

Feature SIR Thermostat Lotka-V Prisoner's D Insurance Crosswalk
BoundaryAction
Policy
Mechanism
ControlAction
>> (sequential)
| (parallel)
.feedback()
.loop()
CONTRAVARIANT wiring
Temporal wiring
Multi-variable Entity
Multiple entities
Parameters (Θ)

Building New Examples

See CLAUDE.md for a detailed guide covering:

  • Step-by-step model creation (types → entities → spaces → blocks → spec → system)
  • Role constraint rules (what each role enforces on its interface)
  • Composition operator reference with pitfalls
  • Common mistakes at construction, registration, and validation time
  • Test patterns to follow
  • Design decisions (state vs signal, parameter vs exogenous input, ControlAction vs Policy)

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gds_examples-0.1.2.tar.gz (61.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gds_examples-0.1.2-py3-none-any.whl (74.2 kB view details)

Uploaded Python 3

File details

Details for the file gds_examples-0.1.2.tar.gz.

File metadata

  • Download URL: gds_examples-0.1.2.tar.gz
  • Upload date:
  • Size: 61.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","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

Hashes for gds_examples-0.1.2.tar.gz
Algorithm Hash digest
SHA256 ebf15615751d2cb92f3611ec8a4ce39645fedda2b139bb20e8ccab630c788a1f
MD5 41e914011cfd23ca9574773a4e14aea5
BLAKE2b-256 e94ee0cb10ddcf5d43272bd394cbbf21f12bae003c364663901a3557fab57d05

See more details on using hashes here.

File details

Details for the file gds_examples-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: gds_examples-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 74.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","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

Hashes for gds_examples-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c863a62bc277e3735ff8827db361a06216d9c79e8baa687b4728480700bc8345
MD5 adc4a5e490a7357a2c29438aa62339f6
BLAKE2b-256 1cf9f9b042e714d0048d819aba326030628a6287aa2418ec1c41eb64da757798

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page