Library Fexp2

Require Export ThreeSumProps.
Require Export List.
Section Fexp2.
Variable b : Fbound.
Variable precision : nat.

Let radix := 2%Z.

Let FtoRradix := FtoR radix.
Coercion FtoRradix : float >-> R.
Hypothesis precisionGreaterThanOne : 1 < precision.
Hypothesis pGivesBound : Zpos (vNum b) = Zpower_nat radix precision.
Hypothesis Ngd : (1 <= pPred (vNum b) * (1 - / radix))%R.
Hypothesis Ngd2 : (6%nat <= pPred (vNum b) * (1 - / radix * / radix))%R.

Inductive IsExp : list float -> Prop :=
  | IsExpNil : IsExp nil
  | IsExpSingle : forall x : float, Fbounded b x -> IsExp (x :: nil)
  | IsExpTop :
      forall (x y : float) (L : list float),
      Fbounded b x ->
      Fbounded b y ->
      (Fexp y <= Fexp x)%Z -> IsExp (y :: L) -> IsExp (x :: y :: L).
Hint Resolve IsExpNil IsExpSingle IsExpTop.

Inductive NearEqual : list float -> list float -> Prop :=
  | IsEqual : forall x : list float, NearEqual x x
  | OneMoreR :
      forall (x : list float) (e : float),
      Fbounded b e -> NearEqual x (e :: x).
Hint Resolve IsEqual OneMoreR.

Fixpoint sum (L : list float) : R :=
  match L with
  | nil => 0%R
  | x :: L1 => (FtoRradix x + sum L1)%R
  end.

Definition hdexp (L : list float) :=
  match L with
  | nil => (- dExp b)%Z
  | x :: L1 => Fexp x
  end.

Fixpoint lastexp (L : list float) : Z :=
  match L with
  | nil => (- dExp b)%Z
  | x :: nil => Fexp x
  | x :: L1 => lastexp L1
  end.

Definition hd (L : list float) :=
  match L with
  | nil => Fzero (- dExp b)
  | x :: L1 => x
  end.

Theorem IsExpZle :
 forall (i : float) (L : list float), IsExp (i :: L) -> (hdexp L <= Fexp i)%Z.

Theorem isExpInv :
 forall (x y : float) (L : list float), IsExp (x :: y :: L) -> IsExp (y :: L).

Theorem isExpSkip :
 forall (x y : float) (L : list float), IsExp (x :: y :: L) -> IsExp (x :: L).

Theorem sum_IsExp :
 forall (L : list float) (x : float) (m : R),
 IsExp (x :: L) ->
 (Float (pPred (vNum b)) (Fexp x) <= m)%R ->
 (Rabs (sum (x :: L)) <= length (x :: L) * m)%R.

Inductive IsRleExp : list float -> Prop :=
  | IsRleExpNil : IsRleExp nil
  | IsRleExpSingle : forall x : float, Fbounded b x -> IsRleExp (x :: nil)
  | IsRleExpTop :
      forall (x y : float) (L : list float),
      Fbounded b x ->
      Fbounded b y ->
      (Rabs x <= Rabs y)%R -> IsRleExp (y :: L) -> IsRleExp (x :: y :: L).
Hint Resolve IsRleExpNil IsRleExpSingle IsRleExpTop.

Inductive EqListFloat : list float -> list float -> Prop :=
  | EqListFloatnil : EqListFloat nil nil
  | EqListFloatTop :
      forall (x y : float) (L L' : list float),
      Fbounded b x ->
      Fbounded b y ->
      x = y :>R -> EqListFloat L L' -> EqListFloat (x :: L) (y :: L').
Hint Resolve EqListFloatnil EqListFloatTop.

Theorem sum_app :
 forall (L : list float) (x : float), (x + sum L)%R = sum (L ++ x :: nil) :>R.

Theorem cons_neq :
 forall (x : float) (L : list float), x :: L <> L :>list float.

Definition endof (all part : list float) :=
  exists rest : list float, all = rest ++ part.

Theorem app_length :
 forall l1 l2 : list float, length (l1 ++ l2) = length l1 + length l2.

Theorem endof_length :
 forall L l : list float, endof L l -> length l <= length L.

Inductive IsCanExp : list float -> Prop :=
  | IsCanExpNil : IsCanExp nil
  | IsCanExpTop :
      forall (x : float) (L : list float),
      Fcanonic radix b x -> IsCanExp L -> IsCanExp (x :: L).
Hint Resolve IsCanExpNil IsCanExpTop.

Theorem IsCanExpBounded :
 forall (i : float) (L : list float), IsCanExp (i :: L) -> Fbounded b i.

Inductive IsRleExpRev : list float -> Prop :=
  | IsRleExpRevNil : IsRleExpRev nil
  | IsRleExpRevSingle :
      forall x : float, Fbounded b x -> IsRleExpRev (x :: nil)
  | IsRleRevExpTop :
      forall (x y : float) (L : list float),
      Fbounded b x ->
      Fbounded b y ->
      (Rabs y <= Rabs x)%R ->
      IsRleExpRev (y :: L) -> IsRleExpRev (x :: y :: L).
Hint Resolve IsRleExpRevNil IsRleExpRevSingle IsRleRevExpTop.

Theorem IsRleExpRevComp :
 forall L1 L2, EqListFloat L1 L2 -> IsRleExpRev L1 -> IsRleExpRev L2.

Theorem IsRleExpRevIsExp :
 forall L : list float,
 IsRleExpRev L ->
 exists L' : list float,
   IsCanExp L' /\ IsRleExpRev L' /\ EqListFloat L L' /\ IsExp L'.

Fixpoint last (L : list float) : float :=
  match L with
  | nil => Fzero (- dExp b)
  | x :: nil => x
  | x :: L1 => last L1
  end.

Theorem ExpRev_aux :
 forall (l : list float) (x : float),
 Fbounded b x ->
 IsRleExpRev l -> (Rabs x <= Rabs (last l))%R -> IsRleExpRev (l ++ x :: nil).

Theorem Exp_aux :
 forall (l : list float) (x : float),
 Fbounded b x ->
 IsRleExp l -> (Rabs (last l) <= Rabs x)%R -> IsRleExp (l ++ x :: nil).

Theorem last_hd : forall l : list float, last l = hd (rev l).

Theorem IsRleExpRev_IsRleExp :
 forall l : list float, IsRleExpRev l -> IsRleExp (rev l).

Theorem IsRleExp_IsRleExpRev :
 forall l : list float, IsRleExp l -> IsRleExpRev (rev l).

Theorem EqListFloat_length :
 forall l l' : list float, EqListFloat l l' -> length l = length l'.

Theorem EqListFloat_sum :
 forall l l' : list float, EqListFloat l l' -> sum l = sum l' :>R.

Theorem rev_sum : forall l : list float, sum l = sum (rev l) :>R.

Theorem rev_length : forall l : list float, length l = length (rev l).
End Fexp2.