1.1 Le Lambda-calcul

Definition — Lambda-calcul

Le lambda-calcul de Church (1936) est un formalisme minimal pour la programmation. Il se compose de trois constructions uniquement :

  • Variable : x
  • Abstraction : λx. M (fonction anonyme)
  • Application : M N (application de M a N)

1.1.1 Reduction beta

Reduction beta

La regle fondamentale : (λx. M) N ⟶ M[x := N]
On remplace toutes les occurrences de x dans M par N.

(* Exemple : (λx. x + 1) 3 ⟶ 3 + 1 = 4 *)

(* La reduction est deterministic : il existe un seul resultat normal *)

1.2 Codage de Church

Le codage de Church encode les donnees et les operations dans le lambda-calcul pur, sans primitives exposees.

1.2.1 Booleens de Church

true  = λx. λy. x     (* choisit le premier argument *)
false = λx. λy. y     (* choisit le deuxieme argument *)
if b then t else f = b t f

1.2.2 Entiers naturels de Church

Entiers de Church

L'entier naturel n est encode comme : &bar;n; = &lambda>f. λx. fn(x)
C'est une fonction qui applique f n fois sur x.

&bar;0; = &lambda>f. λx. x
&bar;1; = &lambda>f. λx. f x
&bar;2; = &lambda>f. λx. f (f x)
&bar;3; = &lambda)f. λx. f (f (f x))

(* Successeur : *)
succ = λn. λf. λx. f (n f x)

(* Addition : *)
add = λm. λn. λf. λx. m f (n f x)

(* Multiplication : *)
mul = λm. λn. λf. λx. m (n f) x

1.2.3 Paires

pair  = λa. λb. λf. f a b
fst   = λp. p (λa. λb. a)
snd   = λp. p (λa. λb. b)

1.2.4 Listes (fold-right)

nil    = λc. λn. n
cons   = λh. λt. λc. λn. c h (t c n)
isnil  = λl. l (λh. λt. false) true

1.3 Le langage OCaml

1.3.1 Types de base

TypeExemplesDescription
int0, 42, -7Entiers (precision machine)
float3.14, -0.5Flottants (IEEE 754)
booltrue, falseBooleens
char'a', 'Z'Caracteres
string"bonjour"Chaines de caracteres
unit()Type a unique valeur

1.3.2 Liaison et recursivite

let x = 42 in x + 1      (* liaison locale *)

let rec factorielle n =
  if n = 0 then 1
  else n * factorielle (n - 1)

let rec fib n =
  if n <= 1 then n
  else fib (n - 1) + fib (n - 2)

(* Pattern matching *)
let signe x =
  match x with
  | x when x > 0 -> "positif"
  | x when x < 0 -> "negatif"
  | _ -> "nul"

1.3.3 Fonctions d'ordre superieur

(* Application partielle *)
let add5 = (+) 5
(* add5 3 = 8 *)

(* Fonction anonyme *)
let carres = List.map (fun x -> x * x) [1; 2; 3; 4]

(* Composition *)
let compose f g x = f (g x)

(* Application partielle sur deux arguments *)
let add a b = a + b
let add10 = add 10    (* add10 5 = 15 *)

1.3.4 Operateurs binaires

(* Operations arithmetiques *)
(+)   (-)   (*)   (/)   (mod)
(+.)  (-.)  (*.)  (/.)

(* Operations sur les chaines *)
(^)   (* concatenation *)

(* Comparaisons *)
(=)   (<>)   (<)   (>)   (<=)   (>=)

(* Logiques *)
(&&)  (||)  not

1.4 Application — Calcul numerique

1.4.1 Approximation de pi

(* Serie de Leibniz : pi/4 = 1 - 1/3 + 1/5 - 1/7 + ... *)
let rec somme_series n =
  if n = 0 then 0.0
  else
    let k = float (2 * n - 1) in
    ((-1.0) ** (n + 1 |> float)) /. k +. somme_series (n - 1)

let pi_approx n = 4.0 *. somme_series n

1.4.2 Derivees numeriques

(* Difference centree : f'(x) ~ (f(x+h) - f(x-h)) / 2h *)
let derivee f x =
  let h = 1e-8 in
  (f (x +. h) -. f (x -. h)) /. (2.0 *. h)

(* Exemple : derivee de x^2 en x=3 = 6.0 *)
let () = Printf.printf "%.4f\n" (derivee (fun x -> x *. x) 3.0)

1.4.3 Integrales numeriques

(* Methode des trapezes : integrale de f sur [a,b] *)
let integrale f a b n =
  let dx = (b -. a) /. float n in
  let rec aux i acc =
    if i >= n then acc
    else
      let x = a +. float i *. dx in
      aux (i + 1) (acc +. (f x +. f (x +. dx)) *. dx /. 2.0)
  in aux 0 0.0

(* Exemple : integrale de x^2 sur [0,1] ~ 1/3 *)

1.4.4 Systeme logistique

Definition — Application du logistique

xn+1 = r · xn · (1 - xn)
Pour differentes valeurs de r, le systeme converge, oscille, ou devient chaotique.

let rec iterations r x n =
  if n = 0 then [x]
  else
    let x' = r *. x *. (1.0 -. x) in
    x :: iterations r x' (n - 1)

let logistique r x0 n =
  List.rev (iterations r x0 n)

(* Bifurcation : tracer logistique r x0 100 pour r = 2.5 a 4.0 *)
Exercices
  • Implementez fib avec recursion terminale (deux accumulateurs).
  • Memoisez fib avec un Hashtbl.
  • Implementez la formule de Bailey-Borwein-Plouffe pour pi.
  • Implementez la methode de Runge-Kutta d'ordre 4.