From 67c5f554b59362bf09c80bd04dbb18e45e55c3c6 Mon Sep 17 00:00:00 2001
From: Arthur Correnson <arthur.correnson@gmail.com>
Date: Tue, 29 Jun 2021 10:29:15 +0200
Subject: [PATCH] [ieee/coq] cleaning proofs

---
 src_common/ieee/coq/Finterval.v | 235 +-------------------------------
 src_common/ieee/coq/Futils.v    | 227 +-----------------------------
 src_common/ieee/coq/Rextended.v |  62 ++++++++-
 3 files changed, 64 insertions(+), 460 deletions(-)

diff --git a/src_common/ieee/coq/Finterval.v b/src_common/ieee/coq/Finterval.v
index 333327025..67d8b7261 100644
--- a/src_common/ieee/coq/Finterval.v
+++ b/src_common/ieee/coq/Finterval.v
@@ -13,11 +13,6 @@ Variable emax : Z.
 Context (Hprec : FLX.Prec_gt_0 prec).
 Context (Hemax : Prec_lt_emax prec emax).
 
-Notation "x <= y" := (Bleb x y = true).
-Notation "x <= y <= z" := (Bleb x y = true /\ Bleb y z = true).
-Notation "'+oo'" := (B754_infinity false).
-Notation "'-oo'" := (B754_infinity true).
-
 Definition float := binary_float prec emax.
 
 Record Interval := MK_INTERVAL {
@@ -166,232 +161,6 @@ Lemma Iadd2_correct :
     x ∈ I1 -> y ∈ I2 ->
     Bplus m x y ∈ Iadd2 m I1 I2.
 Proof.
-  intros m x y I1 I2 [ ] [ ] [ [Hx1 Hx2] | Hx ] [ [Hy1 Hy2] | Hy ];
-  destruct I1 as [lo1 hi1 nan1] eqn:EI1;
-  destruct I2 as [lo2 hi2 nan2] eqn:EI2;
-  unfold γ in *;
-  simpl in *.
-  - destruct (is_nan (Bplus m lo1 lo2)) eqn:E1;
-    destruct (is_nan (Bplus m hi1 hi2)) eqn:E2.
-    + unfold Iadd2; simpl.
-      rewrite (is_nan_inv _ _ _ E1).
-      rewrite (is_nan_inv _ _ _ E2).
-      simpl. right. easy.
-
-
-
-End Finterval.
-
-(* Module MakeI (F : B_FORMAT).
-
-Module Float := MakeIEEE F.
-
-Local Notation "x <= y" := (Float.le x y = true).
-Local Notation "x <= y <= z" := (Float.le x y = true /\ Float.le y z = true).
-Local Notation "'+oo'" := (B754_infinity false).
-Local Notation "'-oo'" := (B754_infinity true).
-
-Axiom Fadd_le_compat:
-  forall m (w x y z : Float.T),
-    is_nan w = false ->
-    is_nan x = false ->
-    is_nan y = false ->
-    is_nan z = false ->
-    w <= x -> y <= z ->
-    Float.add m w y <= Float.add m x z.
-
-Record Interval := MK_INTERVAL {
-  lo : Float.T;
-  hi : Float.T;
-  infp : bool;
-  infm : bool;
-  nan : bool;
-}.
-
-Definition contains (I : Interval) (x : Float.T) :=
-  (lo I <= x <= hi I) \/
-  (Float.is_nan x = true /\ nan I = true) \/
-  (Float.is_infp x = true /\ infp I = true) \/
-  (Float.is_infm x = true /\ infm I = true).
-
-Notation "x ∈ I" := (contains I x) (at level 80). 
-
-Definition orb2 (x y : bool) := 
-  match x with
-  | false => y
-  | true => true
-  end.
-
-Lemma orb2_orb :
-  forall b1 b2, b1 || b2 = orb2 b1 b2.
-Proof. now intros [ ] [ ]. Qed.
-
-Definition andb2 (x y : bool) :=
-  match x, y with
-  | true, true => true
-  | _, _ => false
-  end.
-
-Lemma andb2_andb :
-  forall b1 b2, b1 && b2 = andb2 b1 b2.
-Proof. now intros [ ] [ ]. Qed.
-
-Infix "or" := (orb2) (at level 50).
-Infix "and" := (andb2) (at level 40).
-
-Definition check (I : Interval) : bool :=
-  is_finite (lo I) and is_finite (hi I).
-
-Definition Iadd (m : mode) (A B : Interval) : Interval :=
-  let (a1, b1) := (lo A, hi A) in
-  let (a2, b2) := (lo B, hi B) in
-  let a := Float.add m a1 a2 in
-  let b := Float.add m b1 b2 in
-  let nan := (nan A) or (nan B) or (infp A and infm B) or (infm A and infp B) in
-  MK_INTERVAL a b (infp A or infp B) (infm A or infm B) nan.
-
-Ltac checked :=
-  match goal with
-  | [ H : check _ = true |- _ ] =>
-    unfold check in H;
-    rewrite <- andb2_andb in H;
-    rewrite Bool.andb_true_iff in H;
-    simpl in H;
-    destruct H;
-    checked
-  | _ => idtac
-  end.
-
-Ltac contained :=
-  match goal with
-  | [ H : contains _ _ |- _ ] =>
-    case H; [ simpl; intros [ ] | simpl; intros [ ] ]; 
-    clear H;
-    contained
-  | _ => idtac
-  end.
-
-Ltac classify_nan x :=
-  match goal with
-  | [ H : Float.is_nan x = true |- _ ] =>
-    rewrite (Float.is_nan_inv x H) in *
-  | [ H : _ <= x |- _ ] =>
-    assert (Float.is_nan x = false) by apply (Float.le_not_nan_r _ _ H)
-  | [ H : x <= _ |- _ ] =>
-    assert (Float.is_nan x = false) by apply (Float.le_not_nan_l _ _ H)
-  | _ => fail "can't determine if" x "is NaN"
-  end.
-
-Ltac classify_inf x :=
-  match goal with
-  | [ H : Float.is_infp x = true |- _ ] =>
-    rewrite (Float.is_infp_inv x H) in *
-  | [ H : +oo <= x |- _ ] =>
-    rewrite (Float.infp_le_is_infp _ H) in *
-  | [ H : Float.is_infm x = true |- _ ] =>
-    rewrite (Float.is_infm_inv x H) in *
-  | [ H : x <= -oo |- _ ] =>
-    rewrite (Float.le_infm_is_infm x H) in *
-  | _ => fail "can't determine if" x "is +oo or -oo"
-  end.
-
-Ltac feasy :=
-  try easy;
-    match goal with
-    | |- is_nan ?x = false => classify_nan x; (try easy; intuition)
-    end.
-
-Ltac auto_contain :=
-  try easy; first [ progress (right; simpl; intuition) | progress (left; simpl; intuition) ].
-
-Lemma contains_nan :
-  forall I, contains I Float.NaN <-> nan I = true.
-Proof.
-  intros [ ? ? ? ? [ ] ]; simpl; split; intros; try auto_contain. 
-  inversion H; try easy; intuition.
-Qed.
-
-Lemma bounded_finite :
-  forall m M x, m <= x <= M -> is_finite m  = true -> is_finite M = true -> Float.is_finite x = true.
-Proof.
-  intros m M x Hx Fm FM.
-  destruct Hx, x; try easy.
-  destruct s.
-  - classify_inf m; discriminate.
-  - classify_inf M; discriminate.
-Qed.
-
-Ltac boolean :=
-  match goal with
-  | [ |- true = _ ] => symmetry; boolean
-  | [ |- true or _ = true ] => simpl; reflexivity
-  | [ |- ?x or true = true ] =>
-    destruct x; simpl; reflexivity
-  | [ |- ?x or ?y = true ] =>
-    replace x with true by boolean; boolean
-  end.
-
-Ltac irewrite :=
-  match goal with
-  | [ H : infp _ = _ |- _ ] => rewrite H; irewrite
-  | [ H : infm _ = _ |- _ ] => rewrite H; irewrite
-  | [ H : nan _ = _ |- _ ] => rewrite H; irewrite
-  | _ => idtac
-  end.
-
-Ltac fdiscriminate x :=
-  (classify_inf x; discriminate) ||
-  (classify_nan x; discriminate).
-
-Ltac fdestruct x :=
-  destruct (x : Float.T) as [ [ ] | [ ] | | ].
-
-Lemma Iadd_correct :
-  forall m ix iy x y, 
-  check ix = true ->
-  check iy = true ->
-  contains ix x ->
-  contains iy y ->
-  contains (Iadd m ix iy) (Float.add m x y).
-Proof.
-  intros.
-  checked.
-  contained; intuition; unfold Iadd; irewrite.
-  + left; split; simpl; apply Float.add_le_compat; eauto using bounded_finite.
-  + classify_nan x; irewrite; auto_contain.
-  + classify_inf x. fdestruct y; auto_contain.
-    classify_inf (lo iy); discriminate.
-  + classify_inf x. fdestruct y;
-    try fdiscriminate (hi iy); auto_contain.
-  + classify_nan y; fdestruct x; auto_contain.
-  + classify_nan x; auto_contain.
-  + classify_nan y; fdestruct x; auto_contain.
-  + classify_nan y; fdestruct x; auto_contain.
-  + classify_inf y; fdestruct x; 
-    try fdiscriminate (lo ix); auto_contain.
-  + classify_inf y; fdestruct x; 
-    try fdiscriminate (hi ix); auto_contain.
-  + classify_nan x; auto_contain.
-  + classify_nan x; auto_contain.
-  + classify_inf x; classify_inf y; auto_contain.
-  + classify_inf x; classify_inf y; auto_contain.
-  + classify_inf x; classify_inf y; auto_contain.
-  + classify_inf x; classify_inf y; auto_contain.
-Qed.
-
-Lemma Iadd_check :
-  forall m ix iy,
-  check ix = true ->
-  check iy = true ->
-  Float.dont_overflow m Rplus (lo ix) (lo iy) = true ->
-  Float.dont_overflow m Rplus (hi ix) (hi iy) = true ->
-  check (Iadd m ix iy) = true.
-Proof.
-  intros m ix iy Hx Hy; checked.
-  unfold check.
-  rewrite <- andb2_andb, Bool.andb_true_iff; split; now apply Float.add_finite.
-Qed.
-
-
+Admitted.
 
-End MakeI. *)
\ No newline at end of file
+End Finterval.
\ No newline at end of file
diff --git a/src_common/ieee/coq/Futils.v b/src_common/ieee/coq/Futils.v
index d7e87ca61..40ce8d3fe 100644
--- a/src_common/ieee/coq/Futils.v
+++ b/src_common/ieee/coq/Futils.v
@@ -194,229 +194,4 @@ End Utils.
 
 Arguments le_not_nan {prec} {emax}.
 Arguments le_not_nan_l {prec} {emax}.
-Arguments le_not_nan_r {prec} {emax}.
-
-
-
-(* Class leb_op (A:Type) : Type := leb : A -> A -> bool.
-Local Notation "x <= y" := (leb x y = true).
-
-Class ltb_op (A:Type) : Type := ltb : A -> A -> bool.
-Local Notation "x < y" := (ltb x y = true).
-
-Class eqb_op (A:Type) : Type := eqb : A -> A -> bool.
-Local Notation "x = y" := (eqb x y = true).
-
-Class infp_symb (A:Type) : Type := infp : A.
-Local Notation "+oo" := (infp).
-
-Class infm_symb (A:Type) : Type := infm : A.
-Local Notation "-oo" := (infm).
-
-Module Type B_FORMAT.
-  Parameter prec  : Z.
-  Parameter emax  : Z.
-  Parameter Hprec : (0 < prec)%Z.
-  Parameter Hprec_emax : (prec < emax)%Z.
-End B_FORMAT.
-
-Module MakeIEEE (F : B_FORMAT).
-
-Definition T := binary_float F.prec F.emax.
-
-Definition NaN : T := B754_nan.
-
-Definition add (m : mode) : T -> T -> T := @Bplus _ _ F.Hprec F.Hprec_emax m.
-
-Definition sub (m : mode) : T -> T -> T := @Bminus _ _ F.Hprec F.Hprec_emax m.
-
-Definition mul (m : mode) : T -> T -> T := @Bmult _ _ F.Hprec F.Hprec_emax m.
-
-Definition div (m : mode) : T -> T -> T := @Bdiv _ _ F.Hprec F.Hprec_emax m.
-
-Definition sqrt (m : mode) : T -> T := @Bsqrt _ _ F.Hprec F.Hprec_emax m.
-
-Instance lt : ltb_op T := Bltb.
-
-Instance le : leb_op T := Bleb.
-#[global] Transparent leb.
-
-
-Instance eq : eqb_op T := Beqb.
-
-Instance infm : infm_symb T := B754_infinity true.
-
-Instance infp : infp_symb T := B754_infinity false.
-
-Definition is_inf (x : T) :=
-  match x with
-  | B754_infinity _ => true
-  | _ => false
-  end.
-
-Definition is_infp (x : T) :=
-  match x with
-  | B754_infinity s => negb s
-  | _ => false
-  end.
-
-Definition is_infm (x : T) :=
-  match x with
-  | B754_infinity s => s
-  | _ => false
-  end.
-
-Definition is_finite (x : T) := is_finite x.
-
-Definition is_nan (x : T) := is_nan x.
-
-Lemma le_Rle :
-  forall (x y :T),
-    is_finite x = true ->
-    is_finite y = true ->
-    x <= y -> (B2R x <= B2R y)%R.
-Proof.
-  intros x y Fx Fy Hxy.
-  unfold leb, le, Bleb, SpecFloat.SFleb in Hxy.
-  replace (SpecFloat.SFcompare (B2SF x) (B2SF y)) with (Bcompare x y) in Hxy by auto.
-  pose proof (Bcompare_correct _ _ x y Fx Fy).
-  rewrite H in Hxy.
-  destruct Raux.Rcompare eqn:E in Hxy.
-  - right. auto using Raux.Rcompare_Eq_inv.
-  - left. auto using Raux.Rcompare_Lt_inv.
-  - discriminate.
-Qed.
-
-Lemma Rle_le :
-  forall (x y :T),
-    is_finite x = true ->
-    is_finite y = true ->
-    (B2R x <= B2R y)%R -> x <= y.
-Proof.
-  intros x y Fx Fy Hxy.
-  unfold leb, le, Bleb, SpecFloat.SFleb.
-  replace (SpecFloat.SFcompare (B2SF x) (B2SF y)) with (Bcompare x y) by auto.
-  rewrite (Bcompare_correct _ _ _); auto.
-  destruct Raux.Rcompare eqn:E; auto.
-  apply Raux.Rcompare_Gt_inv in E; lra.
-Qed.
-
-Definition add_to_nan (x y : T) :=
-  ((is_infm x && is_infp y) || (is_infp x && is_infm y))%bool.
-
-
-Definition dont_overflow (m : mode) (op : R -> R -> R) (x  y : T) : bool :=
-  let fexp := @SpecFloat.fexp F.prec F.emax in
-  let fmax := Raux.bpow Zaux.radix2 F.emax in
-  let rsum := Generic_fmt.round Zaux.radix2 fexp (round_mode m) (op (B2R x) (B2R y)) in
-  Raux.Rlt_bool (Rabs rsum) fmax.
-
-Lemma add_le_compat_aux :
-  forall m w x y z,
-    is_finite w = true ->
-    is_finite x = true ->
-    is_finite y = true ->
-    is_finite z = true ->
-    dont_overflow m Rplus w y = true ->
-    dont_overflow m Rplus x z = true ->
-    (B2R w <= B2R x)%R -> (B2R y <= B2R z)%R ->
-    (B2R (add m w y) <= B2R (add m x z))%R.
-Proof.
-  intros m w x y z Fw Fx Fy Fz Ho1 Ho2 Hwx Hyz.
-  unfold dont_overflow in Ho1, Ho2; unfold add.
-  pose proof (Hc1 := Bplus_correct _ _ F.Hprec F.Hprec_emax m w y Fw Fy).
-  pose proof (Hc2 := Bplus_correct _ _ F.Hprec F.Hprec_emax m x z Fx Fz).
-  pose proof F.Hprec_emax; pose proof F.Hprec.
-  rewrite Ho1 in Hc1; rewrite Ho2 in Hc2.
-  rewrite (proj1 Hc1), (proj1 Hc2).
-  apply Generic_fmt.round_le;
-  unfold SpecFloat.fexp, SpecFloat.emin, Generic_fmt.Valid_exp in *;
-  intuition.
-Qed.
-
-Lemma add_le_compat_aux2 :
-  forall m w x y z,
-    is_nan w = false ->
-    is_nan x = false ->
-    is_nan y = false ->
-    is_nan z = false ->
-    add_to_nan w y = false ->
-    add_to_nan x z = false ->
-    dont_overflow m Rplus w y = true ->
-    dont_overflow m Rplus x z = true ->
-    (B2R w <= B2R x)%R -> (B2R y <= B2R z)%R ->
-    (B2R (add m w y) <= B2R (add m x z))%R.
-Proof.
-
-Lemma add_finite :
-  forall m x y,
-  is_finite x = true ->
-  is_finite y = true ->
-  dont_overflow m Rplus x y = true ->
-  is_finite (add m x y) = true.
-Proof.
-  intros m x y Fx Fy Ho.
-  unfold dont_overflow in Ho; unfold add.
-  pose proof (Bplus_correct _ _  F.Hprec F.Hprec_emax m x y Fx Fy).
-  rewrite Ho in H. intuition.
-Qed.
-
-Lemma add_le_compat :
-  forall m w x y z,
-    is_finite w = true ->
-    is_finite x = true ->
-    is_finite y = true ->
-    is_finite z = true ->
-    dont_overflow m Rplus w y = true ->
-    dont_overflow m Rplus x z = true ->
-    w <= x -> y <= z ->
-    add m w y <= add m x z.
-Proof.
-  intros m w x y z Fw Fx Fy Fz Ho1 Ho2 Hwx Hyz.
-  unfold dont_overflow in Ho1, Ho2; unfold add.
-  assert(Hwx': (B2R w <= B2R x)%R) by auto using le_Rle.
-  assert(Hyz': (B2R y <= B2R z)%R) by auto using le_Rle.
-  pose proof (add_le_compat_aux m w x y z Fw Fx Fy Fz Ho1 Ho2 Hwx' Hyz').
-  apply Rle_le; auto using add_finite.
-Qed.
-
-Lemma add_nan :
-  forall m x y,
-  is_finite x = true ->
-  is_finite y = true ->
-  is_nan (add m x y) = false.
-Proof.
-  intros m [[ ] | [ ] | | ] [ [ ] | [ ] | | ] Fx Fy; try easy.
-  - now destruct m.
-  - now destruct m.
-  - unfold add, Bplus, is_nan.
-    auto using is_nan_binary_normalize.
-Qed.
-
-End MakeIEEE.
-
-Module B32_FORMAT : B_FORMAT.
-  Definition emax := 128%Z.
-  Definition prec := 24%Z.
-  
-  Lemma Hprec : (0 < prec)%Z.
-  Proof. reflexivity. Qed.
-
-  Lemma Hprec_emax : (prec < emax)%Z.
-  Proof. reflexivity. Qed.
-End B32_FORMAT.
-
-Module B32 := MakeIEEE (B32_FORMAT).
-
-Module B64_FORMAT : B_FORMAT.
-  Definition emax := 1024%Z.
-  Definition prec := 53%Z.
-  
-  Lemma Hprec : (0 < prec)%Z.
-  Proof. reflexivity. Qed.
-
-  Lemma Hprec_emax : (prec < emax)%Z.
-  Proof. reflexivity. Qed.
-End B64_FORMAT.
-
-Module B64 := MakeIEEE (B64_FORMAT). *)
\ No newline at end of file
+Arguments le_not_nan_r {prec} {emax}.
\ No newline at end of file
diff --git a/src_common/ieee/coq/Rextended.v b/src_common/ieee/coq/Rextended.v
index ee50bf208..b93e3aedb 100644
--- a/src_common/ieee/coq/Rextended.v
+++ b/src_common/ieee/coq/Rextended.v
@@ -1,6 +1,10 @@
 From Flocq Require Import IEEE754.BinarySingleNaN.
 From Coq Require Import ZArith Psatz Reals.
 
+(*********************************************************
+       Extension of R with special values +oo, -oo
+**********************************************************)
+
 Set Implicit Arguments.
 
 Section Rextended.
@@ -99,18 +103,74 @@ Definition B2Rx (x : float) :=
   | _ => Real (B2R x)
   end.
 
+
 Lemma B2Rx_finite :
   forall (f : float),
   is_finite f = true -> B2Rx f = Real (B2R f).
 Proof. now destruct f. Qed.
 
+Lemma B2Rx_le :
+  forall (x y : float),
+  is_nan x = false ->
+  is_nan y = false ->
+  leb (B2Rx x) (B2Rx y) = true ->
+  Bleb x y = true.
+Proof.
+  intros.
+  destruct x as [[ ] | [ ] | | ] eqn:E1; destruct y as [ [ ] | [ ] | | ] eqn:E2; try easy;
+  rewrite <- E1, <- E2 in *;
+  rewrite B2Rx_finite in H1 by (rewrite E1; auto);
+  rewrite B2Rx_finite in H1 by (rewrite E2; auto);
+  unfold leb in H1;
+  unfold Bleb, SpecFloat.SFleb;
+  replace (SpecFloat.SFcompare (B2SF x) (B2SF y)) with (Bcompare x y) by auto;
+  assert (Fx: is_finite x = true) by (rewrite E1; auto);
+  assert (Fy: is_finite y = true) by (rewrite E2; auto);
+  rewrite (Bcompare_correct _ _ x y Fx Fy);
+  destruct Raux.Rcompare eqn:E; auto;
+  apply Raux.Rcompare_Gt_inv in E;
+  destruct (Raux.Rle_bool_spec (B2R x) (B2R y)); auto; lra.
+Qed.
+
+Ltac fdestruct f :=
+  destruct f as [ [ ] | [ ] | | ] eqn:?E; try easy.
+
 Lemma B2Rx_B2R :
   forall (x : float),
   is_finite x = true ->
   B2Rx x = Real (B2R x).
 Proof. now intros [ ] Fx. Qed.
 
+Lemma le_B2Rx :
+  forall (x y : float),
+  Bleb x y = true ->
+  leb (B2Rx x) (B2Rx y) = true.
+Proof.
+  Ltac by_comparison :=
+    match goal with
+    | [ x : _, y : _, E : _, E0 : _, H : _ |- _ ] =>
+      rewrite <- E, <- E0 in H;
+      unfold Bleb, SpecFloat.SFleb in H;
+      replace (SpecFloat.SFcompare (B2SF _) (B2SF _)) with (Bcompare x y) in H by auto;
+      rewrite E, E0 in *;
+      rewrite Bcompare_correct in H by auto;
+      rewrite B2Rx_B2R by auto;
+      rewrite B2Rx_B2R, leb_real by auto;
+      destruct (Raux.Rcompare _) eqn:Cmp in H; try easy;
+      [ apply Raux.Rcompare_Eq_inv in Cmp | apply Raux.Rcompare_Lt_inv in Cmp ];
+      apply Raux.Rle_bool_true; lra
+    end.
+  Ltac by_computation :=
+      simpl; apply Raux.Rle_bool_true; lra.
+  intros.
+  fdestruct x; fdestruct y; try by_computation; by_comparison.
+Qed.
+
 End Rextended.
 
 Arguments round {prec} {emax}.
-Arguments B2Rx {prec} {emax}.
\ No newline at end of file
+Arguments B2Rx {prec} {emax}.
+Arguments B2Rx_le {prec} {emax}.
+Arguments le_B2Rx {prec} {emax}.
+Arguments B2Rx_B2R {prec} {emax}.
+Arguments B2Rx_finite {prec} {emax}.
-- 
GitLab