Object model

longeron.model

In-memory model of SysML v2 elements.

This is a pragmatic projection of the SysML v2 metamodel: typed dataclasses with enough structure to faithfully capture every construct of the textual notation (packages, definitions, usages, expressions, actions, states, requirements, views, metadata) while staying small. The builder maps each construct to a typed element with no lossy fallback; Unsupported remains only as a defensive dead-end that the test suite asserts is never produced.

All elements can also be constructed programmatically:

pkg = Package(name="Vehicles")
part = Definition(kind="part", name="Vehicle")
part.add(Usage(kind="attribute", name="mass", types=["Real"],
               value=FeatureValue(Literal(1500.0))))
pkg.add(part)
class longeron.model.AcceptAction(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, payload_name=None, payload_types=<factory>, trigger_kind=None, trigger=None, via=None)[source]

Bases: Element

class longeron.model.Alias(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, target='')[source]

Bases: Element

class longeron.model.AllocationUsage(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, members=<factory>, kind='allocation', direction=None, is_abstract=False, is_variation=False, is_variant=False, is_readonly=False, is_derived=False, is_ref=False, is_end=False, is_individual=False, is_parallel=False, is_negated=False, is_exhibit=False, portion_kind=None, types=<factory>, subsets=<factory>, redefines=<factory>, references=None, crosses=None, multiplicity=None, value=None, result=None, constraint_kind=None, ends=<factory>)[source]

Bases: Usage

allocate a to b / allocation al allocate a to b

class longeron.model.AssignmentAction(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, target='', expr=<factory>)[source]

Bases: Element

class longeron.model.BindingConnector(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, members=<factory>, kind='binding', direction=None, is_abstract=False, is_variation=False, is_variant=False, is_readonly=False, is_derived=False, is_ref=False, is_end=False, is_individual=False, is_parallel=False, is_negated=False, is_exhibit=False, portion_kind=None, types=<factory>, subsets=<factory>, redefines=<factory>, references=None, crosses=None, multiplicity=None, value=None, result=None, constraint_kind=None, source_end=None, target_end=None)[source]

Bases: Usage

class longeron.model.Comment(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, body='', about=<factory>, locale=None)[source]

Bases: Element

class longeron.model.ConnectionUsage(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, members=<factory>, kind='connection', direction=None, is_abstract=False, is_variation=False, is_variant=False, is_readonly=False, is_derived=False, is_ref=False, is_end=False, is_individual=False, is_parallel=False, is_negated=False, is_exhibit=False, portion_kind=None, types=<factory>, subsets=<factory>, redefines=<factory>, references=None, crosses=None, multiplicity=None, value=None, result=None, constraint_kind=None, ends=<factory>)[source]

Bases: Usage

class longeron.model.ConnectorEnd(target='', name=None, multiplicity=None)[source]

Bases: object

class longeron.model.ControlNode(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, kind='merge')[source]

Bases: Element

class longeron.model.Definition(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, members=<factory>, kind='part', is_abstract=False, is_variation=False, is_individual=False, is_parallel=False, supers=<factory>, result=None)[source]

Bases: Namespace

longeron.model.DefinitionKind

definition kind values map 1:1 to declaration keywords

alias of Literal[‘part’, ‘item’, ‘attribute’, ‘port’, ‘action’, ‘calc’, ‘constraint’, ‘requirement’, ‘concern’, ‘state’, ‘occurrence’, ‘individual’, ‘enum’, ‘connection’, ‘flow’, ‘allocation’, ‘metadata’, ‘rendering’, ‘case’, ‘analysis’, ‘verification’, ‘use_case’, ‘view’, ‘viewpoint’, ‘interface’, ‘extended’]

class longeron.model.Dependency(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, clients=<factory>, suppliers=<factory>)[source]

Bases: Element

class longeron.model.Documentation(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, body='', locale=None)[source]

Bases: Element

class longeron.model.Element(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None)[source]

Bases: object

Base class for every model element.

source_location = None

build-time SourceLocation (or None). Set as a plain instance attribute by the builder – deliberately not a dataclass field, so serialization and text round-trips stay position-free. Read by lint diagnostics.

source_file = None

the .sysml file this element was loaded from when a directory workspace was merged (longeron.workspace.load_dir() stamps its per-file models’ top-level members), or None. A plain instance attribute like source_location – deliberately not a dataclass field, so JSON exports and text round-trips stay file-agnostic. Read by longeron.export.save_workspace() (per-file save-back).

class longeron.model.ElementFilter(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, condition=<factory>)[source]

Bases: Element

filter <expr>; in packages and views.

class longeron.model.EnumerationDefinition(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, members=<factory>, kind='enum', is_abstract=False, is_variation=False, is_individual=False, is_parallel=False, supers=<factory>, result=None)[source]

Bases: Definition

class longeron.model.Expose(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, target='', is_namespace=False, is_recursive=False, filters=<factory>)[source]

Bases: Element

expose X::*; inside a view.

class longeron.model.FeatureValue(expr=<factory>, is_default=False, is_initial=False)[source]

Bases: object

class longeron.model.FlowUsage(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, members=<factory>, kind='flow', direction=None, is_abstract=False, is_variation=False, is_variant=False, is_readonly=False, is_derived=False, is_ref=False, is_end=False, is_individual=False, is_parallel=False, is_negated=False, is_exhibit=False, portion_kind=None, types=<factory>, subsets=<factory>, redefines=<factory>, references=None, crosses=None, multiplicity=None, value=None, result=None, constraint_kind=None, payload=None, source=None, target_end=None, is_succession=False)[source]

Bases: Usage

flow of Payload from a.out to b.in (also message / succession flow).

class longeron.model.ForLoop(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, var='', seq=<factory>, body=<factory>)[source]

Bases: Element

class longeron.model.IfAction(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, condition=<factory>, then_body=<factory>, else_body=None)[source]

Bases: Element

class longeron.model.Import(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, target='', is_namespace=False, is_recursive=False, is_import_all=False, filters=<factory>)[source]

Bases: Element

class longeron.model.InitialNode(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, target='')[source]

Bases: Element

class longeron.model.InterfaceUsage(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, members=<factory>, kind='interface', direction=None, is_abstract=False, is_variation=False, is_variant=False, is_readonly=False, is_derived=False, is_ref=False, is_end=False, is_individual=False, is_parallel=False, is_negated=False, is_exhibit=False, portion_kind=None, types=<factory>, subsets=<factory>, redefines=<factory>, references=None, crosses=None, multiplicity=None, value=None, result=None, constraint_kind=None, ends=<factory>)[source]

Bases: Usage

interface i : I connect a.p to b.q { ... }

class longeron.model.MetadataUsage(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, members=<factory>, typed_by='', about=<factory>)[source]

Bases: Namespace

@Safety { level = 3; } annotating usage (also metadata ...).

class longeron.model.MetadataValue(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, redefines='', value=None, nested=<factory>)[source]

Bases: Element

A body member of a metadata usage: level = 3; or :>> f = v;.

class longeron.model.Model(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, members=<factory>, source_name=None)[source]

Bases: Namespace

The root namespace of one or more parsed sources.

class longeron.model.Multiplicity(lower=None, upper=None, is_ordered=False, is_nonunique=False)[source]

Bases: object

class longeron.model.Namespace(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, members=<factory>)[source]

Bases: Element

An element that owns other elements.

find(qualified)[source]

Naive descent through owned members by ::-separated path.

Return type:

Element | None

class longeron.model.Package(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, members=<factory>, is_library=False, is_standard=False)[source]

Bases: Namespace

class longeron.model.PerformAction(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, target=None, action=None)[source]

Bases: Element

class longeron.model.SatisfyUsage(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, members=<factory>, kind='satisfy', direction=None, is_abstract=False, is_variation=False, is_variant=False, is_readonly=False, is_derived=False, is_ref=False, is_end=False, is_individual=False, is_parallel=False, is_negated=False, is_exhibit=False, portion_kind=None, types=<factory>, subsets=<factory>, redefines=<factory>, references=None, crosses=None, multiplicity=None, value=None, result=None, constraint_kind=None, is_assert=False, by=None)[source]

Bases: Usage

satisfy R by system; / assert not satisfy ...

class longeron.model.SendAction(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, payload=<factory>, via=None, to=None)[source]

Bases: Element

class longeron.model.StateAction(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, kind='entry', action=None)[source]

Bases: Element

entry ...; / do ...; / exit ...; inside a state.

class longeron.model.Succession(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, source=None, target='', guard=None, is_else=False)[source]

Bases: Element

class longeron.model.TerminateAction(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, target=None)[source]

Bases: Element

class longeron.model.TextualRepresentation(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, language='', body='')[source]

Bases: Element

class longeron.model.TransitionUsage(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, source=None, trigger=None, guard=None, effect=None, target='')[source]

Bases: Element

class longeron.model.Unsupported(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, text='', rule='')[source]

Bases: Element

A construct the builder does not model; text is verbatim source.

class longeron.model.Usage(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, members=<factory>, kind='part', direction=None, is_abstract=False, is_variation=False, is_variant=False, is_readonly=False, is_derived=False, is_ref=False, is_end=False, is_individual=False, is_parallel=False, is_negated=False, is_exhibit=False, portion_kind=None, types=<factory>, subsets=<factory>, redefines=<factory>, references=None, crosses=None, multiplicity=None, value=None, result=None, constraint_kind=None)[source]

Bases: Namespace

longeron.model.UsageKind

usage kind values; mostly declaration keywords plus a few synthetic ones (feature for keyword-less usages, enum_literal, …)

alias of Literal[‘part’, ‘item’, ‘attribute’, ‘port’, ‘ref’, ‘feature’, ‘enum’, ‘enum_literal’, ‘occurrence’, ‘individual’, ‘snapshot’, ‘timeslice’, ‘event’, ‘event_occurrence’, ‘action’, ‘calc’, ‘constraint’, ‘requirement’, ‘concern’, ‘state’, ‘case’, ‘analysis’, ‘verification’, ‘use_case’, ‘subject’, ‘actor’, ‘stakeholder’, ‘objective’, ‘connection’, ‘binding’, ‘interface’, ‘allocation’, ‘flow’, ‘message’, ‘view’, ‘viewpoint’, ‘rendering’, ‘render’, ‘satisfy’, ‘verify’, ‘frame’, ‘include’, ‘extended’]

class longeron.model.WhileLoop(name=None, short_name=None, visibility=None, metadata=<factory>, owner=None, condition=None, body=<factory>, until=None)[source]

Bases: Element

longeron.ast

Expression AST for SysML v2 / KerML owned expressions.

The model builder converts the ANTLR parse tree of ownedExpression into these compact nodes; the interpreter evaluates them and the exporters render them back to text / JSON. Qualified names are stored as tuples of (unquoted) name parts, e.g. ("ISQ", "mass") for ISQ::mass.

class longeron.ast.Expr[source]

Bases: object

Base class for all expression nodes.

class longeron.ast.Literal(value)[source]

Bases: Expr

true / 42 / 3.14 / "hi" / null / * (infinity).

class longeron.ast.FeatureRef(parts)[source]

Bases: Expr

A (possibly qualified) reference: x, engine.power, P::c.

parts are the ::-separated segments; a leading "$" denotes a root-relative reference. Feature chains written with dots inside a single reference come through ChainAccess instead when they follow a primary expression.

class longeron.ast.ChainAccess(base, parts)[source]

Bases: Expr

<primary> . a.b.c – member access on the result of an expression.

class longeron.ast.Unary(op, operand)[source]

Bases: Expr

class longeron.ast.Binary(op, left, right)[source]

Bases: Expr

class longeron.ast.Conditional(test, then, orelse)[source]

Bases: Expr

if test ? then else orelse

class longeron.ast.Classification(op, type, operand=None)[source]

Bases: Expr

x istype T / x hastype T / x @ T (operand may be implied).

class longeron.ast.Cast(type, operand=None, op='as')[source]

Bases: Expr

x as T (operand may be implied) or x meta T.

class longeron.ast.AllOf(type)[source]

Bases: Expr

all T – the extent of a type (not evaluable in this interpreter).

class longeron.ast.SequenceExpr(items)[source]

Bases: Expr

(a, b, c) – sequence construction.

class longeron.ast.IndexOp(base, index)[source]

Bases: Expr

seq#(i) – 1-based indexing.

class longeron.ast.QuantityOp(base, unit)[source]

Bases: Expr

10 [SI::m] – a value annotated with a measurement reference.

class longeron.ast.Param(name, direction=None)[source]

Bases: Expr

A parameter of a body expression, e.g. in x.

class longeron.ast.BodyExpr(params=(), lets=(), result=None)[source]

Bases: Expr

{ in x; x + 1 } – an anonymous function body.

lets are valued members declared in the body (name, expression).

class longeron.ast.Invocation(target, args=(), named=())[source]

Bases: Expr

Foo(a, b) or Foo(x = a, y = b).

class longeron.ast.Constructor(type, args=(), named=())[source]

Bases: Expr

new Foo(a, b)

class longeron.ast.ArrowOp(base, name, args=(), body=None, func=None)[source]

Bases: Expr

seq->select { in x; x > 2 } / seq->size() / seq->reduce f.

class longeron.ast.CollectOp(base, body)[source]

Bases: Expr

seq.{ in x; x * 2 }

class longeron.ast.SelectOp(base, body)[source]

Bases: Expr

seq.?{ in x; x > 2 }

class longeron.ast.MetadataAccess(target)[source]

Bases: Expr

Element.metadata

longeron.ast.expr_to_text(expr, min_prec=0)[source]

Render an expression AST back to SysML textual notation.

Return type:

str

longeron.ast.expr_to_dict(expr)[source]

Serialize an expression AST node to plain JSON-able data.

Return type:

dict[str, Any] | None

longeron.ast.expr_from_dict(data)[source]

Rebuild an expression AST from expr_to_dict() output.

Return type:

Expr | None