Appendix B: Migration from SysML v1
If you have existing SysML v1 models, this appendix maps the v1 concepts to their v2 equivalents and provides a practical migration approach.
Concept Mapping
SysML v2 replaces SysML v1’s diagram-centric approach with a textual, element-centric model. Many v1 concepts have direct v2 equivalents, but the framing is different.
Structural Concepts
| SysML v1 | SysML v2 | Notes |
|---|---|---|
| Block | part def | Blocks become part definitions. The keyword changed, but the intent is the same. |
| Block property | part usage | A property typed by a Block becomes a typed part usage. |
| Value Type | attribute def | Value types become attribute definitions. |
| Value Property | attribute usage | Properties typed by a value type become attribute usages. |
| Flow Port | port def / port | Flow ports become port definitions with directional items. |
| Full Port | port def / port | Full ports become port definitions. The in/out direction model is more explicit. |
| Item Flow | flow on connection | Item flows are now part of connection modeling. |
| Internal Block Diagram | Composite structure in part def | No separate diagram type – structure is expressed inline. |
| Block Definition Diagram | part def declarations | Definitions are written directly in text. |
Behavioral Concepts
| SysML v1 | SysML v2 | Notes |
|---|---|---|
| Activity | action def | Activities become action definitions. |
| Activity Partition | Ownership or allocation | Partitions become structural ownership or explicit allocations. |
| State Machine | state def with state usages | State machines are modeled as state definitions with transitions. |
| State | state def / state | States become state definitions (reusable) or state usages (in context). |
| Transition | transition ... from ... to ... | Transitions name source, target, guard, and trigger explicitly. |
| Signal | item def | Signals become item definitions that flow through ports. |
Requirements and Traceability
| SysML v1 | SysML v2 | Notes |
|---|---|---|
| Requirement | requirement def | Requirements become first-class model elements with doc text. |
| Satisfy relationship | satisfy | Direct equivalent. Applied inside the satisfying element. |
| Verify relationship | verify inside verification def | Verification cases explicitly link to requirements. |
| Derive relationship | Specialization (:>) | Derived requirements specialize their parent. |
| Copy relationship | No direct equivalent | Use specialization or imports instead. |
| Requirement Diagram | Package with requirements | No separate diagram – requirements live in packages. |
Organizational Concepts
| SysML v1 | SysML v2 | Notes |
|---|---|---|
| Package | package | Direct equivalent. |
| Model | Top-level package | No separate Model element. Packages serve the same role. |
| Profile | metadata def | Profiles become metadata definitions applied with @. |
| Stereotype | metadata def | Stereotypes become metadata definitions. |
| Tagged Value | attribute in metadata def | Tagged values become attributes on metadata definitions. |
| View | view / viewpoint def | Views and viewpoints are now explicit model elements. |
Semantic Caveats
The mapping tables above are one-to-one enough to be useful, but three of the mappings hide a change in meaning. These are the ones teams get wrong.
A v1 Block splits into two concepts
In v1 a Block played two roles with no syntactic distinction. On a BDD it stood for a classifier – a reusable type. On an IBD it appeared as a property – an occurrence of another Block owned by a parent. Tools inferred the role from context.
v2 makes the distinction mandatory and syntactic. Every v1 Block becomes one of:
part defif it was used as a type – something instantiated more than once, referenced from elsewhere, or specialized.- a
partusage (nodef) if it was used as a slot – one occurrence inside one owning definition.
So a v1 Block: CoffeeMachine with part properties brewer : Brewer and grinder : Grinder becomes two kinds of element:
part def Brewer { }
part def Grinder { }
part def CoffeeMachine {
part brewer : Brewer;
part grinder : Grinder;
}
Brewer and Grinder are definitions; brewer and grinder are usages of them. The test when you are unsure: can this element be typed by, specialized by, or referenced from somewhere else? If yes, it needs def.
FlowPort direction becomes conjugation
A v1 FlowPort carried direction as a flag – in, out, or inout – and you matched an out port to an in port when connecting.
v2 uses conjugation instead. You write one port def from one side’s perspective and take its conjugate with ~, which reverses every flow direction inside it. Two ports are connector-compatible when one is the conjugate of the other:
port def WaterOutlet {
out item water : Water;
}
part def WaterTank {
port supply : WaterOutlet; // supplies water
}
part def Brewer {
port inlet : ~WaterOutlet; // receives water (conjugate)
}
out item water becomes in item water in ~WaterOutlet. You did not write a second port def; the language derived it.
For migration: for every pair of v1 FlowPorts you used to connect, write one port def and apply ~ at the other end. Writing symmetric WaterInlet/WaterOutlet pairs is the v1 pattern translated literally, not the v2 idiom.
Stereotypes become first-class metadata
In v1, extending the language meant a UML Profile: a Profile package holding Stereotype elements that extended base metaclasses, applied through ProfileApplication, with tagged values as owned Property elements. It worked, but profiles coupled models together, tagged values were stringly-typed in practice, and cross-tool compatibility was uneven.
v2 replaces the whole mechanism with metadata def – an ordinary element declared in a package alongside part def, carrying typed attributes, applied with @. No profile file, no ProfileApplication, no metaclass extension:
metadata def Safety {
attribute level : String;
attribute standard : String;
}
@Safety { :>> level = "SIL-2"; :>> standard = "IEC-61508"; }
part def Brewer {
attribute waterTemp : Real;
}
Three consequences. The annotations live in your package structure, so they import, specialize, and query like anything else. The attributes are strongly typed – including quantity types from ISQ – where v1 tagged values defaulted to String even when a number was meant. And :>> is just the redefinition syntax you already use everywhere else; there is no separate tagged-value syntax.
One thing metadata does not do, which profiles attempted: it does not extend the metamodel. Stacking @ annotations adds independent annotations to an element; it does not create new kinds of element or new structural relationships. If you wrote profiles to introduce constructs that behaved like SysML built-ins, those have to be re-expressed with standard v2 mechanisms.
Diagram Types to Constructs
v1 divided modeling across nine diagram types, each a separate artifact with its own notation. v2 has no diagram types – the model is one textual artifact – but the concerns each diagram addressed still exist as language constructs. This table maps the concern; the view-preset table further down maps how you would render it.
| v1 diagram type | Abbr. | v2 constructs covering the same concern |
|---|---|---|
| Block Definition Diagram | BDD | part def, attribute, port def, interface def, item def, connection def at package scope |
| Internal Block Diagram | IBD | part usages, connect, flow, port usages inside a part def body |
| Requirement Diagram | REQ | requirement def, requirement usages, satisfy, verify, nested decomposition; refinement is expressed by specialization (:>), not a refine keyword |
| Activity Diagram | ACT | action def, action usages, first/then successions, flow, fork, join, decide, merge, send, accept |
| State Machine Diagram | STM | state def, state usages, transition, accept, if guard, do effect, entry/do/exit sub-actions, exhibit state |
| Parametric Diagram | PAR | constraint def, constraint usages, assume constraint, require constraint |
| Sequence Diagram | SD | message usages plus successions between action performers. Partial: message is real surface syntax but produces a FlowUsage – there is no Message metaclass and no interaction def form (see Appendix G) |
| Use Case Diagram | UC | use case def, use case usages, actor, subject, include use case |
| Package Diagram | PKG | package, import, alias; public / private visibility |
What replaces the BDD/IBD boundary
The BDD/IBD split was the most operationally significant boundary in v1: the BDD defined types, the IBD defined the internal architecture of one Block. In v2 both live in one part def body:
part def CoffeeMachine {
// BDD-style: typed part usages naming sub-components
part grinder : Grinder;
part brewer : Brewer;
part waterTank : WaterTank;
// IBD-style: connectivity between those parts' ports
connect waterTank.waterOut to brewer.waterInlet;
flow of Water from waterTank.waterOut to brewer.waterInlet;
}
No file boundary, no diagram boundary, and no synchronization problem between the two.
What replaces the REQ diagram
A v1 Requirements Diagram showed Requirement-stereotyped Classes, containment decomposition, DeriveReqt arrows, and satisfy/verify dependencies. These become body members and relationships on requirement def:
requirement def BrewSafetyReqs {
doc /* The brewer shall not operate unsafely. */
subject machine : CoffeeMachine;
// nested decomposition (v1 containment)
requirement temperatureReq : WaterTemperatureReq;
requirement cupReq : CupPresenceReq;
}
// v1 satisfy dependency -> v2 satisfy
part myCoffeeMachine : CoffeeMachine {
satisfy requirement : BrewSafetyReqs;
}
Note the : in satisfy requirement : BrewSafetyReqs. The name slot after requirement declares a requirement usage; the type annotation is what binds it to BrewSafetyReqs. Writing satisfy requirement BrewSafetyReqs; parses, but it declares an untyped usage that happens to share the name and links to nothing.
What replaces the PAR diagram
A v1 Parametric Diagram showed ConstraintBlock instances with parameters wired together by binding connectors. In v2 the constraint usage and its bindings are written inline:
constraint def TemperatureInRange {
in attribute temp : Real;
in attribute minTemp : Real;
in attribute maxTemp : Real;
constraint { temp >= minTemp and temp <= maxTemp }
}
part def Brewer {
attribute waterTemp : Real;
constraint brewTempOk : TemperatureInRange {
:>> temp = waterTemp;
:>> minTemp = 90.0;
:>> maxTemp = 96.0;
}
}
The v1 binding connectors become :>> redefinitions on the constraint usage. Same structure, inline text.
Migration Strategy
Migration works best in phases. Do not try to convert everything at once.
Phase 1: Structure First
Start with your block definitions and their properties. Convert blocks to part def, value types to attribute def, and block properties to typed usages. This gives you a structural baseline in v2 that you can check immediately.
// v1: Block "Grinder" with value property "grindSize: Real"
// v2:
part def Grinder {
attribute grindSize : Real;
}
Phase 2: Requirements and Traceability
Migrate your requirements next. Convert each v1 requirement into a requirement def with a short ID and doc text. Add satisfy links to the structural elements from Phase 1.
requirement def <'REQ-001'> BrewTempReq {
doc /* Extraction temperature shall remain between 90 and 96 C. */
}
part def CoffeeMachine {
satisfy requirement : BrewTempReq;
}
This gives you traceable requirements early, before you tackle behavior.
Phase 3: Behavior
Convert activities to action def and state machines to state def. The biggest change is that v2 uses textual control flow (first...then, fork, join, decide, merge) instead of diagram-based arrows. Guards and triggers on transitions are now written inline.
Phase 4: Governance and Views
Add metadata definitions to replace profiles and stereotypes. Create viewpoints and views to replace v1’s diagram-based stakeholder communication.
The v1 diagram zoo collapses to a small set of v2 view definitions, often combined with a sysml-rs-supplied preset (in parentheses):
| v1 Diagram | v2 View Definition |
|---|---|
| Block Definition Diagram | GeneralView with a definition/usage filter (BDD preset) |
| Internal Block Diagram | InterconnectionView (IBD preset) |
| Parametric Diagram | InterconnectionView + binding overlay (Parametric preset) |
| Activity Diagram | ActionFlowView |
| State Machine Diagram | StateTransitionView |
| Sequence Diagram | SequenceView |
| Use Case Diagram | GeneralView with a use-case filter (no standard UseCaseView exists) |
| Requirement Diagram | GeneralView with a requirement-metaclass filter |
| Package Diagram | BrowserView (or Package preset) |
The eight standard view definitions (GeneralView, InterconnectionView, ActionFlowView, StateTransitionView, SequenceView, GeometryView, GridView, BrowserView) are spec, defined in the standard library package StandardViewDefinitions; the parenthesised preset names are sysml-rs’s preset registry. There is no standard use-case or requirement view definition – both are written as GeneralView specializations with a filter, which is the recipe the library’s own GeneralView documentation prescribes. Either form is enough to replace the v1 diagram. See Chapter 13.
Key Mindset Shifts
From diagrams to text. In v1, the diagram was the primary artifact. In v2, the text is the source of truth and diagrams are generated views. This changes your workflow: you edit text files, review diffs, and run checks – not drag boxes on a canvas.
From implicit to explicit. v1 often relied on diagram layout to convey meaning. v2 makes everything explicit in text: ownership, direction, typing, sequencing. This feels verbose at first but pays off in reviewability and automation.
From copy to reuse. v1 models often duplicated similar blocks across diagrams. v2’s definition/usage pattern makes reuse natural: define once, use everywhere. Resist the urge to copy-paste definitions.
From monolithic to modular. v1 models often lived in one large project file. v2 models naturally split across files and packages, with imports making dependencies visible. Plan your package structure early.
Common Migration Pitfalls
Direct syntax translation without cleanup. Migration is an opportunity to improve model quality. Do not just translate v1 ambiguity into v2 ambiguity – tighten definitions, add types, and make traceability explicit.
Postponing verification links. In v1, verification was often managed outside the model. In v2, verification cases are model elements. Add them during migration, not after.
Mixing conventions. If part of your team uses v1 habits (untyped usages, missing imports) while another part uses v2 patterns, the model becomes inconsistent. Set v2 conventions early and enforce them in review.