(** Divisions that can be turned into multiplications by an inverse *)

Definition Bexact_inverse_mantissa := Z.iter (prec - 1) xO xH.Remark Bexact_inverse_mantissa_value:
  Zpos Bexact_inverse_mantissa = 2 ^ (prec - 1).Remark Bexact_inverse_mantissa_digits2_pos:
  Z.pos (digits2_pos Bexact_inverse_mantissa) = prec.Remark bounded_Bexact_inverse:
  forall e,
  emin <= e <= emax - prec <-> bounded prec emax Bexact_inverse_mantissa e = true.Program Definition Bexact_inverse (f: binary_float) : option binary_float :=
  match f with
  | B754_finite _ _ s m e B =>
      if Pos.eq_dec m Bexact_inverse_mantissa then
      let e' := -e - (prec - 1) * 2 in
      if Z_le_dec emin e' then
      if Z_le_dec e' emax then
        Some(B754_finite _ _ s m e' _)
      else None else None else None
  | _ => None
  end.

(* Specifications: *)
Lemma Bexact_inverse_correct: forall f f', Bexact_inverse f = Some f' -> is_finite_strict _ _ f = true /\ is_finite_strict _ _ f' = true /\ B2R _ _ f' = (/ B2R _ _ f)%R /\ B2R _ _ f <> 0%R /\ Bsign _ _ f' = Bsign _ _ f.
Theorem Bdiv_mult_inverse: forall div_nan mult_nan mode x y z, (forall (x y z: binary_float), is_nan _ _ x = true -> is_finite _ _ y = true -> is_finite _ _ z = true -> div_nan x y = mult_nan x z) -> Bexact_inverse y = Some z -> Bdiv _ _ _ Hmax div_nan mode x y = Bmult _ _ _ Hmax mult_nan mode x z.
Lemma Bexact_inverse_correct: forall f f', Bexact_inverse f = Some f' -> is_finite_strict _ _ f = true /\ is_finite_strict _ _ f' = true /\ B2R _ _ f' = (/ B2R _ _ f)%R /\ B2R _ _ f <> 0%R /\ Bsign _ _ f' = Bsign _ _ f.
Theorem Bdiv_mult_inverse: forall div_nan mult_nan mode x y z, (forall (x y z: binary_float), is_nan _ _ x = true -> is_finite _ _ y = true -> is_finite _ _ z = true -> div_nan x y = mult_nan x z) -> Bexact_inverse y = Some z -> Bdiv _ _ _ Hmax div_nan mode x y = Bmult _ _ _ Hmax mult_nan mode x z.