Repository navigation
fix(runtime): = values in action, calc, block and state bodies hold at all times - #842
Conversation
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)".
|
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…alue-bindings Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # internal/ir/lower/action_graph.go
…alue-bindings Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # internal/exec/runtime/held_image_behavior.go
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
|
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 |
…s-develop-merge Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # internal/exec/runtime/frame.go # internal/exec/runtime/statements.go
…s-develop-merge Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # internal/exec/runtime/action_executor.go # internal/exec/runtime/frame.go # internal/exec/runtime/state_executor.go # internal/exec/runtime/state_statements.go
…llocated markUnvalued allocated the map on a copy of the frame, so the mark was lost whenever the frame held no unvalued name yet; calcRun.bindingsFrame then read a case-local the run left unvalued through to the enclosing binding of the same name. Mark through a pointer, and drop the pre-allocation the constraint result no longer needs. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…n a slow runner Co-Authored-By: jason.han <hanhuijun@gmail.com>
What and why
A feature written with
=inside an action, calculation, statement block or state machine was evaluated once, when the body started. The same declaration on a part already tracked what it read. For example:sysml -action U::actreporteda = 5, s = 0, r = 0. It now reportss = 10, r = 10. State-machine data had the same problem: afterassign a := 5in a transition effect,sstayed0, soaccept when s > 3never fired.Body and state value stores are now backed by dependency cells that reuse the existing object-level mechanism in
dependents.go; there is no separate recomputation path:lower.Declare,lower.Attributeandlower.Featurecarry aBindingflag, true for a value written with=and false for:=anddefault. Executors read the flag and never inspect declaration syntax.deriveFeatureValue's stale-retry loop is factored intoderiveWith, which body cells reuse (body_bindings.goderiveBodyCell).noteRead, so a derivation records it.beforeWrite/afterWrite, so whatever read the written feature is unmaterialized and derived again on its next read.assignto an=cell keeps the assigned value and stops tracking, the same as object-level values.derivedandconstantfeatures is unchanged.ErrCyclicFeatureValue.spec-compliance.md.=attributes so they track again for the new visit; written attributes keep their value.terminateall go throughcompleteRoot, which freezes the root cells before the performance ends.ResultsWithErrorreports the first binding that fails to derive (for example, one reading a destroyed object while the action waits) and omits that feature.Resultskeeps its map-only signature. The Context entry points that return action results propagate the error, asStateDataWithErroralready does for states.Known limitation: a body-local calc usage lowered as
DeclareUsage(calc k1 : Rhs { in x = x; }inside a block) still evaluates its=pins once per declaration, so the pins do not follow later writes. This is recorded in the compliance row, pinned byTestRuntimeRobustnessBodyFeatureBindings/calc_usage_remains_one_shot, and named at the execution site.Changed answers in existing fixtures
Two existing fixtures change answers. Both changes follow from the specification. No other existing fixture, trace golden or corpus expectation changes.
action_step_multiplicity_shared_writers: this fixture declaresattribute l : Integer = cin each ofa[3], andwdoesassign c := l + 1.=,lis bound to the currentcfor the whole performance (KerML 1.0 §7.3.4.5, §7.4.9), so every interleaving ends atc = 3.{1,2,3}to{3}, and check goes from divergent to agreed atc = 3.:=.action_step_multiplicity_shared_writers_initialusesl := cand keeps{1,2,3}with a divergent check, so the race coverage is kept.action_inherited_default_root:Basedeclaresin x : Integer = 3; in z : Integer = x * 2;, andDeriveddoesassign x := 10and thenassign r := z.z, so its=binds it tox * 2for the performance, andzfollows the assignedx:z = r = 20, previously 6.action_inherited_default_root_fallback:in z : Integer default x * 2keeps 6.action_inherited_supplied_parameter: a supplied argument (Base(x = 3, z = 7)) is a write and stays at 7 afterxchanges.To let the shared-writers fixture state its single explored result as
outputsbesideexploreBudget, the conformance schema now accepts a budget beside a single action or state result. A budget with no result, and anoutcomeslist holding only one result, are still schema errors.Specification basis
isDefault = false, the feature is bound to the expression's result for the life of the featuring occurrence.Actions::Action :> Performance,States::StateAction), so its body features follow the same rule as object features.docs/project/spec-compliance.md:=row is extended from object-level values to performance, body and state cells, and gains a section covering the end-of-performance freeze, supplied pins and the calc-usage limitation (How it was verified
if/while/for), calc body, constraint body;ais seen as a change ofs), state attributes, entry/do/exit locals;:=, a write to an=feature, read-only features, a flow-supplied pin, occurrence mirroring;action_body_feature_binding.trace.golden.body_feature_bindings.TestLoweredBodyFeaturesPreserveValueOperators.TestRuntimeRobustnessBodyFeatureBindingscases: a cycle, a read of a destroyed object, a state exit, a write that stops tracking, read-only features, the step budget during a re-derivation, snapshot/restore mid-performance followed by a write and a read, a held image, replay, and the calc-usage limitation.go build ./...,go vet ./...,gofmt -l .(empty),go test ./...make lint,make docs-check,python3 scripts/changelog.py checkgo test -race ./internal/exec/runtime/... ./internal/ir/lower/...training_examples_expected.txtuntouched) and the pilot XMI identity gateChecklist
make testandmake lintpass locallychanges/unreleased/<slug>.<section>.md, not as an edit toCHANGELOG.mdmake docs-countsrun if a gate count moved (compliance rows need nothing: the census is counted at docs build)F4,K5) in the body, docs, or changelog