Repository navigation
feat(runtime): execute repeated action steps beyond plain successions - #834
devin-ai-integration[bot] wants to merge 30 commits into
Conversation
…reads and bindings Co-Authored-By: jason.han <hanhuijun@gmail.com>
… on parts Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…uarded successions Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…get end Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…nd compliance map Co-Authored-By: jason.han <hanhuijun@gmail.com>
…odec Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
…ed it A join reached per performance consumes the earliest sibling arrival and mints the token that performs it, so the tried token neither moves nor changes the token count and the step looked unacted. Compare the token-ID counter before and after the step too, so the explore slot and the check replay see the synchronization as that token's act. Pin every checkable repeated-step conformance case with a check expectation; a case with a check expectation may carry an explore budget without outcomes. Co-Authored-By: jason.han <hanhuijun@gmail.com>
The runtime reaches a repeated step in one step, splits the token into its siblings in the next, then performs the step in a third. The encoding placed the siblings on the arriving move, compressing the split into the arrival, so every witness step and choice was off by one and witnesses would not replay. Arrivals into a repeated step now land the token pending and the next move mints its siblings, mirroring the runtime, and the SMT witness tests pin that violated properties over repeated steps replay. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…arget ends Co-Authored-By: jason.han <hanhuijun@gmail.com>
|
I tested the built CLI/REPL at a75f494 across 129 commands. The full command matrix changed only in the five results the two fixes target.
|
…e the successions derive it Co-Authored-By: jason.han <hanhuijun@gmail.com>
…han proved or bounded Co-Authored-By: jason.han <hanhuijun@gmail.com>
…tics from the spec Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ends force the repeated step's A control node that declares no multiplicity takes the executor's one-performance reading beside a repeated step, so a written [*] into a fork or decision is a barrier and a written [*] out of a join or merge fans out. The four derived crossings — a bijective crossing into a join or out of a fork, the lone incoming edge of a merge, the lone outgoing edge of a decision — still fix the node's count to the step's, and a merge or decision carrying another succession is unsatisfiable under count one through the mandated 0..1 ends. Restores the fork-barrier, decision-barrier and merge-fanout conformance fixtures to running, and the corresponding SMT witness and outcome cases. The conformance README notes that an exploration budget raise is pinned for completeness only and never changes a standing. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…es beside repeated steps Co-Authored-By: jason.han <hanhuijun@gmail.com>
The default 1024-run budget leaves the check-agrees exploration of the merge per-performance fixture incomplete; raise it like the join per-performance fixture's. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…it makes the siblings Co-Authored-By: jason.han <hanhuijun@gmail.com>
…g the check search Co-Authored-By: jason.han <hanhuijun@gmail.com>
… instead of refusing it Co-Authored-By: jason.han <hanhuijun@gmail.com>
…s stay ambiguous Co-Authored-By: jason.han <hanhuijun@gmail.com>
… the pruned single-performance guard Co-Authored-By: jason.han <hanhuijun@gmail.com>
…-coverage Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # docs/project/spec-compliance.md
…-coverage Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # internal/exec/analysis/standing.go # internal/exec/runtime/check.go # internal/exec/runtime/classifier_behavior.go # internal/exec/runtime/explore.go # internal/exec/runtime/explore_queue.go # internal/exec/runtime/held_image_behavior.go # internal/exec/runtime/snapshot.go
…-coverage Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # internal/exec/runtime/held_image_behavior.go # internal/ir/lower/action_graph.go
…-coverage Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # internal/workspace/libs/stdlib.snapshot
|
This branch now conflicts with
To resolve: merge current Planned merge order for the execution PRs: #844 → #850 → #838 → (#851 → #853 → #857) → #830 → #833 → #842 → #837 → #834 → #816. Re-run the full gate ( |
|
Hold on pushes: please don't push to this branch, including |
What and why
Exact action-step multiplicity (
a[n]) executed only between plain successions; every other shape around a repeated step was refused withaction-step-multiplicity-unsupported. This PR executes the shapes KerML/SysML determine and keeps a typed refusal for the ones they leave open. Unchanged: the strict refusal of an ambiguous plainthenaround a repeated step,[0]as a no-op, refusal of non-fixed counts ([0..1],[*]),ErrIntegerUnaddressablefor bounds beyond 64 bits, and validate/run/explore/check agreement (the SMT engine now refuses every shapeCheckSteprefuses).Now executes
a[n]in awhile/for/ifbodynperformances per body pass,[0]none. Each repetition runs as one move, so explore and check report the result as observed, not proved or bounded, with a typed reason (their interleavings are not explored).perform action run[n]on a partndistinct occurrences, each with its own behaviour, kept through held images.PerformedActionsOf(run)returns alln, so a request to runrunon that part is ambiguous (ErrAmbiguousAction, "performs run 2 times").a.xread outsideax, duplicates kept, in repetition-index order. Reading before allnend givesErrNodeNotPerformed. Inside a performance,xis that performance's own value.action a[n] { in x = c; }x.bind a.x = e,esingle-valuede's value. An out-pin requires allnvalues to agree, otherwiseErrBindingConflict.a[n]→ join, or → merge as its only incoming successionntimes, once per performance ofa(derived below). The other edges at the node are checked under that count.succession first [*] a then f;into a fork or decisionfperforms once, under the sametallyinfirst [*] a then [1] tally. Its ends do not force another count.then [*] afirst p if g then [*] a;(guard into a written target end)gholds, every performance is ordered afterp. The parser now admits that end (GuardedSuccession/GuardedTargetSuccession→TransitionSuccession→ConnectorEndOwnedCrossMultiplicityMember). It goes through the AST codec,DeclaredSuccessionsand RDF export/import.sysml -engine smt)a[n]is encoded as the runtime runs it:n-1sibling tokens placed in free slots on the split move that follows arrival (from a fork too), a retire-until-last barrier (or per-performance crossing into a join/merge),[0]as a pass-through, and a false guard into a written target end as a failing move.Still refused, and why
flow from a.out to b.inand connections at a repeated pinTransfers.kerml: flow ends have no multiplicity in the grammar and a flow defaults to[0..*](SysML §7.6.3), so how many transfers there are, and from which performances, is undetermined.bind a.x = ewith a multi-valuedeinto in-pinse's values goes to which performance is open.a[n]GuardedSuccessionhas no source end you can write, so KERML-29 leaves it open.a[n]with no written target endaction-step-order-opennperformances, but nothing orders them. Validate warns when the guard is literalfalse. Into a single performance (a[1]) the false guard just prunes the edge (guard_false_single).thenfroma[n]into a fork or decision, or from a join or merge intoa[n]thenpolicy)a-side end is not mandated.0..1ends cannot takencrossings.a[n]ntimes, and its predecessor, which performs once, cannot orderncrossings.a[n]in awhile/for/ifbody next to another member, with no succession writtenaction-step-order-openthen.Specification basis
a[n]isnperformances per performance of the action, body pass or part that featuresa.semantics.ImplicitMultiplicityApplies/EffectiveParameterRangeimplement it: the implicit[1..1]reaches only owned attribute, item, part and port usages. Any other usage takes what it subsets or redefines, else[0..*]. A control node is an action usage specializingActions::Action::controls : ControlAction[0..*], andmergesis[0..*].forks,joinsanddecisionsdeclare nothing, so they inherit[0..*]. An unwritten control node's count is therefore[0..*], and only its successions can fix it:a[n]→ join (both ends mandated1..1): a bijection, sonjoin performances.a[n]→ merge as its only incoming succession: target1..1plusControlPerformances.kermlMergePerformance::incomingHBLink : HappensBefore[1], son.a[n], and a lone-outgoing decision →a[n](DecisionPerformance::outgoingHBLink[1]), are derived the same way. Both then refuse at the node's predecessor.tallybarrier therefore differ only in their mandated ends, not in their defaults.[0..*], so running it once per token arrival is the executor's reading, not a derived rule. Its compliance row is nowsemantics.AssumedRangecomment no longer attributes[1..1]to KerML §7.4.5, which says "the usual default of 0..*".1..1;1..1;1..1; into a merge: source0..1;1..1; out of a decision: target0..1.TransitionPerformances.kerml(guarded successions):HappensBefore;SelfLink) and KerML §7.4.11 (feature values).ControlFunctions.kerml'.': source and result[0..*], nonunique.LoopPerformance/IfThenPerformance: each body pass is a performance of its own.Parts::performedActionsandOccurrences::enactedPerformances: the basis for part-level performed actions.The derivation is recorded in
docs/project/behavior-semantic-oracle.md(repeated action steps), the SMT encoding indocs/internals/design/smt-model-checking.md, and the RDF form indocs/reference/rdf-mapping.md. Indocs/project/spec-compliance.md:How it was verified
action_step_multiplicity_loop_body,perform_action_multiplicity,guarded_succession_target_multiplicity.action_step_multiplicity_while_body,for_body,if_body,unordered_loop_body;part_perform,external_read,pin_value,bind_input,bind_output;join_per_performance,merge_per_performance;fork_barrier,decision_barrier,merge_fanout, which run under the one-performance reading;while_body,unordered_loop_bodyandmerge_per_performancekeepexploreBudget: {"runs": 8192}, andjoin_per_performancekeeps2048. The default 1024 runs leave their exploration incomplete. The budget is pinned for completeness only and does not affect the observed standing;loop_body_race: the admitted set is{c = 1, c = 2}. Exploration reaches onlyc = 2, and the fixture pins the observed standing through a newexploreNotesschema field.while_body,for_body,if_bodyandunordered_loop_bodycarry the same note, with outcomes unchanged;guard_true,guard_false,guard_false_single,fork_into_repeated.robustness_repeated_step_coverage_test.go:TestRuntimeRobustnessRepeatedStepCoveragecovers:perform action run[0], and per-inner-pass counting forwhilenested infor;[0..2]in a loop staying not-fixed;a[2]unaffected;.check.expected.json.TestCheckConformanceOracles,TestCheckAgreesWithExploreOverTheConformanceCorpusandTestCheckWitnessesReplayOverTheConformanceCorpusrun them through the explicit-state check, exploration and witness replay.exploreBudgetwithoutoutcomeswhen the case has a check expectation (join_per_performanceneeds 1680 exploration runs). New schema-test rows pin both the refusal and the allowance.-engine checkalready refuseswhile/for/ifbodies ondevelopwithout any repetition (token 1 is not one the step may move). That is a pre-existing limitation, not in scope here; run and explore agree on those fixtures.CheckSteprefusal);sysx:sourceTextstripped.Results:
At the latest head,
go build/vet/gofmt, the lower, behavior-pass, SMT, analysis and runtime packages, the runtime race suite (conformance, traces, robustness),./tests/...,make docs-checkand the changelog check were rerun: all ok.Corpus gates ran with
OPENSYSML_REQUIRE_TRAINING_CORPUS=1 OPENSYSML_REQUIRE_PILOT_CORPORA=1 OPENSYSML_REQUIRE_PILOT_LIBRARY_XMI=1 OPENSYSML_REQUIRE_PSSM_SUITE=1, after all four download scripts:./tests/...,./cmd/sysml/...,./internal/exec/analysis/...,./internal/exec/solve/...,./internal/frontend/repl/...,./internal/workspace/model/...: ok;go test -C tools ./referee/pssm/... ./oracle/errata/...: ok;go run -C tools ./cmd/pilot-diff -check: 381 files, 343 fully agreeing, baseline reproduced.SMT referee corpus: 7 encoded, 10 refused, 7 agreeing (unchanged by the
CheckStepagreement fix). No baseline moved, so nothing was regenerated, andtraining_examples_expected.txtis untouched.Two defects that end-to-end CLI testing found are fixed here:
stepTokenNoting).Pendingmove, andTestEngineWitnessesReplayOverRepeatedStepspins that the witnesses replay (exact, fork barrier, merge fan-out, join and merge per performance).A flat
a[2] { t := c; c := t + 1; }outside any block still explores as proved overc = 2only. That is the leaf-body indivisibility the separate body-interleaving change addresses, and it holds ondeveloptoo. Merged with that change, the flat case reaches{c = 1, c = 2}, but the block-body cases do not, which is why they report observed here.The SMT engine already refuses any nested block flow, so it never encodes a repeated step inside a loop or if body.
internal/workspace/libs/stdlib.snapshotis regenerated withmake stdlib-snapshot, because the AST codec now encodes the succession target ends.Two existing tests now assert shapes that are newly supported. Neither was weakened:
TestAnalyzeRefusesRepeatedActionStepsbecameTestAnalyzeCountsRepeatedActionSteps.TestFirstThenWithADeclaringEndIsRefusednow grafts its[2]bound onto the source end.then [2] bis legal grammar, and the source end still has no notation.Checklist
make testandmake lintpass locallychanges/unreleased/repeated-step-coverage.added.md, not as an edit toCHANGELOG.mdmake docs-countsrun if a gate count moved (no gate count moved)F4,K5) in the body, docs, or changelogLink to Devin session: https://nasa-jpl-demo.devinenterprise.com/sessions/72bb3b97dfe04df688e76e4a623130eb
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/72bb3b97dfe04df688e76e4a623130eb?variant=devin
Requested by: @HuiJun