Teaching Case — An Arrow Carrying the Wrong Thing
A flow declares what it carries and the feature it arrives at declares what it accepts, and the arrow is identical whether or not those agree. Here coolant is routed into a port that accepts fuel. Conformance is decided by the `:>` declarations in the document and by nothing else — not by the names looking alike, not by the two types having similar features — so `Petrol` reaching a `Fuel` port passes because the document says `Petrol :> Fuel`, and `Coolant` reaching the same port does not.
Make it your own.
package Thermal {
item def Fluid;
item def Fuel :> Fluid;
item def Petrol :> Fuel;
item def Coolant :> Fluid;
port def FuelInlet { in item charge : Fuel; }
port def GenericInlet { in item charge : Fluid; }
part def PetrolPump { port outlet : ~FuelInlet; }
part def CoolantPump { port outlet : ~FuelInlet; }
part def Burner { port inlet : FuelInlet; }
part def Sump { port inlet : GenericInlet; }
part def Bay {
part petrolPump : PetrolPump;
part coolantPump : CoolantPump;
part burner : Burner;
part sump : Sump;
// Correct: the document declares Petrol :> Fuel.
flow of Petrol from petrolPump.outlet.charge to burner.inlet.charge;
// Correct: Coolant :> Fluid, and the sump accepts Fluid.
flow of Coolant from coolantPump.outlet.charge to sump.inlet.charge;
// Wrong, and drawn identically: the burner accepts Fuel, and nothing
// declares that Coolant specializes it.
flow of Coolant from coolantPump.outlet.charge to burner.inlet.charge;
}
}