(* This file was originally generated by why.
   It can be modified; only the generated parts will be overwritten. *)

Require Export Malcolm_spec_why.
Require Export WhyFloats.
Require Export Veltkamp.



(* Why obligation from file "/users/demons/ayad/ppc/why/examples-c/float/Malcolm.c", line 8, characters 13-17: *)
(*Why goal*) Lemma malcolm1_impl_po_1 : 
  forall (A: double),
  forall (HW_2: A = (r_to_d nearest_even (IZR 2))),
  (* CADUCEUS_4 *) (* CADUCEUS_4 *) (eq (d_to_r A) (IZR 2)).
Proof.
intros.
rewrite HW_2;auto with zarith real.
Save.

(* Why obligation from file "/users/demons/ayad/ppc/why/examples-c/float/Malcolm.c", line 10, characters 16-72: *)
(*Why goal*) Lemma malcolm1_impl_po_2 : 
  forall (A: double),
  forall (HW_2: A = (r_to_d nearest_even (IZR 2))),
  forall (HW_3: (* CADUCEUS_4 *) (eq (d_to_r A) (IZR 2))),
  (* CADUCEUS_2 *) ((eq (d_to_r A) (powerRZ (IZR 2) (my_log (d_to_r A)))) /\
  1 <= (my_log (d_to_r A)) /\ (my_log (d_to_r A)) <= 53).
Proof.
intros.
rewrite HW_3.
replace (my_log 2%Z) with 1%Z.
split; auto with real zarith.
unfold Rpower; simpl.
ring (1*ln 2)%R; rewrite exp_ln; auto with real.
apply sym_eq; apply my_log_correct.
unfold Rpower; simpl.
ring (1*ln 2)%R; rewrite exp_ln; auto with real.
Save.

(* Why obligation from file "/users/demons/ayad/ppc/why/examples-c/float/Malcolm.c", line 10, characters 16-72: *)
(*Why goal*) Lemma malcolm1_impl_po_3 : 
  forall (A: double),
  forall (HW_2: A = (r_to_d nearest_even (IZR 2))),
  forall (HW_3: (* CADUCEUS_4 *) (eq (d_to_r A) (IZR 2))),
  forall (A0: double),
  forall (HW_4: (* CADUCEUS_2 *)
                ((eq (d_to_r A0) (powerRZ (IZR 2) (my_log (d_to_r A0)))) /\
                1 <= (my_log (d_to_r A0)) /\ (my_log (d_to_r A0)) <= 53)),
  forall (HW_5: ~(eq (d_to_r A0) (d_to_r
                                  (add_double
                                   nearest_even A0 (r_to_d
                                                    nearest_even (IZR 1)))))),
  forall (A1: double),
  forall (HW_6: A1 =
                (mul_double nearest_even A0 (r_to_d nearest_even (IZR 2)))),
  (* CADUCEUS_2 *)
  ((eq (d_to_r A1) (powerRZ (IZR 2) (my_log (d_to_r A1)))) /\ 1 <=
  (my_log (d_to_r A1)) /\ (my_log (d_to_r A1)) <= 53).
Proof.
intros.
unfold Zwf.
assert (d_to_r A1 = Rpower (Zpos 2) (my_log (d_to_r A0) + 1)%Z).
rewrite plus_IZR; elim HW_5; intros H1 H2; rewrite Rpower_plus; rewrite <- H1.
rewrite Rpower_1; auto with real zarith.
clear HW_2 HW_3 HW_4 HW_5 HW_6 H1 H2.
unfold d_to_r; destruct A0; destruct A1; simpl.
inversion HW_7.
replace (FtoRradix (RND_EvenClosest bdouble radix 53 2)) with 2%R;[idtac|auto].
assert (FtoRradix (Float (Fnum df) (Fexp df+1)) = df*2)%R.
unfold FtoRradix, FtoR; simpl.
rewrite powerRZ_add; auto with zarith real; simpl; ring.
rewrite <- H; unfold FtoRradix.
apply RoundedModeProjectorIdemEq with bdouble 53%nat 
  (EvenClosest bdouble radix 53); [auto with zarith|
    auto with zarith|auto with zarith|auto with zarith|idtac|idtac].
apply FcanonicBound with radix; auto with real zarith.
assert (Fbounded bdouble (Float (Fnum df) (Fexp df + 1))).
assert (H3:Fbounded bdouble df); auto with zarith.
elim H3; intros.
split; auto with zarith.
apply Zle_trans with (1:=H5); simpl; auto with zarith.
generalize EvenClosestUniqueP; unfold UniqueP; intros T.
rewrite T with bdouble radix 53%nat (FtoR radix (Float (Fnum df) (Fexp df + 1)))
    (RND_EvenClosest bdouble radix 53
           (FtoR radix (Float (Fnum df) (Fexp df + 1))))
    (Float (Fnum df) (Fexp df + 1)); auto with zarith; clear T.
apply RoundedModeProjectorIdem with (P:=EvenClosest bdouble radix 53) (b:=bdouble); 
  auto with zarith.
apply RoundedModeProjectorIdem with (P:=EvenClosest bdouble radix 53) (b:=bdouble); 
  auto with zarith.
cut (my_log (d_to_r A1)=my_log (d_to_r A0)+1)%Z; [intros H1| apply my_log_correct; auto].
rewrite H1.
repeat split; auto with zarith.
case (Zle_or_lt (my_log(d_to_r A0)) 52); auto with zarith.
intros H2; Contradict HW_6.
assert (my_log(d_to_r A0)= 53); auto with zarith.
unfold add_double, r_to_d_aux, d_to_r; simpl.
replace (FtoRradix (df A0)) with (Rpower (Zpos 2) (Zpos 53)).
2: elim HW_5; rewrite H0; intros H3 H4; rewrite <- H3.
2: unfold d_to_r; auto with real.
replace (FtoRradix (RND_EvenClosest bdouble radix 53 1)) with 1%R;[idtac|auto].
assert (Rpower (Zpos 2) (Zpos 53)=Float (Zpower_nat radix 52) 1).
unfold Rpower; rewrite Rmult_comm; rewrite exp_ln_powerRZ; auto with zarith.
unfold FtoRradix, FtoR.
apply trans_eq with ((Zpower_nat radix 52)*powerRZ radix 1)%R; auto.
rewrite Zpower_nat_Z_powerRZ.
rewrite <- powerRZ_add; auto with real zarith.
exact bdouble.
exact radix.
exact O.
assert (Fcanonic radix bdouble (Float (Zpower_nat radix 52) 1)).
left; split;[split|idtac].
rewrite pdGivesBound; apply Zle_lt_trans with (Zpower_nat radix 52);
  auto with zarith.
simpl; auto with zarith.
rewrite pdGivesBound; apply Zle_trans with (Zabs (radix *(Zpower_nat radix 52)));
  auto with zarith.
rewrite H3; generalize EvenClosestUniqueP; unfold UniqueP; intros T.
unfold FtoRradix; apply T with bdouble 53%nat (Float 1 53 + 1)%R; auto with zarith.
clear T; split.
apply ImplyClosest with 53%nat 1; auto with zarith.
replace (1 + S 52 - 1)%Z with 53%Z; auto with zarith.
apply Rle_trans with (powerRZ radix 53+0)%R;[right; ring
    |apply Rplus_le_compat; auto with real].
unfold FtoRradix, FtoR; simpl; auto with real.
replace (1 + S 52 - 1)%Z with 53%Z; auto with zarith.
right; apply trans_eq with ((Zpower_nat radix 52)*(powerRZ radix 1))%R.
rewrite Zpower_nat_Z_powerRZ; rewrite <- powerRZ_add; auto with real zarith.
unfold FtoR.
apply trans_eq with (Zpower_nat radix 52*
    powerRZ radix (Fexp (Float (Zpower_nat radix 52) 1)))%R; auto.
replace  (FtoR radix (Float (Zpower_nat radix 52) 1)) with
   (powerRZ radix 53).
replace  (Float 1 53 + 1 - powerRZ radix 53)%R with 1%R.
rewrite Rabs_right; auto with real.
simpl; right; field; auto with real.
apply Rle_ge; auto with real.
unfold FtoR; apply trans_eq with (1*powerRZ radix 53 + 1 - powerRZ radix 53)%R;
  auto; ring.
apply trans_eq with ((Zpower_nat radix 52)*(powerRZ radix 1))%R.
rewrite Zpower_nat_Z_powerRZ; rewrite <- powerRZ_add; auto with real zarith.
unfold FtoR.
apply trans_eq with (Zpower_nat radix 52*
    powerRZ radix (Fexp (Float (Zpower_nat radix 52) 1)))%R; auto.
left.
unfold FNeven; rewrite FcanonicFnormalizeEq; auto with zarith.
unfold Feven, Even; exists (Zpower_nat radix 51).
simpl; auto with zarith.
replace   (FtoR radix (Float (Zpower_nat radix 52) 1) + 1)%R
  with (Float 1 53 + 1)%R; auto with zarith.
replace  (FtoR radix (Float (Zpower_nat radix 52) 1)) with
   (powerRZ radix 53); auto with real.
unfold FtoRradix, FtoR; auto with real.
apply trans_eq with ((Zpower_nat radix 52)*(powerRZ radix 1))%R.
rewrite Zpower_nat_Z_powerRZ; rewrite <- powerRZ_add; auto with real zarith.
unfold FtoR.
apply trans_eq with (Zpower_nat radix 52*
    powerRZ radix (Fexp (Float (Zpower_nat radix 52) 1)))%R; auto.
Save.

(* Why obligation from file "/users/demons/ayad/ppc/why/examples-c/float/Malcolm.c", line 12, characters 15-27: *)
(*Why goal*) Lemma malcolm1_impl_po_4 : 
  forall (A: double),
  forall (HW_2: A = (r_to_d nearest_even (IZR 2))),
  forall (HW_3: (* CADUCEUS_4 *) (eq (d_to_r A) (IZR 2))),
  forall (A0: double),
  forall (HW_4: (* CADUCEUS_2 *)
                ((eq (d_to_r A0) (powerRZ (IZR 2) (my_log (d_to_r A0)))) /\
                1 <= (my_log (d_to_r A0)) /\ (my_log (d_to_r A0)) <= 53)),
  forall (HW_5: ~(eq (d_to_r A0) (d_to_r
                                  (add_double
                                   nearest_even A0 (r_to_d
                                                    nearest_even (IZR 1)))))),
  forall (A1: double),
  forall (HW_6: A1 =
                (mul_double nearest_even A0 (r_to_d nearest_even (IZR 2)))),
  (Zwf 0 ((* CADUCEUS_3 *) (53 - (my_log (d_to_r A1)))) ((* CADUCEUS_3 *)
                                                        (53 -
                                                        (my_log (d_to_r A0))))).
Proof.
intros.
elim HW_5; intros.
rewrite H; replace (my_log (d_to_r A0)) with 53%Z; auto with real.
case (Zle_or_lt 53 (my_log (d_to_r A0))); auto with zarith.
intros H1; Contradict HW_8.
rewrite H; replace (d_to_r (add_double nearest_even A0 
  (r_to_d nearest_even (Zpos 1)))) with (Rpower (Zpos 2) (my_log (d_to_r A0))+1)%R;
   auto with real.
unfold d_to_r, add_double; simpl.
replace (FtoRradix (RND_EvenClosest bdouble radix 53 1)) with 1%R;auto.
destruct A0; simpl.
unfold d_to_r in HW_5, H, H0, H1; simpl in HW_5, H, H0, H1.
assert (exists df':float, Fbounded bdouble df' /\(Fexp df'=0) /\ (FtoRradix df'=df)).
exists (Float (Zpower_nat radix (Zabs_nat (my_log df))) 0).
split;split.
rewrite pdGivesBound; simpl.
rewrite Zabs_eq; auto with zarith.
assert  (Zabs_nat (my_log df) < 53)%nat; auto with zarith.
assert  (Zabs_nat (my_log df) < 53)%Z; auto with zarith.
rewrite <- Zabs_absolu; rewrite Zabs_eq; auto with zarith.
simpl; auto with zarith.
simpl; auto with zarith.
pattern (FtoRradix df) at 2; rewrite H; unfold Rpower; rewrite Rmult_comm.
replace 2%R with (IZR 2); auto with real; rewrite exp_ln_powerRZ; auto with zarith.
unfold FtoRradix at 1; unfold FtoR; simpl; 
  rewrite Zpower_nat_Z_powerRZ; auto with real zarith.
rewrite <- Zabs_absolu; rewrite Zabs_eq; auto with zarith real.
exact bdouble.
exact radix.
exact O.
elim H2; intros df' T;elim T;clear H2; intros H2 T'; elim T'; intros H3 H4; clear T T'.
rewrite <- H4.
elim FboundNext with radix bdouble 53%nat df'; auto with zarith.
intros f T; elim T; intros H5 H6; clear T.
apply trans_eq with (FtoR radix f); [rewrite H6| idtac].
rewrite H4; rewrite <- H; rewrite <- H4.
unfold FtoRradix, FtoR, Zsucc; simpl.
rewrite plus_IZR; simpl; ring.
rewrite H3; simpl; ring.
unfold FtoRradix.
apply RoundedModeProjectorIdemEq with bdouble 53%nat (EvenClosest bdouble radix 53);
   auto with zarith.
replace  (FtoR radix f) with (FtoR radix df' + 1)%R; auto with zarith.
rewrite H6; unfold FtoR, Zsucc; simpl; rewrite plus_IZR; simpl.
rewrite H3; ring.
Save.

(* Why obligation from file "/users/demons/ayad/ppc/why/examples-c/float/Malcolm.c", line 3, characters 12-32: *)
(*Why goal*) Lemma malcolm1_impl_po_5 : 
  forall (A: double),
  forall (HW_2: A = (r_to_d nearest_even (IZR 2))),
  forall (HW_3: (* CADUCEUS_4 *) (eq (d_to_r A) (IZR 2))),
  forall (A0: double),
  forall (HW_4: (* CADUCEUS_2 *)
                ((eq (d_to_r A0) (powerRZ (IZR 2) (my_log (d_to_r A0)))) /\
                1 <= (my_log (d_to_r A0)) /\ (my_log (d_to_r A0)) <= 53)),
  forall (HW_7: (eq (d_to_r A0) (d_to_r
                                 (add_double
                                  nearest_even A0 (r_to_d
                                                   nearest_even (IZR 1)))))),
  (* CADUCEUS_1 *) (eq (d_to_r A0) (powerRZ (IZR 2) 53)).
Proof.
intuition.
(* FILL PROOF HERE *)
Save.

