08 · Exemples des cas d’usage
Scripts recopiés des cas d’usage livrés
Orléans Flood Crisis — une zone de danger qui suit la Loire
Le potentiel Loire flooding est Generated_By le pont George-V. Sa règle lit le capteur de niveau d’eau fixé sur le pont : à partir de 1,50 m la zone est active, centrée sur le capteur, avec un rayon de 50 m par mètre d’eau ; en dessous, elle est gelée et réduite.
Loire flooding –Generated_By→ George-V bridgeactivation conditionNode sensor = $target <-[Fixed_Onto]- ("Loire water level - Orleans");
if(sensor.currentValue >= 1.5) {
Float radius = sensor.currentValue * 50;
$source.active();
$source.getGeoloc().setRadius(radius);
$source.getGeoloc().setPosition(sensor.getGeoloc().getPosition());
} else {
$source.freeze();
$source.getGeoloc().setRadius(0);
$source.getGeoloc().setPosition(null);
}
Le risque George-V bridge flood risk est Generated_By cette zone. À partir de 2,50 m, les règles CEP du capteur écrivent sa probabilité par paliers : 0,2 à 2,50 m, 0,5 à 3,50 m, 0,8 à 4,00 m et 1 à 4,50 m. Sous 2,50 m aucun seuil CEP n’est jamais franchi : 2L fixe donc le palier bas, le risque est actif à 0,05 dès que la zone l’est. Cette règle remplace la règle par défaut, qui recopierait la probabilité de la zone sur le risque et écraserait les paliers CEP.
George-V bridge flood risk –Generated_By→ Loire floodingactivation conditionNode risk = $source;
Node zone = $target;
Node sensor = findNodeInstance("Sensor", "Loire water level - Orleans");
if(zone.isActive() && sensor.currentValue < 2.5 && risk.isFreeze()) {
risk.probability = 0.05;
risk.active();
risk.getGeoloc().setPosition(sensor.getGeoloc().getPosition());
}
if(zone.isFreeze() && sensor.currentValue < 2.5 && risk.isActive()) {
risk.probability = 0;
risk.freeze();
risk.getGeoloc().setPosition(null);
}
À 4,50 m la probabilité atteint 1 : la règle Generated_By de l’actualité Loire flood at George-V bridge l’active à l’endroit du risque et gèle le risque (if($target.probability >= 1), comme la règle par défaut). La crue ne se termine pas dès que l’eau baisse : le seuil du capteur qui l’a levée n’est relâché qu’une fois le niveau resté 6 heures sous 4,00 m (voir l’intercepteur Sensor).
Orléans Flood Crisis — attendre la fin de la crue avant de rouvrir
Dans les rôles de crise partagés, la fonction Mediation Wait until a bridge can be inspected se place entre Close a bridge to traffic et Inspect a bridge after a flood, reliées par de simples liens Implies. Sa durée est un intervalle de 6 à 24 h et elle scrute toutes les 5 s. Le processus déduit ferme le pont, puis l’attente retient l’inspection, et ce qui la suit, jusqu’à ce que la condition soit vraie ; les tâches qui la suivent sont planifiées dans une fenêtre, de l’attente la plus courte à la plus longue. La condition est générique : elle retrouve la crue par l’objectif pour lequel l’inspection a été déduite, la même fonction sert donc pour n’importe quel pont et n’importe quelle crue.
Wait until a bridge can be inspected (Mediation, Wait Until)Wait ConditionNode objective = $target.createdFor();
Node risk = objective -[Prevents]-> (Risk);
Node flood = risk <-[Generated_By]- (Actuality);
boolean cleared = flood == null || !flood.isActive();
boolean riskLow = risk == null || risk.probability < 0.8;
boolean reopen = cleared && riskLow;
reopen;
Dans la procédure corrective, Wait until the flood has receded se place de la même façon entre Cut the utility networks crossing a bridge et Restore the utility networks crossing a bridge (6 à 24 h, toutes les 5 s) : les réseaux sont rétablis une fois que la crue traitée par l’objectif n’est plus active.
Wait until the flood has receded (Mediation, Wait Until)Wait ConditionNode objective = $target.createdFor();
Node flood = objective -[Treats]-> (Actuality);
boolean cleared = flood == null || !flood.isActive();
cleared;
Barbecue — un risque de brûlure qui grandit quand Henri s’approche
Le potentiel High Temperature est une zone de 6 m autour du barbecue, active tant que son capteur thermique indique 50 ou plus. Le risque Henri risks getting burned est Generated_By cette zone : sa probabilité va de 0 au bord de la zone à 1 à 1,5 m du barbecue, où l’alerte Henri burns prend le relais.
Henri risks getting burned –Generated_By→ High Temperatureactivation conditionNode riskBurns = $source;
Node highTemperature = $target;
Node objectiveRiskBurns = riskBurns <-[Prevents]- ("Prevent Henri risks getting burned");
Node actualityBurns = findNodeInstance("Alert", "Henri burns");
Node barbecue = findNodeInstance("Good", "Barbecue");
Node henri = findNodeInstance("Kid", "Henri Martinez");
if(henri != null && highTemperature.isActive() && actualityBurns.isFreeze() && henri.getGeoloc().getPosition().distanceTo(barbecue.getGeoloc().getPosition()) <= highTemperature.getGeoloc().radius) {
Float distance = henri.getGeoloc().getPosition().distanceTo(barbecue.getGeoloc().getPosition());
Float zoneRadius = highTemperature.getGeoloc().radius;
if(distance > 1.5) {
Float remaining = zoneRadius - distance;
Float span = zoneRadius - 1.5;
riskBurns.probability = remaining / span;
riskBurns.getGeoloc().setPosition(henri.getGeoloc().getPosition());
riskBurns.active();
objectiveRiskBurns.active();
}
} else {
if(actualityBurns.isFreeze()) {
riskBurns.probability = 0;
riskBurns.freeze();
objectiveRiskBurns.freeze();
}
}
L’alerte de noyade combine une distance et une zone : Henri doit être à moins de 10 m de la piscine et dans son polygone.
Henri drowns –Generated_By→ Henri is in danger of drowningextraitif(henri != null && henri.getGeoloc().getPosition().distanceTo(swimmingPool.getGeoloc().getPosition()) <= 10 && henri.isInside(swimmingPool)) {
riskSubmersion.probability = 1;
riskSubmersion.freeze();
objectiveRiskSubmersion.freeze();
actualitySubmersion.getGeoloc().setPosition(henri.getGeoloc().getPosition());
actualitySubmersion.active();
objectiveActualitySubmersion.active();
}
IMT Albi Healthcare — une règle de susceptibilité qui parcourt le graphe
Un logiciel de santé est Is_Susceptible_To le potentiel Danger of Electrical Failure. La règle parcourt les risques générés par ce potentiel et active chacun d’eux, avec son objectif de prévention, tant que le logiciel est dans la zone active et que le risque n’est pas encore certain.
Healthcare software –Is_Susceptible_To→ Danger of Electrical Failuresusceptibility conditionNode software = $source;
if(software.isInstanceOf("Good")) {
Node potential = $target;
List<Node> risks = potential <-[Generated_By]- ();
for(Node risk: risks) {
if(potential.isActive() && software.isInside(potential) && risk.probability < 1) {
risk.active();
if(risk <-[Prevents]- () != null) {
risk <-[Prevents]- ().active();
}
risk.getGeoloc().setPosition(software.getGeoloc().getPosition());
} else {
risk.freeze();
if(risk <-[Prevents]- () != null) {
risk <-[Prevents]- ().freeze();
}
risk.getGeoloc().setPosition(null);
}
}
}
IMT Albi Crisis — liens conditionnés et correctif qualifié
La fonction Confirm gas leak implique deux fonctions, chacune gardée par la réponse que le pompier donne dans la variable de sortie Confirmed gas leak. Les deux conditions sont exclusives : le processus déduit garde les deux branches et le moteur en suit une (voir liens conditionnés).
Confirm gas leak –Implies→ Cut off the local gas valve · Cut off the school gas supplyCondition Evaluation@Confirmed gas leak[Confirm gas leak] == "Yes and repairable"
@Confirmed gas leak[Confirm gas leak] == "Yes and non-repairable"
Quand la déduction retient un correctif pour un risque trouvé par la détection ML, le planificateur écrit la condition de l’Event_Flow attaché à la sous-tâche nominale. Le nom de l’actualité ne suffit pas, puisque la même Power outage peut être générée par plusieurs risques : la condition exige aussi que l’actualité soit liée au risque validé, dans un sens ou dans l’autre, car la détection ML écrit l’arête Generated_By du risque vers l’actualité et un cas d’usage modélisé en général dans l’autre sens (parcours des procédures correctives).
Nominal SubTask –Event_Flow→ sous-processus correctifCondition Evaluation (générée)Node triggerActuality = findNodeInstance("Actuality", "Power outage");
boolean generated = triggerActuality <-[Generated_By]- ("Power outages") != null || triggerActuality -[Generated_By]-> ("Power outages") != null;
boolean triggered = triggerActuality.isActive() && generated;
triggered;
Un risque de mise en œuvre attaché à une tâche reçoit plutôt un Exception_Flow, dont la condition générée ne surveille que l’actualité (parcours des procédures de reprise) :
Blood test Request –Exception_Flow→ sous-processus de repriseCondition Evaluation (générée)findNodeInstance("Actuality", "Healthcare software unavailability for Blood Test Request Function").isActive()