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

Require Export ZQ_CRings.
Require Export CFields. 


(* Summary:
 1- Definition of Qinv -inverse on Q_star (the nonzero part of Q).
 2- Q is CField.
*)



Definition Q_star:=(NonZeros Q_as_CRing).

Remark mosbat :(y:positive;n:nat)(nonZeroP Q_as_CRing 
(!Build_Q (POS y) n)).
Intros.
Simpl.
Red.
Simpl.
Red.
Unfold EqQ.
Unfold ZEROQ.
Unfold numerator.
Unfold denominator.
Unfold 1 inject_nat .
Ring `0+1`.
Ring `0*((inject_nat n)+1)`.
Ring `(POS y)*1`.
Cut (`(POS y)>0`).
Intro.
Exact (Zgt_not_eq (POS y) `0` H).
Exact (POS_gt_ZERO y).
Qed.


Definition Zsgn:=[x:Z]
 <Z> Cases (`x ?= ZERO`) of
      EGAL  => ZERO
    | SUPERIEUR  => `1`
    | INFERIEUR  => `-1`
     end.

(* 
Lemma Zsgn_1:(x:Z){`(Zsgn x)=0`}+{`(Zsgn x)=1`}+{`(Zsgn x)=(-1)`}.
Intros.
Case x.
Left.
Left.
Unfold Zsgn.
Trivial.
Left.
Right.
Unfold Zsgn.
Trivial.
Right.
Unfold Zsgn.
Trivial.
Qed. 
*)

Lemma Zsgn_2:(x:Z)`(Zsgn x)=0`->`x=0`.
Intros.
Case (dec_eq x `0`).
Intro.
Assumption.
Intro.
Apply False_ind.
Cut (`x<0`\/`x>0`).
Intro.
ElimCompare x `0`.
Intro.
Cut (`x=0`).
Assumption.
Cut ((Zcompare x `0`)=EGAL->`x=0`).
Intro.
Apply H3.
Assumption.
Apply proj1 with B:=(`x=0`->(`x ?= 0`=EGAL)).
Change (`x ?= 0`=EGAL<->`x = 0`).
Apply Zcompare_EGAL.

Intro.
Cut (`(Zsgn x)=(-1)`).
Intro.
Rewrite H in H3.
Cut (`0>(-1)`).
Intro.
Apply (Zgt_not_eq `0` `-1` H4).
Assumption.
Apply Zlt_gt.
Apply Zlt_S_n.
Unfold Zs.
Simpl.
Apply Zgt_lt.
Apply POS_gt_ZERO.
Unfold Zsgn.
Rewrite H2.
Trivial.

Intro.
Cut (`(Zsgn x)=1`).
Intro.
Rewrite H in H3.
Cut (`1=0`).
Intro.
Apply (Zgt_not_eq `1` `0` (POS_gt_ZERO xH)).
Assumption.
Apply sym_eq.
Assumption.
Unfold Zsgn.
Rewrite H2.
Trivial.
Cut (`x<0`\/`0<x`).
Intro.
Apply or_ind with A:=`x<0` B:=`0<x` P:=(`x < 0`\/`x > 0`).
Intro.
Left.
Assumption.
Intro.
Right.
Apply Zlt_gt.
Assumption.
Assumption.
Apply not_Zeq.
Assumption.
Qed.

Lemma Zsgn_3:(x:Z)`x<>0`->`(Zsgn x)<>0`.
Intros.
Intro.
Apply H.
Apply Zsgn_2.
Assumption.
Qed.


Remark nonzero:(x:Q_star)(nonZeroP Q_as_CRing ((nzinj Q_as_CRing) x)).
Intro.
Red.
Simpl.
Red.
Unfold EqQ.
Unfold ZEROQ.
Unfold 1 denominator.
Unfold 2 numerator.
Unfold 1 inject_nat.
Ring `0*((inject_nat (denominator (nzinj Q_as_CRing x)))+1)`.
Ring `0+1`.
Ring `(numerator (nzinj Q_as_CRing x))*1`.
Unfold nzinj.
Unfold nonZeroP.
Simpl.
Unfold Q_star in x.
Case x.
Intros.
Unfold nonZeroP in scs_prf.
Unfold scs_elem.
Red.
Intro.
Cut (EqQ scs_elem ZEROQ).
Intro.
Apply scs_prf.
Assumption.
Unfold EqQ.
Rewrite H.
Unfold ZEROQ.
Unfold numerator.
Ring (`0*((inject_nat (denominator (Build_Q 0 O)))+1)`).
Ring (`0*((inject_nat (denominator scs_elem))+1)`).
Reflexivity.
Qed.


Remark nonZero: (x:Q_star)~(EqQ 
  (!Build_Q `(Zsgn (numerator ((nzinj Q_as_CRing) x)))*
               ((denominator ((nzinj Q_as_CRing) x))+1)`
               (pred (absolu (numerator ((nzinj Q_as_CRing) x))))) 
   ZEROQ). 
Intro.
Unfold EqQ.
Unfold 1 numerator.
Unfold ZEROQ.
Unfold 2 numerator.
Ring `0*
   ((inject_nat
    (denominator
    (Build_Q ((Zsgn (numerator (nzinj Q_as_CRing x)))*
    ((inject_nat (denominator (nzinj Q_as_CRing x)))+1))
    (pred (absolu (numerator (nzinj Q_as_CRing x)))))))+1)`.
Unfold 2 denominator.
Unfold 2 inject_nat.
Ring `0+1`.

Rewrite (Zmult_n_1) with n:=`(Zsgn (numerator (nzinj Q_as_CRing x)))*
   ((inject_nat (denominator (nzinj Q_as_CRing x)))+1)`.
Cut (`(Zsgn (numerator (nzinj Q_as_CRing x)))<>0`).
Intro.
Cut (`((inject_nat (denominator (nzinj Q_as_CRing x)))+1)<>0`).
Intro.
Red.
Intro.
Apply H.
Exact (Zmult_eq `(inject_nat (denominator (nzinj Q_as_CRing x)))+1`
                `(Zsgn (numerator (nzinj Q_as_CRing x)))` H0 H1).
Cut (`(inject_nat (denominator (nzinj Q_as_CRing x)))+1>0`).
Intro.
Apply Zgt_not_eq.
Assumption.
Apply Zlt_gt.
Apply Zle_lt_n_Sm with m:=(inject_nat (denominator (nzinj Q_as_CRing x))).
Case ((denominator (nzinj Q_as_CRing x))).
Unfold inject_nat.
Apply Zle_n.
Intro.
Apply inj_le with x:=O.

Apply le_O_n.
Apply Zsgn_3.
Intro.
Cut (EqQ (nzinj Q_as_CRing x)  ZEROQ).
Intro.
Apply (nonzero x).
Simpl.
Assumption.
Unfold EqQ.
Unfold ZEROQ.
Unfold 1 denominator.
Unfold 2 numerator.
Unfold 1 inject_nat.
Simpl.
Rewrite Zmult_n_1 with n:=(numerator (nzinj Q_as_CRing x)).
Assumption.
Qed.


Definition Qinv:Q_star->Q_star:=[x:Q_star] 
  ( (nzpro Q_as_CRing) 
    (!Build_Q `(Zsgn (numerator ((nzinj Q_as_CRing) x)))*
               ((denominator ((nzinj Q_as_CRing) x))+1)`
               (pred (absolu (numerator ((nzinj Q_as_CRing) x)))))     
    (nonZero x) ).



Theorem Q_star_EQ1: (x,y:Q_star)(x [=] y)->((nzinj Q_as_CRing) x)
                                             [=] ((nzinj Q_as_CRing) y).
Intros x y.
Case x.
Intros x1 b1.
Case y.
Intros y1 c1.
Intro H.
Red in H.

Unfold nzinj.
Unfold Q_star in H.
Simpl in H.
Red.
Simpl.
Assumption.
Qed.

Lemma  ZL9: (p:positive)(inject_nat (convert p))=(POS p). 
Intro.
Cut (EX h:nat | (convert p)=(S h)).
Intro.
Case H.
Intros.
Unfold inject_nat.
Rewrite H0.

Apply f_equal with A:=positive B:=Z f:=POS.
Cut ((anti_convert (convert p))=(anti_convert (S x))).
Intro.
Rewrite bij2 in H1.
Cut ((sub_un  (add_un p))=(sub_un (anti_convert (S x)))).
Intro.
Rewrite sub_add_one in H2.
Simpl in H2.
Rewrite sub_add_one in H2.
Apply sym_eq.
Assumption.
Apply f_equal with A:=positive B:=positive f:=sub_un.
Assumption.
Apply f_equal with f:=anti_convert.
Assumption.
Apply ZL4.
Qed.



Theorem Zsgn_4:(a:Z)`a=(Zsgn a)*(absolu a)`. 
Intro.
Case a.
Simpl.
Trivial.
Intro.
Unfold absolu.
Rewrite ZL9.
Unfold Zsgn.
Cut (`(POS p) ?= 0`=SUPERIEUR).
Intro.
Rewrite H.
Simpl.
Trivial.
Change (`(POS p) > 0`).
Exact (POS_gt_ZERO p).
Intro.
Unfold absolu.
Rewrite ZL9.
Unfold Zsgn.
Cut (`(NEG p) ?= 0`=INFERIEUR).
Intro.
Rewrite H. 
Change (`(NEG p)=-(POS p)`).
Simpl.
Trivial.
Change (`(NEG p)<0`).
Apply Zgt_lt.
Change (`(Zopp 0)>(Zopp (POS p))`).
Apply Zlt_opp.
Apply Zgt_lt.
Exact (POS_gt_ZERO p).
Qed.

Theorem Zsgn_5: (a,b,x,y:Z)`x<>0`->`y<>0`-> 
                 `(Zsgn a)*x=(Zsgn b)*y`->`(Zsgn a)*y=(Zsgn b)*x`. 
Intros a b x y H H0.
Case a.

Case b.
Simpl.
Trivial.

Intro.
Unfold 1 Zsgn.
Unfold 2 Zsgn.
Cut (`0 ?= 0`=EGAL).Intro.
Rewrite H1.
Rewrite Zero_mult_left.
Rewrite Zero_mult_left.
Unfold Zsgn.
Cut (`(POS p) ?= 0`=SUPERIEUR).
Intro.
Rewrite H2.
Intro.
Rewrite Zmult_1_n in H3. 
Apply False_ind.
Apply H0.
Apply sym_eq.
Assumption.
Change (`(POS p)>0`).
Exact (POS_gt_ZERO p).
(******)
Cut (`0=0`).
Apply proj1 with B:=`0 ?= 0`=EGAL->`0 = 0`. 
Change (`0=0`<->`0 ?= 0`=EGAL).
Cut (`0 ?= 0`=EGAL<->`0=0`).
Tauto.
Exact (Zcompare_EGAL `0` `0`).
Trivial.
(******)
Intro.
Unfold 1 Zsgn.
Unfold 2 Zsgn.
Cut (`0 ?= 0`=EGAL).
Intro.
Rewrite H1.
Rewrite Zero_mult_left.
Rewrite Zero_mult_left.
Unfold Zsgn.
Cut (`(NEG p) ?= 0`=INFERIEUR).
Intro.
Rewrite H2.
Intro.
Change `(Zopp 0)=-y` in H3.
Cut (`0=y`).
Intro.
Apply False_ind.
Apply H0.
Apply sym_eq.
Assumption.
Apply Zopp_intro.
Assumption.


Change (`(NEG p)<0`).
Apply Zgt_lt.
Change (`(Zopp 0)>(Zopp (POS p))`).
Apply Zlt_opp.
Apply Zgt_lt.
Exact (POS_gt_ZERO p).

Cut (`0=0`).
Apply proj1 with B:=`0 ?= 0`=EGAL->`0 = 0`. 
Change (`0=0`<->`0 ?= 0`=EGAL).
Cut (`0 ?= 0`=EGAL<->`0=0`).
Tauto.
Exact (Zcompare_EGAL `0` `0`).
Trivial.

Intro.

Case b.


Unfold 2 Zsgn.
Unfold 3 Zsgn.
Cut (`0 ?= 0`=EGAL).
Intro.
Rewrite H1.
Rewrite Zero_mult_left.
Rewrite Zero_mult_left.
Unfold Zsgn.
Cut (`(POS p) ?= 0`=SUPERIEUR).
Intro.
Rewrite H2.
Intro.
Rewrite Zmult_1_n in H3. 
Apply False_ind.
Apply H.
Assumption.
Change (`(POS p)>0`).
Exact (POS_gt_ZERO p).

Cut (`0=0`).
Apply proj1 with B:=`0 ?= 0`=EGAL->`0 = 0`. 
Change (`0=0`<->`0 ?= 0`=EGAL).
Cut (`0 ?= 0`=EGAL<->`0=0`).
Tauto.
Exact (Zcompare_EGAL `0` `0`).
Trivial.

Intro.
Unfold  Zsgn.

Cut (`(POS p) ?= 0`=SUPERIEUR).
Intro.
Rewrite H1.
Cut (`(POS p0) ?= 0`=SUPERIEUR).
Intro.
Rewrite H2.
Rewrite Zmult_1_n.
Rewrite Zmult_1_n.
Intro.
Apply sym_eq.
Assumption.
Change (`(POS p0)>0`).
Exact (POS_gt_ZERO p0).
Change (`(POS p)>0`).
Exact (POS_gt_ZERO p).

Intro.
Unfold  Zsgn.

Cut (`(POS p) ?= 0`=SUPERIEUR).
Intro.
Rewrite H1.
Cut (`(NEG p0) ?= 0`=INFERIEUR).
Intro.
Rewrite H2.
Rewrite Zmult_1_n.
Rewrite Zmult_1_n.Intro.
Apply sym_eq.
Cut (`(-1)*x=(-1)*(-1)*y`).
Intro.
Cut (`(-1)*(-1)=1`).
Intro.
Rewrite H5 in H4.
Rewrite Zmult_1_n in H4.
Assumption.
Simpl.
Trivial.
Rewrite <- Zmult_assoc.
Apply f_equal2 with f:=Zmult x2:=x y2:=`(-1)*y` x1:=`-1` y1:=`-1`.  
Trivial.
Assumption.

Change (`(NEG p)<0`).
Apply Zgt_lt.
Change (`(Zopp 0)>(Zopp (POS p))`).
Apply Zlt_opp.
Apply Zgt_lt.
Exact (POS_gt_ZERO p).

Change (`(POS p)>0`).
Exact (POS_gt_ZERO p).



Case b.

Intro.
Unfold 2 Zsgn.
Unfold 3 Zsgn.
Cut (`0 ?= 0`=EGAL).
Intro.
Rewrite H1.
Rewrite Zero_mult_left.
Rewrite Zero_mult_left.
Unfold Zsgn.
Cut (`(NEG p) ?= 0`=INFERIEUR).
Intro.
Rewrite H2.
Intro.
Change (`-x=(Zopp 0)`) in H3.
Cut (`x=0`).
Intro.
Apply False_ind.
Apply H.
Assumption.
Apply Zopp_intro.
Assumption.

Change (`(NEG p)<0`).
Apply Zgt_lt.
Change (`(Zopp 0)>(Zopp (POS p))`).
Apply Zlt_opp.
Apply Zgt_lt.
Exact (POS_gt_ZERO p).

Cut (`0=0`).
Apply proj1 with B:=`0 ?= 0`=EGAL->`0 = 0`. 
Change (`0=0`<->`0 ?= 0`=EGAL).
Cut (`0 ?= 0`=EGAL<->`0=0`).
Tauto.
Exact (Zcompare_EGAL `0` `0`).
Trivial.

Intro.
Intro.
Unfold  Zsgn.

Cut (`(POS p) ?= 0`=SUPERIEUR).
Intro.
Rewrite H1.
Cut (`(NEG p0) ?= 0`=INFERIEUR).
Intro.
Rewrite H2.
Rewrite Zmult_1_n.
Rewrite Zmult_1_n.
Intro.
Apply sym_eq.
Cut (`(-1)*(-1)*x=(-1)*y`).
Intro.
Cut (`(-1)*(-1)=1`).
Intro.
Rewrite H5 in H4.
Rewrite Zmult_1_n in H4.
Assumption.
Simpl.
Trivial.
Rewrite <- Zmult_assoc.
Apply f_equal2 with f:=Zmult x2:=`(-1)*x` y2:=y x1:=`-1` y1:=`-1`.  
Trivial.
Assumption.

Change (`(NEG p0)<0`).
Apply Zgt_lt.
Change (`(Zopp 0)>(Zopp (POS p0))`).
Apply Zlt_opp.
Apply Zgt_lt.
Exact (POS_gt_ZERO p0).

Change (`(POS p)>0`).
Exact (POS_gt_ZERO p).

Intro.
Intro.
Unfold  Zsgn.

Cut (`(NEG p) ?= 0`=INFERIEUR).
Intro.
Rewrite H1.
Cut (`(NEG p0) ?= 0`=INFERIEUR).
Intro.
Rewrite H2.
Intro.
Apply sym_eq.
Assumption.

Change (`(NEG p0)<0`).
Apply Zgt_lt.
Change (`(Zopp 0)>(Zopp (POS p0))`).
Apply Zlt_opp.
Apply Zgt_lt.
Exact (POS_gt_ZERO p0).

Change (`(NEG p)<0`).
Apply Zgt_lt.
Change (`(Zopp 0)>(Zopp (POS p))`).
Apply Zlt_opp.
Apply Zgt_lt.
Exact (POS_gt_ZERO p).
Qed.

Lemma nat_nat_pos:(m,n:nat)`(m+1)*(n+1)>0`.
Intros.
Apply Zlt_gt.
Cut (`(inject_nat m)+1>0`).
Intro.
Cut(`0<(inject_nat n)+1`).
Intro.
Cut (`(((inject_nat m)+1)*0) < ((inject_nat m)+1)*((inject_nat n)+1)`).
Rewrite Zero_mult_right.
Intro.
Assumption.

Apply Zlt_reg_mult_l.
Assumption.
Assumption.
Change (`0<(Zs (inject_nat n))`).
Apply Zle_lt_n_Sm.
Change (`(inject_nat O) <= (inject_nat n)`).
Apply inj_le.
Apply le_O_n.
Apply Zlt_gt.
Change (`0<(Zs (inject_nat m))`).
Apply Zle_lt_n_Sm.
Change (`(inject_nat O) <= (inject_nat m)`).
Apply inj_le.
Apply le_O_n.
Qed.


Lemma Q_non_zero: (x:Q)(ap_Q x ZEROQ)->`(numerator x)<>0`.
Intros.
Red in H.
Intro.
Apply H.
Unfold EqQ.
Unfold ZEROQ.
Unfold 2 numerator.
Rewrite H0.
Simpl.
Trivial.
Qed.


Theorem S_predn:(m:nat)(~(m=O))->(S (pred m))=m.
Intros.

Case (O_or_S m).
Intro.
Case s.
Intros.
Rewrite <- e. 
Rewrite <- pred_Sn with m:=x. 
Trivial.
Intro.
Apply False_ind.
Apply H.
Apply sym_eq.
Assumption.
Qed.

Lemma absolu_1:(x:Z)((absolu x)=O)->(`x=0`).
Intros.
Case (dec_eq x `0`).
Intro.
Assumption.
Intro.
Apply False_ind.
Cut (`x<0`\/`x>0`).
Intro.
ElimCompare x `0`.
Intro.
Cut (`x=0`).
Assumption.
Cut (`x ?= 0`=EGAL ->`x=0`).
Intro.
Apply H3.
Assumption.
Apply proj1 with B:=(`x=0`->(`x ?= 0`=EGAL)).
Change (`x ?=0`=EGAL<->`x=0`).
Apply Zcompare_EGAL.

(***)
Intro.
Cut ((EX h:nat| (absolu x)=(S h))).
Intro.
Case H3.
Rewrite H.
Exact O_S.

Change (`x<0`) in H2.
Cut (`0>x`).
Intro.
Cut ((EX p:positive |`0+(Zopp x)=(POS p)`)).
Simpl.
Intro.
Case H4.
Intros.
Cut (EX q:positive |x=(NEG q)).
Intro.
Case H6.
Intros.
Rewrite H7.
Unfold absolu.
Generalize x1.
Exact ZL4.
Cut (x=(Zopp (POS x0))).
Simpl.
Intro.
Exists x0.
Assumption.
Cut ((Zopp (Zopp x))=x).
Intro.
Rewrite <- H6.
Exact (f_equal Z Z Zopp `-x` (POS x0) H5). 
Apply Zopp_Zopp.
Apply SUPERIEUR_POS.
Assumption.
Apply Zlt_gt.
Assumption.

(***)
Intro.
Cut ((EX h:nat| (absolu x)=(S h))).
Intro.
Case H3.
Rewrite H.
Exact O_S.

Cut ((EX p:positive |`x+(Zopp 0)=(POS p)`)).
Simpl.
Rewrite Zero_right.
Intro.
Case H3.
Intros.
Rewrite H4.
Unfold absolu.
Generalize x0.
Exact ZL4.
Apply SUPERIEUR_POS.
Assumption.

(***)
Cut (`x<0`\/`0<x`).
Intro.
Apply or_ind with A:=`x<0` B:=`0<x` P:=(`x < 0`\/`x > 0`).
Intro.
Left.
Assumption.
Intro.
Right.
Apply Zlt_gt.
Assumption.
Assumption.
Apply not_Zeq.
Assumption.
Qed.

Lemma absolu_2: (x:Z)(`x<>0`)->(~((absolu x)=O)).
Intros.
Intro.
Apply H.
Apply absolu_1.
Assumption.
Qed.

Theorem Qinv_simpl : (x,y:Q_star) (x [=] y)->((Qinv x) [=] (Qinv y)).
Intros x y.
Case x.
Intros x1 p1.
Case y.
Intros y1 q1.
Intro.
Simpl.
Simpl in H.
Unfold EqQ in H.
Unfold EqQ.
Unfold 1 numerator.
Unfold 2 denominator.
Unfold 3 numerator.
Unfold 3 denominator.
Cut (`(Zsgn (numerator x1))*((inject_nat (denominator y1))+1)
        *((inject_nat (pred (absolu (numerator x1))))+1)=
      (Zsgn (numerator y1))*((inject_nat (denominator x1))+1)*
   ((inject_nat (pred (absolu (numerator y1))))+1)`).
Intro.
Rewrite <- Zmult_assoc  with x:=(Zsgn (numerator x1)) 
                          y:=`((inject_nat (denominator x1))+1)`
                          z:=`((inject_nat (pred (absolu (numerator
y1))))+1)`.
Rewrite <- Zmult_assoc  with x:=(Zsgn (numerator y1)) 
                          y:=`((inject_nat (denominator y1))+1)`
                          z:=`((inject_nat (pred (absolu (numerator
x1))))+1)`.
Cut (`((inject_nat (denominator x1))+1)*
   ((inject_nat (pred (absolu (numerator y1))))+1)<>0`).
Intro.
Cut (`((inject_nat (denominator y1))+1)*
   ((inject_nat (pred (absolu (numerator x1))))+1)<>0`).
Intro.
Rewrite <- Zmult_assoc  with x:=(Zsgn (numerator x1)) 
                          y:=`((inject_nat (denominator y1))+1)`
                          z:=`((inject_nat (pred (absolu (numerator
x1))))+1)`
                           in H0.
Rewrite <- Zmult_assoc  with x:=(Zsgn (numerator y1)) 
                          y:=`((inject_nat (denominator x1))+1)`
                          z:=`((inject_nat (pred (absolu (numerator
y1))))+1)`
                           in H0.
Exact (Zsgn_5 (numerator x1) (numerator y1) 
       `((inject_nat (denominator y1))+1)*
       ((inject_nat (pred (absolu (numerator x1))))+1)`
       `((inject_nat (denominator x1))+1)*
       ((inject_nat (pred (absolu (numerator y1))))+1)`
       H2 H1 H0).
Apply Zgt_not_eq.
Exact (nat_nat_pos  (denominator y1) (pred (absolu (numerator x1)))).
Apply Zgt_not_eq.
Exact (nat_nat_pos  (denominator x1) (pred (absolu (numerator y1)))).


Rewrite <- Zmult_assoc  with x:=(Zsgn (numerator x1)) 
                          y:=`((inject_nat (denominator y1))+1)`
                          z:=`((inject_nat (pred (absolu (numerator
x1))))+1)`.
                         
Rewrite <- Zmult_assoc  with x:=(Zsgn (numerator y1)) 
                          y:=`((inject_nat (denominator x1))+1)`
                          z:=`((inject_nat (pred (absolu (numerator
y1))))+1)`.
Rewrite Zmult_sym with x:=`((inject_nat (denominator y1))+1)`
                       y:=`((inject_nat (pred (absolu (numerator
x1))))+1)`.
Rewrite Zmult_sym with x:=`((inject_nat (denominator x1))+1)`
                       y:=`((inject_nat (pred (absolu (numerator
y1))))+1)`.
Rewrite Zmult_assoc  with x:=(Zsgn (numerator x1)) 
                          z:=`((inject_nat (denominator y1))+1)`
                          y:=`((inject_nat (pred (absolu (numerator
x1))))+1)`.
Rewrite Zmult_assoc  with x:=(Zsgn (numerator y1)) 
                          z:=`((inject_nat (denominator x1))+1)`
                          y:=`((inject_nat (pred (absolu (numerator
y1))))+1)`.
Change (`(Zsgn (numerator x1))*((inject_nat (pred (absolu (numerator
x1))))+
   (inject_nat (S O)))*((inject_nat (denominator y1))+1) = 
  (Zsgn (numerator y1))*
   ((inject_nat (pred (absolu (numerator y1))))+(inject_nat (S O)))*
   ((inject_nat (denominator x1))+1)`).
Rewrite <- inj_plus with x:=(pred (absolu (numerator x1))) y:=(S O).
Rewrite <- inj_plus with x:=(pred (absolu (numerator y1))) y:=(S O).
Rewrite <- plus_n_Sm.
Rewrite <- plus_n_Sm.
Rewrite <- plus_n_O.
Rewrite <- plus_n_O.
Red in p1.
Simpl in p1.

Cut ((S (pred (absolu (numerator x1))))=(absolu (numerator x1))).
Intro.
Rewrite H0.
Cut ((S (pred (absolu (numerator y1))))=(absolu (numerator y1))).
Intro.
Rewrite H1.
Rewrite <- Zsgn_4 with a:=(numerator x1).
Rewrite <- Zsgn_4 with a:=(numerator y1).
Assumption.
Apply S_predn.
Apply absolu_2.
Apply Q_non_zero.
Red in q1.
Simpl in q1.
Assumption.
Apply S_predn.
Apply absolu_2.
Apply Q_non_zero.
Assumption.
Qed.


Remark Qinv_is_well_defined:(!fun_well_def Q_star Q_star Qinv).
Red.
Exact Qinv_simpl.
Qed.

Remark Qinv_is_extensional:(!fun_strong_ext Q_star Q_star Qinv).
Red.
Intros x y.
Case x.
Intros x1 p1.
Case y.
Intros y1 q1.
Intro.
Simpl.
Simpl in H.
Intro.
Apply H.

Unfold EqQ in H0.
Unfold EqQ.
Unfold 1 numerator.
Unfold 2 denominator.
Unfold 3 numerator.
Unfold 3 denominator.
Cut (`(Zsgn (numerator x1))*((inject_nat (denominator y1))+1)
        *((inject_nat (pred (absolu (numerator x1))))+1)=
      (Zsgn (numerator y1))*((inject_nat (denominator x1))+1)*
   ((inject_nat (pred (absolu (numerator y1))))+1)`).
Intro.
Rewrite <- Zmult_assoc  with x:=(Zsgn (numerator x1)) 
                          y:=`((inject_nat (denominator x1))+1)`
                          z:=`((inject_nat (pred (absolu (numerator
y1))))+1)`.
Rewrite <- Zmult_assoc  with x:=(Zsgn (numerator y1)) 
                          y:=`((inject_nat (denominator y1))+1)`
                          z:=`((inject_nat (pred (absolu (numerator
x1))))+1)`.
Cut (`((inject_nat (denominator x1))+1)*
   ((inject_nat (pred (absolu (numerator y1))))+1)<>0`).
Intro.
Cut (`((inject_nat (denominator y1))+1)*
   ((inject_nat (pred (absolu (numerator x1))))+1)<>0`).
Intro.
Rewrite <- Zmult_assoc  with x:=(Zsgn (numerator x1)) 
                          y:=`((inject_nat (denominator y1))+1)`
                          z:=`((inject_nat (pred (absolu (numerator
x1))))+1)`
                           in H1.
Rewrite <- Zmult_assoc  with x:=(Zsgn (numerator y1)) 
                          y:=`((inject_nat (denominator x1))+1)`
                          z:=`((inject_nat (pred (absolu (numerator
y1))))+1)`
                           in H1.
Exact (Zsgn_5 (numerator x1) (numerator y1) 
       `((inject_nat (denominator y1))+1)*
       ((inject_nat (pred (absolu (numerator x1))))+1)`
       `((inject_nat (denominator x1))+1)*
       ((inject_nat (pred (absolu (numerator y1))))+1)`
       H3 H2 H1).
Apply Zgt_not_eq.
Exact (nat_nat_pos  (denominator y1) (pred (absolu (numerator x1)))).
Apply Zgt_not_eq.
Exact (nat_nat_pos  (denominator x1) (pred (absolu (numerator y1)))).


Rewrite <- Zmult_assoc  with x:=(Zsgn (numerator x1)) 
                          y:=`((inject_nat (denominator y1))+1)`
                          z:=`((inject_nat (pred (absolu (numerator
x1))))+1)`.
                         
Rewrite <- Zmult_assoc  with x:=(Zsgn (numerator y1)) 
                          y:=`((inject_nat (denominator x1))+1)`
                          z:=`((inject_nat (pred (absolu (numerator
y1))))+1)`.
Rewrite Zmult_sym with x:=`((inject_nat (denominator y1))+1)`
                       y:=`((inject_nat (pred (absolu (numerator
x1))))+1)`.
Rewrite Zmult_sym with x:=`((inject_nat (denominator x1))+1)`
                       y:=`((inject_nat (pred (absolu (numerator
y1))))+1)`.
Rewrite Zmult_assoc  with x:=(Zsgn (numerator x1)) 
                          z:=`((inject_nat (denominator y1))+1)`
                          y:=`((inject_nat (pred (absolu (numerator
x1))))+1)`.
Rewrite Zmult_assoc  with x:=(Zsgn (numerator y1)) 
                          z:=`((inject_nat (denominator x1))+1)`
                          y:=`((inject_nat (pred (absolu (numerator
y1))))+1)`.
Change (`(Zsgn (numerator x1))*((inject_nat (pred (absolu (numerator
x1))))+
   (inject_nat (S O)))*((inject_nat (denominator y1))+1) = 
  (Zsgn (numerator y1))*
   ((inject_nat (pred (absolu (numerator y1))))+(inject_nat (S O)))*
   ((inject_nat (denominator x1))+1)`).
Rewrite <- inj_plus with x:=(pred (absolu (numerator x1))) y:=(S O).
Rewrite <- inj_plus with x:=(pred (absolu (numerator y1))) y:=(S O).
Rewrite <- plus_n_Sm.
Rewrite <- plus_n_Sm.
Rewrite <- plus_n_O.
Rewrite <- plus_n_O.
Red in p1.
Simpl in p1.

Cut ((S (pred (absolu (numerator x1))))=(absolu (numerator x1))).
Intro.
Rewrite H1.
Cut ((S (pred (absolu (numerator y1))))=(absolu (numerator y1))).
Intro.
Rewrite H2.
Rewrite <- Zsgn_4 with a:=(numerator x1).
Rewrite <- Zsgn_4 with a:=(numerator y1).
Assumption.
Apply S_predn.
Apply absolu_2.
Apply Q_non_zero.
Red in q1.
Simpl in q1.
Assumption.
Apply S_predn.
Apply absolu_2.
Apply Q_non_zero.
Assumption.
Qed.

Definition Qinv_is_fun :=(!Build_CSetoid_fun Q_star Q_star Qinv 
  Qinv_is_well_defined Qinv_is_extensional) : (CSetoid_un_op 
(NonZeros Q_as_CRing)).

Remark Q_is_CField:(!is_CField Q_as_CRing Qinv_is_fun).
Red.
Intro.
Unfold is_inverse.
Case x.
Intros x1 p1.
Simpl.
Unfold Qmult.
Red.
Unfold 1 numerator.
Unfold 2 numerator.
Unfold ONEQ.
Unfold 2 denominator. 
Unfold 3 numerator.
Unfold 2 denominator.
Unfold 3 denominator.
Unfold 4 denominator.
Rewrite Zmult_1_n.
Unfold 2 inject_nat.
Rewrite Zero_left.
Rewrite Zmult_n_1.
Rewrite inj_plus.
Rewrite inj_mult.
Rewrite inj_plus.
Rewrite <- Zmult_1_n with n:=`(inject_nat (denominator x1))*
   (inject_nat (pred (absolu (numerator x1))))+
   ((inject_nat (denominator x1))+
   (inject_nat (pred (absolu (numerator x1)))))+1`.
Rewrite Zmult_assoc.
Rewrite Zmult_sym with x:=(numerator x1)
                       y:=(Zsgn (numerator x1)).
Rewrite <- Zmult_assoc.
Cut (`1*((numerator x1)*((inject_nat (denominator x1))+1))=
      (Zsgn (numerator x1))* ((inject_nat (denominator x1))*
   (inject_nat (pred (absolu (numerator x1))))+
   ((inject_nat (denominator x1))+
   (inject_nat (pred (absolu (numerator x1)))))+1)`).
Intro.
Apply sym_eq.
Cut (`1=(Zsgn 1)`).
Intro.
Rewrite H0 in H.
Rewrite H0.
Apply Zsgn_5.
Unfold Zsgn.
Simpl.
Intro.
Cut (`(numerator x1)<>0`).Intro.
Cut (`((inject_nat (denominator x1))+1)<>0`). 
Intro.
Apply H2.
Apply Zmult_eq with x:=`((inject_nat (denominator x1))+1)`.
Assumption.
Assumption.
Apply Zgt_not_eq.
Change (`(Zs (inject_nat (denominator x1)))>0`).
Rewrite <- inj_S.
Change (`(inject_nat (S (denominator x1))) > (inject_nat O)`).
Apply inj_gt.
Apply gt_Sn_O.
Red in p1.
Simpl in p1.
Apply Q_non_zero.
Assumption.
Unfold Zsgn.
Simpl.
Apply Zgt_not_eq.
Rewrite <- inj_mult.
Rewrite <- inj_plus.
Rewrite <- inj_plus.
Change ( `(Zs (inject_nat
    (plus (mult (denominator x1) (pred (absolu (numerator x1))))
    (plus (denominator x1) (pred (absolu (numerator x1)))))))
 > (inject_nat O)`).
Rewrite <- inj_S.
Apply inj_gt.
Apply gt_Sn_O.
Assumption.
Unfold Zsgn.
Simpl.
Trivial.


Rewrite Zmult_1_n.
Rewrite Zplus_assoc.
Rewrite <- Zplus_assoc.
Rewrite Zred_factor3 with x:=(inject_nat (denominator x1)).
Rewrite Zplus_sym with x:=`1`.
Change ( `(numerator x1)*(Zs (inject_nat (denominator x1)))
   = (Zsgn (numerator x1))*((inject_nat (denominator x1))*
   (Zs (inject_nat (pred (absolu (numerator x1)))))+
   (Zs (inject_nat (pred (absolu (numerator x1))))))`).
Rewrite Zmult_Sm_n.
Rewrite Zmult_sym with x:=(Zs (inject_nat (denominator x1))).
Rewrite Zmult_assoc.
Rewrite <- inj_S.
Rewrite <- inj_S.
Cut ((S (pred (absolu (numerator x1))))=(absolu (numerator x1))).
Intro.
Rewrite H.
Rewrite <- Zsgn_4 with a:=(numerator x1).
Trivial.
Apply S_predn.
Apply absolu_2.
Apply Q_non_zero.
Assumption.
Qed.

Definition Q_as_CField:=(!Build_CField Q_as_CRing Qinv_is_fun
Q_is_CField).


