feat(migrate): map calls to the fUML and Alf library primitives to the v2 library - #487
Open
devin-ai-integration[bot] wants to merge 9 commits into
Conversation
RefIDs keeps an href as written even once the model bundles a copy of the document it names and the reference resolves to that copy, so a reader can tell which document an element came from. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…e v2 library A CallBehaviorAction whose behavior is an element of fUML_Library.xmi or Alf-Library.xmi is known by the library document its href names and the fragment within it, whatever the date segment of the URI, never by the behavior's bare name. The call is written with its pins, and each result pin takes the v2 library expression over the argument pins, so the flows out of it carry the computed value. Every behavior of both documents is inventoried: mapped, approximated with the semantic difference in the note, or refused with the reason. A scalar parameter the call passes nothing for, or whose pin nothing valued feeds, starves the call as in v1. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Contributor
Author
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
…gicDraw modules A CallBehaviorAction whose behavior href points into the library's own module (fUML-Library.mdzip, Alf-Library.mdzip) is a primitive when its target — the bundled copy the href resolves to, or the referentPath MagicDraw records beside the href — sits under the library's root package, family and name. Both are required, so a package of the model's own named fUML_Library stays its own. Each call's note says which provenance identified it: the OMG href, the bundled copy, or the referentPath. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Add the ListFunctions behavior fUML 1.5 Table 9.7 lists but the 2018 library document omits, with runtime coverage of the fUML list functions, and state in the reference the trusted-module-name boundary of bundled library recognition and that pins bind by position, unchecked against the primitive's signature. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…rimitive-behaviors Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # internal/translate/migrate/arguments.go
…L/Alf primitive mappings Unions the golden construct fixtures from both lines. The PSSM suite ratchet now records the library calls this branch computes: 580 CallBehaviorActions on fUML/Alf primitives (Including, Concat, ToString, Size, Not, lt, ...) leave unmapped for mapped or approximated, the 68 object flows feeding them are written again, and four trace calls whose segment argument those primitives compute are performed instead of carried as inert placeholders. Validation errors stay at 21. Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration
Bot
changed the base branch from
develop
to
feature/composite-state-connection-points
September 21, 2026 15:44
…cannot write A value pin holding an unlimited natural * or a non-finite real was taken as supplied, so the call was written live over a pin whose initializer was dropped and failed at run time. The call is now a placeholder with the value and the reason in its note. Co-Authored-By: jason.han <hanhuijun@gmail.com>
A value pin whose expression names a sibling pin was judged unwritable before the pins had names, so the call was deadened. The pins are settled first, as the writer does, so the value reads them. Co-Authored-By: jason.han <hanhuijun@gmail.com>
This branch has not been deployed
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.
What and why
sysml model.xmi -convert sysmlrefused everyCallBehaviorActionwhose behavior is a primitive of the fUML library (http://www.omg.org/spec/FUML/<date>/fUML_Library.xmi) or the Alf library (http://www.omg.org/spec/ALF/<date>/Alf-Library.xmi) as "a behavior with no v2 declaration", and the flows out of them then carried nothing, so any migrated activity that builds a string or a list was inert. On the OMG PSSM suite that was 586 refused calls (398Including, 104Concat, 18 IntegerToString, 13 BooleanToString, 9plus, 9Size, 5lt, 5WriteLine, …).The migrator now maps these calls to the SysML v2 / KerML standard library:
primitiveAt(href)keys on the library document the href names (FUML/<any date>/fUML_Library.xmi,ALF/<any date>/Alf-Library.xmi,httporhttps, hostwww.omg.org) and the exact fragment within it. A model's ownConcatis an ordinary call. Nothing is loaded from the network or the file system.sysmlv1.Element.RefIDs(new, the raw ids a role refers to) keeps an href as written even once the model bundles a copy of the library and the reference resolves to that copy.migration.primitiveCalledmaps by that href; the copy's element is still what the pins' types are read from.fUML-Library.mdzip#_jJIy…, and beside it MagicDraw recordsreferentPath="fUML_Library::PrimitiveBehaviors::ListFunctions::ListSize" referentType="FunctionBehavior"; the bundled snapshot is auml:Package fUML_Library→PrimitiveBehaviors→ListFunctions→uml:FunctionBehavior ListSizewith the OMG structure and different ids.primitiveNamedrecognizes such a call by the library's identity, and needs both halves: the href's document must be the library's own (fUML-Library/fUML_Library,Alf-Library, whatever the extension or path —libraryIdentities), and the behavior it resolves to — the bundled copy when the module's contents are in the archive, else thereferentPath— must be a behavior sitting under the library's own root package, family and name (fUML_Library::orFoundationalModelLibrary::for fUML;Alf::Library::for Alf, which is whatAlf-Library.xmi's root model and package are called), keyed into the sameprimitivestable by path (primitivePaths, the second index over the one table). A package of the model's own that happens to be calledfUML_Library, or areferentPathnaming the library beside an href into some other module, matches neither and stays what it is. Each report entry says which provenance identified the call: "known by its OMG href …", "known by the copy of the library the model bundles as fUML-Library.mdzip, which its href resolves to", or "known by the referentPath … recorded beside its href into the library module fUML-Library.mdzip".activity.callPrimitivewrites the call through the existing pin writer: the action with its pins, each result pin valued by the v2 expression over the argument pins in v1 order (out result : ScalarValues::String = StringFunctions::'+'(x, y);,out result[0..*] ordered nonunique = SequenceFunctions::including(seq, element);). The expression is a side table (activity.computed) consulted bydeclarePins;producesAtreports the result pins as producing, so the existing flow/starvation analysis carries the values on. Pin declarations now also carryordered/nonuniquefrom the pin, which the value's sequence type needs.primitiveRefusalruns before the "no v2 declaration" check. A behavior the v2 library has no equivalent for isUnmappedwith the reason. A scalar parameter the call passes no pin for, or whose pin only flows from something producing no value (valueless), or that admits none and nothing fills (holdsNone), starves the call as in v1 (as in fUML, where an action does not fire until every input pin holds the values its lower bound requires) — the action is written empty and carries the token,Approximatedwith the exact reason. Sequence parameters fire on nothing (the empty sequence).primitives.goholds every behavior of both documents — the 58 offUML_Library.xmi(Integer, Real, UnlimitedNatural, Boolean, String, List functions andBasicInputOutput) plusListConcat, which fUML 1.5 Table 9.7 lists but the 2018 document omits, and the 82 ofAlf-Library.xmi(BitString, Sequence and Collection functions) — as data: library, family, fragment, v1 parameter names and order, whether each must hold a value, one v2 expression template per result (with$nnaming the v1 argument, so permutations such asIncludingAt(seq, index, element)→includingAt($1, $3, $2)are explicit), verdict and note.TestPrimitivesCoverBothLibrariespins the inventory against the two documents' parameter lists.Verdict summary (the full table is in
docs/reference/sysml-v1-migration.md, "Calls to the fUML and Alf libraries"):Neg Abs + - * Max Min < > <= >= ToString/ Div Mod(v2 fails on a 0 divisor, v1 gives no result),ToUnlimitedNatural(negative),ToInteger(non-numeric text)Neg Abs Floor Round + - * Max Min < > <= >= ToIntegerInv /(0),ToReal(text),ToString(v2 writes the shortest round-trip text, v1 leaves the format open)Naturalhas no*, bounded values behave as in v1Or Xor And Implies Not ToString(true/false)ToBoolean(v1 readsTRUE, v2 onlytrue)Concat SizeSubstring(bounds outside1..Size)ListSize ListConcatListGet(index outside1..ListSize)WriteLine ReadLine(v2 has no console)ToNatural(v2 reads decimal text only, not0b/0o/0x)BitString)Size Includes Excludes Count IsEmpty NotEmpty IncludesAll ExcludesAll Equals First Last Union Intersection Difference Including ExcludingAt IncludeAt InsertAt IncludeAllAt ExcludeAt ReplacingAt Subsequence(v2 fails on an index outside the sequence where v1 gives no result or the sequence unchanged)IndexOf ExcludingOne Replacing ReplacingOne ToOrderedSet(no v2 function for the first occurrence, for replacement, or for de-duplication)size includes excludes count isEmpty notEmpty includesAll excludesAll equals first last union intersection difference including excluding clearadd addAll addAt addAllAt remove removeAll removeAt replaceAt(the inout parameter and the result are one value in v2)indexOf excludingOne replacing replacingOne toOrderedSet removeOne replace replaceOneSpecification basis
fUML 1.5 §9.3 (the primitive behaviors), §9.4 (basic input and output); Alf 1.1 §11.4 (primitive behaviors), §11.6 (collection functions) and Annex B; the fUML execution model (an action fires once every input pin holds the values its lower bound requires). No row of
docs/project/spec-compliance.mdmoves: the record does not cover v1 migration.How it was verified
New fixture
tests/migrate/testdata/xmi/library_calls.xmi(hand-written, where the other construct fixtures live) chains IntegerToString→Concat→Including→Including→Size, plus BooleanToString, a refusedIndexOf, a refusedWriteLine, and a call fed by the refused one; golden.sysmland.report.txt.tests/migrate/library_test.goruns the migrated model through the REPL session runtime (the precedentrunActionhelpers of the package) and asserts"42","n=42",["n=42"],["n=42", "n=42"],2,"true", and that the refused call's result and the starved call's input stay empty; it also pins Boolean/Integer/RealToStringformatting,Concatwith a missing pin, an unfed pin and an optional pin, href matching (any date,https, exact fragment, no bare names), a bundled copy of the library, and extra pins.tests/migrate/library_sequences_test.goexecutes every mapped Alf Sequence and Collection function and every fUML primitive on generated fixtures and asserts the results, duplicates included.internal/translate/migrate/primitives_internal_test.gopins the inventory against both library documents' parameter lists, the href recognizer, and the result templates.Two more fixtures, in the MagicDraw form:
bundled_library.xmi(exporterMagicDraw UML; a bundledfUML_Library::PrimitiveBehaviors::…package whoseFunctionBehaviors the hrefsfUML-Library.mdzip#…resolve to, plus hrefs into the same module that resolve to nothing but theirreferentPath) chainsToString→Concat→ListSize/ListGetand a refusedWriteLine;TestBundledLibraryCallsAreKnownByIdentityexecutes it ("3","n=3",1,"n=3"), checks each provenance note, and that the bundled library package is not written into the user's output.user_library.xmiis the negative: a user package namedfUML_Library::PrimitiveBehaviors::ListFunctionswith its ownListSizeactivity, and aListGetwhose href goes intoHelpers.mdzipwith areferentPathnaming the library;TestUserPackageNamedLikeTheLibraryIsNotItpins that the first stays an ordinaryaction size : fUML_Library::…::ListSize, the second stays "has no v2 declaration", and noSequenceFunctions::expression or provenance note appears.TestPrimitiveNamedcovers the lookup directly: fUML and Alf by bundled copy and byreferentPath, both fUML roots, case, a missing family, a non-behavior target, a wrong document, the fUML path under the Alf document, a same-named user package, and an unresolved target.Gates, all green on this branch:
PSSM suite (
./scripts/download-pssm-suite.sh)Migration report,
develop→ this branch (47303 elements both):has no v2 declaration: 627 → 41; the 41 left are allCommentnotes ("annotates 'S1', which has no v2 declaration in the document"), none a call. Every one of the 586 library calls moved; by id:CallBehaviorActionunmapped → approximated: 398 for reasons that already applied to other calls (fan-out through a fork, fan-in through a join, a sibling of the same name), 105Includingwhoseelementpin is fed by an activity-level fork that the migrator already did not trace ("nothing the flow carries comes from a pin or parameter", unchanged), 6Concat/ToStringinUtil::Tracing::formatParameterValuestarved by an unmapped upstream cast, 1 UnlimitedNaturalToString(*), 1ToUnlimitedNatural.CallBehaviorActionunmapped → mapped: Integer/BooleanToString,Size,IsEmpty,NotEmptywith values on all pins.ObjectFlowapproximated → mapped: the result flows of the calls, which now carry a value.InputPinmapped → approximated and 2ObjectFlowapproximated → unmapped (Event::019,Standalone::003):call('trace')was a starved placeholder with every pin declared, so the flow carryingthisto itstargetpin was written; the call is now live and written asaction x : Owner::Opin the caller's context, whose existing rule leaves the target pin unwritten and reports the flow.SendSignalActionapproximated → mapped (Util::Architecture::SemanticTestSuite): its target isCall('At')'s result, which now carries a value.WriteLine("no v2 library function: v2 has no console"), 1 BitStringToInteger.Not achieved, on
developas well as here:bin/sysml build/pssm/PSSM_TestSuite.xmi -convert sysml -migration-report … -o …stops before writing either file with12343:41: expected the target of the transition after 'then'— the state writer emitstransition 'T1.2' first 'S1.1' do action effect; then done;for an empty transition effect, which the parser rejects; that writer is fixed separately in #485 and this PR does not touchstates.go. The reports above were produced throughmigrate.Migratedirectly.bin/sysml <out> -validateon both outputs reports that same one syntax error each; with that line removed by hand, both report the same set of unresolved-member and junction diagnostics (no difference between develop and this branch).Behavior 001 execution: the migrated
Util::Tracing::TraceBuilder::addSegmentnow computes itsConcat/Including/Size/IsEmptycalls, but its trace still cannot be produced, for three reasons that predate this PR and are outside the library-call path:Util::Architecture::Target::tracereadstraceBuilderthrough aReadSelfActioninside an Alf-compiledBodyand is refused ("the object read, this, is a …::Body, which has no feature traceBuilder"); theTargetconstructor'sCreateObjectAction 'Create(TraceBuilder)'is refused, sotraceBuilderis never assigned; and%instantiateof any PSSMTargetdoes not terminate, because the constructor patternaction target : Target;(an action usage whoseout returnis typed by the enclosing part def) recurses on instantiation — with those four usages removed from a copy the model instantiates in 0.1 s, entersS1, acceptsStart, andT2then fails atread(traceBuilder): uninitialized feature value. Each is reproducible ondevelop's output.TMT model
On the OMG-href-only head (
9b0a70603) the model was unaffected: the.sysmlbyte-identical todevelop's,-validateno errors, counts unchanged at 28,626 / 10,319 / 5,191 mapped / approximated / unmapped, and three refusals left —the behavior fUML_Library::PrimitiveBehaviors::ListFunctions::ListSize/ListGetit calls has no v2 declaration— because Cameo references the library as a used project (fUML-Library.mdzip#…with areferentPath), never by the OMG URI.With recognition by library identity (
761e053fd, TMT-2024x): 44,136 entries, 28,633 / 10,315 / 5,188 mapped / approximated / unmapped,-validate0 errors. All three bundledListSize/ListGetcalls now writeSequenceFunctions::size(…)/SequenceFunctions::'#'(…)with their flows and binds restored, and their report notes read "known by the referentPath … recorded beside its href into the library module fUML-Library.mdzip"; nothing else in the model moved. The command:Checklist
make testandmake lintpass locallychanges/unreleased/<slug>.<section>.md, not as an edit toCHANGELOG.mdmake docs-countsrun if a gate count moved (none moved)F4,K5) in the body, docs, or changelog