• Aucun résultat trouvé

ISommes binaires Sym´etriquement, on peut ´equiper Core ML de sommes binaires en introdui-sant deux constructeurs unaires,inj1 et inj2, appel´esinjection gauche et injection droite, respec-tivement, et un destructeur ternaire casedont la s´emantique est d´efinie par la r`egle suivante, o`u j∈ {1,2}:

(injjv)casev1v2/ µ−casevjv+∅ (case) Les valeursv1 et v2 sont typiquement des λ-abstractions et repr´esentent les deux branches d’une constructioncaseoumatch. . .withhabituelle.

Les Bool´eens peuvent naturellement ˆetre vus comme un cas particulier de somme binaire : on repr´esente les constantestrueet falserespectivement parinj1() etinj2(). La constructionifvthen e1elsee2peut est alors un sucre syntaxique pourvcase(λx.e1) (λx.e2), o`uxest une variable qui n’est libre ni danse1ni danse2. Il est ais´e de v´erifier que l’on a alors les deux r´eductions suivantes :

if true thene1elsee2e1

if false thene1elsee2e2

IPoint fixe Les constructions de base de Core ML ne permettent pas la r´ecursion. Celle-ci peut ˆetre introduite `a l’aide d’une primitive binairefix. En ML, la s´emantique de cette constante est d´efinie de telle mani`ere que l’applicationfixv1v2 produit l’expressionv1(fixv1)v2. Cependant, cette derni`ere forme n’est pas une expression valide Core ML, `a cause des restrictions pos´ees sur la syntaxe. Il est n´ecessaire d’effectuer une η-expansion de l’application partielle fixv1, puis d’introduire une liaisonbindpour nommer le r´esultat de l’application dev1`a son premier argument, ce qui donne la r`egle suivante :

fixv1v2/ µ−fixbindx1=v1(λx2.fixv1x2)inx1v2+∅ (fix) (Il n’est pas n´ecessaire de faire d’hypoth`ese de fraˆıcheur sur les variables x1 et x2, puisque les valeurs v1 et v2 sont n´ecessairement closes.) La primitive fix est g´en´eralement utilis´ee avec une λ-abstraction comme premier argument. En particulier, la construction usuelle let recf x =e1 in e2, qui permet de d´efinir une fonctionf de mani`ere r´ecursive, peut ˆetre cod´ee par l’expression letf =λy.fix(λf.λx.e1)yine2(avecy6∈fpv(e1)).

5.2 Le langage Core ML

2

5.2.1 Pr´esentation

Prouver une propri´et´e de non-interf´erence n´ecessite de consid´erer simultan´ement deux pro-grammes pour ´etablir qu’ils partagent des sous-expressions tout au long de leur r´eduction. Afin de rendre ce raisonnement plus simple, je vais repr´esenter ces deux programmes commeune seule expression d’un langage ´etendu, appel´e Core ML2, au lieu d’une paire d’expressions Core ML. Les valeurs, r´esultats et expressions de Core ML2 sont obtenus en ´etendant la syntaxe de Core ML comme suit :

v ::=. . .| hv|vi (valeur) a::=. . .| ha|ai (r´esultat) e::=. . .| he|ei (expression)

L’expression Core ML2he1|e2ipermet de repr´esenter la paire d’expressions (e1, e2). Il faut noter que les crochets peuvent apparaˆıtre `a une profondeur arbitraire dans une expression. Par exemple, siv est une valeur Core ML alors les expressionshv1|v2iv et hv1v |v2virepr´esentent toutes les deux la paire (v1v, v2v). Cependant, la premi`ere est plus pr´ecise que la seconde puisqu’elle explicite le fait que le nœud de l’application et son argument v sont partag´es entre les deux expressions.

L’imbrication de constructionsh. . .|. . .in’est pas autoris´ee, puisque cela n’aurait pas de sens

vis-`

a-vis de l’interpr´etation donn´ee aux crochets : ainsi, les sous-expressionse1 ete2 d’une expression he1 | e2i doivent ˆetre des expressions du sous-ensemble Core ML. La correspondance entre Core

104 Chapitre 5·Core ML et Core ML2: Syntaxe et s´emantique

ML et Core ML2 est rendue explicite par deux projections, not´eesb·ci o`u i est un ´el´ement de {1,2}. Ces deux fonctions v´erifient bhe1 | e2ici = ei et sont des homomorphismes sur toutes les autres constructions du langage. On ´etend la d´efinition de fpv(e) et fml(e) aux expressions Core ML2.

J’ai choisi de ne pas introduire pour Core ML2des notations distinctes de celles de Core ML, dans le but de ne pas alourdir la pr´esentation : ainsi, je conserve les mˆemes meta-variablev,aeteet r´eutiliserai plusieurs des notations introduites `a la section5.1.2(page99) pour d´efinir la s´emantique de Core ML2. Cependant, aucune ambigu¨ıt´e n’en r´esultera puisque je consid`ere d´esormais Core ML comme un sous-ensemble de Core ML2.

Avant de poursuivre, il est peut-ˆetre utile d’expliquer informellement comment Core ML2 per-met de garder trace des diff´erences entre deux expressions Core ML tout au long de leur r´eduction.

Consid´erons par exemple la fonctionλx.b0. ´Evidemment, son r´esultat ne r´ev`ele aucune information sur son argument, puisqu’il s’agit d’une constante enti`ere. Le syst`eme de types que je vais pr´esenter au chapitre6(page113) ´etablira que cette fonction associe des r´esultats«publics»`a des entr´ees

« secr`etes ». D`es lors, pour prouver que le syst`eme de types est correct, je dois ´etablir un r´esul-tat de non-interf´erence : pour tous entiers n1 et n2, les deux programmes (λx.b0)bn1 et (λx.b0)nb2

produisent la mˆeme valeur. Pour cela, je repr´esenterai cette paire de programmes `a l’aide d’une expression Core ML2,e= (λx.b0)hnb1|bn2i; ses deux projections ´etant naturellement les deux pro-grammes originaux : pour tout i∈ {1,2},beci est ei. Notons que les arguments« secrets»nb1et b

n2apparaissent dansesous des crochets, alors que l’application deλx.b0 est partag´ee,i.e.apparaˆıt en dehors des crochets. Suivant la s´emantique de Core ML2 que je vais d´ecrire `a la section5.2.3, l’expression (λx.b0)hnb1 | bn2i se r´eduit en la valeur Core ML2 b0. Le fait que ce r´esultat ne com-porte aucune construction h· | ·i assure que ses deux projections co¨ıncident, c’est-`a-dire que les programmes originauxe1ete2produisent tous les deux la mˆeme valeur. La preuve du th´eor`eme de non-interf´erence d´evelopp´ee au chapitre6(page113) est bas´ee sur le mˆeme principe : je montrerai que, sous des hypoth`eses de typage appropri´ees, le r´esultat d’une s´equence de r´eductions Core ML2 ne comporte pas de crochets.

La r´eduction (λx.b0)hbn1 | nb2i →b0 que nous venons d’´etudier est tr`es simple. Cependant, les r´eductions de Core ML2peuvent, en g´en´eral, ˆetre plus complexes : plusieurs des r`egles de r´eduction que je vais introduire doivent faire remonter les crochets quand ils bloquent la r´eduction (j’appellerai ces r`egles des r`egles«lift»). Par exemple, puisque l’applicationhλx.x|λx.b0ib1 n’est pas unβ-redex, elle ne peut ˆetre r´eduite par (β). C’est pourquoi j’introduirai une nouvelle r`egle, (lift-β), pour la r´eduire enh(λx.x)b1|(λx.b0)b1i. Il faut remarquer que cette ´etape de r´eduction n’affecte aucune des projections de l’expression en question. Ainsi, elle n’a pas de contenu calculatoire : le d´eplacement des crochets refl`ete seulement un flot d’information. Enfin, chaque membre de la nouvelle expression est maintenant unβ-redex qui peut ˆetre r´eduit : nous obtenons ainsih(λx.x)b1|(λx.b0)b1i →hb1|b0i.

5.2.2 ´ Etats m´emoire et configurations

De mˆeme que la syntaxe des valeurs, r´esultats et expressions, je dois ´etendre celle des blocs m´emoire, des ´etats m´emoire et des configurations pour donner une s´emantique op´erationnelle `a Core ML2. En effet, il faut garder trace du partage non seulement entre les expressions mais aussi entre les ´etats m´emoire de deux configurations. Cependant, deux ´etats m´emoire peuvent allouer des adresses m´emoire distinctes ; c’est la raison pour laquelle la syntaxe des blocs m´emoire doit ˆetre ´etendue comme suit :

w::=. . .| hv|nulli | hnull|vi (bloc m´emoire)

Les blocs de la formehv|nulliouhnull|vi(o`u la valeurvdoit ˆetre close) permettent de repr´esenter les situations o`u une adresse m´emoirem est allou´ee dans seulement un des deux ´etats m´emoire Core ML repr´esent´es par un ´etat m´emoire Core ML2, qui est naturellement une fonction totale

5.2· Le langage Core ML2 105

R´eductions de base

(λx.e)v /iµ → e[x←v]/iµ (β)

letx=vine /iµ → e[x←v]/iµ (let)

f ~v /iµ → e /iµ4iµ0

sif ~v /bµcife+µ0

(δ)

E[a]/ µ → Ea / µ (pop)

R`egles «lift»

hv1|v2iv / µ → hv1bvc1|v2bvc2i/ µ (lift-β) f ~v / µ → hfb~vc1|fb~vc2i/ µ

si~v / µ6↓f, b~vc1/bµc1f etb~vc2/bµc2f

(lift-δ) E[ha1|a2i]/ µ → hbEc1a1| bEc2a2i/ µ

siEn’accepte pasha1|a2i

(lift-pop) R´eduction sous un contexte

E[e]/iµ → E[e0]/iµ0 sie /iµ→e0/iµ0

(context) he1|e2i/ µ → he01|e02i/ µ0

siei1/i1µ→e0i1/i1µ0 etei2=e0i2

avec {i1, i2}={1,2}

(bracket)

Figure 5.3– S´emantique op´erationelle de Core ML2

des adresses m´emoire vers ces blocs m´emoire. Les fonctions de projection sont ´etendues au blocs m´emoire par les ´egalit´es

bnullc1 = null bhnull|vic1 = null bhv|nullic1 = v bnullc2 = null bhnull|vic2 = v bhv|nullic2 = null

puis point `a point aux ´etats m´emoire : pour tousiet m, bµci(m) =bµ(m)ci. Un ´etat m´emoireµ de Core ML2 est bien form´e si et seulement si seul un nombre fini d’adresses m´emoire est allou´e dansµ, et si, pour tousi∈ {1,2},µ∈fml(bµci) impliquebµ(m)ci6=null. Ce crit`ere est ´equivalent

`

a la bonne formation, au sens de Core ML, des deux ´etats m´emoirebµc1 etbµc2.

Une configuration Core ML2, not´ee e /iµ, est un triplet form´e d’une expressione, d’un ´etat m´emoireµainsi que d’un indexi∈ {•,1,2}dont j’expliquerai le rˆole section5.2.3. Notons toutefois que, dans le cas o`u i est 1 ou 2, edoit ˆetre une expression Core ML (c’est-`a-dire une expression sans crochets). J’´ecris e / µ pour e / µ et d´efinis les projections d’une telle configuration par be / µci=beci/bµci.

Les r`egles de bonne formation des configurations donn´ees pour Core ML doivent ˆetre ´etendues

`

a Core ML2 comme suit :

– La configuratione/µest bien form´ee si et seulement siµest bien form´e et pour tousi∈ {1,2}

et m∈fml(beci),bµ(m)ci6=null. Ce crit`ere est ´equivalent `a la bonne formation, au sens de Core ML, des configurationsbe / µc1 et be / µc2.

– Pour pour i ∈ {1,2}, la configuration e /iµ, est bien form´ee si et seulement si µ est bien form´e et, pour toutm∈fml(e),bµ(m)ci6=null.

5.2.3 S´emantique op´erationnelle

La s´emantique op´erationnelle `a petits pas de Core ML2est donn´ee figure5.3. Cette s´emantique

´etend celle donn´ee pour Core ML (section 5.1.2, page 99). Les r`egles sont con¸cues de telle sorte que l’image d’une r´eduction par une projection soit ´egalement une r´eduction valide. L’´evaluation

106 Chapitre 5·Core ML et Core ML2: Syntaxe et s´emantique

peut avoir lieu en dehors des crochets — les deux projections effectuant alors la mˆeme ´etape de r´eduction — ou bien avoir lieu `a l’int´erieur des crochets — l’une des projections progressant ind´ependamment, l’autre restant inchang´ee — ou bien faire remonter des crochets — perdant alors une partie du partage.

Les r`egles du premier groupe sont syntaxiquement identiques `a celles de Core ML — `a l’excep-tion de quelques d´etails techniques expliqu´es dans le prochain paragraphe. Les meta-variablev,a, e et µrepr´esentent maintenant des valeurs, r´esultats, expressions et ´etats m´emoire de Core ML2 qui peuvent comporter des crochetsh· | ·i.

La substitution de la variablex par la valeurv danse, utilis´ee dans les r`egles (β) et (let), est not´eee[x←v]. Elle est d´efinie de la mani`ere habituelle, except´ee aux nœudsh· | ·i, o`u la projection appropri´ee devdoit ˆetre prise pour chaque branche :he1|e2i[x←v] =he[x← bvc1]|e[x← bvc2]i.

La fonctionutilis´ee dans la r`egle (pop) peut toujours ˆetre d´efinie par les ´egalit´es de la figure5.2 (page100). Cependant, celles-ci doivent d´esormais ˆetre lues en consid´erant que les meta-variablee, v,aet hd´enotent des expressions, valeurs, r´esultats et clauses du langage Core ML2. Il faut noter quen’est plus une fonction totale : (bindx= [ ]ine) ha1|a2iet ([ ]handle~h) ha1|a2ine sont pas d´efinis sia1eta2 ne sont pas deux valeurs. La r`egle (pop) n’est naturellement applicable que siEaest d´efini, on dit dans ce cas queEaccepte a. De mˆeme, la s´emantique des primitives doit ˆetre ´etendue : elle est donn´ee par des relations −f (dont les jugements sont de la forme

~v /µ−fe+ ˙µo`u les valeurs~v, l’´etat m´emoireµet le fragment ˙µainsi que l’expressionepeuvent comporter des crochets), et qui ´etendent les relations−f. Je donnerai des exemples section5.2.4 (page108).

Les r`egles des deux premiers groupes sont applicables sous tout contexte. Cependant, (δ) a be-soin d’un peu d’information contextuelle pour acc´eder `a l’´etat m´emoire : les r´eductions qui ont lieu sous une constructionh· | ·ine doivent lire ou ´ecrire qu’une de ses deux projections. C’est pr´ecis´e-ment le rˆole de l’indexiport´e par les configurations : sa valeur est •pour les ´etapes de r´eduction en dehors des crochets, la r`egle (bracket) rend sa valeur ´egale `a 1 (resp. 2) pour les r´eductions qui ont lieu `a l’int´erieur d’une branche gauche (resp. droite) d’une constructionh· | ·i. Cet indice est ensuite utilis´e dans la r`egle (δ) pour manipuler l’´etat m´emoire d’une mani`ere convenable. Tout d’abord, la primitive ne doit acc´eder qu’`a la partie de l’´etat m´emoire qui correspond au contexte : ainsi, le membre gauche de la pr´emisse de (δ) mentionne la projection bµci (par convention, on posebµc=µ). D’autre part, la r´eduction ne peut affecter (en allouant ou en modifiant des blocs) que cette mˆeme projection : pouri∈ {•,1,2}, l’op´erateur4i est d´efini par les ´equations

(µ4iµ0)(m) = µ(m) sim6∈dom(µ0) (µ4µ0)(m) = µ0(m) 

(µ41µ0)(m) = hµ0(m)| bµ(m)c2i  sim∈dom(µ0) (µ42µ0)(m) = hbµ(m)c10(m)i

Notons que l’indicein’est pas transmis aux relations−f. En utilisant le fait qu’elles retournent un fragment ˙µ pr´ecisant les modifications apport´ees `a l’´etat m´emoire initial (au lieu du nouvel

´etat m´emoire lui-mˆeme), il est en effet possible de d´eduire la s´emantique des primitives dans les contextesi= 1 eti= 2 `a partir de celle donn´ee pour le cas i=•: c’est pr´ecis´ement le rˆole de la r`egle (δ) et de l’op´erateur4i.

Il me faut enfin ´enoncer quelques hypoth`eses sur chaque relation −f. Les deux premi`eres hypoth`eses sont techniques, elles visent `a pr´eserver la bonne formation des configurations : l’une est la contrepartie l’hypoth`ese5.1(page100) donn´ee pour Core ML, l’autre garantit que si l’argument d’une primitive ne comporte pas de crochets alors il en est de mˆeme de son r´esultat (ce qui assure que l’on ne construit pas d’imbrications de telles constructions).

Hypoth`ese 5.5 Pour toutf, (i)la relation−fest stable par renommage des adresses m´emoires et (ii) si f ~v / µ −f e+ ˙µ alors, pour tout i ∈ {1,2} et m ∈ fml(beci,bµc˙ i), m ∈ dom( ˙µ) ou

bµ(m)ci6=null.

5.2· Le langage Core ML2 107

Hypoth`ese 5.6 Sif ~v / µ−fe+ ˙µet~vetµne comportent pas de constructionh· | ·i alors il en

est de mˆeme deeetµ.˙

La troisi`eme hypoth`ese exprime, au niveau des primitives, la correspondance entre la s´emantique de Core ML2 et celle du sous-ensemble Core ML : l’image d’une r´eduction par une projection doit rester une r´eduction valide. Cette hypoth`ese est utilis´ee dans la preuve du lemme 5.10(page109).

Hypoth`ese 5.7 Sif ~v / µ−fe+ ˙µalors, pour touti∈ {1,2}, fb~vci/bµcifbeci+bµc˙ i. Les r`egles du deuxi`eme groupe empˆechent les constructions h· | ·i de bloquer la r´eduction : pour cela, elles« remontent» les crochets, d´epartageant des sous-expressions mais permettant `a la r´eduction de se poursuivre ind´ependemment dans chaque branche. Par exemple, l’expression du membre gauche de (lift-β) n’est pas un β-redex et son application duplique la sous-expressionv.

Le calcul ´etiquet´e de Abadi, Lampson et L´evy [ALL96] comporte une r`egle quelque peu analogue, permettant de r´eduire les applications dont le membre gauche est une valeur ´etiquet´ee. On peut interpr´eter les r`egleslift en voyant le contenu de chaque h· | ·icomme« secret» : en rendant de nouvelles sous-expressions secr`etes lors des r´eductions, ces r`egles donnent en fait une description dynamique des flots d’information.

La r`egle (lift-δ) permet de d´epartager un appel `a une primitive bloqu´e par des crochets. Le pr´edicat~v / µ↓f utilis´e dans sa condition d’application signifie que, sous l’´etat m´emoire, l’appel `a la primitivef avec les arguments~vn’est pas bloquant,i.e.il existeaet ˙µtels quef ~v /µ−fa+ ˙µ.

La r`egle (lift-pop) compl`ete la r`egle (pop) en r´eduisant les expressions de la forme E[a] o`u E n’accepte pasa. Le traitement de ces formes d’expressions diff`ere quelque peu de celui suivi pour les paires de r`egles (β) et (lift-β) ou (δ) et (lift-δ) : en effet, en plus de d´epartager le contexteE, (lift-pop) effectue imm´ediatement une ´etape de r´eduction dans chaque projection. Il serait probablement plus naturel de consid´erer la r`egle suivante :

E[ha1|a2i]→ hbEc1[a1]| bEc2[a2]i siEn’accepte pasha1|a2i

(lift-pop’)

Supposons un instant que r`egle (lift-pop) est remplac´ee par (lift-pop’). La r´eductionE[ha1 |a2i]/ µ→hbEc1a1| bEc2a2i/ µs’effectue alors en trois ´etapes de r´eduction :

E[ha1|a2i]/ µ → hbEc1[a1]| bEc2[a2]i/ µ (lift-pop’)

→ hbEc1a1| bEc2[a2]i/ µ (pop)

→ hbEc1a1| bEc2a2i/ µ (pop)

Cependant, cette d´efinition de la s´emantique de Core ML2n´ecessiterait une formulation plus com-plexe du syst`eme de type pour Core ML2 au chapitre 6 (page 113), de mani`ere `a garantir la pr´eservation du typage parchacune des ´etapes interm´ediaires. Le langage Core ML2n’´etant qu’un outil utilis´e pour prouver le th´eor`eme de non-interf´erence, je pr´ef`ere compliquer l´eg`erement la d´efinition de sa s´emantique et conserver une formulation simple du syst`eme de type.

Bien entendu, la s´emantique de Core ML2 est donn´ee de mani`ere `a limiter autant que possible la perte de partage ; on pourrait en effet remplacer toutes les r`egleslift par la seule r`egle

e / µ→ hbec1| bec2i/ µ

qui est s´emantiquement correcte, mais obligerait ensuite le syst`eme de type `a consid´erer toute expression comme«secr`ete». Par ailleurs, la constructionh· | ·irappelle les nœudsfork introduits par Field et Teitelbaum pour effectuer une r´eduction incr´ementale des λ-termes [FT90] : (lift-β) est en fait l’une de leurs r`egles de r´eduction. Cependant, mon approche diff`ere sur certains points.

En particulier, je manipule des expressions alors que Field et Teitelbaum consid`erent des graphes, permettant `a des sous-expressions d’ˆetre partag´ees par les deux projections.

108 Chapitre 5·Core ML et Core ML2: Syntaxe et s´emantique

c

n1+bcn2/ µ −+b n\1+n2+∅ (add)

projj(v1, v2)/ µ −projj vj+∅ (proj)

(injjv)casev1v2/ µ −case vjv+∅ (case) refv / µ −ref m+ (m7→v)

siµ(m) =null

(ref) m:=v0/ µ[m7→v] −:= () + (m7→v0) (assign)

!m / µ[m7→v] −! v+∅ (deref)

fixv1v2/ µ −fix bindx1=v1(λx2.fixv1x2)inx1v2+∅ (fix) Figure 5.4– R`egles de r´eduction des constantes

hv1|v2i+bv / µ → hv1+bbvc1|v2+bbvc2i/ µ (lift-add-1) v+bhv1|v2i/ µ → hbvc1+bv1| bvc2+bv2i/ µ (lift-add-2) projjhv1|v2i/ µ → hprojjv1|projjv2i/ µ (lift-proj) hv1|v2icasev01v20 / µ → hv1casebv10c1bv20c1|v2casebv10c2bv02c2i/ µ (lift-case) hv1|v2i:=v / µ → hv1:=bvc1|v2:=bvc2i/ µ (lift-assign)

!hv1|v2i/ µ → h!v1|!v2i/ µ (lift-deref) Figure 5.5– R`egles«lift»

5.2.4 Constantes

Je termine cette section en poursuivant le traitement des exemples de constructeurs et destruc-teurs introduits `a la section5.1.3(page102). Les r`egles de r´eduction de ces constantes dans Core ML2 sont donn´ees figure 5.4. Une fois encore, elles sont syntaxiquement identiques `a celles des r`egles de Core ML, cependant les meta-variablev etµ d´esignent ici des valeurs et ´etats m´emoire Core ML2. Il est imm´ediat de v´erifier la correction de ces r`egles exprim´ees par l’´enonc´e suivant.

Propri´et´e 5.8 Les relations −+b, −projj, −case, −ref, −:=, −! et −fix v´erifient les

hypoth`eses5.5, 5.6et 5.7.

Dans la pr´esentation originale de Core ML2 [PS02, PS03], chaque primitive est munie d’une r`eglelift sp´ecifique applicable lorsque un argument de la forme hv1|v2ibloque la r´eduction. Ces r`egles sont rappel´ees par la figure5.5. Elles sont int´eressantes pour elles-mˆemes, car elles d´ecrivent les flots d’information engendr´es par les primitives. Dans cette th`ese, ces r`egles sont remplac´ees par (lift-δ), qui d´epartage une application de primitive quand son ´evaluation est bloqu´ee par les crochets. Pour ce qui concerne nos exemples, cette r`egle permet de r´ealiser exactement les r´eductions indiqu´ees figure5.5.