(* Specifications: *)
Lemma R1_lem : forall t : nat, (* R1(t)[0:n-1-t]=B[t:n-1] *) t <= size -> truncbv (R1 t) (size - t) = stripbv V1 t.
Lemma R1_lem3 : forall t : nat, (* R1(t)[0]=B[t] *) t < size -> abit (R1 t) 0 = abit V1 t.
Lemma lem_le_minus_v1_Sn : forall n : nat, S n <= size -> n <= size -> size - S n <= lengthbv (appbv (highs (R1 n)) (consbv (lowbit (R2 n)) nilbv)).
Lemma BV_to_nat_lem0 : forall v : BV, lengthbv v <> 0 -> BV_to_nat v = BV_to_nat (consbv (lowbit v) nilbv) + power2 1 * BV_to_nat (highs v).
Lemma BV_nat_lem1 : forall (v : BV) (n : nat), lengthbv v <> 0 -> power2 n * BV_to_nat (consbv (lowbit v) nilbv) + power2 (S n) * BV_to_nat (highs v) = power2 n * BV_to_nat v.
Lemma Invariant_t_O : BV_to_nat (appbv (stripbv (R1 0) size) (R2 0)) = BV_to_nat V2 * BV_to_nat (truncbv V1 0).
Lemma inv_ind_false : forall t n : nat, (n <= size -> BV_to_nat (appbv (stripbv (R1 n) (size - n)) (R2 n)) = BV_to_nat V2 * BV_to_nat (truncbv V1 n)) -> S n <= size -> n <= size -> BV_to_nat (appbv (stripbv (appbv (highs (R1 n)) (Mux false (abit (BV_full_adder_sum (R2 n) V2 false) 0) (consbv (lowbit (R2 n)) nilbv))) (size - S n)) (appbv (highs (Mux false (BV_full_adder_sum (R2 n) V2 false) (R2 n))) (Mux false (consbv (BV_full_adder_carry (R2 n) V2 false) nilbv) (consbv false nilbv)))) = BV_to_nat V2 * BV_to_nat (appbv (truncbv V1 n) (consbv false nilbv)).
Lemma inv_ind_true : forall t n : nat, (n <= size -> BV_to_nat (appbv (stripbv (R1 n) (size - n)) (R2 n)) = BV_to_nat V2 * BV_to_nat (truncbv V1 n)) -> S n <= size -> n <= size -> BV_to_nat (appbv (stripbv (appbv (highs (R1 n)) (Mux true (abit (BV_full_adder_sum (R2 n) V2 false) 0) (consbv (lowbit (R2 n)) nilbv))) (size - S n)) (appbv (highs (Mux true (BV_full_adder_sum (R2 n) V2 false) (R2 n))) (Mux true (consbv (BV_full_adder_carry (R2 n) V2 false) nilbv) (consbv false nilbv)))) = BV_to_nat V2 * BV_to_nat (appbv (truncbv V1 n) (consbv true nilbv)).
Lemma Invariant : forall t : nat, t <= size -> BV_to_nat (appbv (stripbv (R1 t) (size - t)) (R2 t)) = BV_to_nat V2 * BV_to_nat (truncbv V1 t).
Theorem Correct : BV_to_nat (appbv (R1 size) (R2 size)) = BV_to_nat V2 * BV_to_nat V1.
Lemma plus_n_SO : forall x : nat, x + 1 = S x.
Lemma plus_permute2 : forall x y z : nat, x + y + z = x + z + y.
Lemma mult_sym : forall a b : nat, a * b = b * a.
Lemma mult_permute : forall a b c : nat, a * b * c = a * c * b.
Lemma plus_O_O : forall n m : nat, n + m = 0 -> n = 0.
Lemma mult_plus_distr2 : forall n m p : nat, n * (m + p) = n * m + n * p.
Lemma length_eq1 : length (nil:list A) = 0.
Lemma length_eq2 : forall (x : A) (l : list A), length (x :: l) = S (length l).
Lemma app_eq1 : forall l' : list A, nil ++ l' = l'.
Lemma app_eq2 : forall (x : A) (l l' : list A), (x :: l) ++ l' = x :: l ++ l'.
Lemma neg_eq : forall a b : bool, negb a = negb b -> a = b.
Lemma false_to_true : false = negb true.
Lemma true_to_false : true = negb false.
Lemma BV_full_adder_nil_true_ok : forall v : BV, BV_to_nat (BV_full_adder v nilbv true) = S (BV_to_nat v).
Lemma BV_full_adder_nil_ok : forall (v : BV) (cin : bool), BV_to_nat (BV_full_adder v nilbv cin) = BV_to_nat v + bool_to_nat cin.
Theorem BV_full_adder_ok : forall (v w : BV) (cin : bool), BV_to_nat (BV_full_adder v w cin) = BV_to_nat v + BV_to_nat w + bool_to_nat cin.