Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

level-2 physical realization

This notebook introduces HeatGenerationReq, the requirement a heat generator’s rating is checked against, and ResistanceCoil, the concrete mechanism selected and built to satisfy it; after running it you can see a requirement stated on an abstract carrier, a mechanism selected for a real, recorded reason, and a physical part realizing that selection, checked on two real candidates.

The previous notebook left HeatGenerator abstract: a function, a port, and an unbound performance slot, with no mechanism chosen. This notebook states the requirement that slot is checked against first, then chooses and builds the mechanism that realizes it, in that order: the selection is argued from a stated engineering premise, not read off the name of a part built before the argument for it exists.

requirement def HeatGenerationReq {
    subject heatGen : HeatGenerator;
    require constraint { heatGen.power >= 600.0 [SI::W] }
}
requirement heatGenerationReq : HeatGenerationReq;

HeatGenerationReq’s subject is HeatGenerator, the abstract carrier, not any concrete realization: any realization of the carrier is checked against the same threshold, the design-space form a logical requirement takes. Its 600 W bound is not yet derived from any stated measure of effectiveness: no supply and no coil exist together in this model to derive it from. What kind of measure this threshold states is recorded next, as AC-C06.

The cumulative model, loaded here so the judgment records below can cite real analysis directly instead of the model’s own declaration. The next cells record AC-C06, following the construction zone Hawkins’ taxonomy uses (anchor, claim, frame, premises, evidence, challenge, assemble).

Before AC-C06 states its claim, the next cells give it a real anchor in the model: a ReviewRecordRef tag naming heatGenerationReq as what AC-C06 is about.

metadata acC06Tag : ReviewRecordRef about heatGenerationReq {
    identifier = "AC-C06";
}

This fragment is the same text now committed in models/ch06-cumulative.sysml onward, alongside the ReviewRecordRef definition (carried forward since Chapter 2); loading the cumulative model (the model.ok cell above, unchanged) is what makes this a real, checkable tag rather than an assertion the reader has to trust. AC-C06 states the claim next: what heatGenerationReq is being framed as.

heatGenerationReq (HeatGenerationReq) is framed as a measure of performance: an engineering rating on a chosen component, not a direct measure of the user's acceptance of the toast.

The standard this framing is checked against, the same one Chapter 3’s AC-C03 used for toast timing.

MoE if the split names who cares and frames the measure as acceptance; MoP if its threshold is derived from a stated MoE with a means of checking (SEBoK's MoE/MoP distinction, PDF 1562).

What the framing takes as given.

['The MoE/MoP split for a component rating is a case-specific modeling judgment, not a fixed rule (AC-C03 makes the same split for toast timing).']

What supports the claim, and the argument connecting it.

HeatGenerationReq's rationale argues from a component's own rating, not from what a user notices about the toast: it names no one who would reject a toaster on this figure alone, and a heat generator rated below 600 W could still make acceptable toast more slowly. Framing it as a MoP is honest about who cares (the engineer sizing a component) and what the threshold characterizes (a rating), not the user's acceptance.

The challenge: what stays open about this framing, and about the threshold itself.

A user might notice a heat generator so weak that toasting takes too long, which links this rating back to timely (Chapter 3) indirectly. The link is not modeled: no relation connects power, resistance and cycle time yet, so treating power as purely engineering-internal is a simplification.
The 600 W threshold is not derived from timely or from any stated measure of effectiveness through the energy relation: no supply and no coil exist together in this model to derive it from. It is recorded as a free-standing engineering figure, honestly, not a fixed rule for every future chapter.

With every part named above, the framing record assembles from them directly.

Model tag: {'tag': 'ToasterDemo::acC06Tag', 'identifier': 'AC-C06', 'annotated_element': 'ToasterDemo::heatGenerationReq'}
Validation errors: []

The tag printed above is now part of the loaded model, and validate_record confirms the Python record and the model’s own tag agree about what AC-C06 is actually about, with no errors reported. With the requirement framed, the next cells record which mechanism is chosen to satisfy it, and why. GenerateHeat and HeatGenerator commit to no energy form or mechanism (notebook 01): the selection below is what actually chooses one, not a fact already built into either of them.

ControlSystem: partDef, durationOut: portUsage

ControlSystem really does declare durationOut, a discrete duration signal (Chapter 5), confirmed directly rather than assumed. The selection below cites this fact alongside a domain premise about how the two mechanisms work; it does not argue from energyIn already being electrical, since it is not, until this record commits it.

Before AS-C06 states its claim, the next cells give it a real anchor in the model: a ReviewRecordRef tag naming ResistanceCoil as what AS-C06 is about.

metadata asC06Tag : ReviewRecordRef about ResistanceCoil {
    identifier = "AS-C06";
}

This fragment is the same text now committed in models/ch06-cumulative.sysml onward, alongside the ReviewRecordRef definition and acC06Tag (above); loading the cumulative model (the model.ok cell above, unchanged) is what makes this a real, checkable tag rather than an assertion the reader has to trust. AS-C06 states the claim next: which mechanism is selected, and over what alternative.

ResistanceCoil, an electrically switched resistive element that converts energy to heat by Joule heating, is selected over a combustion-based alternative (a gas burner, the tongs-and-blowtorch alternative this tutorial already contrasts) as the mechanism HeatGenerator commits to.

The standard the selection is checked against: what the model already provides that a chosen mechanism must pair with, and what it must expose to be checked.

The chosen mechanism must pair with the discrete timing control ControlSystem's durationOut already provides, and must expose a rating heatGenerationReq's power threshold can be checked against once a concrete part exists.

What the selection takes as given: the confirmed fact above, plus a domain premise about how the two mechanisms work, stated as two premises below.

['ControlSystem declares durationOut : DurationPort (Chapter 5), a discrete duration signal, confirmed by model.find() above.', "Domain premise, not derived from the model: a resistive element responds to being switched on and off directly, while a combustion source needs separate ignition and fuel-metering machinery to do the same. Neither HeatGenerator nor any of its realizations is yet connected to ControlSystem's port in this model; this premise is about the physical mechanisms themselves, not about what the model currently wires together."]

The evidence, and the argument connecting it to the claim.

An electrically resistive element responds to being switched on and off directly, the same shape as duration's discrete timing signal, while a combustion-based burner needs separate ignition and fuel-metering machinery to respond the same way (the domain premise above). That is a claim about how the two mechanisms work, not something this model currently shows: no realization of HeatGenerator is yet connected to ControlSystem's durationOut port, so this selection is a reasoned engineering preference argued from mechanism, not a claim that the model already connects one mechanism and not the other.

The challenge: what this selection does not establish, stated plainly.

This does not rule out a combustion design: a burner controlled by its own timed valve could equally use a duration-like signal, which is exactly why the argument above rests on a domain premise about how the two mechanisms work, not on anything the model itself already builds or connects. Joule heating's own relation (power proportional to resistance and the square of current) is still not modeled, so efficiency and response-time comparisons remain out of reach either way.
Once a supply and a control policy are modeled together, this selection could be revisited against a real trade study rather than a domain premise alone.

With every part named above, the selection record assembles from them directly.

Model tag: {'tag': 'ToasterDemo::asC06Tag', 'identifier': 'AS-C06', 'annotated_element': 'ToasterDemo::ResistanceCoil'}
Validation errors: []

The tag printed above is now part of the loaded model, and validate_record confirms the Python record and the model’s own tag agree about what AS-C06 is actually about, with no errors reported. With the selection on record, ResistanceCoil’s electrically-specific name and Joule-heating doc are now admissible: the mechanism they name has a real, recorded argument behind it, not a name chosen and justified afterward.

part def ResistanceCoil :> HeatGenerator {
    attribute :>> power default = 800.0 [SI::W];
    attribute resistance : ISQ::ResistanceValue default = 12.0 [SI::ohm];
}

ResistanceCoil specializes HeatGenerator and binds its power slot to a default, redefined with default = so a candidate can still override it. resistance is a physical sizing value with a real unit, ISQ::ResistanceValue in ohms, not the bare number the mechanism-suggestive name alone would need.

part rated : ResistanceCoil {
    assert satisfy heatGenerationReq by rated;
}

rated takes ResistanceCoil’s default power, 800 W, and asserts it satisfies heatGenerationReq directly: a real, evaluable claim about a real candidate.

part weak : ResistanceCoil {
    attribute :>> power = 400.0 [SI::W];
    assert not satisfy heatGenerationReq by weak;
}

weak overrides power down to 400 W, below the threshold, and folds the claim into its own context as a negated assertion: assert not satisfy, not a false positive. Its failure is a design choice, a 400 W part rated below what the requirement asks for, the same class of legitimate failing branch as a chosen part’s rating anywhere else in this model.

A requirement’s subject must resolve to a declared type. The negative control below types the subject by a def that was never declared.

Neg control diagnostics: 'unresolved reference: UndefinedCarrier'

The diagnostic reports an unresolved reference: UndefinedCarrier names no declared type, so the subject cannot be typed.

rated.power = 800 [SI::W], heatGenerationReq(rated) = True
weak.power = 400 [SI::W], heatGenerationReq(weak) = False

rated evaluates True against the threshold; weak evaluates False, confirming the assertion folded into its own context above is the correct one to make.

The requirement and the candidates printed above loaded without error, the selection and framing records validated with no errors, and the evaluated results confirm what each candidate’s own assertion claims.

Try the chapter exercise in exercises/ch06/exercise.ipynb: nest MoveWater inside ApplyWater, build WaterMover as its abstract carrier, and add a BrewReq requirement with its subject on WaterMover itself (not BrewUnit) constraining minimum throughput, then create a lower-throughput candidate that fails it, following the requirement and candidate pattern this notebook builds.