(** [triangle a b c] donne la nature d'un triangle de côtés [a], [b] et [c]: * [`Impossible] si aucun triangle n'existe pour ces valeurs, * [`Isocele] si le triangle est possible et isocèle, * [`Equilateral] si le triangle est possible et équilatéral, * [`Quelconque] si le triangle est possible et quelconque. *) let triangle a b c = assert (a>=0 && b>=0 && c>=0) ; if a+b 1 | false -> 0 in let equalities = b2i (a=b) + b2i (a=c) + b2i (b=c) in match equalities with | 0 -> `Quelconque | 1 -> `Isocele | 3 -> `Equilateral | _ -> assert false (** Tests pour [triangle], dans un premier temps sans se soucier des * permutations. *) let tests = [ (* Faire passer *une* inégalité du premier test. *) (1,1,3),`Return `Impossible ; (* Cas limite pour le premier test. *) (6,6,12),`Return `Isocele ; (* Explorer chaque cas pour les b2i (x=y). *) (2,2,1),`Return `Isocele ; (1,1,1),`Return `Equilateral ; (1,2,3),`Return `Quelconque ; (* Violer une égalité de l'assertion. *) (-1,0,0),`Fail ] (** Toutes les permutations des tests précédents. *) let tests = let permute ((a,b,c),r) = if a=b && a=c then [(a,b,c),r] else [ (a,b,c),r ; (a,c,b),r ; (b,c,a),r ; (b,a,c),r ; (c,a,b),r ; (c,b,a),r ] in List.concat (List.map permute tests) let kind_to_string = function | `Impossible -> "Impossible" | `Quelconque -> "Quelconque" | `Equilateral -> "Equilateral" | `Isocele -> "Isocele" (** Ceci n'est PAS un bon environnement de test! *) let () = List.iter (function | ((a,b,c),`Return r) -> Printf.printf "(%d,%d,%d) = %s... %s\n" a b c (kind_to_string r) (if r = triangle a b c then "OK" else "FAIL") | ((a,b,c),`Fail) -> Printf.printf "Fail on (%d,%d,%d)... %s\n" a b c (try ignore (triangle a b c) ; "FAIL" with _ -> "OK")) tests