Definition double_round_mult_hyp fexp1 fexp2 :=
  (forall ex ey, (fexp2 (ex + ey) <= fexp1 ex + fexp1 ey)%Z)
  /\ (forall ex ey, (fexp2 (ex + ey - 1) <= fexp1 ex + fexp1 ey)%Z).

(* Specifications: *)
Lemma double_round_mult_aux : forall (fexp1 fexp2 : Z -> Z), double_round_mult_hyp fexp1 fexp2 -> forall x y, generic_format beta fexp1 x -> generic_format beta fexp1 y -> generic_format beta fexp2 (x * y).
Theorem double_round_mult : forall (fexp1 fexp2 : Z -> Z), double_round_mult_hyp fexp1 fexp2 -> forall x y, generic_format beta fexp1 x -> generic_format beta fexp1 y -> round beta fexp1 rnd (round beta fexp2 rnd (x * y)) = round beta fexp1 rnd (x * y).
Theorem double_round_mult_FLX : (2 * prec <= prec')%Z -> forall x y, FLX_format beta prec x -> FLX_format beta prec y -> round beta (FLX_exp prec) rnd (round beta (FLX_exp prec') rnd (x * y)) = round beta (FLX_exp prec) rnd (x * y).
Theorem double_round_mult_FLT : (emin' <= 2 * emin)%Z -> (2 * prec <= prec')%Z -> forall x y, FLT_format beta emin prec x -> FLT_format beta emin prec y -> round beta (FLT_exp emin prec) rnd (round beta (FLT_exp emin' prec') rnd (x * y)) = round beta (FLT_exp emin prec) rnd (x * y).
Theorem double_round_mult_FTZ : (emin' + prec' <= 2 * emin + prec)%Z -> (2 * prec <= prec')%Z -> forall x y, FTZ_format beta emin prec x -> FTZ_format beta emin prec y -> round beta (FTZ_exp emin prec) rnd (round beta (FTZ_exp emin' prec') rnd (x * y)) = round beta (FTZ_exp emin prec) rnd (x * y).
Lemma ln_beta_plus_disj : forall x y, 0 < y -> y <= x -> ((ln_beta (x + y) = ln_beta x :> Z) \/ (ln_beta (x + y) = (ln_beta x + 1)%Z :> Z)).
Lemma ln_beta_plus_separated : forall fexp : Z -> Z, forall x y, 0 < x -> 0 <= y -> generic_format beta fexp x -> (ln_beta y <= fexp (ln_beta x))%Z -> (ln_beta (x + y) = ln_beta x :> Z).
Lemma ln_beta_minus_disj : forall x y, 0 < x -> 0 < y -> (ln_beta y <= ln_beta x - 2)%Z -> ((ln_beta (x - y) = ln_beta x :> Z) \/ (ln_beta (x - y) = (ln_beta x - 1)%Z :> Z)).
Lemma ln_beta_minus_separated : forall fexp : Z -> Z, Valid_exp fexp -> forall x y, 0 < x -> 0 < y -> y < x -> bpow (ln_beta x - 1) < x -> generic_format beta fexp x -> (ln_beta y <= fexp (ln_beta x))%Z -> (ln_beta (x - y) = ln_beta x :> Z).
Lemma double_round_mult_aux : forall (fexp1 fexp2 : Z -> Z), double_round_mult_hyp fexp1 fexp2 -> forall x y, generic_format beta fexp1 x -> generic_format beta fexp1 y -> generic_format beta fexp2 (x * y).
Theorem double_round_mult : forall (fexp1 fexp2 : Z -> Z), double_round_mult_hyp fexp1 fexp2 -> forall x y, generic_format beta fexp1 x -> generic_format beta fexp1 y -> round beta fexp1 rnd (round beta fexp2 rnd (x * y)) = round beta fexp1 rnd (x * y).
Theorem double_round_mult_FLX : (2 * prec <= prec')%Z -> forall x y, FLX_format beta prec x -> FLX_format beta prec y -> round beta (FLX_exp prec) rnd (round beta (FLX_exp prec') rnd (x * y)) = round beta (FLX_exp prec) rnd (x * y).
Theorem double_round_mult_FLT : (emin' <= 2 * emin)%Z -> (2 * prec <= prec')%Z -> forall x y, FLT_format beta emin prec x -> FLT_format beta emin prec y -> round beta (FLT_exp emin prec) rnd (round beta (FLT_exp emin' prec') rnd (x * y)) = round beta (FLT_exp emin prec) rnd (x * y).
Theorem double_round_mult_FTZ : (emin' + prec' <= 2 * emin + prec)%Z -> (2 * prec <= prec')%Z -> forall x y, FTZ_format beta emin prec x -> FTZ_format beta emin prec y -> round beta (FTZ_exp emin prec) rnd (round beta (FTZ_exp emin' prec') rnd (x * y)) = round beta (FTZ_exp emin prec) rnd (x * y).
Lemma ln_beta_plus_disj : forall x y, 0 < y -> y <= x -> ((ln_beta (x + y) = ln_beta x :> Z) \/ (ln_beta (x + y) = (ln_beta x + 1)%Z :> Z)).
Lemma ln_beta_plus_separated : forall fexp : Z -> Z, forall x y, 0 < x -> 0 <= y -> generic_format beta fexp x -> (ln_beta y <= fexp (ln_beta x))%Z -> (ln_beta (x + y) = ln_beta x :> Z).
Lemma ln_beta_minus_disj : forall x y, 0 < x -> 0 < y -> (ln_beta y <= ln_beta x - 2)%Z -> ((ln_beta (x - y) = ln_beta x :> Z) \/ (ln_beta (x - y) = (ln_beta x - 1)%Z :> Z)).
Lemma ln_beta_minus_separated : forall fexp : Z -> Z, Valid_exp fexp -> forall x y, 0 < x -> 0 < y -> y < x -> bpow (ln_beta x - 1) < x -> generic_format beta fexp x -> (ln_beta y <= fexp (ln_beta x))%Z -> (ln_beta (x - y) = ln_beta x :> Z).