Skip to main content

Relationships

Relationships are typed references between instances. Together with fields, they make SedaroML models relational: a model is a graph of instances, not a bag of records. Relationships represent:

  • Flows — e.g. data, propellant, electrical current
  • Composition — e.g. Component A is bolted to Component B
  • Association — e.g. a Threat was launched by a ThreatLauncher

Declaring Relationships

A relationship is simply a field whose type is another ontology. The shape of the type determines cardinality:

DeclarationCardinalitySupported
battery: Batteryone-to-one, required
battery: Battery?one-to-one, optional
cells: list[BatteryCell]one-to-many (ordered)
cells: set[BatteryCell]one-to-many (unordered)
panels: (SolarPanel, SolarPanel)one-to-many (fixed arity)
source: GroundStation | Satelliteone-to-one (union target)
cells: dict[str, BatteryCell]one-to-many (keyed)

A union target (source: GroundStation | Satellite) and a keyed / "data side" dict relationship (cells: dict[str, BatteryCell]) are expressible in the language surface but are not currently supported relation types — see Current Limitations.

Because subtyping applies, a relationship targeting Actuator accepts any instance whose ontology extends Actuator.

Reverse Relationships

A relationship may declare a reverse: the name of a field on the target ontology that refers back. As the model is built, the two sides are kept consistent — setting the forward side populates the reverse side:

  • If the reverse field is a collection, the referring instance is added to it.
  • If the reverse field is scalar, it is set — and if it is already set to a different instance, the assignment is an error (no silent re-linking).

For example, Threat.threatLauncher (with reverse threats) and ThreatLauncher.threats (with reverse threatLauncher) form a consistent one-to-many pair maintained from either side.

The built-in parent/children pair that forms the composition tree is itself an ordinary reverse-linked relationship — composition is not a separate mechanism, just a distinguished relationship. Within a single agent, every instance is reachable from the agent root through the transitive closure of children, so the composition tree spans the whole agent.

Current Limitations

  • Many-to-many reverse relationships are not yet supported.
  • Union-target relationships (source: A | B) are not currently a supported relation type: RelInfo is rejected on union targets, so reverse links cannot attach to them — model the alternatives as separate fields instead.
  • Keyed (dict) relationships — the simulator's data-side relationships — are not currently available in SedaroML.