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

(* Specifications: *)
Lemma ln_beta_sqrt_disj : forall x, 0 < x -> (ln_beta x = 2 * ln_beta (sqrt x) - 1 :> Z)%Z \/ (ln_beta x = 2 * ln_beta (sqrt x) :> Z)%Z.
Lemma double_round_sqrt_aux : forall fexp1 fexp2 : Z -> Z, Valid_exp fexp1 -> Valid_exp fexp2 -> double_round_sqrt_hyp fexp1 fexp2 -> forall x, 0 < x -> (fexp2 (ln_beta (sqrt x)) <= fexp1 (ln_beta (sqrt x)) - 1)%Z -> generic_format beta fexp1 x -> / 2 * ulp beta fexp2 (sqrt x) < Rabs (sqrt x - midp fexp1 (sqrt x)).
Lemma double_round_sqrt : forall fexp1 fexp2 : Z -> Z, Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_sqrt_hyp fexp1 fexp2 -> forall x, generic_format beta fexp1 x -> double_round_eq fexp1 fexp2 choice1 choice2 (sqrt x).
Lemma FLX_double_round_sqrt_hyp : (2 * prec + 2 <= prec')%Z -> double_round_sqrt_hyp (FLX_exp prec) (FLX_exp prec').
Theorem double_round_sqrt_FLX : forall choice1 choice2, (2 * prec + 2 <= prec')%Z -> forall x, FLX_format beta prec x -> double_round_eq (FLX_exp prec) (FLX_exp prec') choice1 choice2 (sqrt x).
Lemma FLT_double_round_sqrt_hyp : (emin <= 0)%Z -> ((emin' <= emin - prec - 2)%Z \/ (2 * emin' <= emin - 4 * prec - 2)%Z) -> (2 * prec + 2 <= prec')%Z -> double_round_sqrt_hyp (FLT_exp emin prec) (FLT_exp emin' prec').
Theorem double_round_sqrt_FLT : forall choice1 choice2, (emin <= 0)%Z -> ((emin' <= emin - prec - 2)%Z \/ (2 * emin' <= emin - 4 * prec - 2)%Z) -> (2 * prec + 2 <= prec')%Z -> forall x, FLT_format beta emin prec x -> double_round_eq (FLT_exp emin prec) (FLT_exp emin' prec') choice1 choice2 (sqrt x).
Lemma FTZ_double_round_sqrt_hyp : (2 * (emin' + prec') <= emin + prec <= 1)%Z -> (2 * prec + 2 <= prec')%Z -> double_round_sqrt_hyp (FTZ_exp emin prec) (FTZ_exp emin' prec').
Theorem double_round_sqrt_FTZ : (4 <= beta)%Z -> forall choice1 choice2, (2 * (emin' + prec') <= emin + prec <= 1)%Z -> (2 * prec + 2 <= prec')%Z -> forall x, FTZ_format beta emin prec x -> double_round_eq (FTZ_exp emin prec) (FTZ_exp emin' prec') choice1 choice2 (sqrt x).
Lemma ln_beta_sqrt_disj : forall x, 0 < x -> (ln_beta x = 2 * ln_beta (sqrt x) - 1 :> Z)%Z \/ (ln_beta x = 2 * ln_beta (sqrt x) :> Z)%Z.
Lemma double_round_sqrt_aux : forall fexp1 fexp2 : Z -> Z, Valid_exp fexp1 -> Valid_exp fexp2 -> double_round_sqrt_hyp fexp1 fexp2 -> forall x, 0 < x -> (fexp2 (ln_beta (sqrt x)) <= fexp1 (ln_beta (sqrt x)) - 1)%Z -> generic_format beta fexp1 x -> / 2 * ulp beta fexp2 (sqrt x) < Rabs (sqrt x - midp fexp1 (sqrt x)).
Lemma double_round_sqrt : forall fexp1 fexp2 : Z -> Z, Valid_exp fexp1 -> Valid_exp fexp2 -> forall (choice1 choice2 : Z -> bool), double_round_sqrt_hyp fexp1 fexp2 -> forall x, generic_format beta fexp1 x -> double_round_eq fexp1 fexp2 choice1 choice2 (sqrt x).
Lemma FLX_double_round_sqrt_hyp : (2 * prec + 2 <= prec')%Z -> double_round_sqrt_hyp (FLX_exp prec) (FLX_exp prec').
Theorem double_round_sqrt_FLX : forall choice1 choice2, (2 * prec + 2 <= prec')%Z -> forall x, FLX_format beta prec x -> double_round_eq (FLX_exp prec) (FLX_exp prec') choice1 choice2 (sqrt x).
Lemma FLT_double_round_sqrt_hyp : (emin <= 0)%Z -> ((emin' <= emin - prec - 2)%Z \/ (2 * emin' <= emin - 4 * prec - 2)%Z) -> (2 * prec + 2 <= prec')%Z -> double_round_sqrt_hyp (FLT_exp emin prec) (FLT_exp emin' prec').
Theorem double_round_sqrt_FLT : forall choice1 choice2, (emin <= 0)%Z -> ((emin' <= emin - prec - 2)%Z \/ (2 * emin' <= emin - 4 * prec - 2)%Z) -> (2 * prec + 2 <= prec')%Z -> forall x, FLT_format beta emin prec x -> double_round_eq (FLT_exp emin prec) (FLT_exp emin' prec') choice1 choice2 (sqrt x).
Lemma FTZ_double_round_sqrt_hyp : (2 * (emin' + prec') <= emin + prec <= 1)%Z -> (2 * prec + 2 <= prec')%Z -> double_round_sqrt_hyp (FTZ_exp emin prec) (FTZ_exp emin' prec').
Theorem double_round_sqrt_FTZ : (4 <= beta)%Z -> forall choice1 choice2, (2 * (emin' + prec') <= emin + prec <= 1)%Z -> (2 * prec + 2 <= prec')%Z -> forall x, FTZ_format beta emin prec x -> double_round_eq (FTZ_exp emin prec) (FTZ_exp emin' prec') choice1 choice2 (sqrt x).