Skip to content

Enhance State Transition View with attached transitions and pseudostate support#30

Merged
Malcolmnixon merged 6 commits into
mainfrom
feature/state-transition-initial-pseudostate
Jul 12, 2026
Merged

Enhance State Transition View with attached transitions and pseudostate support#30
Malcolmnixon merged 6 commits into
mainfrom
feature/state-transition-initial-pseudostate

Conversation

@Malcolmnixon

Copy link
Copy Markdown
Member

This pull request implements comprehensive support for attached state transitions, entry/do/exit actions, and inherited pseudostate features in SysML v2 state machines. It addresses several correctness bugs and limitations in the previous implementation, ensuring that all states and transitions are properly modeled and rendered, including those using common SysML idioms such as implicit transition sources (start, done) and attached transitions. The changes span the AST builder, reference resolver, and layout strategy, and update both code and documentation to reflect the new behavior.

State Machine Modeling and AST Construction:

  • AstBuilder now supports attached transitions (e.g., state X; accept ... then Y;) and entry/do/exit action features by introducing explicit visitor methods for these grammar constructs. This ensures all states and transitions are captured in the AST, including those with implicit or inherited sources. [1] [2]
  • Entry/do/exit actions are minimally modeled as resolvable features, allowing references to them from transitions.

Reference Resolution Improvements:

  • ReferenceResolver now resolves transition sources via a new ResolveTransitionSource method, which first tries regular feature-chain resolution, then falls back to a dedicated inherited-member lookup for start/done and entry-action features. This resolves previously unresolvable transitions that use inherited pseudostate features. [1] [2]
  • The fallback for inherited pseudostate resolution is intentionally narrow, covering only the standard library's Actions::Action for start/done, consistent with the SysML v2 spec and project roadmap.

Layout and Rendering Logic:

  • StateTransitionViewLayoutStrategy now prefers a semantically-resolved initial transition (e.g., from start or an entry action) over the previous first-declared-state heuristic when placing the initial marker. It also excludes pseudostate and entry-action sources from being rendered as state boxes, eliminating spurious boxes for non-state features. [1] [2] [3] [4]

Documentation Updates:

  • The roadmap and technical documentation have been updated to describe the new behavior, the rationale for changes, and the limitations of the current implementation. This includes detailed explanations of the new AST visitor logic, reference resolution fallback, and layout strategy adjustments. [1] [2] [3] [4] [5] [6] [7]

Summary of Most Important Changes:

1. State Machine Parsing and AST Construction

  • Added explicit handling for attached transitions and entry/do/exit actions in AstBuilder, ensuring all relevant state machine elements are captured and resolvable. [1] [2]

2. Reference Resolution Enhancements

  • Implemented ResolveTransitionSource and TryResolveInheritedActionMember in ReferenceResolver to resolve inherited pseudostate features (start/done) and entry-action sources for transitions. [1] [2]

3. Layout and Rendering Improvements

  • Updated StateTransitionViewLayoutStrategy to use semantically-resolved initial transitions for marker placement and to exclude pseudostate/entry-action sources from state box rendering. [1] [2] [3] [4]

4. Documentation and Roadmap

  • Revised roadmap and technical documentation to reflect new modeling capabilities, rationale, and known limitations. [1] [2] [3] [4] [5] [6] [7]

These changes close several longstanding gaps in SysML v2 state machine support, ensuring correctness and spec compliance for common modeling idioms.

Malcolm Nixon added 6 commits July 12, 2026 11:57
Cross-checked against the OMG training corpus (25.Transitions) and the
official spec's own Annex A.7 worked example. The gap is larger than
originally scoped: attached-transition state bodies silently drop both
the state and its transition; entry/do/exit action features have no
AstBuilder support at all; inherited pseudostate-like features (start,
done) don't resolve; and the initial-marker rendering already exists
but is a pure first-declared-state heuristic, not semantically driven.
…atures

- AstBuilder: add MultiNodeCapture sentinel; synthesize attached transitions
  for behaviorUsageMember/targetTransitionUsageMember and
  entryActionMember/entryTransitionMember state body shapes; build minimal
  entry/do/exit action feature nodes; populate FeatureTyping in
  VisitStateUsage (previously always dropped).
- ReferenceResolver: add TryResolveInheritedActionMember fallback so a
  transition's implicit start/done source resolves against the enclosing
  state's supertype chain, with a narrow last-resort fallback to stdlib
  Actions::Action for unqualified state/action definitions.
- Add WorkspaceLoader and OMG corpus regression tests covering attached
  transitions, entry actions, explicit state typing, and inherited
  start/done resolution.
…yout

- CollectStates: exclude pseudostate (start/done) and entry-action sources
  from ordinary state-box rendering.
- Add FindInitialTargetIndex helper to locate the semantically-correct
  initial state from a pseudostate-sourced transition.
- BuildLayout: use the resolved initial target for the initial marker,
  falling back to the first-declared state when no such transition exists.
- Add layout tests covering pseudostate/entry-action source exclusion and
  semantic initial-marker selection.
- Add SysML2Tools-Language-Semantic-Model-AstBuilder-AttachedTransitionStateBody
  and -EntryDoExitActionFeatures requirements with test traces.
- Add SysML2Tools-Language-Semantic-Model-ReferenceResolver-InheritedTransitionSource
  requirement with test traces.
- Add SysML2Tools-Core-Layout-Internal-StateTransitionViewLayoutStrategy-PseudostateExclusion
  and -SemanticInitialMarker requirements with test traces.
- Update AstBuilder, ReferenceResolver, and StateTransitionViewLayoutStrategy
  design docs' Key Methods/Data Model sections to describe the new behavior.
- Add Test Scenarios entries to the corresponding verification docs.
…allery

- 03-elevator-state.sysml: add 'first start then idle;' as a real initial
  transition (previously relied only on the first-declared-state heuristic),
  and convert the idle/doorsClosing pair to the attached-transition idiom
  ('state idle; accept callReceived then doorsClosing;').
- Regenerate ElevatorStateTransitionView.svg/.png; visually verified per
  diagram-quality.md's Agent Checklist.
- Update the gallery README's descriptive text for this example.
@Malcolmnixon
Malcolmnixon merged commit 207dcac into main Jul 12, 2026
15 checks passed
@Malcolmnixon
Malcolmnixon deleted the feature/state-transition-initial-pseudostate branch July 12, 2026 18:45
Malcolmnixon added a commit that referenced this pull request Jul 12, 2026
* docs(roadmap): scope Action Flow control-node AST bug and split Sequence View item

Investigation found actionBodyItem has the same combined-shape AST bug
as stateBodyItem (fixed in #30): the compact 'action a; then b;' idiom
drops both nodes, and fork/join/decide/merge/accept/send control nodes
are entirely uncaptured. Scopes this branch to the AST correctness fix
plus fork/join (thick bar) and decision/merge (diamond) rendering using
existing Rendering-package BadgeShape primitives, explicitly deferring
a true pentagon accept/send shape (needs an external Rendering package
change), swim-lanes, and item-flow annotations. Split Sequence View
dynamics into its own item since it is an unrelated subsystem.

* Support attached-succession action bodies and control-node features

- AstBuilder: add VisitActionBodyItem synthesizing SysmlTransitionNode(s) for
  the initialNodeMember/actionTargetSuccessionMember and actionBehaviorMember/
  actionTargetSuccessionMember combined shapes, reusing the MultiNodeCapture
  sentinel; add BuildActionTargetSuccession covering targetSuccession/
  guardedTargetSuccession/defaultTargetSuccession.
- Add VisitMergeNode/VisitDecisionNode/VisitJoinNode/VisitForkNode/
  VisitAcceptNode/VisitSendNode building minimal SysmlFeatureNodes via a shared
  BuildActionNodeFeature helper; anonymous control nodes get a synthesized
  internal \\$<keyword><n>\ name so their successions still wire correctly.
- Add WorkspaceLoader and OMG corpus regression tests covering the compact
  action idiom, multiple attached successions, bare/attached first markers,
  anonymous/named control nodes, and guarded/default target successions.

* Render fork/join/decision/merge control nodes as badges in Action Flow View

- ActionFlowViewLayoutStrategy: widen CollectActions/FindRoot to recognize the
  merge/decide/join/fork/accept/send FeatureKeyword values in addition to
  action; add ComputeActionSize/MakeActionNode routing so fork/join render as
  a LayoutBadge(BadgeShape.HorizontalBar), decision/merge as
  LayoutBadge(BadgeShape.Diamond), and accept/send keep the rounded-rectangle
  box shape but show their own Keyword instead of the hard-coded action text.
- Blank rendered labels derived from AstBuilder-synthesized \\$\-prefixed
  internal names.
- Ordinary-action rendering path left unchanged to avoid regressing existing
  gallery/test fixtures.
- Add layout tests covering fork/join bars, decision/merge diamonds,
  accept/send boxes, synthetic-name blank labels, and the compact idiom.

* Document attached-succession action-body and control-node support

- Add SysML2Tools-Language-Semantic-Model-AstBuilder-ActionBodyAttachedSuccession
  and -ActionControlNodes requirements with test traces.
- Add SysML2Tools-Core-Layout-Internal-ActionFlowViewLayoutStrategy-
  ControlNodeShapes requirement with test traces.
- Update AstBuilder and ActionFlowViewLayoutStrategy design docs' Key
  Methods/Data Model sections to describe the new visitors, synthetic-naming
  convention, and kind-routed badge/box construction.
- Add Test Scenarios entries to the corresponding verification docs.

* Add fork/join branch and compact idiom to pipeline gallery model

- 04-pipeline-action-flow.sysml: convert checkout/restoreDependencies to the
  compact 'action a; then b;' idiom, and replace the implicit dual-successor
  build branch with an explicit named fork/join pair (buildFork/testJoin)
  feeding parallel unitTest/securityScan branches that rejoin before
  qualityGate.
- Regenerate PipelineActionFlowView.svg/.png; visually verified per
  diagram-quality.md's Agent Checklist (horizontal-bar badges at the fork/join
  positions, no overlaps).
- Update the gallery README's caption for this example.
- Mark the Action Flow View control-node/successor AST correctness item in
  ROADMAP.md as delivered, listing the pentagon accept/send shape,
  swim-lanes, item-flow annotations, assignment/terminate/if/while/for-loop
  node AST support, and actionUsage-level nested action bodies as explicitly
  deferred future work.

* Fix missing incoming edge for leading sourceSuccessionMember in action bodies

- AstBuilder.VisitActionBodyItem now reads context.sourceSuccessionMember() in
  the actionBehaviorMember branch and synthesizes the implicit incoming
  SysmlTransitionNode when a preceding flow position is known.
- Added CollectActionBodyChildren (parallel to CollectChildren, which stays
  untouched for state bodies) plus DetermineFlowPositionName and the
  _actionBodyPreviousNodeName field to track the current flow position while
  iterating an action body's actionBodyItems in source order.
- VisitActionDefinition now calls CollectActionBodyChildren for action bodies.
- Extended WorkspaceLoaderTests and OmgModelsTests to assert the previously
  missing incoming edges (a->f, TurnOn->\, J->F, start->continueCharging,
  continueCharging->monitor, monitor->\).
- Updated ast-builder reqstream requirement, design doc, and verification doc
  to describe the new incoming-edge mechanism and note the two discovered but
  out-of-scope analogous gaps (nonBehaviorBodyItem structureUsageMember and
  VisitStateBodyItem) as known follow-ups.

* Fix QualifiedName registration for named action-flow control nodes

BuildActionNodeFeature previously always set QualifiedName to null, even for explicitly named fork/join/merge/decide/accept/send nodes. This meant named control nodes were never registered in the symbol table and were not subject to expose-scope filtering in ActionFlowViewLayoutStrategy.CollectActions, unlike every other named feature in AstBuilder. Now, when a control node has an explicitly declared name, QualifiedName is populated via QualifyName (mirroring BuildStateActionFeatureNode); only the synthesized anonymous $<keyword><n> names keep QualifiedName = null.

---------

Co-authored-by: Malcolm Nixon <Malcolm.Nixon@hiarc.inc>
Malcolmnixon added a commit that referenced this pull request Jul 13, 2026
* docs(roadmap): ground Annotating elements item in confirmed AST/render gaps

Comment/doc annotation text is already captured semantically but never
read by GeneralViewLayoutStrategy; enum literal values, constraint
bodies, and requirement subject/constraints/doc are not captured in
the AST at all yet. Cites the spec's stereotype-style compartment
title conventions (subject, doc, constraint).

* Capture enum literals, requirement subject/constraints, and standalone constraints in AstBuilder

- Add nullable ExpressionText to SysmlFeatureNode, mirroring SysmlTransitionNode.Guard,
  for constraint-kind features' raw expression text.
- VisitEnumerationDefinition: full body-collecting visitor via new
  CollectEnumerationBodyChildren helper, since enumerationBody uniquely alternates
  annotatingMember/enumerationUsageMember directly rather than wrapping them in a single
  rule. VisitEnumeratedValue builds an 'enum value'-keyword feature for each literal
  (bare, value-assignment, and redefinition-body forms).
- VisitRequirementDefinition/VisitConcernDefinition: full body-collecting visitor
  (push-scope/CollectChildren(requirementBodyItem)/register), mirroring VisitStateUsage's
  established pattern. Also extend VisitRequirementUsage/VisitConcernUsage the same way,
  beyond a literal *Definition-only reading of the plan, because the dominant real OMG
  corpus idiom nests subject/assume constraint inside a requirement usage that
  specializes a def, not inside the def's own body.
- New VisitSubjectUsage/VisitActorUsage/VisitStakeholderUsage (subject/actor/stakeholder
  keywords) and VisitRequirementConstraintMember/BuildConstraintFeatureNode (require
  constraint/assume constraint keywords, capturing raw expression text for both the
  reference and inline requirementConstraintUsage grammar alternatives).
- New VisitConstraintUsage (previously entirely absent) and rewritten
  VisitConstraintDefinition, synthesizing a 'constraint'-keyword child feature carrying
  the raw calculationBody text.
- New VisitRequirementVerificationMember/VisitFramedConcernMember returning null: once
  body-collection reaches requirementBodyItem, ANTLR's default dispatch would otherwise
  recurse into a nested verify/frame member's own body and incorrectly hoist its content
  onto the outer enclosing requirement.

* Render annotation notes and new stereotype compartments in General View

- Add DefBox.Annotations, threaded through CollectDefinitions.
- New AddAnnotationNote/BuildNoteText/ComputeNoteBoxSize helpers: emit one
  BoxShape.Note box per annotated definition (concatenating multiple
  Documentation/Comment annotations into a single note), connected by a plain solid
  line with no end marker. Implemented as ordinary LayoutGraph nodes/edges added
  during the existing single-pass BuildGraph traversal, a documented deviation from
  a literal post-layout marker-decoration approach (this strategy has no equivalent
  decoration phase).
- Pluralize: add guillemet stereotype titles for subject/assume constraint/require
  constraint/constraint compartments, reusing the pre-existing «allocate» edge-label
  convention.
- FormatFeatureRow: render a constraint-kind feature's raw ExpressionText instead of
  the generic name : Type [multiplicity] row shape.

* Add tests for enum/requirement/constraint capture and note/compartment rendering

- WorkspaceLoaderTests: enum def bare/value-assignment literal capture, requirement
  def/usage subject+constraint capture, actor/stakeholder capture, standalone
  constraint usage/definition, and a verify-member no-hoist regression guard.
- OmgModelsTests: regression fixtures against the real OMG corpus for enumeration
  definitions, requirement definitions/usages, and comment/documentation examples.
- GeneralViewLayoutStrategyTests: note-box emission (including the no-note and
  multiple-annotations-combine-into-one cases), «subject» guillemet compartment
  title, constraint expression-text rows, and the enum values compartment title.

* Document AstBuilder and GeneralViewLayoutStrategy annotation/compartment changes

- ast-builder.md/general-view-layout-strategy.md design docs: describe the new
  visitor methods, the deliberate VisitRequirementUsage/VisitConcernUsage extension,
  the verify/frame null-suppression safeguard, and the AddAnnotationNote
  architectural deviation from a post-layout marker-decoration approach.
- sysml-node.md: document the new SysmlFeatureNode.ExpressionText field.
- Verification docs: add Test Scenarios entries for every new test.
- Reqstream YAMLs: add new requirement IDs with test traces, following the shape
  established by PR #30/#31.

* Add annotation, enum, and requirement compartments to gallery + mark roadmap item delivered

- 01-drone-general.sysml: Battery gains a doc annotation, FlightMode is now an enum
  def with literal values, and FlightTimeRequirement gains a subject/require
  constraint body.
- Regenerate DroneGeneralView/BatterySubsystemView SVG and PNG.
- Update gallery README caption for the new content.
- ROADMAP.md: mark 'Annotating elements & compartment depth' delivered.

* test(semantic): add concern def/usage subject coverage; close traceability gap in ast-builder requirement

The RequirementSubjectAndConstraints requirement in ast-builder.yaml claims coverage of both requirement and concern definition/usage paths (VisitConcernDefinition/VisitConcernUsage), but WorkspaceLoaderTests.cs only exercised requirement cases.

- Add WorkspaceLoader_LoadAsync_ConcernDefinitionAndUsage_CapturesSubject to WorkspaceLoaderTests.cs, verifying that a concern def and a concern usage each capture their subject member as a Children entry.
- Reference the new test in the RequirementSubjectAndConstraints requirement's tests list in docs/reqstream/sysml2-tools-language/semantic/model/ast-builder.yaml.
- Add the corresponding row to docs/verification/sysml2-tools-language/semantic/model/ast-builder.md.

---------

Co-authored-by: Malcolm Nixon <Malcolm.Nixon@hiarc.inc>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant