• Aucun résultat trouvé

Dans le chapitre pr´esent nous nous concentrons donc sur le typage des collections topolo-giques h´et´erog`enes et des transformations qui n’ont pas ´et´e ´etudi´ees auparavant. MGS int`egre des caract´eristiques ayant ´emerg´e r´ecemment mais qui ont ´et´e d´ej`a ´etudi´ees et que nous ne traiterons pas ici. Il s’agit notamment de la surcharge (voir par exemple [Fur02]), des enregis-trements extensibles [R´em93b, Oho95], des traits imp´eratifs [Wri95, Gar04] ou des arguments optionnels [FG95]. Nous ´ecartons aussi des notions plus anciennes comme les types alg´ebriques et les produits pour privil´egier la simplicit´e de la pr´esentation. Enfin nous simplifions l´eg`erement la syntaxe des transformations et nous montrons en fin de ce chapitre qu’on peut adapter le syst`eme pr´esent´e aux transformations de MGS.

VII.2.1 Syntaxe

Le langage est restreint au λ-calcul avec constantes et let auquel on ajoute les transforma-tions.

e ::= x | c | λx.e | e e | let x = e in e | {m/e ⇒ e; . . . ; m/e ⇒ e} m ::= µ, . . . , µ

µ ::= x | x : b | x : r | ∗ as x | b∗ as x | r∗ as x

Dans la grammaire ci-dessus, e est une expression, c est une constante (par exemple set:(), +ou ::) et m est un motif.

Motifs

Dans les motifs, un motif ´el´ementaire µ est :

– soit une variable, filtrant une valeur quelconque (x), une valeur d’un type atomique donn´e (x : b) ou une valeur qui est une collection et dont la topologie est donn´ee (x : r),

– soit une r´ep´etition nomm´ee, filtrant un nombre quelconque de valeurs voisines successive-ment et qui sont :

– quelconques (∗ as x),

– d’un type atomique donn´e (b∗ as x)

126 Typage ensembliste

On note B l’ensemble des types atomiques dans lequel on peut choisir b, on prendra par exemple B = {int, bool, f loat, string}. On note R l’ensemble des topologies de base dans lequel on peut choisir r, on prendra ici R = {set, seq, bag, grid }. Remarquons que les topologies de base ne sont que des symboles.

Les gardes d’un motif sont r´eduites `a une seule expression en fin de motif. Les conditions de type sont restreintes aux types atomiques et aux topologies de base mais on peut encoder d’autres tests (voir ci-dessous). La discussion en section VII.8.1 justifie le choix de se restreindre `a ces tests.

L’identificateur x dans ∗ as x d´enote la s´equence des valeurs filtr´ees. Une s´equence est en effet suffisante pour d´enoter les ´el´ements filtr´es en partie droite d’une r`egle ou dans la garde d’un motif tout en garantissant que la transformation puisse ˆetre appliqu´ee sur n’importe quelle topologie (un motif filtre un chemin, voir la section IV.3 dans le chapitre Filtrage). Les r`egles de transformation seront not´ees :

m/g ⇒ e

o`u m est la partie du motif non gard´ee, g est la garde du motif et e est l’expression rempla¸cante. Simplifications

Les simplifications de la syntaxe des transformations par rapport `a la syntaxe MGS concernent les points suivants :

Directions. Les directions dans les motifs peuvent ˆetre vues comme du sucre syntaxique au niveau du typage (au niveau du filtrage elles sont importantes). Exemple :

{ x |nord> y => y,x }

peut ˆetre vu comme un raccourci pour :

fun (c) -> ( { x,y / nord? (x,y,c) => [y,x] } c) o`u nord? est un pr´edicat de voisinage.

Tests de type. Un test de type de la forme x : [int]seq peut s’encoder de la mani`ere suivante dans notre langage :

let t = { x:int => true ; x => false } in let all int =

fun c -> fold (fun (x,y) -> x && y) (t x) true in { x:seq / all int x => ... }

ou plus simplement, si on dispose d’un pr´edicat testant si une valeur est d’un type atomique particulier1 :

let all int =

fun c -> fold (fun (x,y) -> is int(x) && y) (t x) true in { x:seq / all int x => ... }

1

Ce pr´edicat s’encode de la mani`ere suivante dans notre langage : let is int = fun x ->

let t = {x:int =>[true] ; x => [false]} in hd ( t (x::seq:()) )

Dans MGS on peut tester le type d’une valeur en dehors d’un motif comme dans l’exemple suivant : if x:int then e1 else e2.

Gardes. Les gardes sont rejet´ees `a la fin du motif pour la simplicit´e des r`egles de typage. Nous donnons en fin de chapitre une version de la r`egle de typage des transformations qui prend en compte des gardes sur les sous-motifs.

R´ep´etitions. La r´ep´etition arbitraire ∗ ne porte pas sur un sous-motif. Le motif ∗ as X dans notre langage restreint correspond au motif x* as X de MGS. On ne traite donc pas de motifs comme (x/x=0,y/y=1)* as Z. Un tel motif peut toutefois ˆetre encod´e `a l’aide de tests dans la garde.

Par ailleurs, dans les exemples que nous donnerons nous adopterons le sucre syntaxique suivant :

– les op´erateurs binaires seront ´ecrits en position infixe,

– on pourra ´ecrire une s´equence en ´enum´erant ses ´el´ements entre crochets au lieu d’utiliser le constructeur standard comme le montre l’exemple suivant : [1, 2, 3] pour 1 :: 2 :: 3 :: empty seq,

– on pourra omettre la garde d’un motif lorsque celle-ci est la constante true.

On appelle op´erateurs les fonctions constantes donn´ees dans le langage. Parmi les constantes on trouvera les collections vides comme empty set ou empty seq, et les op´erateurs manipulant des collections comme le constructeur2 g´en´erique :: ou les constructeurs sp´ecifiques aux grilles comme nord ou est.

Une r`egle de la forme x ⇒ e est appel´ee une r`egle attrape-tout (le motif est non gard´e et r´eduit `a une variable).

Discussion 3 (Formes sp´eciales.) Le pr´edicat nord? dont nous parlons ci-dessus n’a de sens que sur des variables introduites par le motif. En effet, appliquer nord? `a 1 et 2 par exemple n’a pas de sens car 1 et 2 peuvent apparaˆıtre plusieurs fois dans la collection.

Le langage MGS propose d’autres op´erations qui n’ont de sens que sur des variables intro-duites par un motif. V´erifier que ces op´erateurs ne sont utilis´es qu’avec de telles variables est un probl`eme simple qui peut ´eventuellement relever du typage mais que nous ne traiterons pas. Pour illustrer cette tˆache, consid´erons la transformation { x => left(x) + x }. Ici x d´enote `a la fois une position et sa valeur. Ce probl`eme apparaˆıt souvent dans les langages de programmation et n’est pas caract´eristique de l’utilisation de collections ou de transformations [Str67, Str00].

VII.2.2 Topologies

Dans la section IV.5.2 une topologie est vue comme la donn´ee d’un ensemble de constructeurs et d’une substitution topologique.

D´efinition 2 L’ensemble des directions d’une topologie r est l’ensemble de toutes les directions pouvant apparaˆıtre dans une collection construite uniquement `a partir des constructeurs de r et de sa substitution topologique.

Dans ce chapitre nous supposerons que toutes les topologies consid´er´ees ont des ensembles de directions disjoints deux `a deux.

VII.2.3 S´emantique d´enotationnelle

Nous donnons ici une s´emantique au langage ´etudi´e afin de montrer par la suite la correction du typage que nous proposons.

2

Ici le mot constructeur n’est pas utilis´e au sens alg´ebrique mais d´esigne une fonction ajoutant un ´el´ement `a une collection.

128 Typage ensembliste

Le langage s’´evalue dans un domaine D que nous d´ecrivons ici (voir [Mos90] pour une intro-duction aux domaines s´emantiques). Pour chaque type atomique b de B il est donn´e un ensemble Bb de valeurs dites litt´erales (dont l’intersection deux `a deux est vide). Pour chaque topologie r de R il est donn´e un ensemble C(D, r) de collections `a valeurs dans D. On peut prendre simplement C(D, r) = Posr → D o`u Posr est l’ensemble des positions possibles pour une col-lection de topologie r. Pour r1 6= r2, l’intersection de C(D, r1) et de C(D, r2) est vide3. Le domaine D → D contient les fonctions continues totales de D dans D. Les transformations sont repr´esent´ees dans D par des fonctions strictes de D → D. Les transformations sont continues si l’on suppose qu’elles sont d´eterministes. Elles le sont si l’on fixe la strat´egie d’application des r`egles. Leur s´emantique correspond `a la description donn´ee en section IV.5.3, page 79. Notons que cette s´emantique impose d’avoir une s´equence comme partie droite des r`egles d’une trans-formation. En effet, les substitutions topologiques, qui sont les op´erateurs substituant les valeurs filtr´ees par les valeurs rempla¸cantes, attendent une s´equence de valeurs en argument. Ceci est naturel puisqu’un motif d´ecrit un chemin, c’est `a dire un parcours s´equentiel de la partie filtr´ee. Enfin, D contient ⊥, qui d´enote un calcul qui ne termine pas, ainsi que les deux valeurs wrong et shape. La valeur wrong correspond `a une erreur de type `a l’ex´ecution, par exemple lorsqu’un entier est appliqu´e comme une fonction. La valeur shape peut ˆetre vue comme une exception lev´ee lorsqu’une transformation est amen´ee `a rompre une topologie (par exemple, lorsque le chemin filtr´e et la s´equence rempla¸cante n’ont pas la mˆeme taille dans une collection newto-nienne ; c’est ΨN qui provoque la lev´ee de l’exception). La d´efinition formelle de D est donn´ee par l’´equation ci-dessous :

D = {⊥, wrong, shape} ∪ [

b∈B

Bb[

r∈R

C(D − {⊥}, r) ∪ (D → D)

Nous distinguons shape de wrong car les erreurs de types « classiques » seront d´etect´ees par notre syst`eme de types alors que les violations de topologie, d’une nature plus subtiles ne le seront pas (voir la section VII.10.2 `a ce sujet). On note T l’ensemble des valeurs ne faisant pas intervenir wrong. Cet ensemble ne se r´eduit pas `a D − {wrong} et est d´efini comme suit :

T = {⊥, shape} ∪ [

b∈B

Bb[

r∈R

C(T − {⊥}, r) ∪ (T → T)

Un environnement est une fonction d’un ensemble d’identifiants vers l’ensemble des valeurs D. On note Eval (e, E) la s´emantique de l’expression e dans l’environnement E.