Enhance SysML v2 support with Dependency, Binding, and layout fixes#29
Merged
Conversation
…arch Per OMG SysML v2 spec section 8.2.3, item/occurrence/action/state/requirement usages render as compartment rows (already handled generically), not as diamond-edge-connected boxes. Removes 'containment' from the edge-kind list, adds a ref-to-dependency-style-edge fix (shared aggregation removed in v2). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add SysmlEdgeKind.Dependency and .Binding - Add SysmlDependencyNode AST node for standalone dependency statements - Add AstBuilder.VisitDependency and VisitBindingConnectorAsUsage - Add ReferenceResolver support: Dependency cross-product resolution (pass 1), Binding dotted feature-chain resolution (pass 2)
…GeneralViewLayoutStrategy - Fix ref keyword bug: remove obsolete hollow-diamond marker, render ref as a Dependency-shaped edge (dashed, open chevron) instead - Add ResolveOwningBox helper for Connect/Binding feature-chain endpoint resolution (shortest-typed-feature-prefix walk, avoids self-loop edges) - Add Subsetting as a private view-layer EdgeKind (not a new SysmlEdgeKind), reusing ResolveRedefinitionOwner and SysmlFeatureNode.SupertypeNames - Add ModelEdge.Label and wire it through BuildGraph for allocate/binding midpoint labels (allocate guillemets, equals sign) - BuildModelEdges now takes the SysmlWorkspace to read workspace.Index.AllEdges for Connect/Allocate/Dependency/Binding edges
…Subsetting and ref-fix
…rpus tests Adds parse/resolve unit tests for Dependency (binary + comma-list cross product + unresolved-end) and Binding (dotted-chain + unresolved-end) in WorkspaceLoaderTests.cs. Adds OMG corpus regression tests validating the 7 expected Dependency edges from DependencyExample.sysml/12a-Dependency.sysml, and documents a pre-existing gap (BuildUsageNode has no name fallback for bare 'redefines' targets) that prevents Binding resolution in BindingConnectorsExample-1.sysml.
Documents the new SysmlEdgeKind.Dependency/Binding values, SysmlDependencyNode, AstBuilder.VisitDependency/VisitBindingConnectorAsUsage, ReferenceResolver's Dependency cross-product and Binding feature-chain resolution passes, and GeneralViewLayoutStrategy's ref-fix, ResolveOwningBox endpoint-resolution algorithm, and the private view-layer Subsetting classification.
…onnect/Allocate/Dependency/Binding/Subsetting Adds reqstream requirements and matching verification entries for: - AstBuilder.VisitDependency / VisitBindingConnectorAsUsage - ReferenceResolver's Dependency cross-product resolution and Binding feature-chain resolution - GeneralViewLayoutStrategy's Connect/Allocate/Dependency/Binding rendering, the private Subsetting classification, and the ref-fix (updates the existing ReferenceMembership requirement, which previously described the now-removed obsolete hollow-diamond notation). All test-name references were checked against the actual xUnit fact names in GeneralViewLayoutStrategyTests.cs, WorkspaceLoaderTests.cs, and OmgModelsTests.cs.
… drone gallery - Extend docs/gallery/models/01-drone-general.sysml with a connect edge (controller.power to battery.output, using inline nested port redeclarations so the dotted chain resolves through the instance features rather than the shared PowerPort type, avoiding a ResolveOwningBox self-loop), an allocate edge (FlightTimeRequirement to Battery), a standalone dependency edge (FlightController to Battery), and a RacingDrone part def demonstrating subsets (frontMotors subsets motors). - Regenerate docs/gallery/svg/DroneGeneralView.svg and docs/gallery/png/*.png via the sysml2tools render CLI to visually confirm the new edge kinds render with distinct, correctly-headed styles. - Update docs/gallery/README.md with one sentence per new relationship kind.
…, subsetted vocabulary) - Replace unicode escape \u00ab/\u00bb with literal guillemet characters in the allocate label string literal (cspell was tokenizing the escape plus following word as a single false-positive 'aballocate' token). - Shorten the VisitBindingConnectorAsUsage table row in ast-builder.md to fit the 120-character line-length limit. - Add 'subsetted'/'Subsetted' to .cspell.yaml's project words list (paired with the already-whitelisted 'Subsetting'/'subsettings' terms) since this is genuine SysML/technical vocabulary introduced by this feature.
…gnostic Root-cause fix: TryResolveFeatureChain now tracks a parallel instancePath accumulator, and FindFeatureMember reports whether a segment was resolved via the type-hierarchy fallback branch. When it was, the returned qualified name preserves the instance-relative path (e.g. Drone::controller::power) instead of collapsing to the type's own declared path (e.g. FlightController::power). This fixes the ResolveOwningBox self-loop for the dominant real-world connect/bind shape (two sibling features declared directly in their owning part defs, no per-instance nested redeclaration). Defense-in-depth: BuildModelEdges now also reports any Connect/Allocate/ Dependency/Binding edge dropped because an endpoint failed to resolve to a box, or because both endpoints collapsed to the same box, via the new LayoutWarnings.ForDroppedRelationshipEdges warning, threaded into BuildLayout's existing warnings list. Tests: updated the 3 typing-fallback qualified-name assertions in WorkspaceLoaderTests.cs affected by the resolver change, updated QueryVerbsTests.cs's Connections_ReportsResolvedEndpointsIncludingFeatureChain test (query element/assertion now use the instance-relative path; the query --element option requires a declared node, so the element is now the engine part usage rather than the port itself), added a new dominant-shape test to WorkspaceLoaderTests.cs, and added an end-to-end GeneralViewLayoutStrategyTests test that runs the real WorkspaceLoader + BuildLayout (no synthetic edges) plus a warning assertion on the existing self-loop test proving the new diagnostic fires.
WorkspaceLoader_LoadAsync_BindingDottedChain_RecordsBindingEdge asserts a Binding edge produced via the same type-hierarchy fallback branch as the 3 already-enumerated Connect tests (bind a.x = b.y inside part def Q, both a and b typed by definitions declared elsewhere) — the fix plan's blast-radius table did not enumerate this test. Full 3-TFM test suite is green with this 5th update; no other assertion in the 764-test suite needed changing.
…expose noise docs/gallery/models/01-drone-general.sysml: remove the now-unneeded inline nested port redeclarations under battery/controller — the ReferenceResolver root-cause fix means the natural, bare part declarations now resolve the 'connect controller.power to battery.output;' statement correctly. Regenerated DroneGeneralView/BatterySubsystemView SVG+PNG: byte-identical to the already-committed images, confirming the fix reproduces the exact same (correct) rendering the workaround previously forced. GeneralViewLayoutStrategy.cs: refined the dropped-relationship-edge diagnostic added in the previous commit so it only reports an unresolved-endpoint drop when the view is not expose-scoped; a genuine self-loop (both endpoints resolve, to the same box) is still always reported regardless of scoping. Without this, every expose-narrowed view legitimately produces Allocate/Dependency/Connect drops for relationships crossing the exposed boundary by design (confirmed while regenerating BatterySubsystemView, an expose-scoped gallery view, which surfaced 3 such warnings before this refinement and 0 after) -- noise unrelated to the quality report's actual concern (silent self-loop collapse).
…stic - design/.../general-view-layout-strategy.md: correct the self-loop mischaracterization (the dominant real-world connect shape resolves to two distinct boxes, not a self-loop, once ReferenceResolver preserves the instance-relative path); document BuildModelEdges's new isScoped parameter, DroppedRelationshipEdge record, and the dropped-edge diagnostic threaded into BuildLayout's warnings, including the expose-scope exclusion rule. - design/.../reference-resolver.md: document the instancePath accumulator and viaTypeFallback distinction in TryResolveFeatureChain/FindFeatureMember. - verification/.../reference-resolver.md: add acceptance criterion and Test Scenario rows for dotted feature-chain resolution (previously undocumented entirely), covering direct-child, type-hierarchy-fallback, mixed, inherited, dominant-shape, and unresolved-endpoint cases. - verification/.../general-view-layout-strategy.md: correct the self-loop wording, add the new dropped-edge-diagnostic acceptance criterion and Test Scenario rows for the self-loop warning and the new end-to-end test. - reqstream/sysml2-tools-language.yaml: add the new dominant-shape test to the existing FeatureChainResolution requirement's test list; clarify its title to mention instance-relative-path preservation (bug fix to already-specified behavior, no new requirement ID). - reqstream/.../general-view-layout-strategy.yaml: correct the Connect requirement's self-loop justification; add the new end-to-end test; add a new DroppedRelationshipEdgeWarning requirement for the diagnostic. All docs verified against pwsh ./lint.ps1 (exit code 0) and pwsh ./fix.ps1.
Gzip re-compression produces different bytes for identical content (non-deterministic header), unrelated to this branch's actual scope. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…a fallback hop TryResolveFeatureChain reset the instance-relative accumulator to a member's raw QualifiedName whenever a segment was found via FindFeatureMember's direct-child branch. That is only correct while every prior segment was also a direct child of a true instance node. Once an earlier segment resolves via the type-hierarchy fallback branch, 'current' refers to the type's own declared path rather than the instance, so a later 'direct child' match is still only reachable relative to that type — and the old code incorrectly collapsed the accumulated instance path back to the type-declared path in that case. Fixed by latching an 'in type context' flag on the first fallback hop and keeping every subsequent segment in instance-relative-append mode once that flag is set, regardless of whether later segments individually resolve via direct-child or fallback. Found by code-review agent during this branch's automated review pass; added a regression test mirroring the existing ConnectionThreeSegmentChain_MixesDirectChildAndTypingFallback test but with the fallback/direct-child hop order reversed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
F2 (Medium): assert the Warning diagnostic in WorkspaceLoader_LoadAsync_BindingUnresolvedEnd_ProducesWarningNoEdge, matching its own doc summary and the parallel Dependency test. F1 (Low): sysml-edge.md said 'twelve members' and omitted MetadataType from the bulleted list; corrected to thirteen and added the missing bullet. F3 (Low): SysmlConnectionNode.ConnectionKeyword XML doc now lists 'binding' alongside connection/message/allocation. F4 (Low): SysmlDependencyNode.FromNames XML doc corrected — the implicit-from shape (dependency z to x;) still populates FromNames; it is only empty when no qualified name precedes 'to' at all. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…pseudostate) gap Documents a separate, harder limitation than the Binding/item implicit-name gap fixed in the next commit: SysML v2 allows a transition with no explicit source (then TargetState;), an initial-pseudostate semantic that today produces no Transition edge at all. Closing it requires distinguishing "no source" from "unresolved source" plus new marker rendering, so it is tracked as its own roadmap item rather than folded into this branch. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…lared name
SysML v2 allows a redefining usage to omit its own declared name, taking the
redefined feature's name instead (e.g. `port redefines fuelTankPort { item
redefines fuelSupply; }` is named `fuelTankPort`). AstBuilder.BuildUsageNode
previously only used the explicit declared name, so such usages were built
as anonymous nodes never registered in the symbol table -- any subsequent
reference to them (including `bind` connector ends) failed to resolve.
Adds SimpleNameFromReference to derive the trailing ::-segment of a
redefined-feature reference, and uses it as an effectiveName fallback
throughout BuildUsageNode (namespace stack, QualifiedName, Name) whenever no
explicit name is declared.
Rewrites the OMG binding corpus regression test to assert the two Binding
edges now resolve correctly (previously asserted only "parses without
crashing" against 0 resolved edges), adds a focused
WorkspaceLoaderTests regression test mirroring the fixture shape in
isolation, and updates the ast-builder design/verification docs and
reqstream requirement to document the new fallback behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… naming
Code review of the prior commit found that SimpleNameFromReference only
stripped a trailing "::" segment, but ownedRedefinition is grammatically
qualifiedName ( DOT qualifiedName )*, so a redefinition reference can be a
dotted feature-chain path (e.g. tank.fuelTankPort), not just a ::-qualified
name. The old logic would have assigned a bogus dotted name (e.g.
"tank.fuelTankPort") instead of the correct trailing simple name
("fuelTankPort") for such usages.
Fixes SimpleNameFromReference to take whichever of the last "::" or last "."
separator occurs furthest to the right. Adds a regression test
(WorkspaceLoader_LoadAsync_ImplicitNameFromDottedRedefinitionChain_UsesTrailingSegment)
and updates the ast-builder design/verification docs and reqstream
requirement accordingly.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rename The Binding OMG corpus test was renamed from Binding_OmgCorpusFixture_ParsesAndResolvesWithoutCrashing to Binding_OmgCorpusFixture_ResolvesBindingEdgesViaImplicitRedefinitionNames in commit b5eea86, but two other reqstream requirements (AstBuilder-BindingConnector, ReferenceResolver-BindingFeatureChain) and the reference-resolver verification doc still referenced the old test name, leaving them without a satisfying test per the reqstream tool. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Malcolmnixon
pushed a commit
that referenced
this pull request
Jul 12, 2026
The drone gallery model (docs/gallery/models/01-drone-general.sysml) already has real connect/allocate/dependency/subsets usages from the merged PR #29 work; the roadmap entry was never tagged done.
This was referenced Jul 13, 2026
This was referenced Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces significant improvements and corrections to the documentation and configuration for SysML v2 diagram rendering, focusing on relationship edge handling, terminology, and notation accuracy. The main updates clarify and extend how various relationship types (including subsetting, dependency, allocation, binding, and connect) are represented and described in the codebase and documentation, aligning them with the latest SysML v2 specifications.
General View Relationship Edge Handling:
subsetting,connect,allocate,dependency,binding) inGeneralViewLayoutStrategy, detailing how each is resolved and rendered, and clarifying the removal of the obsolete hollow-diamond membership forrefusages. [1] [2] [3] [4]SysML v2 Notation and Relationship Corrections:
refusages (now dependency-style, not hollow-diamond membership), and corrected previous misconceptions about containment and compartment rendering for certain usages.AST and Semantic Model Alignment:
Configuration and Spelling:
These changes collectively improve the accuracy, completeness, and maintainability of the SysML v2 rendering subsystem and its documentation, ensuring closer alignment with the standard and better diagnostics for edge-case scenarios.