Library Fexp

Require Export AllFloat.
Require Export List.
Section mf.
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.

Inductive IsExpansion : list float -> Prop :=
  | IsExpansionNil : IsExpansion nil
  | IsExpansionSingle :
      forall x : float, Fbounded b x -> IsExpansion (x :: nil)
  | IsExpansionTop1 :
      forall (x : float) (L : list float),
      is_Fzero x -> Fbounded b x -> IsExpansion L -> IsExpansion (x :: L)
  | IsExpansionTop2 :
      forall (x y : float) (L : list float),
      Fbounded b x ->
      is_Fzero y ->
      Fbounded b y -> IsExpansion (x :: L) -> IsExpansion (x :: y :: L)
  | IsExpansionTop :
      forall (x y : float) (L : list float),
      ~ is_Fzero x ->
      ~ is_Fzero y ->
      Fbounded b x ->
      Fbounded b y ->
      (MSB radix x < LSB radix y)%Z ->
      IsExpansion (y :: L) -> IsExpansion (x :: y :: L).

Theorem Zlt_MSB_LSB :
 forall x y : float,
 ~ is_Fzero y -> (MSB radix x < LSB radix y)%Z -> (Fabs x < Fabs y)%R.

Theorem IsExpansion_comp1 :
 forall (L : list float) (x y : float),
 Fbounded b y -> x = y :>R -> IsExpansion (x :: L) -> IsExpansion (y :: L).

Theorem IsExpansion_comp2 :
 forall (L : list float) (x y z : float),
 Fbounded b z ->
 y = z :>R -> IsExpansion (x :: y :: L) -> IsExpansion (x :: z :: L).

Fixpoint expValue (L : list float) : float :=
  match L with
  | nil => Fzero 0
  | x :: L1 => Fplus radix x (expValue L1)
  end.

Fixpoint expNormalize (L : list float) : list float :=
  match L with
  | nil => nil
  | x :: L1 =>
      match Fnum x with
      | Z0 => expNormalize L1
      | Zpos p => x :: expNormalize L1
      | Zneg p => x :: expNormalize L1
      end
  end.

Theorem expInv :
 forall (a : float) (L : list float), IsExpansion (a :: L) -> IsExpansion L.

Theorem expBoundedInv :
 forall (a : float) (L : list float), IsExpansion (a :: L) -> Fbounded b a.

Theorem expNormalizeCorrect :
 forall L : list float, expValue L = expValue (expNormalize L) :>R.

Theorem expNormalizeExp :
 forall L : list float, IsExpansion L -> IsExpansion (expNormalize L).

Inductive IsNzExpansion : list float -> Prop :=
  | IsNzExpansionNil : IsNzExpansion nil
  | IsNzExpansionSingle :
      forall x : float,
      ~ is_Fzero x -> Fbounded b x -> IsNzExpansion (x :: nil)
  | IsNzExpansionTop :
      forall (x y : float) (L : list float),
      ~ is_Fzero x ->
      ~ is_Fzero y ->
      Fbounded b x ->
      Fbounded b y ->
      (MSB radix x < LSB radix y)%Z ->
      IsNzExpansion (y :: L) -> IsNzExpansion (x :: y :: L).

Theorem isNzExpansionIsExpansion :
 forall l : list float, IsNzExpansion l -> IsExpansion l.

Theorem IsNzExpansionInv :
 forall (a : float) (l : list float),
 IsNzExpansion (a :: l) -> IsNzExpansion l.

Inductive IsNzExpansionR : list float -> Prop :=
  | IsNzExpansionNilR : IsNzExpansionR nil
  | IsNzExpansionSingleR :
      forall x : float,
      ~ is_Fzero x -> Fbounded b x -> IsNzExpansionR (x :: nil)
  | IsNzExpansionTopR :
      forall (x y : float) (L : list float),
      ~ is_Fzero x ->
      ~ is_Fzero y ->
      Fbounded b x ->
      Fbounded b y ->
      (MSB radix y < LSB radix x)%Z ->
      IsNzExpansionR (y :: L) -> IsNzExpansionR (x :: y :: L).

Theorem isNzExpansionRIsNzExpansion :
 forall l : list float, IsNzExpansionR l -> IsNzExpansion (rev l).

Theorem IsNzExpansionRInv :
 forall (a : float) (l : list float),
 IsNzExpansionR (a :: l) -> IsNzExpansionR l.

Theorem mkIsNzAux :
 forall (n : nat) (p : float),
 (- dExp b <= LSB radix p)%Z ->
 (MSB radix p < - dExp b + n)%Z ->
 exists l : list float,
   IsNzExpansionR l /\
   p = expValue l :>R /\
   match l with
   | a :: _ => ToZeroP b radix p a
   | nil => True
   end.

Theorem expValueApp :
 forall l1 l2 : list float,
 expValue (l1 ++ l2) = (expValue l1 + expValue l2)%R :>R.

Theorem expValueRev :
 forall l : list float, expValue (rev l) = expValue l :>R.

Theorem existExp :
 forall p : float,
 (- dExp b <= LSB radix p)%Z ->
 exists l : list float, IsExpansion l /\ p = expValue l :>R.
End mf.