ch-tom.tex 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342
  1. % vim:spell spelllang=fr
  2. \chapter{Un langage basé sur la réécriture : Tom}
  3. \label{ch:tom}
  4. %15p
  5. \index{\tom|(}
  6. %\ttodo{Autres points à voir :
  7. % \begin{itemize}
  8. %\item autres : notation implicite vs explicite (parenthèses vs crochets
  9. % dans filtrage, dans backquote) ; alias -> sous-partie notations diverses,
  10. % ou à diluer dans le reste ?
  11. %\item théories (utile ici ?)
  12. %\item règles de normalisation (module rule utile ici ?)
  13. %\item intro DSL ?, topo fonctionnement global de {\tom}, schéma compilateur
  14. % {\tom} pour expliquer, phases ?
  15. %\item exemple simple : Peano ? toujours le même mais connu ; Nat tout le
  16. % temps ou implém' directement par des int ? (mappings)
  17. %\end{itemize}}
  18. Dans ce chapitre, nous abordons les notions élémentaires utiles à la lecture de
  19. ce document. Nous présentons d'abord la réécriture de termes, puis nous
  20. décrivons le langage {\tom}~\cite{Moreau2003,Balland2007} et nous terminons par
  21. les ancrages formels.
  22. %\ttodo{ref bibtex d'un ouvrage de référence pour les déf}
  23. %nous présentons le langage {\tom} ainsi que les notions
  24. %élémentaires utiles à la lecture de ce tapuscrit.
  25. %\ttodo{tom == adjonction catégorique}
  26. \section{Réécriture}
  27. \subsection{Signature algébrique et termes}
  28. Cette section traite des notions de base concernant les algèbres de termes du
  29. premier ordre.
  30. \begin{definition}[Signature]
  31. Une signature \caF est un ensemble fini d'opérateurs (ou symboles de fonction),
  32. dont chacun est associé à un entier naturel par la fonction d'arité, $ar : \caF
  33. \rightarrow \nat$. $\caF_n$ désigne le sous-ensemble de symboles d'arité n,
  34. c'est-à-dire $\caF_n = \{ f \in \caF \mid ar(f) = n\}$.
  35. L'ensemble des constantes est désigné par $\caF_0$.
  36. \end{definition}
  37. %\ttodo{Signature algébrique multi-sortée à définir comme j'en parle plus tard +
  38. %sorte aussi donc, juste ici ; sorte = type de type, définition ci-après suffit
  39. %?}
  40. On classifie parfois les termes selon leur type dans des \emph{sortes}. On
  41. parle alors de signature multi-sortée.
  42. \begin{definition}[Signature algébrique multi-sortée]
  43. Une signature multi-sortée est un couple \SF où \caS est un ensemble de sortes
  44. et \caF est un ensemble d'opérateurs sortés défini par $\caF = \bigcup
  45. \limits_{S_1,\ldots,S_n, S \in \caS} \caF_{S_1,\ldots,S_n,S}$. Le rang d'un
  46. symbole de fonction $f \in \caF_{S_1,\ldots,S_n,S}$ noté $rank(f)$ est défini
  47. par le tuple ($S_1$,\ldots,$S_n$,S) que l'on note souvent $f : S_1 \times
  48. \ldots \times S_n \rightarrow S$
  49. \end{definition}
  50. \begin{definition}[Terme]
  51. Étant donné un ensemble infini dénombrable de variables \caX et une signature
  52. \caF, on définit l'ensemble des termes \TFX comme le plus petit ensemble tel
  53. que :
  54. \begin{itemize}
  55. \item \caX $\subseteq$ \TFX : toute variable de \caX est un terme de \TFX ;
  56. \item pour tous $t_1,\ldots,t_n$ éléments de \TFX et pour tout opérateur $f \in
  57. \caF$ d'arité n, le terme $f(t_1,\ldots,t_n)$ est un élément de \TFX.
  58. \end{itemize}
  59. \end{definition}
  60. %\ttodo{donc définir ce qu'est une variable}
  61. Pour tout terme $t$ de la forme $f(t_1,\ldots,t_n)$, le symbole de tête de $t$,
  62. noté $symb(t)$ est, par définition, l'opérateur $f$.\\
  63. Un symbole de fonction dont l'arité est variable est appelé \emph{opérateur
  64. variadique}, c'est-à-dire qu'il prend un nombre arbitraire d'arguments.
  65. \begin{definition}[Variables d'un terme]
  66. L'ensemble \var{t} des variables d'un terme t est défini inductivement comme
  67. suit :
  68. \begin{itemize}
  69. \item \var{t} = $\emptyset$, pour t $\in \caF_0$ ;
  70. \item \var{t} = \{t\}, pour t $\in \caX$ ;
  71. %\item \var{t} = $\bigcup \limits_{i=1}^n \var{t_i}$, pour $t = f(t_1, \ldots, t_n)$.
  72. \item \var{t} = $\bigcup_{i=1}^n \var{t_i}$, pour $t = f(t_1, \ldots, t_n)$.
  73. \end{itemize}
  74. \end{definition}
  75. On note souvent $a,b,c,\ldots$ les constantes et $x,y,z,\ldots$ les
  76. variables.\\
  77. On représente les termes sous forme arborescente. Par exemple,
  78. %la figure~\ref{fig:ex_terme} illustre la représentation du terme $f(x,g(a))$ :
  79. on peut
  80. représenter le terme $f(x,g(a))$ comme dans la figure~\ref{fig:ex_terme} :
  81. \begin{figure}[H]
  82. \begin{center}
  83. \input{figures/ex_terme}
  84. \caption{Exemple de représentation arborescente d'un terme.}
  85. \label{fig:ex_terme}
  86. \end{center}
  87. \end{figure}
  88. %\ttodo{donc définir aussi la position}
  89. \begin{definition}[Terme clos]
  90. Un terme t est dit clos s'il ne contient aucune variable, c'est-à-dire si $\var{t} = \emptyset$. On note \TF l'ensemble des termes clos.
  91. \end{definition}
  92. Chaque nœud d'un arbre peut être identifié de manière unique par sa position.
  93. \begin{definition}[Position]
  94. Une position dans un terme t est représentée par une séquence $\omega$
  95. d'entiers naturels, décrivant le chemin de la racine du terme jusqu'à un nœud
  96. $t_{|\omega}$ du terme. Un terme $u$ a une occurrence dans $t$ si $u =
  97. t_{|\omega}$ pour une position $\omega$ dans $t$.
  98. \end{definition}
  99. On notera ${\caP}os(t)$ l'ensemble des positions d'un terme $t$ et
  100. $t[t']_{\omega}$ le remplacement du sous-terme de $t$ à la position $\omega$
  101. par $t'$.
  102. Par exemple, la figure~\ref{fig:ex_positions} illustre la notation des
  103. positions pour le terme $t = f(x,g(a))$. On obtient l'ensemble des positions
  104. ${\caP}os(t)$ = $\{\epsilon, 1, 2, 21\}$ ce qui correspond respectivement aux
  105. sous-termes $t_{|\epsilon} = f(x,g(a))$, $t_{|1} = x$, $t_{|2} = g(a)$ et
  106. $t_{|21} = a$.
  107. \begin{figure}[H]
  108. \begin{center}
  109. \input{figures/ex_positions}
  110. \caption{Notation des positions dans un terme.}
  111. \label{fig:ex_positions}
  112. \end{center}
  113. \end{figure}
  114. %\textbf{Notations :}
  115. %\begin{itemize}
  116. % \item ${\caP}os(t)$ est l'ensemble des positions d'un terme $t$ ;
  117. % \item $t[t']_{\omega}$ indique le remplacement du sous-terme de $t$ à la
  118. % position $\omega$ par $t'$
  119. % \item $t[\omega \hookleftarrow \sigma(r)]$ signifie que le sous-terme de $t$
  120. % à la position $\omega$ a été remplacé par $\sigma(r)$.
  121. %\end{itemize}
  122. \subsection{Filtrage}
  123. \label{subsec:filtrage}
  124. %FIXME\ttodo{ajouter une phrase de liant}
  125. Une substitution est une opération de remplacement, uniquement définie par une
  126. fonction des variables vers les termes clos.
  127. \begin{definition}[Substitution]
  128. Une substitution $\sigma$ est une fonction de \caX vers \TF, notée lorsque son
  129. domaine $\dom{\sigma}$ est fini, $\sigma = \{x_1 \mapsto t_1, \ldots, x_k
  130. \mapsto t_k\}$. Cette fonction s'étend de manière unique en un endomorphisme
  131. $\sigma' : \TFX \rightarrow \TFX$ sur l'algèbre des termes, qui est défini
  132. inductivement par :
  133. \begin{itemize}
  134. \item $\sigma'(x) = \left\{
  135. \begin{array}{l}
  136. \sigma(x) \text{ si } x \in \dom{\sigma}\\
  137. x \text{ sinon}\\
  138. \end{array} \right.$
  139. \item $\sigma'(f(t_1,\ldots,t_n)) = f(\sigma'(t_1),\ldots,\sigma'(t_n))$ pour
  140. tout symbole de fonction $f \in \caF_n$.
  141. \end{itemize}
  142. \end{definition}
  143. %\ttodo{donc définir aussi algèbre de termes T(S,F,V) ?}
  144. \begin{definition}[Filtrage]
  145. Étant donnés un motif p $\in$ \TFX et un terme clos t $\in$ \TF, p filtre t,
  146. noté $p \match t$, si et seulement s'il existe une substitution $\sigma$ telle que
  147. $\sigma(p) = t$ :
  148. $$ p \match t \Leftrightarrow \exists \sigma, \sigma(p) = t $$
  149. \end{definition}
  150. %\ttodo{remarques de PEM : algo de filtrage, existe ?, décidabilité ?\\ filtrage
  151. %unitaire, filtrage syntaxique}
  152. %
  153. %\ttodo{oui, il existe des algos de filtrage :\\
  154. %filtrage syntaxique $\Rightarrow$ algo récursif, solution unique si existe,
  155. %thèse de Gérard Huet~\cite{Huet1976}}
  156. On parle de \emph{filtrage unitaire} lorsqu'il existe une unique solution à
  157. l'équation de filtrage. Si plusieurs solutions existent, le filtrage est
  158. \emph{non unitaire}.
  159. %Le filtrage peut aussi être \emph{syntaxique} ou \emph{modulo une théorie
  160. %équationnelle}. Dans ce second cas, cela signifie que l'on a associé une
  161. Le filtrage peut aussi être \emph{modulo une théorie équationnelle}. Cela
  162. signifie que l'on a associé une théorie équationnelle au problème de filtrage.
  163. \begin{definition}[Filtrage modulo une théorie équationnelle]
  164. Étant donnés une théorie équationnelle \caE, un motif $p$ $\in$ \TFX et un
  165. terme clos $t$ $\in$ \TF, $p$ filtre $t$ modulo \caE,
  166. noté $p \match_{\caE} t$, si et seulement s'il existe une substitution $\sigma$ telle que
  167. $\sigma(p) =_{\caE} t$, avec $=_{\caE}$ l'égalité modulo $\caE$ :
  168. $$ p \match_{\caE} t \Leftrightarrow \exists \sigma, \sigma(p) =_{\caE} t $$
  169. \end{definition}
  170. Dans la suite de cette section, nous allons expliquer ce concept, donner des
  171. exemples de théories équationnelles et illustrer notre propos.
  172. %\subsection{Théorie équationnelle}
  173. Une paire de termes $(l,r)$ est appelée \emph{égalité}, \emph{axiome
  174. équationnel} ou \emph{équation} selon le contexte, et est notée $(l=r)$. Une
  175. théorie équationnelle peut être définie par un ensemble d'égalités. Elle
  176. définit une classe d'équivalence entre les termes.
  177. Dans la pratique, les théories équationnelles les plus communes sont
  178. l'associativité, la commutativité et l'élément neutre (ainsi que leurs
  179. combinaisons).
  180. \begin{definition}[Opérateur associatif]
  181. Un opérateur binaire $f$ est associatif si $\forall x,y,z \in \TFX, f(f(x,y),z) =
  182. f(x,f(y,z))$.
  183. \end{definition}
  184. Par exemple, l'addition et la multiplication sont associatives sur l'ensemble
  185. des réels $\mathbb{R}$ : $((x+y)+z) = (x+(y+z))$ et $((x\times y)\times z)) =
  186. (x\times (y\times z))$. En revanche, la soustraction sur $\mathbb{R}$ n'est pas
  187. associative : $((x-y)-z) \neq (x-(y-z))$.
  188. \begin{definition}[Opérateur commutatif]
  189. Un opérateur binaire $f$ est commutatif si $\forall x,y \in \TFX f(x,y) =
  190. f(y,x)$.
  191. \end{definition}
  192. Par exemple, l'addition et la multiplication sont commutatives sur
  193. $\mathbb{R}$, ainsi $x+y = y+x$ et $x\times y = y\times x$. Ce qui n'est pas le
  194. cas de la soustraction sur $\mathbb{R}$, en effet $x-y \neq y-x$.
  195. \begin{definition}[Élément neutre]
  196. Soit un opérateur binaire $f$ et $x \in \TFX$, la constante $e \in \TF$ est :
  197. \begin{itemize}
  198. \item neutre à gauche pour $f$ si $f(e,x) = x$ ;
  199. \item neutre à droite pour $f$ si $f(x,e) = x$ ;
  200. \item neutre si elle est neutre à gauche et neutre à droite pour $f$.
  201. \end{itemize}
  202. \end{definition}
  203. %Pour illustrer la notion d'élément neutre
  204. %Ainsi, 0 est neutre pour l'addition sur $\mathbb{R}$ car : $0+x = x$ et $x+0 = x$.
  205. Pour illustrer cette notion d'élément neutre, examinons la constante 0 avec
  206. l'addition sur l'ensemble des réels $\mathbb{R}$ :
  207. \begin{itemize}
  208. \item $0+x = x$, 0 est donc neutre à gauche pour l'addition ;
  209. \item $x+0 = x$, 0 est donc neutre à droite pour l'addition ;
  210. \item on en déduit que 0 est neutre pour l'addition sur $\mathbb{R}$.
  211. \end{itemize}
  212. On note généralement $A$, $U$ et $C$ les théories équationnelles engendrées
  213. respectivement par l'équation d'associativité, l'équation de neutralité et
  214. celle de commutativité. On note $AU$ la théorie engendrée par les équations
  215. d'associativité et de neutralité.
  216. La théorie associative est associée aux opérateurs binaires. Pour des raisons
  217. techniques, elle est souvent associée à une syntaxe variadiques dans les
  218. langages de programmation fondés sur la réécriture. Par exemple, l'opérateur
  219. variadique $list$ est simulé par l'opérateur $nil$ d'arité nulle, ainsi que par
  220. l'opérateur binaire $cons$. Cela permet d'écrire que le terme $list(a,b,c)$ est
  221. équivalent au terme $list(list(a,b),c)$, et qu'ils peuvent être représentés par
  222. $cons(a,cons(b,cons(c,nil)))$.
  223. On peut alors définir des opérations modulo une théorie équationnelle : on
  224. parlera de \emph{filtrage équationnel} lorsque le filtrage sera associé à une
  225. telle théorie. Pour illustrer cette notion, prenons deux exemples simples de
  226. filtrage.
  227. \paragraph{Exemple 1 :} Le filtrage associatif avec élément neutre ($AU$)
  228. ---~aussi appelé filtrage de liste~--- est un problème bien connu en
  229. réécriture. Il permet d'exprimer facilement des algorithmes manipulant des
  230. listes. En considérent $X1*$ et $X2*$ comme ides variables représentant 0 ou
  231. plusieurs éléments d'une liste, le problème de filtrage $list(X1*,x,X2*) \ll
  232. list(a,b,c)$ admet trois solutions : $\sigma_1 = \{ x\rightarrow a\}$,
  233. $\sigma_2 = \{ x\rightarrow b\}$ et $\sigma_3 = \{ x\rightarrow c\}$.
  234. %\paragraph{Exemple 1 :} Le filtrage associatif avec élément neutre ($AU$)
  235. %---~aussi appelé filtrage de liste~--- est un problème bien connu en
  236. %réécriture. Il permet d'exprimer facilement des algorithmes manipulant des
  237. %listes. Considérons l'opérateur associatif $list$ avec élément neutre noté $e$.
  238. %Le problème de filtrage $list(x,y,z) \ll list(a,b)$ admet trois solutions :
  239. %$\sigma_1 = \{ x\rightarrow a, y\rightarrow b, z\rightarrow e\}$, $\sigma_2 =
  240. %\{ x\rightarrow a, y\rightarrow e, z\rightarrow b\}$ et $\sigma_3 = \{
  241. %x\rightarrow e, y\rightarrow a, z\rightarrow b\}$.
  242. \paragraph{Exemple 2 :} Illustrons le filtrage associatif-commutatif ($AC$) et
  243. l'addition, dont les axiomes d'associativité et commutativité sont les suivants
  244. :
  245. %Pour illustrer cette notion, prenons l'exemple du filtrage
  246. %associatif-commutatif ($AC$) et de l'addition, dont les axiomes d'associativité
  247. %et commutativité sont les suivants :
  248. \begin{itemize}
  249. \item $\forall x,y,~ plus(x,y) = plus(y,x)$ ;
  250. \item $\forall x,y,~ plus(x,plus(y,z))=plus(plus(x,y),z)$.
  251. \end{itemize}
  252. Le problème de filtrage $plus(x,y) \ll plus(a,b)$ présente deux solutions
  253. distinctes modulo AC : $\sigma_1 = \{ x\rightarrow a,y\rightarrow b\}$ et
  254. $\sigma_2=\{ x\rightarrow b, y\rightarrow a\}$.
  255. %Prenons l'exemple du filtrage associatif-commutatif ($AC$) permettant de
  256. %modéliser le calcul dans les groupes et dans d'autres structures algébriques
  257. %dotées de lois commutatives et associatives, notamment l'addition sur les
  258. %entiers. $plus$ est associatif-commutatif et les axiomes d'associativité et
  259. %commutativité sont les suivants :
  260. %$$\forall x,y ; plus(x,y) = plus(y,x)$$
  261. %$$\forall x,y ; plus(x,plus(y,z))=plus(plus(x,y),z)$$
  262. %\begin{itemize}
  263. % \item le problème de filtrage $plus(a,b) \ll plus(x,y)$ possède deux solutions
  264. % distinctes modulo $AC$ : $\sigma_1 = \{ x\rightarrow a,y\rightarrow b\}$ et
  265. % $\sigma_2=\{ x\rightarrow b, y\rightarrow a\}$
  266. %
  267. % \item le problème de filtrage $plus(x,y) \ll plus(plus(plus(a,b),c)$ possède
  268. % six solutions modulo $AC$ :
  269. %\end{itemize}
  270. \subsection{Réécriture}
  271. En réécriture, on oriente des égalités que l'on appelle des \emph{règles de
  272. réécriture} et qui définissent un calcul.
  273. \begin{definition}[Règle de réécriture]
  274. Une règle de réécriture est un couple (l,r) de termes dans \TFX, notée l
  275. $\rightarrow$ r. l est appelé membre gauche de la règle, et r membre droit.
  276. \end{definition}
  277. Un exemple de règle de réécriture est l'addition de n'importe quel entier $x$
  278. avec $0$ : $$x+0~\rightarrow~x$$
  279. Un autre exemple un peu plus complexe de règle de réécriture est la
  280. distributivité de la multiplication par rapport à l'addition dans un anneau,
  281. comme illustré par la figure~\ref{fig:ex_rwRule_distrib}. %ci-dessous :
  282. %\todo{[x*(y+z) -> (x*y)+(x*z)]}
  283. \begin{figure}[!h]
  284. \begin{center}
  285. \input{figures/ex_rwRule_distrib}
  286. \caption{Exemple de règle de réécriture : distributivité de la
  287. multiplication par rapport à l'addition dans un anneau, à savoir $x\times(y+z)
  288. \rightarrow (x\times y)+(x\times z)$.}
  289. \label{fig:ex_rwRule_distrib}
  290. \end{center}
  291. \end{figure}
  292. \begin{definition}[Système de réécriture]
  293. Un système de réécriture sur les termes est un ensemble de règles de réécriture
  294. (l,r) tel que :
  295. \begin{itemize}
  296. \item les variables du membre droit de la règle font partie des variables du
  297. membre gauche ($\var{r} \subseteq \var{l}$) ;
  298. \item le membre gauche d'une règle n'est pas une variable ($l \notin \caX$).
  299. \end{itemize}
  300. %\todo{À voir : plus « formel » (à la Cláudia) ou alors cette définition est
  301. %suffisante ?}
  302. \end{definition}
  303. \begin{definition}[Réécriture]
  304. Un terme $t \in \TFX$ se réécrit en $t'$ dans un système de réécriture \caR, ce
  305. que l'on note $t \rarrow t'$, s'il existe :
  306. \begin{itemize}
  307. \item une règle $l \rightarrow r \in \caR$ ;
  308. \item une position $\omega$ dans $t$ ;
  309. \item une substitution $\sigma$ telle que $t_{|\omega} = \sigma(l)$ et $t' =
  310. t[\sigma(r)]_{\omega}$. %t[\omega \hookleftarrow \sigma(r)]
  311. \end{itemize}
  312. \end{definition}
  313. On appelle \emph{radical} le sous-terme $t_{|\omega}$.
  314. Pour une relation binaire $\rightarrow$, on note $\refltransclo$ sa fermeture
  315. transitive et réflexive. La fermeture transitive, réflexive et symétrique de
  316. $\rightarrow$ ---~qui est alors une relation d'équivalence~--- est notée
  317. $\symrefltransclo$.
  318. \begin{definition}[Forme normale]
  319. Soit $\rightarrow$ une relation binaire sur un ensemble T.
  320. %\begin{itemize}
  321. %\item un élément $t \in T$ est une forme normale s'il n'existe pas
  322. % d'élément $t' \in T $ tel que $t \rightarrow t'$. On dit alors que t est
  323. % irréductible ;
  324. %\item $t \in T$ a une forme normale si $t \refltransclo t'$ pour une forme
  325. % normale $t'$ notée $t\downarrow$.
  326. %\end{itemize}
  327. Un élément t $\in$ T est réductible par $\rightarrow$ s'il existe $t' \in T$
  328. tel que $t \rightarrow t'$. Dans le cas contraire, on dit qu'il est
  329. irréductible. On appelle forme normale de $t$ tout élément $t'$ irréductible de
  330. T tel que $t \refltransclo t'$. Cette forme est unique.
  331. \end{definition}
  332. Deux propriétés importantes d'un système de réécriture sont la
  333. \emph{confluence} et la \emph{terminaison}. Lorsque l'on souhaite savoir si
  334. deux termes sont équivalents, on cherche à calculer leurs formes normales et à
  335. vérifier si elles sont égales. Cela n'est possible que si la forme normale
  336. existe et qu'elle est unique. Une forme normale existe si $\rightarrow$
  337. \emph{termine}, et son unicité est alors assurée si $\rightarrow$ est
  338. \emph{confluente}, ou si elle vérifie la \emph{propriété de Church-Rosser}, qui
  339. est équivalente.
  340. \begin{definition}[Terminaison]
  341. Une relation binaire $\rightarrow$ sur un ensemble T est dite terminante s'il
  342. n'existe pas de suite infinie $(t_i)_{i\ge 1}$ d'éléments de T telle que $t_1
  343. \rightarrow t_2 \rightarrow~\cdotp\cdotp\cdotp$.
  344. \end{definition}
  345. \begin{definition}[Confluence]
  346. Soit une relation binaire $\rightarrow$ sur un ensemble T. %$\rightarrow$ est
  347. %confluente si et seulement si : $$\forall t,t_1,t_2 (t \refltransclo t_1~et~t
  348. %\refltransclo t_2) \Rightarrow \exists t', (t_1 \refltransclo t'~et~t_2 \refltransclo
  349. %t')$$
  350. \begin{itemize}
  351. \item[(a)] $\rightarrow$ est \emph{confluente} si et seulement si :
  352. $$\forall t,u,v ~(t \refltransclo u~et~t \refltransclo v) \Rightarrow
  353. \exists w, (u \refltransclo w~et~v \refltransclo w)$$
  354. \item[(b)] $\rightarrow$ vérifie la \emph{propriété de Church-Rosser} si et seulement si :
  355. $$\forall u,v,~u \symrefltransclo v \Rightarrow
  356. \exists w, (u \refltransclo w~et~v \refltransclo w)$$
  357. \item[(c)] $\rightarrow$ est \emph{localement confluente} si et seulement si :
  358. $$\forall t,u,v ~(t \rightarrow u~et~t \rightarrow v) \Rightarrow
  359. \exists w, (u \refltransclo w~et~v \refltransclo w)$$
  360. \end{itemize}
  361. \end{definition}
  362. %La figure~\ref{fig:confluence} illustre cette propriété de confluence.
  363. %\begin{figure}[H]
  364. % \begin{center}
  365. % \input{figures/confluence}
  366. % \caption{Propriété de confluence.}
  367. % \label{fig:confluence}
  368. % \end{center}
  369. %\end{figure}
  370. La figure~\ref{fig:proprietes_binRel} illustre ces propriétés.
  371. \begin{figure}[H]
  372. \begin{center}
  373. \input{figures/proprietes_binRel}
  374. \caption{Propriétés sur les relations binaires.}
  375. \label{fig:proprietes_binRel}
  376. \end{center}
  377. \end{figure}
  378. \subsection{Stratégies de réécriture}
  379. %\ttodo{1. intuition 2. définitions formelles : Stratégie et réécriture sous
  380. %stratégie ; évaluation en lambda calcul ; stratégie abstraite -> ARS ; }
  381. En réécriture, on applique habituellement de manière exhaustive toutes les
  382. règles sur le terme pour calculer sa forme normale, c'est-à-dire que l'on
  383. applique toutes les règles jusqu'à ce qu'aucune règle ne puisse plus être
  384. appliquée. Il est cependant courant d'écrire des systèmes de réécriture ne
  385. terminant pas ou n'étant pas confluents. La méthode d'application des règles
  386. adoptée prend donc de l'importance, car elle a, dans ce cas, un effet sur le
  387. résultat. Il est par conséquent important d'avoir un contrôle sur l'application
  388. des règles du système de réécriture. C'est l'objet du concept de
  389. \emph{stratégie} que nous allons décrire dans cette section.
  390. %On va donc définir des \emph{stratégies} pour spécifier le parcours à suivre
  391. %dans l'arbre des dérivations.
  392. Illustrons ce problème par un exemple où l'on considère le système de
  393. réécriture suivant avec la signature $\{a,f\}$, $a$ étant d'arité 0 et $f$
  394. d'arité 1 :\\
  395. %ex confluent non-terminant extrait du manuscrit de Antoine -> permet de donner
  396. %une bonne intuition
  397. $\left\{\begin{array}{lclr}
  398. f(x) & \rightarrow & f(f(x)) & (r1)\\
  399. f(a) & \rightarrow & a & (r2)\\
  400. \end{array} \right. $\\
  401. Sans aucune précision sur la manière d'appliquer les règles, nous remarquons
  402. qu'il existe une suite infinie de pas de réécriture partant de $f(a)$ si l'on
  403. applique toujours la règle $r1$ :\\
  404. $f(a) \overset{r1}{\longrightarrow} f(f(a)) \overset{r1}{\longrightarrow}
  405. f(f(f(a))) \overset{r1}{\longrightarrow} \cdots $\\
  406. Le calcul ne termine pas. Si l'on applique les règles de réécriture $r1$ et $r2$
  407. différemment, nous constatons que $f(a)$ se réduit en $a$ :\\
  408. %$f(a) \overset{r1}{\longrightarrow} f(f(a)) \overset{r2}{\longrightarrow} f(f(a))$
  409. $\begin{array}{lllllll}
  410. f(a) & \overset{r1}{\longrightarrow} & f(f(a)) &
  411. \overset{r2}{\longrightarrow} & f(a) & \overset{r2}{\longrightarrow}& a\\
  412. \downarrow {\vspace{-1.0em}\footnotesize ^{r2}} &&&&&&\\
  413. a&&&&&&\\
  414. \end{array}$\\
  415. Cet exemple illustre clairement le fait que les résultats du calcul ne sont pas
  416. les mêmes selon la méthode d'application des règles. Pour avoir des calculs qui
  417. terminent, on pourrait alors adopter une \emph{stratégie} d'application des
  418. règles donnant la priorité à la règle $r2 : f(a) \rightarrow a$ par rapport à
  419. la règle $r1 : f(x) \rightarrow f(f(x))$.
  420. %On constate qu'il est confluent et non-terminant : il existe une suite infinie
  421. %de pas de réécriture partant de $f(a)$ ou $g(a)$, mais ils se réduisent
  422. %cependant tous deux en $a$. Pour avoir des calculs qui terminent, on pourrait
  423. %adopter une stratégie d'application des règles donnant la priorité aux deux
  424. %règles $f(a) \rightarrow a$ et $g(a) \rightarrow a$ par rapport aux deux
  425. %premières règles.
  426. %~\cite{Kirchner1996}
  427. Après cette intuition de ce qu'est une stratégie, nous pouvons donner des
  428. définitions plus formelles des concepts liés. La notion de système abstrait de
  429. réduction (\emph{Abstract Reduction System} -- ARS)~\cite{Bezem2003} est une
  430. manière abstraite de modéliser les calculs par transformations pas à pas
  431. d'objets, indépendamment de la nature des objets qui sont réécrits. Un ARS peut
  432. se définir comme un couple $(\caT,\rightarrow)$, où $\rightarrow$ est une
  433. relation binaire sur l'ensemble \caT. De là,~\cite{Kirchner2008} donne une
  434. représentation des ARS sous forme de graphe et introduit le concept de
  435. stratégie abstraite.
  436. %définitions formelles -> obligé de les mettre ? -> oui, cf cohérence avec le
  437. %reste + déf ARS et dérivation nécessaires en cascade car déf de stratégie
  438. %abstraite. Trouver une définition un peu plus light ?
  439. %\begin{definition}[Système abstrait de réduction]%\cite{Bezem2003}
  440. % Un système abstrait de réduction (ARS) est un couple $(\caT,\rightarrow)$ où
  441. % $\rightarrow$ est une relation binaire sur l'ensemble \caT
  442. %\end{definition}
  443. \begin{definition}[Système abstrait de réduction]%\cite{Kirchner2008}
  444. Un système abstrait de réduction (ARS) est un graphe orienté étiqueté
  445. $(\caO, \caS)$. Les nœuds \caO sont appelés objets, les arêtes orientées \caS
  446. sont appelées pas.\\
  447. \end{definition}
  448. Pour un ensemble de termes \TFX, le graphe (\TFX, \caS) est l'ARS correspondant
  449. à un système de réécriture \caR. Les arêtes correspondent à des pas de
  450. réécriture de \caR et sont étiquetées par le nom des règles de \caR.
  451. \begin{definition}[Dérivation]
  452. Soit un ARS \caA :
  453. \begin{itemize}
  454. \item[1.] un \emph{pas de réduction} est une arête étiquetée $\phi$ complétée de sa
  455. source a et de sa destination b. On note un pas de réduction
  456. $a \aphiarrow{} b$, ou simplement $a \phiarrow{} b$ lorsqu'il n'y a pas
  457. d'ambiguïté ;
  458. \item[2.] une \emph{\caA-dérivation} (ou \emph{séquence de
  459. \caT-réductions}) est un chemin $\pi$ dans le graphe \caA ;
  460. \item[3.] lorsque cette dérivation est finie, $\pi$ peut s'écrire $a_0
  461. \phiarrow{0} a_1 \phiarrow{1} a_2 \cdots \phiarrow{n-1} a_n$ et on dit
  462. que $a_0$ se réduit en $a_n$ par la dérivation $\pi =
  463. \phi_0\phi_1\ldots\phi_{n-1}$ ; notée aussi $a_0
  464. \rightarrow^{\phi_0\phi_1\ldots\phi_{n-1}} a_n$ ou simplement $a_0
  465. \piarrow a_n$. n est la \emph{longueur} de $\pi$ ;
  466. \begin{itemize}
  467. \item[(a)] la source de $\pi$ est le singleton \{$a_0$\}, notée
  468. $dom(\pi)$ ;
  469. \item[(b)] la destination de $\pi$ est le singleton $\{a_n\}$,
  470. notée $\pi[a_0]$.
  471. \end{itemize}
  472. \item[4.] une dérivation est vide si elle n'est formée d'aucun pas de
  473. réduction. La dérivation vide de source a est notée $id_a$.
  474. \end{itemize}
  475. \end{definition}
  476. \begin{definition}[Stratégie abstraite]%definition de \cite{Kirchner2008}, p5-6
  477. Soit un ARS \caA :
  478. \begin{itemize}
  479. \item[1.] une stratégie abstraite est un sous-ensemble de toutes les
  480. dérivations de \caA ;
  481. \item[2.] appliquer la stratégie $\zeta$ sur un objet a, noté par $\zeta[a]$, est
  482. l'ensemble de tous les objets atteignables depuis a en utilisant une
  483. dérivation dans $\zeta$ :
  484. $\zeta[a] = \{\pi[a]~|~\pi \in \zeta\}$. Lorsqu'aucune dérivation dans
  485. $\zeta$ n'a pour source a, on dit que l'application sur $a$ de la
  486. stratégie a échoué ;
  487. \item[3.] appliquer la stratégie $\zeta$ sur un ensemble d'objets consiste
  488. à appliquer $\zeta$ à chaque élément $a$ de l'ensemble. Le résultat est
  489. l'union de $\zeta[a]$ pour tous les $a$ de l'ensemble d'objets ;
  490. \item[4.] le \emph{domaine} d'une stratégie est l'ensemble des objets qui
  491. sont la source d'une dérivation dans $\zeta$ : $dom(\zeta) =
  492. \bigcup \limits_{\delta \in \zeta} dom(\delta)$ ;
  493. \item[5.] la stratégie qui contient toutes les dérivations vides est $Id = \{
  494. id_a ~|~ a \in \caO\}$.
  495. \end{itemize}
  496. \end{definition}
  497. %\ttodo{transition section suivante : lien vers le langage}
  498. Concrètement, on peut exprimer ces stratégies de manière déclarative grâce aux
  499. langages de stratégies que proposent la plupart des langages à base de règles
  500. tels que {\elan}~\cite{Vittek1994,Borovansky1998,Borovansky1996},
  501. {\stratego}~\cite{Visser1998,Visser01},
  502. {\maude}~\cite{Clavel1996a,Clavel2002,Clavel2011} et {\tom}, que
  503. nous allons présenter dans la section suivante.
  504. \paragraph{{\elan}.} {\elan} propose deux types de règles : les
  505. règles anonymes systématiquement appliquées (servant à la normalisation de
  506. termes) et les règles étiquetées pouvant être déclenchées à la demande
  507. sous contrôle d'une stratégie. Le résultat de l'application d'une telle règle
  508. sur un terme est un multi-ensemble de termes, ce qui permet de gérer le
  509. non-déterminisme. {\elan} a introduit la notion de stratégie en proposant un
  510. langage de combinateurs permettant de composer les stratégies et de contrôler
  511. leur application. Parmi ces combinateurs, on retiendra notamment l'opérateur de
  512. séquence, des opérateurs de choix non-déterministes et des opérateurs de
  513. répétition.
  514. \paragraph{{\stratego}.} S'inspirant d'{\elan}, {\stratego} se concentre sur un
  515. nombre restreint de combinateurs élémentaires, ainsi que sur leur combinaison.
  516. À ces combinateurs (séquence, identité, échec, test, négation, choix
  517. déterministe et non-déterministe) sont ajoutés un opérateur de récursion
  518. ($\mu$) et des opérateurs permettant d'appliquer la stratégie : sur le
  519. $i^{\text{\textit{ème}}}$ fils du sujet (\emph{i(s)}), sur tous les sous-termes
  520. du sujet (\emph{All(s)}), sur le premier fils du sujet sans échec
  521. (\emph{One(s)}), sur tous les sous-termes du sujet sans échec (\emph{Some(s)}).
  522. Grâce à ces opérateurs, il est possible d'élaborer des stratégies de haut
  523. niveau telles que \emph{TopDown} et \emph{BottomUp}.
  524. \paragraph{{\maude}.} L'approche de {\maude} est un peu différente : le
  525. contrôle sur l'application des règles s'opère grâce à la réflexivité du
  526. système~\cite{Clavel1996,Clavel2002a}. Les objets du langage {\maude} ayant une
  527. représentation \emph{meta}, il est possible d'utiliser un opérateur
  528. (\texttt{meta-apply}) pour appliquer les règles. Cet opérateur évalue les
  529. équations, normalise le terme, et retourne la \emph{meta-représentation} du
  530. terme résultant de l'évaluation. On peut contrôler l'application des règles de
  531. réécriture par un autre programme défini par réécriture. Pour des raisons
  532. pratiques, des travaux ont été menés plus
  533. récemment~\cite{MartiOliet2005,Eker2007} pour offrir un langage de stratégies
  534. plus proche de ce que {\elan}, {\stratego} et {\tom} proposent.
  535. \paragraph{{\tom}.} À partir du concept de stratégie et en s'inspirant de ces
  536. langages, {\tom} implémente lui aussi un langage de
  537. stratégies~\cite{BallandMR08,Balland2012}. Il est fondé sur des stratégies
  538. élémentaires (\emph{Identity} et \emph{Fail}), sur des combinateurs de
  539. composition (\emph{Sequence}, \emph{Recursion} ---$\mu$---, \emph{Choice},
  540. \emph{Not}, \emph{IfThenElse}) et de traversée (\emph{All}, \emph{One},
  541. \emph{Up} et \emph{Omega}). De ces combinateurs, à l'image de {\stratego}, des
  542. stratégies composées peuvent être élaborées (\emph{Try}, \emph{Repeat},
  543. \emph{Innermost}, etc.). Nous reviendrons sur les stratégies de {\tom} dans la
  544. section suivante, en particulier sur leur utilisation concrète au sein du
  545. langage.
  546. \section{Le langage Tom}
  547. {\tom}~\cite{Moreau2003,Balland2007} est un langage conçu pour enrichir des
  548. langages généralistes de fonctionnalités issues de la réécriture et de la
  549. programmation fonctionnelle. Il ne s'agit pas d'un langage \emph{stand-alone} :
  550. il est l'implémentation du concept des \og îlots formels \fg (\emph{formal
  551. islands})~\cite{Balland2006} qui sont ajoutés au sein de programmes écrits dans
  552. un langage hôte. Les constructions {\tom} sont transformées et compilées vers
  553. le langage hôte. Parmi les fonctionnalités apportées par {\tom}, on compte le
  554. filtrage de motif (\emph{pattern-matching}), les règles de réécriture, les
  555. stratégies, ainsi que les ancrages algébriques (\emph{mappings}).
  556. %Le compilateur {\tom} est lui-même écrit en {\tom} (\emph{bootstrap}).
  557. %\ttodo{Fonctionnement de {\tom} : faire le schéma chaîne de compilation, ou
  558. %alors tout à la fin ? Plutôt à la fin vu qu'il faut faire apparaître les
  559. %mappings, etc.}
  560. Dans la suite de cette section, nous décrirons le langage {\tom} en illustrant
  561. ses fonctionnalités et constructions par des exemples simples. Sauf indication
  562. contraire, les extraits de code hôte seront en {\java}. Pour une documentation
  563. complète et détaillée, le lecteur intéressé pourra se référer au manuel
  564. disponible en téléchargement~\cite{Bach2009} ou directement en
  565. ligne~\cite{TomManual-2.10}. Les outils sont tous accessibles {\via} le site
  566. officiel du projet {\tom}\footnote{Voir \url{http://tom.loria.fr/}.}.
  567. \subsection{Signature algébrique}
  568. \label{subsec:signalg}\index{signature algébrique}
  569. {\tom} permet à l'utilisateur de spécifier des signatures algébriques
  570. multi-sortées {\via} l'outil {\gom}~\cite{Reilles2007}. Le langage
  571. {\gom}\index{\gom} permet de décrire une structure de données et d'en générer
  572. l'implémentation typée en {\java}. Le listing~\ref{code:gomPeanoSimple}
  573. illustre une définition de signature {\gom} :
  574. \input{code/gomPeanoSimple}
  575. Un module {\gom} est composé d'un préambule comportant un nom
  576. ---~\texttt{Peano} dans cet exemple~--- précédé du mot-clef \texttt{module}
  577. (ligne 1). Le début de la signature est annoncé par le mot-clef
  578. \texttt{abstract syntax} (ligne 2). Cet exemple étant extrêmement simple, le
  579. préambule est composé uniquement de ces deux lignes. Pour un module plus
  580. complexe qui utiliserait des types définis dans une autre signature, la clause
  581. \texttt{imports} suivie des signatures à importer peut être intercalée entre
  582. les deux clauses précédentes. Le projet {\tom} fournit notamment une
  583. bibliothèque de signatures pour les types primitifs (types \emph{builtin}) tels
  584. que les \emph{entiers} (\texttt{int}), les \emph{caractères} (\texttt{char}),
  585. les \emph{flottants} (\texttt{float}) et les \emph{chaînes de caractères}
  586. (\texttt{String}). La signature en elle-même est composée d'un ensemble de
  587. sortes ---~\texttt{Nat} dans notre exemple~--- ayant des constructeurs
  588. ---~\texttt{zero} et \texttt{suc} ici.
  589. Ce générateur propose un typage fort au niveau de la structure de données
  590. {\java} générée, ce qui garantit que les objets créés sont conformes à la
  591. signature multi-sortée. Un second aspect intéressant de cet outil est le fait
  592. qu'il offre le partage maximal~\cite{Appel1993}, rendant les structures
  593. générées très efficaces en temps (tests d'égalité en temps constant) et en
  594. espace. Les classes générées peuvent être modifiées par l'intermédiaire de la
  595. fonctionnalité de \emph{hooks}. Ce mécanisme permet d'ajouter des blocs de code
  596. {\java} aux classes générées (par exemple, intégration d'attributs invisibles
  597. au niveau algébrique, mais manipulables par la partie {\java} de l'application)
  598. ou d'associer une théorie équationnelle telle que A, AC, ACU à certains
  599. opérateurs. Il est même possible de spécifier cette théorie équationnelle par
  600. des règles de normalisation. Les termes construits sont ainsi toujours en forme
  601. normale.
  602. La signature est compilée en une implémentation {\java} ainsi qu'un ancrage
  603. permettant l'utilisation de cette structure dans les programmes {\tom}. Dans un
  604. premier temps, pour présenter les constructions du langage {\tom}, nous ne nous
  605. préoccuperons pas de ces ancrages ni de l'implémentation concrète {\java}.
  606. \subsection{Construction \emph{backquote} « ` »}
  607. \index{\tom!backquote, \lex{`}|(}
  608. La construction \lex{`} (\emph{backquote}) permet de créer la structure de
  609. données représentant un terme algébrique en allouant et initialisant les objets
  610. en mémoire. Elle permet à la fois de construire un terme et de récupérer la
  611. valeur d'une variable instanciée par le filtrage de motif. Ainsi, on peut
  612. construire des termes de type \texttt{Nat} de l'exemple précédent avec des
  613. instructions \emph{backquote}. L'instruction {\tomjava} \og\texttt{Nat un =
  614. `suc(zero());}\fg déclare une variable \texttt{un} dont le type est \texttt{Nat},
  615. ayant pour valeur le représentant algébrique \emph{suc(zero())}.
  616. Un terme \emph{backquote} peut aussi contenir des variables du langage hôte,
  617. ainsi que des appels de fonctions. Ainsi, l'instruction \texttt{Nat deux =
  618. `suc(un);} permet de créer le terme \texttt{deux} à partir de \texttt{un} créé
  619. précédemment. Le compilateur {\tom} n'analysant pas du tout le code hôte,
  620. notons que nous supposons que la partie hôte ---~\texttt{un} dans l'exemple~---
  621. est conforme à la signature algébrique et que le terme est donc bien formé.
  622. L'utilisation du \emph{backquote} permet à l'utilisateur %de ne pas se soucier
  623. %de l'implémentation concrète du type du langage hôte et de ne manipuler que sa
  624. %vue algébrique.
  625. de créer un terme et de manipuler sa vue algébrique sans se soucier de
  626. son implémentation concrète dans le langage hôte.
  627. \index{\tom!backquote, \lex{`}|)}
  628. \subsection{Filtrage de motif}
  629. \label{subsec:matching}\index{Filtrage|(}\index{Pattern-matching|(}
  630. Dans la plupart des langages généralistes tels que {\C} ou {\java}, on ne
  631. trouve pas les notions de type algébrique et de terme, mais uniquement celle de
  632. types de données composées (structures {\C} et objets {\java}). De même, la
  633. notion de filtrage de motif (\emph{pattern-matching}) que l'on retrouve dans
  634. les langages fonctionnels tels que {\caml} ou {\haskell} n'existe généralement
  635. pas dans la plupart des langages impératifs classiques. Le filtrage permet de
  636. tester la présence de motifs (\emph{pattern}) dans une structure de données et
  637. d'instancier des variables en fonction du résultat de l'opération de filtrage.
  638. Ces constructions sont apportées par {\tom} dans des langages généralistes. Il
  639. devient donc possible de filtrer des motifs dans {\java}. En outre, les
  640. constructions de filtrage de {\tom} étant plus expressives que dans {\caml}
  641. (notamment le filtrage équationnel et le filtrage non linéaire), il
  642. est possible de les employer aussi en son sein pour utiliser le filtrage
  643. équationnel.
  644. Le lexème \lex{\%match}\index{\tom!\lex{\%match}} introduit la construction de
  645. filtrage de {\tom}. Celle-ci peut être vue comme une généralisation de la
  646. construction habituelle \emph{switch-case} que l'on retrouve dans beaucoup de
  647. langages généralistes. Cependant, plutôt que de filtrer uniquement sur des
  648. entiers, des caractères, voire des chaînes de caractères, {\tom} filtre sur des
  649. \emph{termes}. Les motifs permettent de discriminer et de récupérer
  650. l'information contenue dans la structure de données algébrique sur laquelle on
  651. filtre.
  652. Dans le listing~\ref{code:matchPeanoPlus} suivant, nous reprenons l'exemple des
  653. entiers de Peano pour lesquels nous encodons l'addition avec {\tom} et {\java}.
  654. Pour ce premier exemple où les deux langages apparaissent en même temps, nous
  655. adoptons un marquage visuel pour désigner {\java} (noir) et {\tom} (gris). Cela
  656. permet de visualiser le tissage étroit entre le langage {\tom} et le langage
  657. hôte dans lequel il est intégré. Par la suite, le principe étant compris, nous
  658. n'adopterons plus ce code visuel.
  659. %\ttodo{voir quelle version garder : JNat, ou la simple avec Nat ?}
  660. \input{code/matchPeanoPlus}
  661. Dans cet exemple, la fonction \texttt{peanoPlus} prend en arguments deux termes
  662. \texttt{t1} et \texttt{t2} de type \texttt{Nat}
  663. représentant deux entiers de Peano, et retourne la
  664. somme des deux.
  665. %\todo{[Ou alors je passe la phrase suivante sous silence, et j'en reparle dans les mappings] }
  666. %\texttt{t1} et \texttt{t2} sont du type {\tom} \texttt{Nat}, implémenté par le type {\java} \texttt{JNat}.
  667. Le calcul est opéré par filtrage en utilisant la construction \lex{\%match} :
  668. \begin{itemize}
  669. \item elle prend un ou plusieurs arguments ---~deux dans notre exemple~---
  670. entre parenthèses ;
  671. \item elle est composée d'un ensemble de \emph{règles} de la forme
  672. \texttt{membre gauche -> \{membre droit\}} ;
  673. \item le membre gauche est composé du ou des motifs séparés les uns des autres
  674. par une virgule ;
  675. \item le membre droit est un bloc de code mixte (hôte + \textsf{Tom}).
  676. \end{itemize}
  677. Dans notre exemple, le calcul de filtrage est le suivant :
  678. \begin{itemize}
  679. % \item si \texttt{x} filtre \texttt{t1}, alors \texttt{zero()} et
  680. % \texttt{succ(y)} peuvent éventuellement filtrer \texttt{t2} ;
  681. \item si \texttt{zero()} filtre \texttt{t2}, alors le résultat de
  682. l'évaluation de la fonction \texttt{peanoPlus} est \texttt{x}, instancié par
  683. \texttt{t1} par filtrage ;
  684. \item si \texttt{suc(y)} filtre \texttt{t2}, alors le symbole de tête du
  685. terme \texttt{t2} est \emph{suc}. Le sous-terme \texttt{y} est ajouté à
  686. \texttt{x} et le résultat de l'évaluation de \texttt{peanoPlus} est donc
  687. \texttt{suc(peanoPlus(x,y))}.
  688. \end{itemize}
  689. %Bien que l'expression de la fonction \texttt{peanoPlus} soit donnée de manière
  690. %fonctionnelle, elle définit bien une fonction {\java} qui peut être utilisée
  691. %comme toute autre fonction {\java} dans le programme.
  692. L'expression de la fonction \texttt{peanoPlus} est donnée par filtrage et
  693. définit une fonction {\java} qui peut être utilisée comme toute autre fonction
  694. {\java} dans le programme.
  695. Notons cette
  696. particularité qu'a le langage {\tom} de complètement s'intégrer au langage hôte
  697. sans pour autant être intrusif. Ainsi, le compilateur {\tom} n'analyse que le
  698. code {\tom} (parties grisées dans le listing~\ref{code:matchPeanoPlus}), les
  699. instructions hôtes n'étant pas examinées et ne fournissant aucune information
  700. au compilateur. Les instructions {\tom} sont traduites vers le langage hôte
  701. et remplacées en lieu et place, sans modification du code hôte existant.
  702. Une deuxième particularité des constructions de filtrage du langage {\tom} est
  703. liée à la composition des membres droits des règles : plutôt qu'être de simples
  704. termes, il s'agit en fait d'instructions du langage hôte qui sont exécutées
  705. lorsqu'un filtre est trouvé. Si aucune instruction du langage hôte ne rompt le
  706. flot de contrôle, toutes les règles peuvent potentiellement être exécutées.
  707. Pour interrompre ce flot lorsqu'un filtre est trouvé, il faut utiliser les
  708. instructions {\adhoc} du langage hôte, telles que \texttt{break} ou
  709. \texttt{return}, comme dans le listing~\ref{code:matchPeanoPlus}.
  710. %\ttodo{match alternatif ?~\ref{code:matchAltPeanoPlus} :
  711. %\input{code/matchPeanoPlus}}
  712. \index{Filtrage!associatif|(}
  713. \paragraph{Filtrage associatif.} Dans le cas d'un filtrage non unitaire
  714. (filtrage pour lequel il existe plusieurs solutions,
  715. voir~\ref{subsec:filtrage}), l'action est exécutée pour chaque filtre
  716. solution. Le filtrage syntaxique étant unitaire, il n'est pas possible
  717. d'exprimer ce comportement. Le langage {\tom} dispose de la possibilité
  718. d'opérer du \emph{filtrage associatif avec élément neutre} (ou \emph{filtrage
  719. de liste}, noté $AU$ dans la section~\ref{subsec:filtrage}) qui n'est pas
  720. unitaire et qui permet d'exprimer aisément des algorithmes opérant du filtrage
  721. sur des listes. Il est ainsi possible de définir des opérateurs variadiques
  722. (opérateurs d'arité variable, par exemple les opérateurs de listes), comme nous
  723. l'avons vu dans la section précédente (\ref{subsec:filtrage}). Dans le
  724. listing~\ref{code:gomPeano} suivant, nous reprenons notre exemple des entiers
  725. de Peano que nous augmentons d'un nouveau constructeur, \texttt{concNat} de
  726. sorte \texttt{NatList} et dont les sous-termes sont de type \texttt{Nat}.
  727. %\pagebreak
  728. \input{code/gomPeano}
  729. L'opérateur \texttt{concNat} peut être vu comme un opérateur de concaténation
  730. de listes de \texttt{Nat} : \texttt{concNat()} représente la liste vide
  731. d'entiers naturels, \texttt{concNat(zero())} la liste ne contenant que
  732. \texttt{zero()} et \texttt{concNat(zero(),suc(zero()),suc(suc(zero())))} la
  733. liste contenant trois entiers naturels : 0, 1 et 2. La liste vide est
  734. l'élément neutre.
  735. {\tom} distingue syntaxiquement les variables de filtrage représentant un
  736. élément ---~par exemple \texttt{x} dans le
  737. listing~\ref{code:matchPeanoPlus}~--- et les variables représentant une
  738. sous-liste d'une liste existante en ajoutant le caractère \texttt{*}.
  739. Le filtrage associatif permet d'opérer une itération sur les éléments d'une
  740. liste comme l'illustre l'exemple du
  741. listing~\ref{code:listmatchingAfficherPeano} :
  742. \input{code/listmatchingAfficherPeano}
  743. Dans cet exemple, \texttt{liste} est une liste d'entiers naturels, de type
  744. \texttt{NatList} implémenté par le type {\java} \texttt{NatList}. Nous
  745. souhaitons afficher ces entiers avec leur position dans la liste. L'action est
  746. exécutée pour chaque filtre trouvé, et les variables de listes \texttt{X1*} et
  747. \texttt{X2*} sont instanciées pour chaque sous-liste préfixe et suffixe de la
  748. liste \texttt{liste}. \texttt{X1} correspond à un objet {\java} de type
  749. \texttt{NatList}, la méthode \texttt{length()} retournant la longueur de la
  750. liste peut donc être utilisée pour obtenir l'indice de l'élément \texttt{x}.
  751. L'énumération s'opère tant que le flot d'exécution n'est pas interrompu. Dans
  752. notre exemple, nous nous contentons d'afficher l'élément et sa position.
  753. L'exécution de la procédure \texttt{afficher} sur l'entrée \texttt{liste =
  754. `conc(zero(), zero(), suc(suc(zero())), zero())} donne :
  755. \input{code/outputAfficherPeano}
  756. \index{Filtrage!associatif|)}
  757. \index{Filtrage!non\ linéaire|(}
  758. Le langage {\tom} offre aussi la possibilité de procéder à du filtrage
  759. \emph{non-linéaire} (motifs pour lesquels une même variable apparaît plusieurs
  760. fois). Le listing~\ref{code:nonlinearlistmatchingSupprimerDoublon} ci-après
  761. illustre ce mécanisme : dans la fonction \texttt{supprimerDoublon}, la variable
  762. \texttt{x} apparaît à plusieurs reprises dans le motif.
  763. \index{Filtrage!non\ linéaire|)}
  764. \input{code/nonlinearlistmatchingSupprimerDoublon}
  765. Parmi les notations disponibles dans le langage, certaines sont très couramment
  766. utilisées et apparaîtront dans les extraits de code de ce document. Nous les
  767. illustrons dans le
  768. %Ajoutons aussi des notations disponibles dans le langage que nous utiliserons
  769. %couramment, que nous illustrons dans le
  770. listing~\ref{code:aliasunderscoreAfficherPeano} dont le but est d'afficher un
  771. sous-terme de la liste \texttt{liste} ayant la forme \texttt{suc(suc(y))},
  772. ainsi que sa position dans la liste, s'il existe :
  773. \input{code/aliasunderscoreAfficherPeano}
  774. Les notations \texttt{\_} et \texttt{\_*} pour les sous-listes désignent des
  775. variables dites anonymes : c'est-à-dire que leur valeur ne peut être utilisée
  776. dans le bloc action de la règle. La notation \texttt{@} permet de créer des
  777. alias : ainsi, on peut nommer des sous-termes obtenus par filtrage. L'alias
  778. permet de vérifier qu'un motif filtre ---~\texttt{suc(suc(\_))} dans notre
  779. exemple~--- tout en instanciant une variable ---~\texttt{x}~--- avec la valeur
  780. de ce sous-terme. Si on applique la procédure \texttt{chercher} à l'entrée
  781. précédente définie comme \texttt{liste = `conc(zero(), zero(),
  782. suc(suc(zero())), zero())}, on obtient le résultat suivant :
  783. \begin{tomcode4}
  784. suc(suc(zero())) trouv#\texttt{é}#, en position 2
  785. \end{tomcode4}
  786. \index{Filtrage|)}\index{Pattern-matching|)}
  787. \subsection{Notations implicite et explicite}
  788. %\todo{notation implicite vs explicite ? ou alors au fil de l'eau plus tard ? ou
  789. %pas trop utile ?}
  790. Lorsque l’on écrit un \emph{pattern} dans le membre gauche d'une règle, il est
  791. possible d'écrire l'opérateur et ses champs de deux manières. %En effet, les
  792. %champs des opérateurs {\tom}
  793. Ces derniers étant nommés, plutôt qu'écrire l'opérateur avec tous ses arguments
  794. (\emph{notation explicite}), on peut utiliser leurs noms dans le motif pour
  795. expliciter des sous-termes particuliers et en omettre d'autres. Ces derniers
  796. sont alors ignorés lors du filtrage. Cette notation est dite \emph{implicite}
  797. et s'utilise {\via} les lexèmes \lex{[} et \lex{]}. Il existe également une
  798. notation à base de contraintes qui peut rendre l'écriture implicite plus
  799. naturelle dans certains cas.
  800. Considérons un exemple simple pour illustrer ces deux notations : si on définit
  801. les personnes comme des termes construits en utilisant l'opérateur
  802. \emph{Personne}, d'arité \emph{3} et de type \emph{Personne}, ayant les
  803. arguments nommés \emph{nom} et \emph{prenom} de type « chaîne de caractères »,
  804. et \emph{age} de type entier, les trois fonctions suivantes du
  805. listing~\ref{code:implicitExplicitNotations} sont équivalentes :
  806. \input{code/implicitExplicitNotations}
  807. Outre l'indéniable gain en lisibilité du code qu'elle apporte de par
  808. l'utilisation des noms, la notation implicite améliore la maintenabilité du
  809. logiciel développé. En effet, dans le cas d'une extension de la signature
  810. (ajout d'un champ \emph{numTelephone}, par exemple), l'usage de la notation
  811. explicite impose d'ajouter un \texttt{\_} dans toutes les règles où l'opérateur
  812. \emph{Personne} est utilisé. Dans notre exemple, la première fonction
  813. ---~\texttt{peutConduireExplicite()}~--- devrait donc être modifiée,
  814. contrairement aux deux autres ---~\texttt{peutConduireImplicite()} et
  815. \texttt{peutConduireImplicite2()}. Avec cette
  816. notation, seuls les motifs manipulant explicitement les champs ayant été
  817. changés doivent être modifiés, d'où une plus grande robustesse au changement.\\
  818. Dans la suite de ce manuscrit, nous utiliserons indifféremment l'une ou l'autre
  819. des notations dans les extraits de code proposés.
  820. \subsection{Stratégies : maîtriser l'application des règles de réécriture}
  821. \label{subsec:strategy}\index{Stratégie|(}\index{\tom!\lex{\%strategy}}
  822. On peut analyser la structure de termes et encoder des règles de transformation
  823. grâce à la construction \lex{\%match}. Le contrôle de l'application de ces
  824. règles peut alors se faire en {\java} en utilisant par exemple la récursivité.
  825. Cependant, traitement et parcours étant entrelacés, cette solution n'est pas
  826. robuste au changement et le code peu réutilisable. En outre, il est difficile
  827. de raisonner sur une telle transformation. Une autre solution est d'utiliser
  828. des \emph{stratégies}~\cite{BallandMR08,Balland2012}, qui sont un moyen
  829. d'améliorer le contrôle qu'a l'utilisateur sur l'application des règles de
  830. réécriture. Le principe de programmation par stratégies permet de séparer le
  831. traitement (règles de réécriture, partie métier de l'application) du parcours
  832. (traversée de la structure de données arborescente), et de spécifier la manière
  833. d'appliquer les règles métier.
  834. {\tom} fournit un puissant langage de stratégies, inspiré de
  835. {\elan}~\cite{Borovansky1998}, {\stratego}~\cite{Visser1998},
  836. %\cite{Kats2010}\cite{Hemel2010}
  837. et {\jjtrav}~\cite{Visser2001}. Ce langage permet d'élaborer des stratégies
  838. complexes en composant des combinateurs élémentaires tels que
  839. \texttt{Sequence}, \texttt{Repeat}, \texttt{TopDown} et la récursion. Il sera
  840. donc en mesure de contrôler finement l'application des règles de réécriture en
  841. fonction du parcours défini. Le listing~\ref{code:strategyPeanoTransform}
  842. illustre la construction \lex{\%strategy}, ainsi que son utilisation :
  843. \input{code/strategyPeanoPlus}
  844. Dans cet exemple, nous supposons que notre signature contient d'autres
  845. opérateurs : \texttt{plus} et \texttt{one} de type \texttt{Nat}. La stratégie
  846. \texttt{transformationPeano} réécrit les constructeurs \texttt{one} en
  847. \texttt{suc(zero())} et les constructeurs \texttt{plus(zero(),x)} en
  848. \texttt{x}. Ligne 1, \texttt{additionPeano} étend \texttt{Identity}, ce qui
  849. donne le comportement par défaut de la stratégie : si aucune
  850. règle ne s'applique, aucune transformation n'a lieu, par opposition à
  851. \texttt{Fail} qui spécifie que la transformation échoue si la règle ne peut
  852. être appliquée. La construction \lex{visit} (ligne 2) opère un premier filtre
  853. sur les sortes de type \texttt{Nat} sur lesquelles les règles doivent
  854. s'appliquer. Les règles sont quant à elles construites sur le même modèle que
  855. les règles de la construction \lex{\%match}, décrite dans la
  856. section~\ref{subsec:matching}. Le membre gauche est un \emph{pattern}, tandis
  857. que le membre droit est un bloc action composé de code {\tomjava}. Ensuite, la
  858. stratégie est composée avec une stratégie de parcours fournie par une
  859. bibliothèque appelée \texttt{sl}. Le terme la représentant est créé, et sa
  860. méthode \texttt{visit} est appliquée sur le nombre que nous souhaitons
  861. transformer. Pour l'entrée donnée, le résultat affiché est le suivant (les
  862. couleurs ont été ajoutées pour faire apparaître clairement les sous-termes
  863. transformés) :
  864. \begin{tomcode4}
  865. plus(plus(suc(suc(#\colcode{darkgreen}{one()}#)), #\tomred{one()}#), #\javablue{plus(suc(one()),zero())}#)
  866. a #\texttt{é}#t#\texttt{é}# transform#\texttt{é}# en
  867. plus(plus(suc(suc(#\colcode{darkgreen}{suc(zero())}#)), #\tomred{suc(zero())}#), #\javablue{suc(suc(zero()))}#)
  868. \end{tomcode4}
  869. Pour des informations plus détaillées sur les stratégies {\tom} ainsi que sur
  870. leur implémentation dans le langage, nous conseillons la lecture
  871. de~\cite{Balland2009, BallandMR08, Balland2012} ainsi que la page dédiée du
  872. site officiel du projet
  873. {\tom}\footnote{Voir
  874. \url{http://tom.loria.fr/wiki/index.php5/Documentation:Strategies/}.}.
  875. %\ttodo{est-il nécessaire de lister les stratégies disponibles ? Est-il
  876. %nécessaire d'écrire ce que sont chacune d'entre elles ?}
  877. %\ttodo{ ?? mettre une explication formelle : fonction, composition, énumération
  878. % de positions, etc. ; ? -> oui, certainement}
  879. \index{Stratégie|)}
  880. \section{Ancrages formels}
  881. \label{subsec:mapping}\index{Ancrages algébriques|(}\index{Mappings|(}
  882. Précédemment, nous avons vu que nous pouvons ajouter des constructions de
  883. filtrage au sein de langages hôtes et que nous sommes en mesure de filtrer des
  884. termes. %objets arbitraires.
  885. Les constructions de filtrage sont compilées indépendamment des implémentations
  886. concrètes des termes. Ainsi, dans les exemples, nous filtrons sur des termes
  887. de type \texttt{Nat} et \texttt{NatList}, définis dans la signature {\gom}.
  888. Cependant, les fonctions {\java} prennent des paramètres d'un type donné que
  889. le compilateur {\java} est censé comprendre, et nous n'avons pas détaillé la
  890. manière dont le lien entre les types {\tom} et les types {\java} est assuré.
  891. %Cependant, les fonctions {\java} prenaient des paramètres de type
  892. %\texttt{JNat} et \texttt{JNatList}.
  893. À la compilation, les instructions sur les
  894. termes algébriques sont traduites en instructions sur le type de données
  895. concret représentant ces termes algébriques. Le mécanisme permettant d'établir
  896. cette relation entre les structures de données algébriques et concrètes
  897. s'appelle le mécanisme d'\emph{ancrage}, ou \emph{mapping}. Il permet de donner une
  898. vue algébrique d'une structure de données quelconque afin de pouvoir la
  899. manipuler à l'aide des constructions {\tom}, sans modifier l'implémentation
  900. concrète.
  901. On spécifie les \emph{mappings} à l'aide des constructions {\tom}
  902. \lex{\%typeterm}\index{\tom!\lex{\%typeterm}},
  903. \lex{\%op}\index{\tom!\lex{\%op}} et \lex{\%oplist}\index{\tom!\lex{\%oplist}}
  904. pour décrire respectivement les sortes, les opérateurs algébriques et les
  905. opérateurs variadiques. Dans la section~\ref{subsec:signalg}, nous avons défini
  906. une signature algébrique, et l'outil {\gom} génère une
  907. implémentation concrète ainsi que les ancrages. Cela nous permet de rendre
  908. ce mécanisme complètement transparent pour l'utilisateur. Pour expliquer les
  909. constructions constituant les \emph{mappings}, nous allons les expliciter
  910. sans passer par la génération de {\gom}. Pour la suite de cette section, nous
  911. prenons l'exemple du type \texttt{Individu} et de l'opérateur
  912. \texttt{personne}, qui prend trois arguments : un nom et un prénom, de type
  913. \texttt{String}, et un âge de type \texttt{int}. Nous adoptons aussi une
  914. notation pour lever toute ambiguïté sur les types : nous préfixons les types
  915. {\java} de la lettre \texttt{J}, et nous utiliserons l'implémentation qui suit.
  916. %Nous utiliserons l'implémentation
  917. %{\java} suivante des entiers de Peano.
  918. %%Avant d'expliquer ces constructions, le
  919. %%listing~\ref{code:implementationJPeano} donne l'implémentation concrète des
  920. %%entiers de Peano que nous utilisons pour ces exemples :
  921. %%\input{code/implementationJPeano}
  922. %Avant d'expliquer ces constructions, donnons l'implémentation concrète des
  923. %entiers de Peano que nous utilisons pour ces exemples.
  924. Nous considérons les classes {\java} \texttt{JIndividu} et \texttt{JIndividuList}
  925. suivantes qui implémentent respectivement les types algébriques
  926. \texttt{Individu} et \texttt{IndividuList}.
  927. %\lstinputlisting[name=expeano,numberstyle=\tiny,numbers=left,numberblanklines=false,frame=tb,firstnumber=1,firstline=6,lastline=7]{code/ExamplePeano.t}%style=codesource,
  928. \lstinputlisting[name=exhumain,numberstyle=\tiny,numbers=left,numberblanklines=false,frame=tb,firstnumber=1,firstline=6,lastline=7]{code/ExempleHumain.t}%style=codesource,
  929. %Nous considérons ensuite les classes {\java} \texttt{Jzero}, \texttt{Jsuc} et
  930. Nous considérons ensuite les classes {\java} \texttt{Jpersonne} et
  931. \texttt{JconcJIndividu} suivantes qui implémentent les opérateurs algébriques :
  932. %\lstinputlisting[name=expeano,numberstyle=\tiny,numbers=left,numberblanklines=false,frame=tb,firstnumber=auto,linerange={9-10,11-22,30-30,48-59,72-72}]{code/ExamplePeano.t}%style=codesource,
  933. \lstinputlisting[name=exhumain,numberstyle=\tiny,numbers=left,numberblanklines=true,frame=tb,firstnumber=auto,linerange={19-22,24-28,235-256}]{code/ExempleHumain.t}%style=codesource, %9-17
  934. %avec head et tail
  935. %\lstinputlisting[name=exhumain,numberstyle=\tiny,numbers=left,numberblanklines=true,frame=tb,firstnumber=auto,linerange={19-22, 24-28,40-51,64-64}]{code/ExempleHumain.t}%style=codesource, %9-17
  936. Les sortes \texttt{Individu} et \texttt{IndividuList} sont exprimées {\via} le lexème
  937. \lex{\%typeterm} comme le montre le listing~\ref{code:typetermIndividu} suivant :
  938. %\input{code/typetermNat}
  939. \input{code/typetermIndividu}
  940. La construction \lex{\%typeterm} permet d'établir la relation entre le type
  941. algébrique \texttt{Individu} et le type concret {\java} \texttt{JIndividu}.
  942. Deux sous-constructions la composent :
  943. \begin{itemize}
  944. \item \lex{implement} donne l'implémentation effective du langage hôte
  945. à lier au type algébrique ;
  946. \item \lex{is\_sort} est utilisée en interne par le compilateur pour tester le
  947. type d'un élément (optionnel) ;
  948. % \item \lex{equals} définit comment comparer deux termes (optionnel).
  949. \end{itemize}
  950. La sorte \texttt{Individu} étant définie, il est nécessaire de spécifier à
  951. {\tom} comment \emph{construire} et comment \emph{détruire} (décomposer) les
  952. termes de ce type. Pour cela, nous utilisons la construction \lex{\%op}, comme
  953. illustré par le listing~\ref{code:opIndividu} où l'opérateur \texttt{personne}
  954. est défini :
  955. %\input{code/opNat}
  956. \input{code/opIndividu}
  957. La définition d'opérateurs passe par une construction composée de quatre
  958. sous-cons\-tructions :
  959. \begin{itemize}
  960. \item \lex{is\_fsym} spécifie la manière de tester si un objet donné
  961. représente bien un terme dont le symbole de tête est l'opérateur ;
  962. \item \lex{make} spécifie la manière de créer un terme ;
  963. \item \lex{get\_slot} (optionnel) spécifie la manière de récupérer la valeur
  964. d'un champ du terme ;
  965. \item \lex{get\_default} (optionnel) donne la valeur par défaut de l'attribut.
  966. \end{itemize}
  967. %\todo{[utile ?]}
  968. Notons que {\tom} ne permet pas la surcharge d'opérateurs, c'est-à-dire
  969. qu'il n'est pas possible de définir plusieurs opérateurs ayant le même nom, mais
  970. des champs différents.
  971. La construction \lex{\%oplist} est le pendant de \lex{\%op} pour les opérateurs
  972. variadiques. Ainsi, dans le listing~\ref{code:opIndividuList}, nous pouvons
  973. définir un opérateur de liste d'individus \texttt{concIndividu}, de type
  974. \texttt{IndividuList}, et acceptant un nombre variable de paramètres de type
  975. \texttt{Individu}.
  976. %\input{code/typetermNatList} %inutile
  977. %\input{code/opNatList}
  978. \clearpage %pour éviter une coupure
  979. \input{code/opIndividuList}
  980. Les sous-constructions suivantes la composent :
  981. \begin{itemize}
  982. \item \lex{is\_fsym} spécifie la manière de tester si un objet donné
  983. représente bien un terme dont le symbole de tête est l'opérateur ;
  984. \item \lex{make\_empty} spécifie la manière de créer un terme vide;
  985. \item \lex{make\_insert} spécifie la manière d'ajouter un fils en
  986. première position à la liste ;
  987. \item \lex{get\_head} spécifie la manière de récupérer le premier élément de
  988. la liste;
  989. \item \lex{get\_tail} spécifie la manière de récupérer la queue de la liste
  990. (sous-liste constituée de la liste privée du premier élément) ;
  991. \item \lex{is\_empty} spécifie la manière de tester si une liste est vide.
  992. \end{itemize}
  993. Notons que le langage {\tom} supporte aussi le
  994. sous-typage~\cite{tavares09,Tavares2012}. Il est donc possible de spécifier un
  995. type comme sous-type d'un autre type déjà exprimé. Cette relation de
  996. sous-typage exprimée dans les types {\tom} doit évidemment être cohérente avec
  997. celle exprimée dans l'implémentation concrète en {\java}. Reprenons l'exemple
  998. précédent des \emph{individus} et considérons différents sens possibles :
  999. \emph{être vivant} (sens couramment utilisé, d'où le constructeur
  1000. \texttt{personne}), \emph{spécimen vivant d'origine animale ou végétale} (en
  1001. biologie) et \emph{élément constituant un ensemble} (en statistiques). Le type
  1002. \emph{Individu} pouvant être ambigu, nous décidons de le préciser en intégrant
  1003. des sous-types. Pour cela, il existe une construction {\tom} permettant de
  1004. spécifier un sous-type dans un ancrage algébrique : \lex{extends}, qui complète
  1005. la construction \lex{\%typeterm}.
  1006. \input{code/subtype.tex}
  1007. Dans le listing~\ref{code:subtypeIndividu}, nous déclarons donc un nouveau
  1008. type, \texttt{IndividuBiologie}, sous-type de \texttt{Individu} (lignes 1 à 5).
  1009. Il est implémenté par le type {\java} \texttt{JIndividuBiologie} dont la
  1010. relation de sous-typage avec \texttt{JIndividu} est exprimée par la
  1011. construction {\java} consacrée à l'héritage : \lex{extends} (ligne 7). Il est
  1012. ensuite possible de définir de manière classique des opérateurs de type
  1013. \texttt{IndividuBiologie} comme l'illustre le listing~\ref{code:opSubtype}.
  1014. \input{code/opSubtype}
  1015. \index{Ancrages algébriques|)}\index{Mappings|)}
  1016. \section{Domaines d'applications}
  1017. {\tom} est particulièrement utile pour parcourir et transformer les structures
  1018. arborescentes comme {\xml} par exemple. Il est donc tout à fait indiqué pour
  1019. écrire des compilateurs ou interpréteurs, et plus généralement des outils de
  1020. transformation de programmes ou de requêtes. Outre son utilisation pour écrire
  1021. le compilateur {\tom} lui-même, nous noterons son usage dans les cadres
  1022. académiques et industriels suivants :
  1023. \begin{itemize}
  1024. \item implémentation d'un mécanisme défini par Guillaume Burel dans sa
  1025. thèse~\cite{burel09} pour une méthode des tableaux particulière appelée
  1026. {\tamed}~\cite{bonichon04} ;
  1027. \item prototypage de langages tels que {\miniml} dont la compilation a été
  1028. décrite par Paul Brauner dans sa thèse~\cite{brauner10} ;
  1029. \item implémentation d'un assistant à la preuve tel que {\lemuridae}
  1030. développé par Paul Brauner pour un calcul des séquents nommé
  1031. {\lkms}~\cite{brauner10} ;
  1032. \item implémentation de compilateurs ou interpréteurs, comme le
  1033. compilateur {\pluscaltwo}
  1034. \footnote{Voir \url{https://gforge.inria.fr/projects/pcal2-0/}.} qui traduit des
  1035. algorithmes exprimés en {\pluscal} en {\tlaplus} pour faire du
  1036. \emph{model-checking} ;
  1037. \item raisonnement formel sur la plateforme
  1038. {\rodin}~\footnote{Voir \url{http://www.event-b.org/}.}. Il s'agit d'un outil
  1039. industriel \emph{open source} développé par
  1040. Systerel\footnote{Voir \url{http://www.systerel.fr/}.} qui permet de formaliser,
  1041. d'analyser et de prouver les spécifications de systèmes complexes ;
  1042. %http://ovado.fr/
  1043. %Tom est utilisé pour la plateforme Rodin (http://www.event-b.org/), notamment
  1044. %pour faire du raisonnement formel. La plateforme Rodin est un outil industriel
  1045. %open-source qui permet de formaliser, d'analyser et de prouver les
  1046. %spécifications de systèmes complexes.
  1047. \item outil de transformation de requêtes OLAP (\emph{OnLine Analytical
  1048. Processing}) en requêtes {\sql} (\emph{Structured Query Language}) pour
  1049. assurer la rétro-compatibilité entre les versions du logiciel
  1050. {\crystalreports}\footnote{Voir \url{http://crystalreports.com/}.} développé par
  1051. Business Object\footnote{Voir \url{http://www.businessobjects.com/}.} ;
  1052. \item transformations de modèles qualifiables pour les systèmes embarqués
  1053. temps-réel dans le projet
  1054. {\quarteft}\footnote{Site du projet : \url{http://quarteft.loria.fr/}.} porté par le LAAS-CNRS
  1055. \footnote{Laboratoire d'Analyse et d'Architecture des Systèmes :
  1056. \url{http://www.laas.fr/}.}, l'IRIT \footnote{Institut de Recherche en
  1057. Informatique de Toulouse : \url{http://www.irit.fr/}.}, l'ONERA-DTIM
  1058. \footnote{Office national d'études et de recherches aérospatiales :
  1059. \url{http://www.onera.fr/fr/dtim/}.} et Inria Nancy ainsi que nos partenaires
  1060. industriels Airbus\footnote{Voir \url{http://www.airbus.com/}.} et Ellidiss
  1061. Software\footnote{Voir \url{http://www.ellidiss.com/}.}. C'est dans ce cadre que
  1062. s'inscrit cette thèse.
  1063. \end{itemize}
  1064. \index{\tom|)}
  1065. \section{Apport de la thèse au projet {\tom}}
  1066. \label{sec:contrib}
  1067. %\ttodo{contrib technique : extension \%transformation, \%resolve, \%tracelink,
  1068. %participation/évolution de {\tom}-{\emf} (prototype développé avant ma thèse),
  1069. %schéma pour que ce soit plus clair ; contribution : expression de
  1070. %transformations haut-niveau accessibles à tous ; expression de modèles EMF
  1071. %Ecore ; traçabilité}
  1072. Durant cette thèse, j'ai contribué techniquement au projet {\tom}. La
  1073. figure~\ref{fig:wholeTomProcessBeforeThesis} illustre le fonctionnement global
  1074. du système {\tom} au début de ma thèse, et sert de point de comparaison avec la
  1075. figure~\ref{fig:wholeTomProcessContrib} pour illustrer cet apport de
  1076. développement.
  1077. \begin{figure}[h]
  1078. \begin{center}
  1079. % \begingroup
  1080. % \tikzset{every picture/.style={scale=0.9}}
  1081. \input{figures/wholeTomProcessBeforeThesis}
  1082. % \endgroup
  1083. \end{center}
  1084. \caption{Fonctionnement global du projet {\tom} en début de thèse.}
  1085. \label{fig:wholeTomProcessBeforeThesis}
  1086. \end{figure}
  1087. La contribution technique de cette thèse au projet {\tom} a consisté en
  1088. l'extension du langage {\tom} par l'ajout de constructions haut-niveau dédiées
  1089. à la transformation de modèles. Ces constructions haut niveau
  1090. (\lex{\%transformation}, \lex{\%resolve} et \lex{\%tracelink}) sont détaillées
  1091. dans le chapitre~\ref{ch:outils}. La construction \lex{\%transformation}
  1092. implémente une méthode proposée dans~\cite{Bach2012} pour transformer des
  1093. modèles {\emf} {\ecore}, tout en simplifiant l'écriture de la transformation
  1094. pour l'utilisateur. Cette méthode se déroule en deux phases :
  1095. \begin{itemize}
  1096. \item une phase de \emph{décomposition} de la transformation en
  1097. transformations élémentaires encodées par des stratégies {\tom} ;
  1098. \item une phase de \emph{réconciliation} durant laquelle le résultat
  1099. intermédiaire obtenu lors de la première phase est rendu cohérent et
  1100. conforme au métamodèle cible.
  1101. \end{itemize}
  1102. Les constructions \lex{\%resolve} et \lex{\%tracelink} servent à la phase de
  1103. \emph{réconciliation} d'une transformation de modèle suivant la méthode
  1104. proposée. En suivant cette approche, l'utilisateur peut écrire les
  1105. transformations élémentaires de manière indépendante et sans aucune notion
  1106. d'ordre d'application des pas d'exécution de la transformation.
  1107. La construction \lex{\%tracelink} présente aussi un intérêt en termes de
  1108. traçabilité de la transformation. Nous souhaitons générer des traces
  1109. d'exécution de la transformation à la demande de l'utilisateur, ce pour quoi
  1110. \lex{\%tracelink} a été conçue.
  1111. Cela a eu pour conséquence l'ajout d'un nouveau greffon (voir la
  1112. figure~\ref{fig:tomArchi}) dans la chaîne de compilation (\emph{transformer}),
  1113. ainsi que l'adaptation de cette chaîne, du \emph{parser} au \emph{backend},
  1114. afin de prendre en compte cette extension du langage.\\
  1115. Outre l'évolution du langage {\tom} lui-même, le générateur d'ancrages
  1116. algébriques {\tomemf} a aussi évolué et est maintenant disponible en
  1117. version stable.
  1118. %\todo{[schéma bof bof ; en fait ce schéma peut apparaitre plus loin, dans la
  1119. %partie outillage avec les travaux d'implémentation, ici ce serait bien d'avoir
  1120. %un schéma plus simple, ou alors pas de schéma ?] }
  1121. %La figure~\ref{fig:wholeTomProcessContrib} permet de visualiser ces
  1122. %contributions, les pointillés mettant en avant les points essentiels d'apport
  1123. %de mon travail au projet {\tom}.
  1124. Nos contributions au projet {\tom} apparaissent en pointillés sur la
  1125. figure~\ref{fig:wholeTomProcessContrib}.
  1126. %Les
  1127. %pointillés dans la figure~\ref{fig:wholeTomProcessContrib} mettent en avant les
  1128. %points essentiels d'apport de mon travail au projet {\tom}.
  1129. \begin{figure}[h]
  1130. \begin{center}
  1131. \input{figures/wholeTomProcessContrib}
  1132. \end{center}
  1133. \caption{Fonctionnement global de {\tom} et contributions de ce travail de thèse au projet.}
  1134. \label{fig:wholeTomProcessContrib}
  1135. \end{figure}
  1136. %La figure~\ref{fig:wholeTomProcessContrib} illustre le fonctionnement global du
  1137. %système {\tom}. Les zones en pointillés %fig:apportTheseTom}
  1138. %mettent en avant les points essentiels d'apport de cette thèse au projet {\tom}.
  1139. %\input{figures/wholeTomProcess}
  1140. %\ttodo{faire la version précédente sans le dessous, puis la même avec les pointillés $\righarrow$ c'est wholeTomProcessContrib}
  1141. %\input{figures/wholeTomProcess2}
  1142. %\input{figures/tomSystemContrib}
  1143. %\input{figures/tomEMFCompiler}
  1144. % vim:spell spelllang=fr