Principes des lang. de progr. INE 11 Michel Mauny Inria-Paris pré[email protected] Michel Mauny (Inria-Paris) INE 11 pré[email protected] 1 / 31 pré[email protected] 2 / 31 Le lambda-calcul 1 Termes du λ-calcul 2 Propriétés 3 Programmer en λ-calcul 4 Stratégies d’évaluation Stratégies internes/externes Réduction faible Stratégie externe gauche, standardisation Michel Mauny (Inria-Paris) INE 11 Le λ-calcul Système formel basé sur les fonctions Alonzo Church, 193x problème de décision – de validité de formules logiques – ⇒ fonctions calculables Alan Turing : machines ⇒ fonctions calculables λ-calcul ≈ machines de Turing Utilité fondement des langages de programmation (bloc, fonction/procédure) fondement des langages fonctionnels sémantique dénotationnelle systèmes de spécification et de preuves de programmes Michel Mauny (Inria-Paris) INE 11 pré[email protected] 1 3 / 31 Termes Grammaire Les termes du λ-calcul, aussi appelés λ-termes, sont donnés par la grammaire suivante : identificateurs applications abstractions (e est le corps la portée de x) M, e ::= x | ee | λx.e Lire «λx.e» comme «fun x → e» Syntaxe concrète l’application «associe à gauche» : e1 e2 e3 ≡ (e1 e2 )e3 l’abstraction «porte» aussi loin que possible : λx.λy .λz.xzyz ≡ λx.(λy .(λz.xzyz)) Michel Mauny (Inria-Paris) INE 11 pré[email protected] 4 / 31 Variables, occurrences Occurrences de variables Occurrences liantes : là où on introduit une variable (λ) Occurrences liées : se rapportant à une occurrence liante Occurrences libres : pas d’occurrence liante correspondante freeVars(x) = {x} freeVars(e1 e2 ) = freeVars(e1 ) ∪ freeVars(e2 ) freeVars(λx.e) = freeVars(e) − {x} Exemple : (les occurrences rouges sont libres) Michel Mauny (Inria-Paris) INE 11 pré[email protected] 5 / 31 Substitution La substitution d’un terme M à une variable x dans le terme e, notée [M/x]e, est définie comme le terme résultant du remplacement de toutes les occurrences libres de x par M dans e : [M/x]x [M/x]y [M/x](e1 e2 ) [M/x](λx.e) [M/x](λy .e) [M/x](λy .e) Michel Mauny (Inria-Paris) = = = = = = M y , pour y 6= x ([M/x]e1 )([M/x]e2 ) (λx.e) λy .[M/x]e pour x 6= y et y 6∈ freeVars(M) λz.[M/x]([z/y ]e) pour z 6∈ freeVars(e) ∪ freeVars(M) et z 6= x et y 6= x INE 11 pré[email protected] 2 6 / 31 Équivalences, réductions α-équivalence le nom des variables liées (les variables muettes) importe peu on peut les renommer à volonté, mais de façon cohérente α-équivalence (ou α-conversion) (α) λx.e ← → λy .[y /x]e, pour y n’apparaissant ni libre, ni liée dans e relation d’équivalence passage au contexte Les λ-termes sont (presque toujours) considérés modulo α-équivalence Michel Mauny (Inria-Paris) INE 11 pré[email protected] 7 / 31 Équivalences, réductions β-équivalence passage d’argument à une fonction de paramètre formel x β-équivalence (ou β-conversion) (β) (λx.e)M ← → [M/x]e sens → : avancer dans le calcul sens ← : factoriser M La règle importante du λ-calcul Michel Mauny (Inria-Paris) INE 11 pré[email protected] 8 / 31 Équivalences, réductions η-équivalence egalité entre f et x 7→ f (x) η-équivalence (ou η-conversion) (η) λx.ex ← → e, si x 6∈ freeVars(e) en OCaml : changer fact en (fun n → fact(n)) changer e : () en (fun () → e()) pour évaluer e à chaque application Michel Mauny (Inria-Paris) INE 11 pré[email protected] 3 9 / 31 Notations Utilisation des conversions (équivalence, réduction) «candidat à réduction» appelé radical passage au contexte : réduire des sous-termes quelconques fermeture transitive : chaînes de conversions Notation M =α N ∗ M← →N ∗ M →β,α N Vocabulaire terme irréductible / normalisé / en forme normale Michel Mauny (Inria-Paris) INE 11 pré[email protected] 10 / 31 pré[email protected] 11 / 31 Questions Utiliser la règle β pour réduire (calculer) choisir un (sous-terme) radical le réduire ⇒ nouveau terme recommencer Questions comment choisir le prochain radical (stratégie) ? cela termine-t-il toujours ? le résultat final dépend-il de ce choix ? Michel Mauny (Inria-Paris) INE 11 Terminaison Cela termine-t-il toujours ? Non ! la réduction de (λx.xx)(λx.xx) ne termine pas pas étonnant (expressivité théorique) Définitions Normalisation forte e est dit fortement normalisant si toutes les réductions partant de e sont finies. Normalisation faible e est dit faiblement normalisant si ∃ une réduction finie de e menant à un terme irréductible. (λx.λy .y )((λx.xx)(λx.xx)) est faiblement normalisant Michel Mauny (Inria-Paris) INE 11 pré[email protected] 4 12 / 31 Confluence Théorème ∗ ∗ ∗ ∗ Si M →β N et M →β P, alors ∃ Q tel que N →β Q et P →β Q M * * N Corollaire Les formes normales, quand elles existent, sont uniques P * * Q Michel Mauny (Inria-Paris) INE 11 pré[email protected] 13 / 31 pré[email protected] 14 / 31 pré[email protected] 15 / 31 Programmer en λ-calcul Booléens True ≡ λx.λy .x False ≡ λx.λy .y If ≡ λa.λb.λc.a b c On a : If True B C If False B C ∗ →β ∗ →β B C Paires/Listes Pair ≡ λa.λb.λp.p a b First ≡ λa.a True Rest ≡ λa.a False On a : First (Pair A B) Rest (Pair A B) Michel Mauny (Inria-Paris) ∗ →β →β A B ∗ INE 11 Programmer en λ-calcul Liste vide Nil ≡ λx.True Cons ≡ Pair Null ≡ λa.a (λx.λy .False) ∗ On a : Null Nil → True ∗ Null (Cons A B) → Nombres Zero One Two Three ... Succ Michel Mauny (Inria-Paris) ≡ ≡ ≡ ≡ False λf .λx.x λf .λx.f x λf .λx.f (f x) λf .λx.f (f (f x)) ≡ λn.λf .λx.f ((n f ) x) INE 11 5 Programmer en λ-calcul Nombres (suite) IsZero ≡ λn.n (λx.False) True Plus ≡ λm.λn.(m Succ) n Mult ≡ λm.λn.λf .m (n f ) Power ≡ λm.λn.(n (Mult m)) (Succ Zero) Michel Mauny (Inria-Paris) INE 11 pré[email protected] 16 / 31 Points fixes Un point fixe d’une fonction f est un élément a tel que : a = f (a) Dans le λ-calcul, un point fixe d’un terme f est un terme e tel que : e← →f e Un opérateur (combinateur) de point fixe est un terme Fix tel que : Fix M ← → M (Fix M) Fix M est donc un point fixe de M Michel Mauny (Inria-Paris) INE 11 pré[email protected] 17 / 31 Points fixes et récursion Dans le λ-calcul les opérateurs de point fixe sont définissables : Y ≡ λf .(λx.f (xx))(λx.f (xx)) En effet YM ← → (λx.M(xx))(λx.M(xx)) ← → M((λx.M(xx))(λx.M(xx))) ← → M(YM) Construction d’une fonction récursive f = ...f ... plus petit point fixe d’une fonctionnelle (λf . ...f ...) «plus petit» = «le moins défini», au sens des CPO Michel Mauny (Inria-Paris) INE 11 pré[email protected] 6 18 / 31 Récursion Exemple : factorielle let rec fact n = if n = 0 then 1 else n ∗ fact(n−1) Fonctionnelle correspondante : let ffact fact = fun n → if n = 0 then 1 else n ∗ fact(n−1) On a : (Fix ffact) 3 ← →Fix (ffact (Fix ffact)) 3 ← →β (fun n → if n=0 then 1 else n ∗ (Fix ffact)(n−1)) 3 ← →β,δ if 3=0 then 1 else 3 ∗ (Fix ffact)(3−1) ← →δ 3 ∗ (Fix ffact) 2 ← → ... Michel Mauny (Inria-Paris) INE 11 pré[email protected] 19 / 31 Stratégies Le choix du prochain radical à réduire n’influe pas sur la valeur (confluence) influe sur la terminaison externes Stratégie = choix systématique internes radical interne ou externe à gauche ou à droite Michel Mauny (Inria-Paris) INE 11 pré[email protected] 20 / 31 Stratégies internes Choisir le prochain radical le plus à l’intérieur dans le terme évaluer les arguments de fonction avant de les substituer aux paramètres formels (λx.(λy .y ))((λx.xx)(λx.xx)) Gauche, droite correspond à l’ordre d’évaluation des arguments (λx.λy .e)e1 e2 peu important (mais attention aux effets de bord !) Michel Mauny (Inria-Paris) INE 11 pré[email protected] 7 21 / 31 Stratégies extermes Choisir le prochain radical le plus à l’extérieur dans le terme substituer les arguments de fonction aux paramètres formels sans les évaluer (λx.(λy .y ))((λx.xx)(λx.xx)) Gauche, droite choix de la fonction ou de l’argument ((λx.e1 )M) ((λy .e2 )N) on s’intéresse essentiellement à la stratégie externe gauche (leftmost-outermost) Michel Mauny (Inria-Paris) INE 11 pré[email protected] 22 / 31 pré[email protected] 23 / 31 Spécifier une stratégie Quelle est la forme des termes irréductibles ? notion de valeur, notées ici v , v1 , etc. Quelle(s) règle(s) de réduction ? ici, β-réduction Contextes d’application ? arbitraires ? argument déjà évalué ? etc. Michel Mauny (Inria-Paris) INE 11 Réduction faible Réduction faible s’interdire de réduire le corps des abstractions exécution de programmes contraire : réduction forte Valeurs v ::= xv1 . . . vn | λx.e avec n ≥ 0 Appel par valeur des langages de programmation évaluer les arguments avant de les passer à la fonction on évalue des termes clos (pas de valeur de la forme (xv1 . . . vn )) ordre d’évaluation des arguments pas nécessairement spécifié Michel Mauny (Inria-Paris) INE 11 pré[email protected] 8 24 / 31 Stratégie interne, réduction faible Valeurs v ::= xv1 . . . vn | λx.e avec n ≥ 0 Règle de réduction (λx.e)v → e[v /x] Contextes de réduction e1 → e10 e1 e2 → e2 → e20 (Fun) e10 e2 Michel Mauny (Inria-Paris) e1 e2 → e1 e20 INE 11 (Arg ) pré[email protected] 25 / 31 Réduction faible et langages de programmation Appel par valeur gauche d’abord (SML, . . . ) droite d’abord non-spécifié (OCaml, C, . . . ) Fonctions, constructions syntaxiques évaluation des arguments systématique et partagée entre les différentes occurrences pas de substitution explicite, mais environnements conditionnelle : pas une fonction encodage de la récursion avec Z = λf .((λx.f (λy .(xx)y ))(λx.f (λy .(xx)y ))) Michel Mauny (Inria-Paris) INE 11 pré[email protected] 26 / 31 Stratégie externe gauche : standardisation Réduire le radical le + externe, le + à gauche ne réduire que les radicaux nécessaires (pas de calcul inutile) risque de dupliquer le calcul des arguments Conduit à la forme normale si elle existe Theorème de standardisation Si le terme e est faiblement normalisant, alors la stratégie externe gauche trouvera sa forme normale en un nombre fini d’étapes Michel Mauny (Inria-Paris) INE 11 pré[email protected] 9 27 / 31 Stratégie externe gauche et réduction faible Valeurs (formes normales de tête) avec n ≥ 0 v ::= xe1 . . . en | λx.e Règle de réduction (λx.e1 )e2 → e1 [e2 /x] Contexte de réduction e1 → e10 e1 e2 → e10 e2 Michel Mauny (Inria-Paris) (Fun) INE 11 pré[email protected] 28 / 31 Appel par nom, évaluation paresseuse Externe + gauche + faible pas de calcul inutile, mais . . . . . . évaluations multiples d’arguments appel par nom Remède : évaluation paresseuse arguments évalués si et lorsque nécessaire partager leur évaluation entre différentes occurrences du paramètre formel ∗ première évaluation x → 5 ultérieurement : 5 sans calcul langage Haskell Michel Mauny (Inria-Paris) INE 11 pré[email protected] 29 / 31 Évaluation paresseuse Évaluation paresseuse en OCaml structure de donnée «paresseuse» mot-clé lazy module Lazy : sig type α t exception Undefined val force : α t → α [...] end Michel Mauny (Inria-Paris) # let x = lazy (printf "Hello\n%!");; val x : unit Lazy.t = <lazy> # Lazy.force x ;; Hello − : unit = () # Lazy.force x ;; − : unit = () INE 11 pré[email protected] 10 30 / 31 Conclusion λ-calcul : théorie du calcul et de la fonctionnalité support d’expression et d’étude de sémantiques, de modes d’exécution, d’analyses de programmes, de compilation doté de systèmes de types, il devient formalisme logique Michel Mauny (Inria-Paris) INE 11 pré[email protected] 11 31 / 31