From a5892bc02e5c07f6e7a2a2d53f151b51e94b7392 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sun, 25 Oct 2026 06:04:59 +0000 Subject: [PATCH 1/2] docs(examples): re-record the example walkthroughs against the pinned binaries Calculation and analysis results print in their effective multiplicity, choice-point counts name the independent ones, the Mermaid frontmatter and container titles changed, a completed state machine lists under Behaviors, and the instance IDs, check-engine and -render-all figures moved. The two Python demo scripts read the one-element sequences the opensysml client returns. examples/README.md lists general-views-demo/, whose walkthrough now names the name-conflict warning its model prints, and the parser feature demos page states the current 110-file conformance figure. Co-Authored-By: jason.han --- .../unreleased/docs-audit-examples.fixed.md | 1 + examples/EXPRESSIONS-DEMO.md | 18 +-- examples/PARSER_FEATURES_DEMOS.md | 39 +++--- examples/README.md | 6 +- examples/SOLVER-DEMO.md | 1 + examples/VIEWS-DEMO.md | 26 ++-- examples/analysis-demo/README.md | 122 +++++++++++------- examples/analysis-demo/lander_demo.py | 11 +- examples/analysis-results-demo/README.md | 30 ++--- examples/disposal-robot-demo/README.md | 61 ++++----- examples/disposal-robot-demo/robot_demo.py | 4 +- examples/disposal-team-demo/README.md | 3 - examples/general-views-demo/README.md | 5 + examples/relay-probe-demo/README.md | 4 +- examples/runtime-showcase/README.md | 22 ++-- 15 files changed, 182 insertions(+), 171 deletions(-) create mode 100644 changes/unreleased/docs-audit-examples.fixed.md diff --git a/changes/unreleased/docs-audit-examples.fixed.md b/changes/unreleased/docs-audit-examples.fixed.md new file mode 100644 index 0000000000..1539f50da9 --- /dev/null +++ b/changes/unreleased/docs-audit-examples.fixed.md @@ -0,0 +1 @@ +- The example walkthroughs under `examples/` again show what the pinned binaries print: a calculation or analysis result held in its effective multiplicity (`fuelUsed = [120.0]`, `= [6432.955324716369 [SI::'m/s']]`), the `(N independent)` choice-point counts and the `order-dependent` marker on a value a schedule decides, the current Mermaid frontmatter and one-line container titles, the `%features` listing of a completed state machine, the instance IDs a session allocates, and the figures of the check engine, `-render-all` and the stdlib conformance gate. `lander_demo.py` and `robot_demo.py` read the one-element sequences the `opensysml` client now returns instead of failing to format them, `examples/README.md` lists `general-views-demo/`, and the general-views walkthrough names the `name-conflict` warning its model prints. diff --git a/examples/EXPRESSIONS-DEMO.md b/examples/EXPRESSIONS-DEMO.md index 9a0d381362..1709d6006d 100644 --- a/examples/EXPRESSIONS-DEMO.md +++ b/examples/EXPRESSIONS-DEMO.md @@ -176,11 +176,11 @@ over. `square` and `halve` are usages of the `Square` and `Halve` definitions; ``` ✓ Squared(3.0) - = 9.0 + = [9.0] ✓ Halved(3.0) - = 1.5 + = [1.5] ✓ Apply(halve, 9.0) - = 4.5 + = [4.5] ``` Reading a calculation on its own answers the function, named by its @@ -210,7 +210,7 @@ function: ``` ``` -Instance: ExpressionsDemo::Amplifier (ID: 13) +Instance: ExpressionsDemo::Amplifier (ID: 9) Features: gain = 1.5 transfer = ExpressionsDemo::Amplifier::amplify @@ -240,11 +240,11 @@ equal, and so are their `elements`. ``` ``` -Instance: ExpressionsDemo::RadioBands (ID: 14) +Instance: ExpressionsDemo::RadioBands (ID: 10) Features: - requested = Instance(ID: 15) + requested = Instance(ID: 11) elements = Set{"Ka", "S", "X"} - licensed = Instance(ID: 16) + licensed = Instance(ID: 12) elements = Set{"Ka", "S", "X"} distinctBands = 3 sameBands = true @@ -270,7 +270,7 @@ dimension, and the arithmetic keeps the shape component by component: ``` ``` -Instance: ExpressionsDemo::MountStress (ID: 17) +Instance: ExpressionsDemo::MountStress (ID: 13) Features: field = Tensor(2, 2, 2)[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0] [Pa] rank = 3 @@ -300,7 +300,7 @@ in i : Instrument; i.mass }` is a `MassValue[0..*]` and can be declared as one ``` ``` -Instance: ExpressionsDemo::MassRollup (ID: 19) +Instance: ExpressionsDemo::MassRollup (ID: 15) Features: instruments = [Instance(ID: 2), Instance(ID: 4), Instance(ID: 3)] mass = 4.0 [kg] diff --git a/examples/PARSER_FEATURES_DEMOS.md b/examples/PARSER_FEATURES_DEMOS.md index a492a0affb..c7b6796c07 100644 --- a/examples/PARSER_FEATURES_DEMOS.md +++ b/examples/PARSER_FEATURES_DEMOS.md @@ -4,13 +4,13 @@ Demonstrations of the SysML v2 / KerML parser features that let every file of th ## Overview -These demos showcase parser improvements across multiple development sessions (Sessions 2-5). Each demo file focuses on a specific category of features with working examples extracted from real stdlib usage patterns. +Each demo file focuses on a specific category of features with working examples extracted from real stdlib usage patterns. -**Parser Status:** 96/96 bundled library files parse cleanly (94 official SysML v2 standard library files plus two OpenSysML extensions), gated by `internal/workspace/libs/stdlib_conformance_test.go`. +**Parser Status:** 110/110 bundled library files parse cleanly (94 official SysML v2 standard library files plus the 16 libraries under `OpenSysML Libraries/`), gated by `internal/workspace/libs/stdlib_conformance_test.go`. ## Demo Files -### Original Demos (Sessions 2-3) +### Original Demos #### 1. Relationships Demo (`parser_features_demo_relationships.kerml`) @@ -81,7 +81,7 @@ demo 6, `parser_features_demo_advanced_connectors.kerml`. - Alternative to `=` for value assignment - Clearer intent for default values -### Advanced Demos (Sessions 4-5) +### Advanced Demos #### 6. Advanced Connectors Demo (`parser_features_demo_advanced_connectors.kerml`) @@ -258,38 +258,33 @@ go test ./examples -run '^TestParserFeaturesDeclarations$' -v go test ./examples -run '^TestParserFeaturesEdgeCases$' -v ``` -## Development Context +## Feature Summary -These features were implemented across five development sessions: +### Original features +- inverse of, unions, protected/readonly, nonunique, default keyword, binding syntax, constant modifier, succession first/then, chains relationship, connection connect keyword -### Sessions 2-3 (Tasks 47-57) -- **Coverage:** 76.8% → 81.1% (+4.3pp, +4 files) -- **Features:** inverse of, unions, protected/readonly, nonunique, default keyword, binding syntax, constant modifier, succession first/then, chains relationship, connection connect keyword +### Advanced features +- Connector enhancements (end modifiers, references, single-end typing, transition usage) +- Action semantics (assign, perform, while, if, namespace succession) +- Advanced bodies (predicate/bool returns, shorthand params, constraint members) +- Messages & events (message/event keywords, ref with body) +- Declarations (multiplicity, classifier/subclassifier, multiple typing, subset/disjoint) +- Edge cases (keywords in expressions, identifier multiplicities, bind/require/step shortcuts) -### Sessions 4-5 (Tasks 58-94) -- **Coverage:** 81.1% → 100.0% (+18.9pp, +18 files) -- **Features:** 37 tasks implementing all remaining stdlib patterns - - Connector enhancements (end modifiers, references, single-end typing, transition usage) - - Action semantics (assign, perform, while, if, namespace succession) - - Advanced bodies (predicate/bool returns, shorthand params, constraint members) - - Messages & events (message/event keywords, ref with body) - - Declarations (multiplicity, classifier/subclassifier, multiple typing, subset/disjoint) - - Edge cases (keywords in expressions, identifier multiplicities, bind/require/step shortcuts) - -**Final Status:** 100.0% (96/96 bundled library files parse cleanly) +**Status:** 110/110 bundled library files parse cleanly (`go test -run TestStdlibConformance ./internal/workspace/libs`) ## Real-World Usage These patterns appear throughout the official standard library: -**Original features (Sessions 2-3):** +**Original features:** - Base.kerml: chains relationship, visibility modifiers - Occurrences.kerml: inverse of, succession patterns - Interfaces.sysml: protected references, nonunique ports - ShapeItems.sysml: complex binding patterns, connection with connect - CausationConnections.sysml: named succession with first/then -**Advanced features (Sessions 4-5):** +**Advanced features:** - Actions.sysml: action semantics, namespace succession, transition usage - Flows.sysml: message/event keywords, ref with body - Base.kerml: multiplicity declarations, classifier keyword diff --git a/examples/README.md b/examples/README.md index ba5946101a..d67de39cec 100644 --- a/examples/README.md +++ b/examples/README.md @@ -40,6 +40,7 @@ Each of these is a model and a walkthrough of the commands that exercise it. | [solver-demo.sysml](solver-demo.sysml) | [SOLVER-DEMO.md](SOLVER-DEMO.md) | `%check`, `%explain`, `%solve`, `%configure` and `%optimize` — what conditions *can* hold, which conflict, what satisfies them, which variants are permitted, what is best (needs z3 or cvc5) | | [oosem-demo/oosem-demo.sysml](oosem-demo/oosem-demo.sysml) | [oosem-demo/README.md](oosem-demo/README.md) | the `OOSEM` library on a small Earth-observation mission: as-is and to-be enterprise, causal analysis, stakeholder needs derived down to component requirements with `#moe`/`#mop`, the black-box system context and its use case, the logical scenario and components, and the physical architecture distributed over nodes | | [mosa-demo/mosa-demo.sysml](mosa-demo/mosa-demo.sysml) | [mosa-demo/README.md](mosa-demo/README.md) | the `MOSA` library on a modular ground vehicle: the major system platform, its major system components and a modular autonomy system, the modular system interfaces between them (one written as `#keyInterface`), the consensus standards they conform to, data rights and proprietary elements, interface control, MOSA requirements with their traces, a conformance assessment, the MOSA views and a generated interface control document; `-validate` reports the openness gaps the model leaves on purpose | +| [general-views-demo/](general-views-demo/) | [general-views-demo/README.md](general-views-demo/README.md) | `GeneralView`s drawn as graphs: a requirement graph with satisfy, verify, derive and refine edges, coloured by verification verdict with `-render-overlay verdicts`; a definition-and-usage graph; a package graph; and the use case diagrams a `filter @SysML::UseCaseUsage` view is drawn as | | [views-demo.sysml](views-demo.sysml) | [VIEWS-DEMO.md](VIEWS-DEMO.md) | `%view` and `%render` — the seven rendering kinds, the text/Mermaid/Markdown forms, viewpoint conformance and filtered exposure | | [expressions-demo.sysml](expressions-demo.sysml) | [EXPRESSIONS-DEMO.md](EXPRESSIONS-DEMO.md) | the expression forms worked through one payload: `as` casts that select rather than convert, `*` as the unbounded value, `.metadata` on an annotated part, calculations passed and invoked as function values, a `Set` with no order and no repeats, a rank-three tensor quantity indexed and scaled, and `collect`/`select`/`reduce` bodies typed by what they return | | [action-executor-demo.sysml](action-executor-demo.sysml) | [ACTION-EXECUTOR-DEMO.md](ACTION-EXECUTOR-DEMO.md) | executing actions, and stepping one in the REPL | @@ -57,7 +58,10 @@ in [checking](../docs/guide/05-checking.md), and [rdf-interop-demo.sysml](rdf-interop-demo.sysml) — structure only, so it round-trips — in [saving and RDF](../docs/guide/07-saving-and-rdf.md). [phase-c-behavioral-bodies.sysml](phase-c-behavioral-bodies.sysml) exercises the -calculation, constraint, requirement, action and state bodies the parser accepts, and +calculation, constraint, requirement, action and state bodies the parser accepts, +[gridview-relationship-matrix.sysml](gridview-relationship-matrix.sysml) is the `GridView` +relationship matrix the [view rendering forms](../docs/project/view-rendering-forms.md) record +describes, and [runtime-demo/](runtime-demo/) is a Go program (`go run ./examples/runtime-demo`) that drives the parser, resolver and runtime directly rather than through `sysml`. diff --git a/examples/SOLVER-DEMO.md b/examples/SOLVER-DEMO.md index a61f0d97db..bf36099f1a 100644 --- a/examples/SOLVER-DEMO.md +++ b/examples/SOLVER-DEMO.md @@ -52,6 +52,7 @@ exceed its own budget, so it cannot hold: ``` ``` +✗ Requirement OverbookedBudget is unsatisfiable (z3, 9ms) ✗ Requirement OverbookedBudget is unsatisfiable: 3 conditions conflict (z3, 26ms) Every condition below is needed: dropping any one leaves the rest satisfiable. 1. required condition: `rover.drivePower + rover.sciencePower <= 200` — requirement OverbookedBudget, at …:65:13 diff --git a/examples/VIEWS-DEMO.md b/examples/VIEWS-DEMO.md index af8974f835..0683226d7d 100644 --- a/examples/VIEWS-DEMO.md +++ b/examples/VIEWS-DEMO.md @@ -185,22 +185,20 @@ config: … flowchart: subGraphTitleMargin: - bottom: 48 + bottom: 24 --- %% LanderViews::descentFlow — action rendering (view def ActionFlowView) %% not represented: 2 fork/join name(s) (split, sync); Mermaid's fork bar draws no label -%% not represented: 2 pin(s) not drawn (Lander::Descend.fuel, burn.propellant); a flowchart draws the pins an edge ends at flowchart TD - subgraph n0 ["`*«action def»* -**Descend**`"] + subgraph n0 ["`*«action def»* **Descend**`"] direction TD n1@{ shape: f-circ, label: "" } n2("`*«action»* **deployParachute**`") - subgraph n3 ["`*«action»* -**burn** + subgraph n3 ["`*«action»* **burn** own flow`"] direction TD + n3_anchor[" "] … end n4 --> n5 @@ -209,10 +207,11 @@ own flow`"] … ``` -The leading frontmatter carries the theme and reserves the height of a cluster -title's second and third lines, which Mermaid would otherwise draw under the -first child. The `%% not represented` lines name what the text form shows and -the diagram cannot: the names of fork and join bars, and pins no edge ends at. +The leading frontmatter carries the theme and, because `burn`'s title still +spans two lines (its `own flow` note), reserves the height of a cluster title's +second line, which Mermaid would otherwise draw under the first child. The +`%% not represented` line names what the text form shows and the diagram +cannot: the names of fork and join bars. ``` %render LanderViews::partsTable markdown @@ -243,11 +242,8 @@ reaches only what carries the `Safety` metadata: ``` LanderViews::safetyView - tree rendering (the view states no rendering; a tree is the default) -part def Lander::Thruster - attribute thrust : Real - item fuelIn : Fuel - port supply : FuelPort -part def Lander::Parachute +part def Thruster +part def Parachute ``` ## Rendering without the REPL diff --git a/examples/analysis-demo/README.md b/examples/analysis-demo/README.md index 71aa6da3e9..2b9a3683d5 100644 --- a/examples/analysis-demo/README.md +++ b/examples/analysis-demo/README.md @@ -41,9 +41,9 @@ runs by name: ✓ package Selection ✓ package Timing ✓ Descent::scoutBudget - fuelUsed = 120.0 - wetMass = 730.0 - fuelLeft = 130.0 + fuelUsed = [120.0] + wetMass = [730.0] + fuelLeft = [130.0] objective reserveHeld: satisfied ``` @@ -66,9 +66,9 @@ long leaves 10 kg, under the 20 kg reserve, and the run exits `1`: ``` ✗ Descent::scoutBudget(burnTime = 80.0) - fuelUsed = 240.0 - wetMass = 610.0 - fuelLeft = 10.0 + fuelUsed = [240.0] + wetMass = [610.0] + fuelLeft = [10.0] objective reserveHeld: not satisfied: fuelLeft >= reserve ``` @@ -87,9 +87,9 @@ object after the case: ID: 1 Use %features Landers::hauler to inspect ✓ Descent::FuelBudget on object #1 of "Landers::hauler" - fuelUsed = 320.0 - wetMass = 1980.0 - fuelLeft = 580.0 + fuelUsed = [320.0] + wetMass = [1980.0] + fuelLeft = [580.0] objective reserveHeld: satisfied ``` @@ -120,9 +120,11 @@ objective is evaluated after the `return`: [trace] eval operator - -> 130.0 [trace] leave action node: analysis Descent::scoutBudget [trace] stmt return -[trace] exit analysis Descent::scoutBudget -> 130.0 -[trace] output Descent::scoutBudget.fuelUsed = 120.0 -[trace] output Descent::scoutBudget.wetMass = 730.0 +[trace] exit analysis Descent::scoutBudget -> (130.0) +… +[trace] output Descent::scoutBudget.fuelUsed = (120.0) +… +[trace] output Descent::scoutBudget.wetMass = (730.0) … [trace] eval operator >= -> true ``` @@ -145,10 +147,30 @@ entry per output and objective. "subject": "Descent::scoutBudget(burnTime = 80.0)", "status": "fails", "values": [ - { "name": "fuelUsed", "value": "240.0" }, - { "name": "wetMass", "value": "610.0" }, - { "name": "fuelLeft", "value": "10.0" }, - { "name": "objective reserveHeld", "value": "not satisfied: fuelLeft >= reserve" } + { + "name": "fuelUsed", + "value": "[240.0]" + }, + { + "name": "wetMass", + "value": "[610.0]" + }, + { + "name": "fuelLeft", + "value": "[10.0]" + }, + { + "name": "objective reserveHeld", + "value": "not satisfied: fuelLeft \u003e= reserve" + } + ], + "lines": [ + "✗ Descent::scoutBudget(burnTime = 80.0)", + " fuelUsed = [240.0]", + " wetMass = [610.0]", + " fuelLeft = [10.0]", + " objective reserveHeld: not satisfied: fuelLeft \u003e= reserve", + " standing: value (observed: 1 run under reverse)" ], … } @@ -172,7 +194,7 @@ is under the 1.5 m/s limit: ``` ✓ Descent::checkScout - result = VerdictKind::pass + result = [VerdictKind::pass] objective obj: satisfied ✓ Verification Descent::checkScout verdict: pass ``` @@ -187,7 +209,7 @@ both ways, and the exit status is `1`: ``` ✗ Descent::TouchdownCheck on object #1 of "Landers::hauler" - result = VerdictKind::fail + result = [VerdictKind::fail] objective obj: not satisfied: lander.touchdownSpeed <= 1.5 ✗ Verification Descent::TouchdownCheck verdict: fail ``` @@ -226,11 +248,11 @@ check of where the design stops holding: ``` sweep Descent::scoutBudget — 4 run(s) burnTime | fuelUsed | wetMass | fuelLeft | verdict | time ----------+----------+---------+----------+----------------------------+-------- -20.0 | 60.0 | 790.0 | 190.0 | reserveHeld: satisfied | 0.142ms -40.0 | 120.0 | 730.0 | 130.0 | reserveHeld: satisfied | 0.082ms -60.0 | 180.0 | 670.0 | 70.0 | reserveHeld: satisfied | 0.075ms -80.0 | 240.0 | 610.0 | 10.0 | reserveHeld: not satisfied | 0.073ms +---------+----------+---------+----------+----------------------------+--------- +20.0 | [60.0] | [790.0] | [190.0] | reserveHeld: satisfied | 38.820ms +40.0 | [120.0] | [730.0] | [130.0] | reserveHeld: satisfied | 38.778ms +60.0 | [180.0] | [670.0] | [70.0] | reserveHeld: satisfied | 38.959ms +80.0 | [240.0] | [610.0] | [10.0] | reserveHeld: not satisfied | 38.662ms standing: table (observed: 4 rows) ``` @@ -246,12 +268,12 @@ when sampling. ``` samples Descent::scoutBudget — 4 run(s), seed 7 -burnTime | fuelUsed | wetMass | fuelLeft | verdict | time -------------------+--------------------+-------------------+--------------------+----------------------------+-------- -21.90164941545121 | 65.70494824635364 | 784.2950517536464 | 184.29505175364636 | reserveHeld: satisfied | 0.087ms -78.07478446864098 | 234.22435340592295 | 615.775646594077 | 15.775646594077045 | reserveHeld: not satisfied | 0.073ms -42.7187552135554 | 128.1562656406662 | 721.8437343593338 | 121.84373435933381 | reserveHeld: satisfied | 0.069ms -51.35890304495193 | 154.07670913485578 | 695.9232908651443 | 95.92329086514422 | reserveHeld: satisfied | 0.067ms +burnTime | fuelUsed | wetMass | fuelLeft | verdict | time +------------------+----------------------+---------------------+----------------------+----------------------------+--------- +21.90164941545121 | [65.70494824635364] | [784.2950517536464] | [184.29505175364636] | reserveHeld: satisfied | 37.868ms +78.07478446864098 | [234.22435340592295] | [615.775646594077] | [15.775646594077045] | reserveHeld: not satisfied | 38.004ms +42.7187552135554 | [128.1562656406662] | [721.8437343593338] | [121.84373435933381] | reserveHeld: satisfied | 37.928ms +51.35890304495193 | [154.07670913485578] | [695.9232908651443] | [95.92329086514422] | reserveHeld: satisfied | 37.582ms standing: table (observed: 4 rows) ``` @@ -272,7 +294,7 @@ three candidates as its subject, minimizes, and scores mass on the pad: ``` ✓ Selection::lightest - selectedAlternative = Landers::relay (object #5) + selectedAlternative = [Landers::relay (object #5)] objective tradeStudyObjective: satisfied evaluationFunction(Landers::scout (object #1)) = 850.0 evaluationFunction(Landers::hauler (object #3)) = 2300.0 @@ -297,7 +319,7 @@ fuel costs, at a rate the caller supplies: ``` ✓ Selection::mostValuable(fuelCost = 0.1) - selectedAlternative = Landers::hauler (object #3) + selectedAlternative = [Landers::hauler (object #3)] objective tradeStudyObjective: satisfied evaluationFunction(Landers::scout (object #1)) = 15.0 evaluationFunction(Landers::hauler (object #3)) = 210.0 [selected] @@ -314,11 +336,11 @@ and the table shows where the choice flips: ``` sweep Selection::mostValuable — 3 run(s) -fuelCost | selectedAlternative | verdict | evaluations | time ----------+-----------------------------+--------------------------------+---------------------------------------------------------------+-------- -0.0 | Landers::hauler (object #3) | tradeStudyObjective: satisfied | …scout…) = 40.0; …hauler…) = 300.0 [selected]; …relay…) = 25.0 | 5.592ms -0.25 | Landers::hauler (object #3) | tradeStudyObjective: satisfied | …scout…) = -22.5; …hauler…) = 75.0 [selected]; …relay…) = -20.0 | 0.261ms -0.5 | Landers::relay (object #5) | tradeStudyObjective: satisfied | …scout…) = -85.0; …hauler…) = -150.0; …relay…) = -65.0 [selected] | 0.254ms +fuelCost | selectedAlternative | verdict | evaluations | time +---------+-------------------------------+--------------------------------+-------------------------------------------------------------------+--------- +0.0 | [Landers::hauler (object #3)] | tradeStudyObjective: satisfied | …scout…) = 40.0; …hauler…) = 300.0 [selected]; …relay…) = 25.0 | 39.926ms +0.25 | [Landers::hauler (object #3)] | tradeStudyObjective: satisfied | …scout…) = -22.5; …hauler…) = 75.0 [selected]; …relay…) = -20.0 | 39.934ms +0.5 | [Landers::relay (object #5)] | tradeStudyObjective: satisfied | …scout…) = -85.0; …hauler…) = -150.0; …relay…) = -65.0 [selected] | 39.860ms standing: table (observed: 3 rows) ``` @@ -356,8 +378,8 @@ machine is running, start the action, and advance the clock: Action steps taken: 5 ✓ Action completed Results: - armed = true - sawBraking = false + armed = [true] + sawBraking = [false] (order-dependent; 1 choice point — explore shows the set) ``` Both timers came due at `t=5.0`. Which runs first is not fixed by the model — @@ -379,8 +401,8 @@ goes first, and the watch sees the brake: ``` Results: - armed = true - sawBraking = true + armed = [true] + sawBraking = [true] (order-dependent; 1 choice point — explore shows the set) ``` **Enumerate every order.** `-schedule explore` runs each linearization of the @@ -394,10 +416,10 @@ run reaching that outcome made: ``` ✓ explored Timing::groundWatch: 2 outcomes -outcome | linearizations | probability | witness ----------------------------------+----------------+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -armed = true; sawBraking = false | 1 | possible | t=5.0: action GroundWatch first of state machine flightMode of object #1, action GroundWatch; t=5.0: action GroundWatch first of state machine flightMode of object #1, action GroundWatch -armed = true; sawBraking = true | 2 | possible | t=5.0: state machine flightMode of object #1 first of state machine flightMode of object #1, action GroundWatch +outcome | linearizations | probability | witness +-------------------------------------+----------------+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +armed = [true]; sawBraking = [false] | 1 | possible | t=5.0: action GroundWatch first of state machine flightMode of object #1, action GroundWatch; t=5.0: action GroundWatch first of state machine flightMode of object #1, action GroundWatch +armed = [true]; sawBraking = [true] | 2 | possible | t=5.0: state machine flightMode of object #1 first of state machine flightMode of object #1, action GroundWatch complete (3 runs) standing: outcomes (proved over schedules: 3 linearizations, inputs as written) ``` @@ -422,13 +444,13 @@ its body waits on time — no `-advance` is needed: ``` ✓ Timing::watchDescent - sawBraking = false + sawBraking = [false] standing: value (observed: 1 run under reverse) ✓ explored Timing::watchDescent: 2 outcomes -outcome | linearizations | probability | witness --------------------+----------------+-------------+----------------------------------------------------------------------------------------------------------------- -sawBraking = false | 1 | possible | t=5.0: action watchDescent first of state machine flightMode of object #1, action watchDescent -sawBraking = true | 1 | possible | t=5.0: state machine flightMode of object #1 first of state machine flightMode of object #1, action watchDescent +outcome | linearizations | probability | witness +---------------------+----------------+-------------+----------------------------------------------------------------------------------------------------------------- +sawBraking = [false] | 1 | possible | t=5.0: action watchDescent first of state machine flightMode of object #1, action watchDescent +sawBraking = [true] | 1 | possible | t=5.0: state machine flightMode of object #1 first of state machine flightMode of object #1, action watchDescent complete (2 runs) standing: outcomes (proved over schedules: 2 linearizations, inputs as written) ``` @@ -475,7 +497,7 @@ python examples/analysis-demo/lander_demo.py fuel left 130.0 kg after 120.0 kg burned reserve held True 80 s burn 10.0 kg left, reserve held False - ✗ objective reserveHeld fails (on Landers::scout ID: 1): condition evaluated to false: fuelLeft >= reserve + ✗ objective reserveHeld fails (on Landers::scout ID: 1): condition evaluated to false: fuelLeft >= reserve — observed by run the hauler 580.0 kg left, reserve held True == how far the budget stretches diff --git a/examples/analysis-demo/lander_demo.py b/examples/analysis-demo/lander_demo.py index b04db21177..72375192b4 100644 --- a/examples/analysis-demo/lander_demo.py +++ b/examples/analysis-demo/lander_demo.py @@ -20,22 +20,23 @@ def main() -> None: print("== the fuel budget of one descent") budget = model.run_analysis("Descent::scoutBudget") - print(f"fuel left {budget.outputs['fuelLeft']} kg after {budget.outputs['fuelUsed']} kg burned") + fuel_left, fuel_used = budget.outputs["fuelLeft"][0], budget.outputs["fuelUsed"][0] + print(f"fuel left {fuel_left} kg after {fuel_used} kg burned") print(f"reserve held {budget.satisfied}") long_burn = model.run_analysis("Descent::scoutBudget", named_arguments={"burnTime": 80.0}) - print(f"80 s burn {long_burn.outputs['fuelLeft']} kg left, reserve held {long_burn.satisfied}") + print(f"80 s burn {long_burn.outputs['fuelLeft'][0]} kg left, reserve held {long_burn.satisfied}") for verdict in long_burn.verdicts: print(f" {verdict.explain()}") hauler = model.run_analysis("Descent::FuelBudget", subject="Landers::hauler") - print(f"the hauler {hauler.outputs['fuelLeft']} kg left, reserve held {hauler.satisfied}") + print(f"the hauler {hauler.outputs['fuelLeft'][0]} kg left, reserve held {hauler.satisfied}") print("\n== how far the budget stretches") table = model.run_sweep("Descent::scoutBudget", {"burnTime": (20.0, 80.0, 20.0)}) for row in table: held = "holds" if row else "fails" - print(f"burnTime {row.inputs['burnTime']:>5} fuelLeft {row.outputs['fuelLeft']:>6} reserve {held}") + print(f"burnTime {row.inputs['burnTime']:>5} fuelLeft {row.outputs['fuelLeft'][0]:>6} reserve {held}") drawn = model.run_sweep("Descent::scoutBudget", {"burnTime": (20.0, 80.0)}, samples=4, seed=7) print(f"seed {drawn.seed}: {len(drawn)} draws, " @@ -63,7 +64,7 @@ def main() -> None: print("\n== the watch and the flight mode on one clock") runs = model.explore_analysis("Timing::watchDescent") for outcome in runs: - print(f"sawBraking = {outcome.outputs['sawBraking']!s:<5} " + print(f"sawBraking = {outcome.outputs['sawBraking'][0]!s:<5} " f"({outcome.linearizations} order): {outcome.witness[0]}") diff --git a/examples/analysis-results-demo/README.md b/examples/analysis-results-demo/README.md index 9c29b43b2f..0eca74718d 100644 --- a/examples/analysis-results-demo/README.md +++ b/examples/analysis-results-demo/README.md @@ -99,9 +99,9 @@ Each is labelled; the scout and hauler runs print the same numbers now. ``` ✓ Descent::scoutBudget - fuelUsed = 120.0 - wetMass = 730.0 - fuelLeft = 130.0 + fuelUsed = [120.0] + wetMass = [730.0] + fuelLeft = [130.0] objective reserveHeld: satisfied ``` @@ -110,9 +110,9 @@ Each is labelled; the scout and hauler runs print the same numbers now. ``` ``` - fuelUsed = 320.0 - wetMass = 1980.0 - fuelLeft = 580.0 + fuelUsed = [320.0] + wetMass = [1980.0] + fuelLeft = [580.0] ``` The relay run, **as recorded** (when `relay.fuel` was `180.0`): @@ -131,9 +131,9 @@ The same command **now prints** — the difference the `relayRun` record detects: ``` - fuelUsed = 100.0 - wetMass = 560.0 - fuelLeft = 110.0 + fuelUsed = [100.0] + wetMass = [560.0] + fuelLeft = [110.0] ``` A sweep of `scoutBudget`, one record per row (this README's tables omit the @@ -147,9 +147,9 @@ A sweep of `scoutBudget`, one record per row (this README's tables omit the ``` burnTime | fuelUsed | wetMass | fuelLeft | verdict ---------+----------+---------+----------+---------------------------- -40.0 | 120.0 | 730.0 | 130.0 | reserveHeld: satisfied -60.0 | 180.0 | 670.0 | 70.0 | reserveHeld: satisfied -80.0 | 240.0 | 610.0 | 10.0 | reserveHeld: not satisfied +40.0 | [120.0] | [730.0] | [130.0] | reserveHeld: satisfied +60.0 | [180.0] | [670.0] | [70.0] | reserveHeld: satisfied +80.0 | [240.0] | [610.0] | [10.0] | reserveHeld: not satisfied ``` The 80 s row leaves the objective unsatisfied, so the sweep exits `1`; the @@ -252,9 +252,9 @@ model — records included — back out: ``` ✓ Descent::scoutBudget - fuelUsed = 120.0 - wetMass = 730.0 - fuelLeft = 130.0 + fuelUsed = [120.0] + wetMass = [730.0] + fuelLeft = [130.0] objective reserveHeld: satisfied standing: value (observed: 1 run under reverse) recorded Records::scoutBudget_run1 (Records::ScoutBudgetRun) diff --git a/examples/disposal-robot-demo/README.md b/examples/disposal-robot-demo/README.md index e89ea87d08..4c690135e4 100644 --- a/examples/disposal-robot-demo/README.md +++ b/examples/disposal-robot-demo/README.md @@ -47,9 +47,9 @@ the robot's draw. ``` ✓ RobotBehavior::Approach(120.0, 90.0) - = 150.0 + = [150.0] ✓ RobotBehavior::energyForDrive(150.0, 0.42, 120.0) - = 11.904761904761907 + = [11.904761904761907] ``` **Run the call-out.** `DisposalRun` forks the survey and the retrieval, joins @@ -142,35 +142,33 @@ config: --- %% RobotViews::interfaces — interconnection rendering (render asInterconnectionDiagram) flowchart LR - subgraph n0 ["`*«part def»* -**Platform**`"] + subgraph n0 ["`*«part def»* **Platform**`"] direction LR n1("`*«attribute»* -**mass : Real**`") +**mass**`") … - subgraph n3 ["`*«part»* -**battery : Battery**`"] + subgraph n3 ["`*«part»* **battery**`"] direction LR - n3_anchor[" "] n3.0["outlet"] + … end … end - n3.0 ===|"drivePower"| n5.0 - n6 ===|"imageryLink"| n8.0 - n3_anchor -.->|"of Charge"| n5_anchor - n6 -.->|"of Frame"| n8_anchor + n3.0 === n11.0 + n20.0 === n28.0 + n6 -.-> n17 + n22 -.-> n31 … ``` ``` -wrote rendered/RobotViews.interfaces.mmd (mermaid, 1819 bytes) -wrote rendered/RobotViews.modes.mmd (mermaid, 1419 bytes) -wrote rendered/RobotViews.run.mmd (mermaid, 2109 bytes) +wrote rendered/RobotViews.interfaces.mmd (mermaid, 2848 bytes) +wrote rendered/RobotViews.modes.mmd (mermaid, 1413 bytes) +wrote rendered/RobotViews.run.mmd (mermaid, 1866 bytes) wrote rendered/RobotViews.partsTable.md (markdown, 842 bytes) -wrote rendered/RobotViews.criticalParts.mmd (mermaid, 1783 bytes) -wrote rendered/RobotViews.overview.mmd (mermaid, 1886 bytes) -wrote rendered/RobotViews.overview.interfaceSubview.mmd (mermaid, 1835 bytes) +wrote rendered/RobotViews.criticalParts.mmd (mermaid, 884 bytes) +wrote rendered/RobotViews.overview.mmd (mermaid, 10443 bytes) +wrote rendered/RobotViews.overview.interfaceSubview.mmd (mermaid, 2864 bytes) ``` **Identify elements with an OSLC query.** `-query` takes @@ -288,7 +286,7 @@ robot is approaching. ``` ``` -✓ Advanced to 5.0 (1 event(s) processed) +✓ Advanced to 5.0 (2 event(s) processed) Current state: rolling Current state: rolling State stack (active configuration): @@ -325,23 +323,12 @@ Features: log = Instance(ID: 3) frames = 15 passes = 1 - modes = Instance(ID: 2) +Behaviors: + modes: exhibited state machine, completed odometer = 21.0 framesCaptured = 12 faults = 0 - idle = - approach = Instance(ID: 4) - rolling = - holding = - handling = - safing = - idle_to_rolling = - rolling_to_holding = - rolling_to_safe = - approach_to_handling = - recordPass = Instance(ID: 5) - frames = - store = + recordPass: action, not running ✓ modes.odometer (on RobotBehavior::controller ID: 1) = 21.0 ✓ log.frames (on RobotBehavior::controller ID: 1) @@ -493,7 +480,7 @@ view RobotViews::overview ``` RobotViews::modes - state rendering (view def StateTransitionView) -state def RobotBehavior::Modes +state def Modes start state idle (initial) state approach @@ -504,7 +491,7 @@ state def RobotBehavior::Modes final done transitions: - start of RobotBehavior::Modes -> idle + start of Modes -> idle idle -> rolling: after 5 [s] approach -> handling: after 20 [s] rolling -> holding: after 10 [s] @@ -548,8 +535,8 @@ states idle -> approach -> rolling -> holding -> handling -> done wrote faults=0, framesCaptured=12, odometer=21.0 == checking the call-out budget -✓ satisfy runIsBudgeted by run12 holds (on RobotSolver::run12 ID: 1) -✗ satisfy runIsBudgeted by run13 fails (on RobotSolver::run13 ID: 2): condition evaluated to false: … +✓ satisfy runIsBudgeted by run12 holds (on RobotSolver::run12 ID: 1) — observed by run +✗ satisfy runIsBudgeted by run13 fails (on RobotSolver::run13 ID: 2): condition evaluated to false: … — witnessed by run both hold False heavy mockup over the mass budget ``` diff --git a/examples/disposal-robot-demo/robot_demo.py b/examples/disposal-robot-demo/robot_demo.py index 3c9ff79b93..3a5b2d0b3f 100644 --- a/examples/disposal-robot-demo/robot_demo.py +++ b/examples/disposal-robot-demo/robot_demo.py @@ -26,11 +26,11 @@ def main() -> None: print(f"battery {robot.battery.charge} of {robot.battery.capacity} Wh") print("\n== planning the approach") - metres = model.calc("RobotBehavior::Approach", arguments=[120.0, 90.0]).value + metres = model.calc("RobotBehavior::Approach", arguments=[120.0, 90.0]).value[0] energy = model.calc( "RobotBehavior::energyForDrive", arguments=[metres, robot.mobility.speed, robot.mobility.drivePower], - ).value + ).value[0] print(f"{metres} m costs {energy:.1f} Wh of the {robot.battery.charge} Wh aboard") print("\n== running the call-out") diff --git a/examples/disposal-team-demo/README.md b/examples/disposal-team-demo/README.md index 98897b4110..990f6a26ec 100644 --- a/examples/disposal-team-demo/README.md +++ b/examples/disposal-team-demo/README.md @@ -81,9 +81,6 @@ verifies the requirement reaches its verdict from the same comparison. standing: holds (observed: 1 run under reverse) ✓ satisfy payloadAsserted by loadedTruck holds (on TeamCases::loadedTruck ID: 6) standing: holds (observed: 1 run under reverse) -✓ satisfy payloadHolds holds -✓ Verification TeamCases::checkPayload verdict: pass - standing: holds (observed: 1 run under reverse) ``` ## From the REPL diff --git a/examples/general-views-demo/README.md b/examples/general-views-demo/README.md index 5ba8ec23a8..ad4e55223d 100644 --- a/examples/general-views-demo/README.md +++ b/examples/general-views-demo/README.md @@ -16,6 +16,11 @@ sysml vehicle.sysml -render GeneralViews::definitionView -render-form dot -rende sysml vehicle.sysml -render GeneralViews::packageView -render-form plantuml ``` +Every command on `vehicle.sysml` also prints one `name-conflict` warning at line 102: +`definitionView`'s recursive `expose VehicleStructure::**` brings the `mass` of `Vehicle`, +`vehicle` and `heavyVehicle` into the view's namespace under one name. The renderings are +unaffected. + `-render-overlay verdicts` runs the verification cases and colours each requirement by its worst verdict: `vehicleMass` passes the light vehicle's test and fails the heavy one's, and `emergencyStop`'s test is inconclusive. diff --git a/examples/relay-probe-demo/README.md b/examples/relay-probe-demo/README.md index 6e2601b070..2f9ae60885 100644 --- a/examples/relay-probe-demo/README.md +++ b/examples/relay-probe-demo/README.md @@ -78,12 +78,14 @@ different times; the calculation's defaults read one feature at two of them. ``` sysml> %eval scout.postSeparation.mass +✓ scout.postSeparation.mass = 118.0 sysml> %eval scout.postFlyby.mass +✓ scout.postFlyby.mass = 96.0 sysml> %calc massSpent ✓ massSpent() - = 22.0 + = [22.0] standing: value (observed: 1 run under reverse) ``` diff --git a/examples/runtime-showcase/README.md b/examples/runtime-showcase/README.md index 3a92d71df1..4e4c75968e 100644 --- a/examples/runtime-showcase/README.md +++ b/examples/runtime-showcase/README.md @@ -125,7 +125,7 @@ number; the tool checks and carries this at every step: ``` ✓ DeltaVBudget::RocketEquation(421 [SI::s], 9.80665 [SI::'m/s²'], 133000 [SI::kg], 28000 [SI::kg]) - = 6432.955324716369 [SI::'m/s'] + = [6432.955324716369 [SI::'m/s']] standing: value (observed: 1 run under reverse) ``` @@ -140,9 +140,9 @@ requirement. `saturnIBAscent` binds the subject, so it runs by name: ``` ✓ DeltaVBudget::saturnIBAscent - stage1DeltaV = 3037.6966629706967 [SI::'m/s'] - stage2DeltaV = 6432.955324716369 [SI::'m/s'] - margin = 70.65198768706614 [SI::'m/s'] + stage1DeltaV = [3037.6966629706967 [SI::'m/s']] + stage2DeltaV = [6432.955324716369 [SI::'m/s']] + margin = [70.65198768706614 [SI::'m/s']] objective reachesOrbit: satisfied standing: value (observed: 1 run under reverse) ``` @@ -158,9 +158,9 @@ and the exit status becomes `1`: ``` ✗ DeltaVBudget::saturnIBAscent(required = 9800 ['m/s']) - stage1DeltaV = 3037.6966629706967 [SI::'m/s'] - stage2DeltaV = 6432.955324716369 [SI::'m/s'] - margin = -329.34801231293386 [SI::'m/s'] + stage1DeltaV = [3037.6966629706967 [SI::'m/s']] + stage2DeltaV = [6432.955324716369 [SI::'m/s']] + margin = [-329.34801231293386 [SI::'m/s']] objective reachesOrbit: not satisfied: margin > 0 ['m/s'] standing: value (observed: 1 run under reverse) ``` @@ -399,7 +399,7 @@ three with the action and completes it once all three have: Tokens: 3 ✓ Action completed Final state: Completed - 1 choice point; %trace on to see them + 1 choice point (1 independent); %trace on to see them standing: value (observed: 1 run under reverse) ``` @@ -452,7 +452,7 @@ the spacecraft's, and `-advance` runs the one clock both parts share: Current state: transmitted | notRecharging Last event at: 241.0 Remaining events: 0 - 592 choice points; %trace on to see them + 592 choice points (591 independent); %trace on to see them Do behavior actions run: 808 standing: value (observed: 1 run under reverse) ``` @@ -561,7 +561,7 @@ policies' ([a do behavior under `explore` and ``` ``` -✗ State machine SpacecraftComms::SpacecraftVehicle::modes: divergent up to t=80.0 (14664 states, 35546 moves, depth 757) +✗ State machine SpacecraftComms::SpacecraftVehicle::modes: divergent up to t=80.0 (14748 states, 35626 moves, depth 757) divergent: this.battery ends as 39 or 41 divergent: this.data ends as 51200 or 52224 or 53248 (…) @@ -641,7 +641,7 @@ The model's mass-budget step runs as written: ``` ✓ CalculationsPackage::calculateMassBudgetStep(2900000 [SI::kg], 2000000 [SI::kg], 130000 [SI::kg]) - = 770000 [SI::kg] + = [770000 [SI::kg]] standing: value (observed: 1 run under reverse) ``` From 8f7ade0e35a7e9aead99979a33e38e4ad2d1448c Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sun, 25 Oct 2026 08:16:06 +0000 Subject: [PATCH 2/2] docs(examples): point the parser-features page at the roadmap's measured gate count Co-Authored-By: jason.han --- examples/PARSER_FEATURES_DEMOS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/PARSER_FEATURES_DEMOS.md b/examples/PARSER_FEATURES_DEMOS.md index c7b6796c07..b410cfedba 100644 --- a/examples/PARSER_FEATURES_DEMOS.md +++ b/examples/PARSER_FEATURES_DEMOS.md @@ -6,7 +6,7 @@ Demonstrations of the SysML v2 / KerML parser features that let every file of th Each demo file focuses on a specific category of features with working examples extracted from real stdlib usage patterns. -**Parser Status:** 110/110 bundled library files parse cleanly (94 official SysML v2 standard library files plus the 16 libraries under `OpenSysML Libraries/`), gated by `internal/workspace/libs/stdlib_conformance_test.go`. +**Parser Status:** every bundled library file — the official SysML v2 standard library plus the libraries under `OpenSysML Libraries/` — parses cleanly, gated by `internal/workspace/libs/stdlib_conformance_test.go`; the measured count lives in [the gate table of the roadmap](../docs/project/roadmap.md#where-the-repository-stands) (Stdlib parser conformance). ## Demo Files @@ -271,7 +271,7 @@ go test ./examples -run '^TestParserFeaturesEdgeCases$' -v - Declarations (multiplicity, classifier/subclassifier, multiple typing, subset/disjoint) - Edge cases (keywords in expressions, identifier multiplicities, bind/require/step shortcuts) -**Status:** 110/110 bundled library files parse cleanly (`go test -run TestStdlibConformance ./internal/workspace/libs`) +**Status:** every bundled library file parses cleanly (`go test -run TestStdlibConformance ./internal/workspace/libs`); the count is kept in [the roadmap's gate table](../docs/project/roadmap.md#where-the-repository-stands). ## Real-World Usage