(* $Id: QArith.v,v 1.3 2000/11/01 15:54:55 milad Exp $ *)

Require Export Arith.
Require Export ZArith.
Require Export Peano_dec.
Require Export ZArithRing.

(* Summary:

 Definition of Q -set of rationals- as pair of <p,n> with p:Z and n:nat.
 This file contains minimum arithmetics needed to prove that Q is CRing.

*)



Coercion inject_nat: nat>->Z.

Record Q : Set := 
{
numerator: Z;
denominator: nat
}.


Definition EqQ := [p,q :Q] (eq Z 
          (Zmult (numerator p) (Zplus (denominator q) `1`))
          (Zmult (numerator q) (Zplus (denominator p) `1`))). 



Theorem refl_equalQ :(x:Q) (EqQ x x).
Intro.
Unfold EqQ.
Trivial.
Qed.




Theorem sym_equalQ: (x,y:Q)((EqQ x y)->(EqQ y x)). 
Intros.
Unfold EqQ.
Unfold EqQ in H.
Apply (sym_eq Z).
Assumption.
Qed.


Lemma Zlt_reg_mult_l: (x,y,z:Z)`x>0`->`y<z`->`x*y < x*z`.
Intros.
Case (SUPERIEUR_POS x `0`).
Unfold Zgt in H.
Assumption.
Intros.
Cut (`x = (POS x0)`). 
Intro.
Rewrite H2.
Unfold Zlt in H0.
Unfold Zlt.
Cut ( (Zcompare `(POS x0)*y` `(POS x0)*z`) = (Zcompare y z)).
Intro.
Exact (trans_eq relation `(POS x0)*y ?= (POS x0)*z` `y ?= z`  INFERIEUR 
 H3 H0).
Apply Zcompare_Zmult_compatible.
Cut (`x = x + (Zopp 0)`).
Intro.
Exact ( trans_eq Z x `x+(Zopp 0)` (POS x0) H2 H1).
Simpl.
Apply (sym_eq Z).
Exact (Zero_right x).
Qed.


Lemma Zlt_opp: (x,y:Z)`x<y`->`(-x)>(-y)`.
Intros.
Red.
Apply sym_eq.
Cut(SUPERIEUR =(Zcompare y x)).
Intro.
Cut ((Zcompare y x)=(Zcompare (Zopp x) (Zopp y))).
Intro.
Exact (trans_eq relation SUPERIEUR (Zcompare y x) (Zcompare (Zopp x)
     (Zopp y)) H0 H1). 
Exact (Zcompare_Zopp y x).
Apply sym_eq.
Exact (Zlt_gt x y H).
Qed.


Lemma Zlt_conv_mult_l :(x,y,z:Z)`x<0`->`y<z`->`x*y>x*z`.
Intros.
Cut (`(-x)>0`).
Intro.
Cut (`(-x)*y<(-x)*z`).
Intro.
Cut (`(-((-x)*y))>(-((-x)*z))`).
Intro.
Cut (`(-(-(x*y)))>(-(-(x*z)))`).
Intro.
Cut (`(-(-(x*y)))=x*y`).
Intro.
Rewrite H5 in H4.
Cut (`(-(-(x*z)))=x*z`).
Intro.
Rewrite H6 in H4.
Assumption.
Exact (Zopp_Zopp (`x*z`)).
Exact (Zopp_Zopp (`x*y`)).
Cut (`(-((-x)*y))=(-(-(x*y)))`).
Intro.
Rewrite H4 in H3.
Cut (`(-((-x)*z))=(-(-(x*z)))`). 
Intro.
Rewrite H5 in H3.
Assumption.
Cut (`(-x)*z=(-(x*z))`).
Intro.
Exact (f_equal Z Z Zopp `(-x)*z` `(-(x*z))` H5).
Exact (Zopp_Zmult x z).
Cut (`(-x)*y=(-(x*y))`).
Intro.
Exact (f_equal Z Z Zopp `(-x)*y` `(-(x*y))` H4).
Exact (Zopp_Zmult x y).
Exact (Zlt_opp `(-x)*y` `(-x)*z` H2).
Exact (Zlt_reg_mult_l `(-x)` y z H1 H0).
Exact (Zlt_opp x `0` H).
Qed.

Lemma Zgt_not_eq :(x,y:Z)`x>y`->(~(x=y)).
Intros.
Cut (`y<x`).
Intro.
Cut (`y<>x`).
Intro.
Red.
Intros.
Cut (`y=x`).
Intros.
Apply H1.
Assumption.
Exact (sym_eq Z x y H2).
Exact (Zlt_not_eq y x H0).
Exact (Zgt_lt x y H).
Qed.

Lemma Zmult_absorb : (x,y,z: Z)~(x=ZERO)->(Zmult x y)=(Zmult x z)->y=z.
Intros.
Case (dec_eq y z).
Intro.
Assumption.
Intro.
Case (not_Zeq y z).
Assumption.
Intro.
Case (not_Zeq x `0`).
Assumption.
Intro.
Apply False_ind.
Cut (`x*y>x*z`).
Intro.
Cut (`x*y <> x*z`).
Intro.
Apply H5.
Assumption.
Exact (Zgt_not_eq `x*y` `x*z` H4 ).
Exact (Zlt_conv_mult_l x y z H3 H2).
Intro.
Apply False_ind.
Cut (`x*y<x*z`).
Intro.
Cut(`x*y<>x*z`).
Intro.
Apply H5.
Assumption.
Exact (Zlt_not_eq `x*y` `x*z` H4).
Cut (`x>0`).
Intro.
Exact (Zlt_reg_mult_l x y z H4 H2).
Exact (Zlt_gt `0` x H3).
Intro.
Apply False_ind.
Cut(`x*z<x*y`).
Intro.
Cut(`x*z<>x*y`).
Intro.
Apply H4.
Apply (sym_eq Z).
Assumption.
Exact (Zlt_not_eq `x*z` `x*y` H3).
Apply False_ind.
Case (not_Zeq x `0`).
Assumption.
Intro.
Cut(`x*z>x*y`).
Intro.
Cut (`x*z<>x*y`).
Intro.
Apply H5.
Apply (sym_eq Z).
Assumption.
Exact (Zgt_not_eq `x*z` `x*y` H4).
Exact (Zlt_conv_mult_l x z y H3 H2).
Intro.
Cut(`x*z<x*y`).
Intro.
Cut (`x*z<>x*y`).
Intro.
Apply H5.
Apply (sym_eq Z).
Assumption.
Exact (Zlt_not_eq `x*z` `x*y` H4).
Cut (`x>0`).
Intro.
Exact (Zlt_reg_mult_l x z y H4 H2).
Exact (Zlt_gt `0` x H3).
Qed.

Lemma strange :(a,b,c,d,e,f:Z)`c<>0`->`a*b=c*d`->`c*e=f*b`->`a*e=f*d`.
Intros.
Cut (`a*(c*e)=a*(f*b)`).
Intro.
Cut (`f*(a*b)=f*(c*d)`).
Intro.
Cut (`a*(f*b)=f*(a*b)`).
Intro.
Cut (`a*(c*e)=f*(a*b)`).
Intro.
Cut (`a*(c*e)=f*(c*d)`).
Intro.
Cut (`a*(c*e)=c*(a*e)`).
Intro.
Cut (`f*(c*d)=c*(f*d)`).
Intro.
Cut (`c*(a*e)=a*(c*e)`).
Intro.
Cut (`c*(a*e)=f*(c*d)`).
Intro.
Cut (`c*(a*e)=c*(f*d)`).
Intro.
Exact (Zmult_absorb c `a*e` `f*d` H H11).
Cut (`f*(c*d)=c*(f*d)`).
Intro.
Exact (trans_eq Z `c*(a*e)` `f*(c*d)` `c*(f*d)` H10 H11).
Exact (Zmult_permute f c d).
Exact (trans_eq Z `c*(a*e)` `a*(c*e)` `f*(c*d)` H9 H6).
Exact (Zmult_permute c a e).
Exact (Zmult_permute f c d).
Exact (Zmult_permute a c e).
Exact (trans_eq Z `a*(c*e)` `f*(a*b)` `f*(c*d)` H5 H3).
Exact (trans_eq Z `a*(c*e)` `a*(f*b)` `f*(a*b)` H2 H4).
Exact (Zmult_permute a f b).
Cut (`f=f`).
Intro.
Exact (f_equal2 Z Z Z Zmult f f `a*b` `c*d` H3 H0). 
Trivial.
Cut (`a=a`).
Intro.
Exact (f_equal2 Z Z Z Zmult a a `c*e` `f*b` H2 H1).
Trivial.
Qed.


Theorem trans_equalQ : (x,y,z:Q)(EqQ x y)->(EqQ y z)->(EqQ x z).
Red.
Unfold EqQ.
Intros.
Case (dec_eq (numerator y) `0`).
Intro.
Cut (`(numerator x)=0`).
Intro.
Rewrite H2.
Cut (`(numerator z)=0`).
Intro.
Rewrite H3.
Simpl.
Trivial.
Rewrite H1 in H0.
Cut (`((inject_nat (denominator y))+1)<>0`).
Intro.
Cut (`(numerator z)*((inject_nat (denominator y))+1)=0`).
Intro.
Exact (Zmult_eq `(inject_nat (denominator y))+1` (numerator z) H3 H4).
Apply sym_eq.
Cut (`0=0*((inject_nat (denominator z))+1)`).
Intro.
Apply (trans_eq Z `0` `0*((inject_nat (denominator z))+1)` 
`(numerator z)*((inject_nat (denominator y))+1)` H4 H0).
Apply sym_eq.
Simpl.
Trivial.
Cut ( `0 <= (inject_nat (denominator y))`).
Intro.
Cut (`0 < (inject_nat (denominator y))+1`).
Intro.
Apply Zgt_not_eq.
Apply Zlt_gt.
Assumption.
Cut (`0 < (Zs (inject_nat (denominator y)))`).
Unfold Zs.
Intro.
Assumption.
Exact (Zle_lt_n_Sm `0` `(inject_nat (denominator y))` H3).
Case (denominator y).
Simpl.
Exact (Zle_n `0`).
Simpl.
Intro.
Exact (ZERO_le_POS (anti_convert n)).
Rewrite H1 in H.
Cut (`((inject_nat (denominator y))+1)<>0`).
Intro.
Cut (`(numerator x)*((inject_nat (denominator y))+1)=0`).
Intro.
Exact (Zmult_eq `(inject_nat (denominator y))+1` (numerator x) H2 H3).
Cut (`0* ((inject_nat (denominator x))+1)=0`).
Intro.
Exact (trans_eq Z `(numerator x)*((inject_nat (denominator y))+1)` 
`0*((inject_nat (denominator x))+1)` `0` H H3).
Simpl.
Trivial.
Cut ( `0 <= (inject_nat (denominator y))`).
Intro.
Cut (`0 < (inject_nat (denominator y))+1`).
Intro.
Apply Zgt_not_eq. 
Apply Zlt_gt.
Assumption.
Cut (`0 < (Zs (inject_nat (denominator y)))`).
Unfold Zs.
Intro.
Assumption.
Exact (Zle_lt_n_Sm `0` `(inject_nat (denominator y))` H2).
Case (denominator y).
Simpl.
Exact (Zle_n `0`).
Simpl.
Intro.
Exact (ZERO_le_POS (anti_convert n)).
Intro.
Exact (strange (numerator x) `(inject_nat (denominator y))+1` (numerator y)
`(inject_nat (denominator x))+1` `(inject_nat (denominator z))+1`
(numerator z) H1 H H0).
Qed.

Theorem dec_EqQ : (x,y :Q)(decidable (EqQ x y)).
Intros.
Red.
Unfold EqQ.
Case (dec_eq `(numerator x)*((inject_nat (denominator y))+1)` `(numerator y)*
    ((inject_nat (denominator x))+1)`).
Intro.
Left.
Assumption.
Intro.
Right.
Assumption.
Qed.



  (* CONSTANTS *)
Definition ZEROQ := (!Build_Q `0` (0)). 
Definition ONEQ := (!Build_Q `1` (0)).
(* Definition nim:= (!Build_Q `1` (1)).
   Definition nesf := (!Build_Q `2` (3)). *)

Definition Qplus:=[x,y:Q] (!Build_Q 
  `((numerator x)*((inject_nat (denominator y))+1))+
   ((numerator y)*((inject_nat (denominator x))+1))`
   (plus (mult (denominator x) (denominator y))
    (plus (denominator x) (denominator y)) )
    ).

Definition Qmult:=[x,y:Q] (!Build_Q `(numerator x)*(numerator y)`
                           (plus (mult (denominator x) (denominator y)) 
                              (plus (denominator x) (denominator y)))).

Definition Qopp:=[x:Q](!Build_Q `(-(numerator x))` (denominator x)).

Definition inject_Z:= [x:Z](!Build_Q x (0)). 

Coercion inject_Z : Z>->Q.

(* Here we start to use Ring tactic *)



Lemma astonishing:(a,b,c,d,s,r,t,u:Z)`a*r=b*s`->`c*u=d*t`->
                                     `(a*t+c*s)*(r*u)=(b*u+d*r)*(s*t)`.
Intros.
Ring `(a*t+c*s)*(r*u)`.
Ring `(b*u+d*r)*(s*t)`.
Apply (f_equal2 Z Z Z Zplus `u*(r*(c*s))` `t*(s*(d*r))` 
                            `u*(r*(t*a))` `t*(s*(u*b))`).

Rewrite Zmult_permute with n:=r m:=c p:=s.
Rewrite Zmult_assoc with x:=u y:=c z:=`r*s`.
Rewrite Zmult_permute with n:=s m:=d p:=r.
Rewrite Zmult_assoc with x:=t y:=d z:=`s*r`.              
Rewrite Zmult_sym with x:=u y:=c.
Rewrite Zmult_sym with x:=t y:=d.
Rewrite Zmult_sym with x:=s y:=r.
Apply (f_equal2 Z Z Z Zmult `c*u` `d*t` `r*s` `r*s`).
Assumption.
Reflexivity.
Rewrite Zmult_permute with n:=r m:=t p:=a.
Rewrite Zmult_assoc with x:=u y:=t z:=`r*a`.
Rewrite Zmult_permute with n:=s m:=u p:=b.
Rewrite Zmult_assoc with x:=t y:=u z:=`s*b`.              
Rewrite Zmult_sym with x:=r y:=a.
Rewrite Zmult_sym with x:=t y:=u.
Rewrite Zmult_sym with x:=s y:=b.
Apply (f_equal2 Z Z Z Zmult `u*t` `u*t` `a*r` `b*s`).
Reflexivity.
Assumption.
Qed.

Lemma ghahti:(a,b,c,d:Z;s,r,t,u:nat)`a*(r+1)=b*(s+1)`->`c*(u+1)=d*(t+1)`->
             `(a*(t+1)+c*(s+1))*((plus (mult r u) (plus r u))+1)
             =(b*(u+1)+d*(r+1))*((plus (mult s t) (plus s t))+1)`.
Intros a b c d s r t u.
Intros.
Cut (`(a*((inject_nat t)+1)+c*((inject_nat s)+1))*
    (((mult r u)+(plus r u))+1) = (b*((inject_nat u)+
    1)+d*((inject_nat r)+1))*(((mult s t)+(plus s t))+
    1)`).
Intro.
Cut (`(a*((inject_nat t)+1)+c*((inject_nat s)+1))*
   ((inject_nat (plus (mult r u) (plus r u)))+1)=
    (a*((inject_nat t)+1)+c*((inject_nat s)+1))*
    ((inject_nat (mult r u))+(inject_nat (plus r u))+1)`).
Intro.
Cut (`(b*((inject_nat u)+1)+d*((inject_nat r)+1))*
      ((inject_nat (mult s t))+(inject_nat (plus s t))+1)=
      (b*((inject_nat u)+ 1)+d*((inject_nat r)+1))*
      ((inject_nat (plus (mult s t) (plus s t)))+1)`).
Intro.
Cut (`(a*((inject_nat t)+1)+c*((inject_nat s)+1))*
       ((inject_nat (plus (mult r u) (plus r u)))+1)=
      (b*((inject_nat u)+1)+d*((inject_nat r)+1))*
       ((inject_nat (mult s t))+(inject_nat (plus s t))+1)`).
Intro.
Exact (trans_eq Z
                `(a*((inject_nat t)+1)+c*((inject_nat s)+1))*
                 ((inject_nat (plus (mult r u) (plus r u)))+1)`
                 `(b*((inject_nat u)+1)+d*((inject_nat r)+1))*
                  ( (inject_nat (mult s t)) + (inject_nat (plus s t)) +1 )`    
                 `(b*((inject_nat u)+ 1)+d*((inject_nat r)+1))*
                 ((inject_nat (plus (mult s t) (plus s t)))+1)` H4 H3).
Exact (trans_eq Z 
                `(a*((inject_nat t)+1)+c*((inject_nat s)+1))*
                 ((inject_nat (plus (mult r u) (plus r u)))+1)`
                `(a*((inject_nat t)+1)+c*((inject_nat s)+1))*
                ((inject_nat (mult r u))+(inject_nat (plus r u))+1)`
                `(b*((inject_nat u)+1)+d*((inject_nat r)+1))*
                ((inject_nat (mult s t))+(inject_nat (plus s t))+1)` H2 H1).
Cut (`(b*((inject_nat u)+1)+d*((inject_nat r)+1))=
      (b*((inject_nat u)+1)+d*((inject_nat r)+1))`).
Intro.
Cut (`(inject_nat (mult s t))+(inject_nat (plus s t))+1=
      (inject_nat (plus (mult s t) (plus s t)))+1`).
Intro.
Exact (f_equal2 Z Z Z Zmult 
                 `(b*((inject_nat u)+1)+d*((inject_nat r)+1))`
                 `(b*((inject_nat u)+1)+d*((inject_nat r)+1))`
                 `(inject_nat (mult s t))+(inject_nat (plus s t))+1`
                 `(inject_nat (plus (mult s t) (plus s t)))+1` H3 H4). 
Apply Zeq_S with n:=`(inject_nat (mult s t))+(inject_nat (plus s t))` 
                 m:=(inject_nat (plus (mult s t) (plus s t))).
Apply sym_eq.
Exact (inj_plus (mult s t) (plus s t)).  
Trivial.
Cut (`a*((inject_nat t)+1)+c*((inject_nat s)+1)=
      a*((inject_nat t)+1)+c*((inject_nat s)+1)`).
Intro.
Cut (`(inject_nat (plus (mult r u) (plus r u)))+1=
      (inject_nat (mult r u))+(inject_nat (plus r u))+1`).
Intro.
Exact(f_equal2 Z Z Z Zmult 
        `a*((inject_nat t)+1)+c*((inject_nat s)+1)`
        `a*((inject_nat t)+1)+c*((inject_nat s)+1)`      
        `(inject_nat (plus (mult r u) (plus r u)))+1`
        `(inject_nat (mult r u))+(inject_nat (plus r u))+1` H2 H3).
Apply Zeq_S with n:=(inject_nat (plus (mult r u) (plus r u)))
                 m:=`(inject_nat (mult r u))+(inject_nat (plus r u))`. 
Exact (inj_plus (mult r u) (plus r u)). 
Trivial.
Cut (`(a*((inject_nat t)+1)+c*((inject_nat s)+1))*
      (((inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u)))+1)= 
      (b*((inject_nat u)+1)+d*((inject_nat r)+1))*
      (((inject_nat s)*(inject_nat t)+((inject_nat s)+(inject_nat t)))+1)`).
Intro.
Cut (`(a*((inject_nat t)+1)+c*((inject_nat s)+1))*
   ((inject_nat (mult r u))+(inject_nat (plus r u))+1)=
   (a*((inject_nat t)+1)+c*((inject_nat s)+1))*((inject_nat r)*
       (inject_nat u)+((inject_nat r)+(inject_nat u))+1)`).
Intro.
Cut (` (b*((inject_nat u)+1)+d*((inject_nat r)+1))*
       ((inject_nat s)*(inject_nat t)+((inject_nat s)+(inject_nat t))+1)=
       (b*((inject_nat u)+1)+d*((inject_nat r)+1))*
       ((inject_nat (mult s t))+(inject_nat (plus s t))+1)`).
Intro.
Cut (`(a*((inject_nat t)+1)+c*((inject_nat s)+1))*
      ((inject_nat (mult r u))+(inject_nat (plus r u))+1)=
      (b*((inject_nat u)+1)+d*((inject_nat r)+1))*((inject_nat s)*
       (inject_nat t)+((inject_nat s)+(inject_nat t))+1)`).
Intro.
Exact (trans_eq Z                
                 `(a*((inject_nat t)+1)+c*((inject_nat s)+1))*
                 ((inject_nat (mult r u))+(inject_nat (plus r u))+1)`
                 `(b*((inject_nat u)+1)+d*((inject_nat r)+1))*
        ((inject_nat s)*(inject_nat t)+((inject_nat s)+(inject_nat t))+1)`
                 `(b*((inject_nat u)+1)+d*((inject_nat r)+1))*
                 ((inject_nat (mult s t))+(inject_nat (plus s t))+1)` H4 H3).
Exact (trans_eq Z
                `(a*((inject_nat t)+1)+c*((inject_nat s)+1))*
                ((inject_nat (mult r u))+(inject_nat (plus r u))+1)` 
                `(a*((inject_nat t)+1)+c*((inject_nat s)+1))*((inject_nat r)*
                (inject_nat u)+((inject_nat r)+(inject_nat u))+1)`
                `(b*((inject_nat u)+1)+d*((inject_nat r)+1))*((inject_nat s)*
                (inject_nat t)+((inject_nat s)+(inject_nat t))+1)` H2 H1).
Cut ( `b*((inject_nat u)+1)+d*((inject_nat r)+1)=
       b*((inject_nat u)+1)+d*((inject_nat r)+1)`).
Intro.
Cut (`(inject_nat s)*(inject_nat t)+((inject_nat s)+(inject_nat t))+1=
      (inject_nat (mult s t))+(inject_nat (plus s t))+1`).
Intro.
Apply (f_equal2 Z Z Z Zmult 
                   `b*((inject_nat u)+1)+d*((inject_nat r)+1)`
                   `b*((inject_nat u)+1)+d*((inject_nat r)+1)`
       `(inject_nat s)*(inject_nat t)+((inject_nat s)+(inject_nat t))+1`
       `(inject_nat (mult s t))+(inject_nat (plus s t))+1` H3 H4).            
Apply Zeq_S with 
            n:=`(inject_nat s)*(inject_nat t)+((inject_nat s)+(inject_nat t))`
            m:=`(inject_nat (mult s t))+(inject_nat (plus s t))`.
Cut (`(inject_nat s)*(inject_nat t)= (inject_nat (mult s t))`).
Intro.
Cut (`((inject_nat s)+(inject_nat t))=(inject_nat (plus s t))`).
Intro.
Exact (f_equal2 Z Z Z Zplus
          `(inject_nat s)*(inject_nat t)`
           (inject_nat (mult s t))
          `(inject_nat s)+(inject_nat t)` 
           (inject_nat (plus s t)) H4 H5). 
Apply sym_eq.
Exact (inj_plus s t).
Apply sym_eq.
Exact (inj_mult s t). 
Trivial.
Cut ( `a*((inject_nat t)+1)+c*((inject_nat s)+1)=
       a*((inject_nat t)+1)+c*((inject_nat s)+1)`).
Intro.
Cut (`(inject_nat (mult r u))+(inject_nat (plus r u))+1=
      (inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))+1`).
Intro.
Apply (f_equal2 Z Z Z Zmult 
                   `a*((inject_nat t)+1)+c*((inject_nat s)+1)`
                   `a*((inject_nat t)+1)+c*((inject_nat s)+1)`
       `(inject_nat (mult r u))+(inject_nat (plus r u))+1`
   `(inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))+1` H2 H3). 
Apply Zeq_S with 
            m:=`(inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))`
            n:=`(inject_nat (mult r u))+(inject_nat (plus r u))`.

Cut (`(inject_nat (mult r u)) = (inject_nat r)*(inject_nat u)`).
Intro.
Cut (`(inject_nat (plus r u))= (inject_nat r)+(inject_nat u)`).
Intro.
Exact (f_equal2 Z Z Z Zplus
           (inject_nat (mult r u))
          `(inject_nat r)*(inject_nat u)` 
           (inject_nat (plus r u))
          `(inject_nat r)+(inject_nat u)` H3 H4). 
Exact (inj_plus r u).
Exact (inj_mult r u). 
Trivial.
Cut (`(a*((inject_nat t)+1)+c*((inject_nat s)+1))*
      (((inject_nat r)+1)*((inject_nat u)+1))=
      (b*((inject_nat u)+1)+d*((inject_nat r)+1))*
      (((inject_nat s)+1)*((inject_nat t)+1))`).
Intro.
Cut(`(a*((inject_nat t)+1)+c*((inject_nat s)+1))*((inject_nat r)*
     (inject_nat u)+((inject_nat r)+(inject_nat u))+1)=
     (a*((inject_nat t)+1)+c*((inject_nat s)+1))*
     (((inject_nat r)+1)*((inject_nat u)+1))`).
Intro.
Cut(`(b*((inject_nat u)+1)+d*((inject_nat r)+1))*
     (((inject_nat s)+1)*((inject_nat t)+1))=
      (b*((inject_nat u)+1)+d*((inject_nat r)+1))*((inject_nat s)*
   (inject_nat t)+((inject_nat s)+(inject_nat t))+1)`).
Intro.
Cut (`(a*((inject_nat t)+1)+c*((inject_nat s)+1))*
      ((inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))+1)=
      (b*((inject_nat u)+1)+d*((inject_nat r)+1))*
      (((inject_nat s)+1)*((inject_nat t)+1))`).
Intro.
Exact (trans_eq Z                
              `(a*((inject_nat t)+1)+c*((inject_nat s)+1))*((inject_nat r)*
               (inject_nat u)+((inject_nat r)+(inject_nat u))+1)`
              `(b*((inject_nat u)+1)+d*((inject_nat r)+1))*
               (((inject_nat s)+1)*((inject_nat t)+1))`
              `(b*((inject_nat u)+1)+d*((inject_nat r)+1))*
  ((inject_nat s)*(inject_nat t)+((inject_nat s)+(inject_nat t))+1)` H4 H3).
Exact (trans_eq Z
              `(a*((inject_nat t)+1)+c*((inject_nat s)+1))*((inject_nat r)*
               (inject_nat u)+((inject_nat r)+(inject_nat u))+1)`
              `(a*((inject_nat t)+1)+c*((inject_nat s)+1))*
               (((inject_nat r)+1)*((inject_nat u)+1))`
              `(b*((inject_nat u)+1)+d*((inject_nat r)+1))*
               (((inject_nat s)+1)*((inject_nat t)+1))` H2 H1).
Cut (`b*((inject_nat u)+1)+d*((inject_nat r)+1)=
      b*((inject_nat u)+1)+d*((inject_nat r)+1)`).
Intro.
Cut (`((inject_nat s)+1)*((inject_nat t)+1)=
      ((inject_nat s)*(inject_nat t)+((inject_nat s)+(inject_nat t))+1)`).
Intro.
Exact (f_equal2 Z Z Z  Zmult 
              `b*((inject_nat u)+1)+d*((inject_nat r)+1)`
              `b*((inject_nat u)+1)+d*((inject_nat r)+1)`  
     `((inject_nat s)+1)*((inject_nat t)+1)`
     `(inject_nat s)*(inject_nat t)+((inject_nat s)+(inject_nat t))+1` H3 H4). 
Cut (`((inject_nat s)+1)*((inject_nat t)+1) = ((inject_nat s)*
   (inject_nat t)+(inject_nat s))+((inject_nat t)+1)`).
Intro.
Cut (`(inject_nat s)* (inject_nat t)+(inject_nat s)+((inject_nat t)+1)=
      (inject_nat s)*(inject_nat t)+((inject_nat s)+(inject_nat t))+1`).
Intro.
Exact (trans_eq Z 
      `((inject_nat s)+1)*((inject_nat t)+1)`
      `(inject_nat s)*(inject_nat t)+(inject_nat s)+((inject_nat t)+1)`
      `(inject_nat s)*(inject_nat t)+((inject_nat s)+(inject_nat t))+1` H4 H5).
Cut (`(inject_nat s)*(inject_nat t)+(inject_nat s)+((inject_nat t)+1)
   =(((inject_nat s)*(inject_nat t)+(inject_nat s))+(inject_nat t))+1`).
Intro.
Cut (`(((inject_nat s)*(inject_nat t)+(inject_nat s))+(inject_nat t))+1
   = (inject_nat s)*(inject_nat t)+((inject_nat s)+(inject_nat t))+1`).
Intro.
Exact (trans_eq Z
       `(inject_nat s)*(inject_nat t)+(inject_nat s)+((inject_nat t)+1)`
       `(inject_nat s)*(inject_nat t)+(inject_nat s)+(inject_nat t)+1`
       `(inject_nat s)*(inject_nat t)+((inject_nat s)+(inject_nat t))+1` H5 H6).
Apply Zeq_S with 
          n:=`(inject_nat s)*(inject_nat t)+(inject_nat s)+(inject_nat t)`
          m:=`(inject_nat s)*(inject_nat t)+((inject_nat s)+(inject_nat t))`.
Apply sym_eq.
Exact (Zplus_assoc `(inject_nat s)*(inject_nat t)`  (inject_nat s) 
                   (inject_nat t)).
Exact (Zplus_assoc  `(inject_nat s)*(inject_nat t)+(inject_nat s)`
                    (inject_nat t) `1`).
Cut (`((inject_nat s)+1)*((inject_nat t)+1)=
      (inject_nat s)*((inject_nat t)+1)+((inject_nat t)+1)`).
Intro.
Cut (`(inject_nat s)*((inject_nat t)+1)+((inject_nat t)+1)=
      (inject_nat s)*(inject_nat t)+(inject_nat s)*1+((inject_nat t)+1)`). 
Intro.
Cut (`(inject_nat s)*(inject_nat t)+(inject_nat s)*1+((inject_nat t)+1)=
      (inject_nat s)*(inject_nat t)+(inject_nat s)+((inject_nat t)+1)`).
Intro.
Cut (`((inject_nat s)+1)*((inject_nat t)+1)=
      (inject_nat s)*(inject_nat t)+(inject_nat s)*1+((inject_nat t)+1)`).
Intro.
Exact (trans_eq Z
           `((inject_nat s)+1)*((inject_nat t)+1)`
           `(inject_nat s)*(inject_nat t)+(inject_nat s)*1+((inject_nat t)+1)`
           `(inject_nat s)*(inject_nat t)+(inject_nat s)+((inject_nat t)+1)`
       H7 H6).
Exact (trans_eq Z
           `((inject_nat s)+1)*((inject_nat t)+1)`
           `(inject_nat s)*((inject_nat t)+1)+((inject_nat t)+1)`
            `(inject_nat s)*(inject_nat t)+(inject_nat s)*1+((inject_nat t)+1)`
       H4 H5).

Apply Zplus_simpl  with n:=`(inject_nat s)*(inject_nat t)+(inject_nat s)*1` 
                        m:=`(inject_nat s)*(inject_nat t)+(inject_nat s)`
                        p:=`(inject_nat t)+1`
                        q:=`(inject_nat t)+1`.
Apply Zplus_simpl with n:=`(inject_nat s)*(inject_nat t)`
                       m:=`(inject_nat s)*(inject_nat t)`
                       p:=`(inject_nat s)*1`
                       q:=`(inject_nat s)`.
Reflexivity.
Exact (Zmult_n_1 `(inject_nat s)`).
Reflexivity.
Apply Zplus_simpl  with n:=`(inject_nat s)*((inject_nat t)+1)`
                        m:=`(inject_nat s)*(inject_nat t)+(inject_nat s)*1`
                        p:=`(inject_nat t)+1`
                        q:=`(inject_nat t)+1`.
Apply sym_eq.
Exact (Zred_factor4 (inject_nat s) (inject_nat t) `1`). 
Reflexivity.
Apply sym_eq.
Exact (Zmult_Sm_n (inject_nat s) `(inject_nat t)+1`). 
Trivial.
Apply (f_equal2 Z Z Z Zmult 
          `(a*((inject_nat t)+1)+c*((inject_nat s)+1))`
          `(a*((inject_nat t)+1)+c*((inject_nat s)+1))`
          `((inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))+1)`
          `(((inject_nat r)+1)*((inject_nat u)+1))`).
Reflexivity.
Cut (`(inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))+1=
      ((inject_nat r)*(inject_nat u)+(inject_nat r)+(inject_nat u))+1`).
Intro.
Cut (`(inject_nat r)*(inject_nat u)+(inject_nat r)+(inject_nat u)+1=
      (inject_nat r)*(inject_nat u)+(inject_nat r)*1+(inject_nat u)+1`).
Intro.
Cut (`(inject_nat r)*(inject_nat u)+(inject_nat r)*1+(inject_nat u)+1=
      (inject_nat r)*(inject_nat u)+(inject_nat r)*1+((inject_nat u)+1)`).
Intro.
Cut (`(inject_nat r)*(inject_nat u)+(inject_nat r)*1+((inject_nat u)+1)=
      (inject_nat r)*((inject_nat u)+1)+((inject_nat u)+1)`).
Intro.
Cut (`(inject_nat r)*((inject_nat u)+1)+((inject_nat u)+1)=
     ((inject_nat r)+1)*((inject_nat u)+1)`). 
Intro.
Cut (`(inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))+1=
      (inject_nat r)*((inject_nat u)+1)+((inject_nat u)+1)`).
Intro.
Exact (trans_eq Z
            `(inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))+1` 
            `(inject_nat r)*((inject_nat u)+1)+((inject_nat u)+1)`
            `((inject_nat r)+1)*((inject_nat u)+1)` H7 H6).
Cut (`(inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))+1=
      (inject_nat r)*(inject_nat u)+(inject_nat r)*1+((inject_nat u)+1)`).
Intro.
Exact (trans_eq Z
            `(inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))+1`
            `(inject_nat r)*(inject_nat u)+(inject_nat r)*1+((inject_nat u)+1)`
            `(inject_nat r)*((inject_nat u)+1)+((inject_nat u)+1)` H7 H5).
Cut (`(inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))+1=
      (inject_nat r)*(inject_nat u)+(inject_nat r)*1+(inject_nat u)+1`).
Intro.
Exact (trans_eq Z 
        `(inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))+1` 
        `(inject_nat r)*(inject_nat u)+(inject_nat r)*1+(inject_nat u)+1`
        `(inject_nat r)*(inject_nat u)+(inject_nat r)*1+((inject_nat u)+1)`
        H7 H4). 
Cut (`(inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))+1=
      (inject_nat r)*(inject_nat u)+(inject_nat r)+(inject_nat u)+1`).
Intro.
Exact (trans_eq Z
        `(inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))+1` 
        `(inject_nat r)*(inject_nat u)+(inject_nat r)+(inject_nat u)+1`
        `(inject_nat r)*(inject_nat u)+(inject_nat r)*1+(inject_nat u)+1`
        H7 H3).    
Assumption.
Exact (Zmult_Sm_n (inject_nat r) `(inject_nat u)+1`).
Apply (f_equal2 Z Z Z Zplus 
                   `(inject_nat r)*(inject_nat u)+(inject_nat r)*1`
                   `(inject_nat r)*((inject_nat u)+1)`
                   `(inject_nat u)+1`
                   `(inject_nat u)+1`).
Exact (Zred_factor4 (inject_nat r) (inject_nat u) `1`). 
Reflexivity.
Apply sym_eq.
Exact (Zplus_assoc `(inject_nat r)*(inject_nat u)+(inject_nat r)*1`
                   (inject_nat u)  `1`).
Apply (Zeq_S `(inject_nat r)*(inject_nat u)+(inject_nat r)+(inject_nat u)`
             `(inject_nat r)*(inject_nat u)+(inject_nat r)*1+(inject_nat u)`).
Apply (f_equal2 Z Z Z Zplus 
         `(inject_nat r)*(inject_nat u)+(inject_nat r)`
         `(inject_nat r)*(inject_nat u)+(inject_nat r)*1`
         (inject_nat u) (inject_nat u) ).    
Apply (f_equal2 Z Z Z Zplus 
       `(inject_nat r)*(inject_nat u)`
       `(inject_nat r)*(inject_nat u)`
       (inject_nat r)
       `(inject_nat r)*1` ).  
Reflexivity.
Apply sym_eq.
Exact (Zmult_n_1 (inject_nat r)).
Reflexivity.
Apply (Zeq_S `(inject_nat r)*(inject_nat u)+((inject_nat r)+(inject_nat u))`
             ` (inject_nat r)*(inject_nat u)+(inject_nat r)+(inject_nat u)`).
Exact( Zplus_assoc `(inject_nat r)*(inject_nat u)`
                   (inject_nat r) (inject_nat u)).
Exact (astonishing a b c d `(inject_nat s)+1` `(inject_nat r)+1` 
                           `(inject_nat t)+1` `(inject_nat u)+1` H H0).   
Qed.

Theorem Qplus_simpl: (n,m,p,q:Q)(EqQ n m)->(EqQ p q)->
(EqQ (Qplus n p) (Qplus m q)). 

Red.
Simpl.
Unfold EqQ.
Intros n m p q.
Exact (ghahti (numerator n) (numerator m) (numerator p) (numerator q) 
       (denominator n)  (denominator m)
       (denominator p)  (denominator q)). 
Qed.



Lemma tohfe :(a,b,c:Z;m,n,p:nat)
`( (a*( (plus (mult n p) (plus n p)) +1))+(((b*(p+1))+(c*(n+1)))*(m+1)))*
 ((plus (mult (plus (mult m n) (plus m n)) p) 
       (plus (plus (mult m n) (plus m n)) p))+1)             =
 ((((a*(n+1))+(b*(m+1)))*(p+1))+(c*( (plus (mult m n) (plus m n))+1)))*
 ( (plus  (mult m (plus (mult n p) (plus n p)))  
          (plus m (plus (mult n p) (plus n p))))   +1) `.
Intros.
Rewrite inj_plus with x:=(mult n p) y:=(plus n p).
Rewrite inj_plus with x:=n y:=p.
Rewrite inj_mult with x:=n y:=p.
Rewrite inj_plus with x:=(mult (plus (mult m n) (plus m n)) p)
                      y:=(plus (plus (mult m n) (plus m n)) p).
Rewrite inj_mult with x:=(plus (mult m n) (plus m n)) y:=p.
Rewrite inj_plus with x:=(plus (mult m n) (plus m n)) y:=p.
Rewrite inj_plus with x:=(mult m n) y:=(plus m n).
Rewrite inj_plus with x:=m y:=n.
Rewrite inj_mult with x:=m y:=n.
Rewrite inj_plus with x:=(mult m (plus (mult n p) (plus n p)))
                      y:= (plus m (plus (mult n p) (plus n p))).
Rewrite inj_mult with x:=m y:=(plus (mult n p) (plus n p)).
Rewrite inj_plus with x:=m y:=(plus (mult n p) (plus n p)).
Rewrite inj_plus with x:=(mult n p) y:=(plus n p).
Rewrite inj_mult with x:=n y:=p.
Rewrite inj_plus with x:=n y:=p.
Ring.
Qed.

Theorem Qplus_assoc:(x,y,z:Q)(EqQ (Qplus x (Qplus y z)) (Qplus (Qplus x y) z))
.
Intros.
Red.
Unfold Qplus.
Simpl.
Exact (tohfe (numerator x) (numerator y) (numerator z) 
             (denominator x) (denominator y) (denominator z)). 
Qed.

Theorem ZEROQ_right : (x:Q)(EqQ (Qplus x ZEROQ) x).
Intro.
Red.
Unfold Qplus.
Simpl.
Ring `(numerator x)*1`.
Ring `(numerator x)+0`.
Ring (mult (denominator x) O).
Ring (plus (denominator x) O).
Ring (plus O (denominator x)).
Reflexivity.
Qed.

Theorem Qplus_sym : (x,y:Q)(EqQ (Qplus x y) (Qplus y x)).
Intros.
Unfold Qplus.
Red.
Simpl.
Rewrite mult_sym with n:=(denominator y) m:=(denominator x).
Rewrite plus_sym with n:=(denominator y) m:=(denominator x).
Rewrite Zplus_sym with x:=`(numerator x)*((inject_nat (denominator y))+1)`
                       y:=`(numerator y)*((inject_nat (denominator x))+1)`.
Reflexivity.
Qed.

Remark Qopp_simpl : (x,y:Q) (EqQ x y)->(EqQ (Qopp x) (Qopp y)).
Red.
Simpl.
Unfold EqQ.
Intros.
Rewrite Zopp_Zmult with x:=(numerator x) y:=`((inject_nat (denominator y))+1)`.
Rewrite Zopp_Zmult with x:=(numerator y) y:=`((inject_nat (denominator x))+1)`.
Exact (f_equal Z Z Zopp `(numerator x)*((inject_nat (denominator y))+1)`
                        `(numerator y)*((inject_nat (denominator x))+1)` H).
Qed.

Theorem Qplus_inverse_r:(q:Q)(EqQ (Qplus q (Qopp q)) ZEROQ).
Red.
Simpl.
Intro.
Ring.
Qed.

Theorem Qmult_simpl: (n,m,p,q:Q)(EqQ n m)->(EqQ p q)->
(EqQ (Qmult n p) (Qmult m q)). 
Red.
Simpl.
Unfold EqQ.
Intros.
Rewrite inj_plus with x:=(mult (denominator m) (denominator q))
                      y:=(plus (denominator m) (denominator q)).
Rewrite inj_mult with x:=(denominator m) y:=(denominator q). 
Rewrite inj_plus with x:=(denominator m) y:=(denominator q).
Rewrite inj_plus with x:=(mult (denominator n) (denominator p))
                      y:=(plus (denominator n) (denominator p)).
Rewrite inj_mult with x:=(denominator n) y:=(denominator p). 
Rewrite inj_plus with x:=(denominator n) y:=(denominator p). 
Rewrite Zplus_assoc with 
    x:=`(inject_nat (denominator m))* (inject_nat (denominator q))`
    y:=(inject_nat (denominator m)) z:=(inject_nat (denominator q)).
Rewrite <- Zmult_n_1 with n:=(inject_nat (denominator m)).
Rewrite <- Zmult_assoc with x:=(inject_nat (denominator m)) y:=`1` 
z:=(inject_nat (denominator q)).
Rewrite Zmult_1_n with n:=(inject_nat (denominator q)).
Rewrite Zred_factor4 with x:=(inject_nat (denominator m))
                          y:=(inject_nat (denominator q)) z:=`1`.
Rewrite <- Zplus_assoc with 
    x:=`(inject_nat (denominator m))*((inject_nat (denominator q))+1)`
    y:=(inject_nat (denominator q)) z:=`1`.
Rewrite Zmult_Sm_n with n:=(inject_nat (denominator m))
                        m:=`((inject_nat (denominator q))+1)`.
Unfold Zs.
Rewrite  <- Zmult_assoc with x:=(numerator n) y:=(numerator p)
     z:=`(((inject_nat (denominator m))+1)*((inject_nat (denominator q))+1))`.
Rewrite Zmult_permute with n:=(numerator p) 
                           m:=`(inject_nat (denominator m))+1`
                           p:=`(inject_nat (denominator q))+1`.
Rewrite Zmult_assoc with x:=(numerator n) y:=`(inject_nat (denominator m))+1`
             z:=`((numerator p)*((inject_nat (denominator q))+1))`.

Rewrite Zplus_assoc with 
    x:=`(inject_nat (denominator n))* (inject_nat (denominator p))`
    y:=(inject_nat (denominator n)) z:=(inject_nat (denominator p)).
Rewrite <- Zmult_n_1 with n:=(inject_nat (denominator n)).
Rewrite <- Zmult_assoc with x:=(inject_nat (denominator n)) y:=`1` 
z:=(inject_nat (denominator p)).
Rewrite Zmult_1_n with n:=(inject_nat (denominator p)).
Rewrite Zred_factor4 with x:=(inject_nat (denominator n))
                          y:=(inject_nat (denominator p)) z:=`1`.
Rewrite <- Zplus_assoc with 
    x:=`(inject_nat (denominator n))*((inject_nat (denominator p))+1)`
    y:=(inject_nat (denominator p)) z:=`1`.
Rewrite Zmult_Sm_n with n:=(inject_nat (denominator n))
                        m:=`((inject_nat (denominator p))+1)`.
Unfold Zs.
Rewrite  <- Zmult_assoc with x:=(numerator m) y:=(numerator q)
     z:=`(((inject_nat (denominator n))+1)*((inject_nat (denominator p))+1))`.
Rewrite Zmult_permute with n:=(numerator q) 
                           m:=`(inject_nat (denominator n))+1`
                           p:=`(inject_nat (denominator p))+1`.
Rewrite Zmult_assoc with x:=(numerator m) y:=`(inject_nat (denominator n))+1`
                         z:=`((numerator q)*((inject_nat (denominator p))+1))`.
Apply (f_equal2 Z Z Z Zmult `(numerator n)*((inject_nat (denominator m))+1)`
                            `(numerator m)*((inject_nat (denominator n))+1)`
                            `(numerator p)*((inject_nat (denominator q))+1)`
                            `(numerator q)*((inject_nat (denominator p))+1)`).
Assumption.
Assumption.
Qed.

Theorem Qmult_assoc : (n,m,p: Q) 
                      (EqQ (Qmult n (Qmult m p)) (Qmult (Qmult n m) p)).
Intros n m p.
Red.
Simpl.
Rewrite inj_plus with x:=(mult
    (plus 
(mult (denominator n) (denominator m)) (plus (denominator n) (denominator m)))
    (denominator p))
                    y:=(plus
    (plus (mult (denominator n) (denominator m))
    (plus (denominator n) (denominator m))) (denominator p)). 
Rewrite inj_mult with x:=(plus 
                         (mult (denominator n) (denominator m)) 
                         (plus (denominator n) (denominator m)))
                      y:=(denominator p).
Rewrite inj_plus with x:=(plus 
                         (mult (denominator n) (denominator m)) 
                         (plus (denominator n) (denominator m)))
                      y:=(denominator p).
Rewrite inj_plus with x:= (mult (denominator n) (denominator m))
                      y:= (plus (denominator n) (denominator m)).
Rewrite inj_plus with x:=(denominator n) y:=(denominator m).
Rewrite inj_plus with x:=(mult
 (denominator n) 
 (plus 
    (mult (denominator m) (denominator p))
    (plus (denominator m) (denominator p))))
                       y:=(plus
 (denominator n) 
 (plus 
    (mult (denominator m) (denominator p))
    (plus (denominator m) (denominator p)))).
Rewrite inj_mult with x:=(denominator n)
                      y:= (plus 
                            (mult (denominator m) (denominator p)) 
                            (plus (denominator m) (denominator p))).
Rewrite inj_plus with x:=(denominator n)
                      y:= (plus 
                            (mult (denominator m) (denominator p)) 
                            (plus (denominator m) (denominator p))).  
Rewrite inj_plus with x:= (mult (denominator m) (denominator p))
                      y:= (plus (denominator m) (denominator p)).
Rewrite inj_plus with x:=(denominator m) y:=(denominator p).
Rewrite inj_mult with x:=(denominator m) y:=(denominator p).
Rewrite inj_mult with x:=(denominator n) y:=(denominator m).
Ring.
Qed.

Theorem Qmult_n_1 :(n:Q)(EqQ (Qmult n ONEQ) n).
Intro.
Red.
Simpl.
Rewrite Zmult_n_1 with n:=(numerator n).
Rewrite inj_plus with x:=(mult (denominator n) O) y:=(plus (denominator n) O).
Rewrite inj_mult with x:=(denominator n) y:=O.
Rewrite inj_plus with x:=(denominator n) y:=O.
Simpl.
Rewrite Zero_mult_right with x:=(inject_nat (denominator n)). 
Rewrite Zero_right with x:=(inject_nat (denominator n)). 
Rewrite Zero_left with x:= (inject_nat (denominator n)).
Reflexivity.
Qed.

Theorem Qmult_sym : (x,y:Q)(EqQ (Qmult x y) (Qmult y x)).
Intros x y.
Red.
Simpl.
Rewrite inj_plus with x:=(mult (denominator y) (denominator x))
                      y:=(plus (denominator y) (denominator x)).
Rewrite inj_plus with x:=(mult (denominator x) (denominator y))
                      y:=(plus (denominator x) (denominator y)).
Rewrite inj_plus with x:=(denominator y) y:=(denominator x).
Rewrite inj_mult with x:=(denominator y) y:=(denominator x).
Rewrite Zmult_sym with x:=(numerator y) y:=(numerator x).
Rewrite inj_plus with x:=(denominator x) y:=(denominator y).
Rewrite inj_mult with x:=(denominator x) y:=(denominator y).
Ring.
Qed.

Theorem Qmult_plus_distr_r :(x,y,z:Q)(EqQ (Qmult x (Qplus y z)) 
                                          (Qplus (Qmult x y) (Qmult x z))). 
Intros x y z.
Red.
Simpl.
Rewrite inj_plus with 
 x:=(mult (plus (mult (denominator x) (denominator y))
                (plus (denominator x) (denominator y)))
          (plus (mult (denominator x) (denominator z))
                (plus (denominator x) (denominator z))))                     
 y:=(plus (plus (mult (denominator x) (denominator y))
                (plus (denominator x) (denominator y)))
          (plus (mult (denominator x) (denominator z))
                (plus (denominator x) (denominator z)))).      
Rewrite inj_mult with x:=(plus (mult (denominator x) (denominator y))
                               (plus (denominator x) (denominator y)))
                      y:=(plus (mult (denominator x) (denominator z))
                               (plus (denominator x) (denominator z))).
Rewrite inj_plus with x:=(mult (denominator x) (denominator y))
                      y:=(plus (denominator x) (denominator y)).
Rewrite inj_plus with x:=(mult (denominator x) (denominator z))
                      y:=(plus (denominator x) (denominator z)).
Rewrite inj_plus with x:=(plus (mult (denominator x) (denominator y))
                               (plus (denominator x) (denominator y)))
                      y:=(plus (mult (denominator x) (denominator z))
                               (plus (denominator x) (denominator z))).
Rewrite inj_plus with x:=(mult (denominator x) (denominator y))
                      y:=(plus (denominator x) (denominator y)).
Rewrite inj_plus with x:=(mult (denominator x) (denominator z))
                      y:=(plus (denominator x) (denominator z)).
Rewrite inj_mult with x:=(denominator x) y:=(denominator y).
Rewrite inj_plus with x:=(denominator x) y:=(denominator y).
Rewrite inj_mult with x:=(denominator x) y:=(denominator z).
Rewrite inj_plus with x:=(denominator x) y:=(denominator z).
Rewrite inj_plus  with 
   x:=(mult (denominator x)
            (plus (mult (denominator y) (denominator z))
                  (plus (denominator y) (denominator z))))
   y:=(plus (denominator x)
            (plus (mult (denominator y) (denominator z))
                  (plus (denominator y) (denominator z)))).
Rewrite inj_mult with x:=(denominator x)
                      y:= (plus (mult (denominator y) (denominator z))
    (plus (denominator y) (denominator z))).
Rewrite inj_plus with x:=(denominator x)
                      y:= (plus (mult (denominator y) (denominator z))
    (plus (denominator y) (denominator z))).
Rewrite inj_plus with x:=(mult (denominator y) (denominator z))
                      y:=(plus (denominator y) (denominator z)).
Rewrite inj_mult with x:=(denominator y) y:=(denominator z).
Rewrite inj_plus with x:=(denominator y) y:=(denominator z).
Ring.
Qed.

Theorem ONEQ_neq_ZEROQ : (~(EqQ ONEQ ZEROQ)).
Unfold EqQ.
Simpl.
Intro.
Cut (`1>0`).
Intro.
Cut (~(`1=0`)).
Intro.
Apply H1.
Assumption.
Apply (Zgt_not_eq).
Assumption.
Exact (POS_gt_ZERO xH).
Qed.

Theorem Qmult_eq :(x,y:Q)~(EqQ x ZEROQ)->(EqQ (Qmult x y) ZEROQ)->(EqQ y ZEROQ).
Intros x y.
Unfold EqQ.
Simpl.
Rewrite Zmult_n_1 with n:=(numerator x).
Rewrite Zmult_n_1 with n:=`(numerator x)*(numerator y)`.
Rewrite Zmult_n_1 with n:=(numerator y).
Rewrite Zmult_sym with x:=(numerator x) y:=(numerator y).
Exact(Zmult_eq (numerator x) (numerator y)).
Qed.



