



(* This file is generated by Why3's Coq driver *)
(* Beware! Only edit allowed sections below *)
Require Import BuiltIn.
Require Reals.Rbasic_fun.
Require Reals.R_sqrt.
Require BuiltIn.
Require int.Int.
Require real.Real.
Require real.RealInfix.
Require real.Abs.
Require real.FromInt.
Require real.Square.
Require bool.Bool.
Require bv.Pow2int.

Axiom us_private : Type.
Parameter us_private_WhyType : WhyType us_private.
Existing Instance us_private_WhyType.

(* Why3 assumption *)
Definition us_fixed := Numbers.BinNums.Z.

Parameter private__bool_eq: us_private -> us_private -> Init.Datatypes.bool.

Parameter us_null_ext__: us_private.

Axiom us_type_of_heap : Type.
Parameter us_type_of_heap_WhyType : WhyType us_type_of_heap.
Existing Instance us_type_of_heap_WhyType.

(* Why3 assumption *)
Inductive us_type_of_heap__ref :=
  | us_type_of_heap__ref'mk : us_type_of_heap -> us_type_of_heap__ref.
Axiom us_type_of_heap__ref_WhyType : WhyType us_type_of_heap__ref.
Existing Instance us_type_of_heap__ref_WhyType.

(* Why3 assumption *)
Definition us_type_of_heap__content (v:us_type_of_heap__ref) :
    us_type_of_heap :=
  match v with
  | us_type_of_heap__ref'mk x => x
  end.

Axiom us_image : Type.
Parameter us_image_WhyType : WhyType us_image.
Existing Instance us_image_WhyType.

(* Why3 assumption *)
Inductive int__ref :=
  | int__ref'mk : Numbers.BinNums.Z -> int__ref.
Axiom int__ref_WhyType : WhyType int__ref.
Existing Instance int__ref_WhyType.

(* Why3 assumption *)
Definition int__content (v:int__ref) : Numbers.BinNums.Z :=
  match v with
  | int__ref'mk x => x
  end.

(* Why3 assumption *)
Inductive bool__ref :=
  | bool__ref'mk : Init.Datatypes.bool -> bool__ref.
Axiom bool__ref_WhyType : WhyType bool__ref.
Existing Instance bool__ref_WhyType.

(* Why3 assumption *)
Definition bool__content (v:bool__ref) : Init.Datatypes.bool :=
  match v with
  | bool__ref'mk x => x
  end.

(* Why3 assumption *)
Inductive us_fixed__ref :=
  | us_fixed__ref'mk : Numbers.BinNums.Z -> us_fixed__ref.
Axiom us_fixed__ref_WhyType : WhyType us_fixed__ref.
Existing Instance us_fixed__ref_WhyType.

(* Why3 assumption *)
Definition us_fixed__content (v:us_fixed__ref) : Numbers.BinNums.Z :=
  match v with
  | us_fixed__ref'mk x => x
  end.

(* Why3 assumption *)
Inductive real__ref :=
  | real__ref'mk : Reals.Rdefinitions.R -> real__ref.
Axiom real__ref_WhyType : WhyType real__ref.
Existing Instance real__ref_WhyType.

(* Why3 assumption *)
Definition real__content (v:real__ref) : Reals.Rdefinitions.R :=
  match v with
  | real__ref'mk x => x
  end.

(* Why3 assumption *)
Inductive us_private__ref :=
  | us_private__ref'mk : us_private -> us_private__ref.
Axiom us_private__ref_WhyType : WhyType us_private__ref.
Existing Instance us_private__ref_WhyType.

(* Why3 assumption *)
Definition us_private__content (v:us_private__ref) : us_private :=
  match v with
  | us_private__ref'mk x => x
  end.

(* Why3 assumption *)
Definition int__ref___projection (a:int__ref) : Numbers.BinNums.Z :=
  int__content a.

(* Why3 assumption *)
Definition us_fixed__ref___projection (a:us_fixed__ref) : Numbers.BinNums.Z :=
  us_fixed__content a.

(* Why3 assumption *)
Definition bool__ref___projection (a:bool__ref) : Init.Datatypes.bool :=
  bool__content a.

(* Why3 assumption *)
Definition real__ref___projection (a:real__ref) : Reals.Rdefinitions.R :=
  real__content a.

(* Why3 assumption *)
Definition us_private__ref___projection (a:us_private__ref) : us_private :=
  us_private__content a.

Axiom t : Type.
Parameter t_WhyType : WhyType t.
Existing Instance t_WhyType.

Parameter t'real: t -> Reals.Rdefinitions.R.

Parameter t'isFinite: t -> Prop.

Axiom t'axiom :
  forall (x:t), t'isFinite x ->
  ((-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368%R)%R
   <= (t'real x))%R /\ (* non escaped EOL for cpp parsing *)
  ((t'real x) <=
   179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368%R)%R.

Parameter truncate: Reals.Rdefinitions.R -> Numbers.BinNums.Z.

Axiom Truncate_int :
  forall (i:Numbers.BinNums.Z), ((truncate (BuiltIn.IZR i)) = i).

Axiom Truncate_down_pos :
  forall (x:Reals.Rdefinitions.R), (0%R <= x)%R ->
  ((BuiltIn.IZR (truncate x)) <= x)%R /\ (* non escaped EOL for cpp parsing *)
  (x < (BuiltIn.IZR ((truncate x) + 1%Z)%Z))%R.

Axiom Truncate_up_neg :
  forall (x:Reals.Rdefinitions.R), (x <= 0%R)%R ->
  ((BuiltIn.IZR ((truncate x) - 1%Z)%Z) < x)%R /\ (* non escaped EOL for cpp parsing *)
  (x <= (BuiltIn.IZR (truncate x)))%R.

Axiom Real_of_truncate :
  forall (x:Reals.Rdefinitions.R),
  ((x - 1%R)%R <= (BuiltIn.IZR (truncate x)))%R /\ (* non escaped EOL for cpp parsing *)
  ((BuiltIn.IZR (truncate x)) <= (x + 1%R)%R)%R.

Axiom Truncate_monotonic :
  forall (x:Reals.Rdefinitions.R) (y:Reals.Rdefinitions.R), (x <= y)%R ->
  ((truncate x) <= (truncate y))%Z.

Axiom Truncate_monotonic_int1 :
  forall (x:Reals.Rdefinitions.R) (i:Numbers.BinNums.Z),
  (x <= (BuiltIn.IZR i))%R -> ((truncate x) <= i)%Z.

Axiom Truncate_monotonic_int2 :
  forall (x:Reals.Rdefinitions.R) (i:Numbers.BinNums.Z),
  ((BuiltIn.IZR i) <= x)%R -> (i <= (truncate x))%Z.

Parameter floor: Reals.Rdefinitions.R -> Numbers.BinNums.Z.

Parameter ceil: Reals.Rdefinitions.R -> Numbers.BinNums.Z.

Axiom Floor_int :
  forall (i:Numbers.BinNums.Z), ((floor (BuiltIn.IZR i)) = i).

Axiom Ceil_int : forall (i:Numbers.BinNums.Z), ((ceil (BuiltIn.IZR i)) = i).

Axiom Floor_down :
  forall (x:Reals.Rdefinitions.R),
  ((BuiltIn.IZR (floor x)) <= x)%R /\ (* non escaped EOL for cpp parsing *)
  (x < (BuiltIn.IZR ((floor x) + 1%Z)%Z))%R.

Axiom Ceil_up :
  forall (x:Reals.Rdefinitions.R),
  ((BuiltIn.IZR ((ceil x) - 1%Z)%Z) < x)%R /\ (x <= (BuiltIn.IZR (ceil x)))%R.

Axiom Floor_monotonic :
  forall (x:Reals.Rdefinitions.R) (y:Reals.Rdefinitions.R), (x <= y)%R ->
  ((floor x) <= (floor y))%Z.

Axiom Ceil_monotonic :
  forall (x:Reals.Rdefinitions.R) (y:Reals.Rdefinitions.R), (x <= y)%R ->
  ((ceil x) <= (ceil y))%Z.

(* Why3 assumption *)
Inductive mode :=
  | RNE : mode
  | RNA : mode
  | RTP : mode
  | RTN : mode
  | RTZ : mode.
Axiom mode_WhyType : WhyType mode.
Existing Instance mode_WhyType.

(* Why3 assumption *)
Definition to_nearest (m:mode) : Prop := (m = RNE) \/ (m = RNA).

Parameter zeroF: t.

Parameter add: mode -> t -> t -> t.

Parameter sub: mode -> t -> t -> t.

Parameter mul: mode -> t -> t -> t.

Parameter div: mode -> t -> t -> t.

Parameter abs: t -> t.

Parameter neg: t -> t.

Parameter fma: mode -> t -> t -> t -> t.

Parameter sqrt: mode -> t -> t.

Parameter roundToIntegral: mode -> t -> t.

Parameter min: t -> t -> t.

Parameter max: t -> t -> t.

Parameter le: t -> t -> Prop.

Parameter lt: t -> t -> Prop.

Parameter eq: t -> t -> Prop.

Parameter is_normal: t -> Prop.

Parameter is_subnormal: t -> Prop.

Parameter is_zero: t -> Prop.

Parameter is_infinite: t -> Prop.

Parameter is_nan: t -> Prop.

Parameter is_positive: t -> Prop.

Parameter is_negative: t -> Prop.

(* Why3 assumption *)
Definition is_plus_infinity (x:t) : Prop := is_infinite x /\ is_positive x.

(* Why3 assumption *)
Definition is_minus_infinity (x:t) : Prop := is_infinite x /\ is_negative x.

(* Why3 assumption *)
Definition is_plus_zero (x:t) : Prop := is_zero x /\ is_positive x.

(* Why3 assumption *)
Definition is_minus_zero (x:t) : Prop := is_zero x /\ is_negative x.

(* Why3 assumption *)
Definition is_not_nan (x:t) : Prop := t'isFinite x \/ is_infinite x.

Axiom is_not_nan1 : forall (x:t), is_not_nan x <-> ~ is_nan x.

Axiom is_not_finite :
  forall (x:t), ~ t'isFinite x <-> is_infinite x \/ is_nan x.

Axiom zeroF_is_positive : is_positive zeroF.

Axiom zeroF_is_zero : is_zero zeroF.

Axiom zero_to_real :
  forall (x:t), is_zero x <-> t'isFinite x /\ ((t'real x) = 0%R).

Parameter of_int: mode -> Numbers.BinNums.Z -> t.

Parameter to_int: mode -> t -> Numbers.BinNums.Z.

Axiom zero_of_int : forall (m:mode), (zeroF = (of_int m 0%Z)).

Parameter round: mode -> Reals.Rdefinitions.R -> Reals.Rdefinitions.R.

Parameter max_int: Numbers.BinNums.Z.

Axiom max_real_int :
  ((9007199254740991 * 19958403095347198116563727130368385660674512604354575415025472424372118918689640657849579654926357010893424468441924952439724379883935936607391717982848314203200056729510856765175377214443629871826533567445439239933308104551208703888888552684480441575071209068757560416423584952303440099278848)%R
   = (BuiltIn.IZR max_int)).

(* Why3 assumption *)
Definition in_range (x:Reals.Rdefinitions.R) : Prop :=
  ((-(9007199254740991 * 19958403095347198116563727130368385660674512604354575415025472424372118918689640657849579654926357010893424468441924952439724379883935936607391717982848314203200056729510856765175377214443629871826533567445439239933308104551208703888888552684480441575071209068757560416423584952303440099278848)%R)%R
   <= x)%R /\ (* non escaped EOL for cpp parsing *)
  (x <=
   (9007199254740991 * 19958403095347198116563727130368385660674512604354575415025472424372118918689640657849579654926357010893424468441924952439724379883935936607391717982848314203200056729510856765175377214443629871826533567445439239933308104551208703888888552684480441575071209068757560416423584952303440099278848)%R)%R.

(* Why3 assumption *)
Definition in_int_range (i:Numbers.BinNums.Z) : Prop :=
  ((-max_int)%Z <= i)%Z /\ (i <= max_int)%Z.

Axiom is_finite : forall (x:t), t'isFinite x -> in_range (t'real x).

(* Why3 assumption *)
Definition no_overflow (m:mode) (x:Reals.Rdefinitions.R) : Prop :=
  in_range (round m x).

Axiom Bounded_real_no_overflow :
  forall (m:mode) (x:Reals.Rdefinitions.R), in_range x -> no_overflow m x.

Axiom Round_monotonic :
  forall (m:mode) (x:Reals.Rdefinitions.R) (y:Reals.Rdefinitions.R),
  (x <= y)%R -> ((round m x) <= (round m y))%R.

Axiom Round_idempotent :
  forall (m1:mode) (m2:mode) (x:Reals.Rdefinitions.R),
  ((round m1 (round m2 x)) = (round m2 x)).

Axiom Round_to_real :
  forall (m:mode) (x:t), t'isFinite x -> ((round m (t'real x)) = (t'real x)).

Axiom Round_down_le :
  forall (x:Reals.Rdefinitions.R), ((round RTN x) <= x)%R.

Axiom Round_up_ge : forall (x:Reals.Rdefinitions.R), (x <= (round RTP x))%R.

Axiom Round_down_neg :
  forall (x:Reals.Rdefinitions.R), ((round RTN (-x)%R) = (-(round RTP x))%R).

Axiom Round_up_neg :
  forall (x:Reals.Rdefinitions.R), ((round RTP (-x)%R) = (-(round RTN x))%R).

(* Why3 assumption *)
Definition in_safe_int_range (i:Numbers.BinNums.Z) : Prop :=
  ((-9007199254740992%Z)%Z <= i)%Z /\ (i <= 9007199254740992%Z)%Z.

Axiom Exact_rounding_for_integers :
  forall (m:mode) (i:Numbers.BinNums.Z), in_safe_int_range i ->
  ((round m (BuiltIn.IZR i)) = (BuiltIn.IZR i)).

(* Why3 assumption *)
Definition same_sign (x:t) (y:t) : Prop :=
  is_positive x /\ is_positive y \/ is_negative x /\ is_negative y.

(* Why3 assumption *)
Definition diff_sign (x:t) (y:t) : Prop :=
  is_positive x /\ is_negative y \/ is_negative x /\ is_positive y.

Axiom feq_eq :
  forall (x:t) (y:t), t'isFinite x -> t'isFinite y -> ~ is_zero x ->
  eq x y -> (x = y).

Axiom eq_feq :
  forall (x:t) (y:t), t'isFinite x -> t'isFinite y -> (x = y) -> eq x y.

Axiom eq_refl : forall (x:t), t'isFinite x -> eq x x.

Axiom eq_sym : forall (x:t) (y:t), eq x y -> eq y x.

Axiom eq_trans : forall (x:t) (y:t) (z:t), eq x y -> eq y z -> eq x z.

Axiom eq_zero : eq zeroF (neg zeroF).

Axiom eq_to_real_finite :
  forall (x:t) (y:t), t'isFinite x /\ t'isFinite y ->
  eq x y <-> ((t'real x) = (t'real y)).

Axiom eq_special :
  forall (x:t) (y:t), eq x y ->
  is_not_nan x /\ (* non escaped EOL for cpp parsing *)
  is_not_nan y /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ t'isFinite y \/
   is_infinite x /\ is_infinite y /\ same_sign x y).

Axiom lt_finite :
  forall (x:t) (y:t), t'isFinite x /\ t'isFinite y ->
  lt x y <-> ((t'real x) < (t'real y))%R.

Axiom le_finite :
  forall (x:t) (y:t), t'isFinite x /\ t'isFinite y ->
  le x y <-> ((t'real x) <= (t'real y))%R.

Axiom le_lt_trans : forall (x:t) (y:t) (z:t), le x y /\ lt y z -> lt x z.

Axiom lt_le_trans : forall (x:t) (y:t) (z:t), lt x y /\ le y z -> lt x z.

Axiom le_ge_asym : forall (x:t) (y:t), le x y /\ le y x -> eq x y.

Axiom not_lt_ge :
  forall (x:t) (y:t), ~ lt x y /\ is_not_nan x /\ is_not_nan y -> le y x.

Axiom not_gt_le :
  forall (x:t) (y:t), ~ lt y x /\ is_not_nan x /\ is_not_nan y -> le x y.

Axiom le_special :
  forall (x:t) (y:t), le x y ->
  t'isFinite x /\ t'isFinite y \/
  is_minus_infinity x /\ is_not_nan y \/ is_not_nan x /\ is_plus_infinity y.

Axiom lt_special :
  forall (x:t) (y:t), lt x y ->
  t'isFinite x /\ t'isFinite y \/
  is_minus_infinity x /\ is_not_nan y /\ ~ is_minus_infinity y \/
  is_not_nan x /\ ~ is_plus_infinity x /\ is_plus_infinity y.

Axiom lt_lt_finite :
  forall (x:t) (y:t) (z:t), lt x y -> lt y z -> t'isFinite y.

Axiom positive_to_real :
  forall (x:t), t'isFinite x -> is_positive x -> (0%R <= (t'real x))%R.

Axiom to_real_positive :
  forall (x:t), t'isFinite x -> (0%R < (t'real x))%R -> is_positive x.

Axiom negative_to_real :
  forall (x:t), t'isFinite x -> is_negative x -> ((t'real x) <= 0%R)%R.

Axiom to_real_negative :
  forall (x:t), t'isFinite x -> ((t'real x) < 0%R)%R -> is_negative x.

Axiom negative_xor_positive :
  forall (x:t), ~ (is_positive x /\ is_negative x).

Axiom negative_or_positive :
  forall (x:t), is_not_nan x -> is_positive x \/ is_negative x.

Axiom diff_sign_trans :
  forall (x:t) (y:t) (z:t), diff_sign x y /\ diff_sign y z -> same_sign x z.

Axiom diff_sign_product :
  forall (x:t) (y:t),
  t'isFinite x /\ t'isFinite y /\ (((t'real x) * (t'real y))%R < 0%R)%R ->
  diff_sign x y.

Axiom same_sign_product :
  forall (x:t) (y:t), t'isFinite x /\ t'isFinite y /\ same_sign x y ->
  (0%R <= ((t'real x) * (t'real y))%R)%R.

(* Why3 assumption *)
Definition product_sign (z:t) (x:t) (y:t) : Prop :=
  (same_sign x y -> is_positive z) /\ (diff_sign x y -> is_negative z).

(* Why3 assumption *)
Definition overflow_value (m:mode) (x:t) : Prop :=
  match m with
  | RTN =>
      (is_positive x ->
       t'isFinite x /\ (* non escaped EOL for cpp parsing *)
       ((t'real x) =
        (9007199254740991 * 19958403095347198116563727130368385660674512604354575415025472424372118918689640657849579654926357010893424468441924952439724379883935936607391717982848314203200056729510856765175377214443629871826533567445439239933308104551208703888888552684480441575071209068757560416423584952303440099278848)%R)) /\ (* non escaped EOL for cpp parsing *)
      (~ is_positive x -> is_infinite x)
  | RTP =>
      (is_positive x -> is_infinite x) /\ (* non escaped EOL for cpp parsing *)
      (~ is_positive x ->
       t'isFinite x /\ (* non escaped EOL for cpp parsing *)
       ((t'real x) =
        (-(9007199254740991 * 19958403095347198116563727130368385660674512604354575415025472424372118918689640657849579654926357010893424468441924952439724379883935936607391717982848314203200056729510856765175377214443629871826533567445439239933308104551208703888888552684480441575071209068757560416423584952303440099278848)%R)%R))
  | RTZ =>
      (is_positive x ->
       t'isFinite x /\ (* non escaped EOL for cpp parsing *)
       ((t'real x) =
        (9007199254740991 * 19958403095347198116563727130368385660674512604354575415025472424372118918689640657849579654926357010893424468441924952439724379883935936607391717982848314203200056729510856765175377214443629871826533567445439239933308104551208703888888552684480441575071209068757560416423584952303440099278848)%R)) /\ (* non escaped EOL for cpp parsing *)
      (~ is_positive x ->
       t'isFinite x /\ (* non escaped EOL for cpp parsing *)
       ((t'real x) =
        (-(9007199254740991 * 19958403095347198116563727130368385660674512604354575415025472424372118918689640657849579654926357010893424468441924952439724379883935936607391717982848314203200056729510856765175377214443629871826533567445439239933308104551208703888888552684480441575071209068757560416423584952303440099278848)%R)%R))
  | RNA|RNE => is_infinite x
  end.

(* Why3 assumption *)
Definition sign_zero_result (m:mode) (x:t) : Prop :=
  is_zero x -> match m with
               | RTN => is_negative x
               | _ => is_positive x
               end.

Axiom add_finite :
  forall (m:mode) (x:t) (y:t), t'isFinite x -> t'isFinite y ->
  no_overflow m ((t'real x) + (t'real y))%R ->
  t'isFinite (add m x y) /\ (* non escaped EOL for cpp parsing *)
  ((t'real (add m x y)) = (round m ((t'real x) + (t'real y))%R)).

Axiom add_finite_rev :
  forall (m:mode) (x:t) (y:t), t'isFinite (add m x y) ->
  t'isFinite x /\ t'isFinite y.

Axiom add_finite_rev_n :
  forall (m:mode) (x:t) (y:t), to_nearest m -> t'isFinite (add m x y) ->
  no_overflow m ((t'real x) + (t'real y))%R /\ (* non escaped EOL for cpp parsing *)
  ((t'real (add m x y)) = (round m ((t'real x) + (t'real y))%R)).

Axiom sub_finite :
  forall (m:mode) (x:t) (y:t), t'isFinite x -> t'isFinite y ->
  no_overflow m ((t'real x) - (t'real y))%R ->
  t'isFinite (sub m x y) /\ (* non escaped EOL for cpp parsing *)
  ((t'real (sub m x y)) = (round m ((t'real x) - (t'real y))%R)).

Axiom sub_finite_rev :
  forall (m:mode) (x:t) (y:t), t'isFinite (sub m x y) ->
  t'isFinite x /\ t'isFinite y.

Axiom sub_finite_rev_n :
  forall (m:mode) (x:t) (y:t), to_nearest m -> t'isFinite (sub m x y) ->
  no_overflow m ((t'real x) - (t'real y))%R /\ (* non escaped EOL for cpp parsing *)
  ((t'real (sub m x y)) = (round m ((t'real x) - (t'real y))%R)).

Axiom mul_finite :
  forall (m:mode) (x:t) (y:t), t'isFinite x -> t'isFinite y ->
  no_overflow m ((t'real x) * (t'real y))%R ->
  t'isFinite (mul m x y) /\ (* non escaped EOL for cpp parsing *)
  ((t'real (mul m x y)) = (round m ((t'real x) * (t'real y))%R)).

Axiom mul_finite_rev :
  forall (m:mode) (x:t) (y:t), t'isFinite (mul m x y) ->
  t'isFinite x /\ t'isFinite y.

Axiom mul_finite_rev_n :
  forall (m:mode) (x:t) (y:t), to_nearest m -> t'isFinite (mul m x y) ->
  no_overflow m ((t'real x) * (t'real y))%R /\ (* non escaped EOL for cpp parsing *)
  ((t'real (mul m x y)) = (round m ((t'real x) * (t'real y))%R)).

Axiom div_finite :
  forall (m:mode) (x:t) (y:t), t'isFinite x -> t'isFinite y -> ~ is_zero y ->
  no_overflow m ((t'real x) / (t'real y))%R ->
  t'isFinite (div m x y) /\ (* non escaped EOL for cpp parsing *)
  ((t'real (div m x y)) = (round m ((t'real x) / (t'real y))%R)).

Axiom div_finite_rev :
  forall (m:mode) (x:t) (y:t), t'isFinite (div m x y) ->
  t'isFinite x /\ t'isFinite y /\ ~ is_zero y \/
  t'isFinite x /\ is_infinite y /\ ((t'real (div m x y)) = 0%R).

Axiom div_finite_rev_n :
  forall (m:mode) (x:t) (y:t), to_nearest m -> t'isFinite (div m x y) ->
  t'isFinite y ->
  no_overflow m ((t'real x) / (t'real y))%R /\ (* non escaped EOL for cpp parsing *)
  ((t'real (div m x y)) = (round m ((t'real x) / (t'real y))%R)).

Axiom neg_finite :
  forall (x:t), t'isFinite x ->
  t'isFinite (neg x) /\ ((t'real (neg x)) = (-(t'real x))%R).

Axiom neg_finite_rev :
  forall (x:t), t'isFinite (neg x) ->
  t'isFinite x /\ ((t'real (neg x)) = (-(t'real x))%R).

Axiom abs_finite :
  forall (x:t), t'isFinite x ->
  t'isFinite (abs x) /\ (* non escaped EOL for cpp parsing *)
  ((t'real (abs x)) = (Reals.Rbasic_fun.Rabs (t'real x))) /\ (* non escaped EOL for cpp parsing *)
  is_positive (abs x).

Axiom abs_finite_rev :
  forall (x:t), t'isFinite (abs x) ->
  t'isFinite x /\ ((t'real (abs x)) = (Reals.Rbasic_fun.Rabs (t'real x))).

Axiom abs_universal : forall (x:t), ~ is_negative (abs x).

Axiom fma_finite :
  forall (m:mode) (x:t) (y:t) (z:t), t'isFinite x -> t'isFinite y ->
  t'isFinite z ->
  no_overflow m (((t'real x) * (t'real y))%R + (t'real z))%R ->
  t'isFinite (fma m x y z) /\ (* non escaped EOL for cpp parsing *)
  ((t'real (fma m x y z)) =
   (round m (((t'real x) * (t'real y))%R + (t'real z))%R)).

Axiom fma_finite_rev :
  forall (m:mode) (x:t) (y:t) (z:t), t'isFinite (fma m x y z) ->
  t'isFinite x /\ t'isFinite y /\ t'isFinite z.

Axiom fma_finite_rev_n :
  forall (m:mode) (x:t) (y:t) (z:t), to_nearest m ->
  t'isFinite (fma m x y z) ->
  no_overflow m (((t'real x) * (t'real y))%R + (t'real z))%R /\ (* non escaped EOL for cpp parsing *)
  ((t'real (fma m x y z)) =
   (round m (((t'real x) * (t'real y))%R + (t'real z))%R)).

Axiom sqrt_finite :
  forall (m:mode) (x:t), t'isFinite x -> (0%R <= (t'real x))%R ->
  t'isFinite (sqrt m x) /\ (* non escaped EOL for cpp parsing *)
  ((t'real (sqrt m x)) = (round m (Reals.R_sqrt.sqrt (t'real x)))).

Axiom sqrt_finite_rev :
  forall (m:mode) (x:t), t'isFinite (sqrt m x) ->
  t'isFinite x /\ (* non escaped EOL for cpp parsing *)
  (0%R <= (t'real x))%R /\ (* non escaped EOL for cpp parsing *)
  ((t'real (sqrt m x)) = (round m (Reals.R_sqrt.sqrt (t'real x)))).

(* Why3 assumption *)
Definition same_sign_real (x:t) (r:Reals.Rdefinitions.R) : Prop :=
  is_positive x /\ (0%R < r)%R \/ is_negative x /\ (r < 0%R)%R.

Axiom add_special :
  forall (m:mode) (x:t) (y:t),
  let r := add m x y in
  (is_nan x \/ is_nan y -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ is_infinite y -> is_infinite r /\ same_sign r y) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ t'isFinite y -> is_infinite r /\ same_sign r x) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ is_infinite y /\ same_sign x y ->
   is_infinite r /\ same_sign r x) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ is_infinite y /\ diff_sign x y -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ (* non escaped EOL for cpp parsing *)
   t'isFinite y /\ ~ no_overflow m ((t'real x) + (t'real y))%R ->
   same_sign_real r ((t'real x) + (t'real y))%R /\ overflow_value m r) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ t'isFinite y ->
   (same_sign x y -> same_sign r x) /\ (* non escaped EOL for cpp parsing *)
   (~ same_sign x y -> sign_zero_result m r)).

Axiom sub_special :
  forall (m:mode) (x:t) (y:t),
  let r := sub m x y in
  (is_nan x \/ is_nan y -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ is_infinite y -> is_infinite r /\ diff_sign r y) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ t'isFinite y -> is_infinite r /\ same_sign r x) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ is_infinite y /\ same_sign x y -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ is_infinite y /\ diff_sign x y ->
   is_infinite r /\ same_sign r x) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ (* non escaped EOL for cpp parsing *)
   t'isFinite y /\ ~ no_overflow m ((t'real x) - (t'real y))%R ->
   same_sign_real r ((t'real x) - (t'real y))%R /\ overflow_value m r) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ t'isFinite y ->
   (diff_sign x y -> same_sign r x) /\ (* non escaped EOL for cpp parsing *)
   (~ diff_sign x y -> sign_zero_result m r)).

Axiom mul_special :
  forall (m:mode) (x:t) (y:t),
  let r := mul m x y in
  (is_nan x \/ is_nan y -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (is_zero x /\ is_infinite y -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ is_infinite y /\ ~ is_zero x -> is_infinite r) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ is_zero y -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ t'isFinite y /\ ~ is_zero y -> is_infinite r) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ is_infinite y -> is_infinite r) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ (* non escaped EOL for cpp parsing *)
   t'isFinite y /\ ~ no_overflow m ((t'real x) * (t'real y))%R ->
   overflow_value m r) /\ (* non escaped EOL for cpp parsing *)
  (~ is_nan r -> product_sign r x y).

Axiom div_special :
  forall (m:mode) (x:t) (y:t),
  let r := div m x y in
  (is_nan x \/ is_nan y -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ is_infinite y -> is_zero r) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ t'isFinite y -> is_infinite r) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ is_infinite y -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ (* non escaped EOL for cpp parsing *)
   t'isFinite y /\ ~ is_zero y /\ ~ no_overflow m ((t'real x) / (t'real y))%R ->
   overflow_value m r) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ is_zero y /\ ~ is_zero x -> is_infinite r) /\ (* non escaped EOL for cpp parsing *)
  (is_zero x /\ is_zero y -> is_nan r) /\ (~ is_nan r -> product_sign r x y).

Axiom neg_special :
  forall (x:t),
  (is_nan x -> is_nan (neg x)) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x -> is_infinite (neg x)) /\ (* non escaped EOL for cpp parsing *)
  (~ is_nan x -> diff_sign x (neg x)).

Axiom abs_special :
  forall (x:t),
  (is_nan x -> is_nan (abs x)) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x -> is_infinite (abs x)) /\ (* non escaped EOL for cpp parsing *)
  (~ is_nan x -> is_positive (abs x)).

Axiom fma_special :
  forall (m:mode) (x:t) (y:t) (z:t),
  let r := fma m x y z in
  (is_nan x \/ is_nan y \/ is_nan z -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (is_zero x /\ is_infinite y -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ is_zero y -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ ~ is_zero x /\ is_infinite y /\ t'isFinite z ->
   is_infinite r /\ product_sign r x y) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ ~ is_zero x /\ is_infinite y /\ is_infinite z ->
   (product_sign z x y -> is_infinite r /\ same_sign r z) /\ (* non escaped EOL for cpp parsing *)
   (~ product_sign z x y -> is_nan r)) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ t'isFinite y /\ ~ is_zero y /\ t'isFinite z ->
   is_infinite r /\ product_sign r x y) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ t'isFinite y /\ ~ is_zero y /\ is_infinite z ->
   (product_sign z x y -> is_infinite r /\ same_sign r z) /\ (* non escaped EOL for cpp parsing *)
   (~ product_sign z x y -> is_nan r)) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ is_infinite y /\ t'isFinite z ->
   is_infinite r /\ product_sign r x y) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ t'isFinite y /\ is_infinite z ->
   is_infinite r /\ same_sign r z) /\ (* non escaped EOL for cpp parsing *)
  (is_infinite x /\ is_infinite y /\ is_infinite z ->
   (product_sign z x y -> is_infinite r /\ same_sign r z) /\ (* non escaped EOL for cpp parsing *)
   (~ product_sign z x y -> is_nan r)) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ (* non escaped EOL for cpp parsing *)
   t'isFinite y /\ (* non escaped EOL for cpp parsing *)
   t'isFinite z /\ (* non escaped EOL for cpp parsing *)
   ~ no_overflow m (((t'real x) * (t'real y))%R + (t'real z))%R ->
   same_sign_real r (((t'real x) * (t'real y))%R + (t'real z))%R /\ (* non escaped EOL for cpp parsing *)
   overflow_value m r) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ t'isFinite y /\ t'isFinite z ->
   (product_sign z x y -> same_sign r z) /\ (* non escaped EOL for cpp parsing *)
   (~ product_sign z x y ->
    ((((t'real x) * (t'real y))%R + (t'real z))%R = 0%R) ->
    ((m = RTN) -> is_negative r) /\ (~ (m = RTN) -> is_positive r))).

Axiom sqrt_special :
  forall (m:mode) (x:t),
  let r := sqrt m x in
  (is_nan x -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (is_plus_infinity x -> is_plus_infinity r) /\ (* non escaped EOL for cpp parsing *)
  (is_minus_infinity x -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ ((t'real x) < 0%R)%R -> is_nan r) /\ (* non escaped EOL for cpp parsing *)
  (is_zero x -> same_sign r x) /\ (* non escaped EOL for cpp parsing *)
  (t'isFinite x /\ (0%R < (t'real x))%R -> is_positive r).

Axiom of_int_add_exact :
  forall (m:mode) (n:mode) (i:Numbers.BinNums.Z) (j:Numbers.BinNums.Z),
  in_safe_int_range i -> in_safe_int_range j ->
  in_safe_int_range (i + j)%Z ->
  eq (of_int m (i + j)%Z) (add n (of_int m i) (of_int m j)).

Axiom of_int_sub_exact :
  forall (m:mode) (n:mode) (i:Numbers.BinNums.Z) (j:Numbers.BinNums.Z),
  in_safe_int_range i -> in_safe_int_range j ->
  in_safe_int_range (i - j)%Z ->
  eq (of_int m (i - j)%Z) (sub n (of_int m i) (of_int m j)).

Axiom of_int_mul_exact :
  forall (m:mode) (n:mode) (i:Numbers.BinNums.Z) (j:Numbers.BinNums.Z),
  in_safe_int_range i -> in_safe_int_range j ->
  in_safe_int_range (i * j)%Z ->
  eq (of_int m (i * j)%Z) (mul n (of_int m i) (of_int m j)).

Axiom Min_r : forall (x:t) (y:t), le y x -> eq (min x y) y.

Axiom Min_l : forall (x:t) (y:t), le x y -> eq (min x y) x.

Axiom Max_r : forall (x:t) (y:t), le y x -> eq (max x y) x.

Axiom Max_l : forall (x:t) (y:t), le x y -> eq (max x y) y.

Parameter is_int: t -> Prop.

Axiom zeroF_is_int : is_int zeroF.

Axiom of_int_is_int :
  forall (m:mode) (x:Numbers.BinNums.Z), in_int_range x ->
  is_int (of_int m x).

Axiom big_float_is_int :
  forall (m:mode) (i:t), t'isFinite i ->
  le i (neg (of_int m 9007199254740992%Z)) \/
  le (of_int m 9007199254740992%Z) i -> is_int i.

Axiom roundToIntegral_is_int :
  forall (m:mode) (x:t), t'isFinite x -> is_int (roundToIntegral m x).

Axiom eq_is_int : forall (x:t) (y:t), eq x y -> is_int x -> is_int y.

Axiom add_int :
  forall (x:t) (y:t) (m:mode), is_int x -> is_int y ->
  t'isFinite (add m x y) -> is_int (add m x y).

Axiom sub_int :
  forall (x:t) (y:t) (m:mode), is_int x -> is_int y ->
  t'isFinite (sub m x y) -> is_int (sub m x y).

Axiom mul_int :
  forall (x:t) (y:t) (m:mode), is_int x -> is_int y ->
  t'isFinite (mul m x y) -> is_int (mul m x y).

Axiom fma_int :
  forall (x:t) (y:t) (z:t) (m:mode), is_int x -> is_int y -> is_int z ->
  t'isFinite (fma m x y z) -> is_int (fma m x y z).

Axiom neg_int : forall (x:t), is_int x -> is_int (neg x).

Axiom abs_int : forall (x:t), is_int x -> is_int (abs x).

Axiom is_int_of_int :
  forall (x:t) (m:mode) (m':mode), is_int x -> eq x (of_int m' (to_int m x)).

Axiom is_int_to_int :
  forall (m:mode) (x:t), is_int x -> in_int_range (to_int m x).

Axiom is_int_is_finite : forall (x:t), is_int x -> t'isFinite x.

Axiom int_to_real :
  forall (m:mode) (x:t), is_int x ->
  ((t'real x) = (BuiltIn.IZR (to_int m x))).

Axiom truncate_int :
  forall (m:mode) (i:t), is_int i -> eq (roundToIntegral m i) i.

Axiom truncate_neg :
  forall (x:t), t'isFinite x -> is_negative x ->
  ((roundToIntegral RTZ x) = (roundToIntegral RTP x)).

Axiom truncate_pos :
  forall (x:t), t'isFinite x -> is_positive x ->
  ((roundToIntegral RTZ x) = (roundToIntegral RTN x)).

Axiom ceil_le : forall (x:t), t'isFinite x -> le x (roundToIntegral RTP x).

Axiom ceil_lest :
  forall (x:t) (y:t), le x y /\ is_int y -> le (roundToIntegral RTP x) y.

Axiom ceil_to_real :
  forall (x:t), t'isFinite x ->
  ((t'real (roundToIntegral RTP x)) = (BuiltIn.IZR (ceil (t'real x)))).

Axiom ceil_to_int :
  forall (m:mode) (x:t), t'isFinite x ->
  ((to_int m (roundToIntegral RTP x)) = (ceil (t'real x))).

Axiom floor_le : forall (x:t), t'isFinite x -> le (roundToIntegral RTN x) x.

Axiom floor_lest :
  forall (x:t) (y:t), le y x /\ is_int y -> le y (roundToIntegral RTN x).

Axiom floor_to_real :
  forall (x:t), t'isFinite x ->
  ((t'real (roundToIntegral RTN x)) = (BuiltIn.IZR (floor (t'real x)))).

Axiom floor_to_int :
  forall (m:mode) (x:t), t'isFinite x ->
  ((to_int m (roundToIntegral RTN x)) = (floor (t'real x))).

Axiom RNA_down :
  forall (x:t),
  lt (sub RNE x (roundToIntegral RTN x)) (sub RNE (roundToIntegral RTP x) x) ->
  ((roundToIntegral RNA x) = (roundToIntegral RTN x)).

Axiom RNA_up :
  forall (x:t),
  lt (sub RNE (roundToIntegral RTP x) x) (sub RNE x (roundToIntegral RTN x)) ->
  ((roundToIntegral RNA x) = (roundToIntegral RTP x)).

Axiom RNA_down_tie :
  forall (x:t),
  eq (sub RNE x (roundToIntegral RTN x)) (sub RNE (roundToIntegral RTP x) x) ->
  is_negative x -> ((roundToIntegral RNA x) = (roundToIntegral RTN x)).

Axiom RNA_up_tie :
  forall (x:t),
  eq (sub RNE (roundToIntegral RTP x) x) (sub RNE x (roundToIntegral RTN x)) ->
  is_positive x -> ((roundToIntegral RNA x) = (roundToIntegral RTP x)).

Axiom to_int_roundToIntegral :
  forall (m:mode) (x:t), ((to_int m x) = (to_int m (roundToIntegral m x))).

Axiom to_int_monotonic :
  forall (m:mode) (x:t) (y:t), t'isFinite x -> t'isFinite y -> le x y ->
  ((to_int m x) <= (to_int m y))%Z.

Axiom to_int_of_int :
  forall (m:mode) (i:Numbers.BinNums.Z), in_safe_int_range i ->
  ((to_int m (of_int m i)) = i).

Axiom eq_to_int :
  forall (m:mode) (x:t) (y:t), t'isFinite x -> eq x y ->
  ((to_int m x) = (to_int m y)).

Axiom neg_to_int :
  forall (m:mode) (x:t), is_int x -> ((to_int m (neg x)) = (-(to_int m x))%Z).

Axiom roundToIntegral_is_finite :
  forall (m:mode) (x:t), t'isFinite x -> t'isFinite (roundToIntegral m x).

Axiom round_bound_ne :
  forall (x:Reals.Rdefinitions.R), no_overflow RNE x ->
  (((x - ((1 / 9007199254740992)%R * (Reals.Rbasic_fun.Rabs x))%R)%R -
    (1 / 404804506614621236704990693437834614099113299528284236713802716054860679135990693783920767402874248990374155728633623822779617474771586953734026799881477019843034848553132722728933815484186432682479535356945490137124014966849385397236206711298319112681620113024717539104666829230461005064372655017292012526615415482186989568)%R)%R
   <= (round RNE x))%R /\ (* non escaped EOL for cpp parsing *)
  ((round RNE x) <=
   ((x + ((1 / 9007199254740992)%R * (Reals.Rbasic_fun.Rabs x))%R)%R +
    (1 / 404804506614621236704990693437834614099113299528284236713802716054860679135990693783920767402874248990374155728633623822779617474771586953734026799881477019843034848553132722728933815484186432682479535356945490137124014966849385397236206711298319112681620113024717539104666829230461005064372655017292012526615415482186989568)%R)%R)%R.

Axiom round_bound :
  forall (m:mode) (x:Reals.Rdefinitions.R), no_overflow m x ->
  (((x - ((1 / 4503599627370496)%R * (Reals.Rbasic_fun.Rabs x))%R)%R -
    (1 / 202402253307310618352495346718917307049556649764142118356901358027430339567995346891960383701437124495187077864316811911389808737385793476867013399940738509921517424276566361364466907742093216341239767678472745068562007483424692698618103355649159556340810056512358769552333414615230502532186327508646006263307707741093494784)%R)%R
   <= (round m x))%R /\ (* non escaped EOL for cpp parsing *)
  ((round m x) <=
   ((x + ((1 / 4503599627370496)%R * (Reals.Rbasic_fun.Rabs x))%R)%R +
    (1 / 202402253307310618352495346718917307049556649764142118356901358027430339567995346891960383701437124495187077864316811911389808737385793476867013399940738509921517424276566361364466907742093216341239767678472745068562007483424692698618103355649159556340810056512358769552333414615230502532186327508646006263307707741093494784)%R)%R)%R.

(* Why3 assumption *)
Definition neq (x:t) (y:t) : Prop := ~ eq x y.

Parameter bool_lt: t -> t -> Init.Datatypes.bool.

Axiom bool_lt'def :
  forall (x:t) (y:t),
  (lt x y -> ((bool_lt x y) = Init.Datatypes.true)) /\ (* non escaped EOL for cpp parsing *)
  (~ lt x y -> ((bool_lt x y) = Init.Datatypes.false)).

Parameter bool_le: t -> t -> Init.Datatypes.bool.

Axiom bool_le'def :
  forall (x:t) (y:t),
  (le x y -> ((bool_le x y) = Init.Datatypes.true)) /\ (* non escaped EOL for cpp parsing *)
  (~ le x y -> ((bool_le x y) = Init.Datatypes.false)).

Parameter bool_gt: t -> t -> Init.Datatypes.bool.

Axiom bool_gt'def :
  forall (x:t) (y:t),
  (lt y x -> ((bool_gt x y) = Init.Datatypes.true)) /\ (* non escaped EOL for cpp parsing *)
  (~ lt y x -> ((bool_gt x y) = Init.Datatypes.false)).

Parameter bool_ge: t -> t -> Init.Datatypes.bool.

Axiom bool_ge'def :
  forall (x:t) (y:t),
  (le y x -> ((bool_ge x y) = Init.Datatypes.true)) /\ (* non escaped EOL for cpp parsing *)
  (~ le y x -> ((bool_ge x y) = Init.Datatypes.false)).

Parameter bool_eq: t -> t -> Init.Datatypes.bool.

Axiom bool_eq'def :
  forall (x:t) (y:t),
  (eq x y -> ((bool_eq x y) = Init.Datatypes.true)) /\ (* non escaped EOL for cpp parsing *)
  (~ eq x y -> ((bool_eq x y) = Init.Datatypes.false)).

Parameter bool_neq: t -> t -> Init.Datatypes.bool.

Axiom bool_neq'def :
  forall (x:t) (y:t),
  (~ eq x y -> ((bool_neq x y) = Init.Datatypes.true)) /\ (* non escaped EOL for cpp parsing *)
  (eq x y -> ((bool_neq x y) = Init.Datatypes.false)).

Parameter rem: t -> t -> t.

Parameter fliteral: t.

Axiom fliteral_axiom : t'isFinite fliteral /\ ((t'real fliteral) = 1%R).

Axiom one_is_int : is_int fliteral.

Axiom one_of_int : (fliteral = (of_int RNA 1%Z)).

(* Why3 assumption *)
Inductive t__ref :=
  | t__ref'mk : t -> t__ref.
Axiom t__ref_WhyType : WhyType t__ref.
Existing Instance t__ref_WhyType.

(* Why3 assumption *)
Definition t__content (v:t__ref) : t := match v with
                                        | t__ref'mk x => x
                                        end.

(* Why3 assumption *)
Definition ite {a:Type} {a_WT:WhyType a} (b:Init.Datatypes.bool) (x:a)
    (y:a) : a :=
  match b with
  | Init.Datatypes.true => x
  | Init.Datatypes.false => y
  end.

Parameter bool_eq1:
  Init.Datatypes.bool -> Init.Datatypes.bool -> Init.Datatypes.bool.

Axiom bool_eq'def1 :
  forall (x:Init.Datatypes.bool) (y:Init.Datatypes.bool),
  ((x = y) -> ((bool_eq1 x y) = Init.Datatypes.true)) /\ (* non escaped EOL for cpp parsing *)
  (~ (x = y) -> ((bool_eq1 x y) = Init.Datatypes.false)).

Parameter to_int1: Init.Datatypes.bool -> Numbers.BinNums.Z.

Axiom to_int'def :
  forall (b:Init.Datatypes.bool),
  ((b = Init.Datatypes.true) -> ((to_int1 b) = 1%Z)) /\ (* non escaped EOL for cpp parsing *)
  (~ (b = Init.Datatypes.true) -> ((to_int1 b) = 0%Z)).

Parameter of_int1: Numbers.BinNums.Z -> Init.Datatypes.bool.

Axiom of_int'def :
  forall (i:Numbers.BinNums.Z),
  ((i = 0%Z) -> ((of_int1 i) = Init.Datatypes.false)) /\ (* non escaped EOL for cpp parsing *)
  (~ (i = 0%Z) -> ((of_int1 i) = Init.Datatypes.true)).

(* Why3 assumption *)
Definition in_range1 (x:Numbers.BinNums.Z) : Prop := (x = 0%Z) \/ (x = 1%Z).

Parameter attr__ATTRIBUTE_IMAGE: Init.Datatypes.bool -> us_image.

Parameter attr__ATTRIBUTE_VALUE__pre_check: us_image -> Prop.

Parameter attr__ATTRIBUTE_VALUE: us_image -> Init.Datatypes.bool.

Axiom long_float : Type.
Parameter long_float_WhyType : WhyType long_float.
Existing Instance long_float_WhyType.

Parameter bool_eq2: t -> t -> Init.Datatypes.bool.

Axiom bool_eq'def2 :
  forall (x:t) (y:t),
  (eq x y -> ((bool_eq2 x y) = Init.Datatypes.true)) /\ (* non escaped EOL for cpp parsing *)
  (~ eq x y -> ((bool_eq2 x y) = Init.Datatypes.false)).

Parameter user_eq: long_float -> long_float -> Init.Datatypes.bool.

Parameter attr__ATTRIBUTE_IMAGE1: t -> us_image.

Parameter attr__ATTRIBUTE_VALUE__pre_check1: us_image -> Prop.

Parameter attr__ATTRIBUTE_VALUE1: us_image -> t.

Parameter dummy: long_float.

(* Why3 assumption *)
Inductive long_float__ref :=
  | long_float__ref'mk : long_float -> long_float__ref.
Axiom long_float__ref_WhyType : WhyType long_float__ref.
Existing Instance long_float__ref_WhyType.

(* Why3 assumption *)
Definition long_float__content (v:long_float__ref) : long_float :=
  match v with
  | long_float__ref'mk x => x
  end.

(* Why3 assumption *)
Definition long_float__ref_long_float__content__projection
    (a:long_float__ref) : long_float :=
  long_float__content a.

Parameter fliteral1: t.

Axiom fliteral_axiom1 :
  t'isFinite fliteral1 /\ (* non escaped EOL for cpp parsing *)
  ((t'real fliteral1) =
   179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368%R).

(* Why3 assumption *)
Definition dynamic_invariant (temp___expr_74:t)
    (temp___is_init_70:Init.Datatypes.bool)
    (temp___skip_constant_71:Init.Datatypes.bool)
    (temp___do_toplevel_72:Init.Datatypes.bool)
    (temp___do_typ_inv_73:Init.Datatypes.bool) : Prop :=
  (temp___is_init_70 = Init.Datatypes.true) \/ le (neg fliteral1) fliteral1 ->
  t'isFinite temp___expr_74.

Parameter fl_last_sqrt: t.

Parameter attr__ATTRIBUTE_ADDRESS: Numbers.BinNums.Z.

Parameter val1: t.

Parameter attr__ATTRIBUTE_ADDRESS1: Numbers.BinNums.Z.

Parameter val2: t.

Parameter attr__ATTRIBUTE_ADDRESS2: Numbers.BinNums.Z.

Parameter val3: t.

Parameter attr__ATTRIBUTE_ADDRESS3: Numbers.BinNums.Z.

Parameter fliteral2: t.

Axiom fliteral_axiom2 :
  t'isFinite fliteral2 /\ (* non escaped EOL for cpp parsing *)
  ((t'real fliteral2) =
   6703903964971298549787012499102923063739682910296196688861780721860882015036773488400937149083451713845015929093243025426876941405973284973216824503042048%R).

Axiom fl_last_sqrt__def_axiom : (fl_last_sqrt = fliteral2).

Parameter fliteral3: t.

Axiom fliteral_axiom3 :
  t'isFinite fliteral3 /\ (* non escaped EOL for cpp parsing *)
  ((t'real fliteral3) =
   (1491668146240041348658193063092586767475294306920081378854303666641255677014023660987234978080085560672302320651167220290682545619045060532097232965918416938296252158463756275499040814853287052588289310873012782953082843452117701424006337364600644548459512739853070043067441211667303325729200722585486710369393731465299801630663978357915766537189483642578125 / 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)%R).

(* Why3 goal *)
Theorem def'vc :
  dynamic_invariant fl_last_sqrt Init.Datatypes.true Init.Datatypes.false
  Init.Datatypes.true Init.Datatypes.true -> (fliteral2 = fl_last_sqrt) ->
  dynamic_invariant val1 Init.Datatypes.true Init.Datatypes.false
  Init.Datatypes.true Init.Datatypes.true ->
  dynamic_invariant val2 Init.Datatypes.true Init.Datatypes.false
  Init.Datatypes.true Init.Datatypes.true ->
  dynamic_invariant val3 Init.Datatypes.true Init.Datatypes.false
  Init.Datatypes.true Init.Datatypes.true ->
  (((le (neg fliteral2) val1 /\ le val1 fl_last_sqrt) /\ (* non escaped EOL for cpp parsing *)
    le (neg fliteral2) val2 /\ le val2 fl_last_sqrt) /\ (* non escaped EOL for cpp parsing *)
   le fliteral3 val3 /\ le val3 fliteral1) /\ (* non escaped EOL for cpp parsing *)
  le val1 val2 -> le (div RNE val1 val3) (div RNE val2 val3).
Proof.
intros h1 h2 h3 h4 h5 ((((h6,h7),(h8,h9)),(h10,h11)),h12).
unfold dynamic_invariant in *.
assert (Hdumb: true = true \/ le (neg fliteral1) fliteral1). auto.
specialize (h1 Hdumb).
specialize (h3 Hdumb).
specialize (h4 Hdumb).
specialize (h5 Hdumb).
(* file shared by the two lemmas dealing with 64-bit division *)

(* see float64_div_common.prf *)
Require Import Fourier.
Require Import Flocq.Core.Core.
set (a:=IZR 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).
set (b:=IZR 1491668146240041348658193063092586767475294306920081378854303666641255677014023660987234978080085560672302320651167220290682545619045060532097232965918416938296252158463756275499040814853287052588289310873012782953082843452117701424006337364600644548459512739853070043067441211667303325729200722585486710369393731465299801630663978357915766537189483642578125).
assert (0 < a) as a_pos by (now apply (IZR_lt 0)).
assert (0 < b) as b_pos by (now apply (IZR_lt 0)).


assert (t'real fliteral2 = IZR 6703903964971298549787012499102923063739682910296196688861780721860882015036773488400937149083451713845015929093243025426876941405973284973216824503042048) as l2_IZR
    by (destruct fliteral_axiom2 as [fliteral2_finite l_real2]; rewrite l_real2; auto).
assert (9007199254740991 *
        19958403095347198116563727130368385660674512604354575415025472424372118918689640657849579654926357010893424468441924952439724379883935936607391717982848314203200056729510856765175377214443629871826533567445439239933308104551208703888888552684480441575071209068757560416423584952303440099278848 =
        IZR 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368) as maxfloat_IZR by (ring_simplify; auto).

(* file shared by the two lemmas dealing 32/64-bit div monotonicity *)

assert (t'real fliteral3 = b / a) as l4real by
  (destruct fliteral_axiom3 as [fliteral3_finite l_real3]; rewrite l_real3; auto).

(* add the finitness of the concerned literals in the proof context *)
destruct fliteral_axiom1 as [fliteral1_finite l_real1].
destruct fliteral_axiom2 as [fliteral2_finite l_real2].
destruct fliteral_axiom3 as [fliteral3_finite l_real3].

(* project the le predicate on float to inequalities on reals *)
rewrite le_finite in h6, h7, h8, h9, h10, h11, h12; auto.

(* assert that l4 is strictly positive *)
assert (0 < t'real fliteral3) as l4_pos by
 (rewrite l4real; apply Rdiv_lt_0_compat; auto).

assert (t'real val3 <> 0) as v3real_neq_zero.
 {
   intro i. rewrite i in h10.
   rewrite l4real in h10. apply Rle_not_gt in h10.
   destruct h10. eapply Rmult_lt_reg_l with (/b).
   intuition. ring_simplify. field_simplify. unfold Rdiv. ring_simplify.
   intuition.
   split; try intro i2; rewrite i2 in *; eapply (Rle_not_gt 0 0); intuition.
 }

(* the following three lemmas specify that the division is finite *)
assert (~ is_zero val3) as v3_not_zero.
{
 intro Habs. apply v3real_neq_zero. apply zero_to_real in Habs; intuition.
}

assert (no_overflow RNE (t'real val1 / t'real val3)) as no_ov_v1v3.
{ apply Bounded_real_no_overflow.
  apply Abs.Abs_le.
  apply Rle_trans with (r2:=t'real fliteral2 * / t'real fliteral3); auto.
  unfold Rdiv.
  rewrite Abs.Abs_prod.
  apply Rmult_le_compat; try (apply Abs.Abs_pos).
  - rewrite <- h2 in *.
    rewrite Abs.Abs_le; rewrite l_real3, l_real2 in *; auto.
    split; auto.
    apply Rle_trans with (t'real (neg fliteral2)); auto.
    generalize (neg_finite fliteral2 fliteral2_finite). intro Hneg.
    destruct Hneg as [fin Hneg]. rewrite Hneg. rewrite l_real2. right. reflexivity.
  - rewrite Rbasic_fun.Rabs_right.
    apply Rinv_le_contravar; auto.
    apply Rle_ge.
    left; apply Rinv_0_lt_compat.
    rewrite l4real in *. eapply Rlt_le_trans with (b/a); auto.
  - rewrite l4real, Rinv_Rdiv.
    unfold Rdiv.
    rewrite <-Rmult_assoc.
    apply Rmult_le_reg_r with (r:=b); auto.
    field_simplify (t'real fliteral2 * a * / b * b).
    rewrite Real.infix_sl'def, Rinv_1, Rmult_1_r, l2_IZR, maxfloat_IZR.
    unfold a, b.
    repeat rewrite <-mult_IZR.
    apply IZR_le.
    ring_simplify; omega.

    intro i; rewrite i in b_pos; clear - b_pos; fourier.
    intro i; rewrite i in b_pos; clear - b_pos; fourier.
    intro i; rewrite i in a_pos; clear - a_pos; fourier. }

assert (no_overflow RNE (t'real val2 / t'real val3)) as no_ov_v2v3.
{ apply Bounded_real_no_overflow.
  apply Abs.Abs_le.
  apply Rle_trans with (r2:=t'real fliteral2 * / t'real fliteral3); auto.
  unfold Rdiv.
  rewrite Abs.Abs_prod.
  apply Rmult_le_compat; try (apply Abs.Abs_pos).
  - rewrite <- h2 in *.
    rewrite Abs.Abs_le; rewrite l_real3, l_real2, l_real1 in *; split; auto.
    apply Rle_trans with (t'real (neg fliteral2)); eauto.
    generalize (neg_finite fliteral2 fliteral2_finite). intro Hneg.
    destruct Hneg as [fin Hneg]. rewrite Hneg. rewrite l_real2. right. reflexivity.
  - rewrite Rbasic_fun.Rabs_right.
    apply Rinv_le_contravar; auto.
    apply Rle_ge.
    left; apply Rinv_0_lt_compat.
    clear -l4_pos h10. fourier.
  - rewrite l4real, Rinv_Rdiv.
    unfold Rdiv.
    rewrite <-Rmult_assoc.
    apply Rmult_le_reg_r with (r:=b); auto.
    field_simplify (t'real fliteral2 * a * / b * b).
    rewrite Real.infix_sl'def, Rinv_1, Rmult_1_r, l2_IZR, maxfloat_IZR.
    unfold a, b.
    repeat rewrite <-mult_IZR.
    apply IZR_le.
    ring_simplify; omega.

    intro i; rewrite i in b_pos; clear - b_pos; fourier.
    intro i; rewrite i in b_pos; clear - b_pos; fourier.
    intro i; rewrite i in a_pos; clear - a_pos; fourier. }

(* deduce the projections of val1 / val3 and val2 * val3 and that they
   are finite *)
destruct (div_finite RNE _ _ h3 h5 v3_not_zero no_ov_v1v3) as (v1v3_finite,to_real_v1v3).
destruct (div_finite RNE _ _ h4 h5 v3_not_zero no_ov_v2v3) as (v2v3_finite,to_real_v2v3).

(* project to real and conclude the proof using the monotonicity of
   round and monotonicity of the real multiplication *)
rewrite le_finite; auto.
rewrite to_real_v1v3, to_real_v2v3.
apply Round_monotonic.
apply Rmult_le_compat_r; auto.
left; apply Rinv_0_lt_compat; apply Rlt_le_trans with (t'real fliteral3); eauto.
split; auto. apply neg_finite; auto.
split; auto. apply neg_finite; auto.
Qed.

