From 2f9037bbced8bd1cfd15c215154a14fd0758b10d Mon Sep 17 00:00:00 2001
From: Arthur Correnson <arthur.correnson@gmail.com>
Date: Tue, 20 Jul 2021 18:00:51 +0200
Subject: [PATCH] add a module for extraction

---
 src_common/ieee/coq/Colibri2_interval.v | 176 ++++++++---------------
 src_common/ieee/coq/Interval.v          | 180 +++++++++++++++++++++++-
 2 files changed, 234 insertions(+), 122 deletions(-)

diff --git a/src_common/ieee/coq/Colibri2_interval.v b/src_common/ieee/coq/Colibri2_interval.v
index 8724b1f28..29573a66e 100644
--- a/src_common/ieee/coq/Colibri2_interval.v
+++ b/src_common/ieee/coq/Colibri2_interval.v
@@ -1,127 +1,61 @@
-From Coq Require Import ZArith Extraction Bool.
-From F Require Import Utils Interval.
+From Coq Require Import ZArith Extraction Bool Psatz.
 From Flocq Require Import IEEE754.BinarySingleNaN FLX.
+From F Require Import Utils Interval.
+
+Module Intv32.
+  Definition prec := 24%Z.
+  Definition emax := 128%Z.
+  Definition float32 := float prec emax.
+
+  Lemma Hprec : Prec_gt_0 prec.
+  Proof. unfold Prec_gt_0, prec; lia. Qed.
+
+  Lemma Hemax : Prec_lt_emax prec emax.
+  Proof. unfold Prec_lt_emax, prec, emax; lia. Qed.
+
+  Definition t := Interval prec emax.
+
+  Program Definition contains : t -> float32 -> Prop := contains prec emax.
+
+  Definition inter : t -> t -> t := @inter prec emax.
+
+  Definition add : mode -> t -> t -> t := @Iadd prec emax Hprec Hemax.
+
+  Lemma inter_correct :
+    forall (i1 i2 : t) (x : float32),
+      contains i1 x -> contains i2 x -> contains (inter i1 i2) x. 
+  Proof. apply (inter_correct prec emax). Qed.
+
+  Lemma inter_precise :
+    forall (i1 i2 : t) (x : float32),
+      contains (inter i1 i2) x -> contains i1 x /\ contains i2 x.
+  Proof.
+    intros; split.
+    - apply (inter_precise_l prec emax _ _ _ H).
+    - apply (inter_precise_r prec emax _ _ _ H).
+  Qed.
+
+  Lemma add_correct :
+    forall (m : mode) (i1 i2 : t) (x y : float32),
+      contains i1 x -> contains i2 y -> contains (add m i1 i2) (@Bplus prec emax Hprec Hemax m x y).
+  Proof. apply Iadd_correct. Qed.
+
+  Program Definition top : t := Some (Intv prec emax -oo +oo true).
 
-Section Colibri2_interval.
-
-Variable prec : Z.
-Variable emax : Z.
-Context (Hprec : Prec_gt_0 prec).
-Context (Hemax : Prec_lt_emax prec emax).
-
-Definition float := binary_float prec emax.
-
-Inductive Interval' :=
- | Inan : Interval'
- | Intv : forall (lo hi : float) (nan : bool), Interval'.
-
-Definition valid (I : option Interval') :=
-  match I with
-  | Some (Intv lo hi _) => lo <= hi
-  | _ => True
-  end.
-
-Definition Interval := { I : option Interval' | valid I }.
-
-Program Definition contains (I : option Interval') (x : float) : Prop :=
-  match I with
-  | None => False
-  | Some Inan => is_nan x = true
-  | Some (Intv lo hi nan) =>
-    lo <= x <= hi \/ (is_nan x && nan = true)
-  end.
-
-Program Definition inter' (I1 I2 : option Interval') : option Interval' :=
-  match I1, I2 with
-  | None, _ => None
-  | _, None => None
-  | Some Inan, Some Inan => Some Inan
-  | Some Inan, Some (Intv _ _ nan) =>
-    if nan then Some Inan else None
-  | Some (Intv _ _ nan), Some (Inan) =>
-    if nan then Some (Inan) else None
-  | Some (Intv lo1 hi1 nan1), Some (Intv lo2 hi2 nan2) =>
-    if Bltb hi1 lo2 || Bltb hi2 lo1 then
-      if nan1 && nan2 then Some Inan else None
-    else
-      Some (Intv (Bmax lo1 lo2) (Bmin hi1 hi2) (nan1 && nan2))
-  end.
-
-Ltac ieasy :=
-  simpl in *; try easy; try (intuition; fail).
-
-Ltac sdestruct x :=
-  try destruct x; simpl; easy.
-  
-
-Program Definition inter (I1 I2 : Interval) : Interval :=
-  inter' I1 I2.
-Next Obligation with auto.
-  destruct I1 as [[[ | lo1 hi1 nan1]|] H1], I2 as [[[ | lo2 hi2 nan2]|] H2]; ieasy; try (now destruct nan1 || now destruct nan2).
-  case (Bltb (hi1) (lo2)) eqn:?, (Bltb (hi2) (lo1)) eqn:?; simpl; try (destruct nan1, nan2; simpl; easy).
-  pose proof (le_not_nan_l _ _ H1).
-  pose proof (le_not_nan_r _ _ H2).
-  pose proof (le_not_nan_r _ _ H1).
-  pose proof (le_not_nan_l _ _ H2).
-  auto using Bmax_le, Bmin_le, Bltb_false_Bleb.
-Defined.
-
-Program Lemma inter_precise_l :
-  forall I1 I2, forall x, contains (inter I1 I2) x -> contains I1 x.
-Proof with auto.
-  intros [[[|lo1 hi1 [ ]]|] H1] [[[|lo2 hi2 [ ]]|] H2] x Hx; simpl in *...
-  + intuition.
-  + case (Bltb hi1 lo2) eqn:?, (Bltb hi2 lo1) eqn:?; simpl in *; intuition.
-    left; split; [ apply (Bmax_le_inv _ _ _ _ _ H0) | apply (Bmin_le_inv _ _ _ _ _ H3) ].
-  + case (Bltb hi1 lo2) eqn:?, (Bltb hi2 lo1) eqn:?; simpl in *; intuition.
-    - left; split; [apply (Bmax_le_inv _ _ _ _ _ H0) | apply (Bmin_le_inv _ _ _ _ _ H3) ].
-    - destruct x...
-  + case (Bltb hi1 lo2) eqn:?, (Bltb hi2 lo1) eqn:?; simpl in *; intuition.
-    left; split; [ apply (Bmax_le_inv _ _ _ _ _ H0) | apply (Bmin_le_inv _ _ _ _ _ H3) ].
-  + case (Bltb hi1 lo2) eqn:?, (Bltb hi2 lo1) eqn:?; simpl in *; intuition.
-    left; split; [ apply (Bmax_le_inv _ _ _ _ _ H0) | apply (Bmin_le_inv _ _ _ _ _ H3) ].
-Qed.
-
-Program Lemma inter_precise_r :
-  forall I1 I2, forall x, contains (inter I1 I2) x -> contains I2 x.
-Proof with auto.
-  intros [[[|lo1 hi1 [ ]]|] H1] [[[|lo2 hi2 [ ]]|] H2] x Hx; simpl in *...
-  + intuition.
-  + case (Bltb hi1 lo2) eqn:?, (Bltb hi2 lo1) eqn:?; simpl in *; intuition.
-    left; split; [ apply (Bmax_le_inv _ _ _ _ _ H0) | apply (Bmin_le_inv _ _ _ _ _ H3) ].
-  + case (Bltb hi1 lo2) eqn:?, (Bltb hi2 lo1) eqn:?; simpl in *; intuition.
-    left; split; [apply (Bmax_le_inv _ _ _ _ _ H0) | apply (Bmin_le_inv _ _ _ _ _ H3) ].
-  + case (Bltb hi1 lo2) eqn:?, (Bltb hi2 lo1) eqn:?; simpl in *; intuition.
-    - left; split; [ apply (Bmax_le_inv _ _ _ _ _ H0) | apply (Bmin_le_inv _ _ _ _ _ H3) ].
-    - destruct x...
-  + case (Bltb hi1 lo2) eqn:?, (Bltb hi2 lo1) eqn:?; simpl in *; intuition.
-    left; split; [ apply (Bmax_le_inv _ _ _ _ _ H0) | apply (Bmin_le_inv _ _ _ _ _ H3) ].
-Qed.
-
-Program Lemma inter_correct :
-  forall (I1 I2 : Interval), forall x,  contains I1 x -> contains I2 x -> contains (inter I1 I2) x.
-Proof with auto.
-  intros [[[|lo1 hi1 nan1]|] H1] [[[|lo2 hi2 nan2]|] H2] x Hx1 Hx2; simpl in *...
-  - fdestruct x; destruct nan2, Hx2; try easy.
-  - fdestruct x; destruct nan1, Hx1; try easy.
-  - pose proof (le_not_nan_l _ _ H1).
-    pose proof (le_not_nan_r _ _ H1).
-    pose proof (le_not_nan_l _ _ H2).
-    pose proof (le_not_nan_r _ _ H2).
-    destruct Hx1 as [[Hc1 Hc1'] |], Hx2 as [[Hc2 Hc2'] |]; try (fdestruct x ; fail).
-    + pose proof (Hlt1 := Bleb_trans _ _ _ _ _ Hc2 Hc1').
-      apply Bleb_true_Bltb in Hlt1...
-      pose proof (Hlt2 := Bleb_trans _ _ _ _ _ Hc1 Hc2').
-      apply Bleb_true_Bltb in Hlt2...
-      rewrite Hlt1, Hlt2; simpl; left; split; auto using Bmax_le, Bmin_le.
-    + fdestruct x; destruct nan2, nan1, (Bltb hi1 _), (Bltb hi2); simpl; try easy.
-      now right.
-Qed.
-
-End Colibri2_interval.
-
-Recursive Extraction Interval.
+  Program Definition bot : t := None.
 
+  Lemma top_correct :
+    forall (x : float32), contains top x.
+  Proof with auto.
+    unfold top, contains; fdestruct x; simpl...
+  Qed.
 
+  Lemma bot_correct :
+    forall (x : float32), contains bot x -> False.
+  Proof with auto.
+    unfold bot, contains; fdestruct x.
+  Qed.
 
+End Intv32.
 
+Recursive Extraction Intv32.
diff --git a/src_common/ieee/coq/Interval.v b/src_common/ieee/coq/Interval.v
index 7ea3fdf19..a60513f92 100644
--- a/src_common/ieee/coq/Interval.v
+++ b/src_common/ieee/coq/Interval.v
@@ -15,6 +15,184 @@ Context (Hemax : Prec_lt_emax prec emax).
 
 Definition float := binary_float prec emax.
 
+Inductive Interval' :=
+ | Inan : Interval'
+ | Intv : forall (lo hi : float) (nan : bool), Interval'.
+
+Definition valid (I : option Interval') :=
+  match I with
+  | Some (Intv lo hi _) => lo <= hi
+  | _ => True
+  end.
+
+Definition Interval := { I : option Interval' | valid I }.
+
+Program Definition contains (I : option Interval') (x : float) : Prop :=
+  match I with
+  | None => False
+  | Some Inan => is_nan x = true
+  | Some (Intv lo hi nan) =>
+    lo <= x <= hi \/ (is_nan x && nan = true)
+  end.
+
+Program Definition inter' (I1 I2 : option Interval') : option Interval' :=
+  match I1, I2 with
+  | None, _ => None
+  | _, None => None
+  | Some Inan, Some Inan => Some Inan
+  | Some Inan, Some (Intv _ _ nan) =>
+    if nan then Some Inan else None
+  | Some (Intv _ _ nan), Some (Inan) =>
+    if nan then Some (Inan) else None
+  | Some (Intv lo1 hi1 nan1), Some (Intv lo2 hi2 nan2) =>
+    if Bltb hi1 lo2 || Bltb hi2 lo1 then
+      if nan1 && nan2 then Some Inan else None
+    else
+      Some (Intv (Bmax lo1 lo2) (Bmin hi1 hi2) (nan1 && nan2))
+  end.
+
+Ltac ieasy :=
+  simpl in *; try easy; try (intuition; fail).
+
+Ltac sdestruct x :=
+  try destruct x; simpl; easy.
+  
+
+Program Definition inter (I1 I2 : Interval) : Interval :=
+  inter' I1 I2.
+Next Obligation with auto.
+  destruct I1 as [[[ | lo1 hi1 nan1]|] H1], I2 as [[[ | lo2 hi2 nan2]|] H2]; ieasy; try (now destruct nan1 || now destruct nan2).
+  case (Bltb (hi1) (lo2)) eqn:?, (Bltb (hi2) (lo1)) eqn:?; simpl; try (destruct nan1, nan2; simpl; easy).
+  pose proof (le_not_nan_l _ _ H1).
+  pose proof (le_not_nan_r _ _ H2).
+  pose proof (le_not_nan_r _ _ H1).
+  pose proof (le_not_nan_l _ _ H2).
+  auto using Bmax_le, Bmin_le, Bltb_false_Bleb.
+Defined.
+
+Program Lemma inter_precise_l :
+  forall I1 I2, forall x, contains (inter I1 I2) x -> contains I1 x.
+Proof with auto.
+  intros [[[|lo1 hi1 nan1]|] H1] [[[|lo2 hi2 nan2]|] H2] x Hx; simpl in *...
+  + destruct nan2; fdestruct x.
+  + right; destruct nan1; fdestruct x.
+  + case (Bltb hi1 lo2) eqn:?, (Bltb hi2 lo1) eqn:?; simpl in *;
+    try (right; destruct nan1, nan2; simpl in *; fdestruct x; fail).
+    destruct Hx as [[Hc1 Hc2] | H ].
+    - left; split; [ apply (Bmax_le_inv _ _ _ _ _ Hc1) | apply (Bmin_le_inv _ _ _ _ _ Hc2) ].
+    - repeat rewrite andb_true_iff in H; intuition.
+Qed.
+
+Program Lemma inter_precise_r :
+  forall I1 I2, forall x, contains (inter I1 I2) x -> contains I2 x.
+Proof with auto.
+  intros [[[|lo1 hi1 nan1]|] H1] [[[|lo2 hi2 nan2]|] H2] x Hx; simpl in *...
+  + right; destruct nan2; fdestruct x.
+  + destruct nan1; fdestruct x.
+  + case (Bltb hi1 lo2) eqn:?, (Bltb hi2 lo1) eqn:?; simpl in *;
+    try (right; destruct nan1, nan2; simpl in *; fdestruct x; fail).
+    destruct Hx as [[Hc1 Hc2] | H ].
+    - left; split; [ apply (Bmax_le_inv _ _ _ _ _ Hc1) | apply (Bmin_le_inv _ _ _ _ _ Hc2) ].
+    - repeat rewrite andb_true_iff in H; intuition.
+Qed.
+
+Program Lemma inter_correct :
+  forall (I1 I2 : Interval), forall x,  contains I1 x -> contains I2 x -> contains (inter I1 I2) x.
+Proof with auto.
+  intros [[[|lo1 hi1 nan1]|] H1] [[[|lo2 hi2 nan2]|] H2] x Hx1 Hx2; simpl in *...
+  - fdestruct x; destruct nan2, Hx2; try easy.
+  - fdestruct x; destruct nan1, Hx1; try easy.
+  - pose proof (le_not_nan_l _ _ H1).
+    pose proof (le_not_nan_r _ _ H1).
+    pose proof (le_not_nan_l _ _ H2).
+    pose proof (le_not_nan_r _ _ H2).
+    destruct Hx1 as [[Hc1 Hc1'] |], Hx2 as [[Hc2 Hc2'] |]; try (fdestruct x ; fail).
+    + pose proof (Hlt1 := Bleb_trans _ _ _ _ _ Hc2 Hc1').
+      apply Bleb_true_Bltb in Hlt1...
+      pose proof (Hlt2 := Bleb_trans _ _ _ _ _ Hc1 Hc2').
+      apply Bleb_true_Bltb in Hlt2...
+      rewrite Hlt1, Hlt2; simpl; left; split; auto using Bmax_le, Bmin_le.
+    + fdestruct x; destruct nan2, nan1, (Bltb hi1 _), (Bltb hi2); simpl; try easy.
+      now right.
+Qed.
+
+Definition Iadd' (m : mode) (I1 I2 : option Interval') : option Interval' :=
+  match I1, I2 with
+  | None, _ => None
+  | _, None => None
+  | Some Inan, _ => Some Inan
+  | _, Some Inan => Some Inan
+  | Some (Intv l h n) as i1, Some (Intv l' h' n') as i2 =>
+    let sum1 := Bplus m l l' in
+    let sum2 := Bplus m h h' in
+    match is_nan sum1 with
+    | true =>
+      match is_nan sum2 with
+      | true => Some Inan
+      | false => Some (Intv +oo +oo true)
+      end
+    | false =>
+      match is_nan sum2 with
+      | true => Some (Intv -oo -oo true)
+      | false => Some (Intv sum1 sum2 (n || n' || (Beqb h +oo && Beqb l' -oo) || (Beqb h' +oo && Beqb l -oo)))
+      end
+    end
+  end.
+
+Program Definition Iadd (m : mode) (I1 I2 : Interval) : Interval :=
+  Iadd' m I1 I2.
+Next Obligation with auto.
+  destruct I1 as [[[ | l1 h1 ]|] H1], I2 as [[[ | l2 h2 ]|] H2]; simpl in *...
+  destruct (is_nan (Bplus m l1 l2)) eqn:E1, (is_nan (Bplus m h1 h2)) eqn:E2; try easy; simpl.
+  apply B2Rx_le; auto.
+  repeat (rewrite Bplus_correct; auto).
+  apply round_le.
+  eapply leb_trans.
+  - apply (add_leb_mono_l _ _ _ (le_B2Rx _ _ H1)).
+  - apply (add_leb_mono_r _ _ _ (le_B2Rx _ _ H2)).
+Qed.
+
+Ltac tryit t a :=
+  try (t a; fail).
+
+
+Program Lemma Iadd_correct :
+  forall m (I1 I2 : Interval) (x y : float), contains I1 x -> contains I2 y -> contains (Iadd m I1 I2) (Bplus m x y).
+Proof with auto.
+  intros m [[[ | l1 h1 ]|] H1] [[[ | l2 h2 ]|] H2] x y Hx Hy; simpl in *; try (fdestruct x; fdestruct y; fail).
+  case (is_nan (Bplus m l1 l2)) eqn:E1, (is_nan (Bplus m h1 h2)) eqn:E2; intuition; simpl.
+  all: try (fdestruct x; fdestruct y; simpl; auto; fail).
+  - destruct (Bplus_nan_inv _ _ _ E1); intuition; subst; try easy.
+    * rewrite (infp_le_is_infp _ _ _ H0) in *.
+      rewrite (infp_le_is_infp _ _ _ H1) in *.
+      fdestruct h2.
+      rewrite (le_infm_is_infm _ _ _ H5) in *...
+    * rewrite (infp_le_is_infp _ _ _ H4) in *.
+      rewrite (infp_le_is_infp _ _ _ H2) in *.
+      fdestruct h1.
+      rewrite (le_infm_is_infm _ _ _ H3) in *...
+  - destruct (Bplus_nan_inv _ _ _ E1) as [[ -> -> ] | [ [ -> -> ] | [ -> | -> ]]]; try easy;
+    fdestruct x; fdestruct y; simpl...
+  - destruct (Bplus_nan_inv _ _ _ E2) as [[ -> -> ] | [ [ -> -> ] | [ -> | -> ]]]; try easy;
+    fdestruct x; fdestruct y; simpl...
+  - destruct (is_nan (Bplus m x y)) eqn:E.
+    + right. destruct (Bplus_nan_inv _ _ _ E) as [ [-> ->] | [ [ -> -> ] | ] ].
+      * rewrite (infp_le_is_infp _ _ _ H3) in *.
+        rewrite (le_infm_is_infm _ _ _ H4) in *.
+        fdestruct l2; simpl; fdestruct h1; simpl; intuition.
+      * rewrite (infp_le_is_infp _ _ _ H5) in *.
+        rewrite (le_infm_is_infm _ _ _ H0) in *.
+        fdestruct h1; simpl; fdestruct l2; simpl; intuition.
+      * destruct H as [ -> | -> ]; fdestruct h1.
+    + left. split; now apply Bplus_le_compat'.
+  - right; fdestruct y; fdestruct x; destruct nan0; simpl; intuition.
+  - right; fdestruct y; fdestruct x; destruct nan; simpl; intuition.
+  - right; fdestruct y; fdestruct x; destruct nan; simpl; intuition.
+Qed.
+
+
+(* Definition float := binary_float prec emax.
+
 Inductive Interval_aux :=
   | I_Bot : Interval_aux
   | I_nan : Interval_aux
@@ -315,6 +493,6 @@ Proof.
     * apply Bltb_true_Bleb in E2; auto.
       now rewrite (Bleb_trans _ _ _ _ _ Hc1 Hc2') in E2.
     * left; split; [ now apply Bmax_le | now apply Bmin_le ].
-Qed.
+Qed. *)
 
 End Finterval.
\ No newline at end of file
-- 
GitLab