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
      | _      ->
          (* we have to introduce a new variable *)
          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
      | _      ->
          (* we have to introduce a new variable *)
          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)) ->
      (* u has to be standard and is not a variable *)
      if to_purify then
        (* purify u and v if necessary *)
        let (u2,sub2) = purify sub  u in
        let (v2,sub3) = purify sub2 v in
        (* Call purify_pair again, this time with to_purify = false. This is
         * necessary because u or v could have changed their topsymbol. *)

        purify_pair false sub3 (u2,v2)
      else
        (* we know that u is standard and v not, so replace v by a new variable
         * x, add x -> v to the substitution and return (x,u) *)

        let (newvar,sub) = add_newvalue sub v in
        (newvar, u, sub)
  | (u,v) ->
      (* u and v are both standard or variables *)
      if to_purify then
        (* purify u and v if necessary *)
        let (u,sub) = purify sub u in
        let (v,sub) = purify sub v in
        (* Call purify_pair again, this time with to_purify = false. This is
         * necessary because u or v could have changed their topsymbol. *)

        purify_pair false sub (u,v)
      else
        (u, v, sub)