% 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
