let rec purify_pair (to_purify : bool) (sub : t_subst) (u,v : term * term)
: term * term * t_subst =
match (u,v) with
| (Atm(0), Atm(0)) -> (u, v, sub)
| ((Xor _ as u), (Atm 0 as v))
| ((Atm 0 as v), (Xor _ as u)) ->
let u, sub = if to_purify then purify sub u else u, sub in
(v, u, sub)
| (Xor l1, Xor l2) ->
let t, sub = purify sub (Xor (merge l1 l2))
in
(match t with
| Atm(0)
| Xor(_)
| Var(_) -> Atm(0), t, sub
| _ ->
let (newvar,sub) = add_newvalue sub (Atm(0)) in
newvar, t, sub
)
| ((Xor l ), (Atm _ as w))
| ((Atm _ as w), (Xor l ))
| (Xor l , (Var _ as w))
| ((Var _ as w), Xor l ) ->
let t, sub = purify sub (Xor (w::l))
in
(match t with
| Atm(0)
| Xor(_)
| Var(_) -> Atm(0), t, sub
| _ ->
let (newvar,sub) = add_newvalue sub (Atm(0)) in
newvar, t, sub
)
| ((Atm(0) as v), u )
| (u , (Atm(0) as v))
| ((Xor(_) as v), u )
| (u , (Xor(_) as v)) ->
if to_purify then
let (u2,sub2) = purify sub u in
let (v2,sub3) = purify sub2 v in
purify_pair false sub3 (u2,v2)
else
let (newvar,sub) = add_newvalue sub v in
(newvar, u, sub)
| (u,v) ->
if to_purify then
let (u,sub) = purify sub u in
let (v,sub) = purify sub v in
purify_pair false sub (u,v)
else
(u, v, sub)