• Aucun résultat trouvé

Représentants canoniques

Dans le document Réécriture et compilation de confiance (Page 100-103)

4. Structure de données sûre 65

4.4. Représentants canoniques

On a présenté en section 4.2.2 pourquoi il est souhaitable d’intégrer des invariants au

sein même de la structure de données décrite par une signature algébrique.

La description et l’intégration des invariants dans la structure de données, plutôt que

laisser à l’utilisateur la charge de s’assurer que ces invariants sont bien respectés permet

de donner des garanties sur les objets manipulés.

Notre approche pour la description des invariants que la structure de données doit

respecter est d’essayer de fournir un maximum de souplesse à l’utilisateur, tout en

per-mettant aussi une expression à « haut niveau » de ces invariants. Cela s’insère dans les

lignes directrices du développement deTom, qui fournit des constructions pour exprimer

4.4. Représentants canoniques

du filtrage équationnel et des stratégies (donc plutôt de « haut niveau »), tout en laissant

la possibilité à l’utilisateur de revenir aux niveaux les plus bas, et d’utiliser toutes les

ressources du langage hôte, qu’il soitJava,C ou Caml.

On permettra alors à l’utilisateur deGomla description des invariants de la structure

de données en Java, mais aussi en utilisant les constructions de filtrage deTom.

4.4.1. Hooks

Cette description se fait par le biais de hooks, qui permettent de modifier le

compor-tement des opérations sur la structure de données pour chaque opérateur.

Pour illustrer l’utilisation et l’écriture deshooks, nous nous appuierons sur l’exemple

des lois de De Morgan considérées comme une théorie équationnelle pour les booléens.

Ces lois sont décrites par les équations A∨B = A∧B et A∧B = A∨B. On peut

orienter ces équations pour obtenir un système de réécriture confluent et terminant,

qui permet alors d’implémenter un système de normalisation, après l’application duquel

seuls les atomes peuvent être arguments d’une négation. On peut aussi ajouter une règle

afin de supprimer les doubles négations. On obtient alors le système :

A∨B → A∧B

A∧B → A∨B

A → A

Le mécanisme dehook deGompermet de définir des actions arbitraires à exécuter avant

(ou en lieu et place) la fonction originale de création d’un opérateur. Ces actions peuvent

être décrites par n’importe quelle construction Java ou Tom, et autorisent ce codeTom

à utiliser des constructions pour spécifier la fonction de normalisation.

Pour permettre la définition de hooks, on ajoute à la syntaxe de Gom les définitions

des productionshHookDef initioni ethHookOperationi :

hHookDef initioni ::= hOperatorN amei:hHookOperationi{ hT omCodei}

hHookOperationi ::= (make|make_insert)( [hIdentif ieri] (, hIdentif ieri)*)

Unhookest attaché à une définition d’opérateur, et permet d’étendre ou redéfinir la

fonc-tion de construcfonc-tion de cet opérateur. Suivant le type du hook, qui est soit make, soit

make_insert, celui-ci s’appliquera à un opérateur algébrique, ou variadique. En fait, la

distinction entre makeetmake_insertn’est pas réellement nécessaire, car on ne peut

pas utiliser makepour un hook d’opérateur variadique, et inversement,make_insert

n’a pas de sens lorsqu’on s’intéresse à un opérateur algébrique. Cependant, cette

dis-tinction permet de rendre explicite la différence entre les hooks d’opérateurs algébrique,

et ceux qui traitent des opérateur variadiques : tandis que le hook make prendra des

arguments compatibles avec la spécification de l’opérateur algébrique associé, un hook

make_insertprendra deux arguments, le premier ayant le type du domaine de

l’opéra-teur variadique associé et le second celui du co-domaine. La définition dumake_insert

ne modifie alors pas directement l’opération de création d’un opérateur variadique, mais

plutôt l’opération d’insertion d’un nouvel élément dans la liste des arguments d’un

opé-rateur variadique.

Exemple 22. De telshooks peuvent être utilisés pour définir le système de normalisation

correspondant aux lois de De Morgan :

module Boolean

abstract syntax

Bool = | True()

| False()

| Not(b:Bool)

| And(lhs:Bool,rhs:Bool)

| Or(lhs:Bool,rhs:Bool)

not:make(arg) {

%match(Bool arg) {

not(x) -> { return ‘x; }

and(l,r) -> { return ‘or(not(l),not(r)); }

or(l,r) -> { return ‘and(not(l),not(r)); }

}

}

On voit ici qu’il est possible (et d’ailleurs très utile) d’utiliserTomdans la définition du

hook pour filtrer sur la structure de données même qui est en train d’être décrite. Cela

laisse la possibilité à l’utilisateur de définir leshooks comme des règles de réécriture pour

obtenir une fonction de normalisation. Si l’exécution de cette définition se termine sans

retourner de valeur, alors la fonction de création originale de l’opérateur est utilisée,

c’est le cas dans notre exemple lorsque l’argument argest l’une des constantes True()

ou False(). Il est aussi possible d’appeler la fonction makeReal, qui correspond à la

fonction de création originale.

Lorsqu’il utilise le mécanisme des hooks, l’utilisateur doit s’assurer que le système de

normalisation définit par leshooks est confluent et terminant, car ces propriétés ne seront

pas garanties par le compilateurGom. D’autre part, la combinaison dehooks pour

diffé-rentes théories équationnelles dans une même signature doit être faite manuellement par

l’utilisateur, la combinaison de systèmes de réécriture ne préservant pas nécessairement

les propriétés de confluence et terminaison.

Une extension de ce travail serait de fournir un langage de plus haut niveau étendant

Gomet permettant d’exprimer de manière abstraite les différents invariants associés aux

opérateurs. Ce langage permettrait de laisser la tâche de la complétion des règles de

normalisation ou leur combinaison à son compilateur, ainsi que la vérification de leur

terminaison.

On peut considérer Gom comme un composant réutilisable, conçu pour être un outil

permettant d’implanter un autre langage (de la même manière que la bibliothèque des

ATerm et ApiGen ont été utilisés comme base pour ASF+SDF [JO04]), ou comme

composant dans une architecture plus complexe. D’autre part, l’introduction deshooks

Dans le document Réécriture et compilation de confiance (Page 100-103)