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)