Library PradixE

Require Export FroundPlus.
Section prog.
Variable b : Fbound.
Variable radix : Z.
Variable precision : nat.

Coercion Local FtoRradix := FtoR radix.
Hypothesis radixMoreThanOne : (1 < radix)%Z.

Let radixMoreThanZERO := Zlt_1_O _ (Zlt_le_weak _ _ radixMoreThanOne).
Hint Resolve radixMoreThanZERO: zarith.
Hypothesis precisionGreaterThanOne : 1 < precision.
Hypothesis pGivesBound : Zpos (vNum b) = Zpower_nat radix precision.
Variable P : R -> float -> Prop.
Hypothesis ProundedMode : RoundedModeP b radix P.

Let Cp := RoundedModeP_inv2 b radix P ProundedMode.
Variable fplus : float -> float -> float.
Variable fminus : float -> float -> float.
Variable fmult : float -> float -> float.
Hypothesis
  fplusCorrect :
    forall p q : float, Fbounded b p -> Fbounded b q -> P (p + q) (fplus p q).
Hypothesis
  fminusCorrect :
    forall p q : float,
    Fbounded b p -> Fbounded b q -> P (p - q) (fminus p q).
Hypothesis
  fmultCorrect :
    forall p q : float, Fbounded b p -> Fbounded b q -> P (p * q) (fmult p q).
Variables f0 f1 f2 : float.
Variable f0Bounded : Fbounded b f0.
Variable f0Correct : f0 = 0%Z :>R.
Variable f1Bounded : Fbounded b f1.
Variable f1Correct : f1 = 1%Z :>R.
Variable f2Bounded : Fbounded b f2.
Variable f2Correct : f2 = 2%Z :>R.

Theorem Loop0 :
 forall p : float,
 Fbounded b p ->
 forall n : Z,
 (1 <= n)%Z ->
 (n <= pPred (vNum b))%Z -> p = n :>R -> fplus p f1 = (p + f1)%R :>R.

Theorem Loop1 :
 forall p : float,
 Fbounded b p ->
 forall n : Z,
 (Zpos (vNum b) <= n)%Z ->
 (n <= radix * pPred (vNum b))%Z ->
 p = n :>R -> fplus p f1 = p :>R \/ fplus p f1 = (p + radix)%R :>R.

Theorem Loop2 :
 forall p : float,
 Fbounded b p ->
 forall n : Z,
 (1 <= n)%Z ->
 (n <= pPred (vNum b))%Z -> p = n :>R -> fminus (fplus p f1) p = f1 :>R.

Theorem Loop3 :
 forall p : float,
 Fbounded b p ->
 forall n : Z,
 (Zpos (vNum b) <= n)%Z ->
 (n <= radix * pPred (vNum b))%Z ->
 p = n :>R -> fminus (fplus p f1) p <> f1 :>R.

Theorem Loop4 :
 forall p : float,
 Fbounded b p ->
 forall n : Z,
 (1 <= n)%Z -> (n <= pPred (vNum b))%Z -> p = n :>R -> (p < fmult f2 p)%R.

Theorem BLoop1 :
 forall p q : float,
 Fbounded b p ->
 Fbounded b q ->
 forall m n : Z,
 (Zpower_nat radix precision <= m)%Z ->
 (m <= radix * pPred (vNum b))%Z ->
 p = m :>R ->
 (1 <= n)%Z ->
 (n < radix)%Z ->
 q = n :>R -> fplus p q = p :>R \/ fplus p q = (p + radix)%R :>R.

Theorem BLoop2 :
 forall p q : float,
 Fbounded b p ->
 Fbounded b q ->
 forall m n : Z,
 (Zpower_nat radix precision <= m)%Z ->
 (m <= radix * pPred (vNum b))%Z ->
 p = m :>R ->
 (1 <= n)%Z -> (n < radix)%Z -> q = n :>R -> fminus (fplus p q) p <> q :>R.

Theorem BLoop3 :
 forall p q : float,
 Fbounded b p ->
 Fbounded b q ->
 forall m : Z,
 (Zpower_nat radix precision <= m)%Z ->
 (m <= radix * pPred (vNum b))%Z ->
 p = m :>R -> q = radix :>R -> fminus (fplus p q) p = q :>R.

Theorem BLoop4 :
 forall p : float,
 Fbounded b p ->
 forall n : Z,
 (1 <= n)%Z -> (n < radix)%Z -> p = n :>R -> (p < fplus p f1)%R.

Lemma Loop6c :
 forall p b0 : float,
 Fbounded b p ->
 forall n : Z,
 (1 <= n)%Z ->
 (n <= pPred (vNum b))%Z ->
 p = n :>R -> Fbounded b b0 /\ b0 = radix :>R -> (p < fmult p b0)%R.

Let feq := Feq_bool radix.


Theorem Goal1 :
 forall (x0 : float)
   (Pre2 : (exists m : Z,
              (1 <= m)%Z /\ (m <= radix * pPred (vNum b))%Z /\ x0 = m :>R) /\
           Fbounded b x0) (Test1 : feq (fminus (fplus x0 f1) x0) f1 = true),
 Zabs_nat (radix * pPred (vNum b) - Int_part (fmult f2 x0)) <
 Zabs_nat (radix * pPred (vNum b) - Int_part x0) /\
 ex
   (fun m : Z =>
    (1 <= m)%Z /\ (m <= radix * pPred (vNum b))%Z /\ fmult f2 x0 = m :>R) /\
 Fbounded b (fmult f2 x0).

Theorem Goal2 :
 forall (x0 : float)
   (Pre2 : ex
             (fun m : Z =>
              (1 <= m)%Z /\ (m <= radix * pPred (vNum b))%Z /\ x0 = m :>R) /\
           Fbounded b x0) (Test1 : feq (fminus (fplus x0 f1) x0) f1 = false),
 ex
   (fun m : Z =>
    (Zpower_nat radix precision <= m)%Z /\
    (m <= radix * pPred (vNum b))%Z /\ x0 = m :>R) /\
 Fbounded b x0.

Theorem Goal3 :
 ex
   (fun m : Z =>
    (1 <= m)%Z /\ (m <= radix * pPred (vNum b))%Z /\ f1 = m :>R) /\
 Fbounded b f1.

Theorem Goal4 :
 forall (x0 y0 : float)
   (Post3 : ex
              (fun m : Z =>
               (Zpower_nat radix precision <= m)%Z /\
               (m <= radix * pPred (vNum b))%Z /\ x0 = m :>R) /\
            Fbounded b x0)
   (Pre4 : ex
             (fun m : Z => (1 <= m)%Z /\ (m <= radix)%Z /\ y0 = m :>R) /\
           Fbounded b y0) (Test2 : feq (fminus (fplus x0 y0) x0) y0 = false),
 Zabs_nat (radix - Int_part (fplus y0 f1)) < Zabs_nat (radix - Int_part y0) /\
 ex (fun m : Z => (1 <= m)%Z /\ (m <= radix)%Z /\ fplus y0 f1 = m :>R) /\
 Fbounded b (fplus y0 f1).

Theorem Goal5_6b :
 ex (fun m : Z => (1 <= m)%Z /\ (m <= radix)%Z /\ f1 = m :>R) /\
 Fbounded b f1.

Theorem Goal5b :
 forall (x0 y0 : float)
   (Post3 : ex
              (fun m : Z =>
               (Zpower_nat radix precision <= m)%Z /\
               (m <= radix * pPred (vNum b))%Z /\ x0 = m :>R) /\
            Fbounded b x0)
   (Pre4 : ex
             (fun m : Z => (1 <= m)%Z /\ (m <= radix)%Z /\ y0 = m :>R) /\
           Fbounded b y0) (Test2 : feq (fminus (fplus x0 y0) x0) y0 = true),
 Fbounded b y0 /\ y0 = radix :>R.

Theorem Goal6 :
 forall (x0 y0 : float)
   (Post2 : ex
              (fun m : Z =>
               (Zpower_nat radix precision <= m)%Z /\
               (m <= radix * pPred (vNum b))%Z /\ x0 = m :>R) /\
            Fbounded b x0)
   (Post1 : (ex
               (fun m : Z =>
                (1 <= m)%Z /\ (m <= radix)%Z /\ y0 = m :>R) /\
             Fbounded b y0) /\ feq (fminus (fplus x0 y0) x0) y0 = true),
 y0 = radix :>R.


Theorem Goal7b :
 forall (y0 x2 : float) (n0 : nat) (Post2 : Fbounded b y0 /\ y0 = radix :>R)
   (Pre6 : ex
             (fun m : Z =>
              ((1 <= m)%Z /\ (m <= radix * pPred (vNum b))%Z /\ x2 = m :>R) /\
              m = Zpower_nat radix n0) /\ Fbounded b x2)
   (Test3 : feq (fminus (fplus x2 f1) x2) f1 = true),
 Zabs_nat (radix * pPred (vNum b) - Int_part (fmult x2 y0)) <
 Zabs_nat (radix * pPred (vNum b) - Int_part x2) /\
 ex
   (fun m : Z =>
    ((1 <= m)%Z /\ (m <= radix * pPred (vNum b))%Z /\ fmult x2 y0 = m :>R) /\
    m = Zpower_nat radix (S n0)) /\ Fbounded b (fmult x2 y0).

Theorem Goal8b :
 ex
   (fun m : Z =>
    ((1 <= m)%Z /\ (m <= radix * pPred (vNum b))%Z /\ f1 = m :>R) /\
    m = Zpower_nat radix 0) /\ Fbounded b f1.

Theorem Goal9b :
 forall (y0 x2 : float) (n0 : nat) (Post2 : Fbounded b y0 /\ y0 = radix :>R)
   (Post1 : (ex
               (fun m : Z =>
                ((1 <= m)%Z /\ (m <= radix * pPred (vNum b))%Z /\ x2 = m :>R) /\
                m = Zpower_nat radix n0) /\ Fbounded b x2) /\
            feq (fminus (fplus x2 f1) x2) f1 = false),
 y0 = radix :>R /\ n0 = precision.
End prog.