Module FloatIntervalsForward
Require Import Coqlib Utf8 Util FastArith.
Require Import AdomLib.
Require Import ZIntervals.
Require Import Integers.
Require Import FloatLib.
Require Import FloatIntervals.
Transparent Float.neg.
Definition forward_fabs (
x:
fitv+⊤) :
fitv+⊤ :=
match x with
|
Just (
FITV mx Mx) =>
match Bsign mx,
Bsign Mx with
|
true,
true =>
Just (
FITV (
Float.neg Mx) (
Float.neg mx))
|
true,
false =>
Just (
FITV (
B754_zero false)
(
if Fleb Mx (
Float.neg mx)
then (
Float.neg mx)
else Mx))
|
false,
false =>
x
|
false,
true =>
All
end
|
All =>
All
end.
Lemma forward_fabs_correct:
∀
x x_ab,
x ∈ γ
x_ab -> (
Float.abs x) ∈ γ (
forward_fabs x_ab).
Proof.
Definition forward_fadd (
x y:
fitv+⊤) :
fitv+⊤+⊥ :=
match x,
y with
|
Just (
FITV mx Mx),
Just (
FITV my My) =>
if Fleb mx (
B754_infinity true) &&
Fleb (
B754_infinity false)
My then
NotBot All
else if Fleb my (
B754_infinity true) &&
Fleb (
B754_infinity false)
Mx then
NotBot All
else
NotBot (
Just (
FITV (
Float.add mx my) (
Float.add Mx My)))
|
All,
_ |
_,
All =>
NotBot All
end.
Lemma fadd_is_nan:
forall a b pl,
is_nan a =
false ->
is_nan b =
false ->
(
forall s,
a =
B754_infinity s ->
b =
B754_infinity (
negb s) ->
False) ->
is_nan (
Bplus 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a b) =
false.
Proof.
intros.
destruct a as [[]| | |],
b as [[]| | |];
try discriminate;
try reflexivity.
specialize (
H1 _ eq_refl).
destruct b,
b0;
now intuition.
apply binary_normalize_is_nan.
Qed.
Lemma fadd_Fleb_compat:
forall pl a b c,
is_nan a =
false ->
(
forall s,
a =
B754_infinity s ->
b <>
B754_infinity (
negb s) /\
c <>
B754_infinity (
negb s)) ->
Fleb b c =
true ->
Fleb (
Bplus 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a b)
(
Bplus 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a c) =
true.
Proof.
intros.
assert (
is_nan (
Bplus 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a b) =
false).
{
apply fadd_is_nan;
eauto 2.
intros.
specialize (
H0 s).
intuition. }
assert (
is_nan (
Bplus 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a c) =
false).
{
apply fadd_is_nan;
eauto 2.
intros.
specialize (
H0 s).
intuition. }
destruct (
is_finite a)
eqn:
FINa.
destruct (
is_finite b)
eqn:
FINb.
destruct (
is_finite c)
eqn:
FINc.
-
pose proof H1.
rewrite Fleb_Rle in H1 by auto.
Rle_bool_case H1. 2:
discriminate.
use_float_specs.
assert (
round radix2 (
FLT_exp (3 - 1024 - 53) 53) (
round_mode mode_NE) (
a +
b) <=
round radix2 (
FLT_exp (3 - 1024 - 53) 53) (
round_mode mode_NE) (
a +
c)).
{
apply round_le;
auto.
Psatz.lra. }
repeat match goal with
|
A : ?
X ->
_,
B:?
X |-
_ =>
specialize (
A B)
|
H :
context [
Rlt_bool ?
a ?
b] |-
_ =>
Rlt_bool_case H;
[
destruct H as [? [? ?]]|
destruct H as [
H ?];
unfold binary_overflow in H;
simpl in H;
apply B2FF_inj with (
y:=@
B754_infinity 53
_ _)
in H]
end.
+
rewrite Fleb_Rle by auto.
rewrite H6,
H7.
auto using Rle_bool_true.
+
rewrite H6.
replace (
Bsign a)
with false.
match goal with |-
Fleb ?
f _ =
true =>
destruct f as [| | |[]]
end;
try discriminate;
reflexivity.
assert (0 <
round radix2 (
FLT_exp (3 - 1024 - 53) 53) (
round_mode mode_NE) (
a +
c)).
{
unfold Rabs in H9,
H12.
destruct Rcase_abs,
Rcase_abs;
Psatz.lra. }
destruct a,
c;
try discriminate.
*
rewrite Rplus_0_l,
round_0 in H14 by eauto.
Psatz.lra.
*
destruct b1;
simpl in H13 |- *. 2:
congruence.
subst b0.
assert (
forall x y, ~
x+
y <= 0 ->
x <= 0 ->
y <= 0 ->
False)
by (
intros ? ?
A ? ?;
apply A;
Psatz.lra).
edestruct H13;
try apply F2R_le_0_compat.
intro.
contradict H14.
erewrite <-
round_0 by eauto.
apply RIneq.Rle_not_lt,
round_le;
eauto.
compute;
discriminate.
compute;
discriminate.
+
rewrite H7.
replace (
Bsign a)
with true.
match goal with |-
Fleb _ ?
f =
true =>
destruct f end;
try discriminate;
reflexivity.
assert (
round radix2 (
FLT_exp (3 - 1024 - 53) 53) (
round_mode mode_NE) (
a +
b) < 0).
{
unfold Rabs in H9,
H11.
destruct Rcase_abs,
Rcase_abs;
Psatz.lra. }
destruct a,
b;
try discriminate.
*
rewrite Rplus_0_l,
round_0 in H14 by eauto.
Psatz.lra.
*
destruct b;
simpl in H10 |- *.
congruence.
subst b0.
assert (
forall x y, ~ 0 <=
x+
y -> 0 <=
x -> 0 <=
y ->
False)
by (
intros ? ?
A ? ?;
apply A;
Psatz.lra).
edestruct H10;
try apply F2R_ge_0_compat.
intro.
contradict H14.
erewrite <-
round_0 by eauto.
apply RIneq.Rle_not_lt,
round_le;
eauto.
compute;
discriminate.
compute;
discriminate.
+
rewrite H6,
H7,
H12.
destruct c as [[]| | |[]];
try discriminate;
reflexivity.
-
assert (
is_nan c =
false)
by eauto.
destruct c as [[]|[]| |[]];
try discriminate.
destruct b as [| | |[]];
discriminate.
destruct a;
try discriminate;
match goal with |-
Fleb ?
f _ =
true =>
destruct f as [|[]| |[]]
end;
try discriminate;
reflexivity.
-
assert (
is_nan b =
false)
by eauto.
destruct b as [[]|[]| |[]];
try discriminate.
destruct a;
try discriminate;
match goal with |-
Fleb _ ?
f =
true =>
destruct f as [|[]| |[]]
end;
try discriminate;
reflexivity.
destruct c as [|[]| |];
try discriminate.
auto.
-
destruct a as [|[]| |],
b as [|[]| |],
c as [|[]| |];
try reflexivity;
discriminate.
Qed.
Lemma forward_fadd_correct:
∀
x x_ab y y_ab,
x ∈ γ
x_ab ->
y ∈ γ
y_ab ->
(
Float.add x y) ∈ γ (
forward_fadd x_ab y_ab).
Proof.
Definition forward_fsub (
x y:
fitv+⊤) :
fitv+⊤+⊥ :=
forward_fadd x (
forward_fneg y).
Lemma forward_fsub_correct:
∀
x x_ab y y_ab,
x ∈ γ
x_ab ->
y ∈ γ
y_ab ->
(
Float.sub x y) ∈ γ (
forward_fsub x_ab y_ab).
Proof.
Definition mult_nan_criterion (
a b:
float) :
bool :=
match a,
b with
|
B754_infinity _,
B754_zero _ |
B754_zero _,
B754_infinity _ =>
false
|
B754_nan _ _,
_ |
_,
B754_nan _ _ =>
false
|
_,
_ =>
true
end.
Lemma fmult_is_nan:
forall a b pl,
mult_nan_criterion a b =
true ->
is_nan (
Bmult 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a b) =
false.
Proof.
intros.
use_float_specs.
destruct a as [| | |],
b as [| | |];
try discriminate;
try reflexivity.
destruct Rlt_bool.
-
destruct H0 as [? []].
destruct Bmult;
try discriminate;
reflexivity.
-
destruct Bmult as [| |? []|];
try discriminate;
reflexivity.
Qed.
Lemma fmult_Fleb_compat:
forall pl a b c,
mult_nan_criterion a b =
true ->
mult_nan_criterion a c =
true ->
Bsign a =
false ->
Fleb b c =
true ->
Fleb (
Bmult 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a b)
(
Bmult 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a c) =
true.
Proof.
intros.
assert (
is_nan (
Bmult 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a b) =
false)
by (
apply fmult_is_nan;
easy).
assert (
is_nan (
Bmult 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a c) =
false)
by (
apply fmult_is_nan;
easy).
destruct (
is_finite a)
eqn:
FINa.
destruct (
is_finite b)
eqn:
FINb.
destruct (
is_finite c)
eqn:
FINc.
-
rewrite Fleb_Rle in H2 by auto.
Rle_bool_case H2. 2:
discriminate.
use_float_specs.
assert (
round radix2 (
FLT_exp (3 - 1024 - 53) 53) (
round_mode mode_NE) (
a *
b) <=
round radix2 (
FLT_exp (3 - 1024 - 53) 53) (
round_mode mode_NE) (
a *
c)).
{
apply round_le,
Rmult_le_compat_l;
auto.
destruct a;
try discriminate;
simpl in H1;
subst;
simpl.
Psatz.lra.
apply F2R_ge_0_compat.
compute;
discriminate. }
repeat match goal with H :
context [
Rlt_bool ?
a ?
b] |-
_ =>
Rlt_bool_case H;
[
rewrite FINa, ?
FINb, ?
FINc in H;
destruct H as [
H []]|
unfold binary_overflow in H;
simpl in H;
apply B2FF_inj with (
y:=@
B754_infinity 53
_ _)
in H]
end.
+
rewrite Fleb_Rle,
H6,
H7 by auto.
auto using Rle_bool_true.
+
rewrite H6,
H1.
replace (
Bsign c)
with false.
match goal with |-
Fleb ?
f _ =
true =>
destruct f as [| | |[]]
end;
try discriminate;
reflexivity.
assert (0 <
round radix2 (
FLT_exp (3 - 1024 - 53) 53) (
round_mode mode_NE) (
a *
c)).
{
unfold Rabs in H9,
H12.
destruct Rcase_abs,
Rcase_abs;
Psatz.lra. }
destruct a,
c;
try discriminate.
simpl in H1;
subst b0.
destruct b1;
simpl;
try reflexivity.
apply RIneq.Rle_not_lt in H13.
easy.
erewrite <-
round_0 by eauto.
apply round_le;
auto.
erewrite <-
Rmult_0_r.
apply Rmult_le_compat_l.
apply F2R_ge_0_compat;
compute;
discriminate.
apply F2R_le_0_compat;
compute;
discriminate.
+
rewrite H7,
H1.
replace (
Bsign b)
with true.
match goal with |-
Fleb _ ?
f =
true =>
destruct f end;
try discriminate;
reflexivity.
assert (
round radix2 (
FLT_exp (3 - 1024 - 53) 53) (
round_mode mode_NE) (
a *
b) < 0).
{
unfold Rabs in H9,
H10.
destruct Rcase_abs,
Rcase_abs;
Psatz.lra. }
destruct a,
b;
try discriminate.
simpl in H1;
subst b0.
destruct b;
simpl;
try reflexivity.
apply RIneq.Rle_not_lt in H13.
easy.
erewrite <-
round_0 by eauto.
apply round_le,
Rmult_le_pos;
eauto;
apply F2R_ge_0_compat;
compute;
discriminate.
+
assert (~
bpow radix2 1024 <= 0).
{
rewrite <-
Z2R_Zpower by omega.
intro.
apply le_Z2R with (
n:=
Z0)
in H11.
apply H11.
reflexivity. }
rewrite H6,
H7,
H1.
destruct b as [[]| | |[]],
c as [[]| | |[]];
try discriminate;
try reflexivity;
try (
rewrite Rmult_0_r,
round_0,
Rabs_R0 in *
by auto;
easy).
simpl.
eapply Rle_trans in H5.
eapply RIneq.Rle_not_lt in H5.
destruct H5.
apply F2R_lt_0_compat.
reflexivity.
apply F2R_ge_0_compat.
compute;
discriminate.
-
destruct a,
c;
try discriminate.
simpl in H1.
subst.
destruct b1.
destruct b as [| | |[]];
discriminate.
match goal with |-
Fleb ?
f _ =
true =>
destruct f as [|[]| |[]]
end;
try reflexivity.
discriminate.
-
destruct a,
b;
try discriminate.
simpl in H1.
subst.
destruct b.
match goal with |-
Fleb _ ?
f =
true =>
destruct f as [|[]| |[]]
end;
try reflexivity.
discriminate.
destruct c as [|[]| |];
try discriminate;
reflexivity.
-
destruct a;
try discriminate.
simpl in H1.
subst.
destruct b as [|[]| |[]],
c as [|[]| |[]];
try discriminate;
reflexivity.
Qed.
Lemma fmult_neg:
forall pl a b,
mult_nan_criterion a b =
true ->
Bmult 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE (
Float.neg a)
b =
Float.neg (
Bmult 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a b).
Proof.
intros.
assert (
Bsign_Bopp:
forall f:
float,
Bsign (
Bopp _ _ Float.neg_pl f) =
negb (
Bsign f))
by (
destruct f;
easy).
unfold Float.neg.
destruct (
is_finite a)
eqn:?.
destruct (
is_finite b)
eqn:?.
-
use_float_specs.
unfold round_mode in H0.
rewrite B2R_Bopp,
Ropp_mult_distr_l_reverse,
round_NE_opp,
Rabs_Ropp,
is_finite_Bopp in H0.
fold (
round_mode mode_NE)
in H0.
destruct Rlt_bool.
+
destruct H0 as [? []],
H1 as [? []].
apply B2R_Bsign_inj.
*
rewrite H2,
Heqb0,
Heqb1.
easy.
*
rewrite is_finite_Bopp,
H4,
Heqb0,
Heqb1.
easy.
*
rewrite B2R_Bopp,
H1,
H0.
easy.
*
rewrite Bsign_Bopp,
H5,
H3,
negb_xorb_l,
Bsign_Bopp.
easy.
clear -
H2 Heqb0 Heqb1.
destruct Bmult;
try reflexivity.
rewrite Heqb0,
Heqb1 in H2;
discriminate.
apply fmult_is_nan.
auto.
+
apply B2FF_inj.
rewrite H0.
pose proof (
fmult_is_nan _ _ pl H).
match goal with |-
_ =
B2FF (
Bopp _ _ _ ?
f) =>
destruct f end;
try discriminate.
inv H1.
simpl.
destruct a as [[]|[]|[]|[]],
b as [[]|[]|[]|[]];
reflexivity.
-
destruct a,
b;
try discriminate.
simpl.
rewrite negb_xorb_l.
reflexivity.
-
destruct a,
b;
try discriminate;
simpl;
rewrite negb_xorb_l;
reflexivity.
Qed.
Lemma fmult_Fleb_compat_neg:
forall pl a b c,
mult_nan_criterion a b =
true ->
mult_nan_criterion a c =
true ->
Bsign a =
true ->
Fleb b c =
true ->
Fleb (
Bmult 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a c)
(
Bmult 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a b) =
true.
Proof.
Lemma fmult_comm:
forall a b pl,
Bmult 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a b =
Bmult 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt) (
fun a b =>
pl b a)
mode_NE b a.
Proof.
Definition minmax4 (
a b c d:
float) :
float*
float :=
match Fleb a b,
Fleb c d with
|
true,
true => (
if Fleb a c then a else c,
if Fleb b d then d else b)
|
true,
false => (
if Fleb a d then a else d,
if Fleb b c then c else b)
|
false,
true => (
if Fleb b c then b else c,
if Fleb a d then d else a)
|
false,
false => (
if Fleb b d then b else d,
if Fleb a c then c else a)
end.
Lemma minmax4_correct :
forall a b c d,
is_nan a =
false ->
is_nan b =
false ->
is_nan c =
false ->
is_nan d =
false ->
let '(
m,
M) :=
minmax4 a b c d in
Fleb m a =
true /\
Fleb m b =
true /\
Fleb m c =
true /\
Fleb m d =
true /\
Fleb a M =
true /\
Fleb b M =
true /\
Fleb c M =
true /\
Fleb d M =
true.
Proof.
intros.
unfold minmax4.
repeat match goal with |-
context [
if Fleb ?
x ?
y then _ else _] =>
destruct (
Fleb x y)
eqn:?;
[|
destruct (
Fleb_total _ _ x y); [
easy|
easy|
congruence|]]
end;
eauto 12
using Fleb_trans.
Qed.
Definition forward_fmult (
x y:
fitv+⊤) :
fitv+⊤+⊥ :=
match x,
y with
|
Just (
FITV mx Mx),
Just (
FITV my My) =>
if ((
is_finite mx &&
is_finite Mx) ||
negb (
Fleb my (
B754_zero false) &&
Fleb (
B754_zero false)
My))
&&
((
is_finite my &&
is_finite My) ||
negb (
Fleb mx (
B754_zero false) &&
Fleb (
B754_zero false)
Mx))
then
let '(
m,
M) :=
minmax4 (
Float.mul mx my) (
Float.mul mx My)
(
Float.mul Mx my) (
Float.mul Mx My)
in NotBot (
Just (
FITV m M))
else NotBot All
|
All,
_ |
_,
All =>
NotBot All
end.
Local Remove Hints trans_eq_bool.
Theorem forward_fmult_correct:
∀
x x_ab y y_ab,
x ∈ γ
x_ab ->
y ∈ γ
y_ab ->
(
Float.mul x y) ∈ γ (
forward_fmult x_ab y_ab).
Proof.
Transparent Float.mul.
intros.
unfold forward_fmult.
destruct x_ab as [|[
mx Mx]],
y_ab as [|[
my My]];
try easy.
match goal with |-
context [
if ?
c then _ else _] =>
destruct c eqn:?
end;
try easy.
repeat rewrite ?
orb_true_iff, ?
andb_true_iff, ?
orb_false_iff, ?
andb_false_iff, ?
negb_true_iff in Heqb.
destruct H,
H0,
Heqb.
assert (
Fleb mx Mx =
true)
by eauto using Fleb_trans.
assert (
Fleb my My =
true)
by eauto using Fleb_trans.
assert (
forall x'
y',
Fleb mx x' =
true ->
Fleb x'
Mx =
true ->
Fleb my y' =
true ->
Fleb y'
My =
true ->
mult_nan_criterion x'
y' =
true).
{
intros.
destruct x',
y';
try reflexivity;
exfalso;
try discriminate.
destruct H4 as [[]|[]].
destruct b0,
my as [| | |[]],
My as [| | |[]];
discriminate.
destruct mx as [|[]| |[]];
discriminate.
destruct Mx as [|[]| |[]];
discriminate.
destruct H3 as [[]|[]].
destruct b,
mx as [| | |[]],
Mx as [| | |[]];
discriminate.
destruct my as [|[]| |[]];
discriminate.
destruct My as [|[]| |[]];
discriminate. }
assert (
forall x'
y',
mult_nan_criterion y'
x' =
true ->
mult_nan_criterion x'
y' =
true).
{
destruct x',
y';
try discriminate;
reflexivity. }
pose proof (
minmax4_correct (
Float.mul mx my) (
Float.mul mx My)
(
Float.mul Mx my) (
Float.mul Mx My)).
destruct minmax4.
destruct H9 as [?[?[?[?[?[?[]]]]]]];
try apply fmult_is_nan;
eauto 6.
split.
-
destruct (
Bsign x)
eqn:?.
+
destruct (
Bsign My)
eqn:?.
*
eapply Fleb_trans.
apply H12.
eapply Fleb_trans.
unfold Float.mul.
rewrite fmult_comm.
apply fmult_Fleb_compat_neg with (
b:=
x);
eauto 7.
rewrite fmult_comm.
apply fmult_Fleb_compat_neg;
eauto 7.
*
eapply Fleb_trans.
apply H10.
eapply Fleb_trans.
unfold Float.mul.
rewrite fmult_comm.
apply fmult_Fleb_compat with (
c:=
x);
eauto 7.
rewrite fmult_comm.
apply fmult_Fleb_compat_neg;
eauto 7.
+
destruct (
Bsign my)
eqn:?.
*
eapply Fleb_trans.
apply H11.
eapply Fleb_trans.
unfold Float.mul.
rewrite fmult_comm.
apply fmult_Fleb_compat_neg with (
b:=
x);
eauto 7.
rewrite fmult_comm.
apply fmult_Fleb_compat;
eauto 7.
*
eapply Fleb_trans.
apply H9.
eapply Fleb_trans.
unfold Float.mul.
rewrite fmult_comm.
apply fmult_Fleb_compat with (
c:=
x);
eauto 7.
rewrite fmult_comm.
apply fmult_Fleb_compat;
eauto 7.
-
destruct (
Bsign x)
eqn:?.
+
eapply Fleb_trans.
apply fmult_Fleb_compat_neg with (
b:=
my);
eauto 7.
destruct (
Bsign my)
eqn:?.
*
eapply Fleb_trans.
rewrite fmult_comm.
apply fmult_Fleb_compat_neg with (
b:=
mx);
eauto 7.
rewrite <-
fmult_comm.
auto.
*
eapply Fleb_trans.
rewrite fmult_comm.
apply fmult_Fleb_compat with (
c:=
Mx);
eauto 7.
rewrite <-
fmult_comm.
auto.
+
eapply Fleb_trans.
apply fmult_Fleb_compat with (
c:=
My);
eauto 7.
destruct (
Bsign My)
eqn:?.
*
eapply Fleb_trans.
rewrite fmult_comm.
apply fmult_Fleb_compat_neg with (
b:=
mx);
eauto 7.
rewrite <-
fmult_comm.
auto.
*
eapply Fleb_trans.
rewrite fmult_comm.
apply fmult_Fleb_compat with (
c:=
Mx);
eauto 7.
rewrite <-
fmult_comm.
auto.
Qed.
Definition div_nan_criterion (
a b:
float) :
bool :=
match a,
b with
|
B754_infinity _,
B754_infinity _ |
B754_zero _,
B754_zero _ =>
false
|
B754_nan _ _,
_ |
_,
B754_nan _ _ =>
false
|
_,
_ =>
true
end.
Lemma fdiv_is_nan:
forall a b pl,
div_nan_criterion a b =
true ->
is_nan (
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a b) =
false.
Proof.
intros.
use_float_specs.
destruct a as [| | |],
b as [| | |];
try discriminate;
try reflexivity.
assert ((
B754_finite b m0 e1 e2:
R) ≠ 0).
{
intro.
apply B2R_Bsign_inj with (
y:=
B754_zero b)
in H1.
discriminate.
auto.
auto.
auto. }
specialize (
H0 H1).
clear H1.
destruct Rlt_bool.
-
destruct H0 as [? []].
destruct Bdiv;
try discriminate;
reflexivity.
-
destruct Bdiv as [| |? []|];
try discriminate;
reflexivity.
Qed.
Lemma fdiv_Fleb_compat_r:
forall pl a b c,
div_nan_criterion a b =
true ->
div_nan_criterion a c =
true ->
Bsign a =
false ->
Fleb b c =
true ->
Fleb b (
B754_zero false) =
false ->
Fleb (
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a c)
(
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a b) =
true.
Proof.
intros pl a b c CRITab CRITac asign Hbc Hb.
assert (
is_nan (
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a b) =
false)
by (
apply fdiv_is_nan;
easy).
assert (
is_nan (
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a c) =
false)
by (
apply fdiv_is_nan;
easy).
use_float_specs.
assert (
bsign:
Bsign b =
false).
{
destruct b as [|[]| |[]];
try discriminate;
reflexivity. }
destruct (
is_finite a)
eqn:
FINa.
destruct (
is_finite b)
eqn:
FINb.
destruct (
is_finite c)
eqn:
FINc.
-
rewrite Fleb_Rle in Hbc by auto.
Rle_bool_case Hbc. 2:
discriminate.
clear Hbc.
rename H3 into Hbc.
rewrite Fleb_Rle in Hb by auto.
Rle_bool_case Hb.
discriminate.
clear Hb.
rename H3 into Hb.
simpl in Hb.
assert (
bneq0:(
b:
R) <> 0)
by (
apply Rlt_dichotomy_converse;
auto).
specialize (
H2 bneq0).
assert (
cneq0:(
c:
R) <> 0)
by (
apply Rlt_dichotomy_converse;
right;
Psatz.lra).
specialize (
H1 cneq0).
assert (
age0:0 <=
a).
{
destruct a;
try discriminate;
simpl in asign;
subst;
simpl.
auto with real.
apply F2R_ge_0_compat,
Pos2Z.is_nonneg. }
assert (
round radix2 (
FLT_exp (3 - 1024 - 53) 53) (
round_mode mode_NE) (
a /
c) <=
round radix2 (
FLT_exp (3 - 1024 - 53) 53) (
round_mode mode_NE) (
a /
b)).
{
apply round_le,
Rmult_le_compat_l,
Rinv_le;
auto. }
repeat match goal with H :
context [
Rlt_bool ?
a ?
b] |-
_ =>
Rlt_bool_case H;
[
destruct H as [
H []]|
unfold binary_overflow in H;
simpl in H;
apply B2FF_inj with (
y:=@
B754_infinity 53
_ _)
in H]
end.
+
rewrite Fleb_Rle,
H1,
H2 by auto.
auto using Rle_bool_true.
+
destruct (
Rlt_not_le _ _ (
Rlt_le_trans _ _ _ H4 H7)).
rewrite !
Rabs_pos_eq.
auto.
erewrite <-
round_0 by eauto.
apply round_le,
Rmult_le_pos,
Rlt_le,
Rinv_0_lt_compat;
eauto.
erewrite <-
round_0 by eauto.
apply round_le,
Rmult_le_pos,
Rlt_le,
Rinv_0_lt_compat;
eauto.
Psatz.lra.
+
rewrite H2,
asign,
bsign.
match goal with |-
Fleb ?
f _ =
true =>
destruct f as [| | |[]]
end;
try reflexivity;
discriminate.
+
rewrite H1,
H2,
asign,
bsign.
destruct (
Bsign c);
easy.
-
destruct b;
try discriminate.
destruct a,
c;
try discriminate.
reflexivity.
simpl in asign,
bsign;
subst.
assert ((
B754_finite false m e e0:
R) ≠ 0).
{
apply Rgt_not_eq,
F2R_gt_0_compat.
reflexivity. }
specialize (
H2 H3).
match goal with |-
Fleb _ ?
f =
true =>
destruct f as [|[]| |[]]
end;
try discriminate;
try reflexivity.
destruct Rlt_bool in H2.
now intuition.
discriminate.
destruct Rlt_bool in H2.
now intuition.
discriminate.
-
destruct a,
b;
try discriminate.
destruct c;
try reflexivity;
discriminate.
simpl in asign,
bsign;
subst.
destruct c;
try reflexivity;
discriminate.
-
destruct a;
try discriminate.
simpl in asign.
subst.
destruct b as [|[]| |[]],
c as [|[]| |[]];
try discriminate;
reflexivity.
Qed.
Lemma fdiv_Fleb_compat_l:
forall pl a b c,
div_nan_criterion b a =
true ->
div_nan_criterion c a =
true ->
Fleb a (
B754_zero false) =
false ->
Fleb b c =
true ->
Fleb (
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE b a)
(
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE c a) =
true.
Proof.
intros pl a b c CRITab CRITac Ha Hbc.
assert (
asign:
Bsign a =
false)
by (
destruct a as [[]|[]|[]|[]],
b;
try discriminate;
reflexivity).
assert (
is_nan (
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE b a) =
false)
by (
apply fdiv_is_nan;
easy).
assert (
is_nan (
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE c a) =
false)
by (
apply fdiv_is_nan;
easy).
use_float_specs.
destruct a;
try (
destruct b;
discriminate);
simpl in asign;
subst.
-
destruct b as [|[]| |[]],
c as [|[]| |[]];
try discriminate;
reflexivity.
-
assert (
aneq0:(
B754_finite false m e e0:
R) <> 0).
{
apply Rgt_not_eq,
F2R_gt_0_compat.
reflexivity. }
specialize (
H1 aneq0).
specialize (
H2 aneq0).
destruct (
is_finite b)
eqn:
FINb.
destruct (
is_finite c)
eqn:
FINc.
+
assert (
Hbc':=
Hbc).
rewrite Fleb_Rle in Hbc by easy.
Rle_bool_case Hbc. 2:
discriminate.
clear Hbc.
rename H3 into Hbc.
assert (
round radix2 (
FLT_exp (3 - 1024 - 53) 53) (
round_mode mode_NE) (
b /
B754_finite false m e e0) <=
round radix2 (
FLT_exp (3 - 1024 - 53) 53) (
round_mode mode_NE) (
c /
B754_finite false m e e0)).
{
apply round_le,
Rmult_le_compat_r;
auto.
apply Rlt_le,
Rinv_0_lt_compat,
F2R_gt_0_compat.
reflexivity. }
repeat match goal with H :
context [
Rlt_bool ?
a ?
b] |-
_ =>
Rlt_bool_case H;
[
destruct H as [
H []]|
unfold binary_overflow in H;
simpl in H;
apply B2FF_inj with (
y:=@
B754_infinity 53
_ _)
in H]
end.
*
rewrite Fleb_Rle,
H1,
H2 by auto.
auto using Rle_bool_true.
*
rewrite H1.
replace (
Bsign c)
with false.
match goal with |-
Fleb ?
f _ =
true =>
destruct f as [| | |[]]
end;
try reflexivity;
discriminate.
destruct c as [| | |[]];
try reflexivity;
try discriminate.
destruct b as [| | |[]];
try reflexivity;
try discriminate.
destruct (
Rlt_not_le _ _ (
Rlt_le_trans _ _ _ H4 H7)).
rewrite !
Rabs_left1.
Psatz.lra.
erewrite <-
round_0 by eauto.
apply round_le;
auto.
apply Ropp_le_cancel.
unfold Rdiv.
rewrite Ropp_0, <-
Ropp_mult_distr_l_reverse.
apply Rmult_le_pos,
Rlt_le,
Rinv_0_lt_compat.
apply Ropp_0_ge_le_contravar,
Rle_ge.
apply F2R_le_0_compat.
compute.
discriminate.
apply F2R_gt_0_compat.
reflexivity.
erewrite <-
round_0 by eauto.
apply round_le;
auto.
apply Ropp_le_cancel.
unfold Rdiv.
rewrite Ropp_0, <-
Ropp_mult_distr_l_reverse.
apply Rmult_le_pos,
Rlt_le,
Rinv_0_lt_compat.
apply Ropp_0_ge_le_contravar,
Rle_ge.
apply F2R_le_0_compat.
compute.
discriminate.
apply F2R_gt_0_compat.
reflexivity.
*
rewrite H2.
replace (
Bsign b)
with true.
match goal with |-
Fleb _ ?
f =
true =>
destruct f as [| | |]
end;
try reflexivity;
discriminate.
destruct b as [| | |[]];
try reflexivity;
try discriminate.
destruct c as [| | |[]];
try reflexivity;
try discriminate.
destruct (
Rlt_not_le _ _ (
Rlt_le_trans _ _ _ H5 H4)).
rewrite !
Rabs_pos_eq.
auto.
erewrite <-
round_0 by eauto.
apply round_le,
Rmult_le_pos,
Rlt_le,
Rinv_0_lt_compat;
eauto.
apply F2R_ge_0_compat.
compute.
discriminate.
apply F2R_gt_0_compat.
reflexivity.
erewrite <-
round_0 by eauto.
apply round_le,
Rmult_le_pos,
Rlt_le,
Rinv_0_lt_compat;
eauto.
apply F2R_ge_0_compat.
compute.
discriminate.
apply F2R_gt_0_compat.
reflexivity.
*
rewrite H1,
H2.
destruct b as [| | |[]],
c as [| | |[]];
try discriminate;
reflexivity.
+
destruct c as [|[]| |];
try discriminate.
destruct b as [| | |[]];
discriminate.
match goal with |-
Fleb ?
f _ =
true =>
destruct f as [|[]| |[]]
end;
try discriminate;
reflexivity.
+
destruct b as [|[]| |],
c as [|[]| |];
try discriminate;
try reflexivity.
match goal with |-
Fleb _ ?
f =
true =>
destruct f as [|[]| |[]]
end;
try discriminate;
reflexivity.
Qed.
Lemma fdiv_neg_r:
forall pl a b,
div_nan_criterion a b =
true ->
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a (
Float.neg b) =
Float.neg (
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a b).
Proof.
intros.
assert (
Bsign_Bopp:
forall f:
float,
Bsign (
Bopp _ _ Float.neg_pl f) =
negb (
Bsign f))
by (
destruct f;
easy).
destruct (
is_finite a)
eqn:?.
destruct b;
try (
destruct a;
discriminate).
-
destruct a;
try discriminate.
destruct b,
b0;
reflexivity.
-
destruct a;
try discriminate;
destruct b,
b0;
reflexivity.
-
simpl.
unfold Float.neg in *.
use_float_specs.
unfold Rdiv in *.
assert (
forall b', (
B754_finite b'
m e e0:
R) <> 0).
{
intro.
intro.
apply F2R_eq_0_reg in H2.
destruct b';
discriminate. }
specialize (
H0 (
H2 _)).
unfold round_mode in H.
fold (
Bopp _ _ Float.neg_pl (
B754_finite b m e e0))
in H0.
rewrite B2R_Bopp, <-
Ropp_inv_permute,
Ropp_mult_distr_r_reverse,
round_NE_opp,
Rabs_Ropp in H0 by auto.
fold (
round_mode mode_NE)
in H0.
specialize (
H1 (
H2 _)).
simpl Bopp in *.
destruct Rlt_bool.
+
destruct H0 as [? []],
H1 as [? []].
apply B2R_Bsign_inj.
*
congruence.
*
rewrite is_finite_Bopp.
congruence.
*
rewrite B2R_Bopp.
congruence.
*
rewrite Bsign_Bopp,
H6,
H4,
negb_xorb_l.
destruct b, (
Bsign a);
easy.
apply fdiv_is_nan.
destruct a;
try reflexivity.
discriminate.
apply fdiv_is_nan.
easy.
+
apply B2FF_inj.
rewrite H0.
pose proof (
fdiv_is_nan _ _ pl H).
match goal with |-
_ =
B2FF (
Bopp _ _ _ ?
f) =>
destruct f end;
try discriminate.
inv H1.
destruct b, (
Bsign a);
easy.
-
destruct a,
b;
try discriminate;
simpl;
rewrite negb_xorb_r;
reflexivity.
Qed.
Lemma fdiv_neg_l:
forall pl a b,
div_nan_criterion a b =
true ->
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE (
Float.neg a)
b =
Float.neg (
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
pl mode_NE a b).
Proof.
intros.
assert (
Bsign_Bopp:
forall f:
float,
Bsign (
Bopp _ _ Float.neg_pl f) =
negb (
Bsign f))
by (
destruct f;
easy).
destruct (
is_finite a)
eqn:?.
destruct b;
try (
destruct a;
discriminate).
-
destruct a;
try discriminate.
destruct b,
b0;
reflexivity.
-
destruct a;
try discriminate;
destruct b,
b0;
reflexivity.
-
unfold Float.neg in *.
use_float_specs.
unfold Rdiv in *.
assert ((
B754_finite b m e e0:
R) <> 0).
{
intro.
apply F2R_eq_0_reg in H2.
destruct b;
discriminate. }
specialize (
H0 H2).
unfold round_mode in H0.
rewrite B2R_Bopp,
Ropp_mult_distr_l_reverse,
round_NE_opp,
Rabs_Ropp,
is_finite_Bopp in H0.
fold (
round_mode mode_NE)
in H0.
specialize (
H1 H2).
destruct Rlt_bool.
+
destruct H0 as [? []],
H1 as [? []].
apply B2R_Bsign_inj.
*
rewrite H3.
easy.
*
rewrite is_finite_Bopp.
congruence.
*
rewrite B2R_Bopp.
congruence.
*
rewrite Bsign_Bopp,
H6,
H4,
negb_xorb_l,
Bsign_Bopp.
easy.
apply fdiv_is_nan.
destruct a;
try reflexivity.
discriminate.
apply fdiv_is_nan.
easy.
+
apply B2FF_inj.
rewrite H0.
pose proof (
fdiv_is_nan _ _ pl H).
match goal with |-
_ =
B2FF (
Bopp _ _ _ ?
f) =>
destruct f end;
try discriminate.
inv H1.
simpl.
rewrite Bsign_Bopp.
rewrite negb_xorb_l.
reflexivity.
-
destruct a,
b;
try discriminate;
simpl;
rewrite negb_xorb_l;
reflexivity.
Qed.
Definition forward_fdiv (
x y:
fitv+⊤) :
fitv+⊤+⊥ :=
match x,
y with
|
Just (
FITV mx Mx),
Just (
FITV my My) =>
if (
is_finite mx &&
is_finite Mx) || (
is_finite my &&
is_finite My)
then
if Fleb my (
B754_zero false)
then
if Fleb (
B754_zero false)
My then
if (
Fleb mx (
B754_zero false) &&
Fleb (
B754_zero false)
Mx)
then
NotBot All
else
NotBot (
Just (
FITV (
B754_infinity true) (
B754_infinity false)))
else NotBot
(
Just (
FITV (
Float.div Mx (
if Bsign Mx then my else My))
(
Float.div mx (
if Bsign mx then My else my))))
else NotBot
(
Just (
FITV (
Float.div mx (
if Bsign mx then my else My))
(
Float.div Mx (
if Bsign Mx then My else my))))
else
NotBot All
|
All,
_ |
_,
All =>
NotBot All
end.
Theorem forward_fdiv_correct:
∀
x x_ab y y_ab,
x ∈ γ
x_ab ->
y ∈ γ
y_ab ->
(
Float.div x y) ∈ γ (
forward_fdiv x_ab y_ab).
Proof.
Transparent Float.div.
intros.
unfold forward_fdiv.
destruct x_ab as [|[
mx Mx]],
y_ab as [|[
my My]];
try easy.
destruct H,
H0.
assert (
Fleb mx Mx =
true)
by eauto using Fleb_trans.
assert (
Fleb my My =
true)
by eauto using Fleb_trans.
assert (
forall f,
Bsign f =
true ->
Bsign (
Float.neg f) =
false)
by (
destruct f as [[]|[]|[]|[]];
auto).
assert (
forall a b c,
Fleb a b =
c ->
Fleb (
Float.neg b) (
Float.neg a) =
c)
by (
intros;
rewrite fneg_decr;
auto).
assert (
forall x'
y',
div_nan_criterion x'
y' =
true ->
div_nan_criterion (
Float.neg x')
y' =
true)
by (
destruct x';
easy).
assert (
forall x'
y',
div_nan_criterion x'
y' =
true ->
div_nan_criterion x' (
Float.neg y') =
true)
by (
destruct y';
easy).
unfold Float.div.
repeat match goal with |- γ (
if ?
c then _ else _)
_ =>
destruct c eqn:?
end;
try easy;
repeat rewrite ?
orb_true_iff, ?
andb_true_iff, ?
orb_false_iff, ?
andb_false_iff, ?
negb_true_iff in *.
-
assert (
CRIT:
div_nan_criterion x y =
true).
assert (
is_nan x =
false)
by eauto;
assert (
is_nan y =
false)
by eauto;
destruct x as [|[]| |],
y as [|[]| |];
try reflexivity;
try discriminate;
destruct Heqb2,
Heqb as [[]|[]];
try (
destruct mx as [|[]| |[]];
discriminate);
try (
destruct Mx as [|[]| |[]];
discriminate);
try (
destruct my as [|[]| |[]];
discriminate);
try (
destruct My as [|[]| |[]];
discriminate).
apply fdiv_is_nan with (
pl:=
Float.binop_pl)
in CRIT.
destruct Bdiv as [|[]| |[]];
try discriminate;
split;
try reflexivity.
-
assert (
forall x'
y',
Fleb mx x' =
true ->
Fleb x'
Mx =
true ->
Fleb my y' =
true ->
Fleb y'
My =
true ->
div_nan_criterion x'
y' =
true).
{
intros.
destruct x',
y';
try reflexivity;
exfalso;
try discriminate.
destruct My as [|[]| |[]];
discriminate.
destruct Heqb as [[]|[]].
destruct b,
mx as [| | |[]],
Mx as [| | |[]];
discriminate.
destruct b0,
my as [| | |[]],
My as [| | |[]];
discriminate. }
assert (
Fleb (
Float.neg My) (
B754_zero false) =
false)
by (
destruct My as [|[]| |[]];
try discriminate;
reflexivity).
split.
+
apply Fleb_trans with (
f2:=
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
Float.binop_pl mode_NE Mx y).
*
destruct (
Bsign Mx)
eqn:?;
rewrite <-
fneg_decr, <- !
fdiv_neg_r;
eauto 8.
rewrite <-
fneg_decr, <- !
fdiv_neg_l;
eauto 8.
apply fdiv_Fleb_compat_r;
eauto 8.
rewrite <-
not_true_iff_false in H10 |- *.
contradict H10.
eauto using Fleb_trans.
apply fdiv_Fleb_compat_r;
eauto 8.
*
rewrite <-
fneg_decr, <- !
fdiv_neg_r;
eauto.
apply fdiv_Fleb_compat_l;
eauto 8.
rewrite <-
not_true_iff_false in H10 |- *.
contradict H10.
eauto using Fleb_trans.
+
apply Fleb_trans with (
f2:=
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
Float.binop_pl mode_NE mx y).
*
rewrite <-
fneg_decr, <- !
fdiv_neg_r;
eauto.
apply fdiv_Fleb_compat_l;
eauto.
rewrite <-
not_true_iff_false in H10 |- *.
contradict H10.
eauto using Fleb_trans.
*
destruct (
Bsign mx)
eqn:?;
rewrite <-
fneg_decr, <- !
fdiv_neg_r;
eauto 8.
rewrite <-
fneg_decr, <- !
fdiv_neg_l;
eauto 8.
apply fdiv_Fleb_compat_r;
eauto 8.
apply fdiv_Fleb_compat_r;
eauto 8.
rewrite <-
not_true_iff_false in H10 |- *.
contradict H10.
eauto using Fleb_trans.
-
assert (
forall x'
y',
Fleb mx x' =
true ->
Fleb x'
Mx =
true ->
Fleb my y' =
true ->
Fleb y'
My =
true ->
div_nan_criterion x'
y' =
true).
{
intros.
destruct x',
y';
try reflexivity;
exfalso;
try discriminate.
destruct my as [|[]| |[]];
discriminate.
destruct Heqb as [[]|[]].
destruct b,
mx as [| | |[]],
Mx as [| | |[]];
discriminate.
destruct b0,
my as [| | |[]],
My as [| | |[]];
discriminate. }
split.
+
apply Fleb_trans with (
f2:=
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
Float.binop_pl mode_NE mx y).
*
destruct (
Bsign mx)
eqn:?.
rewrite <-
fneg_decr, <- !
fdiv_neg_l;
eauto 8.
apply fdiv_Fleb_compat_r;
eauto 8.
apply fdiv_Fleb_compat_r;
eauto 8.
rewrite <-
not_true_iff_false in Heqb0 |- *.
contradict Heqb0.
eauto using Fleb_trans.
*
apply fdiv_Fleb_compat_l;
eauto 8.
rewrite <-
not_true_iff_false in Heqb0 |- *.
contradict Heqb0.
eauto using Fleb_trans.
+
apply Fleb_trans with (
f2:=
Bdiv 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
Float.binop_pl mode_NE Mx y).
*
apply fdiv_Fleb_compat_l;
eauto.
rewrite <-
not_true_iff_false in Heqb0 |- *.
contradict Heqb0.
eauto using Fleb_trans.
*
destruct (
Bsign Mx)
eqn:?.
rewrite <-
fneg_decr, <- !
fdiv_neg_l;
eauto 8.
apply fdiv_Fleb_compat_r;
eauto 8.
rewrite <-
not_true_iff_false in Heqb0 |- *.
contradict Heqb0.
eauto using Fleb_trans.
apply fdiv_Fleb_compat_r;
eauto 8.
Qed.
Transparent Float.to_single Float.of_single.
Lemma Bconv_incr:
∀
prec emax prec'
emax'
Hprec'
Hmax'
pl f1 f2,
Fleb f1 f2 =
true ->
Fleb (
Bconv prec emax prec'
emax'
Hprec'
Hmax'
pl mode_NE f1)
(
Bconv prec emax prec'
emax'
Hprec'
Hmax'
pl mode_NE f2) =
true.
Proof.
intros.
assert (
is_nan f1 =
false)
by eauto.
assert (
is_nan f2 =
false)
by eauto.
use_float_specs.
destruct (
is_finite f1)
eqn:
FIN1;
[
specialize (
H2 eq_refl)|
clear H2;
destruct f1 as [|[]| |];
try discriminate];
(
destruct (
is_finite f2)
eqn:
FIN2;
[
specialize (
H3 eq_refl)|
clear H3;
destruct f2 as [|[]| |];
try discriminate]);
try reflexivity;
try (
pose proof H;
rewrite Fleb_Rle in H by auto;
Rle_bool_case H; [|
discriminate];
apply (
round_le radix2 (
FLT_exp (3-
emax'-
prec')
prec') (
round_mode mode_NE))
in H5);
repeat match goal with H :
context [
Rlt_bool ?
a ?
b] |-
_ =>
Rlt_bool_case H;
[
destruct H as [
H []]|
unfold binary_overflow in H;
simpl in H;
apply B2FF_inj with (
y:=
B754_infinity _)
in H]
end.
-
rewrite Fleb_Rle by auto.
apply Rle_bool_true.
rewrite H2,
H3.
auto.
-
rewrite H2.
destruct (
Bsign f1)
eqn:
SIG.
destruct (
Bconv _ _ _ _ Hprec'
Hmax'
pl mode_NE f2)
as [|[]| |];
try reflexivity;
discriminate.
exfalso.
destruct f1 as [| | |[]];
try discriminate.
apply Rabs_lt_inv in H6.
destruct H6.
apply Rabs_ge_inv in H9.
destruct H9. 2:
Psatz.lra.
apply Rle_lt_trans with (
r3:=0),
Rlt_not_le in H9.
2:
apply Ropp_lt_gt_0_contravar,
bpow_gt_0.
erewrite <-
round_0 in H9 by auto.
apply H9,
round_le;
eauto.
apply F2R_ge_0_compat.
compute.
discriminate.
-
rewrite H3.
destruct (
Bsign f2)
eqn:
SIG.
2:
destruct (
Bconv _ _ _ _ Hprec'
Hmax'
pl mode_NE f1)
as [|[]| |[]];
try reflexivity;
discriminate.
exfalso.
destruct f2 as [| | |[]];
try discriminate.
apply Rabs_lt_inv in H7.
destruct H7.
apply Rabs_ge_inv in H6.
destruct H6.
Psatz.lra.
apply Rlt_le_trans with (
r1:=0),
Rlt_not_le in H6.
2:
apply bpow_gt_0.
erewrite <-
round_0 in H6 by auto.
apply H6,
round_le;
eauto.
apply F2R_le_0_compat.
compute.
discriminate.
-
rewrite H2,
H3.
destruct f1 as [| | |[]],
f2 as [| | |[]];
try discriminate;
reflexivity.
-
destruct f1 as [| | |[]];
discriminate.
-
destruct f1 as [| | |[]];
discriminate.
-
destruct Bconv as [| | |[]];
try reflexivity;
discriminate.
-
destruct Bconv as [|[]| |];
try reflexivity;
discriminate.
-
destruct Bconv as [| | |[]];
try reflexivity;
discriminate.
-
destruct Bconv as [|[]| |];
try reflexivity;
discriminate.
-
destruct f2 as [| | |[]];
discriminate.
-
destruct f2 as [| | |[]];
discriminate.
Qed.
Lemma singleoffloat_incr:
forall f1 f2,
Fleb f1 f2 =
true ->
Fleb (
Float.of_single (
Float.to_single f1))
(
Float.of_single (
Float.to_single f2)) =
true.
Proof.
Definition forward_singleoffloat (
x:
fitv+⊤) :
fitv+⊤ :=
match x with
|
Just (
FITV mx Mx) =>
Just (
FITV (
Float.of_single (
Float.to_single mx))
(
Float.of_single (
Float.to_single Mx)))
|
All =>
All
end.
Lemma forward_singleoffloat_correct:
∀
x x_ab,
x ∈ γ
x_ab -> (
Float.of_single (
Float.to_single x)) ∈ γ (
forward_singleoffloat x_ab).
Proof.
intros x [|[
mx Mx]]
Hx;
simpl in *.
auto.
split;
apply singleoffloat_incr;
intuition.
Qed.
Lemma BofZ_incr:
∀
z1 z2 prec emax Hprec Hmax,
(
z1 <=
z2)%
Z ->
Fleb (
BofZ prec emax Hprec Hmax z1)
(
BofZ _ _ Hprec Hmax z2) =
true.
Proof.
intros.
use_float_specs.
repeat match goal with H :
context [
Rlt_bool ?
a ?
b] |-
_ =>
Rlt_bool_case H;
[
destruct H as [
H []]|
unfold binary_overflow in H;
simpl in H;
apply B2FF_inj with (
y:=
B754_infinity _)
in H]
end.
-
rewrite Fleb_Rle,
H0,
H1 by auto.
apply Rle_bool_true.
apply round_le;
auto.
apply Z2R_le.
auto.
-
rewrite H0.
destruct (
Zlt_bool_spec z1 0).
destruct (
BofZ _ _ Hprec Hmax z2);
try discriminate;
reflexivity.
exfalso.
eapply Rlt_le_trans,
Rlt_not_le in H5. 2:
apply H2.
apply H5.
rewrite <- !
round_NE_abs, <- !
Z2R_abs, !
Z.abs_eq by (
auto;
omega).
apply round_le,
Z2R_le,
H;
auto.
apply (
valid_rnd_round_mode mode_NE).
-
rewrite H1.
destruct (
Zlt_bool_spec z2 0).
2:
destruct (
BofZ _ _ Hprec Hmax z1)
as [| | |[]];
try discriminate;
reflexivity.
exfalso.
eapply Rlt_le_trans,
Rlt_not_le in H3. 2:
apply H2.
apply H3.
rewrite <- !
round_NE_abs, <- !
Z2R_abs, !
Z.abs_neq by (
auto;
omega).
apply round_le,
Z2R_le;
auto.
apply (
valid_rnd_round_mode mode_NE).
omega.
-
rewrite H0,
H1.
destruct (
Zlt_bool_spec z1 0), (
Zlt_bool_spec z2 0);
try reflexivity.
omega.
Qed.
Lemma floatofz_incr:
forall i1 i2,
(
i1 <=
i2)%
Z ->
Fleb (
BofZ 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
i1)
(
BofZ 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
i2) =
true.
Proof.
Definition forward_floatofz (
x:
zitv+⊤) :
fitv+⊤ :=
match x with
|
Just (
ZITV mx Mx) =>
Just (
FITV (
BofZ 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt) (
mx:
Z))
(
BofZ 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt) (
Mx:
Z)))
|
All =>
Just (
FITV (
B754_infinity true) (
B754_infinity false))
end.
Lemma forward_floatofz_correct:
∀
x x_ab,
x ∈ γ
x_ab -> (
BofZ 53 1024 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
x) ∈ γ (
forward_floatofz x_ab).
Proof.
Lemma singleofz_incr:
forall i1 i2,
(
i1 <=
i2)%
Z ->
Fleb (
Float.of_single (
BofZ 24 128 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
i1))
(
Float.of_single (
BofZ 24 128 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
i2)) =
true.
Proof.
Definition forward_singleofz (
x:
zitv+⊤) :
fitv+⊤ :=
match x with
|
Just (
ZITV mx Mx) =>
Just (
FITV (
Float.of_single (
BofZ 24 128 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
mx))
(
Float.of_single (
BofZ 24 128 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
Mx)))
|
All =>
Just (
FITV (
B754_infinity true) (
B754_infinity false))
end.
Lemma forward_singleofz_correct:
∀
x x_ab,
x ∈ γ
x_ab -> (
Float.of_single (
BofZ 24 128 (@
eq_refl _ Lt) (@
eq_refl _ Lt)
x)) ∈ γ (
forward_singleofz x_ab).
Proof.
Definition forward_zoffloat (
x:
fitv+⊤) :
zitv+⊤ :=
match x with
|
Just (
FITV mx Mx) =>
match ZofB mx,
ZofB Mx with
|
Some m,
Some M =>
Just (
ZITV m M)
|
_,
_ =>
All
end
|
All =>
All
end.
Lemma forward_zoffloat_correct:
∀
x x_ab y,
x ∈ γ
x_ab ->
ZofB x =
Some y ->
y ∈ γ (
forward_zoffloat x_ab).
Proof.
intros x [|[
mx Mx]]
y []
EQ;
simpl in *.
easy.
destruct (
ZofB mx)
eqn:?; [|
exact I].
destruct (
ZofB Mx)
eqn:?; [|
exact I].
split;
eauto using zoffloat_incr.
Qed.