(* ouverture du module Ast.cmi *)
open Ast
(* transforme un arbre en chaine lisible *)
let rec pretty_print res = match res with
Atom(s) -> "`" ^ s
|Not(e) -> "NON(" ^ pretty_print(e) ^ ")"
|And(e1,e2) -> "(" ^ pretty_print(e1) ^ " ET " ^ pretty_print(e2) ^ ")"
|Or(e1,e2) -> "(" ^ pretty_print(e1) ^ " OU " ^ pretty_print(e2) ^ ")"
|Imp(e1,e2) -> "(" ^ pretty_print(e1) ^ " IMPLIQUE " ^ pretty_print(e2) ^ ")"
|Eq(e1,e2) -> "(" ^ pretty_print(e1) ^ " EQUIVALENT " ^ pretty_print(e2) ^ ")"
(* transforme un arbre en arbre disjonctif *)
let rec disj a = match a with
Atom(s) -> Atom(s)
|Not(Atom(s)) -> Not(Atom(s))
|Not(Not(e)) -> disj(e)
|Not(And(e1,e2)) -> Or( disj(Not(disj(e1))) , disj(Not(disj(e2))) )
|Not(Or(e1,e2)) -> disj(And( disj(Not(disj(e1))) , disj(Not(disj(e2))) ))
|Not(e1) -> disj(Not(disj(e1)))
|And(Atom(s1),Atom(s2)) -> And(Atom(s1),Atom(s2))
|And(Or(e1,e2),e3) -> Or( disj(And(disj(e1),disj(e3))) , disj(And(disj(e2),disj(e3))) )
|And(e3,Or(e1,e2)) -> Or( disj(And(disj(e1),disj(e3))) , disj(And(disj(e2),disj(e3))) )
|And(e1,e2) -> And(disj(e1),disj(e2))
|Imp(e1,e2) -> Or( disj(Not(disj(e1))) , (disj(e2)) )
|Eq(e1,e2) -> Or( disj(And((disj(e1)),(disj(e2)))) , disj(And((disj(Not(disj(e1)))),(disj(Not(disj(e2)))))) )
|Or(e1,e2) -> Or(disj(e1),disj(e2))
(* transforme un arbre disjonctif en liste *)
let rec tree_to_list a = match a with
Atom(s) -> s::[]
|Or(e1,e2) -> (tree_to_list(e1))@(tree_to_list(e2))
|And(e1,e2) -> ((tree_to_list(e1))@(tree_to_list(e2)))
|Not(Atom(s1)) -> ("!" ^ s1) :: []
(* cherche si l'inverse (conjugué) de e est dans l2 *)
let rec inv_in e l2 = match l2 with
[] -> false
|h::t when (h = ("!" ^ e)) or (("!" ^ h) = e) -> true
|h::t -> inv_in e t
(* vérifie si la sous liste est satisfiable *)
let rec sat2 l = match l with
[] -> false
|h::t when inv_in h t -> false
|h::t -> sat2(t)
(* vérifie si la liste de liste est satisfiable *)
let rec satisfiable l = match l with
[] -> false
|h::t when sat2(h) = false -> satisfiable(t)
|h::t when sat2(h) = true -> true
(* programme principal *)
let _ =
try
(* ouverture du channel sur l'entree standard stdin *)
let lexbuf =
Lexing.from_channel stdin
in
(* boucle sur les expressions *)
while true do
(* result contient l'arbre obtenu *)
let result = Parser.main Lexer.token lexbuf in
(* Affichage du résultat *)
print_string ("resultat en toutes lettres : " ^ (pretty_print result));
print_string "\n";
print_string "forme disjonctive : " ;
print_string (pretty_print(disj(result))) ;
print_string "\n" ;
print_string "expression satisfiable : " ;
if satisfiable(tree_to_list(disj(result))) = true then print_string "OUI"
else print_string "NON";
print_string "\n" ;
done
(* le lexer leve l'exception Lexer.Eof lorsque la fin de fichier est
atteinte (Ctrl D sur l'entree standard) *)
with Lexer.Eof -> exit 0