INF 321
Programmation fonctionnelle, typage, isomorphisme de Curry-Howard
Eric Goubault
Cours 9
3 juillet 2013
Dans le dernier ´ episode...
On a vu:
Validation
Syst`emes de preuve en logique On va voir:
Retour sur la programmation fonctionnelle (Caml, Haskell...)!
Strat´egies d’´evaluation (eager/lazy) Typage et isomorphisme de Curry-Howard
En fait c’est un cours sur la r´ecursivit´e, les r´ef´erences, et la preuve de programmes, revisit´ees dans les langages fonctionnels! C’est aussi l’occasion de voir une nouvelle s´emantique, op´erationnelle, des langages de programmation
Dans le dernier ´ episode...
On a vu:
Validation
Syst`emes de preuve en logique On va voir:
Retour sur la programmation fonctionnelle (Caml, Haskell...)!
Strat´egies d’´evaluation (eager/lazy) Typage et isomorphisme de Curry-Howard
En fait c’est un cours sur la r´ecursivit´e, les r´ef´erences, et la preuve de programmes, revisit´ees dans les langages fonctionnels! C’est aussi l’occasion de voir une nouvelle s´emantique, op´erationnelle, des langages de programmation
PCF
“Programming Computable Functions” (Gordon Plotkin 1977) Substantifique mo¨elle des langages fonctionnels
Les fonctions sont des objets “de premi`ere classe”
Construction de fonction fun x -> t correspondant au Caml (au nommage pr`es):
l e t f x = t
Application d’une fonction `a un argumentt t (on peut appliquer une fonction `a une fonction - et mˆeme `a soi-mˆeme!
(“Sucre syntaxique” au dessus du λ-calcul)
Grammaire de PCF
t ::= x
| fun x−>t
| t t | t×t
| n
| t+t | t−t | t∗t | t/t
| ifz t then t else t
| fix x t
| let x=t in t
Remarques
On pourrait rajouter une construction somme...
Le langage PCF est complet au sens de Turing! (permet de calculer toutes les fonctions r´ecursives partielles, cf. cours 5)
fix ?
Op´erateur de point fixe
Permet de d´efinir des fonctions r´ecursives (interdites syntaxiquement dans PCF)
Exemple, la fonction factorielle:
fix f fun n -> ifz n then 1 else n∗(f(n−1)) C’est la “plus petite” fonction f telle que
f(n) =
1 si n= 0
n∗f(n−1) sinon
S´emantique donn´ee au cours 7! (plus petit point fixe d’une certaine fonctionnelle)
En Caml, c’est lelet rec
S´ emantique op´ erationnelle
On va d´ecrire les actions, une `a une, lors de l’ex´ecution d’un programme PCF (s´emantiquepetits pas)
Cela va prendre la forme der`egles de r´eductionou de r´e´ecriture:
p→q
ou “le termep se r´e´ecrit (ou se r´eduit en une ´etape) en le terme q”
On a le droit de r´e´ecrire n’importe quel sous-terme, a priori dans n’importe quel ordre
En fait
Forme un automate (cf. taupe)
Ou encore un graphe ´etiquet´e (cf. cours 10)
R` egles de r´ eduction
β-r´eduction
(fun x -> t)u →t[u/x]
o`u t[u/x] est le termet dans lequel on remplace syntaxiquement toutes les occurrences de la variablex par le termeu.
Calcul arithm´etique (tautologique!) p+q →n
si l’entierp plus l’entier q est ´egal `an... Reste similaire...
Conditionnelles
ifz 0 then t else u→t
ifz n then t else u →u sin 6= 0
R` egles de r´ eduction, suite
Op´erateur de point fixe
fix x t →t[fix x t/x]
Ce qui veut dire? Doit vous rappeler les r`egles de calcul de point fixe (par exemple en preuve `a la Hoare)
D´efinition
let x =t in u→u[t/x]
Exemples
Un calcul arithm´etique simple
(fun x -> x+ 2) 3 → 3 + 2 β-r´eduction
→ 5 r`egles arithm´etiques Remarque: notion soulign´ee pour la partie qui int´eragit, qui va ˆetre r´eduite. S’appelle un r´edex.
En fait...
On peut mˆeme se passer de l’arithm´etique...
[n] =fun z -> fun s -> s(s(s(. . .(s z). . .))) (o`u on r´ep`ete n∈Nfois l’application de s) repr´esentel’entier n
On peut ensuite coder facilement les op´erations, addition, multiplication...:
+ = fun n -> fun p -> fun z -> fun s -> n(pzs)s
× = fun n -> fun p -> fun z -> fun s ->
nz(fun z -> pzs)
entiers de Church (Alonzo Church, 1930)
De mˆeme pour les bool´eens et pour la conditionnelle...
PCF:sucre syntaxique autour duλ-calcul (Church!)
Terminaison des r` egles de r´ eduction?
Exemple
fix x x →fix x x →. . .ne termine pas!
En mˆeme temps, qu’est-ce que ca veut dire? (penser au typage...cf. la deuxi`eme moiti´e de ce cours)
Mais pratique, car en fait...du coup...
Le termefix n’est pas n´ecessaire non plus! (dans un cadre non-typ´e, voir la suite...)
Combinateur Y
Definir le terme Y suivant:
fun f -> (fun x -> f (x x))(fun x -> f (x x)) Soit g un terme PCF, alors:
Y g = (fun f -> (fun x -> f (x x)) (fun x -> (f (x x))))g
Combinateur Y
Definir le terme Y suivant:
fun f -> (fun x -> f (x x))(fun x -> f (x x)) Soit g un terme PCF, alors:
Y g = (fun f -> (fun x -> f (x x)) (fun x -> (f (x x))))g β-r´eduction externe
= (fun x -> g (x x))(fun x -> g (x x))
Combinateur Y
Definir le terme Y suivant:
fun f -> (fun x -> f (x x))(fun x -> f (x x)) Soit g un terme PCF, alors:
Y g = (fun f -> (fun x -> f (x x)) (fun x -> (f (x x))))g β-r´eduction externe
= (fun x -> g (x x))(fun x -> g (x x)) β-r´eduction interne
= g(fun x -> g (x x))(fun x -> g (x x))
Combinateur Y
Definir le terme Y suivant:
fun f -> (fun x -> f (x x))(fun x -> f (x x)) Soit g un terme PCF, alors:
Y g = (fun f -> (fun x -> f (x x)) (fun x -> (f (x x))))g β-r´eduction externe
= (fun x -> g (x x))(fun x -> g (x x)) β-r´eduction interne
= g(fun x -> g (x x))(fun x -> g (x x))
= g (Y g)
Oui mais...
On aurait aussi ´evaluer de la fa¸con suivante:
En effectuant la deuxi`emeβ-reduction (interne) avant la premi`ere...
On aurait eu:
Y g = (fun f -> (fun x -> (f (x x)) (fun x -> (f (x x))))) g
Oui mais...
On aurait aussi ´evaluer de la fa¸con suivante:
En effectuant la deuxi`emeβ-reduction (interne) avant la premi`ere...
On aurait eu:
Y g = (fun f -> (fun x -> (f (x x)) (fun x -> (f (x x))))
g (β-r´eduction interne)
= (fun f -> (f (fun x -> f (x x))) (fun x -> f (x x))) g
Oui mais...
On aurait aussi ´evaluer de la fa¸con suivante:
En effectuant la deuxi`emeβ-reduction (interne) avant la premi`ere...
On aurait eu:
Y g = (fun f -> (fun x -> (f (x x)) (fun x -> (f (x x))))) g (β-r´eduction interne)
= (fun f -> (f (fun x -> f (x x))) (fun x -> f (x x)))g
(β-r´eduction interne)
= (fun f -> f f (fun x -> f (x x)) (fun x -> f (x x)))g
= etc.!
Oui mais...
On aurait aussi ´evaluer de la fa¸con suivante:
En effectuant la deuxi`emeβ-reduction (interne) avant la premi`ere...
On aurait eu:
Y g = (fun f -> (fun x -> (f (x x)) (fun x -> (f (x x))))) g (β-r´eduction interne)
= (fun f -> (f (fun x -> f (x x))) (fun x -> f (x x)))g
(β-r´eduction interne)
= (fun f -> f f (fun x -> f (x x)) (fun x -> f (x x)))g
= etc.!
Ne termine pas (en fait c’est Kleene...)! (rappelez vous fix x x!)
Ordre d’´ evaluation
On voit que:
On n’a pas sp´ecifi´e l’ordre d’utilisation des r`egles de r´eduction!
Ca peut tout changer?
Notre chance:
Appelons terme irr´eductible (dans PCF) un terme sur lequel on ne peut appliquer aucune r`egle de r´eduction
On a une propri´et´e de confluence: si on utilise les r`egles de r´eduction dans n’importe quel ordrequi termine sur un terme irr´eductible, alors on termine toujours sur le mˆeme terme irr´eductible
Clairement pas vrai si on oublie la condition d’irr´eductibilit´e...
(penser encore `afix x x!)
Ordres d’´ evaluation
Exemple
(fun f -> fun x -> f(f x))(fun x -> x+ 2)
fun x -> (fun x -> x+ 2)(fun x -> x+ 2)x
fun x -> (fun x -> x+ 2) (x+ 2)
fun x -> (fun x -> (x+ 2) + 2) x
fun x -> (x+ 2) + 2
Beaucoup d’ordres d’´ evaluation possibles!
(merci Jean-Jacques L´ evy)
Beaucoup d’ordres d’´ evaluation possibles!
(merci Jean-Jacques L´ evy)
Passage par valeur, passage par r´ ef´ erence, revisit´ es
Imposons un ordre d’´evaluation!
Ici, commen¸cons par r´eduire les sous-termes les plus profonds (sans ˆetre trop formel)
Cela revient `a ´evaluer d’abord les arguments des fonctions, avant les fonctions elles-mˆemes
C’est le passage d’arguments par valeur!
Passage par valeur: exemple
(fun x -> (x+x))(2 + 3) → (fun x -> (x+x)) 5
´
evaluation de l’argument
→ 5 + 5
→ 10
terme irr´eductible!
Passage par valeur, passage par r´ ef´ erence, revisit´ e
Imposons un ordre d’´evaluation!
Evaluons les r´edexs de l’ext´erieur vers l’int´erieur
Cela revient `a calculer ce que l’on peut d’une fonction, sans les arguments, et de n’´evaluer les arguments qu’au besoin, petit `a petit...
Revient `a un passage par r´ef´erence des arguments: on ne regarde ce qui est point´e par une r´ef´erence, qu’au besoin Passage par r´ef´erence: exemple
Y g! (on ne veut pas ´evaluer `a l’int´erieur deY, pour avoir la terminaison!)
Combinateur de point fixe pour l’appel par valeur
Peut-on quand mˆeme d´efinir un op´erateur de point fixe pour l’appel par valeur?
Oui!
Appel par valeur
Utiliser plutˆot dans ce cas le combinateurZ (dans un langage non typ´e...):
fun f -> (fun x -> f (fun v -> ((x x)v))) (fun x -> f (fun v -> ((x x)v)))
Autre exemple
Exemple: appel par nom
(fun f -> fun x -> f(f x))(fun x -> x+ 2)
fun x -> (fun x -> x+ 2)(fun x -> x+ 2) x
fun x -> (fun x -> x+ 2) (x+ 2)
fun x -> (fun x -> (x+ 2) + 2) x
fun x -> (x+ 2) + 2
Autre exemple
Exemple: appel par nom
(fun f -> fun x -> f(f x))(fun x -> x+ 2)
fun x -> (fun x -> x+ 2)(fun x -> x+ 2) x
fun x -> (fun x -> x+ 2) (x+ 2)
fun x -> (fun x -> (x+ 2) + 2) x
fun x -> (x+ 2) + 2
Autre exemple
Exemple: appel par nom
(fun f -> fun x -> f(f x))(fun x -> x+ 2)
fun x -> (fun x -> x+ 2)(fun x -> x+ 2) x
fun x -> (fun x -> x+ 2) (x+ 2)
fun x -> (fun x -> (x+ 2) + 2) x
fun x -> (x+ 2) + 2
Autre exemple
Exemple: appel par nom
(fun f -> fun x -> f(f x))(fun x -> x+ 2)
fun x -> (fun x -> x+ 2)(fun x -> x+ 2) x
fun x -> (fun x -> x+ 2) (x+ 2)
fun x -> (fun x -> (x+ 2) + 2) x
fun x -> (x+ 2) + 2
Autre exemple
Rappel: appel par valeur
(fun f -> fun x -> f(f x))(fun x -> x+ 2)
fun x -> (fun x -> x+ 2)(fun x -> x+ 2) x
fun x -> (fun x -> x+ 2) (x+ 2)
fun x -> (fun x -> (x+ 2) + 2) x
fun x -> (x+ 2) + 2
Autre exemple
Rappel: appel par valeur
(fun f -> fun x -> f(f x))(fun x -> x+ 2)
fun x -> (fun x -> x+ 2)(fun x -> x+ 2) x
fun x -> (fun x -> x+ 2) (x+ 2)
fun x -> (fun x -> (x+ 2) + 2) x
fun x -> (x+ 2) + 2
Autre exemple
Rappel: appel par valeur
(fun f -> fun x -> f(f x))(fun x -> x+ 2)
fun x -> (fun x -> x+ 2)(fun x -> x+ 2) x
fun x -> (fun x -> x+ 2) (x+ 2)
fun x -> (fun x -> (x+ 2) + 2) x
fun x -> (x+ 2) + 2
Autre exemple
Rappel: appel par valeur
(fun f -> fun x -> f(f x))(fun x -> x+ 2)
fun x -> (fun x -> x+ 2)(fun x -> x+ 2) x
fun x -> (fun x -> x+ 2) (x+ 2)
fun x -> (fun x -> (x+ 2) + 2) x
fun x -> (x+ 2) + 2
Evaluation paresseuse - Haskell
Appel par n´ecessit´e
Variante de l’appel par nom avec partage des sous-termes et des r´eductions correspondantes
Assez proche de l’appel par nom, permet aussi de d´efinir simplement des combinateurs de points fixe typeY
Est impl´ement´e dans le langage fonctionnel Haskell (pas Caml) Haskell langage cr´ee en 1987 et nomm´e en l’honneur du
logicien Haskell Curry
Plus dur `a compiler efficacement
Plus souple pour le programmeur (exemple: structures de donn´ees infinies)
Exemple: n´ ecessit´ e (merci JJL!)
N´ ecessit´ e et structures de donn´ ees infinies
Exemple: en Haskell
numsFrom n = n : numsFrom ( n+1) s q u a r e s =map (\ˆ 2 ) ( numsfrom 0 ) t a k e 5 s q u a r e s=> [ 0 , 1 , 4 , 9 , 1 6 ]
Explication
numsFrom nconstruit une liste infinie d’entiers, commen¸cant enn
square applique la fonction “carr´ee” sur la liste infinie (0,1,2, . . .)
take extrait un pr´efixe fini: c’est l’´evaluationpar n´ecessit´e de ce terme qui demande juste ce qu’il faut d’´evaluation de la liste infinie numsFrom 0
Combinateurs de point fixe en Haskell
Exemple
En Haskell, on peut programmer directement (bien que non n´ecessaire!) un combinateur de point fixe (mais pas le code de Y!), qui va terminer:
y ( f ) = f ( y f )
f a c t f n = i f ( n == 0 ) t h e n 1 e l s e n ∗ f ( n−1) y ( f a c t ) 10
. . .
Remarquez les types:
f : α→α
y : (α→α)→(α→α) fact : (int →int)→int →int
En Caml?
A priori
On ne peut pas coder le combinateurY`a cause de l’appel par valeur (et du typage, cf. plus loin dans ce cours...), mais on peut tricher un peu...
Utiliser une cloture
l e t r e c f i x f x = f ( f i x f ) x
l e t f a c t a b s f a c t =f u n c t i o n 0−>1
| x−> x ∗ f a c t ( x−1) l e t x = ( f i x f a c t a b s ) 5
Remarquez les types:
v a l f i x : ( ( ’ a−> ’ b )−> ’ a−> ’ b )−> ’ a−> ’ b =<f u n>
v a l f a c t a b s : (i n t−> i n t)−> i n t −> i n t =<f u n>
v a l x : i n t = 120
En Caml?
A priori
On ne peut pas coder le combinateurY`a cause de l’appel par valeur (et du typage, cf. plus loin dans ce cours...), mais on peut tricher un peu...
Utiliser une cloture
l e t r e c f i x f x = f ( f i x f ) x
l e t f a c t a b s f a c t =f u n c t i o n 0−>1
| x−> x ∗ f a c t ( x−1) l e t x = ( f i x f a c t a b s ) 5
Remarquez les types:
v a l f i x : ( ( ’ a−> ’ b )−> ’ a−> ’ b )−> ’ a−> ’ b =<f u n>
v a l f a c t a b s : (i n t−> i n t)−> i n t −> i n t =<f u n>
v a l x : i n t = 120
En Caml
On peut s’en sortir aussi avec des r´ef´erences, bien sˆur, et types r´ecursifs;...
t y p e ’ a r e c c = I n o f ( ’ a r e c c−> ’ a ) l e t o u t ( I n x ) = x
l e t y f = (f u n x a−> f ( o u t x x ) a ) ( I n (f u n x a−> f ( o u t x x ) a ) )
En Java?
Il faut ˆetre s´erieusement fou...
On utiliser une forme faible des clotures, en utilisant des objets JAVA (interfaces - cf. cours 4)
Pr´eliminaires...
(merci `a Ken Shirriff) c l a s s YFact {
// i n t −> i n t
i n t e r f a c e I n t F u n c { i n t a p p l y (i n t n ) ; } // ( i n t −> i n t ) −> ( i n t −> i n t )
i n t e r f a c e I n t F u n c T o I n t F u n c {
I n t F u n c a p p l y ( I n t F u n c f ) ; };
Cf. poly pour les courageux...
Le typage, qu’est-ce que c’est?
Int´erˆet
1 torchon + 2 serviettes = ? (donc doit ´eliminer des choses comme (fun x -> x) + 1 etc.)
Et finalement, pas non plusfun x -> x x ni Y! - donc un langage typ´e aura a priori un combinateur de point fixe explicite!
Choix dans les languages
On peut avoir un langage o`u on d´eclare les types et o`u il y a une v´erification minimale des types (Java etc.); ´eventuellement avec r`egles de transtypage (Java, C etc.): typage faible Ou un langage avec inf´erence de types (Caml etc.), et o`u ceux-ci (hors r´ef´erences...) assurent un bon comportement des programmes, minimal - de l’ordre de la preuve (`a la Hoare, ou presque) de certaines propri´et´es de programme
Bon typage et absence de bug
En quelque sorte...
Le typage est une preuve de coh´erence du programme, tr`es formelle!
Correspondance type et formule de logique / programme de ce type et preuve de cette formule, que l’on va voir bri`evement (isomorphisme de Curry-Howard)
Sˆuret´e du typage Th´eor`eme:
Si∅ |=t:τ alors la r´eduction det est infinie ou se termine sur une valeur (le|= est d´ecrit formellement apr`es: c’est l’inf´erence que le termet a le typeτ)
Typage monomorphe/polymorphe
Types monomorphes pour PCF
τ ::= int
| τ →τ
| τ ×τ
Types polymorphes et sch´emas de types
On veut ´eviter d’avoir par exemple une fonction identit´eN→N, de typeR→R, de type (R→R)→(R→R) etc.!:
τ ::= int | bool | . . . types de base
| τ×τ type produit
| τ →τ type d’une fonction
| α variable de type
| ∀α.τ type polymorphe
Environnements et jugements
Environnement (abstrait!)
Pour typer une expression, on a besoin de la connaissance du typage de l’environnement Env.
Au lieu d’avoir Env = Var→Val, un environnement Γ associe
`
a chaque variable x, un type Γ(x) dans notre grammaire de types
On ´ecrira souvent Γ,x:τ pour l’environnement qui vaut Γ (d´efini sur toutes les variables sauf x), et dans lequelx a le type τ
Jugement de typage
Dans l’environnement Γ, l’expression e (de PCF) a le typeτ se note:
Γ|=e :τ
R` egles de typage
Variables
Γ|=x: Γ(x) Constantes
Γ|=n :int
Op´erations arithm´etiques
Γ|=s :int Γ|=t :int Γ|=s+t :int etc.
R` egles de typage, suite
Cr´eation de fonctions
Γ,x :A|=t :B Γ|=fun x -> t:A→B
Application
Γ|=u :A Γ|=v :A→B Γ|=v u:B
R` egles de typage, suite
Affectation
Γ|=t :A Γ,x:A|=u:B Γ|=let x=t in u :B
Conditionnelle
Γ|=t :int Γ|=u:A Γ|=v :A Γ|=ifz t then u else v :A
R` egles de typage, suite et fin
Op´erateur de point fixe
Γ,x:A|=t :A Γ|=fix x t :A
Paire
Γ|=u :A Γ|=v :B Γ|= (u,v) :A×B
Exemple de typage
Terme: let f =fun x -> x+ 1 in f 2
...
x :int |= 1 :int x:int |=x+ 1 :int
∅ |=fun x -> x+ 1 :int→int
...
f :int →int |= 2 :int
∅ |=let f =
fun x -> x+ 1 in f 2 :int
Algorithme de typage
V´erification de type/inf´erence de type
On a donn´e des r`egles pour v´erifier que le typage est correct On veut maintenant trouver l’existence
Algorithmes
Algorithme de Hindley (monomorphe) et de Damas-Milner (polymorphe - `a l’origine du typage Caml):
Tout terme de Caml a un type principal (le plus g´en´eral) L’algorithme est fond´e surl’unificationde termes du premier ordre (sorte de r´esolution d’´equation dans une alg`ebre libre de termes)
Complexit´e au pire exponentielle, en pratique quasi lin´eaire L’inf´erence de types est une forme d’inf´erence de preuve (cf.
calcul des s´equents, cours 8)
Remarque (importante!): logique et typage...
On revient aux id´ees du cours 8!
Tr`es proche de la d´eduction naturelle, dans un fragment de la logique du cours 8 - en fait, pr´esentation d’un fragment intuitioniste par uncalcul de s´equents...
Oublions les termes PCF dans certaines r`egles de typages, un instant...
R` egles de typage - revisit´ ees
Cr´eation de fonctions
Γ,x :A|=t :B Γ|=fun x -> t:A→B
R` egles de typage - revisit´ ees
Cr´eation de fonctions = (⇒Id)?
Γ,A`B Γ`A→B Rappel (cours 8)
(⇒Id) Γ,A`B,∆ Γ`A⇒B,∆ (donc oui, avec ∆ =∅)
R` egles de typage, suite
Affectation
Γ|=t :A Γ,x:A|=u:B Γ|=let x=t in u :B
R` egles de typage, suite
Affectation -(cut)?
Γ`A Γ,A`B Γ`B Rappel cours 8
(cut) Γ`A,∆ Γ0,A`∆0 Γ,Γ0 `∆,∆0 Donc oui, avec ∆ =∅, Γ0 = Γ et ∆0=B
R` egles de typage, suite et fin
Paire
Γ|=u :A Γ|=v :B Γ|= (u,v) :A×B
R` egles de typage, suite et fin
Paire - (∧Id)?
Γ`A Γ`B Γ`A∧B Rappel, cours 8
(∧Id) Γ`A,∆ Γ`B,∆ Γ`A∧B,∆
Revenons aux produits: curryfication
Lien types produits/types fonctionnels
Une fonction def :X ×Y versZ peut-ˆetre consid´er´ee comme:
(i) bien sˆur une fonction qui `a un couple de valeurs (x,y), avec x ∈X ety ∈Y, renvoie f(x,y)∈Z
(ii) une fonction de X versY →Z, qui `a unx dansX associe la fonction partielle fx :Y →Z telle quefx(y) =f(x,y)
(iii) un ´el´ement deX×Y →Z (soit une fonction de () (unit) vers X ×Y →Z)
Passer de (i) `a (ii) est “naturel”
On a une fonction (d’ordre sup´erieur)
curry : ((X×Y)→Z)→(X →(Y →Z))
En Caml
Curryfication
l e t c u r r y f x y = f ( x , y ) ; ;
v a l c u r r y : ( ’ a ∗ ’ b−> ’ c )−> ’ a−> ’ b−> ’ c =<f u n>
D´e-curryfication
l e t u n c u r r y f ( x , y ) = f x y ; ;
v a l u n c u r r y : ( ’ a−> ’ b−> ’ c )−> ’ a ∗ ’ b−> ’ c =<f u n>
Exemple
l e t f ( x , y ) = x+y and g = c u r r y f ; ; v a l f : i n t ∗ i n t −> i n t =<f u n>
v a l g : i n t−> i n t−> i n t =<f u n>
l e t f 5 = g 5 ; ;
v a l f 5 : i n t−> i n t =<f u n>
l e t h x = f u n c t i o n y−> f ( x , y ) and
i = f u n c t i o n x−> f u n c t i o n y−> f ( x , y ) ; ; v a l h : i n t−> i n t−> i n t =<f u n>
v a l i : i n t−> i n t−> i n t =<f u n>
Evaluation
Autre fonction “naturelle”
eval : (X →Z)×X →Z
qui a toutx de X, et toute fonction deX →Z associe eval(f,x) =f(x) dansZ
l e t e v a l f x = f x ; ;
v a l e v a l : ( ’ a−> ’ b )−> ’ a−> ’ b =<f u n>
Similarit´ e avec la logique propositionnelle minimale...
“Proofs as programs”
Dans une logique constructive au moins:
“Programme=preuve de son type”
Caml - rappel
l e t c u r r y f x y = f ( x , y ) ; ;
v a l c u r r y : ( ’ a ∗ ’ b−> ’ c )−> ’ a−> ’ b−> ’ c =<f u n>
La fonctioncurry est une preuve de:
((a∧b) =⇒ c) =⇒ (a =⇒ (b =⇒ c))
curry en Coq
Lemma c u r r y : f o r a l l A B C : Prop , ( ( A/\B)−>C)−>A−>B−>C . P r o o f .
i n t r o s A B C . i n t r o H . i n t r o . i n t r o . a p p l y H .
s p l i t . e x a c t H0 . e x a c t H1 . Qed .
P r i n t c u r r y .
curry en Coq
c u r r y =
f u n (A B C : Prop ) (H : A/\B−>C) ( H0 : A) ( H1 : B)
=> H ( c o n j H0 H1 ) : f o r a l l A B C : Prop , (A/\B−>C)−>A−>B−>C
Autre exemple
“Application”
l e t a p p l y = u n c u r r y e v a l ; ;
v a l a p p l y : ( ’ a −> ’ b ) ∗ ’ a−> ’ b =<f u n>
La fonctionapply est une preuve du “modus ponens”:
((a =⇒ b)∧a) =⇒ b
eval en Coq
Lemma e v a l : f o r a l l A B : Prop , ( A−>B)−>A−>B . P r o o f .
i n t r o s A B . i n t r o H . i n t r o . a p p l y H . e x a c t H0 . Qed .
P r i n t e v a l .
eval en Coq
f u n (A B : Prop ) (H : A−>B) ( H0 : A)
=> H H0
: f o r a l l A B : Prop , (A−>B)−>A−>B
De fa¸ con g´ en´ erale
Correspondance de Curry-Howard
Un programme de typet est une preuve det comme suit: (en logiqueintuitioniste)
Terme logique Type informatique Implication type fonctionnel conjonction type produit
disjonction type somme
vrai type unit
faux ⊥(exception/boucle infinie) Les quantificateurs correspondent aux typesd´ependants
Exemple en Caml
Encore apply...
Supposons qu’on ait les axiomes (=”combinateurs”)eval et uncurry: on peut en d´eduire une preuve constructive dumodus ponens:
(uncurry) ((u =⇒ v) =⇒ w) =⇒ ((u∧v) =⇒ w) en faisantu = (a =⇒ b),v =a,w =b d’o`u:
(((a =⇒ b) =⇒ a) =⇒ b) =⇒ (((a =⇒ b)∧a) =⇒ b) Mais on sait par (eval):
(eval) ((a =⇒ b) =⇒ a) =⇒ b
Donc:
(uncurry eval) ((a =⇒ b)∧a) =⇒ b
Preuve correspondant `a l’ex´ecution de la composition des fonctions uncurryet eval:
u n c u r r y e v a l ; ;
−: ( ’ a−> ’ b ) ∗ ’ a−> ’ b =<f u n>
Pour aller plus loin
R´ealisabilit´e, syst`emes de types d´ependants etc.
G´en´eralisation de la correspondance de Curry-Howard `a la logique classique (call-with-current-continuation,
transformationcontinuation passing style)
Certains “grands” th´eor`emes ont ´et´e interpr´et´es comme des programmes (ex. th´eor`emes de compl´etude et d’incompl´etude de G¨odel, forcing de Cohen etc. - par Jean-Louis Krivine) Lien topologie alg´ebrique et certains syst`emes de types: cf.
Vladimir Voevodsky (m´edaille Fields 2002)
C’est tout pour aujourd’hui...
La prochaine fois
Les langages synchrones, r´eseaux de Kahn LUSTRE et la programmation r´eactive Quelques conseils avant les vacances Bon TD!
C’est tout pour aujourd’hui...
La prochaine fois
Les langages synchrones, r´eseaux de Kahn LUSTRE et la programmation r´eactive Quelques conseils avant les vacances Bon TD!