Repository navigation
fix(runtime): derive implicit specializations for every performance the run creates - #1492
devin-ai-integration[bot] wants to merge 11 commits into
Conversation
…only user declarations Co-Authored-By: jason.han <hanhuijun@gmail.com>
…osite by notation Co-Authored-By: jason.han <hanhuijun@gmail.com>
…alization-runtime-objects
…role; classify redefined items by kind A state's `entry action en` redefines States::StateAction::entryAction implicitly (SysML checkActionUsageStateActionRedefinition), so the state's entryAction and the declared action are one performance. A feature redefining an `item` holds Items too. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…brary-declared members Co-Authored-By: jason.han <hanhuijun@gmail.com>
Conformance fixture, robustness case, spec-compliance row and changelog fragment; a ref step owned by a behavior is one of its enclosed performances. 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)".
|
The body-member modifier path recognised one-word kind keywords only, so
`part def A { ref use case x; }` was composite. The library's UseCase ref
use cases now parse as written (snapshot regenerated).
ImplicitSubsettingCandidates follows the model's compositeness rule for the
step fallback, and the v1 migrator judges a «Viewpoint» by the view def it writes.
Co-Authored-By: jason.han <hanhuijun@gmail.com>
There was a problem hiding this comment.
Note
Newer findings are available below. Devin Review posted a newer report on this PR, in addition to the findings presented here.
Devin Review found 1 potential issue.
⚠️ 1 issue in files not directly in the diff
⚠️ Box materialization checks accept incomplete walks
For the box fixtures, bounded: true accepts materialization checks that stop at the read budget. Errors in unread values can now go undetected.
1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)
A Box's 8 vertices, 12 edges and 6 faces now carry their Item collections (80 objects), more than the 1000 feature-value reads the walk allowed; the budget is 4000, so -instantiate and -validate read both box fixtures in full instead of stopping bounded with unread values unchecked. Co-Authored-By: jason.han <hanhuijun@gmail.com>
|
Re the Devin Review finding on |
…the action that redefines it The role redefinition of a library feature (a state's entry/do/exit action, a view's render) identifies the two at run time without masking the library name, as the pilot resolves sm.entryAction beside entry action en; a case role (subject, objective) keeps masking, which TradeStudy objective evaluation depends on. Co-Authored-By: jason.han <hanhuijun@gmail.com>
|
738defa fixes a regression this PR had introduced at 8a44a9a: the new role redefinition of a state's |
…not subactions StateAction::subactions :> middle holds what runs between entry and exit (States.sysml; StatePerformances.kerml entry then middle then exit), and the pilot's isActionOwnedComposite excludes entry and exit actions, so they take the step fallback (subperformances) instead of Actions::Action::subactions. sm.subactions reads [doAction]; subperformances and enclosedPerformances keep the entry, do and exit actions. Co-Authored-By: jason.han <hanhuijun@gmail.com>
|
2573e8d corrects
Golden movement: |
Co-Authored-By: jason.han <hanhuijun@gmail.com>
What and why
KerML §7.3.4 implicit specialization is a property of every type and feature, but the runtime derived the Kernel/library memberships of an object only from the features of its shape (its user-declared type), and only through implicit subsettings of non-library features. Performances the executor itself creates from library actions — the anonymous
LoopActionnode, each iterationbody, thestart/doneshots — therefore lacked the memberships the Kernel library derives for them:k.loopy.loops#(1).enclosedPerformancesread[]andtimeEnclosedOccurrencesomitted the bodies.Measured on
develop(0cf906f3d) for the reproducerperform action loopy { … loop action body { … } until n >= 3; … }:enclosedPerformances[]timeEnclosedOccurrences[loop, start, done][loop, body×3, start, done]subperformances,suboccurrences[][](body is not composite)snapshotsenclosedPerformances,subperformances,suboccurrences[inc]snapshots,timeSlices,superoccurrencestart/done)timeEnclosedOccurrences,snapshots,portionsloopyenclosedPerformances,subperformances,timeEnclosedOccurrences[loop]starttimeEnclosedOccurrences,portionsRoot causes, each fixed generally (no name or loop special-casing):
runtime/kernel_collections.goshapeSubsettersOfwalked only the shape features; a member the object holds outside its shape (a library parameter the run filled, such asLoopAction::body) now contributes like any other subsetter.runtime/subsetting.gosubsetsTransitively/implicitSubsettingNamesskipped every library-tier feature, so an implicit subsetting a library feature states (LoopAction::bodyis a step of a Performance, hence:> enclosedPerformances) was never followed.semantics/nested.gonestedRuleFQNgave a non-composite step no implicit subsetting at all; per the pilot (isBehaviorOwnedComposite→subperformances, elseisBehaviorOwned→enclosedPerformances) a composite step is a subperformance and a non-composite one (ref action, a parameter such asbody) an enclosed performance. Compositeness of a KerML feature is its declaration's; of a SysML usage its kind's (usageIsComposite, which now also knows a body parameter is not composite).semantics/roles.go: a state'sentry/do/exitaction redefinesStates::StateAction::entryAction/doAction/exitActionby its role (SysMLcheckActionUsageStateActionRedefinition; the pilot'sisComputeRedefinitions"for state and transition actions, always add implicit redefinition"), so the state'sentryActionand its declared entry action are one performance instead of two. This surfaced once the StateAction subactions enteredsubperformances.runtime/shape.goimplicitFeatureBases: a feature redefining anitem(ShapeItemsitem :>> vertices) holds Items as well as what its type says, so the Geometry library'ssubitemsnow derive their edges and vertices.Specification basis
KerML 1.0 §7.3.4 (implicit specialization),
Performances.kerml(enclosedPerformances :> timeEnclosedOccurrences,subperformances :> enclosedPerformances),Occurrences.kerml; KerMLcheckStepEnclosedPerformanceSpecialization; SysML v2checkActionUsageStateActionRedefinition; SysML.xtextUsagePrefix(refbeforeuse case). New row indocs/project/spec-compliance.md(after the nested-usage implicit-subsetting row).Behaviour changes
enclosedPerformances/timeEnclosedOccurrenceslist its iteration bodies; itssubperformances/suboccurrencesstay empty.ref actionowned by a behavior is one of itsenclosedPerformances(semantics/nested_test.go:TestImplicitSubsettingsRefSteppreviously asserted none — stricter than the spec and the pilot).entry/exitaction is a subperformance of the state but not one of itssubactions(States.sysmlaction :>> subactions :> middle;StatePerformances.kermlentry then middle then exit,do :> middle; the pilot'sisActionOwnedCompositeexcludesisEntryExitAction):semantics/nested.goNestedUsage.EntryExitActionsends such an action to the step fallback (subperformance) instead ofActions::Action::subactions.sm.subactions: develop[en], 738defa[en, doAction, exitAction], now[doAction];sm.subperformances/enclosedPerformances: develop[en], 738defa and now[en, doAction, exitAction];sm.middle<undetermined>throughout (an abstract[1..*]step no value binds). Pinned byk.smSubactionCount = 1,k.smSubperformanceCount = 3,k.smSubactionIsDoAction.entryAction/doAction/exitActionis the declaredentry/do/exitaction, and the library name stays resolvable beside it:semantics/roles.gosplitsImplicitRoleRedefinitionsintolibraryRoleRedefinitions(state actions, a view'srender; identity at run time, no masking) andcaseRoleRedefinitions(subject/objective/actor/stakeholder; masked bymasking.gomaskingRedefinedFeaturesas on develop — TradeStudy objective evaluation depends on it). The pinned pilot validator resolvessm.entryActionbesideentry action en; pinned byk.entryActionIsEnin the conformance fixture.subitemsderive their library-declared members: a Rectangle's edges and vertices, an Ellipsoid's faces, a SpatialItem'soriginPoint;Box.subitemsnow reports the same unresolvedtflvbindingBox.verticesalready reported (pinned ininstance_library_geometry_box). Reading a Box in full now costs more than the 1000 feature-value readsmaxMaterializeBudgetallowed (its 8 vertices, 12 edges and 6 faces each carry their Item collections: 80 objects); the budget-instantiateand-validatewalk under is 4000, which reads both box fixtures to the end (materialization: {}stays a complete, clean read) — a recursive type is still cut bymaxMaterializeDepthand the on-path rule (instance_validate_boundedunchanged).checkedConstraintsof a view lists itsviewpointConformancerequirement.ref use casewritten in a body is a reference usage: the body-member parser applied arefbefore a one-word kind keyword only, sopart def A { ref use case x; }was composite (one of the part'sownedActions, so refusednonunique); the top-level form already kept theref. The standard library'sUseCase::self/start/done/includedUseCasesare therefuse cases they are written as (stdlib snapshot regenerated), pinned byparser/ref_use_case_test.go.semantics.ImplicitSubsettingCandidates(what the v1 migrator consults before writingnonunique) follows the same compositeness rule as the model: a non-composite step in a part, item or port owner subsets nothing; in a performance or occurrence ownerenclosedPerformances. The migrator's owner table judged a v1 «Viewpoint» as a viewpoint def while writing it as aview def; it now judges theview defit writes (migrate/uniqueness_test.go:TestImplicitlyUniqueAgreesWithTheChecker, which caught both).Golden movement (every row)
kernel_member_reads_running/state_machine.golden(9 rows):enclosedPerformances,suboccurrences,subperformancesofsmat three points gain the StateActiondoAction/exitActionperformances the runtime materializes for a state declaring nodo/exit(they existed before —sm.doActionwas readable on develop — and are now listed wheresubactions :> subperformancesputs them).kernel_member_reads.golden(4 rows):enclosedPerformances/suboccurrences/subperformancesempty → collection of 3;predecessors11 → 13 (the same objects).docs/project/library-and-prefix-sweep-outcomes.txt(9 rows):vw1/vwq/Vw1().checkedConstraintsempty → theviewpointConformanceobject;sph.subitems→ its face;spat.subitems+originPoint;box.subitems→ thetflvbinding error;st/es/S1().subactionsempty → the three StateAction default performances.docs/project/library-and-prefix-sweep-outcomes.txt(3 more rows, entry/exit fix):p1.st/p1.es/S1().subactionscollection(3)[entryAction, doAction, exitAction]→ collection(1)[doAction];state_machine.goldenandkernel_member_reads.goldendo not move (they list sub-/enclosedPerformances, which keep all three).library_shape_test.go:TestInheritedLibraryFeaturesMaterializeNoObjectsno longer readssubitemsof a Box: the library itself puts the box's faces in it.Cost
10 000-iteration loop, 3 runs each: develop 0.68/0.91/0.87 s, 202–216 MB RSS; this branch 0.65/0.91/1.03 s, 204–214 MB RSS — within noise, no new per-iteration path (the held-member walk is per read, over the object's own feature values).
Follow-ups (not this PR)
A case's
u.subjbesidesubject sis unresolved (as on develop) while the pilot validator resolves it; un-masking case roles breaks TradeStudy objective evaluation (tradeStudyObjective: require condition … evaluationFunction has no return expression), so the evaluator's objective lookup must stop relying on masking first.The on-disk library index cache (
libs/cache.go) served records derived by an earlier local build: with the same source, a binary built in the main tree resolvedu.subj(no masking, from an experiment build) until~/.cache/sysml-lswas cleared, while a worktree build of the same commit refused it. The key carries a build identity meant to prevent exactly this (buildid.go: clean revision, else executable size and mtime), so the stale hit needs a reproducer and a fix of its own.A state declaring no
do/exitstill materializes a defaultdoAction/exitActionperformance; the pilot holds none for an unset[0..1].How it was verified
implicit_specialization_runtime_objects(loop node, bodies, shots, a Rectangle's subitems),robustness_implicit_specialization_test.go:TestRuntimeRobustnessImplicitSpecialization(reading the derived collections creates no objects under a tight object bound; a state's entry/do action is itsentryAction/doAction)TestKernelLibraryMembersReadableWhileRunning,TestKernelLibraryMembersReadable,TestLibraryAndPrefixSweepre-recorded as accounted aboveOccurrencesTest::p1.vandnew OccurrencesTest::P1().vboth still2go build ./...,go vet ./...,gofmt -l .(empty),make lint(staticcheck + gosec pass),go test ./internal/exec/runtime/...(ok),go test -count=1 -timeout 30m ./cmd/sysml/...alone (ok),go test ./tests/corpus/...with the training, pilot, spec-example and PSSM corpora downloaded and theirOPENSYSML_REQUIRE_*set (ok),tests/identitywith the pilot library XMI (ok),internal/exec/smt(ok), the parser, semantics, check, migrate, libs and ir packages (ok),python3 scripts/changelog.py check,python3 scripts/check-doc-ids.pyTestEmbeddedSnapshotIsCurrent/TestSnapshotIndexMatchesFreshLoadpass against the regenerated stdlib snapshotChecklist
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 changelogLink to Devin session: https://nasa-jpl-demo.devinenterprise.com/sessions/d3ecda1e7b624c9facc77be02738785c
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/d3ecda1e7b624c9facc77be02738785c?variant=devin
Requested by: @HuiJun