Fcomp.v



(****************************************************************************
                                                                             
          IEEE754  :  Fcomp                                                     
                                                                             
          Laurent Thery                                                      
                                                                             
*****************************************************************************
*)

Require Import Float.
Section comparisons.
Variable radix:nat.
Hypothesis radixMoreThanOne:(lt (S O) radix).

Local zr := (inject_nat radix).

Definition Fdiff :=
   [x, y:
float]
   (Zminus
      (Zmult
         (Fnum x)
         (Zpower_nat zr (absolu (Zminus (Fexp x) (Zmin (Fexp x) (Fexp y))))))
      (Zmult
         (Fnum y)
         (Zpower_nat zr (absolu (Zminus (Fexp y) (Zmin (Fexp x) (Fexp y))))))).

Local FtoRradix := (FtoR radix).
Coercion FtoRradix : float >-> R.

Theorem Fdiff_correct:
  (x, y:
float)
  (Rmult (Fdiff x y) (powerRZ radix (Zmin (Fexp x) (Fexp y))))==(Rminus x y).
Intros x y; Unfold Fdiff.
Rewrite <- Z_R_minus.
Rewrite Rmult_sym; Rewrite Rmult_Rminus_distr.
Repeat Rewrite Rmult_IZR.
Unfold zr; Repeat Rewrite Zpower_nat_powerRZ; Auto.
Rewrite (Rmult_sym (Fnum x)); Rewrite (Rmult_sym (Fnum y)).
Repeat Rewrite <- Rmult_assoc.
Repeat Rewrite <- powerRZ_add; Auto with real arith.
Repeat Rewrite inj_abs; Auto with arith.
Repeat Rewrite Zle_plus_minus; Auto.
Rewrite [t:R](Rmult_sym t (Fnum x)); Rewrite [t:R](Rmult_sym t (Fnum y)); Auto.
Apply Zsimpl_le_plus_l with p := (Zmin (Fexp x) (Fexp y)); Auto with arith.
Rewrite Zle_plus_minus; Rewrite Zero_right; Apply Zle_min_r; Auto.
Apply Zsimpl_le_plus_l with p := (Zmin (Fexp x) (Fexp y)); Auto with arith.
Rewrite Zle_plus_minus; Rewrite Zero_right; Apply Zle_min_l; Auto.
Qed.

(* Definition of  comparison functions*)

Definition Feq := [x, y:float]<R> x==y.

Definition Fle := [x, y:float](Rle x y).

Definition Flt := [x, y:float](Rlt x y).

Definition Fge := [x, y:float](Rge x y).

Definition Fgt := [x, y:float](Rgt x y).

Definition Fcompare := [x, y:float](Zcompare ZERO (Fdiff x y)).

Definition Feq_bool :=
   [x, y:
float]
      Cases (Fcompare x y) of
          EGAL => true
         | _ => false
      end.

Theorem Feq_bool_correct_t: (x, y:float) (Feq_bool x y)=true ->(Feq x y).
Intros x y H'; Red.
Apply r_Rplus_plus with r := (Ropp y).
Repeat Rewrite (Rplus_sym (Ropp y)).
Rewrite Rplus_Ropp_r.
Change (Rminus x y)==R0.
Rewrite <- Fdiff_correct.
Apply without_div_Oi1; Auto.
Apply IZR_zero; Auto.
Apply sym_equal; Apply Zcompare_EGAL; Auto.
Generalize H'; Unfold Feq_bool Fcompare; Case (Zcompare ZERO (Fdiff x y)); Auto;
 Intros; Discriminate.
Qed.

Theorem Feq_bool_correct_r: (x, y:float) (Feq x y) ->(Feq_bool x y)=true.
Intros x y H'; Cut (Rminus x y)==R0.
Rewrite <- Fdiff_correct; Intros H'1; Case without_div_Od with 1 := H'1.
Intros H'0; Unfold Feq_bool Fcompare.
Rewrite (IZR_zero_r (Fdiff x y)); Auto.
Intros H'0; Contradict H'0.
Case (Zmin (Fexp x) (Fexp y)); Simpl; Auto 10 with real arith.
Apply r_Rplus_plus with r := (FtoR radix y).
Rewrite Rplus_Rminus; Rewrite Rplus_ne_l; Auto with real.
Qed.

Theorem Feq_bool_correct_f: (x, y:float) (Feq_bool x y)=false ->~ (Feq x y).
Intros x y H'; Contradict H'.
Rewrite Feq_bool_correct_r; Auto with arith.
Red; Intros H'0; Discriminate.
Qed.

Definition Flt_bool :=
   [x, y:
float]
      Cases (Fcompare x y) of
          SUPERIEUR => true
         | _ => false
      end.

Theorem Flt_bool_correct_t: (x, y:float) (Flt_bool x y)=true ->(Flt x y).
Intros x y H'; Red.
Apply Rlt_anti_compatibility with r := (Ropp y).
Repeat Rewrite (Rplus_sym (Ropp y)).
Rewrite Rplus_Ropp_r.
Change (Rlt (Rminus x y) R0).
Rewrite <- Fdiff_correct.
Replace R0 with (Rmult (powerRZ radix (Zmin (Fexp x) (Fexp y))) R0);
 Auto with real arith.
Rewrite (Rmult_sym (Fdiff x y)).
Apply Rlt_monotony; Auto with real arith.
Replace R0 with (IZR ZERO); Auto with real arith.
Apply Rlt_IZR; Apply Zgt_lt; Red.
Generalize H'; Unfold Flt_bool Fcompare.
Case (Zcompare ZERO (Fdiff x y)); Auto; Intros; Try Discriminate.
Qed.

Theorem Flt_bool_correct_r: (x, y:float) (Flt x y) ->(Flt_bool x y)=true.
Intros x y H'.
Cut (Rlt R0 (Rminus y x)); Auto with arith.
2:Apply Rlt_anti_compatibility with r := (FtoRradix x); AutoRewrite [Rsimpl];
   Auto with real.
Intros H'0.
Cut (Rlt (Fdiff x y) R0); Auto with arith.
Intros H'1.
Cut (Zlt (Fdiff x y) ZERO); Auto with zarith.
Intros H'2; Generalize (Zlt_Zcompare ? ? H'2);
 Unfold Flt_bool Fcompare Zcompare; Case (Fdiff x y); Auto with arith; Intros;
 Contradiction.
Apply lt_IZR; Auto with arith.
Apply (Rlt_mult_anticompatibility_exp radix) with z := (Zmin (Fexp x) (Fexp y));
 Auto with arith real; AutoRewrite [Rsimpl].
Rewrite Fdiff_correct; Auto with real.
Replace (Rminus x y) with (Ropp (Rminus y x)); [Idtac | Ring].
Apply Rgt_RoppO; Auto with arith.
Qed.

Theorem Flt_bool_correct_f: (x, y:float) (Flt_bool x y)=false ->(Fle y x).
Intros x y H'.
Case (total_order (FtoRradix y) (FtoRradix x)); Auto with real.
Intros H'0; Red; Apply Rlt_le; Auto with real.
Intros H'0; Elim H'0; Clear H'0; Intros H'1.
Red; Rewrite H'1; Auto with real.
Contradict H'; Rewrite Flt_bool_correct_r; Auto with real.
Red; Intros H'; Discriminate.
Qed.

Definition Fle_bool :=
   [x, y:
float]
      Cases (Fcompare x y) of
          SUPERIEUR => true
         | EGAL => true
         | _ => false
      end.

Theorem Fle_bool_correct_t: (x, y:float) (Fle_bool x y)=true ->(Fle x y).
Intros x y H'.
Cut (Feq x y) \/ (Flt x y).
Intros H; Case H; Intros H1; Auto with real.
Red; Apply eq_Rle; Auto with real.
Red; Apply Rlt_le; Auto with real.
Generalize H' (Feq_bool_correct_t x y) (Flt_bool_correct_t x y).
Unfold Fle_bool Feq_bool Flt_bool; Case (Fcompare x y); Auto.
Qed.

Theorem Fle_bool_correct_r: (x, y:float) (Fle x y) ->(Fle_bool x y)=true.
Intros x y H'.
Cut (Feq x y) \/ (Flt x y).
Intros H; Case H; Intros H1; Auto with real.
Generalize (Feq_bool_correct_r x y).
Unfold Fle_bool Feq_bool Flt_bool; Case (Fcompare x y); Auto.
Generalize (Flt_bool_correct_r x y); Unfold Fle_bool Feq_bool Flt_bool;
 Case (Fcompare x y); Auto with arith.
Case H'; Auto with arith.
Qed.

Theorem Fle_bool_correct_f: (x, y:float) (Fle_bool x y)=false ->(Flt y x).
Intros x y H'.
Case (total_order (FtoRradix y) (FtoRradix x)); Auto with real.
Intros H'0; Elim H'0; Clear H'0; Intros H'1.
Contradict H'.
Rewrite Fle_bool_correct_r; Auto with real.
Red; Intros H'; Discriminate.
Red; Rewrite H'1; Auto with real.
Contradict H'.
Rewrite Fle_bool_correct_r; Auto with real.
Red; Intros H'; Discriminate.
Red; Auto with real.
Apply Rlt_le; Auto with real.
Qed.

Lemma Fle_Zle: (n1, n2, d:Z) (Zle n1 n2) ->(Fle (Float n1 d) (Float n2 d)).
Intros; Unfold Fle FtoRradix FtoR; Simpl; Auto.
Case Zle_lt_or_eq with 1 := H; Intros H1.
Apply Rlt_le; Auto with real.
Rewrite <- H1; Auto with real.
Qed.

Lemma Flt_Zlt: (n1, n2, d:Z) (Zlt n1 n2) ->(Flt (Float n1 d) (Float n2 d)).
Intros; Unfold Flt FtoRradix FtoR; Simpl; Auto with real.
Qed.

Lemma Fle_Fge: (x, y:float) (Fle x y) ->(Fge y x).
Unfold Fle Fge; Intros x y H'; Auto with real.
Apply Rle_sym1; Auto.
Qed.

Lemma Fge_Zge: (n1, n2, d:Z) (Zge n1 n2) ->(Fge (Float n1 d) (Float n2 d)).
Intros n1 n2 d H'; Apply Fle_Fge; Auto.
Apply Fle_Zle; Auto.
Apply Zge_le; Auto.
Qed.

Lemma Flt_Fgt: (x, y:float) (Flt x y) ->(Fgt y x).
Unfold Flt Fgt; Intros x y H'; Auto.
Qed.

Lemma Fgt_Zgt: (n1, n2, d:Z) (Zgt n1 n2) ->(Fgt (Float n1 d) (Float n2 d)).
Intros n1 n2 d H'; Apply Flt_Fgt; Auto.
Apply Flt_Zlt; Auto.
Apply Zgt_lt; Auto.
Qed.
(* Arithmetic properties on F : Fle is reflexive, transitive, antisymmetric *)

Lemma Fle_refl: (x, y:float) (Feq x y) ->(Fle x y).
Unfold Feq; Unfold Fle; Intros.
Rewrite H; Auto with real.
Qed.

Lemma Fle_trans: (x, y, z:float) (Fle x y) -> (Fle y z) ->(Fle x z).
Unfold Fle; Intros.
Apply Rle_trans with r2 := (FtoR radix y); Auto.
Qed.

Theorem Rlt_Fexp_eq_Zlt:
  (x, y:
float) (Rlt x y) -> (Fexp x)=(Fexp y) ->(Zlt (Fnum x) (Fnum y)).
Intros x y H' H'0.
Apply lt_IZR.
Apply (Rlt_mult_anticompatibility_exp radix) with z := (Fexp x);
 Auto with real arith.
Pattern 2 (Fexp x); Rewrite H'0; Auto.
Qed.

Theorem Rle_Fexp_eq_Zle:
  (x, y:
float) (Rle x y) -> (Fexp x)=(Fexp y) ->(Zle (Fnum x) (Fnum y)).
Intros x y H' H'0.
Apply le_IZR.
Apply (Rle_mult_anticompatibility_exp radix) with z := (Fexp x);
 Auto with real arith.
Pattern 2 (Fexp x); Rewrite H'0; Auto.
Qed.

Theorem LtR0Fnum: (p:float) (Rlt R0 p) ->(Zlt ZERO (Fnum p)).
Intros p H'.
Apply lt_IZR.
Apply (Rlt_mult_anticompatibility_exp radix) with z := (Fexp p);
 Auto with real arith.
AutoRewrite [Rsimpl]; Auto.
Qed.

Theorem LeR0Fnum: (p:float) (Rle R0 p) ->(Zle ZERO (Fnum p)).
Intros p H'.
Apply le_IZR.
Apply (Rle_mult_anticompatibility_exp radix) with z := (Fexp p);
 Auto with real arith.
AutoRewrite [Rsimpl]; Auto.
Qed.

Theorem LeFnumZERO: (x:float) (Zle ZERO (Fnum x)) ->(Rle R0 x).
Intros x H'; Unfold FtoRradix FtoR.
Replace R0 with (Rmult ZERO ZERO); Auto with real.
Apply Rle_Rmult_comp; Auto with real zarith arith.
Qed.

Theorem R0LtFnum: (p:float) (Rlt p R0) ->(Zlt (Fnum p) ZERO).
Intros p H'.
Apply lt_IZR.
Apply (Rlt_mult_anticompatibility_exp radix) with z := (Fexp p);
 Auto with real arith.
AutoRewrite [Rsimpl]; Auto.
Qed.

Theorem R0LeFnum: (p:float) (Rle p R0) ->(Zle (Fnum p) ZERO).
Intros p H'.
Apply le_IZR.
Apply (Rle_mult_anticompatibility_exp radix) with z := (Fexp p);
 Auto with real arith.
AutoRewrite [Rsimpl]; Auto.
Qed.

Theorem LeZEROFnum: (x:float) (Zle (Fnum x) ZERO) ->(Rle x R0).
Intros x H'; Unfold FtoRradix FtoR.
Apply Ropp_Rle; AutoRewrite [Rsimpl]; Rewrite <- Ropp_mul1.
Replace R0 with (Rmult (Ropp ZERO) ZERO); Auto with real.
Apply Rle_Rmult_comp; Auto with real zarith arith.
Simpl; AutoRewrite [Rsimpl]; Auto with real.
Qed.
End comparisons.
Hints Resolve LeFnumZERO LeZEROFnum :float.

14/12/100, 02:49