123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866 |
- % vim:spell spelllang=fr
- \chapter{Études de cas : illustration et utilisation du langage}
- \label{ch:usecase}
- %15p
- %\ttodo{Ici on donne des cas d'utilisation :
- %\begin{itemize}
- %\item SimplePDLToPetrinet : exemple jouet que tout le monde connait et qui est
- %facile
- %\item SysML2Vhdlams ? Family2Person ? Class2Relational ?
- %\item autre ?
- %\end{itemize}}
- %\todo{refaire, il n'y avait pas encore le deuxième cas (aplatissement de
- %packages), et l'orga était légèrement différente}
- Dans ce chapitre, nous présentons un cas d'étude et expliquons le processus
- complet ainsi que son implémentation, depuis les métamodèles jusqu'au code
- de la transformation.
- Dans la section~\ref{sec:simplepdl2pn}, nous présentons le cas d'étude
- \emph{SimplePDLToPetriNet} tandis que dans la section~\ref{sec:aplatissement}
- nous présentons le cas de la transformation de l'aplatissement d'une hiérarchie
- de classes.
- \section{Cas \emph{SimplePDLToPetriNet}}
- \label{sec:simplepdl2pn}
- Dans cette section, nous présentons la transformation
- \emph{SimplePDLToPetriNet} introduite dans les chapitres précédents. Elle a été
- présentée et traitée par Benoît Combemale~\cite{combemale08}. Son principe est de
- transformer la représentation d'un processus exprimé avec le langage SimplePDL
- en sa représentation exprimée dans le formalisme des réseaux de Petri.
- L'intérêt de cette transformation dans la communauté est de travailler sur la
- vérification : dans le formalisme SimplePDL, il n'est pas possible de vérifier
- directement le processus décrit tandis que sous forme de réseau de Petri
- ---~qui est un modèle mathématique~---, il est tout à fait possible de
- l'utiliser avec un \emph{model-checker} pour en vérifier des propriétés.
- %\todo{[nécessaire de définir mathématiquement le réseau de Petri
- %(6-uplet places/transitions/arcs/marquage initial/arcs primaires/limite de
- %capacité, etc.) ou alors le MM suffira ?]}
- %Dans un premier temps, nous rappelons les métamodèles
- Nous rappelons d'abord les métamodèles permettant d'exprimer un processus que
- nous avons déjà présentés et expliqués précédemment,
- %Nous décrivons tout d'abord les métamodèles permettant d'exprimer un processus,
- puis nous donnons un exemple de processus décrit en SimplePDL ainsi que sa
- version sous forme de réseau de Petri.
- \subsection{Métamodèles}
- \subsubsection{Métamodèle source : formalisme SimplePDL}
- Nous reprenons le métamodèle~\ref{fig:simplesimplepdlmmodel} que nous
- complétons afin de pouvoir représenter des processus hiérarchiques. Nous
- ajoutons deux relations \emph{opposite} entre les métaclasses
- \emph{WorkDefinition} et \emph{Process}, les autres éléments restant identiques. Une \emph{WorkDefinition} peut ainsi
- être elle-même définie par un processus imbriqué (référence \emph{process}),
- qui conserve un lien vers l'activité qu'il décrit (référence \emph{from}). Nous
- obtenons le métamodèle illustré par la figure~\ref{fig:simplepdlmmodel}.
- \begin{figure}[h]%[fig:simplepdlmmodel]{Métamodèle SimplePDL.}%[H] %[!h]
- \begin{center}
- \input{figures/simplepdlmmodel}
- \caption{Métamodèle SimplePDL.}
- \label{fig:simplepdlmmodel}
- \end{center}
- \end{figure}
- %Le langage SimplePDL dont le métamodèle est donné
- %figure~\ref{fig:simplepdlmmodel} permet d'exprimer simplement des processus
- %génériques. Un processus (\emph{Process}) est composé d'éléments
- %(\emph{ProcessElement}). Chaque \emph{ProcessElement} référence son processus
- %\emph{parent} et peut être soit une \emph{WorkDefinition}, soit une
- %\emph{WorkSequence}. Une \emph{WorkDefinition} définit une activité qui doit
- %être effectuée durant le processus (un calcul, une action, {\etc}). Une
- %\emph{WorkSequence} définit quant à elle une relation de dépendance entre deux
- %activités. La deuxième (\emph{successor}) peut être démarrée ---~ou
- %terminée~--- uniquement lorsque la première (\emph{predecessor}) est déjà
- %démarrée ---~ou terminée~--- selon la valeur de l'attribut \emph{linkType} qui
- %peut donc prendre quatre valeurs : \emph{startToStart}, \emph{finishToStart},
- %\emph{startToFinish} ou \emph{finishToFinish}. Afin de pouvoir représenter des
- %processus hiérarchiques, une \emph{WorkDefinition} peut elle-même être définie
- %par un processus imbriqué (référence \emph{process}), qui conserve un lien vers
- %l'activité qu'il décrit (référence \emph{from}).
- \FloatBarrier
- \subsubsection{Métamodèle cible : formalisme des réseaux de Petri}
- Nous reprenons le métamodèle des réseaux de Petri proposé dans le
- chapitre~\ref{ch:traceability}, sans aucune modification additionnelle.
- La figure~\ref{fig:petrinetmmodel} est un rappel du métamodèle des réseaux
- de Petri que nous utilisons.
- %Le métamodèle donné par la figure~\ref{fig:petrinetmmodel} permet d'exprimer
- %les réseaux de Petri. Un tel réseau se définit par un ensemble de nœuds
- %(\emph{Node}) qui sont soit des places de type \emph{Place}, soit des
- %transitions de type \emph{Transition}, ainsi que par des arcs (\emph{Arc}). Un
- %arc (orienté) relie deux nœuds de types différents (le réseau de Petri est un
- %graphe biparti) et peut être de type \emph{normal} ou \emph{read-arc}. Il
- %spécifie le nombre de jetons (\emph{weight} ---~poids~---) consommés dans la
- %place source ou produits dans la place cible lorsqu'une transition est tirée. Un
- %\emph{read-arc} vérifie uniquement la disponibilité des jetons sans pour autant
- %les consommer (test de franchissement). Le marquage d'un réseau de Petri est
- %défini par le nombre de jetons dans chaque place (\emph{marking}).
- \begin{figure}[h]%[fig:petrinetmmodel]{Métamodèle PetriNet.}%[H] %[!h]
- \begin{center}
- \input{figures/petrinetmmodel}
- \caption{Métamodèle des réseaux de Petri.}
- \label{fig:petrinetmmodel}
- \end{center}
- \end{figure}
- \FloatBarrier
- \subsection{Exemple de processus et de réseau de Petri résultant}
- Nous décidons de traiter l'instance de SimplePDL suivante : le processus
- hiérarchique composé d'activités et de contraintes de précédence illustré par
- la figure~\ref{fig:simplepdlusecase}.
- \begin{figure}[h]
- \begin{center}
- \input{figures/simplepdlusecase}
- \caption{Exemple de processus décrit dans le formalisme SimplePDL.}
- \label{fig:simplepdlusecase}
- \end{center}
- \end{figure}
- Dans cet exemple, le processus \texttt{root} est composé de deux activités,
- \texttt{A} et \texttt{B}, reliées par une séquence \emph{start2start} notée
- \emph{s2s}, ce qui signifie que \texttt{B} peut démarrer uniquement si
- \texttt{A} a déjà démarré. \texttt{B} est elle-même décrite par un processus
- (\texttt{child}) composé de deux activités, \texttt{C} et \texttt{D} reliées
- par une séquence \emph{finish2start} notée \emph{f2s}. Ainsi, \texttt{C} doit
- être terminée pour que \texttt{D} puisse démarrer. Ce processus est
- conforme au métamodèle SimplePDL donné par la figure~\ref{fig:simplepdlmmodel}.
- Notre but est de transformer sa représentation actuelle en sa représentation
- sous forme d'un réseau de Petri. La figure~\ref{fig:petrinetusecase} est le
- résultat attendu pour cette transformation.
- \begin{figure}[h]
- \begin{center}
- %\begingroup
- %\tikzset{every picture/.style={scale=0.9}}%
- %\tikzset{global scale/.style={scale=0.9,every node/.style={scale=0.9}}}
- %\input{figures/petrinetusecase}
- %\scalebox{0.9}{\input{figures/petrinetusecase}}
- \resizebox{1.0\linewidth}{!}{\input{figures/petrinetusecase}}
- \caption{Réseau de Petri équivalent au processus décrit par la
- figure~\ref{fig:simplepdlusecase}.}
- \label{fig:petrinetusecase}
- %\endgroup
- \end{center}
- \end{figure}
- Dans cette figure ainsi que dans la suite du document, nous représentons les
- places par des cercles rouges, et les transitions par des carrés bleus. Les
- arcs de type \emph{normal} sont matérialisés par des flèches en trait plein
- noires, ou vertes dans le cas du résultat de la transformation d'une
- \emph{WorkSequence}. Ceux en pointillés correspondent aux synchronisations
- entre éléments, c'est-à-dire aux arcs de type \emph{read\_arc}.
- \FloatBarrier
- \subsection{Implémentation en utilisant les outils développés}
- %\ttodo{décomposition, explication des trois transformations, snippets de code,
- %code complet en annexe ; puis version optimale ? Transfos élémentaires : P2PN,
- %WD2PN et WS2PN.}
- Les métamodèles ainsi qu'un exemple de modèle d'entrée et son résultat attendu
- ayant été présentés, détaillons la transformation, ainsi que sa mise en œuvre
- avec nos outils. Pour améliorer la lisibilité ---~et donc la compréhension~---,
- les extraits de code apparaissant dans cette section sont légèrement simplifiés
- par rapport à l'implémentation réelle qui est donnée en
- annexe~\ref{annexe:pdl2pn}. Nous avons notamment supprimé certains paramètres
- et modifié des noms de variables (ajouts de préfixes $P$ et $WD$ par exemple)
- afin d'extraire l'essentiel du code en tâchant d'éviter toute confusion au
- lecteur. Nous avons aussi conservé une cohérence entre les schémas et les
- extraits de code.
- Pour transformer le processus décrit par la figure~\ref{fig:simplepdlusecase},
- on peut aisément isoler trois transformations élémentaires qui composent la
- transformation globale. Chacune d'entre elles transforme un type d'élément du
- modèle source : respectivement \emph{Process2PetriNet},
- \emph{WorkDefinition2PetriNet} et \emph{WorkSequence2PetriNet} pour les
- éléments \emph{Process}, \emph{WorkDefinition} et \emph{WorkSequence}. Ces
- transformations élémentaires sont implémentées par des sous-constructions
- \texttt{definition}.
- \paragraph{ProcessToPetriNet.} Un \emph{Process} SimplePDL est traduit par un
- réseau de Petri de la forme de celui donné par la
- figure~\ref{fig:PNProcess}. Cette transformation élémentaire est
- implémentée par la \emph{définition} \texttt{P2PN} donnée par le
- listing~\ref{code:p2pn}.
- \begin{figure}[h]
- \begin{center}
- \input{figures/PNProcess}
- \end{center}
- \caption{Réseau de Petri résultant de la transformation d'un \emph{Process}.}
- \label{fig:PNProcess}
- \end{figure}
- L'image d'un processus est donc constituée de trois places ($P_{p_{ready}}$,
- $P_{p_{running}}$ et $P_{p_{finished}}$), deux transitions ($P_{t_{start}}$ et
- $P_{t_{finish}}$) et quatre arcs. Dans le cas où il s’agit d'un processus
- hiérarchique, il peut y avoir un arc de synchronisation pointant vers la
- première place ($P_{p_{ready}}$) et un autre partant de la dernière place
- ($P_{p_{finished}}$).
- Techniquement, nous implémentons cette transformation élémentaire par une
- \emph{définition} comprenant une seule règle filtrant tous les éléments
- \emph{Process} du modèle source (ligne 2). Dans cette règle, seul le nom du
- processus nous importe, nous n'instancions donc que la variable \texttt{name}.
- Dans le membre droit de la règle, les places et arcs de l'image d'un
- \texttt{Process} sont créés comme tout terme {\tom}, en utilisant la
- construction \lex{backquote} (lignes 3 à 5, et 9 à 12). En revanche, pour créer
- les deux transitions \texttt{Pt\_start} et \texttt{Pt\_finish}, nous utilisons
- la construction \lex{\%tracelink} afin de \emph{tracer} ces deux éléments
- (lignes 6 et 7). Notons que ces transitions nouvellement créées et tracées
- sont immédiatement utilisées dans la construction des arcs du réseau de Petri.
- Le bloc de code des lignes 14 à 23 sert à la gestion des processus
- hiérarchiques : dans un tel cas, un processus possède un processus père qui est
- une \emph{WorkDefinition} non \texttt{null}, et il existe un traitement
- particulier. Il s'agit de créer des éléments \emph{resolve} par la construction
- \lex{\%resolve} (lignes 16 et 20) pour jouer le rôle de transitions créées dans
- une autre \emph{définition}. En effet, ces deux nœuds sont censés être créés
- par la transformation de \emph{WorkDefinitions} en réseaux de Petri. Ils sont
- représentés par les deux carrés bleus aux bords pointillés sur la
- figure~\ref{fig:PNProcess}. Les deux éléments \emph{resolve} peuvent être
- immédiatement utilisés dans la construction d'autres termes (lignes 18 et 22,
- arcs en pointillés sur la figure~\ref{fig:PNProcess}) ou avec {\java} (lignes
- 17 et 21).
- \begin{figure}[h]
- \begin{center}
- \input{code/defP2PN}
- \end{center}
- % \caption{\texttt{P2PN :} Code de la définition \emph{ProcessToPetriNet}.}
- % \label{code:p2pn}
- \end{figure}
- \FloatBarrier
- \paragraph{WorkDefinitionToPetriNet.} Une \emph{WorkDefinition} SimplePDL est
- traduite par un réseau de Petri de la forme de celui donné par la
- figure~\ref{fig:PNWorkDefinition}. Cette transformation élémentaire est
- implémentée par la \emph{définition} \texttt{WD2PN} donnée dans le
- listing~\ref{code:wd2pn}.
- \begin{figure}[h]
- \begin{center}
- \input{figures/PNWorkDefinition}
- \end{center}
- \caption{Réseau de Petri résultant de la transformation d'une \emph{WorkDefinition}.}
- \label{fig:PNWorkDefinition}
- \end{figure}
- Le réseau de Petri résultant de cette transformation élémentaire ressemble
- beaucoup à celui obtenu par transformation d'un \emph{Process}. Il se
- différencie par un arc et une place supplémentaires $WD_{p_{started}}$ après
- la transition $WD_{t_{start}}$. Ces éléments additionnels par rapport à l'image
- d'un \emph{Process} permettent l'ajout d'une séquence entre deux
- \emph{WorkDefinitions}. L'image d'une activité est donc constituée de quatre
- places ($WD_{p_{ready}}$, $WD_{p_{running}}$ et $WD_{p_{finished}}$,
- $WD_{p_{started}}$), deux transitions ($WD_{t_{start}}$ et $WD_{t_{finish}}$)
- et cinq arcs. Dans le cas où il s'agit d'un processus hiérarchique, deux arcs
- de synchronisation avec le processus parent sont présents : l'un venant de la
- transition $P_{t_{start}}$ de l'image du processus parent et pointant sur la
- place $WD_{p_{ready}}$, l'autre partant de $WD_{p_{finished}}$ et pointant sur
- la transition $P_{t_{finish}}$ de l'image du \emph{Process} parent.
- Cette \emph{définition} est implémentée par le bloc \texttt{definition}
- \texttt{WD2PN}, comprenant une règle similaire à celle de la \emph{définition}
- \texttt{P2PN}, la différence étant que nous filtrons des éléments de type
- \emph{WorkDefinition} et non plus \emph{Process} (ligne 2). Les places et les
- transitions sont créées grâce à la construction \lex{backquote} (lignes 3 et 5)
- ou {\via} \lex{\%tracelink} (lignes 4, 6, 7 et 8). Tous ces termes ---~tracés ou non~--- sont immédiatement
- utilisés pour construire les arcs du réseau de Petri résultant (lignes 10 à
- 14).
- En fin de bloc \texttt{definition} (lignes 16 à 25), les éléments
- intermédiaires \emph{resolve} représentés dans la
- figure~\ref{fig:PNWorkDefinition} par les deux carrés bleus avec les bords
- pointillés sont créés (lignes 19 et 23). Ils sont utilisés respectivement comme
- source et destination des arcs de synchronisation avec le processus parent
- créés lignes 23 et 27.
- \begin{figure}[h]
- \begin{center}
- \input{code/defWD2PN}
- \end{center}
- % \caption{\texttt{WD2PN :} Code de la définition \emph{WorkDefinitionToPetriNet}.}
- % \label{code:wd2pn}
- \end{figure}
- Le fait de tracer quatre éléments dans cette \emph{définition} aura pour
- conséquence de générer à la compilation une \emph{ReferenceClass} ayant quatre
- champs correspondants.
- \FloatBarrier
- \paragraph{WorkSequenceToPetriNet.} Une \emph{WorkSequence} SimplePDL est
- traduite par un réseau de Petri constitué d'un arc, comme illustré par la
- figure~\ref{fig:PNWorkSequence}. Cette transformation élémentaire est
- implémentée par la \emph{définition} \texttt{WS2PN} donnée par le
- listing~\ref{code:ws2pn}.
- \begin{figure}[h]
- \begin{center}
- \input{figures/PNWorkSequence}
- \end{center}
- \caption{Réseau de Petri résultant de la transformation d'une \emph{WorkSequence}.}
- \label{fig:PNWorkSequence}
- \end{figure}
- Dans cette \emph{définition}, seul un arc est créé à partir de l'élément source
- filtré (\emph{WorkSequence}). Cependant, tout arc ayant deux extrémités et ces
- deux extrémités étant des éléments obtenus lors de l'application d'autres
- transformations élémentaires, il est nécessaire de construire des éléments
- \emph{resolve}. Les extrémités de l'arc image dépendent du type de la
- \emph{WorkSequence} filtrée. Nous filtrons donc sur \texttt{linkType} (ligne 5)
- et, compte tenu des règles écrites et du fait que {\tom} donne toutes les
- solutions possibles du filtrage, nous avons la garantie que pour un type de
- contrainte de précédence donné, deux règles seront déclenchées (une parmi
- celles des lignes 6 et 9, l'autre parmi celles des lignes 13 et 16). Après
- exécution de ce bloc, les variables \texttt{source} et \texttt{target} sont
- bien initialisées et peuvent être utilisées pour construire l'arc image
- \texttt{wsImage} (ligne 23) de la séquence filtrée.
- \begin{figure}[h]
- \begin{center}
- \input{code/defWS2PN}
- \end{center}
- % \caption{\texttt{WS2PN :} code de la définition \emph{WorkSequenceToPetriNet}.}
- % \label{code:ws2pn}
- \end{figure}
- \FloatBarrier
- \paragraph{Transformation globale.}Ces blocs \texttt{definition} s'intègrent
- dans une transformation {\tom}+ {\java}
- dont la forme générale du code est donnée par le
- listing~\ref{code:transfoLightSimplePDL2PN}. Le code complet de la
- transformation est quant à lui donné dans l'annexe~\ref{annexe:pdl2pn} et est
- directement accessible dans le dépôt du
- projet\footnote{\url{https://gforge.inria.fr/scm/?group_id=78}}. Notons que
- cette transformation sert aussi de support pour la documentation sur le site
- officiel de
- {\tom}\footnote{\url{http://tom.loria.fr/wiki/index.php5/Documentation:Playing_with_EMF}}. Expliquons le reste du code de la transformation dans ses grandes lignes :
- \begin{itemize}
- \item[\textbf{début :}] Les points de suspension de la ligne 1 représentent
- du code java classique (\texttt{package} et \texttt{import}).
- \item[\textbf{ancrages :}] Au sein de la classe \texttt{SimplePDLToPetriNet},
- nous notons l'usage de plusieurs constructions \texttt{\%include}. Celle de
- la ligne 3 sert à charger les ancrages formels de la bibliothèque de
- stratégies, celle de la ligne 4 charge l'ancrage du modèle de lien (fourni
- comme bibliothèque) et celle de la ligne 5 permet de charger les types
- {\ecore}, eux aussi fournis sous la forme d'une bibliothèque. Les deux
- ancrages chargés lignes 7 et 8 ont été générés par {\tomemf}. Le bloc de
- code suivant montre des déclarations de variables et l'écriture d'un
- \emph{mapping} minimal permettant d'utiliser la classe
- \texttt{SimplePDLToPetriNet} comme un type {\tom}. Les points de suspension
- suivants représentent du code {\java} (déclarations de variables, {\etc}).
- \item[\textbf{transformation :}] Les trois \emph{définitions} constituent le
- corps d'un bloc \texttt{\%transformation} (lignes 18 à 29). Nous avons
- choisi de les écrire dans l'ordre dans lequel nous les avons présentées,
- cependant nous rappelons que \textbf{cet ordre n'a aucune importance} avec
- notre approche.
-
-
- \item[\textbf{main :}] Nous avons extrait une partie de \texttt{main()}.
- Avant l'extrait, il s'agit de contrôles ainsi que du code permettant de
- charger un modèle ou créer un modèle en {\tom} dans le cas où aucun fichier
- n'est passé en paramètre. L'extrait comprend quant à lui la création de la
- stratégie de transformation (ligne 38) ainsi que son appel (ligne 40). La
- \emph{stratégie de résolution} est appelée à la ligne 42. Étant générée, son
- nom est construit de manière prédictible pour l'utilisateur, à partir du
- nom de la transformation ainsi que d'un préfixe explicite
- (\texttt{tom\_StratResolve\_}). La stratégie appelée à la ligne 44 sert
- pour l'affichage du résultat de la transformation.
- \item[\textbf{fin :}] Le reste du code qui n'est pas montré dans le
- listing~\ref{code:transfoLightSimplePDL2PN} consiste en des méthodes
- d'affichage et de sérialisation pour obtenir un réseau de Petri compatible
- avec le format d'entrée du \emph{model-checker}
- {\tina}\footnote{\url{http://projects.laas.fr/tina}}~\cite{Berthomieu2004}.
- \end{itemize}
- \begin{figure}[h]
- \begin{center}
- \input{code/transfoLightSimplePDL2PN}
- \end{center}
- % \caption{Forme générale du code de la transformation \emph{SimplePDLToPetriNet}.}
- % \label{code:transfoLightSimplePDL2PN}
- \end{figure}
- \paragraph{Usage de cette transformation.}Cette transformation étant bien
- connue, elle nous a servi de support pour le développement de nos outils. Son
- intérêt étant de pouvoir vérifier formellement des propriétés de son résultat,
- nous avons dépassé le simple développement de la transformation pour vérifier
- nos résultats. C'est pour cette raison que le modèle cible est généré par
- défaut au format d'entrée de {\tina}. Cela nous permet de le visualiser et d'en
- vérifier des propriétés avec le \emph{model-checker}.
- Ainsi, nous avons pu exprimer une formule ainsi que des propriétés en logique
- temporelle linéaire (LTL) telles que la terminaison. Nous les avons ensuite
- vérifiées avec {\tina} sur le réseau de Petri résultant de la transformation.
- La formule, les propriétés ainsi que les résultats sont donnés en
- annexe~\ref{annexe:pdl2pn:mc} de ce document.
- \FloatBarrier
- \section{Aplatissement d'une hiérarchie de classes}
- \label{sec:aplatissement}
- Cette deuxième étude de cas avait pour but d'évaluer l'intérêt et les limites
- éventuelles des nouvelles constructions intégrées au langage {\tom}. Il s'agit
- d'une transformation endogène très simple : l'aplatissement d'une hiérarchie de
- classes. Nous disposons de classes, dont certaines héritent d'autres. Nous
- souhaitons aplatir cette hiérarchie en reportant les attributs des surclasses
- dans les classes qui sont les feuilles de l'arbre hiérarchique. Nous
- choisissons aussi de nommer les nouvelles classes reprenant tous les attributs
- hérités. Les classes qui ne sont pas impliquées dans une relation d'héritage ne
- changent pas.
- %\todo{Cet exemple a été implémenté, quelques remarques :
- %\begin{itemize}
- % \item implémentations : v1, v2, v3, v4
- %% \begin{enumerate}
- %% \item version récursive triviale (c'est tout de même en Tom+Java pour des
- %% raisons pratiques, mais sans \lex{\%transfo} et avec les mappings EMF)
- %% \item version avec une stratégie Tom, adaptation de la version
- %% précédente, mini-gain de lisibilité, je fais toujours appel à une
- %% fonction récursive écrite précédemment)
- %% \item version \lex{\%transfo} : pas intéressante dans le sens où elle est
- %% plus compliquée que les versions précédentes. Plus de code, pas de
- %% resolve nécessaire
- %% \end{enumerate}
- % \item Mais ce n'est pas pour autant que l'implémentation a été inutile, elle
- % m'a permis de faire plusieurs constats :
- % \begin{enumerate}
- % \item du point de vue du développeur, actuellement les constructions
- % haut-niveau ne sont vraiment utiles que si la transformation est
- % suffisamment complexe (comprendre « s'il faut du \emph{resolve} »).
- % Sans \emph{resolve}, je déconseille \lex{\%transformation}
- % \item Tom-EMF reste utile et intéressant même sans
- % \lex{\%transformation}. En fait j'ai peur que ce soit la partie là plus
- % utile et intéressante du code lié à ma thèse :$\backslash$ Finalement,
- % peut-être qu'il mériterait bien d'être vraiment revu et écrit
- % proprement.
- % \item Comment trouver de l'intérêt à ces constructions haut-niveau pour
- % une transfo peu complexe ? La traçabilité ! C'est un point intéressant
- % si j'arrive à l'implémenter.
- % \item il y a un gros problème d'implémentation dans mon transformer. Je
- % suis tombé sur des erreurs que je pensais
- % impossibles/absentes/corrigées.
- % \end{enumerate}
- %\end{itemize}
- %}
- Nous présentons un exemple de transformation dans la
- section~\ref{flattening:subsec:model} et le métamodèle dans la
- section~\ref{flattening:subsec:mm}. Pour évaluer et comparer, nous avons écrit
- plusieurs implémentations de cet exemple, que nous décrivons dans la
- section~\ref{flattening:subsec:impl}.
- \subsection{Exemple de transformation}
- \label{flattening:subsec:model}
- Nous considérons comme modèle source la hiérarchie de classes donnée par le
- membre gauche de la figure~\ref{fig:transfohierarchieclasses}. La classe
- \emph{C} possède un attribut \emph{attrC} de type \emph{C} et n'est dans aucune
- hiérarchie de classes. La classe \emph{B} est quant à elle dans une hiérarchie
- de classes : elle hérite de \emph{A} qui hérite elle-même de \emph{D},
- surclasse de toute la hiérarchie. La classe \emph{B} a deux attributs
- \emph{attrB1} et \emph{attrB2} de types \emph{C}. Cette transformation aplatit
- la hiérarchie et doit donc produire le modèle cible illustré par le membre
- droit de la figure~\ref{fig:transfohierarchieclasses}. Il s'agit d'un modèle
- constitué de deux classes : la classe \emph{C} ---~qui reste inchangée par
- rapport au modèle source~--- ainsi qu'une classe \emph{DAB} qui rassemble tous
- les attributs de la hiérarchie de classe aplatie.
- %figure~\ref{fig:hierarchieclassesIN}.
- %\begin{figure}[!h]
- % \begin{center}
- % \input{figures/hierarchieclassesIN}
- % \caption{Hiérarchie de classes.}
- % \label{fig:hierarchieclassesIN}
- % \end{center}
- %\end{figure}
- %
- %\begin{figure}[!h]
- % \begin{center}
- % \input{figures/hierarchieclassesOUT}
- % \caption{Hiérarchie de classes aplatie.}
- % \label{fig:hierarchieclassesOUT}
- % \end{center}
- %\end{figure}
- \begin{figure}[h]
- \begin{center}
- \begin{tabular}{m{0.4\linewidth}m{0.1\linewidth}m{0.4\linewidth}}
- \input{figures/hierarchieclassesIN} & \textbf{$\longrightarrow$} &
- \input{figures/hierarchieclassesOUT}\\
- \centering{(a)} && \centering{(b)}\\
- \end{tabular}
- \caption{Aplatissement d'une hiérarchie de classes.}
- \label{fig:transfohierarchieclasses}
- \end{center}
- \end{figure}
- \FloatBarrier
- \subsection{Métamodèle}
- \label{flattening:subsec:mm}
- S'agissant d'une transformation endogène, le métamodèle source est identique au
- métamodèle cible. Pour cette transformation, nous utilisons le métamodèle
- simplifié d'{\uml} donné par la figure~\ref{fig:simplifiedumlmmodel}.
- \begin{figure}[h]
- \begin{center}
- \input{figures/simplifiedumlmmodel}
- \caption{Métamodèle d'{\uml} simplifié.}
- \label{fig:simplifiedumlmmodel}
- \end{center}
- \end{figure}
- Les \emph{Classifiers} sont des éléments ayant un nom et étant de type
- \emph{DataType} ou de type \emph{Class}. Un élément \emph{Class} peut avoir des
- attributs (\emph{Attribute}), qui sont eux-mêmes des \emph{Classifiers}. Dans
- notre contexte technique, nous avons besoin d'une racine afin d'obtenir un
- arbre de recouvrement. Nous avons donc ajouté une racine virtuelle dans le
- métamodèle ---~élément \emph{VirtualRoot}~--- qui contient tous les
- \emph{Classifiers} (relation de composition).
- Pour les besoins de l'étude et afin de simplifier les explications et le
- développement, nous avons considéré une version épurée du métamodèle
- %extrait l'essentiel du métamodèle ce qui le réduit au métamodèle
- illustré par la figure~\ref{fig:verysimplifiedumlmmodel}.% : dans ce
- %métamodèle, nous supprimons \emph{Classifier} et \emph{DataType}, nous obtenons
- %un métamodèle minimaliste suffisant pour notre exposé.
- %Il s'agit du métamodèle minimal pour notre exposé.
- %\todo{insert MM flatening.ecore}
- \begin{figure}[h]
- \begin{center}
- \input{figures/verysimplifiedumlmmodel}
- \caption{Métamodèle considéré pour l'étude de cas.}
- \label{fig:verysimplifiedumlmmodel}
- \end{center}
- \end{figure}
- \FloatBarrier
- \subsection{Implémentation utilisant les outils développés}
- \label{flattening:subsec:impl}
- %\todo{Comparaison : Java récursif (avec un peu de Tom), Tom+Java stratégie +
- %récursion, Tom+Java \lex{\%transformation} $\rightarrow$ ok}
- Nous avons implémenté cet exemple de plusieurs manières afin de comparer
- l'intérêt d'utiliser les outils développés durant cette thèse pour la
- transformation de modèles :
- \begin{enumerate}
- %V1_notom_UMLClassesFlattening.java
- \item La première version de cette implémentation est écrite en pur {\java}
- (+{\emf}), sans l'aide de {\tom}, des nouvelles constructions et des outils
- liés tels que {\tomemf}. Il s'agit d'une version mêlant récursivité et
- itération ;
- %V2_nostrat_UMLClassesFlattening.t
- \item la deuxième version est écrite en {\tomjava} mais sans user des
- stratégies ni de la nouvelle construction \lex{\%transformation}. En
- revanche, nous avons utilisé {\tomemf} pour générer les \emph{mappings} ;
- %V3_stratnotransfo_UMLClassesFlattening.t
- \item la troisième implémentation est une application de la méthode présentée
- dans~\cite{Bach2012}, à savoir l'écriture d'une transformation en utilisant
- les stratégies de réécriture, mais sans la construction haut niveau
- \lex{\%transformation} ;
- %V4_transfo_UMLClassesFlattening.t
- \item la quatrième et dernière version utilise les outils développés dans le
- cadre de cette thèse.
- \end{enumerate}
- Pour des raisons de lisibilité, nous faisons uniquement apparaître des extraits
- significatifs de code de cette transformation dans cette section. Le code
- complet des implémentations est donné dans l'annexe~\ref{annexe:flattening}.
- %\begin{description}
- % \item[Version 0 :] transformation en Java EMF pur, de manière récursive
- % \item[Version 1 :] intégration d'un peu de code Tom (\emph{mappings} et
- % \lex{\%match})
- % \item[Version 2 :] utilisation d'une stratégie Tom en plus du code Tom de la
- % version précédente
- % \item[Version 3 :] utilisation de la construction dédiée aux transformations
- % de modèles \lex{\%transformation}
- %\end{description}
- \paragraph{Version 1 : {\java-\emf}.}
- L'implémentation en {\java}-{\emf} d'une telle transformation se révèle sans
- véritable difficulté. Le principe est de parcourir les classes du modèle source
- et d'appliquer un aplatissement récursif sur celles qui sont les feuilles de
- l'arbre d'héritage. Cette transformation peut être implémentée en environ 40
- lignes de code, comme le montre le listing~\ref{code:v1flattening} (code
- complet en annexe~\ref{annexe:flattening:v1}).
- \begin{figure}[h]
- \begin{center}
- \input{code/v1flattening}
- \end{center}
- % \caption{Implémentation de la transformation d'aplatissement de hiérarchie de classes en Java.}
- % \label{code:v1flattening}
- \end{figure}
- Les pré-requis pour cette version de la transformation sont de maîtriser
- {\java} et de connaître un minimum {\emf} afin d'être en mesure d'écrire les
- appels adéquats pour créer un élément. Un défaut de cette implémentation est la
- lisibilité du code, le langage {\java} ainsi que le \emph{framework} {\emf}
- étant particulièrement verbeux.
- \paragraph{Version 2 : {\tomjava-\emf}.}
- Pour remédier à ce désagrément ---~qui peut devenir un enjeu fort dans le cadre
- de la maintenance logicielle industrielle~--- nous avons modifié
- l'implémentation initiale avec {\tom}, afin d'user de ses facilités d'écriture.
- L'utilisation de la construction \lex{\%match} (filtrage de motif) ainsi que du
- \emph{backquote} (création et manipulation de termes) permettent notamment
- d'améliorer la lisibilité du programme. Le listing~\ref{code:v2flattening} est
- le code résultant de l'évolution du précédent listing, intégrant du code {\tom}
- simple (le code complet est donné dans l'annexe~\ref{annexe:flattening:v2}).
- \begin{figure}[h]
- \begin{center}
- \input{code/v2flattening}
- \end{center}
- % \caption{Implémentation de la transformation d'aplatissement de hiérarchie de classes en Tom+Java.}
- % \label{code:v2flattening}
- \end{figure}
- Cet extrait de code est plus concis que la version en pur {\java} et
- {\emf} (moins de 25 lignes pour la transformation elle-même), mais il est
- surtout plus lisible. Pour utiliser la construction \lex{backquote} (\lex{`})
- comme nous le faisons dans ce listing, des ancrages algébriques sont
- nécessaires. Nous avons bien évidemment utilisé notre générateur d'ancrages
- formels {\tomemf} plutôt que de les écrire manuellement. L'utilisateur n'a
- donc pas de travail additionnel à fournir par rapport à une transformation en
- pur {\java} et {\emf} autre que la commande de génération (dans la précédente
- version, l'utilisateur doit aussi écrire le métamodèle et générer le code
- {\emf} avec {\eclipse}).
- %\todo{(implémentation Tom+Java \%strategy)}
- \paragraph{Version 3 : {\tomjava-\emf} avec stratégies.}
- Les stratégies étant un aspect important de {\tom}, nous écrivons une autre
- version de cette transformation les utilisant. C'est l'occasion de mettre en
- œuvre la méthode présentée dans~\cite{Bach2012}. Dans cette nouvelle
- implémentation (extrait dans le listing~\ref{code:v3flattening}, code complet
- en annexe~\ref{annexe:flattening:v3}), nous utilisons toujours les ancrages
- algébriques générés par {\tomemf} et nous ajoutons une stratégie {\tom}.
- L'usage des stratégies avec des modèles {\emf \ecore} implique aussi
- l'utilisation de l'outil \emph{EcoreContainmentIntrospector} présenté
- dans~\ref{ch:outils:subsec:tomemf}. Pour rappel, il permet le parcours des
- modèles {\emf \ecore} vus sous leur forme de termes.
- \begin{figure}[h]
- \begin{center}
- \input{code/v3flattening}
- \end{center}
- % \caption{Version 3 : Implémentation de la transformation d'aplatissement de hiérarchie de classes en Tom+Java avec stratégies.}
- % \label{code:v3flattening}
- \end{figure}
- Habituellement, l'utilisation des stratégies {\tom} simplifie systématiquement
- et grandement l'écriture de code ainsi que sa lisibilité, le parcours
- ---~traité par les bibliothèques que nous fournissons~--- étant séparé du
- traitement. Cependant, après écriture et exécution de la transformation, nous
- nous apercevons que la transformation n'est ni véritablement plus courte, ni
- plus lisible, ni plus efficace que les implémentations précédentes.
- C'est en observant plus précisément le métamodèle de notre exemple, la
- transformation attendue ainsi que l'outil permettant l'utilisation des
- stratégies que l'on identifie la raison. Un modèle {\emf} a une racine unique
- par la relation de composition et peut donc être représenté sous la forme d'un
- arbre, comme nous le faisons dans {\tom}. La figure~\ref{fig:treeexamples}
- illustre ce mécanisme appliqué aux modèles sources des deux exemples que nous
- présentons dans ce chapitre.
- %\begin{figure}[h!]
- % \begin{center}
- % \begin{tabular}{m{0.45\linewidth}m{0.45\linewidth}}
- % \input{figures/treeexample1} & \input{figures/treeexample2} \\
- % \centering{(a)} & \centering{(b)} \\
- % \end{tabular}
- % \caption{Arbres représentant les modèles source des exemples
- % \emph{SimplePDLToPetriNet} (a) et \emph{ClassFlattening} (b).}
- % \label{fig:treeexamples}
- % \end{center}
- %\end{figure}
- \begin{figure}[!h]
- \begin{center}
- %\begin{subfigure}[]{0.45\textwidth}
- \begin{subfigure}{0.45\linewidth}
- \input{figures/treeexample1}
- %\caption{Arbre représentant le modèle source de l'exemple \emph{SimplePDLToPetriNet}.}
- \caption{\emph{SimplePDLToPetriNet}.}
- \label{fig:treeexample1}
- \end{subfigure}
- \qquad %\qquad
- \begin{subfigure}{0.45\linewidth}
- \input{figures/treeexample2}
- %\caption{Arbre représentant le modèle source de l'exemple \emph{ClassFlattening}.}
- \caption{\emph{ClassFlattening}.}
- \label{fig:treeexample2}
- \end{subfigure}
- \caption{Arbres représentant les modèles source des exemples \emph{SimplePDLToPetriNet} (a) et \emph{ClassFlattening} (b).}
- \label{fig:treeexamples}
- \end{center}
- \end{figure}
- Dans cette figure, les deux termes sont représentés de manière classique : la
- racine est en haut, les feuilles en bas. Un losange noir ---~le symbole de la
- relation de composition en modélisation~--- a été ajouté à chaque endroit où la
- relation est une relation de composition, c'est-à-dire à chaque relation
- père-fils. L'arbre est bien un arbre par la relation de composition.
- Si l'on examine la figure~\ref{fig:treeexample1}, nous nous apercevons que les
- relations de sa structure correspondent à celles qui nous intéressent dans
- l'exemple, à savoir les relations de composition. En revanche, dans le cas de
- l'exemple de l'aplatissement d'une hiérarchie de classes, la relation entre
- éléments qui nous intéresse véritablement est la relation d'héritage, modélisée
- par une relation bidirectionnelle \emph{subclass}--\emph{superclass} et non par
- une relation de composition. Nous représentons ces relations \og intéressantes
- \fg dans la figure~\ref{fig:treeexample2} par des flèches rouges. La seule
- relation de composition de cet exemple est une relation de composition
- artificielle que nous avons créée (ainsi que l'élément de type
- \emph{VirtualRoot}) afin d'avoir une racine et donc de pouvoir écrire ce modèle
- {\emf} {\ecore}. Notre outil \emph{EcoreContainmentIntrospector} descendra
- bien dans les arbres, mais dans le cas du second exemple, il ne servira qu'à
- obtenir tous les fils de cette racine virtuelle qui sont à plat. Ensuite, pour
- l'aplatissement en lui-même, nous faisons tout de même appel à une fonction
- \texttt{flattening()} récursive, que nous utilisions ou non des stratégies.
- %\todo{(implémentation Tom+Java \%transformation)}
- Passé ce constat, la dernière version de l'implémentation reposant elle aussi
- sur les stratégies de réécriture mais avec les nouvelles constructions, nous
- pouvons supposer qu'elle ne sera pas meilleure (plus lisible, plus concise et
- plus efficace). Nous constatons effectivement que l'implémentation est moins
- lisible et moins concise, avec une efficacité similaire. Différents facteurs
- permettent d'expliquer ce résultat : d'une part, comme pour la version
- précédente, les relations nous intéressant ne sont pas celles constituant
- l'arbre de recouvrement, d'autre part, cette transformation est trop simple pour
- tirer parti de nos outils. Expliquons plus en détail cet aspect. Dans cette
- transformation, nous ne pouvons extraire plusieurs transformations
- élémentaires. La transformation globale sera donc constituée d'une seule
- \emph{définition}, encodée par une stratégie de réécriture, comme dans la
- version précédente de l'implémentation. Ainsi, le gain habituellement apporté
- par la construction \lex{\%transformation} est complètement absent. Outre ce
- point, nous constatons qu'aucun élément en cours de transformation
- ne nécessite le résultat d'un autre élément devant être transformé. Il n'y a
- donc pas besoin d'introduire d'élément \emph{resolve} dans la transformation.
- L'un des apports de nos outils étant de gérer l'ordonnancement des pas
- d'exécution en générant une stratégie de résolution, son intérêt reste limité
- pour cette transformation.
- Finalement, nous pouvons donc déduire de cet exemple que nos outils ne sont pas
- pleinement adaptés à toutes les transformations. Dans ces quatre
- implémentations, la deuxième version semble être le compromis le plus
- judicieux. Le générateur de \emph{mappings} y joue un rôle majeur, nous
- utilisons une partie du langage {\tom}, en revanche nous nous passons des
- constructions plus complexes telles que les stratégies ainsi que les nouvelles
- constructions intégrées durant cette thèse. Cependant, les nouvelles
- constructions pour de tels exemples ne sont pas pour autant inintéressantes :
- en effet, si la résolution (et sa construction associée \lex{\%resolve})
- n'apporte pas de gain, il subsiste le second aspect de nos travaux, à savoir la
- traçabilité. L'utilisation de la construction \lex{\%tracelink} afin de générer
- un modèle de lien reste possible.
- Une autre conclusion de l'étude de cet exemple est que nous avons
- développé nos outils en visant la couverture d'un grand nombre de
- transformations, notamment celles où les relations de composition sont au cœur.
- Une perspective serait maintenant de travailler à l'élaboration d'outils gérant
- d'autres relations ou étant plus génériques. Nous pensons notamment à des
- stratégies de réécriture que nous pourrions paramétrer par des types de
- relations à suivre.
- %point, nous constatons que cette transformation ne nécessite pas du tout
- %d'éléments \emph{resolve}. En effet, aucun élément en cours de transformation
- \section{Synthèse}
- Dans ce chapitre, nous avons présenté deux cas d'étude pour deux objectifs
- distincts : \emph{SimplePDLToPetriNet} et \emph{UMLHierarchyFlattening}. La
- transformation \emph{SimplePDLToPetriNet} nous a permis de présenter
- l'utilisation des outils que nous avons développés durant cette thèse en
- déroulant complètement une transformation. La seconde étude de cas nous a
- permis de donner une première évaluation de nos outils dans un contexte où ils
- ne peuvent donner leur pleine mesure.
- L'objectif de cette seconde étude de cas était de repérer les points
- d'amélioration de nos outils, tant dans leur mise en œuvre actuelle
- qu'envisagée, et de nous donner de nouvelles perspectives techniques et
- scientifiques. En effet, si cette étude de cas nous a montré que nos outils
- n'étaient pas tous adaptés dans toutes les situations, elle nous a permis en
- revanche de relever un point intéressant. La relation de composition dans les
- modèles est centrale et se retrouve bien souvent au cœur des transformations de
- modèles. Dans notre contexte, elle nous permet d'avoir la vision arborescente
- des modèles que nous pouvons parcourir. Cependant, pour certaines
- transformations comme celle d'aplatissement d'une hiérarchie de classes, la
- relation d'intérêt n'est pas celle de composition. Partant de ce constat, il
- est intéressant de se poser la question de la généralisation des stratégies
- pour les transformations de modèles. Une piste est la paramétrisation des
- stratégies par le type de relation à suivre lors de la traversée des termes.
- Dans un premier temps, pour tester la validité de ce principe, on pourrait
- implémenter un \emph{introspecteur} dédié à d'autres types de relations
- (héritage notamment). Cette extension lèverait la limitation révélée par la
- seconde étude de cas. Ensuite, une seconde question d'intérêt serait de
- travailler sur la possibilité de paramétrer dynamiquement une stratégie :
- est-il possible de changer le type de lien à suivre en cours de parcours ? %,
- %et donc de changer de
- %stratégie de réécriture selon le contexte ? cas d'application : réécriture
- %conditionnelle Un cas d'application serait alors la réécriture con
- Ce type de mécanisme permettrait de déclencher localement une stratégie avec un
- autre type de parcours, et donc d'adopter une stratégie de réécriture en
- fonction du contexte.
- Le premier exemple nous a aussi servi de support pour le développement de nos
- outils, et notre confiance en notre implémentation de cette transformation
- étant forte, nous nous en sommes aussi servi pour mener des expériences que
- nous présentons dans le chapitre suivant.%~\ref{ch:evaluation}.
- % vim:spell spelllang=fr
|