Modèles à l'exécution
Ingénierie des Modèles L'IDM généralise l'usage des modèles partout où
on peut le faire
Exécution de modèles Usage productif des modèles
Y compris dans le système en cours d'exécution
Eric Cariou
Usage « passif »
Master Technologies de l'Internet 2ème année Un modèle est utilisé pour représenter l'architecture du
système, pour prendre des décisions...
Université de Pau et des Pays de l'Adour Ex : models@[Link]
UFR Sciences Pau – Département Informatique Discipline où un modèle représente l'état courant du système
Lien de causalité entre le système et le modèle
[Link]@[Link] Analyse du modèle pour détecter d'éventuels problèmes
En cas de problème, on adapte le système en cours d'exécution
Octobre 2016 1 2
Modèles à l'exécution Modèles exécutables
Usage « actif » Variantes de l'exécution de modèle
Le modèle définit le comportement (ou une partie du) du Compilation de modèle
système
On traduit le contenu du modèle vers du code classique via
Ex : une machine à états qui contrôle le fonctionnement éventuellement des frameworks dédiés
d'un ascenseur Ex : PauWare
Librairie Java implémentant la sémantique des machines à états UML
En fonction de l'interaction de l'utilisateur avec les boutons de
contrôle de l'ascenseur On peut « coder » une machine à états UML
Séparation des opérations métier et du comportement qui est dans la
Les transitions entre les états se font via les événements générés machine à états
par l'utilisateur On peut générer ce code Java/PauWare à partir des diagrammes UML
Les états définissent les opérations métier à exécuter Simulation de modèle
Ouverture/fermeture de portes
Monter/descendre à un certain étage En phase de conception, on simule l'exécution du modèle
Exécution de modèle Permet de détecter au plus tôt des erreurs de conception
Le modèle simulé n'est pas (forcément) ensuite présent en tant que
Le système prend en entrée un modèle qui définit le
tel à l'exécution
comportement du système et l'interprète
3 4
Modèles exécutables Constituants d'un i-DSML
Éléments principaux d'un i-DSML
Dans UML
Méta-modèle définissant les éléments qu'on trouvera dans le
Les diagrammes comportementaux sont a priori modèle
exécutables Partie statique
Machines à états, diagrammes de séquence, d'activité … Pour définir le contenu métier du modèle
Les diagrammes structurels ne le sont pas (par défaut) Méta-modèle « classique »
Partie dynamique
Diagramme de classe, de composant, d'objet … Pour définir l'état dans lequel se trouve le modèle au cours de son exécution
En IDM, peut créer ses propres langages de Spécifique aux i-DSML
modélisation Sémantique d'exécution
Définit comment le modèle évolue au fil du temps
DSML : Domain Specific Modeling Language
Chaque évolution = un pas d'exécution
Si on crée des langages de modèles exécutables Moteur d'exécution
i-DSML (interpreted DSML) ou x-DSML (executable DSML) Implémente la sémantique d'exécution
5 Prend en entrée un modèle et l'exécute 6
Exemple de i-DSML Partie statique
Machines à états simplifiées Définit tous les éléments structurels « classiques »
États composites État, composite, transition, état initial, historique, transition,
événement …
État historique
La machine à état est l'élément racine du méta-modèle
Exemple de modèle
Instance unique dans le modèle
Four à micro-onde Est définie comme un composite pour définir son ensemble d'états
Événements Contient en plus les événements et transitions de la machine à états
« Power » : bouton de marche/arrêt de cuisson
« DoorOpen » : ouverture de la porte
« DoorClosed » : fermeture de la porte
7 8
Partie statique Partie statique
Invariants OCL pour compléter le méta-modèle
Invariants OCL sur les transitions
Une machine à états est le seul état sans container
context StateMachine inv noContainerForStatemachine:
Une seule transition partant du même état avec le même événement
[Link]() context Transition inv transEventSource:
[Link]()->forAll(t : Transition |
context State inv containerForAllStates: [Link] = [Link] and [Link] = [Link] implies self = t)
not [Link](StateMachine) implies
not [Link]() Pas de transition partant d'un état historique, pas de transition vers ou
au départ d'un état initial ni d'une machine à états
Un état initial référence forcément un état
context Transition inv transForbiddenStates:
context InitialState inv initialStateNeverEmpty: not [Link](HistoryState) and
not [Link](); not [Link](InitialState) and
Les pseudos-états référencent un état de leur composite not [Link](InitialState) and
not [Link](StateMachine) and
context CompositeState inv pseudoStatesInComposite: not [Link](StateMachine)
[Link]->includes([Link]) and
[Link]->includes([Link]) and
not [Link]() implies (
[Link]->includes([Link]) and
not [Link]()
implies [Link]->includes([Link]) )
9 10
Partie dynamique Partie dynamique
Définition de l'état courant du modèle en cours d'exécution Invariants OCL pour compléter la partie dynamique
Quel(s) est/sont le(s) état(s) actifs Principalement pour assurer la cohérence des états
Rajoute un attribut booléen isActive dans State
actifs
Si un composite contient un état historique, il doit référencer le
dernier état qui était actif Si la machine à états est inactive, alors tous les états du
L'association referencedState sert à cela modèle sont inactifs
Elle est statique pour un état initial (ne change pas) Si elle est active, alors un et un seul de ses états
Elle est dynamique pour un état historique (est modifiée pendant l'exécution) contenus (premier niveau) est actif
Si cet état est composite, alors un et un seul de ses états
est actif
A vérifier récursivement
Un état composite inactif a tous ses états inactifs et cela
récursivement jusqu'à tous les états feuilles
Valable aussi pour la machine à états
11 12
Partie dynamique Partie dynamique
Fonctions et attributs OCL qui vont aider à l'écriture des
invariants sur la cohérence des états actifs
Invariant de cohérence des états actifs de la machine à
états en utilisant les fonctions précédentes
Deux pseudos-attributs pour récupérer les états normaux (exclusion des
pseudo états) et les composites dans l'ensemble des états d'un composite Soit toute la machine à états est désactivée
context CompositeState def: normalStates : Set(State) = Soit elle est activée avec les mêmes règles qu'un composite
[Link]->reject(s : State | [Link](PseudoState))
context Statemachine inv activeStateHierarchyConsistency:
context CompositeState def: compositeStates : Set(State) =
[Link]->select(s : State | [Link](CompositeState))
if [Link]
then [Link]()
Un état composite ne contient aucun état actif (et récursivement) else [Link]()
context CompositeState def: unactiveSubTree() : Boolean = endif
[Link]->forAll(s : State | not [Link]) and
[Link]->forAll(s : State |
[Link](CompositeState).unactiveSubTree())
Un état composite contient un et un seul état actif (et récursivement)
context CompositeState def: activeSubTree() : Boolean =
[Link]->select(s : State | [Link]))->size() = 1 and
[Link]->forAll(s : State |
if [Link] then [Link](CompositeState).activeSubTree()
else [Link](CompositeState).unactiveSubTree() 13 14
endif)
Sémantique d'exécution Sémantique d'exécution
Spécifie la façon dont le modèle évolue durant son exécution Sémantique translationnelle
Ex : pour les machines à états, précise comment suivre les transi-
tions en fonction de l'occurrence d'événements et des états actifs
Traduit le modèle vers un autre espace technologique
pour lequel il existe des outils d'exécution/simulation
Plusieurs manières de spécifier la sémantique pour une
Nécessite d'établir une correspondance sémantique entre les
exécution de modèles éléments du modèle et ceux de l'autre espace
Sémantique axiomatique Différents usages
Sémantique translationnelle
« compiler » un modèle
Sémantique opérationnelle
Ex : génération de code Java pour la libraire PauWare à partir
Sémantique axiomatique du modèle d'une machine à états
Logique de Hoare, contrats … Faire de la simulation/vérification
Définit des contraintes/propriétés qui doivent être respectées avant Ex : traduction du modèle en un réseau de Petri ou génération
et après la réalisation d'un pas d'exécution de spécification formelle en B pour utiliser des outils de
Ne permet pas d'implémenter un moteur d'exécution mais est utile vérification dédiés
si on veut vérifier que l'exécution se déroule correctement 15 16
Sémantique d'exécution Ex. séquence d'exécution
Sémantique opérationnelle
Définit de manière programmatique comment faire
évoluer le modèle
Un moteur écrit dans un langage de programmation
interprète le modèle et implémente cette sémantique
Exemples pour des i-DSML définis en Ecore
Implémentation directe en Java/EMF
Implémentation en Kermeta
Pratique via le mécanisme d'aspects et les opérateurs orientés
modèles
Implémentation via une transformation de modèle en ATL
Conceptuellement pertinent :
un pas d'exécution = une transformation endogène
Par contre peu pratique à réaliser
Nécessite un moteur annexe qui lance la transformation quand par
exemple un événement doit être traité par la machine à états 17 18
Ex. séquence d'exécution Sémantique opérationnelle
Pas initial Pour notre méta-modèle de machines à états,
Active les états initiaux de la machine à états il faut définir un ensemble de méthodes Java
Ici, l'instance de la machine à états, le composite « Closed » et
l'état « Off » auront tous trois leur attribut isActive à vrai
Rendre toute une hiérarchie d'états inactive
Pas d'exécution
Activer une hiérarchie d'états conformément aux règles
décrites précédemment
Pour un événement, s'il existe une transition à suivre par rapport
aux états actifs, change les états actifs
En positionnant les états historiques des composites s'ils
existent
Réalise un pas d'exécution
Initialiser la machine à états : activer les états initiaux
Seule la partie dynamique du modèle est modifiée par l'exécution
Modifier la partie statique = rajouter/supprimer/modifier des états ou des Rechercher s'il existe une transition partant de l'état actif
transitions = modifier le contenu métier du modèle racine ou un de ses super-états pour un événement
Entre pas 1 et 2, pour l'événement « DoorOpen » Traiter l’occurrence d'un événement
Deux transitions éligibles : de « Baking » vers « Paused », de « Closed »
vers « Open »
Suivre la transition requise si elle existe en modifiant la
hiérarchie des états actifs
Sémantique UML : suit la plus interne (comme sur la figure)
19 Désactive la hiérarchie de l'état source et active celle du cible 20
Sémantique statecharts de Harel : suit celle entre les deux composites
Sém. op. : historiques et initialisation Sém. op. : désactivation hiérarchie
// Désactive la hiérarchie haute d'un état
// Positionne l'état en paramètre comme référencé par public void unactivateUpStateHierarchy(State s) {
// l'éventuel état historique que contient son composite State up = [Link]();
public void setAsHistory(State s) { while (up != null) {
[Link](false);
if ([Link]() != null) {
up = [Link]();
if ([Link]().getHistoryState() != null) }
[Link]().getHistoryState().setReferencedState(s); }
}
} // Désactive la hiérarchie basse d'un état
public void unactivateDownStateHierarchy(State s) {
//Initialise la machine à états en activant tous les états initiaux if (s instanceof CompositeState)
public void initStateMachine(StateMachine sm) { for (State down : ((CompositeState)s).getStates()) {
[Link](false);
[Link](true);
if (down instanceof CompositeState)
State s = [Link]().getReferencedState(); [Link](down);
while (s != null) { }
[Link](true); }
[Link](s);
if (s instanceof CompositeState) // Désactive un état et toute sa hiérarchie
s = ((CompositeState)s).getInitialState().getReferencedState(); public void unactivateStateHierarchy(State s) {
else s = null; [Link](false);
} [Link](s);
[Link](s);
} 21 }
22
Sém. op. : activation hiérarchie Sém. op. : recherche transition
// Retourne l'état actif le plus en bas de la hiérarchie
// Active la hiérarchie haute d'un état public State getLeafActiveState(CompositeState comp) {
public void activateUpStateHierarchy(State s) { for (State s: [Link]())
State up = [Link](); if ([Link]())
while (up != null) { if (s instanceof CompositeState)
[Link](true); return [Link]((CompositeState)s);
[Link](up); else return s;
up = [Link](); return null;
} }
}
// Retourne la transition partant de l'état actif le plus bas pour l'événement
// Active la hiérarchie basse d'un état // précisé ou null si aucune transition n'a été trouvée
public void activateDownStateHierarchy(State s) { public Transition getTriggerableTransition(String evt, StateMachine sm) {
if (s instanceof CompositeState) { boolean fini = false;
State init = ((CompositeState)s).getInitialState().getReferencedState(); State activeState = [Link](sm);
[Link](true); Transition trans = null;
[Link](init); while(!fini) {
if (init instanceof CompositeState) [Link](init); for (Transition t : [Link]())
} if ([Link]().getName().equals(evt) && (activeState == [Link]())) {
} trans = t;
fini = true;
// Active toute la hiérarchie d'un état }
public void activateStateHierarchy(State s) { if (!fini) {
[Link](true); activeState = [Link]();
[Link](s); if (activeState == null) fini = true;
[Link](s); }
[Link](s); }
} 23 }
return trans; 24
Sém. op. : traitement d'un événement Sémantique opérationnelle
Moteur d'exécution en Java/EMF des machines à états
// Traite un événement : recherche une transition à suivre puis si elle
// existe, désactive la hiérarchie de l'état source puis modifie Exécute bien les modèles, fait évoluer les états actifs
// la hiérarchie des états actifs à partir de la cible de la transition conformément à la sémantique d'exécution à chaque occurrence
// en prenant en compte le cas où la cible est un état historique
public void processEvent(String event, StateMachine sm) { d'événement
Transition trans = [Link](event, sm); Mais … c'est tout !
if (trans != null) {
[Link]([Link]()); Il manque les opérations métiers associées aux états, les gardes
State target = [Link](); aux transitions …
if (target instanceof HistoryState) {
State histState = ((HistoryState)target).getReferencedState(); Solutions
if (histState == null)
target = Rajouter au méta-modèle de quoi spécifier des opérations
[Link]().getInitialState().getReferencedState();
else target = histState; Nécessite de la structure : variables, classes, types …
}
[Link](target);
Nécessite un langage d'action : affectations, calculs, tests, boucles ...
} En gros : modéliser un langage de programmation
}
Se contenter de représenter le comportement en pouvant rajouter
le métier à coté
25 Les machines à états en PauWare exécutent des méthodes 26
Java standard qui implémentent la partie métier
Exécution de diagrammes UML PauWare
A la base, la spécification UML n'avait pas prévu PauWare : [Link]
d'exécuter les modèles comportementaux
Librairie Java permettant de « programmer » des machines à états
Aucune partie dynamique pour aucun de ces diagrammes
Implémente la sémantique des machines à états UML 2.X
Pas obligatoire mais dans ce cas c'est le moteur d'exécution qui gère États imbriqués, concurrents
lui même en interne l'état courant du modèle en cours d'exécution
Opérations associées aux états (en entrée, sortie et son activité)
Une sémantique d'exécution définie informellement et Gestion des gardes et des opérations des transitions
partiellement en anglais
...
Aujourd'hui, plusieurs spécifications OMG pour faire de Equivalence entre machine à états UML et code Java
l'exécution de diagrammes UML PauWare
fUML : sémantique d'exécution de diagrammes d'activités Le modèle (machine à état ici) est entièrement et totalement
Peut définir le comportement exécutable d'une méthode d'une classe présent dans le code et est une partie du code
ou autre chose Le comportement dynamique est spécifié par la machine à état
ALF : syntaxe textuelle concrète de fUML similaire à celle d'un La logique métier est implémentée dans les opérations associées aux
langage de programmation états et aux transitions
PSCS : sémantique d'exécution des structures composites L'exécution du programme consiste à exécuter la machine à état
PSSM : sémantique d'exécution des machines à états 27 Via le moteur PauWare 28
PauWare : micro-onde Micro-onde : classe métier
public class MicrowaveBusiness {
private boolean lightOn = false;
Implémentation en Java/PauWare de l'exemple du private boolean doorOpen = false;
private boolean magnetronOn = false;
micro-onde public void stop() {
lightOn = false;
Ajout d'un objet métier gérant le micro-onde }
magnetronOn = false;
Lumière : éteinte ou allumée public void heat() {
lightOn = true;
Magnétron : en marche ou arrêté magnetronOn = true;
}
Porte : ouverte ou fermée
public void pause() {
Ensemble d'opérations métier pour modifier l'état de ces magnetronOn = false;
lightOn = true;
éléments }
Création ensuite du comportement avec l'API PauWare public void openDoor() {
doorOpen = true;
}
La hiérarchie des états avec des opérations métier associées
public void closeDoor() {
aux états doorOpen = false;
}
Des transitions entre les états avec là aussi des opérations
métiers associées public String toString() {
return "[ Light on: "+lightOn+", magnetron on: "+magnetronOn+", door open: "+doorOpen+ " ]";
29 }
}
30
Micro-onde : machine à états Micro-onde : machine à états
...
public class MicrowaveStateMachine { offClosed = new Statechart("Off");
[Link](mwb, "stop");
// les états de la machine à états [Link]();
protected AbstractStatechart open;
protected AbstractStatechart closed; baking = new Statechart("Baking");
[Link](mwb, "heat");
protected AbstractStatechart offOpen;
protected AbstractStatechart offClosed; paused = new Statechart("Paused");
protected AbstractStatechart baking; [Link](mwb, "pause");
protected AbstractStatechart paused;
// création des 2 états composites avec un history state pour Closed
// la machine à états closed = [Link](baking).name("Closed");
protected AbstractStatechart_monitor stateMachine; closed.deep_history();
[Link]();
public void buildAndStartMicrowave(MicrowaveBusiness mwb)
throws Statechart_exception { open = [Link](paused).name("Open");
// création des états simple avec associations des activités métiers // création de la machine à états
// et précision si un état est un état initial de son composite stateMachine = new Statechart_monitor([Link](open),"Microwave", true);
offOpen = new Statechart("Off"); ...
[Link](mwb, "stop");
[Link]();
... 31 32
Micro-onde : machine à états Micro-onde : exécution
... Si on exécute ce code :
// création des transitions entre états avec des opérations métier
// pour gérer l'ouverture de la porte MicrowaveStateMachine sm = new MicrowaveStateMachine();
[Link]("DoorOpen", closed, open, true, mwb, "openDoor"); MicrowaveBusiness business = new MicrowaveBusiness();
[Link]("DoorOpen", baking, paused, true, mwb, "openDoor"); [Link](business);
// transition implicite vers l'état historique de Closed : [Link]("Power", business);
[Link]("DoorClosed", open, closed, true, mwb, "closeDoor"); [Link]("DoorOpen", business);
[Link]("Power", offClosed, baking); [Link]("Power", business);
[Link]("Power", baking, offClosed); [Link]("Foo", business);
[Link]("DoorClosed",business);
// démarre la machine à états [Link]("Power", business);
[Link](); [Link]();
}
Donne la trace d'exécution suivante :
public void stopMicrowave() throws Statechart_exception {
Etat métier après Power : [ Light on: true, magnetron on: true, door open: false ]
[Link]();
} Etat métier après DoorOpen : [ Light on: true, magnetron on: false, door open: true ]
public void runEvent(String name, MicrowaveBusiness mwb) throws Exception { Etat métier après Power : [ Light on: true, magnetron on: false, door open: true ]
// traite l’occurrence d'un événement en exécutant les transitions et
// opérations requises Etat métier après Foo : [ Light on: true, magnetron on: false, door open: true ]
stateMachine.run_to_completion(name);
Etat métier après DoorClosed : [ Light on: true, magnetron on: true, door open:
[Link]("Etat métier après "+name+ " : "+mwb);
false ]
}
} 33 Etat métier après Power : [ Light on: false, magnetron on: false, door open: false34
]
Résumé constituants d'un i-DSML
35