(* This program is free software; you can redistribute it and/or      *)
(* modify it under the terms of the GNU Lesser General Public License *)
(* as published by the Free Software Foundation; either version 2.1   *)
(* of the License, or (at your option) any later version.             *)
(*                                                                    *)
(* This program is distributed in the hope that it will be useful,    *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of     *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *)
(* GNU General Public License for more details.                       *)
(*                                                                    *)
(* You should have received a copy of the GNU Lesser General Public   *)
(* License along with this program; if not, write to the Free         *)
(* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *)
(* 02110-1301 USA                                                     *)
Require Export Q_field.
intros n m; case m; case n; auto; intros n' m'; simpl in |- *;
rewrite Qpositive_mult_sym; auto.
Qed.
intros n m p; case p; case m; case n; auto; intros n' m' p'; simpl in |- *;
rewrite Qpositive_mult_assoc; auto.
Qed.
intros n; case n; auto.
Qed.
intros n; case n; simpl in |- *; auto; intros; rewrite Qpositive_mult_One;
auto.
Qed.
intros n; case n; simpl in |- *; auto.
intros n'; Case' (Qpositive_le_dec n' n').
case (Qpositive_eq_dec n' n'); auto.
intros H; elim H; auto.
intros H; elim H; auto.
intros n'; Case' (Qpositive_le_dec n' n').
case (Qpositive_eq_dec n' n'); auto.
intros H; elim H; auto.
intros H; elim H; auto.
Qed.
Definition Q_eq (n m : Q) :=
match n, m with
| Zero, Zero => true
| Qpos n', Qpos m' =>
match Qpositive_eq_dec n' m' with
| left h => true
| right h => false
end
| Qneg n', Qneg m' =>
match Qpositive_eq_dec n' m' with
| left h => true
| right h => false
end
| _, _ => false
end.
intros x y Htrue; generalize Htrue; clear Htrue.
case y; case x; try (intros; simpl in Htrue; discriminate; fail).
(* Focus 1 *)
auto.
(* Focus 2 *)
intros x' y'; simpl in |- *; case (Qpositive_eq_dec x' y').
intros H; rewrite H; auto.
intros; discriminate.
(* Focus 3 *)
intros x' y'; simpl in |- *; case (Qpositive_eq_dec x' y').
intros H; rewrite H; auto.
intros; discriminate.
Qed.
discriminate.
Qed.
Definition Qinv (x : Q) :=
match x with
| Qpos x => Qpos (Qpositive_inv x)
| Qneg x => Qneg (Qpositive_inv x)
| Zero => Zero
end.
intros x; case x.
(* 2 *)
2: intros x' Hneg; simpl in |- *.
2: rewrite Qpositive_mult_inv; auto.
(* 1 *)
intros H; elim H; auto.
(* 3 *)
intros x' Hneg; simpl in |- *.
rewrite Qpositive_mult_inv; auto.
Qed.
intros x y; case y; case x; simpl in |- *; auto; intros x' y' H;
discriminate H.
Qed.
Inductive Qgt : Q -> Q -> Prop :=
| Qgt_pos_pos :
forall x' y' : Qpositive,
~ Qpositive_le x' y' -> Qgt (Qpos x') (Qpos y')
| Qgt_neg_neg :
forall x' y' : Qpositive,
~ Qpositive_le y' x' -> Qgt (Qneg x') (Qneg y')
| Qgt_pos_zero : forall x' : Qpositive, Qgt (Qpos x') Zero
| Qgt_pos_neg : forall x' y' : Qpositive, Qgt (Qpos x') (Qneg y')
| Qgt_zero_neg : forall x' : Qpositive, Qgt Zero (Qneg x').
Hint Resolve Qgt_pos_pos Qgt_neg_neg Qgt_pos_zero Qgt_pos_neg Qgt_zero_neg.
intros x y; case y; case x; auto.
intros x' y'; case (Qpositive_le_dec x' y'); auto with *.
case (Qpositive_eq_dec x' y').
intros e q; right; left; rewrite e; auto.
intros n q; right; right; apply Qgt_pos_pos.
red in |- *; intros H; elim n; apply Qpositive_le_antisym; auto.
intros x' y'; case (Qpositive_le_dec x' y'); auto with *.
case (Qpositive_eq_dec x' y').
intros e q; right; left; rewrite e; auto.
intros n q; left; apply Qgt_neg_neg.
red in |- *; intros H; elim n; apply Qpositive_le_antisym; auto.
Qed.
Definition Q_eq_dec : forall x y : Q, {x = y} + {x <> y}.
intros x y; case x; case y; try (right; discriminate).
(* Focus 1 *)
auto.
(* Focus 2 *)
intros y' x'; case (Qpositive_eq_dec x' y').
intros H; left; rewrite H; auto.
intros H; right; red in |- *; intros H'; elim H.
injection H'; auto.
(* Focus 3 *)
intros y' x'; case (Qpositive_eq_dec x' y').
intros H; left; rewrite H; auto.
intros H; right; red in |- *; intros H'; elim H.
injection H'; auto.
Qed.
intros x y H; elim H.
intros x' y' H1; red in |- *; intros H2; elim H1.
inversion H2.
apply not_Qpositive_le_Qpositive_le'; auto with *.
intros x' y' H1; red in |- *; intros H2; elim H1.
inversion H2; apply not_Qpositive_le_Qpositive_le'; auto.
unfold not in |- *; intros x' H1; inversion H1.
unfold not in |- *; intros x' y' H1; inversion H1.
unfold not in |- *; intros x' H1; inversion H1.
Qed.
intros x y z H; elim H; auto with *.
intros x' y' H1 H2; inversion H2; auto with *.
apply Qgt_pos_pos.
red in |- *; intros H5; elim H3.
apply Qpositive_le_trans with x'; auto with *.
apply not_Qpositive_le_Qpositive_le'.
auto.
intros x' y' H1 H2; inversion H2; auto with *.
apply Qgt_neg_neg.
red in |- *; intros H5; elim H3.
apply Qpositive_le_trans with x'; auto with *.
apply not_Qpositive_le_Qpositive_le'.
auto.
intros x' H1; inversion H1; auto with *.
intros x' y' H1; inversion H1; auto with *.
intros x' H1; inversion H1; auto.
Qed.
intros x y z H; rewrite <- (Qpositive_sub_correct x z).
rewrite <- (Qpositive_sub_correct y z).
apply Qpositive_le_sub_r; auto with *.
rewrite Qpositive_plus_sym; apply sym_not_equal; apply Qpositive_plus_diff.
rewrite Qpositive_plus_sym; apply sym_not_equal; apply Qpositive_plus_diff.
rewrite Qpositive_plus_sym; apply Qpositive_plus_le.
rewrite Qpositive_plus_sym; apply Qpositive_plus_le.
Qed.

Theorem Qpositive_le_sub_simpl_r :
forall x y z : Qpositive,
Qpositive_le z x ->
Qpositive_le z y ->
z <> x ->
z <> y ->
Qpositive_le (Qpositive_sub x z) (Qpositive_sub y z) -> Qpositive_le x y.