(************************************************* Exercice 1. Exemples d'expressions en Ocaml *************************************************) (*********************** Question 2 ***********************) 1, 1., "1";; (1,"1"),(1.,"1");; (1,(1.,"1")),1;; ('1',1),("1",1.);; (************************************************* Exercice 2. Exemples de fonctions en Ocaml *************************************************) (*********************** Question 3 ***********************) let f x = if x = 0 then 0. else 1.;; let f (a,b) = a = 0 && b = 0;; let f a b = a = 0 && b = 0;; let f a b = a + b;; let f a b = if a = b then a else b;; let f g h a = let b = h a in g a b;; (************************************************* Exercice 3. Fonctions élémentaires *************************************************) (*********************** Question 1 ***********************) let signe_int n = if n = 0 then failwith "n vaut zero" else if n > 0 then "positif" else "negatif";; (******** Tests ********) signe_int 0;; signe_int 1;; signe_int (-1);; (*********************** Question 2 ***********************) let signe_float n = if n = 0. then failwith "n vaut zero" else if n > 0. then "positif" else "negatif";; (******** Tests ********) signe_float 0.;; signe_float 1.;; signe_float (-1.);; signe_float 0.5;; (*********************** Question 3 ***********************) let valeur_absolue_int n = if n > 0 then n else -n;; (******** Tests ********) valeur_absolue_int (-1);; valeur_absolue_int 0;; valeur_absolue_int 1;; (*****************) let valeur_absolue_float n = if n >= 0. then n else -.n;; (******** Tests ********) valeur_absolue_float (-1.);; valeur_absolue_float 0.;; valeur_absolue_float 1.;; valeur_absolue_float 0.5;; (************************************************* Exercice 4. Ordre lexicographique *************************************************) let est_plus_petit (a1,b1: int*int) (a2,b2) = a1 < a2 || (a1 = a2 && b1 <= b2);; (******** Tests ********) est_plus_petit (8,0) (2,1);; est_plus_petit (3,-1) (2,1);; est_plus_petit (2,3) (2,1);; est_plus_petit (2,2) (2,1);; est_plus_petit (2,1) (2,1);; est_plus_petit (2,0) (2,1);; est_plus_petit (2,-1) (2,1);; est_plus_petit (2,-2) (2,1);; est_plus_petit (1,12) (2,1);; est_plus_petit (-2,5) (2,1);; (************************************************* Exercice 5. Racines d’un polynome du second degré *************************************************) let solution a b c = if a = 0. then if b = 0. then if c = 0. then failwith "Polynome nul" else failwith "Pas de solution" else -.c/.b, -.c/.b else let delta = b*.b -. 4.*.a*.c in if delta < 0. then failwith "Pas de solution reelle" else let d = sqrt(delta) in (-.b-.d)/.(2.*.a), (-.b+.d)/.(2.*.a);; (******** Tests ********) solution 1. 2. 1.;; solution 1. 2. 1.1;; solution 1. (-1.) (-1.);; (1.-.sqrt(5.))/.2.,(1.+.sqrt(5.))/.2.;; solution 0. 0. 0.;; solution 0. 0. 1.;; solution 0. 1. (-5.);; (************************************************* Exercice 6. Fonctions avec fonctions en paramètre *************************************************) (*********************** Question 1 ***********************) let fonction1 f = (f(5.) +. f(-5.))/.2.;; (******** Tests ********) let f x = x -. 3. in fonction1 f;; let f x = 2. *. x +. 1. in fonction1 f;; (*********************** Question 2 ***********************) let fonction2 f (x: float) = f x *. f x;; (******** Tests ********) let f x = x -. 3. in fonction2 f 2.;; let f x = 2. *. x +. 1. in fonction2 f 3.;; (*********************** Question 3 ***********************) (* L'argument de fonction3 est de type (float -> float) Le type de retour de fonction3 est (float -> float) Donc fonction3 est de type (float -> float) -> (float -> float) C'est à dire (float -> float) -> float -> float *) (* 1ere solution *) let fonction3 f (x: float) = f x *. f x;; (* 2eme solution *) let fonction3 f = let g (x: float) = f x *. f x in g;; (******** Tests ********) (* ... *) (*********************** Question 4 ***********************) (* L'argument de fonction4 est de type (float -> float) Le type de retour de fonction4 est (float -> float) Donc fonction4 est de type (float -> float) -> (float -> float) C'est à dire (float -> float) -> float -> float *) let fonction4 f x: float = f (2.*.x);; (******** Tests ********) (* ... *) (*********************** Question 5 ***********************) (* 1ere solution *) let somme f g (x: int) = f x + g x;; (******** Tests ********) let f x = 2 * x and g x = x + 1 in print_int (somme f g 2); print_newline(); print_int (somme f g (-2)); print_newline(); print_int (somme f g 4); print_newline(); print_int (somme f g 0); print_newline();; (* 2eme solution *) let somme f g = let h (x: int) = f x + g x in h;; (******** Tests ********) let f x = 2 * x and g x = x + 1 in print_int (somme f g 2); print_newline(); print_int (somme f g (-2)); print_newline(); print_int (somme f g 4); print_newline(); print_int (somme f g 0); print_newline();; (*********************** Question 6 ***********************) (* 1ere solution *) let produit f g (x: int) = f x * g x;; (******** Tests ********) let f x = 2 * x and g x = x + 1 in print_int (produit f g 2); print_newline(); print_int (produit f g (-2)); print_newline(); print_int (produit f g 4); print_newline(); print_int (produit f g 0); print_newline();; (* 2eme solution *) let produit f g = let h (x: int) = f x * g x in h;; (******** Tests ********) let f x = 2 * x and g x = x + 1 in print_int (produit f g 2); print_newline(); print_int (produit f g (-2)); print_newline(); print_int (produit f g 4); print_newline(); print_int (produit f g 0); print_newline();; (*********************** Question 7 ***********************) let produit_ext f a (x: int) = a * f x;; (******** Tests ********) let f x = x - 3 in print_int (produit_ext f 4 2); print_newline(); print_int (produit_ext f 3 0); print_newline(); print_int (produit_ext f 0 5); print_newline(); print_int (produit_ext f 10 10); print_newline();; (*********************** Question 8 ***********************) let derive f epsilon x = (f(x +. epsilon) -. f x)/.epsilon;; (******** Tests ********) (* ... *) (*********************** Question 9 ***********************) (* On devrait obtenir une approximation de la dérivée de la fonction f au point 2. f': x -> 3x^2 + 2 Donc on devrait obtenir le flottant 14. *) let f x = x*.x*.x +. 2.*.x +. 1. in derive f (10.**(-5.)) 2.;; (************************************************* Exercice 7. *************************************************) (*********************** Question 1 ***********************) let fonction1 a b c = a (b c);; (* Pour que l'expression "(b c)" soit bien typée, on doit avoir c : 'a b: 'a -> 'b b c: 'b Pour que l'expression "a (b c)" soit bien typée, on doit avoir: a: 'b -> 'c a (b c): 'c Finalement, fonction1: ('b -> 'c) -> ('a -> 'b) -> 'a -> 'c En renommant, fonction1: ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b *) let fonction2 a b c = (a b) c;; (* Pour que (a b) soit bien typée, on doit avoir: b : 'a a : 'a -> 'b a b: 'b Pour que ((a b) c) soit bien typée, on doit avoir: c : 'c (a b): 'c -> 'd ((a b) c) : 'd Donc 'b = 'c -> 'd Finalement, fonction2: ('a -> 'c -> 'd) -> 'a -> 'c -> 'd En renommant, fonction2: ('a -> 'b -> 'c) -> 'a -> 'b -> 'c *) let fonction3 a b c = a b c;; (* ((a b) c) et (a b c) sont les deux mêmes expressions donc: fonction3: ('a -> 'b -> 'c) -> 'a -> 'b -> 'c *) (*********************** Question 2 ***********************) let a = int_of_float and b = float_of_int and c = 0 in fonction1 a b c;; (*********************** Question 3 ***********************) let somme x y = x + y in let a x = somme x and b = 4 and c = 1 in fonction2 a b c;; (*********************** Question 4 ***********************) let somme x y = x + y in let a x = somme x and b = 4 and c = 1 in fonction3 a b c;; (************************************************* Exercice 8. Maximum de trois éléments *************************************************) (*********************** Question 1 ***********************) let max3_fail x y z = max max x y z;; (* La deuxieme fonction "max" est de type 'a -> 'a -> 'a La premiere fonction "max" est de type 'b -> 'b -> 'b L'expression "max max x y z" est équivalente a "(((max max) x) y) z". Ainsi: - Pour que l'expression "max max" soit bien typée, il faut prendre 'b = 'a -> 'a -> 'a. Donc le premier "max" est de type ('a -> 'a -> 'a) -> ('a -> 'a -> 'a) -> ('a -> 'a -> 'a) Et "max max" est de type ('a -> 'a -> 'a) -> ('a -> 'a -> 'a) - Pour que l'expression "max max x" soit bien typée, il faut que "x" soit de type ('a -> 'a -> 'a). Dans ce cas, "max max x" est de type ('a -> 'a ->'a) - Pour que l'expression "max max x y" soit bien typée, il faut que "y" soit de type 'a Dans ce cas, "max max x y" est de type ('a ->'a) - Pour que l'expression "max max x y z" soit bien typée, il faut que "z" soit de type 'a Dans ce cas, "max max x y z" est de type 'a Finalement, max3_fail est de type ('a -> 'a -> 'a) -> 'a -> 'a -> 'a *) (*********************** Question 2 ***********************) let max3 x y z = max (max x y) z;; (******** Tests ********) max3 1 2 3;; max3 (-1) (-2) 3;; max3 10 2 (-103);; max3 1. 20. (-3.5);; (*********************** Question 3 ***********************) let max3_fail_bis a b c = max a (max b) c;; (* Pour que l'expression (max a) soit bien typée on doit avoir: "max" de type 'a -> 'a -> 'a "a" de type 'a "max a" de type 'a -> 'a Pour que l'expression (max b) soit bien typée on doit avoir: "max" de type 'b -> 'b -> 'b "b" de type 'b "max b" de type 'b -> 'b Pour que l'expression (max a (max b)) soit bien typée, on doit avoir: 'a = 'b -> 'b (max a (max b)) de type 'b -> 'b Pour que l'expression (max a (max b) c) soit bien typée, on doit avoir: "c" de type 'b (max a (max b) c) de type 'b Finalement, max3_fail_bis est de type: ('b -> 'b) -> 'b -> 'b -> 'b En renommant, max3_fail_bis est de type: ('a -> 'a) -> 'a -> 'a -> 'a *)