2014-09-04 IFT359 – Programmation fonctionnelle Thème #1 Introduction à la programmation fonctionnelle, le λ-calcul 1 LES STYLES DE PROGRAMMATION LA PROGRAMMATION FONCTIONNELLE 2 La programmation fonctionnelle Un aperçu Les styles de programmation • Programmation impérative • Utilise sous sa forme stricte que deux formes syntaxiques – programmation structurée • • • • – fonction – application de fonction Programmation logique Programmation objet Programmation fonctionnelle Ne pas confondre style de programmation et langage de programmation. • Les fonctions sont des objets de première classe • La récursion est la principale structure de contrôle • Une grande attention est portée aux listes – sous une forme stricte, les listes sont définies comme une fonction – la récursion sur les sous-listes remplace les boucles – Il est possible de faire de la programmation fonctionnelle en C et inversement de faire de la programmation impérative en DrRacket. Les langages sont conçus pour favoriser un style de programmation. • Plusieurs langages fonctionnelles déconseillent l’utilisation de – l’affectation – les effets de bord • Dans ce cours, vous apprenez la programmation fonctionnelle – Apprendre à programmer avec DrRacket est le moyen préconisé pour atteindre ce but 3 • Un programme n’est pas une séquence d’instructions mais une expression à évaluer et des définitions de fonctions 4 1 2014-09-04 Les langages multiparadigmes • Plusieurs langages modernes ont intégré des concepts propres aux langages fonctionnels. – – – – – ramasse-miette λ fermeture macro immutabilité • Plusieurs langages fonctionnels intègrent les concepts de la programmation objet et de la programmation logique. LE λ-CALCUL LE PLUS SIMPLE LANGAGE DE PROGRAMMATION – Une version primitive des objets existait dans les premières versions de LISP 5 6 Le λ-calcul : introduction Le λ-calcul : syntaxe Soit (pour cette diapositive et les suivantes) • Conçu par Alonzo Church en 1941 • Fondation formelle de la programmation fonctionnelle • Le λ-calcul est à la programmation fonctionnelle ce que la machine de Turing est aux langages comme C, C++, Java • Le plus simple langage de programmation – a, b, c …des constantes, – u, v, w … des variables, – U, V, W … des λ-termes ( variable, constante, abstraction, application) • Les variables et les constantes sont des ensembles disjoints d’identificateurs • abstraction = λ(x)V – Syntaxe minimal • λ-termes = variable | abstraction | application [| constante] – elle est interprétée comme une fonction qui associe à x l’expression V (qui contient généralement des occurrences de x) – x est une variable liée dont la portée est V – une variable liée peut être renommée sans conséquence – une variable non liée est dite libre – Les constantes ne sont pas nécessaires, elles symbolisent des fonctions connues et permettent de simplifier les calculs – Une abstraction est une fonction – Exécution d’un programme • est une séquence de réduction • U V est un λ-terme nommé application 7 8 – dans le cas où U est une abstraction, une application est interprétée comme l’application d’une fonction U à un argument V 2 2014-09-04 Le λ-calcul : syntaxe • • Le λ-calcul : syntaxe La portée d’une variable liée par une λ s’étend le plus loin à droite La portée est statique, la valeur de la liaison est la même pour toute la portée • • Dans la littérature, la syntaxe traditionnelle utilise le . pour séparer les variables d’une abstraction de son corps. – – Attention λ(x)x Y (λ(x)U x V) x = λ(x1)x1 Y (λ(x2) U x2 V) x1 • Les λ s’associe à droite U . U . . . – λ(x)λ(y)U = λ(x)(λ(y)U). – On supprime les () et les λ intermédiaires dans des abstractions qui se suivent • λ(x)λ(y)U = λ(xy)U • Les applications s’associe à gauche – X1 X2 ... Xn = ((X1 X2) ... Xn) • x2 est l’argument de la fonction x1 et le résultat ultime de l’application de x1 à x2 est une fonction dont l’argument est x3 … – Les applications ont précédence sur les abstractions • λ(x) X Y Z = λ(x)(X Y) Z = (λ(x)((X Y) Z)) 9 10 Le λ-calcul : syntaxe λ-calcul : Exemple de λ-termes Pour simplifier, on considère que +, 2 et 3 sont des λ-termes • pour simplifier l’écriture, on écrira souvent – – – – – • La fonction f: x ↦ x+2 sera dénotée (λ (x)(+ x 2)) • L'application de f à 3 s'écrit ((λ (x) (+ x 2))3) • L’évaluation de ((λ (x) (+ x 2))3) est (+ 3 2) = ((+ 3) 2). U V plutôt que (U V) U V W plutôt que ((U V) W) … (λ (x1 x2) U) a1 a2 plutôt que (((λ (x1) (λ (x2) U)) a1) a2) … – Le reste dépend des fonctions qui sont représentées par + 3 2 • La fonction identité f: x ↦ x est (λ (x) x) • La fonction constante f: x ↦ 2 est (λ (x) 2) • Par contre, nous distinguerons entre U et (U) – Si U = x y z alors (U) est (((x y) z)) et non pas ((x y) z) i.e. x y z est une abréviation de ((x y) z) • La constante est une fonction qui retourne une fonction – L’application 2 s’évalue comme étant 2 – La notion d’évaluation d’une application sera définie formellement dans les diapositives qui suivent et sera appelée la β-réduction 11 12 3 2014-09-04 Le λ-calcul : variable liée et libre Le λ-calcul : un programme • Variables liées • Un programme est un λ-terme. Pour simplifier l’écriture, on crée souvent plusieurs définitions • L’exécution d’un programme est une séquence de réduction – Varlié(a) = {} • si on ne donne pas la définition de a, on fait abstraction des variables que sa définition peut contenir. – X Y signifie que X a été réduit à Y – l’exécution s’arrête lorsqu’il n’y a plus d’applications qui peuvent être réduites (aucune substitution non triviale peut être appliquée). – le λ-terme résultant est dit dans la forme normale de X – Varlié(x) = {} – Varlié(XY)= Varlié(X) U Varlié(Y) – Varlié ((λ (x) X)= Varlié(X) U {x} • Variables libres • L’opération primitive permettant la réduction est la substitution – une variable non liée est dite libre – On dit alors souvent évaluation par substitution – Comme on fait avec un éditeur des copy-paste pour effectuer une substitution, alors j’associe souvent la substitution au copy-paste. – Vous serez étonné de la puissance de calcul du copy-paste. • Dans l'expression ((λ (x) x) x), il y a 2 occurences de x mais ce sont deux variables différentes 13 – il faut lire ((λ (x1) x1) x) – x1 est liée – x est libre 14 Le λ-calcul : α-conversion Le λ-calcul : substitution • α-conversion • Substitution notée T[x := U] – deux λ-termes sont équivalents s’il est possible de les rendre identiques après avoir renommer les variables liées dans une expression par une autre qui n’est pas libre dans cette expression – si y n’est pas libre dans M alors λ(x)M α λ(y)M et λ(x)M α λ(y)M – on renomme que les variables x qui sont liés par un λ – Exemple – la substitution dans T de la variable x par U et se définit par récurrence sur T : 1. si T est une constante alors T[x := U]=T 2. si T=x alors T[x := U]=U 3. si T≠x et T est une variable alors T[x := U]=T 4. si T = V W alors T[x := U] = V[x := U] W[x := U] 5. si T = λ(y)V et y≠x et y est non libre dans U alors T[x := U] = λ(y)(V[x := U]) 6. si T = λ(y)V et y≠x et y est libre dans U alors T[x := U] = λ(z)((V[y:=z])[x := U]) 7. si T = λ(y)V et x=y alors T[x := U] = T • #6 consiste à utiliser l’ α-conversion avant d’appliquer 5. L’ α-conversion est nécessaire parce que le résultat d’une substitution ne doit pas entrainer de confusion entre deux variables qui portent le même nom. Cette confusion entraîne la capture d’une variable libre y dans U par le λ(y) • (λ(x)((λ(y)y) x)) α (λ(y)((λ(y)y) y)) est correcte parce que y n’est pas libre dans ((λ(y)y) x). Plus précisément en dépit du même nom, nous avons deux variables y différentes. • inutile cependant de jouer avec le feux • La substitution est l’opération d’évaluation primitive 15 16 4 2014-09-04 Le λ-calcul : substitution Le λ-calcul : substitution • Exemple du cas 5 : y est non libre dans U • Exemple du cas 6 : y est libre dans U – T ==λ(y)V – U == λ(y)xyz – V == azyx – – – – • on suppose ici que le z de U et le z de V est la même variable; i.e. on suppose que celui qui a composé la question ou le problème n'avait pas l'intention de se tirer dans le pied. – T[x := U] == λ(y)V[x:=U] == (λ(y) azyx)[x:=U] == (λ(y) azyx [x:=U]) ;;; application de 5 == λ(y)a[x:=U] z[x:=U] y[x:=U] x[x:=U] ;;; application de 4 == λ(y)a z y λ(y)xyz ;;; application de 1,2,3 17 T==λ(y)V U == xyz V == azyx T[x := U] == (λ(y) V) [x := U] == λ(w)((V[y:=w])[x:U]) ;;; -conversion == λ(w)((azyx [y:=w])[x:U]) == λ(w)((a[y:=w] z[y:=w] y[y:=w] x [y:=w])[x:U]) ;;;application 4 == λ(w)(azwx [x:=U]) ;;; application de 1,2,3 == λ(w)a[x:=U] z[x:=U] w[x:=U] x[x:=U] ;;; application 5 puis 4 == λ(w)a z w xyz ;;; application de 1,2,3 18 Le λ-calcul : substitution Le λ-calcul : β-conversion • exemple du cas 6 : y == x i.e. la variable à substituer est la variable de l’abstraction – – – – – • β-réduction – ne s’applique qu’aux expressions réductibles que l’on nomme rédex et qui ont toujours la forme (λ(x)M) N – (λ(x)M) N β M[x :=N] – Exemple T==λ(y)V U == xyz V == azyx T[y := U] == (λ(y)azyx)[y:=U] {ne pas confondre avec λ(y)(azyx)[y:=U] * == (λ(y)azyx) • (λ(x)xy)a β (xy)[x := a] = ay • ((λ(x)x x)(λ(y)y)) β(x x) [x := (λ(y)y)) ] =(λ(y)y) (λ(y)y) βy [y := (λ(y)y))]=λ(y) y • ((λ(x)(λy(x) y))y) α ((λ(x)(λ(y1)x y1))y) β(λ(y1)x y1) [x:=y] = (λ(y1)y y1) • Remarque dans ((λ(x)(λ(y)x y))y) le y de (λ(y)x y) est lié alors que celui à l’extérieur est libre, ce n’est donc pas la même variable bien que leurs noms soient identiques. Le renommage est nécessaire pour éviter la capture après la β-réduction. Nous avons implicitement utilisé le cas 6 de la réduction. * la substition s’applique au tout vs la sustitution s’applique à azyx • β-abstraction – M[x :=N] β (λ(x)M) N 19 20 5 2014-09-04 Le λ-calcul : η-conversion Le λ-calcul : η-conversion • η-réduction • λ(y)(λ(x)yx) et λ(y) y sont des fonctions équivalentes par ηreduction. – (λ(x)Mx) M – λ(y)(λ(x)yx) ↔ à λ(y)y puisque λ(x)yx ↔ η y • ne pas confondre avec (λ(x)M)x – utile pour éliminer les abstractions dont la seule utilité est de passer ses arguments à une autre expression – utilisé dans la construction des compilateurs • Si on avait pas l'η-conversion, la réduction ne peut se faire avant les utilisations particulières ((λ(y) y) M) N – ((λ(y)(λ(x)yx)) M) N MN – (λ(x)Mx) N – MN Comme M et N sont des λ-termes quelconques, nous avons montré que les deux fonctions donnent toujours le même résultat, elles sont donc équivalentes. • η-abstraction – M (λ(x)Mx) – utile dans les langages par appel (les arguments sont évalués en premier) pour empêcher l’évaluation d’une expression (i.e. M dans l’exemple) • Ne sera pas utilisé par la suite et n’est pas matière à examen • Ne sera pas utilisé par la suite et n’est pas matière à examen 21 22 Ordre d’évaluation Ordre normal d’évaluation • Ordre d’évaluation = ordre de réduction • L’ordre souvent proposé est l’ordre normal – on réduit en commençant par les applications les plus hautes et les plus à gauche – garantit de trouver la forme normale mais pas le chemin le plus court • U V W Dans quel ordre faut-il réduire ? • Nous savons que U V W = ((U V) W) mais faut-il réduire U V ou W en premier ? • Un théorème nous assure que tous les ordre de réduction qui se terminent mènent à un forme normale équivalente • Exemple : évaluation de (U V W) = (U V) W 1. évaluation en ordre normal de (U V) X1 1. si U est une application alors on effectue l’application jusqu’au moment où on obtient une abstraction X2 U X2 2. évaluation en ordre normal de (X2 V) X3 – il est possible qu’après l’application de X2 à V que V n’apparaisse plus 3. Si X3 est une application alors on effectue l’application jusqu’au moment où on obtient une abstraction X1 X3 X1 23 24 2. évaluation en ordre normal de (X1 W) X4 3. Si X4 est une application, on effectue l’application jusqu’au moment où on obtient une abstraction X4 X5 4. On évalue, en ordre normal, le corps de l’abstraction X5 6 2014-09-04 Ordre applicatif d’évaluation • Ordre d’évaluation : Exercice L’ordre applicatif est la forme d’évaluation de DrRacket • ((λ(x)x) (λ(x)y))((λ(x)xx) (λ(x)xx)) à faire en ordre normal et en ordre applicatif – on réduit en commençant par les arguments les plus à droite, et ce récursivement jusqu’au moment où tous les arguments sont en forme normale et ensuite on effectue l’application du premier argument en prenant comme paramètres le reste des arguments • en pratique on peut évaluer les arguments dans n’importe quel ordre l’important est d’évaluer avant d’appliquer • si on élimine les abréviations syntaxiques, il n’y a qu’un argument. – peut ne jamais se terminer mais si elle se termine alors c’est le chemin le plus court – évaluation de (U V W) = (U V) W 1. réduction de W X1 1. Si W est une application on l’évalue en ordre applicatif 2. Si W est une abstraction, on évalue en ordre applicatif son corps i.e. les applications les plus hautes sont toujours faites en dernier 2. réduction de (U V) X2 1. 2. 3. 25 3. réduction de V X3 réduction de U X4 réduction de (X3 X4) X2 réduction de (X2 X1) 26 Ordre d’évaluation : Exercice λ-calcul : la logique • ((λ(x)x) (λ(x)y))((λ(x)xx) (λ(x)xx)) à faire en ordre normal et en ordre applicatif • Quelques définitions • • • • • • • • – ordre normal • ((λ(x)x) (λ(x)y))((λ(x)xx) (λ(x)xx)) • ((λ(x)x) (λ(x)y))((λ(x)xx) (λ(x)xx)) • ((λ(x)x) (λ(x)y))((λ(x)xx) (λ(x)xx)) – ((λ(x)x) (λ(x)y)) →ᵦ x [x:=(λ(x)y)] → (λ(x)y) • (λ(x)y)((λ(x)xx) (λ(x)xx)) – (λ(x)y)((λ(x)xx) (λ(x)xx)) →ᵦ y [x:= ((λ(x)xx) (λ(x)xx))] → y V ≡ λ(ab)a F ≡ λ(ab)b IF ≡ λ(buv)(b u v) ≡ λ(xy)xy(λ(uv)v) = λ(xy)xyF ≡ λ(xy)x(λ(uv)u)y = λ(xy)xVy ¬ ≡ λ(x)(x(λ(uv)v)(λ(ab)a))= λ(x)xFV 2≡… 4≡… • y – Ordre applicatif • • • • – Expression à évaluer (IF V 2 4) – L’expression initiale pourrait être plus complexe mais on suppose qu’après une série de réduction nous obtenons (IF V 2 4) ((λ(x)x) (λ(x)y)) ((λ(x)xx) (λ(x)xx)) ((λ(x)x) (λ(x)y))((λ(x)xx) (λ(x)xx)) ((λ(x)x) (λ(x)y)) ((λ(x)xx) (λ(x)xx)) ((λ(x)x) (λ(x)y))((λ(x)xx) (λ(x)xx)) • Réduction à la prochaine diapositive – ((λ(x)xx) (λ(x)xx)) →ᵦ xx [x:=(λ(x)xx)] → (λ(x)xx) (λ(x)xx) 27 • ((λ(x)x) (λ(x)y))((λ(x)xx) (λ(x)xx)) 28 7 2014-09-04 Évaluation IF vrai 2 4 • • • • • • • • • • • (λ(buv)(b u v)) V 2 4 ((((λ(buv)(b u v)) V) 2) 4) ((((λ(b)(λ(u)(λ(v)(b u v)))) V) 2) 4) (((λ(u)(λ(v)(V u v))) 2) 4) ((λ(v)(V 2 v)) 4) (V 2 4) ((V 2) 4) (((λ(ab)a) 2) 4) (((λ(a)(λ(b)a)) 2) 4) ((λ(b)2) 4) 2 Exercice F ≡ λ(ab)b e e beta-reduction + substitution beta-reduction + substitution beta-reduction + substitution e définition de V e beta-reduction + substitution beta-reduction + substitution • Effectuer la réduction de (F X) où X est un λ-terme quelconque Que constatez-vous ? remarquez comment V retourne son premier argument en combinant la fonction constante e ≡ élimination des abréviations syntaxiques i ≡ introduction des abréviations syntaxiques 29 30 Exercice Arithmétique en λ-calcul • effectuer la réduction de (F X) où X est un λ-terme quelconque Que constatez-vous ? • Définition des naturels • • • • • (F X) ((λ(ab)b) X) ((λ(a) (λ(b) b) ) X) (λ(b)b) 0 ≡ λ(sz)z 1 ≡ λ(sz)sz 2 ≡ λ(sz)s(sz) 3 ≡ λ(sz)s(s(sz)) … – on peut donner un sens en interprétant z comme 0 et s comme suivant. • Définition de la fonction successeur • S ≡ λ(wyx)y(wyx) – F appliquer à n’importe quel argument retourne la fonction identité – Et si on ajoute un 2e argument alors il le retournera. 31 – Exemple • S 0 ≡ (λ(wyx)y(wyx)) (λ(sz)z) • voir réduction sur la prochaine diapositive 32 8 2014-09-04 réduction de S 0 • • • • • • • • • • • réduction de S 0 (λ(wyx) y(wyx)) (λ(sz)z) ((λ (w y x) (y (w y x))) (λ (s z) z)) ((λ (w) (λ (y) (λ (x) (y ((w y)x))))) (λ (s z) z)) (λ (y) (λ (x) (y (((λ (s z) z) y) x)))) (λ (y) (λ (x) (y (((λ (s) (λ (z) z)) y) x)))) (λ (y) (λ (x) (y ((λ (z) z)x)))) (λ (y) (λ (x) (y x))) (λ (y x) (y x)) (λ (s x) (s x)) (λ (s z) (s z)) λ(sz)sz 33 • • • • • • • • Version abrégée (attention de ne pas vous trompez) (λ(wyx) y(wyx)) (λ(sz)z) (λ(yx) y((λ(sz)z) yx)) (λ(yx) y((λ(sz)z) yx)) (λ(yx) y(((λ(sz)z) y)x)) (λ(yx) y((λ(z)z)x)) (λ(yx) y x) (λ(sz) sz) 34 réduction de S 1 réduction de S 1 • (λ(wyx) y(wyx)) λ(sz)sz Faites la réduction en exercice • (λ(wyx) y(wyx)) λ(sz)sz Faites la réduction en exercice (λ(wyx)y(wyx)) λ(sz)sz (λ(w)(λ(y)(λ(x)(y(wyx))))) (λ(s)(λ(z)sz)) (λ(y)(λ(x)(y(((λ(s)(λ(z)sz))y)x)))) (λ(y)(λ(x)(y((λ(z)yz)x)))) (λ(y)(λ(x)(y(yx)))) (λ(s)(λ(z)(s(sz)))) Les 2 versions sont identiques. Il n’y a que les espaces qui changent. (λ(w y x) y(w y x)) (λ(s z) s z) (λ(w) (λ(y) (λ(x) (y(w y x))))) (λ(s) (λ(z) s z)) (λ(y) (λ(x) (y(((λ(s) (λ(z) s z))y)x)))) (λ(y) (λ(x) (y((λ(z) y z)x)))) (λ(y) (λ(x) (y(y x)))) (λ(s) (λ(z) (s(s z)))) (λ(s z) s(s z)) 35 36 9 2014-09-04 réduction de (S 1) et de (S 2) Exercice • (S 1) = (λ(wyx)y(wyx)) λ(sz)sz version abrégée (λ(w (λ(y (λ(y (λ(s • Effectuer la réduction de a) 0 M a y x) y(w y x)) (λ(s z) (s z)) x) y((λ(s z) (s z)) y x)) pourquoi les () sont-elles importantes ? x) y(y x)) z) s(s z)) b) 1 M a c) 2 M a • Comment peut-on se servir du résultat pour définir l’addition ? • (S 2) = (λ(wyx)y(wyx)) λ(sz)s(sz) Faites la réduction en exercice (λ(w (λ(y (λ(y (λ(y (λ(s y x) y(w y x)) (λ(s z) s (s z)) x) y((λ(s z) s (s z)) y x)) x) y((λ(s z) (s (s z))) y x)) x) y(y(y x))) z) s(s(s z))) 37 38 Exercice • Effectuer la réduction de a) 0 M a b) 1 M a addition arithmétique c) 2 M a • L’addition découle de la définition de successeur et des entiers • Remarquez la réduction de 2 S – (λ(sz)s(sz)) S – (λ(s)(λ(z)(s(sz))))S – (λ(z)(S(Sz))) réduction de 0 M a réduction de 1 M a réduction de 2 M a (λ(sz)z) M a (λ(sz)sz) M a (λ(sz)s(sz)) M a ((λ(s)(λ(z)z)) M) a ((λ(s)(λ(z)sz)) M) a ((λ(s)(λ(z)s(sz))) M) a (λ(z)z) a (λ(z)Mz) a (λ(z)M(Mz)) a a Ma M(Ma) • C’est une fonction qui applique S deux fois à son argument z • Remarquez maintenant la réduction de 2 S 3 – (2 S) 3 – (λ(z)(S(Sz))) 3 – (S(S (λ(sz)s(s(s(z)))) … – (λ(sz)(s(s(s(s(s(z))))))) – 5 • Comment peut-on se servir du résultat pour définir l’addition ? Que se passe-t-il si M est la fonction successeur et si a est un entier ? • + ≡ λ(xy)xSy 39 40 L’abstraction S est la fonction successeur. (S 3) donne 4 et (S 4) donne 5 comparer l’évaluation en ordre normal et en ordre applicatif pour les étapes manquantes 10 2014-09-04 arithmétique et logique Multiplication arithmétique • fonction test conditionnel • * ≡ (λ(xyz)x(yz)) • Dans le TP1 #2 montrer que * 2 3 ≡ 6 T si x=0 Z ( x) F autrement Z x.xF F • En TP démontrer que (C’est le #1 du TP1) – (Z 0) ≡ T – (Z a) ≡ F si a = 1, 2, … • écrivez un petit texte justifiant la généralisation pour a=3, a=4 … 41 42 Ordre des définitions Il n’y a pas de définition en λ-calcul. Si on les utilise ce n’est que pour simplifier l’écriture. Par exemple le programme suivant f ≡ (λ(ab)(+ a b c)) g ≡ (λ (c)(f 1 2 )) (g 3) ? Ordre des définitions λ-calcul DrRacket est en réalité le programme ci-dessous après avoir remplacé f et g dans (g 3) f ≡ (λ(ab)(+ a b c)) g ≡ (λ (c) (f 1 2 )) (g 3) ? (define f (λ (a b) (+ a b c))) (define g (λ (c) (f 1 2))) (g 3) ((λ(f) ((λ(g) (g 3)) (λ(c) (f 1 2)))) (λ(a b)(+ a b c))) ((λ (c) ((λ (a b) (+ a b c)) 1 2)) 3) Le problème de l’ordre des définitions n’a donc tout simplement pas de sens. On aurait pu aussi écrire ((λ (f) ((λ (c) (f 1 2)) 3) (λ (a b) (+ a b c))) (g 3) ((λ (c) (f 1 2)) 3) ((λ (c) ((λ (a b) (+ a b c)) 1 2)) 3) Cette traduction en λ-calcul d’un programme en DrRacket est approximatif. Pour cet exemple le comportement est le même. Avec DrRacket 2 fonctions peuvent s’influencer mutuellement. Le mécanisme sera exposé avec l’évaluation par environnement. Exercice : Effectuer la réduction du dernier λ-terme L’utilisation des définitions permet de réduire la complexité d’un terme, s’il y a un sous-terme (comme f) qui apparaît plusieurs fois. 43 44 11 2014-09-04 Exercice de réduction (sans erreur) Exercice de réduction 1 2 3 ((λ(f) ((λ(g) (g 3)) (λ(c) (f 1 2)))) (λ (ab) (+ a b c))) ((λ(g) (g 3)) (λ(c) ((λ(ab) (+ a b c)) 1 2))) 4 5 ((λ(c) ((λ(ab) (+ a b c)) 1 2)) 3) ((λ (ab) (+ a b 3)) 1 2) (+ 1 2 3) ((λ(c) ((λ(ab) (+ a b c)) 1 2)) 3) 45 ((λ(f) ((λ(g) (g 3)) (λ(c) (f 1 2)))) (λ(ab) (+ a b c))) ((λ(g) (g 3)) (λ(c) (f 1 2))) ;[f := (λ(ab)(+ a b c))] ((λ(g) (g 3)) (λ(d) ((λ(ab) (+ a b c)) 1 2))) ((λ(d) ((λ(ab) (+ a b c)) 1 2)) 3) ((λ(ab) (+ a b c)) 1 2) (+ 1 2 c) ((λ(g) (g 3));[f := (λ(ab)(+ a b c))] (λ(c) (f 1 2))[f := (λ(ab)(+ a b c))]) ((λ(g) (g 3)) (λ(c) (f 1 2)[c:d])[f := (λ(ab)(+ a b c))]) 46 Représentation d’un couple en λ-calcul Ordre des définitions en DrRacket • un couple (ab) (λ (z) z a b) DrRacket L’ordre des définitions est sans importance mais les définitions doivent être dans le texte du programme avant leur utilisation dans une application. • le car est T (λ (z) z a b) T (T a b) a λ-calcul L’ordre des définitions a un impact sur la réduction. Plus précisément, comme les définitions sont des artifices pour simplifier l’écriture, c’est en réalité quel λ est inclus dans l’application d’une autre λ. 47 ((λ(g) (g 3)) (λ(d) (f 1 2)[f := (λ(ab)(+ a b c))]) • le cdr est F (λ (z) z a b) F (F a b) b 48 • Avec la notion de couple on peut construire des listes, des arbres, des graphes … 12 2014-09-04 P (prédécesseur) P (prédécesseur) • Φ est une fonction auxiliaire qui nous aidera à définir P • Φ ≡(λ(p z) z (S(p T)) (p T)) • • • • • • • • • – p est une paire de nombre – z est soit la fonction car (T) ou cdr (F) • • • • • • (Φ (λ(z) (z 0 0))) ((λ(p z) z (S(p T)) (p T)) (λ(z) (z 0 0))) (λ(z) z (S((λ (z) (z 0 0)) T)) ((λ(z) (z 0 0)) T)) (λ(z)z(S(T 0 0)) (T 0 0)) (λ(z)z(S 0) 0) (λ (z) (z 1 0)) 49 (define P (λ(n)n Φ (λ(z)z00)F)) (P 3) (3 Φ (λ(z)z00)F) (((3 Φ) (λ(z)z00))F) (Φ (Φ (Φ (λ(z)z00))))F (Φ (Φ (λ (z) (z 1 0))))F (Φ (λ (z) (z 2 1)))F (λ (z) (z 3 2))F 2 50 Récursivité • Récursivité Les constantes ne font pas partie du lambda-calcul, on ne les utilise que pour faciliter l’écriture alors comment définir une fonction récursive ? • Quelle fonction R permet de calculer de façon récursive la somme des entiers entre 0 et n ? – idée 1 : Trouver une fonction dont la réduction est récursive Y ≡ (λ(y) ((λ(x)y(x x))(λ(x)y(x x)))) n 1 i 0 i 0 Un -terme qui se rapproche de ce que devrait être R est : ( (r n) nS (r ( Pn))) – n S X est équivalent à additionner n à X est la fonction récursive appliquée au prédécesseur de n – – idée 2 : Utiliser Z avec une constante n • • tant que n ≠ 0 on développe Y R et quand n=0, on applique le résultat du développement à la valeur de R pour l’argument 0 retourne n-1 • r est la fonction récursive, i.e λ – mais en λ-calcul, les fonctions n’ont pas de nom (nous le faisons que pour nous simplifier l’écriture) c’est pour cela que nous utilisons Y – idée 3 : trouver la fonction R spécifique au problème 51 n i n i • Soit R un λ-terme quelconque . • ≡ . ≡ . . ≡ ≡ ≡ ≡… 52 13 2014-09-04 Récursivité Récursivité • Quelle fonction R permet de calculer de façon récursive la somme des entiers entre 0 et n ? n n 1 i 0 i 0 • Rappel de l’idée 2 pour arrêter la récursion lorsque n=0 ? – – i n i • Un -terme qui se rapproche de ce que devrait être R est : ( (r n) nS (r ( Pn))) 0 0 0 0 X si i≠0 0 – n S X est équivalent à additionner n à X est la fonction récursive appliquée au prédécesseur de n – • retourne n-1 • r est la fonction récursive, i.e λ – mais en λ-calcul, les fonctions n’ont pas de nom (nous le faisons que pour nous simplifier l’écriture) c’est pour cela que nous utilisons Y 54 53 Récursivité • Quelle fonction R permet de calculer de façon récursive la somme des entiers entre 0 et n ? • Exemple : calculer la somme des entiers jusqu’à 3 – – – – – – – – – – – • 55 Récursivité • 0 Quelle fonction R permet de calculer de façon récursive la somme des entiers entre 0 et n ? – • Il faut calculer YR3 YR3 R(YR)3 (λ(r n)(Z n 0) (n S(r(P n)))) (YR) 3 (Z 3 0) (3 S ((YR) (P 3))) (3 S ((YR) (P 3))) (S(S(S((YR) (P 3))))) (S(S(S(R(YR) (P 3))))) (S(S(S(Z (P 3) 0) ((P 3) S ((YR) (P(P 3))))))) voir prochaine diapositive 0 Exemple : calculer la somme des entiers jusqu’à 3 – – – – – – – – – ... (S(S(S(Z (P 3) 0) ((P 3) S ((YR) (P(P 3))))))) (S(S(S(Z 2 0) ((P 3) S ((YR) (P(P 3))))))) (S(S(S((P 3) S ((YR) (P(P 3))))))) (S(S(S((P 3) S ((YR) (P(P 3))))))) (S(S(S(2S ((YR) (P (P 3))))))) (S(S(S(S(S ((YR) (P (P 3)))))))) ... terminer le développement en exercice Remarque, il faut utiliser l’ordre normal d’évaluation, sinon YR se développe sans arrêt 56 14 2014-09-04 Récursivité Conclusion • Le λ-calcul est un véritable langage de programmation qui a la même puissance que les langages classiques comme Java, C++ • Avec la récursivité on peut définir toutes les structures d’itération possibles • Je vous encourage à consulter le site web suivant http://www.utdallas.edu/~gupta/courses/apl/lambda.pdf – pour illustrer ce point, nous avons implémenté un peu de logique, d’arithmétique et la récursivité; – nous avons constaté que tous les concepts pouvaient être implémentés comme étant des abstractions (fonctions) – exécuter un programme ressemble à faire des mathématiques • exécuter un programme == simplifier une expression • C’est le plus simple langage de programmation • Il est un outil pour étudier la calculabilité, les langages de programmation… • Comme le λ-calcul est la base de tous les langages de programmation fonctionnelle, vous devez 57 58 – connaître la théorie présentée ; – être en mesure de réduire une expression ; – être en mesure d’identifier les fonctions présentées 15