(****************************************************************)

(* Pourquoi ne peut-on ecrire ceci: ? *)
(*Recursive Definition BV_full_adder_sum : BV -> BV -> bool -> BV :=
utiliser le type BV en parties gauches ????????? UN BUG DE COQ ??????????
*)
(*Recursive Definition BV_full_adder_sum: (list bool)->(list bool)->bool->BV :=
    (nil bool) (nil bool) b => nilbv
  | (nil bool) (cons bool vh vt) b =>
	   (consbv (half_adder_sum vh b)
		   (BV_full_adder_sum (nil bool) vt (half_adder_carry vh b)))
  | (cons bool vh vt) (nil bool) b =>
	   (consbv (half_adder_sum vh b)
		   (BV_full_adder_sum vt (nil bool) (half_adder_carry vh b)))
  | (cons bool vh vt) (cons bool wh wt) b =>
	    (consbv (full_adder_sum vh wh b)
		    (BV_full_adder_sum vt wt (full_adder_carry vh wh b))).
*)

Definition BV_full_adder_sum :=
  (fix F (l : list bool) : list bool -> bool -> BV :=
     match l with
     | nil =>
         (fix F0 (l0 : list bool) : bool -> BV :=
            match l0 with
            | nil => fun _ : bool => nilbv
            | b :: l1 =>
                fun z : bool =>
                consbv (half_adder_sum b z) (F0 l1 (half_adder_carry b z))
            end)
     | b :: l0 =>
         fun x2 : list bool =>
         match x2 with
         | nil =>
             fun y z : bool =>
             consbv (half_adder_sum y z) (F l0 nil (half_adder_carry y z))
         | b0 :: l1 =>
             fun y z : bool =>
             consbv (full_adder_sum y b0 z)
               (F l0 l1 (full_adder_carry y b0 z))
         end b
     end).

Lemma BV_full_adder_sum_eq2 : forall (vh : bool) (vt : list bool) (b : bool), BV_full_adder_sum nil (vh :: vt) b = consbv (half_adder_sum vh b) (BV_full_adder_sum nil vt (half_adder_carry vh b)).