Algorithmique et Programmation Fonctionnelle (APF) Algorithmique et Programmation Fonctionnelle (APF) RICM3 Cours 10 : Traits impératifs et Lambda-calcul Jean-François Monin, Benjamin Wack Polytech 2016 - 2017 1 / 46 Algorithmique et Programmation Fonctionnelle (APF) Déjà vu I Type unit, effets de bord I Séquence d’instructions I Tableaux I Ordre supérieur 2 / 46 Algorithmique et Programmation Fonctionnelle (APF) Plan Traits impératifs Rappels sur les Entrées / Sorties Boucles Enregistrements mutables et références Lambda-calcul Programmation fonctionnelle et modèle de calcul λ-termes Évaluation Modélisation Récursivité 3 / 46 Traits impératifs Rappels sur les Entrées / Sorties Boucles Enregistrements mutables et références Lambda-calcul Programmation fonctionnelle et modèle de calcul λ-termes Évaluation Modélisation Récursivité Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Rappels sur les Entrées / Sorties Entrées / sorties standard Sortie print_string affiche une chaîne de caractères passée en argument. Valeur de retour ? 5 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Rappels sur les Entrées / Sorties Entrées / sorties standard Sortie print_string affiche une chaîne de caractères passée en argument. Valeur de retour ? # print_string "hello" ; ; hello- : unit = () unit est le type/la valeur de retour des fonctions I qui ne renvoient rien I mais qui peuvent avoir des effets de bord 5 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Rappels sur les Entrées / Sorties Entrées / sorties standard Entrée read_line lit une ligne au clavier et renvoie la chaîne lue. Quel est son type ? 6 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Rappels sur les Entrées / Sorties Entrées / sorties standard Entrée read_line lit une ligne au clavier et renvoie la chaîne lue. Quel est son type ? I Un identifiant = une valeur, jamais réévalué # read_line ; ; - : unit-> string = <fun> 6 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Rappels sur les Entrées / Sorties Entrées / sorties standard Entrée read_line lit une ligne au clavier et renvoie la chaîne lue. Quel est son type ? I Un identifiant = une valeur, jamais réévalué # read_line ; ; - : unit-> string = <fun> I Seules sont évaluées les fonctions appliquées à un argument # read_line () ; ; hello - : string = "hello" unit est le type/la valeur de l’argument des fonctions I qui n’ont besoin d’aucun argument I mais qui doivent être réévaluées à chaque fois 6 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Rappels sur les Entrées / Sorties Autres fonctions Affichage print_string print_int print_char print_float print_newline Lecture read_line read_int read_float : : : : : : : : string int char float unit unit unit unit -> -> -> -> -> -> -> -> unit unit unit unit unit string int float Voir aussi la bibliothèque Printf Printf.printf "Il est %d h %d." 8 22 Il est 8 h 22. 7 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Rappels sur les Entrées / Sorties Généralisation Canaux # stdin ; ; - : in_channel = <abstr> # stdout ; ; - : out_channel = <abstr> 8 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Rappels sur les Entrées / Sorties Généralisation Canaux # stdin ; ; - : in_channel = <abstr> # stdout ; ; - : out_channel = <abstr> input_char : in_channel -> char input_line : in_channel -> string output_char : out_channel -> char-> unit output_line : out_channel -> string-> unit 8 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Rappels sur les Entrées / Sorties Lecture / écriture dans un fichier Ouverture d’un fichier en lecture open_in : string-> in_channel # open_in “fichier” ; ; Ouverture d’un fichier en écriture open_out : string-> out_channel # open_out “fichier” ; ; Fermeture d’un canal close_in : in_channel -> unit close_out : out_channel -> unit 9 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Rappels sur les Entrées / Sorties Stream # Stream.of_channel - : in_channel -> char Stream.t = <fun> Permet de récupérer le contenu d’un fichier comme un flot pour pouvoir le parser. À comparer avec # Stream.of_string ; ; - : string-> char Stream.t = <fun> 10 / 46 Traits impératifs Rappels sur les Entrées / Sorties Boucles Enregistrements mutables et références Lambda-calcul Programmation fonctionnelle et modèle de calcul λ-termes Évaluation Modélisation Récursivité Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Boucles for Syntaxe for v = expr1 to expr2 do expr3 done Valeur et type d’un for ? 12 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Boucles for Syntaxe for v = expr1 to expr2 do expr3 done Valeur et type d’un for ? À peu près équivalent à expr3 ; expr3 ; . . . ; expr3 I forcément expr3 : unit I donc toute l’expression aussi 12 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Boucles for Syntaxe for v = expr1 to expr2 do expr3 done Valeur et type d’un for ? À peu près équivalent à expr3 ; expr3 ; . . . ; expr3 I forcément expr3 : unit I donc toute l’expression aussi Exemple #for i = 1 to 10 do print_int i done ; ; 12345678910- : unit = () 12 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Boucles While Syntaxe while expression booléenne do ... done 13 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Boucles While Syntaxe while expression booléenne do ... done Valeur et type unit pour les mêmes raisons que pour for 13 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Boucles While Syntaxe while expression booléenne do ... done Valeur et type unit pour les mêmes raisons que pour for Attention ! La condition doit contenir un mutable, sinon elle ne passera jamais de vrai à faux. 13 / 46 Traits impératifs Rappels sur les Entrées / Sorties Boucles Enregistrements mutables et références Lambda-calcul Programmation fonctionnelle et modèle de calcul λ-termes Évaluation Modélisation Récursivité Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Notions d’enregistrements # type personne = { prenom : string ; nom : string ; age : int} ;; # let quelquun = { prenom = "Bixente" ; nom = "Lizarazu" ; age = 43} ;; # { quelquun with age = quelquun.age + 1 } ;; - : personne = {prenom = "Bixente"; nom = "Lizarazu"; age = 44} # quelquun ;; - : personne = {prenom = "Bixente"; nom = "Lizarazu"; age = 43} # quelquun.age <- quelquun.age + 1;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: The record field age is not mutable 15 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Plus général : les enregistrements mutables # type personne = { prenom : string ; nom : string ; mutable age : int} ;; # let quelquun = { prenom = "Bixente" ; nom = "Lizarazu" ; age = 43 } ;; # quelquun.age <- quelquun.age + 1;; - : unit = () # quelquun;; - : personne = { prenom = "Bixente" ; nom = "Lizarazu" ; age = 44 } # quelquun.prenom <- "Vincent";; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: The record field prenom is not mutable 16 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Si on ajoute un peu de polymorphisme par dessus... # type ’a ref = {mutable contents : ’a} ; ; # let n = {contents = 0} ; ; val n : int ref = { contents = 0 } 17 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Si on ajoute un peu de polymorphisme par dessus... # type ’a ref = {mutable contents : ’a} ; ; # let n = {contents = 0} ; ; val n : int ref = { contents = 0 } # n.contents <- 1 ; ; - : unit = () # n;; val n : int ref = { contents = 1 } # n.contents ; ; - : int = 1 17 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Si on ajoute un peu de polymorphisme par dessus... # type ’a ref = {mutable contents : ’a} ; ; # let n = {contents = 0} ; ; val n : int ref = { contents = 0 } # n.contents <- 1 ; ; - : unit = () # n;; val n : int ref = { contents = 1 } # n.contents ; ; - : int = 1 Le type ref est défini par défaut en OCaml. I ref(x) est un raccourci pour { contents = x } I !r est un raccourci pour r.contents I r := v est un raccourci pour r.contents <- v 17 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Si on ajoute un peu de polymorphisme par dessus... # type ’a ref = {mutable contents : ’a} ; ; # let n = {contents = 0} ; ; val n : int ref = { contents = 0 } # n.contents <- 1 ; ; - : unit = () # n;; val n : int ref = { contents = 1 } # n.contents ; ; - : int = 1 # let n = ref(0) ; ; # n := 1 ; ; # !n ; ; Le type ref est défini par défaut en OCaml. I ref(x) est un raccourci pour { contents = x } I !r est un raccourci pour r.contents I r := v est un raccourci pour r.contents <- v 17 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Exemples I Incrémenter r ? 18 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Exemples I I Incrémenter r ? let r = ref(5);; val r : int ref = {contents = 5} r := !r + 1;; - : unit = () !r;; - : int = 6 Calculer la longueur d’une liste avec une référence ? 18 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Exemples I I Incrémenter r ? let r = ref(5);; val r : int ref = {contents = 5} r := !r + 1;; - : unit = () !r;; - : int = 6 Calculer la longueur d’une liste avec une référence ? let lg = ref 0;; let rec len l = match l with [] -> !lg | _ :: q -> lg := !lg + 1 ; len q;; 18 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Exemples I I Incrémenter r ? let r = ref(5);; val r : int ref = {contents = 5} r := !r + 1;; - : unit = () !r;; - : int = 6 Calculer la longueur d’une liste avec une référence ? let lg = ref 0;; let rec len l = match l with [] -> !lg | _ :: q -> lg := !lg + 1 ; len q;; Mais lg n’est pas remis à 0 à chaque appel ! 18 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Compteur Écrire une fonction compteur de type : unit -> int qui renvoie 1 au premier appel, 2 au second, puis l’entier suivant à chaque appel. 19 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Compteur Écrire une fonction compteur de type : unit -> int qui renvoie 1 au premier appel, 2 au second, puis l’entier suivant à chaque appel. # let c = ref 0;; # let compteur () = c := !c + 1 ; !c;; val compteur : unit -> int = <fun> Écrire une fonction raz qui remet le compteur à zéro. Quel est son type ? 19 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Compteur Écrire une fonction compteur de type : unit -> int qui renvoie 1 au premier appel, 2 au second, puis l’entier suivant à chaque appel. # let c = ref 0;; # let compteur () = c := !c + 1 ; !c;; val compteur : unit -> int = <fun> Écrire une fonction raz qui remet le compteur à zéro. Quel est son type ? # let raz () = c := 0;; val raz : unit -> unit = <fun> Que peut-on reprocher à ce compteur ? 19 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Aliasing pour les références Les égalités # let r = ref 0;; # let q = ref 0;; Que vaut q = r ? 20 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Aliasing pour les références Les égalités # let r = ref 0;; # let q = ref 0;; Que vaut q = r ? true, car même contenu 20 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Aliasing pour les références Les égalités # let r = ref 0;; # let q = ref 0;; Que vaut q = r ? true, car même contenu Que vaut q == r ? 20 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Aliasing pour les références Les égalités # let r = ref 0;; # let q = ref 0;; Que vaut q = r ? true, car même contenu Que vaut q == r ? false, car pas la même “adresse” 20 / 46 Algorithmique et Programmation Fonctionnelle (APF) Traits impératifs Enregistrements mutables et références Aliasing pour les références Les égalités # let r = ref 0;; # let q = ref 0;; Que vaut q = r ? true, car même contenu Que vaut q == r ? false, car pas la même “adresse” Aliasing # let r = ref 0;; # let q = r; Même objet, donc même contenu : true dans les deux cas 20 / 46 Traits impératifs Rappels sur les Entrées / Sorties Boucles Enregistrements mutables et références Lambda-calcul Programmation fonctionnelle et modèle de calcul λ-termes Évaluation Modélisation Récursivité Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Programmation fonctionnelle et modèle de calcul Qu’est-ce qu’un langage de programmation ? 22 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Programmation fonctionnelle et modèle de calcul Qu’est-ce qu’un langage de programmation ? Un langage commun entre l’homme et la machine 22 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Programmation fonctionnelle et modèle de calcul Qu’est-ce qu’un langage de programmation ? Un langage commun entre l’homme et la machine = Assembleur Un langage commun entre l’homme et un modèle de la machine 22 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Programmation fonctionnelle et modèle de calcul Qu’est-ce qu’un langage de programmation ? Un langage commun entre l’homme et la machine = Assembleur Un langage commun entre l’homme et un modèle de la machine I Variables = mémoire accès par références et pas par adresses I Conditionnelle = branchement enchaînement d’un calcul et d’une action I Boucle = manipulation du registre PC cycle dans la table d’action I ... 22 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Programmation fonctionnelle et modèle de calcul À quel machine correspond un langage fonctionnel ? 23 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Programmation fonctionnelle et modèle de calcul À quel machine correspond un langage fonctionnel ? Aucune ! 23 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Programmation fonctionnelle et modèle de calcul À quel machine correspond un langage fonctionnel ? Aucune ! I Au modèle fonctionnel : le λ-calcul I proposé par Alonzo Church en 1936 pour modéliser ce qu’est une fonction calculable automatiquement (i.e. par une machine) 23 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Programmation fonctionnelle et modèle de calcul À quel machine correspond un langage fonctionnel ? Aucune ! I Au modèle fonctionnel : le λ-calcul I proposé par Alonzo Church en 1936 pour modéliser ce qu’est une fonction calculable automatiquement (i.e. par une machine) I Le λ-calcul et la machine de Turing ont été montrés équivalents en 1937 par Turing (et « tous » les autres modèles de calcul aussi) 23 / 46 Traits impératifs Rappels sur les Entrées / Sorties Boucles Enregistrements mutables et références Lambda-calcul Programmation fonctionnelle et modèle de calcul λ-termes Évaluation Modélisation Récursivité Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Syntaxe Notations I x , y , z... sont des variables I A, B, C ...M, N sont des termes Termes Un terme peut être : I une variable x 25 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Syntaxe Notations I x , y , z... sont des variables I A, B, C ...M, N sont des termes Termes Un terme peut être : I une variable x I une abstraction λx .A où A est un terme et x une variable (équivaut à fun x -> A) 25 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Syntaxe Notations I x , y , z... sont des variables I A, B, C ...M, N sont des termes Termes Un terme peut être : I une variable x I une abstraction λx .A où A est un terme et x une variable (équivaut à fun x -> A) I une application A B où A et B sont deux termes 25 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Syntaxe Notations I x , y , z... sont des variables I A, B, C ...M, N sont des termes Termes Un terme peut être : I une variable x I une abstraction λx .A où A est un terme et x une variable (équivaut à fun x -> A) I une application A B où A et B sont deux termes I et c’est tout ! Les fonctions sont encore des citoyens de première classe, et même 25 / 46 les seuls. Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Conventions L’application est prioritaire λx .x y = λx .(x y ) et pas (λx .x ) y 26 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Conventions L’application est prioritaire λx .x y = λx .(x y ) et pas (λx .x ) y L’application est associative à gauche (AB1 B2 . . . Bk ) = (. . . ((AB1 )B2 ) . . . Bk ) 26 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Conventions L’application est prioritaire λx .x y = λx .(x y ) et pas (λx .x ) y L’application est associative à gauche (AB1 B2 . . . Bk ) = (. . . ((AB1 )B2 ) . . . Bk ) Abréviation des abstractions (λx1 .λx2 . . . . λxk .A) = (λx1 .(λx2 . . . . (λxk .A) . . .) = (λx1 x2 . . . xk .A) 26 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Conventions L’application est prioritaire λx .x y = λx .(x y ) et pas (λx .x ) y L’application est associative à gauche (AB1 B2 . . . Bk ) = (. . . ((AB1 )B2 ) . . . Bk ) Abréviation des abstractions (λx1 .λx2 . . . . λxk .A) = (λx1 .(λx2 . . . . (λxk .A) . . .) = (λx1 x2 . . . xk .A) Quizz I f (λx .x ) y = 26 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Conventions L’application est prioritaire λx .x y = λx .(x y ) et pas (λx .x ) y L’application est associative à gauche (AB1 B2 . . . Bk ) = (. . . ((AB1 )B2 ) . . . Bk ) Abréviation des abstractions (λx1 .λx2 . . . . λxk .A) = (λx1 .(λx2 . . . . (λxk .A) . . .) = (λx1 x2 . . . xk .A) Quizz I f (λx .x ) y = (f (λx .x )) y I λx .(λy .y z) x = 26 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Conventions L’application est prioritaire λx .x y = λx .(x y ) et pas (λx .x ) y L’application est associative à gauche (AB1 B2 . . . Bk ) = (. . . ((AB1 )B2 ) . . . Bk ) Abréviation des abstractions (λx1 .λx2 . . . . λxk .A) = (λx1 .(λx2 . . . . (λxk .A) . . .) = (λx1 x2 . . . xk .A) Quizz I f (λx .x ) y = (f (λx .x )) y I λx .(λy .y z) x = λx .((λy .(y z)) x ) 26 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Notion de variable liée Quelle différence y a-t-il entre fun x -> x et fun y -> y ? 27 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Notion de variable liée Quelle différence y a-t-il entre fun x -> x et fun y -> y ? Aucune, ce qui importe n’est pas le nom de la variable mais les endroits où elle est présente. 27 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Notion de variable liée Quelle différence y a-t-il entre fun x -> x et fun y -> y ? Aucune, ce qui importe n’est pas le nom de la variable mais les endroits où elle est présente. Situations similaires omniprésentes en informatique et en mathématiques : I ∀x .P(x ) I for (int i=0 ; i < n ; i++) { ... } I Rb a f (t)dt On parle de variable liée, ou aussi variable muette. 27 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes α-conversion Peut-on vraiment choisir un nom arbitraire pour une variable liée ? λx .x y 6= λy .y y (capture) 28 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes α-conversion Peut-on vraiment choisir un nom arbitraire pour une variable liée ? λx .x y 6= λy .y y (capture) α-conversion = renommer une variable liée sans utiliser une variable déjà présente dans le terme 28 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes α-conversion Peut-on vraiment choisir un nom arbitraire pour une variable liée ? λx .x y 6= λy .y y (capture) α-conversion = renommer une variable liée sans utiliser une variable déjà présente dans le terme Exemple : λx .xy =α λz.zy 28 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Substitution On note A[x := B] pour « remplacer les occurrences de x par B dans A ». 29 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Substitution On note A[x := B] pour « remplacer les occurrences de x par B dans A ». Précautions : I (λx .y )[x := A] = λA.y ?? 29 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Substitution On note A[x := B] pour « remplacer les occurrences de x par B dans A ». Précautions : I (λx .y )[x := A] = λA.y ?? λA.y n’est pas valide DONC ne pas remplacer après un λ. 29 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Substitution On note A[x := B] pour « remplacer les occurrences de x par B dans A ». Précautions : I (λx .y )[x := A] = λA.y ?? λA.y n’est pas valide DONC ne pas remplacer après un λ. I (λx .x )[x := y ] = λx .y ?? 29 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Substitution On note A[x := B] pour « remplacer les occurrences de x par B dans A ». Précautions : I (λx .y )[x := A] = λA.y ?? λA.y n’est pas valide DONC ne pas remplacer après un λ. I (λx .x )[x := y ] = λx .y ?? x est liée au λ DONC ne pas la remplacer. 29 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Substitution On note A[x := B] pour « remplacer les occurrences de x par B dans A ». Précautions : I (λx .y )[x := A] = λA.y ?? λA.y n’est pas valide DONC ne pas remplacer après un λ. I (λx .x )[x := y ] = λx .y ?? x est liée au λ DONC ne pas la remplacer. I (λx .y )[y := x ] = λx .x ?? 29 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Substitution On note A[x := B] pour « remplacer les occurrences de x par B dans A ». Précautions : I (λx .y )[x := A] = λA.y ?? λA.y n’est pas valide DONC ne pas remplacer après un λ. I (λx .x )[x := y ] = λx .y ?? x est liée au λ DONC ne pas la remplacer. I (λx .y )[y := x ] = λx .x ?? y n’est pas liée mais le devient DONC renommer avant 29 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Substitution On note A[x := B] pour « remplacer les occurrences de x par B dans A ». Précautions : I (λx .y )[x := A] = λA.y ?? λA.y n’est pas valide DONC ne pas remplacer après un λ. I (λx .x )[x := y ] = λx .y ?? x est liée au λ DONC ne pas la remplacer. I (λx .y )[y := x ] = λx .x ?? y n’est pas liée mais le devient DONC renommer avant Bref : toujours effectuer une α-conversion avant de substituer. 29 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul λ-termes Substitution On note A[x := B] pour « remplacer les occurrences de x par B dans A ». Précautions : I (λz.y )[x := A] = λz.y λA.y n’est pas valide DONC ne pas remplacer après un λ. I (λz.z)[x := y ] = λz.z x est liée au λ DONC ne pas la remplacer. I (λz.y )[y := x ] = λz.x y n’est pas liée mais le devient DONC renommer avant Bref : toujours effectuer une α-conversion avant de substituer. 29 / 46 Traits impératifs Rappels sur les Entrées / Sorties Boucles Enregistrements mutables et références Lambda-calcul Programmation fonctionnelle et modèle de calcul λ-termes Évaluation Modélisation Récursivité Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Évaluation β-réduction Les λ-termes sont des expressions qui ont donc vocation à être évaluées. Une seule règle locale (λx .A) B → A[x := B] peut être appliquée partout dans le terme, répétée... Exemples : (λx .x ) B → B (λx .x y ) λz.z → (λz.z) y → y 31 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Évaluation β-réduction Les λ-termes sont des expressions qui ont donc vocation à être évaluées. Une seule règle locale (λx .A) B → A[x := B] peut être appliquée partout dans le terme, répétée... Exemples : (λx .x ) B → B (λx .x y ) λz.z → (λz.z) y → y (fun x -> x) 6 ;; - : int = 6 31 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Évaluation Notations I →∗ la clôture réflexive transitive : A →∗ B ssi ∃n ≥ 0, A0 , . . . , An , A = A0 → A1 → . . . → An = B 32 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Évaluation Notations I →∗ la clôture réflexive transitive : A →∗ B ssi ∃n ≥ 0, A0 , . . . , An , A = A0 → A1 → . . . → An = B → passe au contexte : I si A → B alors AC → BC et CA → CB I si A → B alors λx .A → λx .B 32 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Évaluation Exercices I (λx .xx )(λy .y ) 33 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Évaluation Exercices I (λx .xx )(λy .y ) → (λy .y )(λy .y ) → λy .y 33 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Évaluation Exercices I (λx .xx )(λy .y ) → (λy .y )(λy .y ) → λy .y I (λx .(λy .xy ))y 33 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Évaluation Exercices I (λx .xx )(λy .y ) → (λy .y )(λy .y ) → λy .y I (λx .(λy .xy ))y =α (λx .(λz.xz))y → λz.yz 33 / 46 Traits impératifs Rappels sur les Entrées / Sorties Boucles Enregistrements mutables et références Lambda-calcul Programmation fonctionnelle et modèle de calcul λ-termes Évaluation Modélisation Récursivité Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Expressivité Que peut-on calculer avec ça ? I “Tout” ! (thèse de Church-Turing) I En particulier tout ce qui constitue les algorithmes 35 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Expressivité Que peut-on calculer avec ça ? I “Tout” ! (thèse de Church-Turing) I En particulier tout ce qui constitue les algorithmes Structures de contrôle I Conditionnelle I Boucles ( ?) 35 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Expressivité (suite) Données I Booléens I Entiers I n-uplets I Et bien sûr, fonctions 36 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Booléens et conditionnelle vrai faux = λxy .x = λxy .y 37 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Booléens et conditionnelle vrai faux ifthenelse = λxy .x = λxy .y = λbuv .buv 37 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Booléens et conditionnelle vrai faux ifthenelse = λxy .x = λxy .y = λbuv .buv Vérifions ifthenelse vrai A B →∗ A 37 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Booléens et conditionnelle vrai faux ifthenelse = λxy .x = λxy .y = λbuv .buv Vérifions ifthenelse vrai A B →∗ A ifthenelse vrai A B = (λbuv .buv ) vrai A B → (λuv .vrai uv ) A B →∗ (vrai A B) = (λxy .x )A B →∗ A 37 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Booléens et conditionnelle vrai faux ifthenelse = λxy .x = λxy .y = λbuv .buv Vérifions ifthenelse vrai A B →∗ A ifthenelse vrai A B = (λbuv .buv ) vrai A B → (λuv .vrai uv ) A B →∗ (vrai A B) = (λxy .x )A B →∗ A Exercice : ifthenelse faux A B →∗ B 37 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Exercice : définir les connecteurs logiques non et ou 38 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Exercice : définir les connecteurs logiques non non = λb.ifthenelse b faux vrai et ou 38 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Exercice : définir les connecteurs logiques non non = λb.ifthenelse b faux vrai et et = λab.ifthenelse a b faux ou 38 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Exercice : définir les connecteurs logiques non non = λb.ifthenelse b faux vrai et et = λab.ifthenelse a b faux ou ou = λab.ifthenelse a vrai b 38 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Exercice : définir les connecteurs logiques non non = λb.ifthenelse b faux vrai →∗ λb.b faux vrai et et = λab.ifthenelse a b faux →∗ λab.a b faux ou ou = λab.ifthenelse a vrai b →∗ λab.a vrai b 38 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Couples Le couple (A, B) est représenté par λz.zAB 39 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Couples Le couple (A, B) est représenté par λz.zAB Projections π1 = λs.s vrai Vérifier que π1 λz.zAB →∗ A 39 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Couples Le couple (A, B) est représenté par λz.zAB Projections π1 = λs.s vrai Vérifier que π1 λz.zAB →∗ A π2 = λs.s faux Vérifier que π2 λz.zAB →∗ B 39 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Entiers de Church 0 = λfx .x 1 = λfx .fx 2 = λfx .f (fx ) et d’une manière générale : 40 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Entiers de Church 0 = λfx .x 1 = λfx .fx 2 = λfx .f (fx ) et d’une manière générale : n = λfx .f (f (...(fx )...)) = λfx .f n x avec f itérée n fois. 40 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Entiers de Church 0 = λfx .x 1 = λfx .fx 2 = λfx .f (fx ) et d’une manière générale : n = λfx .f (f (...(fx )...)) = λfx .f n x avec f itérée n fois. Exemple : itération itere = λnuv .nuv v est le cas de base et u une fonction. Si n est nul, on calcule v , sinon on calcule u n (v ). 40 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Modélisation Quelques fonctions possibles I Ajouter 1 1. soit en ajoutant un f en tête, 2. soit en queue. I addition I multiplication I exponentielle I test à zéro 41 / 46 Traits impératifs Rappels sur les Entrées / Sorties Boucles Enregistrements mutables et références Lambda-calcul Programmation fonctionnelle et modèle de calcul λ-termes Évaluation Modélisation Récursivité Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Récursivité Une première boucle Soit ω = λx .xx et Ω = ωω = (λx .xx )(λx .xx ) (λx .xx )(λx .xx ) → 43 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Récursivité Une première boucle Soit ω = λx .xx et Ω = ωω = (λx .xx )(λx .xx ) (λx .xx )(λx .xx ) → (λx .xx )(λx .xx ) Donc Ω → Ω → . . . Propriété La β-réduction ne termine pas en général. 43 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Récursivité Notion de point fixe Théorème Tout λ-terme F a un point fixe x , x =β Fx Définition Un λ-terme Y tel que pour tout F , YF soit un point fixe de F est un combinateur de point fixe. 44 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Récursivité Notion de point fixe Théorème Tout λ-terme F a un point fixe x , x =β Fx Définition Un λ-terme Y tel que pour tout F , YF soit un point fixe de F est un combinateur de point fixe. Comment le construire ? 44 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Récursivité Notion de point fixe Théorème Tout λ-terme F a un point fixe x , x =β Fx Définition Un λ-terme Y tel que pour tout F , YF soit un point fixe de F est un combinateur de point fixe. Comment le construire ? Indice : partir de (λx .xx )(λx .xx ) 44 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Récursivité Notion de point fixe Théorème Tout λ-terme F a un point fixe x , x =β Fx Définition Un λ-terme Y tel que pour tout F , YF soit un point fixe de F est un combinateur de point fixe. Comment le construire ? Indice : partir de (λx .xx )(λx .xx ) Combinateur de Church Y = λf .(λx .f (xx ))(λx .f (xx )) 44 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Récursivité Aujourd’hui I Le lambda-calcul est le modèle de calcul sur lequel sont basés les langages fonctionnels I Tous les modèles de calcul permettent de calculer les mêmes choses I Mais les différents langages de programmation offrent des facilités d’expression différentes pour les données, les fonctions... I OCaml permet des traits impératifs comme les langages usuels, tout en imposant la discipline de typage habituelle 45 / 46 Algorithmique et Programmation Fonctionnelle (APF) Lambda-calcul Récursivité La suite I Projet à rendre le 18 décembre (encore 1 TP de suivi) I Examen début janvier Rappels I Transparents et fichiers .ml sur la page web du cours I Annales d’examens (+ corrections) sur la page web du cours http://www-verimag.imag.fr/~wack/APF I 1 feuille A4 recto-verso autorisée pour l’examen I Note finale = 60% Devoirs (DS, Examen) 40% CC (TP, Projet, DM) 46 / 46