Mini-ML
Mini language fonctionnel, pur:
(types)
τ ::= Int | Bool | τ
1→ τ
2(exps)
e ::= c | x | λx → e | e
1e
2| e : τ
let x = e
1in e
2| if e
1then e
2else e
3Ajout d’effets de bord:
(types)
τ ::= ... | ref τ | Unit
(expressions)
e ::= ... | ref e | !e | e
1:= e
2| e
1; e
2Typage bidirectionnel
Au lieu de
Γ ` e : τ
Le typage bidirectionnel utilise 2 jugements:
Γ ` e ⇒ τ Γ ` e ⇐ τ
R `egle habituelle: constructeurs v ´erifi ´es, ´eliminations inf ´er ´ees Souvent suffisant pour ´eliminer annotations sauf sur
let
Exprime un algorithme avec 2 fonctions mutuellements r ´ecursives:
infer
:
Ctx→
Exp→
Typcheck
:
Ctx→
Exp→
Typ→
UnitS ´emantique statique de Mini-ML pur
(type ctx)
Γ ::= • | Γ, x : τ Γ(x) = τ
Γ ` x ⇒ τ
Γ ` e
1⇒ τ
1→ τ
2Γ ` e
2⇐ τ
1Γ ` e
1e
2⇒ τ
2Γ, x : τ
1` e ⇐ τ
2Γ ` λx → e ⇐ τ
1→ τ
2Γ ` e ⇐ τ Γ ` e : τ ⇒ τ
Γ ` e ⇒ τ Γ ` e ⇐ τ
Γ ` e
1⇐ Bool Γ ` e
2⇐ τ Γ ` e
3⇐ τ Γ ` if e
1then e
2else e
3⇐ τ
Γ ` e
1⇒ τ
1Γ, x : τ
1` e
2⇔
aτ
2Γ ` let x = e
1in e
2⇔
aτ
2Pseudocode de l’algorithme bidirectionnel
infer Γ e = case e
| Evar x => lookup Γ x
| Eapply e
1e
2=> case infer Γ e
1| Tarw t
1t
2=> check Γ e
2t
1; t
2| Eannot e t => check Γ e t; t ...
check Γ e t = case e
| Elam x e => case t
| Tarw t
1t
2=> check (extend Γ x t
1) e t
2| Eif e
1e
2e
3=>
check Γ e
1Tbool; check Γ e
2t; check Γ e
3t ...
| _ => assert (t = infer Γ e)
S ´emantique dynamique de Mini-ML pur
(values)
v ::= λx → e | c v
1... v
nR ´eductions primitives:
(+) n
1n
2; n
3 wheren
3= n
1+ n
2(λx : τ → e) v ; e[v/x]
let x = v in e ; e[v/x]
e : τ ; e
if True then e
2else e
3; e
2if False then e
2else e
3; e
3S ´emantique dynamique de Mini-ML pur (suite)
R `egles de congruence:
e
1; e
01e
1e
2; e
01e
2e ; e
0v e ; v e
0e
1; e
01let x = e
1in e
2; let x = e
01in e
2e
1; e
01if e
1then e
2else e
3; if e
01then e
2else e
3Ou aussi:
(exps avec trou)
E ::= • | E e | v E | let x = E in e |
if E then e
2else e
3Typage avec effets de bord
...
Γ ` e ⇒ τ
Γ ` ref e ⇒ ref τ
Γ ` e ⇒ ref τ Γ ` !e ⇒ τ
Γ ` e
1⇐ Unit Γ ` e
2⇔
aτ
2Γ ` e
1; e
2⇔
aτ
2Γ ` e
1⇒ ref τ Γ ` e
2⇐ τ
Γ ` e
1:= e
2⇒ Unit
S ´emantique dynamique avec effets de bord?
e ; e
0 n’est plus suffisant, on a besoin de m ´emoire!Nouvelles valeurs, renvoy ´ees par
ref e
ete
1:= e
2: (values)v ::= ... | () | `
(heap)
M ::= • | M, ` 7→ v
Voyons d’abord une s ´emantique `a grands pas:
(M ; e) ↓ (M
0; v )
Evaluer´
e
dans le tasM
renvoie la valeurv
avec un nouveau tasM
0Effets de bord `a grands pas, partie pure
(M ; v) ↓ (M ; v) (M ; e) ↓ (M
0; v) (M ; e : τ ) ↓ (M
0; v)
(M ; e
1) ↓ (M
1; λx → e) (M
1; e
2) ↓ (M
2; v
2) (M
1; e[v
2/x]) ↓ (M
0; v) (M ; e
1e
2) ↓ (M
0; v)
(M ; e
1) ↓ (M
1; v
1) (M
1; e
2[v
1/x]) ↓ (M
0; v) (M ;
letx = e
1 ine
2) ↓ (M
0; v)
(M ; e
1) ↓ (M
1; v
1) (M
1; e) ↓ (M
0; v) e =
e
2if v
1= True e
3if v
1= False (M ;
ife
1 thene
2 elsee
3) ↓ (M
0; v)
¡L’existence de
:=
oblige `a changer les r `egles pures!Effets de bord `a grands pas, partie impure
(M ; e) ↓ (M
0; v) ` fresh (M ;
refe) ↓ (M
0, ` 7→ v; `)
(M ; e) ↓ (M
0; `) M
0(`) = v (M ; !e) ↓ (M
0; v)
(M ; e
1) ↓ (M
1; `) (M
1; e
2) ↓ (M
0; v) (M ; e
1:= e
2) ↓ (M
0, ` 7→ v; v)
(M ; e
1) ↓ (M
1; v
1) (M
1; e
2) ↓ (M
0; v)
(M ; e
1; e
2) ↓ (M
0; v))
Des expressions et des valeurs
Le r `egle d’ ´evaluation des valeurs est formellement incorrecte
(M ; v) ↓ (M ; v)
Parce qu’ `a gauche on doit avoir une expression:
•
Les valeursv
ne sont plus un sous-ensemble des expressionse
! Il faut(M ; c) ↓ (M ; c)
,(M ; λx → e) ↓ (M ; λx → e)
, ...Pour les petits pas, c¸a ne suffit pas; il faut ´etendre
e
: (exps)e ::= ... | `
ou m ˆeme
(exps)
e ::= ... | v
Effets de bord `a petits pas, partie pure
R ´eductions primitives:
(M ; (+) n
1n
2) ; (M ; n
3)
wheren
3= n
1+ n
2(M ; (λx : τ → e) v) ; (M ; e[v/x])
(M ; let x = v in e) ; (M ; e[v/x]) (M ; e : τ ) ; (M ; e)
(M ; if True then e
2else e
3) ; (M ; e
2) (M ; if False then e
2else e
3) ; (M ; e
3)
Rien de chang ´e, mis `a part l’ajout du
M
partoutEffets de bord `a petits pas, partie impure
R ´eductions primitives:
(M ; ref v ) ; (M, ` 7→ v; `)
where` fresh (M ; !`) ; (M ; v)
whereM (`) = v (M ; ` := v ) ; (M, ` 7→ v; ())
(M ; (); e) ; (M ; e)
(exps avec trou)
E ::= • | E e | v E | let x = E in e
| if E then e
2else e
3| ref E | !E | E := e | v := E | E ; e
R `egles de typage valides?
Comment s’assurer de la validit ´e des r `egles de typage?
Si
e : τ
, la valeurv
retourn ´ee pare
devrait avoir typeτ
La coh ´erence (soundness) des r `egles peut se d ´ecomposer en:
•
pr ´eservation des types: Sie : τ
ete ; e
0 alorse
0: τ
•
progr `es: Sie : τ
, oue ; e
0 oue
est une valeur Ensemble, cela donne:Si
e : τ
ete ;
∗e
0,
alorse
0 n’est pas stuck: oue
0; e
00 oue
0 est une valeur“well-typed programs do not go wrong”
Coh ´erence du typage de Mini-ML?
En g ´en ´eral, progr `es ne s’applique que dans un environnement vide:
Si
• ` e : τ
, alors ou(M ; e) ; (M
0; e
0)
oue
est une valeur Pr ´eservation des types implique, par exemple:Vu que
• `
ref4 :
ref Int et(M ;
ref4) ; (M, ` 7→ 4; `)
alors
• ` ` :
ref IntIl nous faut donc une r `egle de typage pour
`
:?
Γ ` ` : τ Ψ
donnera un type `a chaque adresse:(heap type)
Ψ ::= • | Ψ, ` : τ
Nouveaux jugements de typage
Il faut v ´erifier que
Ψ
est bien le type deM
, avec` M : Ψ
:Ψ ` M : Ψ
` M : Ψ Ψ ` • : •
Ψ ` M : Ψ
0Ψ; • ` v ⇐ τ Ψ ` M, ` 7→ v : Ψ
0, ` : τ
Et les jugements prennent maintenant la forme:
Ψ; Γ ` e ⇔
aτ Γ(x) = τ
Ψ; Γ ` x ⇒ τ · · · Ψ(`) = τ
Ψ; Γ ` ` ⇒ ref τ
Aucun jugement ne modifie
Ψ
, e.g.:Ψ; Γ ` e ⇒ τ
Ψ; Γ ` ref e ⇒ ref τ
Ψ; Γ ` e
1⇒ ref τ Ψ; Γ ` e
2⇐ τ
Ψ; Γ ` e
1:= e
2⇒ Unit
Coh ´erence du typage de Mini-ML
Progr `es:
Si
` M : Ψ ∧ Ψ; • ` e ⇐ τ
alors
(M ; e) ; (M
0; e)
0∨ e
est une valeur Pr ´eservation des types:Si
` M : Ψ ∧ Ψ; Γ ` e ⇐ τ ∧ (M ; e) ; (M
0; e)
0alors
∃Ψ
0. ` M : Ψ
0∧ Ψ
0; Γ ` e
0⇐ τ
Preuve de pr ´eservation des types
Dans le cas o `u
e = (λx : τ → e
1) v
ete
0= e
1[v/x]
, on doit prouverΨ; Γ ` e
1[v/x] ⇐ τ
2,sachant que
Ψ; Γ, x : τ
1` e
1⇐ τ
2 etΨ; Γ ` v ⇐ τ
1Lemme de substitution ressemble habituellement `a:
Si
Ψ; Γ, x : τ
1, Γ
0` e : τ
2∧ Ψ; Γ ` v : τ
1alors
Ψ; Γ, Γ
0` e[v/x] : τ
2Ce genre de lemme est r ´ecurrent dans les preuves de pr ´eservation
Preuve de progr `es
Dans le cas
e = e
1e
2, sie
1 oue
2 n’est pas une valeur,alors on trouve imm ´ediatement un pas
e ; e
0 par induction,sinon il nous faut prouver que
e = (λx → e
3) e
2 pour appliquerβ
Lemme de formes canoniques ressemble habituellement `a:
Si
Ψ; • ` v : τ
1→ τ
2alors
v = λx → e
Ce genre de lemme est r ´ecurrent dans les preuves de progr `es