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).
(* fexp1 (ln_beta x) - 1 <= ln_beta y : * addition is exact in the largest precision (fexp2). *)
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).
(* ln_beta y <= fexp1 (ln_beta x) - 2 : double_round_lt_mid applies. *)
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).
(* double_round_plus_aux{0,1} together *)
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).
(* fexp1 (ln_beta x) - 1 <= ln_beta y : * substraction is exact in the largest precision (fexp2). *)
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).
(* ln_beta y <= fexp1 (ln_beta x) - 2, * fexp1 (ln_beta (x - y)) - 1 <= ln_beta y : * substraction is exact in the largest precision (fexp2). *)
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.
(* ln_beta y <= fexp1 (ln_beta x) - 2 : * ln_beta y <= fexp1 (ln_beta (x - y)) - 2 : * double_round_gt_mid applies. *)
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).
(* double_round_minus_aux{0,1,2} together *)
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).