Skip to content

feat(migrate): write v1 views, viewpoints, use cases, Expression trees and InterfaceRealizations as v2 - #514

Merged
HuiJun merged 12 commits into
developfrom
feature/migrate-views-usecases-expressions
Sep 22, 2026
Merged

HuiJun merged 12 commits into
developfrom
feature/migrate-views-usecases-expressions

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

What and why

The SysML v1 → v2 migrator refused four families of UML/SysML v1 constructs that have a direct or near-direct v2 form. Each is now written, with an explicit report note wherever v2 genuinely has no form, so nothing is dropped silently. All mappings are generic: they key on UML metaclasses, SysML profile stereotypes and the tool provenance the migrator already uses, never on a model's names or paths.

Views and viewpoints (views.go)

Standard v2 admits expose only in a view usage body (in a view def it is an OpenSysML extension flagged with a warning) and satisfy only against a viewpoint usage, so a v1 «View» class becomes a package-level view usage and a «Viewpoint» class a package-level viewpoint usage; a property typed by a view is a nested view x :> Other; (the type becomes subsetting, since the type is now a usage).

«View» Class V, viewpoint tag → VP        view V { satisfy VP; expose …; render Views::asTreeDiagram; }
«Expose» Dependency V → element E         expose Q::E;             (E written in the document)
«Expose» Dependency V → package P         expose Q::P::**;
«Expose» → diagram / external / unwritten reported, unmapped, with the reason (notation only; outside the document; not written)
«Conform» Generalization/Dependency V → VP  satisfy VP;            (placed in V's body ahead of writing, like Satisfy/Verify)
«Viewpoint» Class VP                       viewpoint VP { doc /* purpose, method, language, presentation */ subject; stakeholder s : S; frame concern c { doc … } }
«View» Package                             view holding its members (approximated)

A viewpoint's subject; is written before its stakeholders, and only stakeholders that are written part defs get a stakeholder member; a missing, proxied, unwritten or non-part stakeholder keeps a reason. The bundled OMG standard library has no generic Stakeholder definition (only the non-standard OOSEM library does), so «Stakeholder» stays a plain part def, which the stakeholder members reference. concernList comments become frame concern members and are not repeated as doc.

Use cases (usecase.go)

uml:UseCase is classified as use case def regardless of incidental stereotypes («HyperlinkOwner» etc.). The body gets subject (an anonymous subject; first when actors exist but no writable explicit subject does — the validator requires the subject to be the first parameter), actor a : A for each association to a written Actor and for owned attributes typed by one, include use case i : I; for UML Include, objective from the owned comments. UML Extend is kept as an approximation with a reason: v2 has no extend.

UML Expression trees (expression.go, XMI reader)

uml:Expression / StringExpression trees are lowered recursively over the operator set the opaque-expression translator already uses: arithmetic + - * / % **, comparison, and or not, unary minus, calls in the translated function table (Math.*), literals, InstanceValue, opaque-string operands and feature references, with the same scope-visibility checks (featureResolver). Operators spelled by name (Plus, Minus, Times, Equal, Power, …) are read case-insensitively. Anything else — an unknown symbol, a symbol-less node, an unsupported opaque language, an interval or time construct, an inaccessible or unnamed reference, an instance value naming no instance — is refused with the construct spelled out.

MagicDraw keeps a feature reference inside an Expression as a uml:ElementValue (no such UML metaclass) under an xmi:Extension. The XMI reader now adopts those nodes as operands of the owning element, in document order; other extension content (diagrams, layout) is still skipped and still recorded in Model.Extensions.

InterfaceRealization (realization.go)

A part def specializing a port def is not valid v2, so the mapping depends on how the interface is written: a realizing Block gets a port : I typed by the interface's port def; a realizing InterfaceBlock (itself a port def) specializes it with :>. An external, unwritten or notation-only endpoint keeps a refusal naming why.

Also fixed along the way: an operation of a port def is written ref action, not action (owned usages of a port def other than ports must be referential); nested feature references use dot notation (Outer.inner) rather than ::; a nil upperValue no longer dereferences.

Specification basis

SysML v2 v2.0 §7.24 Views and Viewpoints (ViewUsage, Expose, ViewpointUsage, StakeholderMember, FramedConcernMember), §7.23 Use Cases (SubjectMember, ActorMember, IncludeUseCaseUsage), §7.9 Expressions, and the sysml-v1-migration.md mapping table (rows added for each construct). No row of docs/project/spec-compliance.md moves: this is the v1 → v2 translator, not the v2 semantics.

How it was verified

Fixtures (hand-written, model-neutral, each golden output validates with 0 errors through the same analyser the fixture test runs): report_views.xmi (views, viewpoints, stakeholders, expose of an element / a package / a diagram / an external element, conform, a view property), parking_usecases.xmi (actors, subject, include, extend), tree_constraints.xmi (a Pythagorean constraint whose base operands are extension-held ElementValues, arithmetic, comparison, Boolean, unary minus, a translated call, and a refused xor), realized_interfaces.xmi (interface realized by a block and by an interface block, plus an unwritten one). Focused unit tests in views_internal_test.go, usecase_internal_test.go, expression_internal_test.go, realization_internal_test.go, xmi_test.go.

Gates (all run from a clean tree at the head commit):

gofmt -l .                      → (nothing)
go build ./...                  → ok
go vet ./...                    → ok
OPENSYSML_REQUIRE_TRAINING_CORPUS=1 OPENSYSML_REQUIRE_PILOT_CORPORA=1 \
OPENSYSML_REQUIRE_PSSM_SUITE=1 OPENSYSML_REQUIRE_PILOT_LIBRARY_XMI=1 \
go test -count=1 ./...          → ok (80 packages; tests/corpus 22.6s, tests/identity 1.0s, tests/migrate 33.6s)
python3 scripts/changelog.py check      → ok
python3 scripts/check-doc-ids.py        → ok
make lint (staticcheck + gosec)          → ok

No corpus expectation file changed: neither training_examples_expected.txt nor the pilot / PSSM ratchets moved.

Leakage audit over the changed production files (internal/translate/migrate/*.go, internal/translate/xmi/sysmlv1/xmi.go, tests excluded):

rg -n -i 'TMT|\bAPS\b|IRIS|M1CS|NFIRAOS|WFOS|Collaborator|JPL|Sandbox' <changed production files>
→ only `stmtNote` in behavior.go (pre-existing identifier, matched by the case-insensitive "tmt")

The only numeric literals in the added production lines are 0, 1, 2 and 4 (arity checks, loop starts). The four fixtures contain none of those names either.

Real-model proof (a Cameo 2024x .mdzip, used only as evidence): sysml <model> -convert sysml -o out.sysml -migration-report r.txt -migration-results results.json on develop and on this branch, then sysml out.sysml -validate and sysml out.sysml -compare-results results.json on each.

develop this branch
report rows 44 161 47 151
mapped 28 384 31 008
approximated 10 589 10 868
unmapped 5 188 5 275
skipped 1 713 1 802
-validate errors 0 0
-validate warnings 832 2 283

The 2 990 additional rows are the contents of the «View»/«Viewpoint» classes — their properties, owned activities (the view-method queries), comments and constraints — which develop never reported because a refused classifier's body was not walked; they are now written or refused individually. The warning increase is Duplicate of inherited member name from views that expose several packages declaring same-named members plus the nested views subsetting them; both this validator and the pilot's treat that as a warning, and a minimal probe (view Overview { expose A::**; expose B::**; } with part def X in both) reproduces it with 0 errors.

Rows that moved between categories (by report kind):

kind develop this branch
«View» Class 119 unmapped 118 mapped, 1 approximated; 564 more, nested in view classes, are now reached (651 mapped, 32 approximated in all — the approximations are sibling-name clashes, written under a numbered name)
«Viewpoint» Class 24 unmapped 24 mapped
«Expose» Dependency 233 unmapped 15 mapped, 218 unmapped (216 expose a diagram, which is notation; 2 expose a mounted Model that is not written) — the reason is now named per row
«Conform» Generalization (not reported) 171 mapped
«View» Package 1 mapped 1 approximated
UseCase 8 unmapped 8 mapped
«HyperlinkOwner» UseCase 11 unmapped 11 mapped
Include (not reported) 23 mapped
InterfaceRealization 71 unmapped 71 approximated (each a port typed by the interface's port def)
Constraint with an Expression tree 9 unmapped 1 approximated (cp1 ** 2 + cp2 ** 2 == cp3 ** 2), 8 unmapped
Property 72 approximated 72 mapped (properties typed by a view, formerly untyped since the view was not written; now view :> …)
ElementValue 3 skipped operands of the tree above

The 8 remaining Expression-tree constraints, and 349 more now reached inside view classes, are the tool's view bookkeeping: symbol-less Expression nodes, and InstanceValue operands with no instance (606 such in the source XMI). Each is refused with that reason.

Pilot validator (validate-sysml-batch, pinned by scripts/download-pilot-sysml-validator.sh) on both outputs: 1 577 errors and 13 warnings each, and the two message lists are identical line for line once file positions are stripped. The errors are 1 440 unresolved references (requirement text), 53 A usage must be typed by definitions, 6 An action must be typed by action definitions, and 78 parse errors on OpenSysML-only state notation (defer, accept, transition); since the lists are identical, none arises from the newly written constructs.

-compare-results on both: the same 24 configurations cannot run (their runs draw at random and name no seed), the same 17 run once and reproduce the same standing tables; the only textual difference is the added view … :> …; context lines in warnings.

Checklist

  • make test and make lint pass locally
  • Tests added or updated for the change
  • Documentation extended where it already covers the surface (docs/reference/sysml-v1-migration.md)
  • Changelog entry added as changes/unreleased/migrate-views-usecases-expressions.added.md, not as an edit to CHANGELOG.md
  • baselines regenerated and make docs-counts run if a gate count moved — no gate count moved
  • No internal work-item labels in the body, docs, or changelog

devin-ai-integration Bot and others added 5 commits September 21, 2026 22:50
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ors and inclusions

A UseCase becomes a use case def whatever incidental stereotype it carries. Its
subject is the case's subject (a further one a reference usage), the actors its
associations link it to are actor usages, an Include an include use case usage,
and an Extend a dependency on the extended case since v2 has no extend; extension
points are refused explicitly.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
… views and viewpoints

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…L operators

The XMI reader adopts a uml:ElementValue a tool keeps in an xmi:Extension
block as an owned operand of the block's owner; the expression lowering
resolves it as a feature reference and reads operators spelled by name
(Plus, Equal, Power). A viewpoint's subject precedes its stakeholders, a
use case's precedes its actors, and an operation of a port def is a
referential action, as the pilot validator requires. Adds the changelog
fragment and the migration-guide rows.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review September 22, 2026 00:46
devin-ai-integration[bot]

This comment was marked as resolved.

…ge-typed subjects

A placeholder standing for an instance or element operand of a UML
Expression tree could take a name the tree itself spells, so a like-named
feature read resolved to the instance. Placeholders now avoid every word
the tree's symbols and opaque bodies spell.

A use case subject whose classifier is written as a view or viewpoint
usage was typed with ':', which is invalid for a usage; it is now subset
with ':>', as the general feature writer already does.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ressions

Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…rite root «View» packages as views

An opaque operand of a UML Expression tree is translated in its own
language through a placeholder leaf that keeps its precedence, so a Java
body keeps Java's integer division instead of being refused. An instance
classified by a «View» or «Viewpoint» is left unmapped with a reason
rather than written as an individual specializing a usage. A «View»
package that is the document root is written as a view like any other.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 2 commits September 22, 2026 14:10
… opaque tree operands

Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…subjects honest

Restrict the extension ElementValues the XMI reader adopts to operands of an
Expression, so other tool metadata stays in the extension accounting. A power
over several tree operands is written with its accumulated left side in
parentheses, since the script reads ** right to left. An Extend's unresolved
extension points are kept in its comment and note, and a use-case subject that
is a feature of another definition is refused with the reason rather than
named where it cannot resolve.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…ed name

A featured usage is accessible to its definition's members alone, but a
nested definition is a namespace member any scope can name, so the
accessibility check now applies to usage subjects only.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@HuiJun
HuiJun merged commit 93fe693 into develop Sep 22, 2026
15 checks passed
@HuiJun
HuiJun deleted the feature/migrate-views-usecases-expressions branch September 22, 2026 17:54
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