Attributes#
Role in SysML v2#
An attribute definition defines a set of data values, such as numbers, quantitative values with units, qualitative values such as text strings, or data structures of such values.
An attribute usage is a usage of an attribute definition.
Mapping to C++#
Basic attribute definitions without nested attributes are represented as structs.
Attributes with nested attributes are represented as classes.
Attribute usages typically occur within parts (and can also be package-scoped — see Packages).
Attributes can have default values and a type. If no type is given the type is mapped to an int and set to 0 as default value.
Attributes (and items) may declare multiplicity, for example attribute test : Integer[0..5];. Indexed access in actions uses #(n) where supported.
When a part specializes another, attributes can be redefined with :>> or redefines (see Parts).
Units#
An attribute value may carry a unit in square brackets. All of these notations are accepted:
private import ScalarValues::*;
private import SI::*; // needed for the unqualified spellings below
part def Measurements {
attribute qualified : Real = 2.2 [SI::W]; // qualified name
attribute plain : Real = 100 [kg]; // unqualified
attribute symbol : Real = 47 ['Ω']; // symbol, as an unrestricted name
attribute quotient : Real = 12 [km/h]; // quotient
attribute product : Real = 5 [SI::kilo*SI::metre]; // prefix times unit
}The unqualified forms (
kg,km/h,'Ω') only resolve if the unit names are in scope. Either write them qualified ([SI::kilogram]) or addprivate import SI::*;. Without that import, SysML editors and the reference implementation report the names as unresolved, even though the Sinelabore parser accepts them.
Normalization, not conversion#
Units are normalized, so different spellings of the same unit compare equal: km,
SI::km and SI::kilo*SI::metre all reduce to the same canonical form, and so do 'Ω'
and SI::ohm.
Values are not converted. The generated C++ keeps the numbers you wrote:
attribute mixedScale : Real := 5 [km] + 200 [m]; // becomes 5 + 200, not 5200Because that is easy to overlook, the generator reports it:
W3115: 'mixedScale' adds values with different units ('km' and 'm').
Units are not converted; the generated code combines the plain numbers.The warning is deliberately limited to + and -. Mixing units under * and / is ordinary
physics — electrical power is volts times amperes — so those stay quiet:
attribute power : Real := 12.0 [SI::V] * 2.5 [SI::A]; // no warning
attribute velocity : Real := 100.0 [SI::m] / 9.58 [SI::s]; // no warning
attribute sameUnit : Real := 5 [m] + 200 [m]; // no warningIf you need real unit arithmetic, scale the values in the model yourself — for example by writing both operands in the same unit.
Example#
SysML v2 source code:
private import ScalarValues::*;
package Test {
/*
* Another comment
*/
attribute def Att4{
attribute att5 : Integer default 10;
attribute att6 : Real default 7.0;
}
// comment
part def apart{
attribute att10 : String default "Hello";
attribute b:Integer default 3;
attribute att3 : Boolean;
attribute samples : Integer[0..5];
// attribute with user-defined type
attribute f:Att4;
}
}C++ source code:
namespace Test {
class Att4 {
public:
int att5;
double att6;
// Constructors
Att4(int att5Val, double att6Val) : att5(att5Val), att6(att6Val) {}
Att4() : att5(10), att6(7.0) {}
};
struct Att28 {};
class apart : public Part {
public:
apart() {}
// elements of this part
std::string att10 = "Hello";
int b = 3;
bool att3 = false;
Att4 f;
int x = 0;
virtual void process() override {}
// must be called by derived classes after constructing the parts
virtual void init(void) override {}
};