let rec process_layer_elem unif_std unif_nonstd vi vi_ctrs xor_eqns rem_ls
ctr (tas : t_subst list) (failed : t_subst list) =
function
| (std_ls,fv,_ as std_sub)::tail ->
(try
(* Pre Identification, i.e. identify variables that have already the
* same value, i.e. identify x and y where egal returns true.
*
* pre_identification raises Invalid_Var_Identif, if this var
* identification is not allowed, according to vi_ctrs. *)
let var_identif = pre_identification vi_ctrs std_ls vi
in
(* Add the constraints for the pre identification to xor_eqns, i.e.
* if x and y are identified, add 0 = x + y to xor_eqns. *)
let xor_eqns = add_identification_ctr_xor xor_eqns var_identif
in
(* Pre Choice of Theory.
* Possibly raises No_Solution. *)
let (std_vars, xor_vars, uncertain_vars) =
pre_choice_of_thy xor_eqns std_ls (reps var_identif)
in
(* Choice of Theory.
* choose_theory generates a list of all possibilities. *)
let choices_of_theory = choose_theory std_vars xor_vars uncertain_vars
in
(* Solve the xor problem with the choices of theories.
* If we can compute a substitution for at least one choice of theory,
* we know that all subst for other choices of theories are equivalent.
* So, just keep one.
*
* Possibly raises No_Solution or Invalid_Var_Identif. *)
let sub = solve_xor_eqns_choices unif_nonstd false
(std_ls,xor_eqns,rem_ls,fv,ctr) var_identif vi_ctrs choices_of_theory
in
(* add sub to tas and proceed with tail *)
process_layer_elem unif_std unif_nonstd
vi vi_ctrs xor_eqns rem_ls ctr (sub::tas) failed tail
with
| Invalid_Var_Identif ->
(* This variable identification is invalid for std_sub and vi_ctrs *)
(* just skip this vi for this std_sub and proceed with tail *)
process_layer_elem unif_std unif_nonstd
vi vi_ctrs xor_eqns rem_ls ctr tas failed tail
| No_Solution ->
process_layer_elem unif_std unif_nonstd
vi vi_ctrs xor_eqns rem_ls ctr tas (std_sub::failed) tail
)
| [] -> (tas,failed)