>];;
unjoinables ["0"; "1"; "+"; "*"] eqs;;
(* ------------------------------------------------------------------------- *)
(* Translation to propositional logic. *)
(* ------------------------------------------------------------------------- *)
let rec prop_of_boolterm tm =
match tm with
Fn("+",[p;q]) -> Not(Iff(prop_of_boolterm p,prop_of_boolterm q))
| Fn("*",[p;q]) -> And(prop_of_boolterm p,prop_of_boolterm q)
| Fn("0",[]) -> False
| Fn("1",[]) -> True
| Var x -> Atom(R(x,[]));;
let prop_of_bool (Atom(R("=",[s;t]))) =
Iff(prop_of_boolterm s,prop_of_boolterm t);;
forall tautology (map prop_of_bool eqs);;
END_INTERACTIVE;;
(* ------------------------------------------------------------------------- *)
(* Translation back. *)
(* ------------------------------------------------------------------------- *)
let rec bool_of_prop fm =
match fm with
False -> Fn("0",[])
| True -> Fn("1",[])
| Atom(R(p,[])) -> Fn(p,[])
| Not(p) -> Fn("+",[bool_of_prop p; Fn("1",[])])
| And(p,q) -> Fn("*",[bool_of_prop p; bool_of_prop q])
| Or(p,q) -> let p' = bool_of_prop p and q' = bool_of_prop q in
Fn("+",[p'; Fn("+",[q'; Fn("*",[p';q'])])])
| Imp(p,q) -> bool_of_prop(Or(Not p,q))
| Iff(p,q) -> let p' = bool_of_prop p and q' = bool_of_prop q in
Fn("+",[p'; Fn("+",[q'; Fn("1",[])])]);;
(* ------------------------------------------------------------------------- *)
(* Canonical simplifier for Boolean rings. *)
(* ------------------------------------------------------------------------- *)
START_INTERACTIVE;;
let ord =
let w f g =
match (f,g) with
(("*",2),("+",2)) -> true
| ((_,2),(_,0)) -> true
| ((s,0),(s',0)) -> s > s'
| _ -> false in
lpo_gt w;;
let boolnorm =
depth(orewrite ord (itlist (tryorient ord) eqs ([],[])));;
(* ------------------------------------------------------------------------- *)
(* Examples. *)
(* ------------------------------------------------------------------------- *)
boolnorm (bool_of_prop <>);;
boolnorm (bool_of_prop <<(p ==> q) \/ (q ==> p)>>);;
boolnorm (bool_of_prop <
q \/ (p <=> q)>>);;
(* ------------------------------------------------------------------------- *)
(* 4.5: Groups of exponent two *)
(* ------------------------------------------------------------------------- *)
let eqs =
[<<(x * y) * z = x * y * z>>;
<>;
<>;
<>;
<>;
<>;
<<1 * x = x>>];;
unjoinables ["1"; "*"] eqs;;
(* ------------------------------------------------------------------------- *)
(* 4.7: Distributivity. *)
(* ------------------------------------------------------------------------- *)
let eqs =
[<<(x * y) * z = x * y * z>>;
<>;
<>;
<>;
<<(x + y) * z = x * z + y * z>>];;
unjoinables ["+"; "*"] eqs;;
END_INTERACTIVE;;