Ran Wei / SysML v2 Series / Module 2
中文
SysML v2 — Ran Wei

Module 2: Core Language Concepts

Namespaces, packages, import/visibility, specialisation, multiplicity, and the full feature model — the six core language mechanisms you will use in every SysML v2 model. Each is a SysML L2 realisation of a KerML L1 concept.

KerML → SysML: How Layer 1 becomes Layer 2

Module 1 introduced KerML as the semantic foundation (L1) and SysML v2 as the language layer (L2) built on top. What does that actually mean in practice? Every SysML v2 keyword is a constrained, named application of a KerML concept. The table below shows exactly which KerML construct underlies each SysML feature covered in this module.

SysML v2 concept (L2)Underlying KerML construct (L1)What SysML adds
packageNamespace (non-Type specialisation)Convention that it holds definitions only; no instance semantics
part def / partClass (a Classifier)Keyword part implies composite ownership and default multiplicity [1..1]
attribute def / attributeDataType (a Classifier)Keyword attribute implies referential, value-typed semantics
action def / actionBehavior (a Classifier)Keyword action implies occurrence-over-time semantics
port def / portPortDefinition (specialises StructureDefinition) / directed composite Feature typed by a PortDefinitionKeyword port implies boundary interaction point; conjugation (~) reverses directions
specializesSubclassification (a Relationship)Same semantics; SysML just restricts it to definition-level usage
subsetsSubsetting (a Relationship)Same semantics; SysML restricts it to usage-level features
redefinesRedefinition (a Relationship)Same semantics; SysML restricts it to usage-level features
importImport (a Namespace membership)SysML adds public/private visibility and recursive (::**) variants
Multiplicity [m..n]Multiplicity Feature on a typed elementSysML imposes default [1..1] on part/attribute/port; KerML default is [0..*]
Table 0 — SysML v2 (L2) keywords mapped to their KerML (L1) origins
NOTE

You do not need to write KerML — you write SysML v2. But knowing the KerML origin of each keyword explains why the rules are what they are. When something surprises you (e.g. why default multiplicity differs, why every Type is a Namespace), the answer is always found one layer down in KerML.

With that map in hand, the rest of this module covers each SysML v2 concept in depth, noting where KerML behaviour is inherited vs where SysML adds its own constraints.

1

Namespaces — the backbone of every model

KerML origin: Namespace (Root layer, §8.3.2.4.5)

A Namespace is an Element that contains other Elements, called its members. This is the most fundamental structural concept in KerML. Every pair of curly braces { } in the textual notation delineates a namespace boundary. SysML v2 inherits this concept unchanged — which is why part def, action def, and even individual feature bodies all act as namespaces.

💡 Key insight

In SysML v2, every Type is also a Namespace. Every part def, action def, port def, and even every feature body acts as a namespace. In SysML v1, only Packages and Models were namespaces — in v2, the concept is pervasive.

Name resolution and qualified names

Elements can carry two identifiers: a declared name (regular identifier or unrestricted name in single quotes like 'Ordinary Cargo Bay') and a short name in angle brackets (like <CB>). Qualified names use :: as separator:

1Vehicles::Powertrain::Engine

When a simple unqualified name is unambiguous within the current scope chain, use it directly. When collisions exist or the element is out of scope, use a qualified name.

KerML textual notation for bare namespaces

1namespace Outer {
2 namespace Inner {
3 // Elements here: Outer::Inner::elementName
4 }
5}
⚠️ BEGINNER PITFALL

Assuming only Packages are namespaces — because every Type is a Namespace, imports inside a definition are legal and useful. This technique avoids polluting the outer package with names relevant only to one definition:

1part def Reindeer {
2 private import Datatypes::Color; // scoped to Reindeer only
3 attribute noseColor : Color;
4}
2

Packages — grouping without semantics

KerML origin: Namespace that does not specialise Type

A Package is a Namespace, but unlike part def or action def, it does not specialise Type in KerML. This single fact explains everything: Types classify instances in the modelled universe; Packages have no instance semantics at all — they exist purely to organise the model's elements. You can nest packages freely without any implications for the type hierarchy.

1package VehicleModel {
2 import ScalarValues::*;
3 import ISQ::*;
4
5 part def Vehicle {
6 attribute mass : ISQ::MassValue;
7 part engine : Engine;
8 }
9
10 part def Engine;
11
12 package Powertrain {
13 part def Transmission;
14 part def Drivetrain;
15 }
16}

Library packages

Reusable model libraries use the library package form. Standard libraries use standard library package:

1library package CommonParts {
2 part def Fastener;
3 part def Seal;
4}
⚠️ BEGINNER PITFALL

A package must reside in a single file — there is no mechanism to re-open or extend a package across multiple source files (unlike C# partial classes). Plan your package granularity accordingly.

3

Import & Visibility

KerML origin: Import (a Membership Relationship); VisibilityKind on every Membership

In KerML, Import is a Membership Relationship that introduces elements from one namespace into another. SysML v2 inherits this unchanged and adds two constraints: a visibility annotation (public or private) that controls re-export, and a recursive form (::**) that descends into nested namespaces. Every element in a namespace carries its own VisibilityKind as well — the two are orthogonal.

SysML v2's import system therefore governs three orthogonal dimensions: which elements are imported, how they are imported, and whether they are re-exported.

Visibility kinds

Every Membership carries a VisibilityKind:

KeywordScope
public (default)Visible outside the namespace
privateVisible only inside the owning namespace
NOTE

Default visibility is public — everything you declare is visible unless you say otherwise. Best practice: declare private for implementation details.

Two import mechanisms

1// MembershipImport — single named element
2import Sensors::Accelerometer;
3
4// NamespaceImport — all public members at once
5import Sensors::*;
6
7// Private import — names do NOT re-export
8private import InternalUtils::*;
9
10// Recursive import — all nested namespaces too
11import VehicleModel::**;
12
13// Alias — create an alternative name
14alias Accel for Sensors::Accelerometer;

Public vs private import — controlling re-export

The import relationship's own visibility controls whether imported names are re-exported when this namespace is subsequently imported by others:

1package HighLevel {
2 public import Sensors::*; // names ARE re-exported
3 private import InternalUtils::*; // names stay here
4}
⚠️ COMMON PITFALL

Because both member and import visibility default to public, a chain of wildcard imports can propagate names far beyond their intended scope. Always write private import unless you explicitly intend re-export.

4

Specialisation Chains

KerML origin: Subclassification, Subsetting, Redefinition (Relationship subtypes)

SysML v2 unifies UML generalisation, subsetting, and redefinition under a single concept: Specialisation. These three relationships all exist at the KerML layer — SysML simply exposes them through the keywords specializes, subsets, and redefines, and restricts their use: specializes applies between definitions, while subsets and redefines apply between usages. Because KerML treats both classifiers and features as Types, specialisation applies uniformly across the whole model.

Four specialisation relationships

RelationshipApplies toKeywordShorthandSemantic effect
SubclassificationDefinitions ↔ Definitionsspecializes:>Subtype inherits all features
SubsettingUsages ↔ Usagessubsets:>Values form a subset
RedefinitionUsages ↔ Usagesredefines:>>Replaces inherited feature
Feature TypingUsage → Definitiontyped by:Specifies the type
Table 1 — Specialisation relationships and shorthands
💡 Context-dependent operator

The :> operator means subclassification between definitions, and subsetting between usages. The definition/usage distinction determines the meaning.

Subsetting example

1part def ReindeerTeam {
2 abstract part reindeer : Reindeer[9]; // 9 reindeer total
3 part rudolph : Reindeer subsets reindeer; // rudolph is one of the 9
4 part dasher : Reindeer subsets reindeer; // dasher is another
5}

Redefinition example

1part def Vehicle {
2 part eng : Engine;
3 attribute vendor : ScalarValues::String;
4}
5
6part def DieselVehicle specializes Vehicle {
7 part eng : DieselEngine redefines eng; // narrows type
8 attribute vendor : ScalarValues::String = "BoschMotorsport"
9 redefines vendor; // binds value
10}

Conjugation — mirror-image ports

Conjugation creates a mirror image of a type where all feature directions are reversed: inout, inout stays. The ~ prefix denotes the conjugated form — primarily used for port compatibility:

1port def FuelPort {
2 out item fuelSupply : Fuel;
3 in item fuelReturn : Fuel;
4}
5
6part def FuelTank { port tankPort : FuelPort; } // sends fuel
7part def Engine { port engFuelPort: ~FuelPort; } // receives fuel
⚠️ COMMON PITFALL

Confusing subsets with redefines. Using subsets when you intend redefines creates an additional feature alongside the inherited one — the model ends up with both the original and the new feature. Redefines replaces; subsets adds alongside.

5

Multiplicity

KerML origin: Multiplicity (a Feature — typed element carries a Multiplicity Feature as an owned child)

In KerML, Multiplicity is itself a Feature — it is not a UML-style annotation but a first-class model element owned by the typed element. This matters in two ways: multiplicity participates in the same Feature mechanisms as everything else (it can be inherited, redefined, constrained), and it allows parametric multiplicity — multiplicity expressed as a model-level expression rather than a literal integer. SysML v2 inherits this directly and additionally imposes domain-specific defaults on top of KerML's open [0..*].

Syntax and common forms

1part def Vehicle {
2 part engine : Engine; // default [1..1]
3 part wheels : Wheel[4]; // exactly 4
4 part passengers: Person[0..5]; // zero to 5
5 attribute tags : String[*]; // zero or more (= [0..*])
6 part sensors : Sensor[1..*]; // one or more
7 ref part trailer: Trailer[0..1];// optional reference
8}

Default multiplicity — critical subtlety

ContextDefault multiplicity
KerML feature (unspecified)[0..*] — no constraint
SysML part usage[1..1] — exactly one
SysML attribute usage[1..1] — exactly one
SysML port usage[1..1] — exactly one
Table 2 — Default multiplicity at KerML vs SysML layers

Ordered, unique, and collection types

KeywordsCollection type
(default)Set — unordered, unique
orderedOrdered set — ordered, unique
nonuniqueBag — unordered, allows duplicates
ordered nonuniqueSequence — ordered, allows duplicates
1part def DataCollector {
2 attribute readings : Real[*] ordered nonunique; // sequence
3 attribute deviceIds : String[1..*]; // set of IDs
4}
NOTE

In KerML, the collection type (ordered, nonunique) is encoded as properties on the Multiplicity Feature itself. SysML inherits these flags as keyword modifiers. The default (no keywords) is a set: unordered and unique — consistent with mathematical set theory.

⚠️ BEGINNER PITFALL

Multiplicity on a feature constrains values per featuring instance (e.g., each Vehicle has 4 Wheels). Multiplicity on a classifier constrains the total population across the universe. These are very different — feature-level meaning is overwhelmingly more common in practice.

6

The Feature Model

KerML origin: Feature (a Type — Core layer)

A Feature is a Type that classifies relations between things. Because Features are Types, they can own sub-features, be specialised, carry multiplicity, and participate in every Type relationship. This unification — absent in UML — is the single most consequential architectural decision in KerML. In SysML v2, every usage keyword (part, attribute, action, port) produces a Feature under the hood; the keyword just adds domain-specific constraints on top of the raw KerML Feature.

Feature direction: in, out, inout

Direction declares which way data or control flows through a feature relative to the element that owns it. It is only meaningful on features that participate in an interaction boundary — items inside a port, parameters of an action, or inputs and outputs of a function.

🏠 ANALOGY

Think of a power socket on a wall. From the building's perspective, the wall supplies power — that is out. From the appliance's perspective, it receives power — that is in. The same physical connection looks like out from one side and in from the other. This is exactly what conjugation (~) captures: it creates a mirror-image port type where every direction is reversed.

1port def PowerPort {
2 out item voltage : ElectricalPower; // this port supplies power outward
3 in item load : LoadSignal; // this port receives a load signal
4}
5
6// ~PowerPort is the conjugate — reverses all directions:
7// in item voltage : ElectricalPower (now receives power)
8// out item load : LoadSignal (now sends load signal)
9
10action def MotorControl {
11 in rpm : Real; // input: desired RPM from controller
12 in voltage : Real; // input: supply voltage
13 out torque : Real; // output: resulting torque produced
14}
NOTE

Directed features are automatically referential — no ref keyword needed. Ports themselves are never directed: do not write in port p. Direction belongs to the features inside the port definition, not to the port itself.

Composite vs reference: part vs ref part

This distinction controls ownership and lifetime. It answers: does this element exist because its parent exists, or does it exist independently of it?

🏠 ANALOGY

Composite is like the engine welded into a car: it lives and dies with the car. Reference is like the driver sitting in the car: they step out, they still exist independently.

1part def Hospital {
2 part ward : Ward[1..*]; // isComposite=true: wards owned by hospital
3 ref part doctor: Doctor[0..*]; // isComposite=false: doctor exists independently
4 attribute name : String; // DataType child: gone when Hospital is deleted
5}
6
7// Deleting the Hospital also deletes its Wards (composite ownership)
8// and its name value (DataType, no separate object). Doctors are unaffected.

Four kinds of value assignment

SysML v2 is precise about how a value is assigned, distinguishing permanent constraints from starting points, and inherited defaults from fixed values. The question each form answers:

SyntaxNameQuestion it answersCan it be overridden?
= exprBound valueWhat is this value always?No — permanent invariant, cannot change
:= exprInitial valueWhat does this value start at?Yes — can change during the instance lifetime
default = exprDefault boundWhat is the value unless a specialisation changes it?Yes — a redefining subtype can override it
default := exprDefault initialWhat does it start at unless a specialisation changes it?Yes — a redefining subtype can override it
Table 3 — Four kinds of value assignment in SysML v2
🏠 ANALOGY

A car dashboard. A bound value is like the number of wheels being permanently 4 — a structural fact that never varies. An initial value is like the fuel level starting at full when the car leaves the factory — it changes during use. A default bound is like a standard tyre pressure that all models share unless a sports variant overrides it. A default initial is like the factory seat position setting — it can be changed per driver.

1part def Engine {
2 attribute cylinders : Integer = 4; // bound: always 4, never changes
3 attribute rpm : Real := 0; // initial: starts at 0, changes at runtime
4 attribute idleRPM : Real default = 800; // default bound: 800 unless subtype overrides
5 attribute warmupTime : Real default := 30; // default initial: starts at 30s, overridable
6}
7
8part def RacingEngine specializes Engine {
9 attribute idleRPM : Real = 1200 redefines idleRPM; // overrides the default bound
10}
⚠️ COMMON PITFALL

= is a permanent invariant, not a starting point. Writing attribute rpm : Real = 0 means RPM can never deviate from zero at any point in the instance lifetime. Use := when you mean starts at this value but will change during operation.

Feature chaining — dot-notation paths

Feature chaining lets you navigate a path through nested features using dot notation. It builds a derived feature whose values are the result of following the entire chain — each step produces a set of values that becomes the input domain for the next step.

You use feature chaining in three main situations:

🏠 ANALOGY

"My cousins" is not a direct relationship — you have to follow: my parents, then their siblings, then their children. Feature chaining names exactly this kind of multi-hop path as a single reachable feature.

1// ── Derived feature using dot-notation chaining ─────────────
2part def Company {
3 part department : Department[1..*];
4 // allEmployees navigates: Company -> Department -> Employee
5 feature allEmployees : Employee[*] = department.employee;
6}
7part def Department {
8 part employee : Employee[1..*];
9}
10
11// ── Dot notation in flow statements ─────────────────────────
12// A flow cannot just say "from tank to engine" — it must name
13// the specific item endpoint nested inside each port.
14part def DriveSystem {
15 part tank : FuelTank { port fuelOut : FuelPort; }
16 part engine : Engine { port fuelIn : ~FuelPort; }
17
18 flow of Fuel from tank.fuelOut.fuelSupply // tank -> port fuelOut -> item fuelSupply
19 to engine.fuelIn.fuelSupply; // engine -> port fuelIn -> item fuelSupply
20}
21
22// ── Accessing nested attributes in a constraint ──────────────
23requirement def PowerBudget {
24 subject sys : ElectricalSystem;
25 require constraint {
26 sys.battery.voltage >= 12[V] // sys -> battery (part) -> voltage (attribute)
27 }
28}
NOTE

Dot notation in SysML v2 has precise KerML semantics: each segment of a.b.c narrows the set of values produced by the previous segment. The resulting chained feature is a real Feature in the model with its own multiplicity derived from the chain — it is not merely syntactic sugar.

7

Complete Example — Multi-package System

The following example, adapted from the official Sensmetry SysML v2 cheatsheet, demonstrates most of the concepts from this module in one cohesive model:

1package VehicleSystem {
2 private import ScalarValues::*;
3 private import ISQ::*;
4 private import SI::*;
5
6 package Definitions {
7 part def Vehicle {
8 attribute mass : ISQ::MassValue;
9 part engine : Engine;
10 part fuelTank: FuelTank;
11 port fuelPort: FuelPort;
12 }
13
14 part def Engine {
15 attribute power : ISQ::PowerValue;
16 port engineFuelPort : ~FuelPort;
17 }
18
19 port def FuelPort {
20 out item fuelSupply : Fuel;
21 in item fuelReturn : Fuel;
22 }
23
24 part def SportsCar specializes Vehicle {
25 part engine : TurboEngine redefines engine;
26 }
27
28 part def TurboEngine specializes Engine {
29 attribute boostPressure : ISQ::PressureValue;
30 }
31 }
32
33 package Instances {
34 private import Definitions::*;
35
36 part myCar : SportsCar {
37 attribute mass : ISQ::MassValue = 1400[kg] redefines mass;
38 }
39 }
40
41 package Requirements {
42 private import Definitions::*;
43 private import Instances::*;
44
45 requirement def MassLimit {
46 subject vehicle : Vehicle;
47 attribute massLimit : ISQ::MassValue;
48 require constraint { vehicle.mass <= massLimit }
49 }
50
51 requirement vehicleMassReq : MassLimit {
52 subject vehicle = myCar;
53 attribute massLimit : ISQ::MassValue = 1800[kg] redefines massLimit;
54 }
55
56 assert satisfy vehicleMassReq by myCar;
57 }
58}

This model demonstrates: packages and nesting, private wildcard imports, subclassification (specializes), redefinition (redefines), port definitions with directed features, conjugation (~), feature chaining, constraints, requirements, and the definition/usage pattern.

8

Module Summary

SysML v2 conceptKerML originKey rule
packageNamespace (does not specialise Type)No instance semantics; organises the model only
importImport (a Membership Relationship)Default is public; use private import unless you intend re-export
Visibility (public/private)VisibilityKind on every MembershipApplies to both members and imports independently
specializesSubclassification RelationshipBetween definitions only; subtype inherits all features
subsetsSubsetting RelationshipBetween usages; adds a named subset alongside the inherited feature
redefinesRedefinition RelationshipBetween usages; replaces the inherited feature entirely
Conjugation (~T)KerML Conjugation RelationshipReverses all directions on Features within the type
Multiplicity [m..n]Multiplicity Feature (owned child)KerML default: [0..*]; SysML part/attribute/port: [1..1]
ordered / nonuniqueProperties on Multiplicity FeatureEncode set/bag/sequence/ordered-set collection type
Feature direction (in/out/inout)Direction property on FeatureOnly meaningful at interaction boundaries (ports, actions)
Feature chaining (dot notation)FeatureChaining RelationshipMulti-hop dot-notation path (e.g., a.b.c) builds a derived Feature with multiplicity from the chain
Table — Module 2 concepts and their KerML origins
Up Next

Module 3 — Structure Modelling — Parts, items, attributes, and decomposition: building complete structural models with SysML v2.