let unif_combi
unif_std
unif_nonstd
(to_purify : bool )
(u : term )
(v : term )
(subs : t_subst list)
: t_subst list =
let rec unif_combi_help (tas : t_subst list) : t_subst list -> t_subst list =
function
| sub::tail ->
(* Purify u2 and v2. It is also ensured that they are of the same theory
* afterwards.
* If they are in the xor theory, at least one of them is Atm(0). *)
let (u2,v2,sub) = purify_pair to_purify sub (u,v)
in
(* Split the substitution into three parts, std_ls, xor_eqns and rem_ls.
*)
let (u2,v2,(std_ls,xor_eqns,rem_ls,fv,ctr),std_vars,xor_vars) =
split_subst sub u2 v2
in
(* shared_vars are the variables that occur in std_ls and xor_ls at the
* same time *)
let shared_vars = intersection std_vars xor_vars
in
(* If u2 and v2 are standard std_subs is the result of unifing u2 and v2
* with the unif_std. Otherwise std_subs is [(std_ls,fv,[])].
*
* xor_eqns contains the remaining xor equations that have to be made
* equal to Atm(0) by unification in the xor theory. *)
let (xor_eqns, std_subs) =
match (u2,v2) with
| (Atm(0),Atm(0)) -> (xor_eqns, [(std_ls,fv,[])])
| (Atm(0),Var(n))
| (Var(n),Atm(0)) ->
(* add 0 = Var(n) to xor_eqns *)
([Var(n)]::xor_eqns, [(std_ls,fv,[])])
| (Atm(0),Xor(l))
| (Xor(l),Atm(0)) ->
(* add 0 = l to xor_eqns *)
(l::xor_eqns, [(std_ls,fv,[])])
| _ ->
(* u2 and v2 are both standard,
* (u2,v2) = (Xor(_),Xor(_)), (Atm(0),t) or (Xor(_),t) with t
* standard cannot appear, due to purify_pair *)
(xor_eqns, unif_std false u2 v2 [(std_ls,fv,[])])
in
(if std_subs = [] then
(* solving the std problem failed, so u and v are not unifiable with
* respect to sub. Proceed with tail. *)
unif_combi_help tas tail
else
(* Start the breadth first search with the most general layer element
* (std_subs,vi,[]), so with the trivial variable identif and without
* layer_ctrs. See comments of process_layer for details.
*
* Add the results to tas. *)
let vi = trivial_part shared_vars
in
let tas2 = process_layer unif_std unif_nonstd xor_eqns rem_ls ctr
[] [] [] tas [(std_subs,vi,[])]
in
(* proceed with tail *)
unif_combi_help tas2 tail
)
| [] -> tas
in
unif_combi_help [] subs