Mini-projet PG-IDM : machines à états avec langage d'action
Le but de ce mini-projet est de transformer et exécuter des
machines à états simplifiées comportant un mini-langage d'action.
Description du méta-modèle
Le méta-modèle de machines à états considéré est representé dans la
figure ci-dessus. Ses éléments sont :
- State : un état est défini par un nom et
le fait qu'il soit actif (dans le contexte d'une exécution de la
machine à état). Un état actif a son
attribut isActive positionné à "true". Une
opération peut être associée à un état : une
opération est une suite ordonnée d'affectations de variables et
possède de manière facultative un nom.
- CompositeState : un état composite est
un état qui est composé de plusieurs états internes. Un état composite
possède un état inital.
- InitialState : référence l'état initial
d'un état composite.
- StateMachine : une machine à états est un
état composite particulier (afin de définir la structure des états qui
composent la machine à états) auquel s'ajoutent un ensemble de
transitions, d'événements et de variables.
- Event : définit, par son nom, un
événement pouvant être généré pendant l'exécution de la machine à
états.
- Transition : définit une transition d'un
état source vers un état cible pour un événement associé. Une
transition peut également posséder une garde.
- Variable : une variable est d'un
certain type (booléen ou entier) et est associée à une valeur.
- Data : définit une valeur, soit de type
booléen, soit de type entier.
- ExpressionElement : élément d'expression
abstrait, pouvant être une expression plus complexe, une variable ou
une donnée.
- VariableReference : référence une
variable dans une expression.
- Expression : définit une expression
combinant par un opérateur une partie gauche et une partie
droite. Permet de définir des calculs ou des propositions booléennes
par des combinaisons d'expressions aussi complexes que nécesssaire pour
l'affectation d'une variable ou la définition d'une garde d'une
transition.
- Assignement : définit l'affectation
d'une variable via une expression (soit un calcul, soit directement
une valeur ou une autre variable ...).
- Operator : énumération définissant les
opérateurs permettant de combiner une partie gauche et droite d'une
expression :
- add : addition entière
- sub : soustraction entière
- mul : multiplication entière
- div : division entière
- eq : égalité de valeur
- neq : non égalité de valeur
- gt : plus grand que
- gte : plus grand que ou égal à
- lt : plus petit que
- lte : plus petit que ou égal à
- and : et logique
- or : ou logique
- not : non logique
Un modèle de machine à états se base donc sur une instance de
l'élément StateMachine. Cette instance est
unique par modèle et sert de départ à la création et au référencement
de tous les états et transitions du modèle. Cette unicité est assurée
par une contrainte OCL. D'autres contraintes OCL sont nécessaires pour
notamment spécifier que :
- L'état référencé par un état initial d'un composite est bien un
état de ce composite
- Si une machine à états est active, alors elle contient un et un
seul état actif et si cet état est composite, il contient également un
et un seul état actif et ainsi de suite...
- Il n'existe pas deux états du même nom au sein d'un composite
- ...
Note : dans le méta-modèle Ecore du projet, les
attributs _name des éléments Expression et
Assignment ou autres méta-éléments associés n'ont pas de sémantique
particulière. Ils servent juste à pouvoir identifier les instances de
ces éléments via un nom textuel ou préciser leur contenu donné sous
forme textuelle.
Exemples de modèles et des transformations attendues
Exemple de machines à états sans garde ni opération
La figure ci-dessous présente un exemple de machine à états
modélisant le fonctionnement d'un micro-onde. L'état "Off" est
représenté en gris car il est le premier pas d'exécution du modèle. Il
est en effet l'état initial du composite qui est lui-même l'état inital
de la machine à états.
Exemple d'une machine à états avec gardes et opérations
La figure ci-dessus représente une machine à états de la vitesse
d'une voiture. La vitesse varie entre 0 et 100 km/h, par pas de 10 km/h. La
machine à états possède deux état principaux : Arrêt et Marche, selon
que la vitesse de la voiture est nulle ou pas. Deux événements sont
gérés : accélerer et ralentir. L'état Marche contient 3 états internes
permettant d'incrémenter et décrémenter la vitesse ainsi que de
préciser que l'on est arrivé à la vitesse maximale. La machine à états
possède deux variables : vitesse, de type
entier, initialisé à 0, et
maxAtteint, de type booléen, initialisé à
false.
Travail attendu
Le travail est à faire par groupe de 2 ou 3 étudiants.
Trois éléments sont attendus dans le projet :
- Recopiez le code implémentant la sémantique opérationnelle du
moteur d'exécution en Java vu en cours en l'adaptant pour qu'il
fonctionne : le méta-modèle est presque le même à l'exception de
l'état historique qui n'existe pas ici.
- Complétez le code Java du moteur pour exécuter les opérations
associées aux état et gérer les gardes des opérations pendant
l'exécution. Après chaque pas d'exécution, le modèle est sauvegardé
dans un modèle nommé "nomModele-exec-X.xmi" avec X un entier
correspondant au pas d'exécution (1, 2, 3 ...).
- Une génération de code Acceleo qui va définir pour un modèle, une
classe unique Java contenant :
- Des attributs correspondant aux variables définies dans la
machine à états.
- Une méthode Java par garde ou opération définie dans la
machine à états
Le code Java doit être valide et compiler.
Ressources du projet
L'archive StateMachine.zip contient
le projet Eclipse implémentant les éléments initiaux du projet :
- Répertoire metaModels :
- StateMachine.ecore : méta-modèle de la
machine à états simplifiée et les invariants OCL associés
- Répertoire models : contient trois
exemples de machine à états
- Microwave.xmi : l'exemple du micro-onde
présenté ci-dessus
- Feu.xmi : exemple basique d'un feu
tricolore
- Voiture.xmi : l'exemple de la voiture
présenté ci-dessus
- Répertoire src : le code Java EMF pour
manipuler des modèles et un
fichier StateMachineManipulation.java qui
charge un modèle (sans rien faire de plus) : vous compléterez son code
pour exécuter le modèle.