Qed.

(* Specifications: *)
Theorem Rle_sign_neg_neg: forall x y, (x <= 0 -> y <= 0  -> 0 <= x * y)%R.
intros x y H1 H2; replace (x * y)%R with (-x * -y)%R; auto with real; try ring.
Theorem Rlt_sign_neg_neg: forall x y, (x < 0 -> y < 0  -> 0 < x * y)%R.
intros x y H1 H2; replace (x * y)%R with (-x * -y)%R; auto with real; try ring.
Theorem Rge_sign_pos_pos: forall x y, (x >= 0 -> y >= 0  -> x * y >= 0)%R.
intros; apply Rle_ge; apply Rle_sign_pos_pos; auto with real.
Theorem Rge_neg_pos: forall x, (0 >= -x -> x >= 0)%R.
intros x H; rewrite <- (Ropp_involutive 0);  rewrite <- (Ropp_involutive x); auto with real.
Theorem Rge_sign_pos_neg: forall x y, (x >= 0 -> 0 >= y  -> 0 >= x * y)%R.
intros; apply Rle_ge; apply Rle_sign_pos_neg; auto with real.
Theorem Rgt_sign_neg_neg: forall x y, (0 > x -> 0 > y  -> x * y > 0)%R.
intros; red;  apply Rlt_sign_neg_neg; auto with real.
Theorem Rgt_sign_pos_pos: forall x y, (x > 0 -> y > 0  -> x * y > 0)%R.
intros; red; apply Rlt_sign_pos_pos; auto with real.
Theorem Rgt_neg_pos: forall x, (0 > -x -> x > 0)%R.
intros x H; rewrite <- (Ropp_involutive 0);  rewrite <- (Ropp_involutive x); auto with real.
Theorem Rgt_sign_pos_neg: forall x y, (x > 0 -> 0 > y  -> 0 > x * y)%R.
intros; red; apply Rlt_sign_pos_neg; auto with real.
Theorem Rge_sign_neg_neg_rev: forall x y: R, (0 > x -> x * y  >= 0->  0 >= y)%R.
intros x y H1 H2; apply Rle_ge; apply Rle_sign_neg_neg_rev with x; auto with real.
Theorem Rge_sign_pos_neg_rev: forall x y: R, (x > 0 -> 0 >= x * y -> 0 >= y)%R.
intros x y H1 H2; apply Rle_ge; apply Rle_sign_pos_neg_rev with x; auto with real.
Theorem Rge_sign_neg_pos_rev: forall x y: R, (0 > x -> 0 >= x * y ->  y >= 0)%R.
intros x y H1 H2; apply Rle_ge; apply Rle_sign_neg_pos_rev with x; auto with real.
Theorem Rlt_sign_pos_pos_rev: forall x y: R, (0 < x -> 0 < x * y -> 0 < y)%R.
intros x y H1 H2; case (Rle_or_lt y 0); auto with real.
Theorem Rgt_sign_neg_neg_rev: forall x y: R, (0 > x -> x * y  > 0->  0 > y)%R.
intros x y H1 H2; red; apply Rlt_sign_neg_neg_rev with x; auto with real.
Theorem Rgt_sign_pos_neg_rev: forall x y: R, (x > 0 -> 0 > x * y -> 0 > y)%R.
intros x y H1 H2; red; apply Rlt_sign_pos_neg_rev with x; auto with real.
Theorem Rgt_sign_neg_pos_rev: forall x y: R, (0 > x -> 0 > x * y ->  y > 0)%R.
intros x y H1 H2; red; apply Rlt_sign_neg_pos_rev with x; auto with real.
Theorem Rmult_lt_neg_compat_l:
forall n m p : R, (m < n)%R -> (p < 0)%R -> (p * n < p * m)%R.
Theorem Rmult_ge_compat_l:
forall n m p : R, (m >= n)%R -> (p >= 0)%R -> (p * m >= p * n)%R.
Theorem Rmult_gt_compat_l:
forall n m p : R, (n > m)%R -> (p > 0)%R -> (p * n > p * m)%R.
Theorem Nlt_lt: forall n  m, (N.to_nat n < N.to_nat m)%nat -> n < m.
intros n m; case n; case m; unfold N.lt; simpl; try (intros; discriminate); auto.
Theorem Nge_ge: forall n  m, (N.to_nat n >= N.to_nat m)%nat -> n >= m.
intros n m; case n; case m; unfold N.ge; simpl; try (intros; discriminate); auto.
Theorem Ngt_gt: forall n  m, (N.to_nat n > N.to_nat m)%nat -> n > m.
intros n m; case n; case m; unfold N.gt; simpl; try (intros; discriminate); auto.
Theorem Neq_eq_rev: forall n  m, n = m -> (N.to_nat n = N.to_nat m)%nat.
intros n m H; rewrite H; auto.
Theorem Ngt_le_trans: forall n m p, n > m -> p <= m -> n > p.
intros; to_nat; apply gt_le_trans with nn1; auto.
Theorem Nle_add_l :
forall x y, x <= y + x.
Theorem Eq_diff_Gt: Eq <> Gt.
intros; discriminate.
Theorem mult_ge_compat_l: forall n m p : nat, n >= m -> p * n >= p * m.
intros n m p H; auto with arith.
Theorem mult_gt_compat_l: forall n m p : nat, n > m -> p > 0 -> p * n > p * m.
intros n m p H H1; red; apply mult_lt_compat_l; auto.
Theorem mult_lt_compat_rev_l1: forall n m p : nat, p * n < p * m -> 0 < p.
intros n m p; case p; auto with arith.
Theorem mult_lt_compat_rev_l2: forall n m p : nat, p * n < p * m -> n < m.
intros n m p H; case (le_or_lt m n); auto with arith; intros H1.
Theorem mult_gt_compat_rev_l2: forall n m p : nat, p * n > p * m -> n > m.
intros n m p H; case (le_or_lt n m); auto with arith; intros H1.
Theorem lt_mult_rev_0_l: forall a b, 0 < a * b ->  0 < a .
intros a b; case a; simpl; auto with arith.
Theorem lt_mult_rev_0_r: forall a b, 0 < a * b ->  0 < b .
intros a b; case b; simpl; auto with arith.
Theorem gt_mult_rev_0_r: forall a b, a * b > 0  ->  b > 0 .
intros a b; case b; simpl; auto with arith.
Theorem Ngt_mult_0: forall a b, a > 0 -> b > 0 -> a * b > 0.
intros a b H1 H2; apply Ngt_gt; rewrite N2Nat.inj_mul; apply gt_mult_0; apply gt_Ngt; repeat rewrite N2Nat.id; auto.
Theorem Nlt_mult_rev_0_l: forall a b, 0 < a * b ->  0 < a .
intros a b H1; apply Nlt_lt; apply lt_mult_rev_0_l with (nat_of_N b).
Theorem plus_neg_compat_l: forall a b c, b <> c -> a + b <> a + c.
intros a b c H H1; case H.
Theorem plus_neg_reg_l: forall a b c,  a + b <> a + c -> b <> c.
intros a b c H H1; case H; subst; auto.
Theorem plus_ge_reg_l: forall n m p : nat, p + n >= p + m -> n >= m.
intros n m p H; unfold ge; apply plus_le_reg_l with p; auto.
(* For replace *)
Theorem eq_lt_trans_l : forall x y z, (x = z) -> (x < y) -> (z < y).
intros x y z H; rewrite H; auto.
Theorem eq_lt_trans_r : forall x y z, (y = z) -> (x < y) -> (x < z).
intros x y z H; rewrite H; auto.
Theorem eq_gt_trans_l : forall x y z, (x = z) -> (x > y) -> (z > y).
intros x y z H; rewrite H; auto.
Theorem eq_gt_trans_r : forall x y z, (y = z) -> (x > y) -> (x > z).
intros x y z H; rewrite H; auto.
Theorem eq_le_trans_l : forall x y z, (x = z) -> (x <= y) -> (z <= y).
intros x y z H; rewrite H; auto.
Theorem eq_le_trans_r : forall x y z, (y = z) -> (x <= y) -> (x <= z).
intros x y z H; rewrite H; auto.
Theorem eq_ge_trans_l : forall x y z, (x = z) -> (x >= y) -> (z >= y).
intros x y z H; rewrite H; auto.
Theorem eq_ge_trans_r : forall x y z, (y = z) -> (x >= y) -> (x >= z).
intros x y z H; rewrite H; auto.
Theorem ge_trans: forall x y z, (x >= z) -> (z >= y) -> (x >= y).
intros x y z H1 H2; red; apply le_trans with z; auto.
Theorem Nplus_neg_compat_l: forall a b c, b <> c -> a + b <> a + c.
intros a b c H1 H2; case H1.
Theorem Nplus_gt_compat_l: forall n m p, n > m -> p + n > p + m.
intros; to_nat; auto with arith.
Theorem Nplus_le_compat_l: forall n m p, n <= m -> p + n <= p + m.
intros; to_nat; auto with arith.
Theorem Nplus_ge_compat_l: forall n m p, n >= m -> p + n >= p + m.
intros; to_nat; auto with arith.
Theorem Nplus_neg_reg_l: forall a b c,  a + b <> a + c -> b <> c.
intros a b c H H1; case H; apply f_equal2 with (f:= Nplus); auto.
Theorem Nplus_lt_reg_l: forall n m p, p + n < p + m -> n < m.
intros; to_nat; apply plus_lt_reg_l with nn1; auto with arith.
Theorem Nplus_gt_reg_l: forall n m p, p + n > p + m -> n > m.
intros; to_nat; apply plus_gt_reg_l with nn1; auto with arith.
Theorem Nplus_le_reg_l: forall n m p, p + n <= p + m -> n <= m.
intros; to_nat; apply plus_le_reg_l with nn1; auto with arith.
Theorem Nplus_ge_reg_l: forall n m p, p + n >= p + m -> n >= m.
intros; to_nat; apply plus_ge_reg_l with nn1; auto with arith.
(* For replace *)
Theorem Neq_lt_trans_l : forall x y z, (x = z) -> (x < y) -> (z < y).
intros; subst; auto.
Theorem Neq_lt_trans_r : forall x y z, (y = z) -> (x < y) -> (x < z).
intros; subst; auto.
Theorem Neq_gt_trans_l : forall x y z, (x = z) -> (x > y) -> (z > y).
intros x y z H; rewrite H; auto.
Theorem Neq_gt_trans_r : forall x y z, (y = z) -> (x > y) -> (x > z).
intros x y z H; rewrite H; auto.
Theorem Neq_le_trans_l : forall x y z, (x = z) -> (x <= y) -> (z <= y).
intros x y z H; rewrite H; auto.
Theorem Neq_le_trans_r : forall x y z, (y = z) -> (x <= y) -> (x <= z).
intros x y z H; rewrite H; auto.
Theorem Neq_ge_trans_l : forall x y z, (x = z) -> (x >= y) -> (z >= y).
intros x y z H; rewrite H; auto.
Theorem Neq_ge_trans_r : forall x y z, (y = z) -> (x >= y) -> (x >= z).
intros x y z H; rewrite H; auto.
Theorem Nge_trans: forall x y z, (x >= z) -> (z >= y) -> (x >= y).
intros; to_nat; red; apply le_trans with nn1; auto with arith.
Theorem Zplus_neg_compat_l: forall a b c: Z, (b <> c -> a + b <> a + c)%Z.
intros a b c H H1; case H.
Theorem Zplus_neg_reg_l: forall a b c: Z,  (a + b <> a + c -> b <> c)%Z.
intros a b c H H1; case H; subst; auto.
Theorem Zplus_ge_reg_l: forall n m p : Z, (p + n >= p + m -> n >= m)%Z.
intros n m p H; apply Z.le_ge; apply Zplus_le_reg_l with p; auto; apply Z.ge_le; auto.
Theorem Zle_sign_neg_neg: forall x y: Z, (x <= 0 -> y <= 0  -> 0 <= x * y)%Z.
intros x y H1 H2; replace (x * y)%Z with (-x * -y)%Z; auto with zarith; ring.
Theorem Zopp_le: forall n m, (m <= n -> -n <= -m)%Z.
auto with zarith.
Theorem Zle_pos_neg: forall x, (0 <= -x -> x <= 0)%Z.
auto with zarith.
Theorem Zle_sign_pos_neg: forall x y: Z, (0 <= x -> y <= 0  -> x * y <= 0)%Z.
intros x y H1 H2; apply Zle_pos_neg; replace (- (x * y))%Z with (x * (- y))%Z; auto with zarith; ring.
Theorem Zle_sign_neg_pos: forall x y: Z, (x <= 0 -> 0 <= y  -> x * y <= 0)%Z.
intros x y H1 H2; apply Zle_pos_neg; replace (- (x * y))%Z with (-x * y)%Z; auto with zarith; ring.
Theorem Zlt_sign_pos_pos: forall x y: Z, (0 < x -> 0 < y  -> 0 < x * y)%Z.
intros; apply Zmult_lt_O_compat; auto with zarith.
Theorem Zlt_sign_neg_neg: forall x y: Z, (x < 0 -> y < 0  -> 0 < x * y)%Z.
intros x y H1 H2; replace (x * y)%Z with (-x * -y)%Z; auto with zarith; try ring.
Theorem Zlt_sign_pos_neg: forall x y: Z, (0 < x -> y < 0  -> x * y < 0)%Z.
intros x y H1 H2; apply Zlt_pos_neg; replace (- (x * y))%Z with (x * (- y))%Z; auto with zarith; try ring.
Theorem Zge_sign_pos_pos: forall x y: Z, (x >= 0 -> y >= 0  -> x * y >= 0)%Z.
intros; apply Z.le_ge; apply Zle_sign_pos_pos; auto with zarith.
Theorem Zge_neg_pos: forall x, (0 >= -x -> x >= 0)%Z.
auto with zarith.
Theorem Zge_sign_neg_pos: forall x y: Z, (0 >= x -> y >= 0  -> 0>= x * y)%Z.
intros; apply Z.le_ge; apply Zle_sign_neg_pos; auto with zarith.
Theorem Zge_sign_pos_neg: forall x y: Z, (x >= 0 -> 0 >= y  -> 0 >= x * y)%Z.
intros; apply Z.le_ge; apply Zle_sign_pos_neg; auto with zarith.
Theorem Zgt_sign_neg_neg: forall x y: Z, (0 > x -> 0 > y  -> x * y > 0)%Z.
intros; apply Z.lt_gt; apply Zlt_sign_neg_neg; auto with zarith.
Theorem Zgt_sign_pos_pos: forall x y: Z, (x > 0 -> y > 0  -> x * y > 0)%Z.
intros; apply Z.lt_gt; apply Zlt_sign_pos_pos; auto with zarith.
Theorem Zgt_neg_pos: forall x, (0 > -x -> x > 0)%Z.
auto with zarith.
Theorem Zgt_sign_neg_pos: forall x y: Z, (0 > x -> y > 0  -> 0> x * y)%Z.
intros; apply Z.lt_gt; apply Zlt_sign_neg_pos; auto with zarith.
Theorem Zgt_sign_pos_neg: forall x y: Z, (x > 0 -> 0 > y  -> 0 > x * y)%Z.
intros; apply Z.lt_gt; apply Zlt_sign_pos_neg; auto with zarith.
Theorem Zge_sign_neg_neg_rev: forall x y: Z, (0 > x -> x * y  >= 0->  0 >= y)%Z.
intros x y H1 H2; apply Z.le_ge; apply Zle_sign_neg_neg_rev with x; auto with zarith.
Theorem Zge_sign_pos_neg_rev: forall x y: Z, (x > 0 -> 0 >= x * y -> 0 >= y)%Z.
intros x y H1 H2; apply Z.le_ge; apply Zle_sign_pos_neg_rev with x; auto with zarith.
Theorem Zge_sign_neg_pos_rev: forall x y: Z, (0 > x -> 0 >= x * y ->  y >= 0)%Z.
intros x y H1 H2; apply Z.le_ge; apply Zle_sign_neg_pos_rev with x; auto with zarith.
Theorem Zlt_sign_pos_pos_rev: forall x y: Z, (0 < x -> 0 < x * y -> 0 < y)%Z.
intros x y H1 H2; case (Zle_or_lt y 0); auto with zarith.
Theorem Zgt_sign_neg_neg_rev: forall x y: Z, (0 > x -> x * y  > 0->  0 > y)%Z.
intros x y H1 H2; apply Z.lt_gt; apply Zlt_sign_neg_neg_rev with x; auto with zarith.
Theorem Zgt_sign_pos_neg_rev: forall x y: Z, (x > 0 -> 0 > x * y -> 0 > y)%Z.
intros x y H1 H2; apply Z.lt_gt; apply Zlt_sign_pos_neg_rev with x; auto with zarith.
Theorem Zgt_sign_neg_pos_rev: forall x y: Z, (0 > x -> 0 > x * y ->  y > 0)%Z.
intros x y H1 H2; apply Z.lt_gt; apply Zlt_sign_neg_pos_rev with x; auto with zarith.
Theorem Zmult_lt_neg_compat_l:
forall n m p : Z, (m < n)%Z -> (p < 0)%Z -> (p * n < p * m)%Z.
Theorem Zmult_ge_neg_compat_l:
forall n m p : Z, (m >= n)%Z -> (0 >= p)%Z -> (p * n >= p * m)%Z.
Theorem Zmult_gt_neg_compat_l:
forall n m p : Z, (m > n)%Z -> (0 > p)%Z -> (p * n > p * m)%Z.
Theorem eq_Zlt_trans_r : forall x y z, (y = z) -> (x < y) -> (x < z).
intros x y z H; rewrite H; auto.
Theorem eq_Zgt_trans_l : forall x y z, (x = z) -> (x > y) -> (z > y).
intros x y z H; rewrite H; auto.
Theorem eq_Zgt_trans_r : forall x y z, (y = z) -> (x > y) -> (x > z).
intros x y z H; rewrite H; auto.
Theorem eq_Zle_trans_l : forall x y z, (x = z) -> (x <= y) -> (z <= y).
intros x y z H; rewrite H; auto.
Theorem eq_Zle_trans_r : forall x y z, (y = z) -> (x <= y) -> (x <= z).
intros x y z H; rewrite H; auto.
Theorem eq_Zge_trans_l : forall x y z, (x = z) -> (x >= y) -> (z >= y).
intros x y z H; rewrite H; auto.
Theorem eq_Zge_trans_r : forall x y z, (y = z) -> (x >= y) -> (x >= z).
intros x y z H; rewrite H; auto.
Theorem Zge_trans: forall x y z, (x >= z) -> (z >= y) -> (x >= y).
intros x y z H1 H2; red; apply Zge_trans with z; auto.
Theorem Rplus_neg_compat_l: forall a b c: R, (b <> c -> a + b <> a + c)%R.
intros a b c H H1; case H.
Theorem Rplus_neg_reg_l: forall a b c: R,  (a + b <> a + c -> b <> c)%R.
intros a b c H H1; case H; subst; auto.
Theorem Rplus_ge_reg_l: forall n m p : R, (p + n >= p + m -> n >= m)%R.
intros n m p H; apply Rle_ge; apply Rplus_le_reg_l with p; auto; apply Rge_le; auto.
Theorem Rle_sign_neg_neg: forall x y, (x <= 0 -> y <= 0  -> 0 <= x * y)%R.
intros x y H1 H2; replace (x * y)%R with (-x * -y)%R; auto with real; try ring.
Theorem Rlt_sign_neg_neg: forall x y, (x < 0 -> y < 0  -> 0 < x * y)%R.
intros x y H1 H2; replace (x * y)%R with (-x * -y)%R; auto with real; try ring.
Theorem Rge_sign_pos_pos: forall x y, (x >= 0 -> y >= 0  -> x * y >= 0)%R.
intros; apply Rle_ge; apply Rle_sign_pos_pos; auto with real.
Theorem Rge_neg_pos: forall x, (0 >= -x -> x >= 0)%R.
intros x H; rewrite <- (Ropp_involutive 0);  rewrite <- (Ropp_involutive x); auto with real.
Theorem Rge_sign_pos_neg: forall x y, (x >= 0 -> 0 >= y  -> 0 >= x * y)%R.
intros; apply Rle_ge; apply Rle_sign_pos_neg; auto with real.
Theorem Rgt_sign_neg_neg: forall x y, (0 > x -> 0 > y  -> x * y > 0)%R.
intros; red;  apply Rlt_sign_neg_neg; auto with real.
Theorem Rgt_sign_pos_pos: forall x y, (x > 0 -> y > 0  -> x * y > 0)%R.
intros; red; apply Rlt_sign_pos_pos; auto with real.
Theorem Rgt_neg_pos: forall x, (0 > -x -> x > 0)%R.
intros x H; rewrite <- (Ropp_involutive 0);  rewrite <- (Ropp_involutive x); auto with real.
Theorem Rgt_sign_pos_neg: forall x y, (x > 0 -> 0 > y  -> 0 > x * y)%R.
intros; red; apply Rlt_sign_pos_neg; auto with real.
Theorem Rge_sign_neg_neg_rev: forall x y: R, (0 > x -> x * y  >= 0->  0 >= y)%R.
intros x y H1 H2; apply Rle_ge; apply Rle_sign_neg_neg_rev with x; auto with real.
Theorem Rge_sign_pos_neg_rev: forall x y: R, (x > 0 -> 0 >= x * y -> 0 >= y)%R.
intros x y H1 H2; apply Rle_ge; apply Rle_sign_pos_neg_rev with x; auto with real.
Theorem Rge_sign_neg_pos_rev: forall x y: R, (0 > x -> 0 >= x * y ->  y >= 0)%R.
intros x y H1 H2; apply Rle_ge; apply Rle_sign_neg_pos_rev with x; auto with real.
Theorem Rlt_sign_pos_pos_rev: forall x y: R, (0 < x -> 0 < x * y -> 0 < y)%R.
intros x y H1 H2; case (Rle_or_lt y 0); auto with real.
Theorem Rgt_sign_neg_neg_rev: forall x y: R, (0 > x -> x * y  > 0->  0 > y)%R.
intros x y H1 H2; red; apply Rlt_sign_neg_neg_rev with x; auto with real.
Theorem Rgt_sign_pos_neg_rev: forall x y: R, (x > 0 -> 0 > x * y -> 0 > y)%R.
intros x y H1 H2; red; apply Rlt_sign_pos_neg_rev with x; auto with real.
Theorem Rgt_sign_neg_pos_rev: forall x y: R, (0 > x -> 0 > x * y ->  y > 0)%R.
intros x y H1 H2; red; apply Rlt_sign_neg_pos_rev with x; auto with real.
Theorem Rmult_lt_neg_compat_l:
forall n m p : R, (m < n)%R -> (p < 0)%R -> (p * n < p * m)%R.
Theorem Rmult_ge_compat_l:
forall n m p : R, (m >= n)%R -> (p >= 0)%R -> (p * m >= p * n)%R.
Theorem Rmult_gt_compat_l:
forall n m p : R, (n > m)%R -> (p > 0)%R -> (p * n > p * m)%R.
Theorem eq_Rlt_trans_r : forall x y z, (y = z) -> (x < y) -> (x < z).
intros x y z H; rewrite H; auto.
Theorem eq_Rgt_trans_l : forall x y z, (x = z) -> (x > y) -> (z > y).
intros x y z H; rewrite H; auto.
Theorem eq_Rgt_trans_r : forall x y z, (y = z) -> (x > y) -> (x > z).
intros x y z H; rewrite H; auto.
Theorem eq_Rle_trans_l : forall x y z, (x = z) -> (x <= y) -> (z <= y).
intros x y z H; rewrite H; auto.
Theorem eq_Rle_trans_r : forall x y z, (y = z) -> (x <= y) -> (x <= z).
intros x y z H; rewrite H; auto.
Theorem eq_Rge_trans_l : forall x y z, (x = z) -> (x >= y) -> (z >= y).
intros x y z H; rewrite H; auto.
Theorem eq_Rge_trans_r : forall x y z, (y = z) -> (x >= y) -> (x >= z).
intros x y z H; rewrite H; auto.
Theorem Rge_trans: forall x y z, (x >= z) -> (z >= y) -> (x >= y).
intros x y z H1 H2; red; apply Rge_trans with z; auto.
Theorem Z2R_lt: forall p q, (p < q)%Z -> (Z2R p < Z2R q)%R.
intros p q; repeat rewrite Z2R_correct; intros; apply IZR_lt; auto.
Theorem Z2R_ge: forall p q, (p >= q)%Z -> (Z2R p >= Z2R q)%R.
intros p q; repeat rewrite Z2R_correct; intros; apply IZR_ge; auto.
Theorem Z2R_gt: forall p q, (p > q)%Z -> (Z2R p > Z2R q)%R.
intros p q; repeat rewrite Z2R_correct; intros; red; apply IZR_lt;
apply Z.gt_lt; auto.