Ltac Inside_Square_Qsgn_ p1 p2 :=
  repeat
   match goal with
   | id1:(?X1 < ?X2)%Z |- _ =>
       unfold X2 in id1 || unfold X1 in id1;
        repeat
         match goal with
         | id1:(2 < outside_square ?X1 ?X2 ?X3 ?X4)%Z,id2:
         (~ (?X2 = 0%Z /\ ?X3 = 0%Z /\ ?X4 = 0%Z)) |- _ =>
             generalize
              (Qsgn_7 _ (outside_square_correct_1 X1 X2 X3 X4 p1 p2 id1 id2));
              clear id1
         | id1:(outside_square ?X1 ?X2 ?X3 ?X4 < -2)%Z,id2:
         (~ (?X2 = 0%Z /\ ?X3 = 0%Z /\ ?X4 = 0%Z)) |- _ =>
             generalize
              (Qsgn_8 _ (outside_square_correct_2 X1 X2 X3 X4 p1 p2 id1 id2));
              clear id1
         end
   end.

(* Specifications: *)
Lemma quadratic_sign : forall (a b c d e f g h : Z) (p1 p2 : Qpositive) (H_Qquadratic_sg_denom_nonzero : Qquadratic_sg_denom_nonzero e f g h p1 p2), q_sign a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero = Qsgn (spec_Qquadratic_Qpositive_to_Q a b c d e f g h p1 p2).
Lemma quadraticAcc_positive : forall (a b c d e f g h : Z) (p1 p2 : Qpositive), quadraticAcc a b c d e f g h p1 p2 -> Qlt Zero (Qplus (Qplus (Qplus (Qmult (Qmult a (Qpos p1)) (Qpos p2)) (Qmult b (Qpos p1))) (Qmult c (Qpos p2))) d) /\ Qlt Zero (Qplus (Qplus (Qplus (Qmult (Qmult e (Qpos p1)) (Qpos p2)) (Qmult f (Qpos p1))) (Qmult g (Qpos p2))) h).
Lemma quadraticAcc_positive_numerator : forall (a b c d e f g h : Z) (p1 p2 : Qpositive), quadraticAcc a b c d e f g h p1 p2 -> Qlt Zero (Qplus (Qplus (Qplus (Qmult (Qmult a (Qpos p1)) (Qpos p2)) (Qmult b (Qpos p1))) (Qmult c (Qpos p2))) d).
Lemma quadraticAcc_positive_denominator : forall (a b c d e f g h : Z) (p1 p2 : Qpositive), quadraticAcc a b c d e f g h p1 p2 -> Qlt Zero (Qplus (Qplus (Qplus (Qmult (Qmult e (Qpos p1)) (Qpos p2)) (Qmult f (Qpos p1))) (Qmult g (Qpos p2))) h).
Lemma quadratic_output_bit : forall (a b c d e f g h : Z) (p1 p2 : Qpositive) (hyp_quadraticAcc : quadraticAcc a b c d e f g h p1 p2), Qquadratic_Qpositive_to_Qpositive a b c d e f g h p1 p2 hyp_quadraticAcc = spec_Qquadratic_Qpositive_to_Qpositive2 a b c d e f g h p1 p2.
Lemma spec_Qquadratic_Qpositive_to_Q_spec_Qquadratic_Qpositive_to_Qpositive2_pos : forall (a b c d e f g h : Z) (p1 p2 : Qpositive), Qsgn (spec_Qquadratic_Qpositive_to_Q a b c d e f g h p1 p2) = 1%Z -> spec_Qquadratic_Qpositive_to_Q a b c d e f g h p1 p2 = Qpos (spec_Qquadratic_Qpositive_to_Qpositive2 a b c d e f g h p1 p2).
Lemma spec_Qquadratic_Qpositive_to_Q_spec_Qquadratic_Qpositive_to_Qpositive2_neg_1 : forall (a b c d e f g h : Z) (p1 p2 : Qpositive), Qsgn (spec_Qquadratic_Qpositive_to_Q a b c d e f g h p1 p2) = (-1)%Z -> spec_Qquadratic_Qpositive_to_Q a b c d e f g h p1 p2 = Qneg (spec_Qquadratic_Qpositive_to_Qpositive2 (- a) (- b) (- c) (- d) e f g h p1 p2).
Lemma spec_Qquadratic_Qpositive_to_Q_spec_Qquadratic_Qpositive_to_Qpositive2_neg_2 : forall (a b c d e f g h : Z) (p1 p2 : Qpositive), Qsgn (spec_Qquadratic_Qpositive_to_Q a b c d e f g h p1 p2) = (-1)%Z -> spec_Qquadratic_Qpositive_to_Q a b c d e f g h p1 p2 = Qneg (spec_Qquadratic_Qpositive_to_Qpositive2 a b c d (- e) (- f) (- g) (- h) p1 p2).
Lemma spec_Qquadratic_Qpositive_to_Q_Zopp : forall (a b c d e f g h : Z) (p1 p2 : Qpositive), spec_Qquadratic_Qpositive_to_Q (- a) (- b) (- c) (- d) (- e) (- f) (- g) (- h) p1 p2 = spec_Qquadratic_Qpositive_to_Q a b c d e f g h p1 p2.
Lemma spec_Qquadratic_Qpositive_to_Q_Zopp_2 : forall (a b c d e f g h : Z) (p1 p2 : Qpositive), spec_Qquadratic_Qpositive_to_Q (- a) (- b) (- c) (- d) e f g h p1 p2 = Qopp (spec_Qquadratic_Qpositive_to_Q a b c d e f g h p1 p2).
Lemma spec_Qquadratic_Qpositive_to_Q_Zopp_3 : forall (a b c d e f g h : Z) (p1 p2 : Qpositive), spec_Qquadratic_Qpositive_to_Q a b c d (- e) (- f) (- g) (- h) p1 p2 = Qopp (spec_Qquadratic_Qpositive_to_Q a b c d e f g h p1 p2).
Lemma Qquadratic_sign_pres_fraction : forall (a b c d e f g h : Z) (p1 p2 : Qpositive) (H_Qquadratic_sg_denom_nonzero : Qquadratic_sg_denom_nonzero e f g h p1 p2), Qmult (Qplus (Qplus (Qplus (Qmult (Qmult (qnew_a a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero) (Qpos (qnew_p1 a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero))) (Qpos (qnew_p2 a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero))) (Qmult (qnew_b a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero) (Qpos (qnew_p1 a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero)))) (Qmult (qnew_c a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero) (Qpos (qnew_p2 a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero)))) (qnew_d a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero)) (Qinv (Qplus (Qplus (Qplus (Qmult (Qmult (qnew_e a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero) (Qpos (qnew_p1 a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero))) (Qpos (qnew_p2 a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero))) (Qmult (qnew_f a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero) (Qpos (qnew_p1 a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero)))) (Qmult (qnew_g a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero) (Qpos (qnew_p2 a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero)))) (qnew_h a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero))) = Qmult (Qplus (Qplus (Qplus (Qmult (Qmult a (Qpos p1)) (Qpos p2)) (Qmult b (Qpos p1))) (Qmult c (Qpos p2))) d) (Qinv (Qplus (Qplus (Qplus (Qmult (Qmult e (Qpos p1)) (Qpos p2)) (Qmult f (Qpos p1))) (Qmult g (Qpos p2))) h)).
Lemma Qquadratic_sg_denom_nonzero_correct_1 : forall (e f g h : Z) (p1 p2 : Qpositive), Qquadratic_sg_denom_nonzero e f g h p1 p2 -> Qplus (Qplus (Qplus (Qmult (Qmult e (Qpos p1)) (Qpos p2)) (Qmult f (Qpos p1))) (Qmult g (Qpos p2))) h <> Zero.
Lemma Qquadratic_sg_denom_nonzero_correct_2 : forall (e f g h : Z) (p1 p2 : Qpositive), Qplus (Qplus (Qplus (Qmult (Qmult e (Qpos p1)) (Qpos p2)) (Qmult f (Qpos p1))) (Qmult g (Qpos p2))) h <> Zero -> Qquadratic_sg_denom_nonzero e f g h p1 p2.
Lemma a_field_equality_2 : forall a b c d e f g h q1 q2 : Q, e <> Zero -> Qmult a h = Qmult d e -> Qmult a g = Qmult c e -> Qmult a f = Qmult b e -> Qplus (Qplus (Qplus (Qmult (Qmult e q1) q2) (Qmult f q1)) (Qmult g q2)) h <> Zero -> Qmult a (Qinv e) = Qmult (Qplus (Qplus (Qplus (Qmult (Qmult a q1) q2) (Qmult b q1)) (Qmult c q2)) d) (Qinv (Qplus (Qplus (Qplus (Qmult (Qmult e q1) q2) (Qmult f q1)) (Qmult g q2)) h)).
Lemma a_field_equality_3 : forall a b c d e f g h q1 q2 : Q, f <> Zero -> Qmult b h = Qmult d f -> Qmult b g = Qmult c f -> Qmult a f = Qmult b e -> Qplus (Qplus (Qplus (Qmult (Qmult e q1) q2) (Qmult f q1)) (Qmult g q2)) h <> Zero -> Qmult b (Qinv f) = Qmult (Qplus (Qplus (Qplus (Qmult (Qmult a q1) q2) (Qmult b q1)) (Qmult c q2)) d) (Qinv (Qplus (Qplus (Qplus (Qmult (Qmult e q1) q2) (Qmult f q1)) (Qmult g q2)) h)).
Lemma a_field_equality_4 : forall a b c d e f g h q1 q2 : Q, g <> Zero -> Qmult a g = Qmult c e -> Qmult b g = Qmult c f -> Qmult c h = Qmult d g -> Qplus (Qplus (Qplus (Qmult (Qmult e q1) q2) (Qmult f q1)) (Qmult g q2)) h <> Zero -> Qmult c (Qinv g) = Qmult (Qplus (Qplus (Qplus (Qmult (Qmult a q1) q2) (Qmult b q1)) (Qmult c q2)) d) (Qinv (Qplus (Qplus (Qplus (Qmult (Qmult e q1) q2) (Qmult f q1)) (Qmult g q2)) h)).
Lemma a_field_equality_5 : forall a b c d e f g h q1 q2 : Q, h <> Zero -> Qmult b h = Qmult d f -> Qmult a h = Qmult d e -> Qmult c h = Qmult d g -> Qplus (Qplus (Qplus (Qmult (Qmult e q1) q2) (Qmult f q1)) (Qmult g q2)) h <> Zero -> Qmult d (Qinv h) = Qmult (Qplus (Qplus (Qplus (Qmult (Qmult a q1) q2) (Qmult b q1)) (Qmult c q2)) d) (Qinv (Qplus (Qplus (Qplus (Qmult (Qmult e q1) q2) (Qmult f q1)) (Qmult g q2)) h)).
Lemma quadratic_positive_input : forall (a b c d e f g h : Z) (p1 p2 : Qpositive) (H_Qquadratic_sg_denom_nonzero : Qquadratic_sg_denom_nonzero e f g h p1 p2), Qquadratic_Qpositive_to_Q a b c d e f g h p1 p2 H_Qquadratic_sg_denom_nonzero = Qmult (Qplus (Qplus (Qplus (Qmult (Qmult a (Qpos p1)) (Qpos p2)) (Qmult b (Qpos p1))) (Qmult c (Qpos p2))) d) (Qinv (Qplus (Qplus (Qplus (Qmult (Qmult e (Qpos p1)) (Qpos p2)) (Qmult f (Qpos p1))) (Qmult g (Qpos p2))) h)).
Lemma quadratic : forall (a b c d e f g h : Z) (s1 s2 : Q) (H_Qquadratic_denom_nonzero : Qquadratic_denom_nonzero e f g h s1 s2), Qquadratic a b c d e f g h s1 s2 H_Qquadratic_denom_nonzero = spec_q a b c d e f g h s1 s2.
Lemma Qquadratic_denom_nonzero_correct_1 : forall (e f g h : Z) (q1 q2 : Q), Qquadratic_denom_nonzero e f g h q1 q2 -> Qplus (Qplus (Qplus (Qmult (Qmult e q1) q2) (Qmult f q1)) (Qmult g q2)) h <> Zero.
Lemma Qquadratic_denom_nonzero_correct_2 : forall (e f g h : Z) (q1 q2 : Q), Qplus (Qplus (Qplus (Qmult (Qmult e q1) q2) (Qmult f q1)) (Qmult g q2)) h <> Zero -> Qquadratic_denom_nonzero e f g h q1 q2.
Theorem quadratic_algorithm_is_correct : forall (a b c d e f g h : Z) (q1 q2 : Q) (H_denom : Qplus (Qplus (Qplus (Qmult (Qmult e q1) q2) (Qmult f q1)) (Qmult g q2)) h <> Zero), Qquadratic a b c d e f g h q1 q2 (Qquadratic_denom_nonzero_correct_2 e f g h q1 q2 H_denom) = Qmult (Qplus (Qplus (Qplus (Qmult (Qmult a q1) q2) (Qmult b q1)) (Qmult c q2)) d) (Qinv (Qplus (Qplus (Qplus (Qmult (Qmult e q1) q2) (Qmult f q1)) (Qmult g q2)) h)).