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

(* Specifications: *)
Lemma double_round_plus_aux0_aux_aux : forall (fexp1 fexp2 : Z -> Z), forall x y, (fexp1 (ln_beta x) <= fexp1 (ln_beta y))%Z -> (fexp2 (ln_beta (x + y))%Z <= fexp1 (ln_beta x))%Z -> (fexp2 (ln_beta (x + y))%Z <= fexp1 (ln_beta y))%Z -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> generic_format beta fexp2 (x + y).
Lemma double_round_plus_aux0_aux : forall (fexp1 fexp2 : Z -> Z), forall x y, (fexp2 (ln_beta (x + y))%Z <= fexp1 (ln_beta x))%Z -> (fexp2 (ln_beta (x + y))%Z <= fexp1 (ln_beta y))%Z -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> generic_format beta fexp2 (x + y).
Lemma double_round_plus_aux0 : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> double_round_plus_hyp fexp1 fexp2 -> forall x y, (0 < x)%R -> (0 < y)%R -> (y <= x)%R -> (fexp1 (ln_beta x) - 1 <= ln_beta y)%Z -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> generic_format beta fexp2 (x + y).
Lemma double_round_plus_aux1_aux : forall k, (0 < k)%Z -> forall (fexp : Z -> Z), forall x y, 0 < x -> 0 < y -> (ln_beta y <= fexp (ln_beta x) - k)%Z -> (ln_beta (x + y) = ln_beta x :> Z) -> generic_format beta fexp x -> 0 < (x + y) - round beta fexp Zfloor (x + y) < bpow (fexp (ln_beta x) - k).
Lemma double_round_plus_aux1 : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 < x -> 0 < y -> (ln_beta y <= fexp1 (ln_beta x) - 2)%Z -> generic_format beta fexp1 x -> double_round_eq fexp1 fexp2 choice1 choice2 (x + y).
Lemma double_round_plus_aux2 : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 < x -> 0 < y -> y <= x -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> double_round_eq fexp1 fexp2 choice1 choice2 (x + y).
Lemma double_round_plus_aux : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 <= x -> 0 <= y -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> double_round_eq fexp1 fexp2 choice1 choice2 (x + y).
Lemma double_round_minus_aux0_aux : forall (fexp1 fexp2 : Z -> Z), forall x y, (fexp2 (ln_beta (x - y))%Z <= fexp1 (ln_beta x))%Z -> (fexp2 (ln_beta (x - y))%Z <= fexp1 (ln_beta y))%Z -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> generic_format beta fexp2 (x - y).
Lemma double_round_minus_aux0 : forall (fexp1 fexp2 : Z -> Z), double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 < y -> y < x -> (fexp1 (ln_beta x) - 1 <= ln_beta y)%Z -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> generic_format beta fexp2 (x - y).
Lemma double_round_minus_aux1 : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 < y -> y < x -> (ln_beta y <= fexp1 (ln_beta x) - 2)%Z -> (fexp1 (ln_beta (x - y)) - 1 <= ln_beta y)%Z -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> generic_format beta fexp2 (x - y).
Lemma double_round_minus_aux2_aux : forall (fexp : Z -> Z), Valid_exp fexp -> forall x y, 0 < y -> y < x -> (ln_beta y <= fexp (ln_beta x) - 1)%Z -> generic_format beta fexp x -> generic_format beta fexp y -> round beta fexp Zceil (x - y) - (x - y) <= y.
Lemma double_round_minus_aux2 : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 < y -> y < x -> (ln_beta y <= fexp1 (ln_beta x) - 2)%Z -> (ln_beta y <= fexp1 (ln_beta (x - y)) - 2)%Z -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> double_round_eq fexp1 fexp2 choice1 choice2 (x - y).
Lemma double_round_minus_aux3 : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 < y -> y <= x -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> double_round_eq fexp1 fexp2 choice1 choice2 (x - y).
Lemma double_round_minus_aux : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 <= x -> 0 <= y -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> double_round_eq fexp1 fexp2 choice1 choice2 (x - y).
Lemma double_round_plus : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, generic_format beta fexp1 x -> generic_format beta fexp1 y -> double_round_eq fexp1 fexp2 choice1 choice2 (x + y).
Lemma double_round_minus : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, generic_format beta fexp1 x -> generic_format beta fexp1 y -> double_round_eq fexp1 fexp2 choice1 choice2 (x - y).
Lemma FLX_double_round_plus_hyp : (2 * prec + 1 <= prec')%Z -> double_round_plus_hyp (FLX_exp prec) (FLX_exp prec').
Theorem double_round_plus_FLX : forall choice1 choice2, (2 * prec + 1 <= prec')%Z -> forall x y, FLX_format beta prec x -> FLX_format beta prec y -> double_round_eq (FLX_exp prec) (FLX_exp prec') choice1 choice2 (x + y).
Theorem double_round_minus_FLX : forall choice1 choice2, (2 * prec + 1 <= prec')%Z -> forall x y, FLX_format beta prec x -> FLX_format beta prec y -> double_round_eq (FLX_exp prec) (FLX_exp prec') choice1 choice2 (x - y).
Lemma FLT_double_round_plus_hyp : (emin' <= emin)%Z -> (2 * prec + 1 <= prec')%Z -> double_round_plus_hyp (FLT_exp emin prec) (FLT_exp emin' prec').
Theorem double_round_plus_FLT : forall choice1 choice2, (emin' <= emin)%Z -> (2 * prec + 1 <= prec')%Z -> forall x y, FLT_format beta emin prec x -> FLT_format beta emin prec y -> double_round_eq (FLT_exp emin prec) (FLT_exp emin' prec') choice1 choice2 (x + y).
Theorem double_round_minus_FLT : forall choice1 choice2, (emin' <= emin)%Z -> (2 * prec + 1 <= prec')%Z -> forall x y, FLT_format beta emin prec x -> FLT_format beta emin prec y -> double_round_eq (FLT_exp emin prec) (FLT_exp emin' prec') choice1 choice2 (x - y).
Lemma FTZ_double_round_plus_hyp : (emin' + prec' <= emin + 1)%Z -> (2 * prec + 1 <= prec')%Z -> double_round_plus_hyp (FTZ_exp emin prec) (FTZ_exp emin' prec').
Theorem double_round_plus_FTZ : forall choice1 choice2, (emin' + prec' <= emin + 1)%Z -> (2 * prec + 1 <= prec')%Z -> forall x y, FTZ_format beta emin prec x -> FTZ_format beta emin prec y -> double_round_eq (FTZ_exp emin prec) (FTZ_exp emin' prec') choice1 choice2 (x + y).
Theorem double_round_minus_FTZ : forall choice1 choice2, (emin' + prec' <= emin + 1)%Z -> (2 * prec + 1 <= prec')%Z -> forall x y, FTZ_format beta emin prec x -> FTZ_format beta emin prec y -> double_round_eq (FTZ_exp emin prec) (FTZ_exp emin' prec') choice1 choice2 (x - y).
Lemma double_round_plus_aux0_aux_aux : forall (fexp1 fexp2 : Z -> Z), forall x y, (fexp1 (ln_beta x) <= fexp1 (ln_beta y))%Z -> (fexp2 (ln_beta (x + y))%Z <= fexp1 (ln_beta x))%Z -> (fexp2 (ln_beta (x + y))%Z <= fexp1 (ln_beta y))%Z -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> generic_format beta fexp2 (x + y).
Lemma double_round_plus_aux0_aux : forall (fexp1 fexp2 : Z -> Z), forall x y, (fexp2 (ln_beta (x + y))%Z <= fexp1 (ln_beta x))%Z -> (fexp2 (ln_beta (x + y))%Z <= fexp1 (ln_beta y))%Z -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> generic_format beta fexp2 (x + y).
Lemma double_round_plus_aux0 : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> double_round_plus_hyp fexp1 fexp2 -> forall x y, (0 < x)%R -> (0 < y)%R -> (y <= x)%R -> (fexp1 (ln_beta x) - 1 <= ln_beta y)%Z -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> generic_format beta fexp2 (x + y).
Lemma double_round_plus_aux1_aux : forall k, (0 < k)%Z -> forall (fexp : Z -> Z), forall x y, 0 < x -> 0 < y -> (ln_beta y <= fexp (ln_beta x) - k)%Z -> (ln_beta (x + y) = ln_beta x :> Z) -> generic_format beta fexp x -> 0 < (x + y) - round beta fexp Zfloor (x + y) < bpow (fexp (ln_beta x) - k).
Lemma double_round_plus_aux1 : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 < x -> 0 < y -> (ln_beta y <= fexp1 (ln_beta x) - 2)%Z -> generic_format beta fexp1 x -> double_round_eq fexp1 fexp2 choice1 choice2 (x + y).
Lemma double_round_plus_aux2 : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 < x -> 0 < y -> y <= x -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> double_round_eq fexp1 fexp2 choice1 choice2 (x + y).
Lemma double_round_plus_aux : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 <= x -> 0 <= y -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> double_round_eq fexp1 fexp2 choice1 choice2 (x + y).
Lemma double_round_minus_aux0_aux : forall (fexp1 fexp2 : Z -> Z), forall x y, (fexp2 (ln_beta (x - y))%Z <= fexp1 (ln_beta x))%Z -> (fexp2 (ln_beta (x - y))%Z <= fexp1 (ln_beta y))%Z -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> generic_format beta fexp2 (x - y).
Lemma double_round_minus_aux0 : forall (fexp1 fexp2 : Z -> Z), double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 < y -> y < x -> (fexp1 (ln_beta x) - 1 <= ln_beta y)%Z -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> generic_format beta fexp2 (x - y).
Lemma double_round_minus_aux1 : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 < y -> y < x -> (ln_beta y <= fexp1 (ln_beta x) - 2)%Z -> (fexp1 (ln_beta (x - y)) - 1 <= ln_beta y)%Z -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> generic_format beta fexp2 (x - y).
Lemma double_round_minus_aux2_aux : forall (fexp : Z -> Z), Valid_exp fexp -> forall x y, 0 < y -> y < x -> (ln_beta y <= fexp (ln_beta x) - 1)%Z -> generic_format beta fexp x -> generic_format beta fexp y -> round beta fexp Zceil (x - y) - (x - y) <= y.
Lemma double_round_minus_aux2 : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 < y -> y < x -> (ln_beta y <= fexp1 (ln_beta x) - 2)%Z -> (ln_beta y <= fexp1 (ln_beta (x - y)) - 2)%Z -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> double_round_eq fexp1 fexp2 choice1 choice2 (x - y).
Lemma double_round_minus_aux3 : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 < y -> y <= x -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> double_round_eq fexp1 fexp2 choice1 choice2 (x - y).
Lemma double_round_minus_aux : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, 0 <= x -> 0 <= y -> generic_format beta fexp1 x -> generic_format beta fexp1 y -> double_round_eq fexp1 fexp2 choice1 choice2 (x - y).
Lemma double_round_plus : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, generic_format beta fexp1 x -> generic_format beta fexp1 y -> double_round_eq fexp1 fexp2 choice1 choice2 (x + y).
Lemma double_round_minus : forall (fexp1 fexp2 : Z -> Z), Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_plus_hyp fexp1 fexp2 -> forall x y, generic_format beta fexp1 x -> generic_format beta fexp1 y -> double_round_eq fexp1 fexp2 choice1 choice2 (x - y).
Lemma FLX_double_round_plus_hyp : (2 * prec + 1 <= prec')%Z -> double_round_plus_hyp (FLX_exp prec) (FLX_exp prec').
Theorem double_round_plus_FLX : forall choice1 choice2, (2 * prec + 1 <= prec')%Z -> forall x y, FLX_format beta prec x -> FLX_format beta prec y -> double_round_eq (FLX_exp prec) (FLX_exp prec') choice1 choice2 (x + y).
Theorem double_round_minus_FLX : forall choice1 choice2, (2 * prec + 1 <= prec')%Z -> forall x y, FLX_format beta prec x -> FLX_format beta prec y -> double_round_eq (FLX_exp prec) (FLX_exp prec') choice1 choice2 (x - y).
Lemma FLT_double_round_plus_hyp : (emin' <= emin)%Z -> (2 * prec + 1 <= prec')%Z -> double_round_plus_hyp (FLT_exp emin prec) (FLT_exp emin' prec').
Theorem double_round_plus_FLT : forall choice1 choice2, (emin' <= emin)%Z -> (2 * prec + 1 <= prec')%Z -> forall x y, FLT_format beta emin prec x -> FLT_format beta emin prec y -> double_round_eq (FLT_exp emin prec) (FLT_exp emin' prec') choice1 choice2 (x + y).
Theorem double_round_minus_FLT : forall choice1 choice2, (emin' <= emin)%Z -> (2 * prec + 1 <= prec')%Z -> forall x y, FLT_format beta emin prec x -> FLT_format beta emin prec y -> double_round_eq (FLT_exp emin prec) (FLT_exp emin' prec') choice1 choice2 (x - y).
Lemma FTZ_double_round_plus_hyp : (emin' + prec' <= emin + 1)%Z -> (2 * prec + 1 <= prec')%Z -> double_round_plus_hyp (FTZ_exp emin prec) (FTZ_exp emin' prec').
Theorem double_round_plus_FTZ : forall choice1 choice2, (emin' + prec' <= emin + 1)%Z -> (2 * prec + 1 <= prec')%Z -> forall x y, FTZ_format beta emin prec x -> FTZ_format beta emin prec y -> double_round_eq (FTZ_exp emin prec) (FTZ_exp emin' prec') choice1 choice2 (x + y).
Theorem double_round_minus_FTZ : forall choice1 choice2, (emin' + prec' <= emin + 1)%Z -> (2 * prec + 1 <= prec')%Z -> forall x y, FTZ_format beta emin prec x -> FTZ_format beta emin prec y -> double_round_eq (FTZ_exp emin prec) (FTZ_exp emin' prec') choice1 choice2 (x - y).