Algorithmique et Programmation Fonctionnelle (APF)

publicité
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
Téléchargement