Vous êtes sur la page 1sur 10

Rapport des Séances d'Ingénierie des Modèles.

Sommaire.

I. Metamodélisation avec Elipse/EMF et ………………………………… 1


Topcased

-Création et vérification d'un méta-modèle en Ecore


-Génération du code Java et l'éditeur arborescent
-Génération d'un éditeur graphique avec Topcased
-Définition des propriétés structurelles en OCL

II. Transformation des Modeles ………………………………… 5

- Transformation ATL de SimplePDL vers PetriNet


- Transformation PetriNet vers Tina

III. Questions ………………………………… 7

- Apport d'OCL par rapport à Ecore


- L'intérêt de traduire un modèle de processus en
réseau de Petri
-L'intérêt de passer par le méta-modèle PetriNet plutôt
que de faire directement une transformation
SimplePDL vers Tina
-L’intérêt de vérifier des propriétés sous Tina par
rapport aux propriétés exprimées en OCL

IV. Anexes ………………………………… 8

- Code PetriNet2Tina
- Code SimplePDL2PetriNet

1
I. Meta-modélisation avec Elipse/EMF et Topcased

EMF est un Framework de modélisation et un outil de génération de code pour créer


outils et des autres applications basées dans un modèle structuré.
L'objectif de cette première partie est de prendre en main l'outil Topcased (fourni par
Eclipse version Europa) pour faire de la Meta-modélisation.

On a eu une approche de la modélisation et on a utilisé les briques d’EMF (plug-ins).


On a étudié lors des TPs le Meta-modèle Ecore, un Canevas de classes pour
décrire les modèles EMF et manipuler les référentiels de modèles

Création et vérification d'un méta-modèle en Ecore

On a implanté en Ecore le meta-modèle SimplePDL, en utilisant l'editeur graphique Ecore :

2
Pour valider le modèle Ecore, il a fallu de sauvegarder le modèle et après cliquer sur le symbole
vert suivant.

Génération du code Java et l'éditeur arborescent.

Grâce a une brique d’EMF(plug-in – Version Eclipse Europa -), on a généré un éditeur
arborescent permettant de saisir un Process conforme à SimplePDL.
Le fichier SimplePDF.genmodel nous a permit aussi, avec l’éditeur arborescente, de générer du
code Java.

Génération d'un éditeur graphique avec topcased

Topcased propose un outil qui nous permet d’engendrer un éditeur graphique conforme au
meta-modèle SimplePDL et le fichier genmodel, qui contient les configurations des modèles à
éditer.

L’étape suivant la création d’un fichier de configuration de l’éditeur est la création d’un fichier de
configuration de diagramme. Un diagramme définit une vue editable sur le modèle dans
l’éditeur graphique. Ce fichier doit être lié au genmodel et à l'éditeur à créer.

Il faut configurer :

 La définition des éléments de l'éditeur graphique et ses representations.

 Les liens entre l'éditeur graphique et le méta-modèle SimplePDL

 La palette de l'éditeur.

Définition des propriétés structurelles en OCL

Le méta-modèle SimplePDL dispose de quelques propriétés structurelles, d'où vient des


contraintes. Voici la liste des différentes propriétés structurelles que nous avons contrôlées :

 Un Process doit avoir au moins une WorkDefinition.


 Deux ou plus WorkDefinition d’un même Process doivent avec des noms différents.
 Plus généralement, les différents éléments d’un processus doivent avoir des noms différents.
 Entre deux WorkDefinition données, il ne peut pas y avoir plusieurs relations de précédence
(WorkSequence) de même type. Les relations supplémentaires sont inutiles.

3
 Le texte d’une guidance doit être défini et non vide.
 Une WorkSequence ne peut pas avoir même cible et même source.
Les contraintes sont codées en ATL. Prenons par exemple, la première contrainte :

Codée en OCL, cela donne :

pdl!Process.allInstances()->asSequence()->first().workDefinitions->size() > 0

Vérification en ATL :

query VerifSimplePDL = if pdl!Process.allInstances()->asSequence()->


first().workDefinitions->size() <1
then 'Propriété 1 : KO (Aucun WorkDefinition présent dans le processus)'
else 'Propriété 1 : OK'
endif
.writeTo('/tmp/SimplePDL.verif');

4
II. Transformation des Modèles

Notre objectif a été de faire des verifications sur des modeles de procesus. L’idee est de
transformer le modele de processus dans un langage forme l (semantique de traduction).

Transformation de SimplePDL vers PetriNet avec ATL

On a utilisé le fichier contentant le meta-modèle


Petri Net fournit. Voici (à droite) la structure de ce
meta-modèle.

On a créé un fichier ATL qui permet de


transformer un modèle en SimplePDL en un
modèle Petri Net. Le schéma à droite montre les
différents éléments du meta-modèle SimplePDL
sous réseau de Petri :

Le schéma à gauche montre les éléments


du SimplePDL avec ses équivalentes en
éléments du meta-modèle PetriNet.

5
Le schéma ci-dessous montre la transformation d’un work sequence à une arc-lecture entre la
place de la source work definition et la transition approprié du target work definition.

Transformation PetriNet vers Tina

On a écrit une requête ATL qui transforme un modèle de Petri Net vers Tina, pour traiter toutes
les caractéristiques d’un model de réseaux de Petri, afin de pouvoir visualiser et simuler un
réseau de Pétri sous Tina.
Pour faire cette partie, on a défini une configuration pour spécifier les meta- modèles et
modèles utilises par une requête ou un module ATL, et après on a complété la requête pour
atteindre le but ci-dessus.

Voir codes annexes.

6
III. Questions

 Qu'apporte OCL par rapport à Ecore ?

Ecore permet d'exprimer un certain nombre d'information structurelles, mais pas toutes. Pour faire des
instances valides des modèles, on a OCL (Object Constraint Language), qui permet de rajouter des
contraintes qu’on ne peut pas trouver sous Ecore. Un clair exemple est PetriNet et ses transitions, on doit
utiliser les contraints d’OCL pour faire des instances valides.

Quel est l'intérêt de traduire un modèle de processus en réseau de Petri ?

Un modèle sous réseau de Pétri est composé de nœuds, qui permettent de faire une représentation par
transitions et/ou places. Ça permette d’exprimer notre modèle d’une façon plus réel et temporelle, dans
certain intervalle qui contient un temps max et min. En SimplePDL on a aussi des contraints de temps,
mais SimplePDL est une version beaucoup simplifié, pour garder notre présentation d’une manière plus
simple, mais on peut commettre des erreurs grâce a qu’on peut lier des transitions incorrectement.

Voir le diagramme montre sur la Transformation SimplePDL vers PetriNet. Page 6

Quel est l'intérêt de passer par le méta-modèle PetriNet plutôt que de faire directement une
transformation SimplePDL vers Tina ?

Le modèle des réseaux de Petri est considéré comme un meta-modèle pivot. On peut par exemple
changer une boite a outil, il suffira d’écrire une nouvelle transformation M2T (Modèle vers Texte –Petri
vers Tina-). On peut aussi considérer un autre modèle que les processus et, dans ce cas, c’est la
transformation M2M (Modèle vers modèle – Simple PDL vers Petri Net-) qu’il faut changer.

Dans la dernière question, on a dit que la tranformation nous permette d’exprimer notre modèle d’une
façon plus réel et temporelle, et on a Tina comme model-checker de Petri.

En plus, Tina comme model-checker de Petri Net, la configuration pour la gestion de Petri Net existe
déjà. Ecrire cette même configuration pour SimplePDL, n’est pas nécessaire (ça serait trop long), il suffira
d'écrire une transformation SimplePDL à PétriNet.

Quel intérêt de vérifier des propriétés sous Tina par rapport aux propriétés exprimées en OCL ?

Avec la boite à outils de Tina, on peut vérifier les modèles de processus et plus de propriétés.

7
III. Annexes

Code PetriNet2Tina

--@atlcompiler atl2006
-- build a net file from a Petri net model
query PetriNet2Tina = PetriNet!PetriNet->allInstances()
->first().toTina().writeTo('/tmp/res.net');

helper
def: concatenateStrings(strings: Sequence(String), terminator: String): String =
strings->iterate(s; acc: String = '' | acc + s + terminator);

helper
context PetriNet!PetriNet
def: toTina(): String = ('net ' + self.name + '\n') +thisModule.concatenateStrings(
self.nodes-> collect(n|n.toTina()),'\n');

helper
context PetriNet!Node
def:toTina():String =(self.toTina() +'\n' );

helper
context PetriNet!Place
def:toTina():String =('pl ' + self.name+ ' ' + '(' + self.marking.toString() + ')');

helper
context PetriNet!Transition
def:toTina():String =
'tr ' + self.name +' ' + thisModule.concatenateStrings(self.ingoings-> collect(i|i.toTina()),' ')
+ ' -> ' + thisModule.concatenateStrings(self.outgoings-> collect(j|j.target.name()) ,' ');

helper
context PetriNet!Arc
def:toTina():String =(
self.source.name +
if (self.kind = #read_arc)
then ('?' +self.weigth.toString() )
else if (self.weigth>1)
then ('*'+self.weigth.toString())
else ' '
endif
endif );

Code SimplePDL2PetriNet

8
-- @atlcompiler atl2006
-- Description : SimplePDL (Model) to PetriNet (Model) transformation
module SimplePDL2PetriNet;
create OUT : PetriNet from IN : SimplePDL;
rule Process2PetriNet {
from process : SimplePDL!Process
to petrinet : PetriNet!PetriNet (name <- process.name)
}
rule WorkDefinition2PetriNet {
from wd : SimplePDL!WorkDefinition
to process_isNotStarted : PetriNet!Place (name <- wd.name+'_isNotStarted' ,
net <- thisModule.resolveTemp(SimplePDL!Process->allInstances()->first() ,
'petrinet')),
process_isStarted : PetriNet!Place (name <- wd.name+'_isStarted' ,
net <- thisModule.resolveTemp(SimplePDL!Process->allInstances()->first() ,
'petrinet')),
process_isInProgress : PetriNet!Place (name <- wd.name+'_isInProgress' ,
net <- thisModule.resolveTemp(SimplePDL!Process->allInstances()->first() ,
'petrinet')),
process_isFinished : PetriNet!Place (name <- wd.name+'_isFinished' ,
net <- thisModule.resolveTemp(SimplePDL!Process->allInstances()->first() ,
'petrinet')),
transition_start : PetriNet!Transition (name <- wd.name+'_start' ,
net <- thisModule.resolveTemp(SimplePDL!Process->allInstances()->first() ,
'petrinet')),
transition_finish : PetriNet!Transition (name <- wd.name+'_finish' ,
net <- thisModule.resolveTemp(SimplePDL!Process->allInstances()->first() ,
'petrinet')),
arc1 : PetriNet!Arc (weigth <- 1 ,
kind <- #normal,
source <- process_isNotStarted,
target <- transition_start,
net <- thisModule.resolveTemp(SimplePDL!Process->allInstances()->first() ,
'petrinet')),
arc2 : PetriNet!Arc (weigth <- 1 ,
kind <- #normal,
source <- transition_start,
target <- process_isInProgress,
net <- thisModule.resolveTemp(SimplePDL!Process->allInstances()->first() ,
'petrinet')),
arc3 : PetriNet!Arc (weigth <- 1 ,
kind <- #normal,
source <- transition_start,
target <- process_isStarted,
net <- thisModule.resolveTemp(SimplePDL!Process->allInstances()->first() ,
'petrinet')),
arc4 : PetriNet!Arc (weigth <- 1 ,
kind <- #normal,
source <- process_isInProgress,
target <- transition_finish,
net <- thisModule.resolveTemp(SimplePDL!Process->allInstances()->first() ,
'petrinet')),

9
arc5 : PetriNet!Arc (weigth <- 1 ,
kind <- #normal,
source <- transition_finish,
target <- process_isFinished,
net <- thisModule.resolveTemp(SimplePDL!Process->allInstances()->first() ,
'petrinet'))
}

rule Worksequence2PetriNet {
from ws : SimplePDL!WorkSequence
to a : PetriNet!Arc ( weigth <- 1, kind <- #read_arc,source <- if (ws.linkType =
#startToStart or ws.linkType = #startToFinish)
then thisModule.resolveTemp(ws.predecessor , 'process_isStarted ')
else thisModule.resolveTemp(ws.predecessor , 'process_isFinished ')
endif, target <- if (ws.linkType = #startToStart or ws.linkType = #finishToStart)
then thisModule.resolveTemp(ws.successor , 'transition_start ')
else thisModule.resolveTemp(ws.successor , 'transition_finish ')
endif
)
}

10