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

Require Export QArith.
Require Export Peano_dec.
Require Export Relations.
Require Export CRings.


(* Summary:
 1- <nat, plus, O> (Inductive Natural Numbers) is CSemi_grp.
 2- <Z, Zplus , ZERO, Zopp, Zmult, ONEZ> (Integers as defined in ZArith) is 
	CRing.
 3- <Q, Qplus, ZEROQ, Qopp, Qmult, ONEQ> (rationals as defined in QArith) is 
	CRing.
*) 



Definition ap_nat := [x,y:nat](~(eq nat x y)).

Remark ap_nat1: (!irreflexive nat ap_nat).
Red.
Intros.
Unfold ap_nat.
Red.
Intros.
Cut (x=x).
Intro.
Apply H.
Assumption.
Constructor 1.
Qed.


Remark ap_nat2: (!symmetric nat ap_nat).
Red.
Intros x y.
Unfold ap_nat.
Intros.
Red.
Intro.
Cut (x=y).
Intro.
Apply H.
Assumption.
Rewrite H0.
Reflexivity.
Qed.


Remark ap_nat3: (!cotransitive nat ap_nat).
Red.
Intros. 
Unfold ap_nat.
Case (eq_nat_dec x z).
Intro.
Right.
Rewrite <- e.
Assumption.
Intro.
Left.
Assumption.
Qed.


Remark ap_nat4 :(!tight_apart  nat (eq nat) ap_nat). 
Red.
Intros x y.
Red.
Split.
Unfold ap_nat.
Intro.
Case (eq_nat_dec x y).
Intro.
Assumption.
Intro.
Apply False_ind.
Apply H.
Assumption.
Intro.
Unfold ap_nat.
Red.
Intro.
Apply H0.
Assumption.
Qed.

Definition ap_nat_is_apartness := (!Build_is_CSetoid nat (eq nat) ap_nat
ap_nat1 ap_nat2 ap_nat3 ap_nat4).

Definition nat_as_CSetoid := (!Build_CSetoid nat (eq nat) ap_nat
ap_nat_is_apartness).

    (* NOW INTEGERS *)

Definition ap_Z := [x,y: Z](~ (eq Z x y)).

Remark ap_Z1 : (!irreflexive Z ap_Z).
Red.
Intros.
Unfold ap_Z.
Red.
Intro.
Cut (eq Z x x).
Assumption.
Trivial.
Qed.

Remark ap_Z2: (!symmetric Z ap_Z).
Red.
Intros.
Unfold ap_Z.
Red.
Intros.
Cut (eq Z x y).
Assumption.
Rewrite H0.
Reflexivity.    
Qed.

Remark ap_Z3 : (!cotransitive Z ap_Z).
Red.
Intros.
Unfold ap_Z.
Case (dec_eq x z).
Intro.
Right.
Rewrite <- H0.
Assumption.
Intro.
Left.
Assumption.
Qed.

Remark ap_Z4 : (!tight_apart Z (eq Z) ap_Z).
Red.
Intros x y.
Red.
Split.
Unfold ap_Z.
Intro.
Case (dec_eq x y).
Intro.
Assumption.
Intro.
Apply False_ind.
Apply H.
Assumption.
Intro.
Unfold ap_Z.
Red.
Intro.
Apply H0.
Assumption.
Qed.

Definition ap_Z_is_apartness := (!Build_is_CSetoid Z (eq Z) ap_Z ap_Z1 
  ap_Z2 ap_Z3 ap_Z4).

Definition Z_as_CSetoid := (!Build_CSetoid Z (eq Z) ap_Z
ap_Z_is_apartness).


   (* NOW RATIONALS *)

Definition ap_Q := [x,y: Q](~ (EqQ x y)).

Remark ap_Q1: (!irreflexive Q ap_Q).
Red.
Intros.
Unfold ap_Q.
Red.
Intro.
Cut (EqQ x x).
Assumption.
Unfold EqQ.
Trivial.
Qed.


Remark ap_Q2 :(!symmetric Q ap_Q).
Red.
Intros.
Unfold ap_Q.
Red.
Intros.
Cut (EqQ x y).
Assumption.
Apply sym_equalQ.
Assumption.
Qed.


Remark ap_Q3 :(!cotransitive Q ap_Q).
Red.
Intros.
Unfold ap_Q.
Case (dec_EqQ x z).
Intro.
Right.
Red.
Intro.
Cut (EqQ x y).
Intro.
Apply H.
Assumption.
Exact (trans_equalQ x z y H0 H1).
Intro.
Left.
Assumption.
Qed.

Remark ap_Q4 : (!tight_apart Q EqQ ap_Q).
Red.
Intros.
Red.
Split.
Unfold ap_Q.
Intro.
Case (dec_EqQ x y).
Intro.
Assumption.
Intro.
Apply False_ind.
Apply H.
Assumption.
Intro.
Unfold ap_Q.
Red.
Intro.
Apply H0.
Assumption.
Qed.

Definition ap_Q_is_apartness := (!Build_is_CSetoid Q EqQ ap_Q ap_Q1
ap_Q2
ap_Q3 ap_Q4).

Definition Q_as_CSetoid := (!Build_CSetoid Q EqQ ap_Q ap_Q_is_apartness).

(* defining monoid operations *)

Remark plus_is_well_defined:(bin_fun_well_def nat_as_CSetoid 
nat_as_CSetoid nat_as_CSetoid plus).
Red.
Intros.
Simpl.
Simpl in H.
Simpl in H0.
Auto.
Qed.

Remark plus_is_extensional:(bin_fun_strong_ext nat_as_CSetoid
nat_as_CSetoid 
nat_as_CSetoid plus).
Red.
Intros.
Simpl.
Simpl in H.
Unfold ap_nat.
Unfold ap_nat in H.
Case (eq_nat_dec x1 x2).
Intro.
Right.
Red.
Intro.
Exact (H (f_equal2 nat nat nat plus x1 x2 y1 y2 e H0)).
Intro.
Left.
Assumption.
Qed.

Definition plus_is_bin_fun:= (!Build_CSetoid_bin_fun nat_as_CSetoid 
nat_as_CSetoid nat_as_CSetoid plus plus_is_well_defined
plus_is_extensional).  


Remark plus_is_assoc : (Associative plus_is_bin_fun).
Red.
Intros x y z.
Simpl.
Apply (plus_assoc_l).
Qed.

(* Definition plus_is_assoc_opern := (!Build_CSetoid_assoc_opern
nat_as_CSetoid 
  plus_is_bin_fun plus_is_assoc).
*)

  

(* SO ADDITION IS AN ASSOCIATIVE OPERATION ON SETOID OF NATURAL
NUMBERS! *)

Remark Zplus_is_well_defined : (bin_fun_well_def Z_as_CSetoid Z_as_CSetoid
 Z_as_CSetoid Zplus).
Red.
Intros.
Simpl.
Simpl in H.
Simpl in H0.
Apply (Zplus_simpl x1 x2 y1 y2).  (* Here we use fast_integer *)
Assumption.
Assumption.
Qed.


Remark Zplus_is_extensional :(bin_fun_strong_ext Z_as_CSetoid Z_as_CSetoid
                Z_as_CSetoid Zplus).
Red.
Intros.
Simpl.
Simpl in H.
Unfold ap_Z.
Unfold ap_Z in H.
Case (dec_eq x1 x2).    (* using auxiliary *)
Intro.
Right.
Red.
Intro.
Exact (H (f_equal2 Z Z Z Zplus x1 x2 y1 y2 H0 H1)).
Intro.
Left.
Assumption.
Qed.

Definition Zplus_is_bin_fun := (!Build_CSetoid_bin_fun Z_as_CSetoid 
Z_as_CSetoid Z_as_CSetoid Zplus Zplus_is_well_defined
Zplus_is_extensional).

Remark Zplus_is_assoc : (associative Z_as_CSetoid Zplus_is_bin_fun).
Red.
Intros x y z.
Simpl.
Apply (Zplus_assoc).   (* using fast_integer *)
Qed.

(*
Definition Zplus_is_assoc_opern := (!Build_CSetoid_assoc_opern
Z_as_CSetoid 
Zplus_is_bin_fun Zplus_is_assoc).
*)

(* ALSO ADDITION IS ASSOCIATIVE ON INTEGERS *)

Remark Qplus_is_well_defined : (bin_fun_well_def Q_as_CSetoid Q_as_CSetoid
 Q_as_CSetoid Qplus).
Red.
Simpl.
Intros.
Exact (Qplus_simpl x1 x2 y1 y2 H H0).
Qed.

Remark Qplus_is_extensional :(bin_fun_strong_ext Q_as_CSetoid Q_as_CSetoid 
                              Q_as_CSetoid Qplus).
Red.
Simpl.
Unfold ap_Q.
Intros.
Case (dec_EqQ x1 x2).
Intro.
Right.
Red.
Intro.
Exact (H (Qplus_simpl x1 x2 y1 y2 H0 H1)).
Intro.
Left.
Assumption.
Qed.

Definition Qplus_is_bin_fun :=(!Build_CSetoid_bin_fun Q_as_CSetoid 
Q_as_CSetoid Q_as_CSetoid Qplus Qplus_is_well_defined
Qplus_is_extensional).

Remark Qplus_is_assoc : (associative Q_as_CSetoid Qplus_is_bin_fun).
Red.
Intros x y z.
Simpl.
Exact (Qplus_assoc x y z).
Qed.

(*
Definition Qplus_is_assoc_opern := (!Build_CSetoid_assoc_opern
Q_as_CSetoid 
Qplus_is_bin_fun Qplus_is_assoc).
*)

(* AND THUS ADDITION IS ASSOCIATIVE ON RATIONALS *)


Definition nat_as_CSemi_grp := (!Build_CSemi_grp nat_as_CSetoid O 
plus_is_bin_fun plus_is_assoc). 

Definition Z_as_CSemi_grp := (!Build_CSemi_grp Z_as_CSetoid ZERO 
 Zplus_is_bin_fun Zplus_is_assoc).

Definition Q_as_CSemi_grp := (!Build_CSemi_grp Q_as_CSetoid ZEROQ 
Qplus_is_bin_fun Qplus_is_assoc).


Remark O_as_rht_unit :( !is_rht_unit nat_as_CSetoid plus_is_bin_fun O).
Red.
Simpl.
Auto.
Qed.

Remark plus_is_commut : (commutes nat_as_CSetoid plus_is_bin_fun). 
Red.
Simpl.
Exact plus_sym.  (* Plus.g *)
Qed.


Definition nat_is_CMonoid := (!Build_is_CMonoid nat_as_CSemi_grp
O_as_rht_unit
                         plus_is_commut).  


Definition nat_as_CMonoid := (!Build_CMonoid nat_as_CSemi_grp
nat_is_CMonoid). 

Remark ZERO_as_rht_unit : (!is_rht_unit Z_as_CSetoid Zplus_is_bin_fun
ZERO).
Red.
Simpl.
Exact Zero_right.   (* using first_integer *)
Qed.

Remark Zplus_is_commut : (commutes Z_as_CSetoid Zplus_is_bin_fun).
Red.
Simpl.
Exact Zplus_sym.  (* using first_integer *)
Qed.

Definition Z_is_CMonoid := (!Build_is_CMonoid Z_as_CSemi_grp
ZERO_as_rht_unit 
           Zplus_is_commut).

Definition Z_as_CMonoid := (!Build_CMonoid Z_as_CSemi_grp Z_is_CMonoid).

Remark ZEROQ_as_rht_unit : (!is_rht_unit Q_as_CSetoid Qplus_is_bin_fun
ZEROQ).
Red.
Simpl.
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.

Remark Qplus_is_commut : (commutes Q_as_CSetoid Qplus_is_bin_fun).
Red.
Simpl.
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.

Definition Q_is_CMonoid :=(!Build_is_CMonoid Q_as_CSemi_grp
ZEROQ_as_rht_unit 
Qplus_is_commut).

Definition Q_as_CMonoid := (!Build_CMonoid Q_as_CSemi_grp Q_is_CMonoid).


Remark  Zopp_is_well_defined :(!fun_well_def Z_as_CSetoid Z_as_CSetoid
Zopp).
Red.
Simpl.
Intros.
Apply (f_equal Z Z Zopp x y H).
Qed.

Remark Zopp_is_extensional :(!fun_strong_ext Z_as_CSetoid Z_as_CSetoid
Zopp).
Red.
Simpl.
Unfold ap_Z.
Intros.
Intro.
Exact (H (f_equal Z Z Zopp x y H0)).
Qed.

Definition Zopp_is_fun :=(!Build_CSetoid_fun Z_as_CSetoid Z_as_CSetoid
Zopp 
Zopp_is_well_defined Zopp_is_extensional).



Remark Z_is_CGroup :(!is_CGroup Z_as_CMonoid Zopp_is_fun). 
Red.
Simpl.
Exact Zplus_inverse_r.   (* using fast_integer *)
Qed.

Definition Z_as_CGroup :=(!Build_CGroup Z_as_CMonoid Zopp_is_fun
Z_is_CGroup).

Remark Qopp_is_well_defined:(!fun_well_def Q_as_CSetoid Q_as_CSetoid
Qopp).
Red.
Simpl.
Intros.
Exact (Qopp_simpl x y H).
Qed.

Remark Qopp_is_extensional :(!fun_strong_ext Q_as_CSetoid Q_as_CSetoid
Qopp).
Red.
Simpl.
Unfold ap_Q.
Intros.
Red.
Intro.
Apply H.
Exact (Qopp_simpl x y H0).
Qed.

Definition Qopp_is_fun := (!Build_CSetoid_fun Q_as_CSetoid Q_as_CSetoid
Qopp 
Qopp_is_well_defined Qopp_is_extensional).

Remark Q_is_CGroup :(!is_CGroup Q_as_CMonoid Qopp_is_fun).
Red.
Simpl.
Exact Qplus_inverse_r.
Qed.

Definition Q_as_CGroup :=(!Build_CGroup Q_as_CMonoid Qopp_is_fun
Q_is_CGroup).



Remark Zmult_is_well_defined :(bin_fun_well_def Z_as_CSetoid Z_as_CSetoid 
Z_as_CSetoid Zmult).
Red.
Simpl.
Intros.
Apply (f_equal2 Z Z Z Zmult x1 x2 y1 y2).
Assumption.
Assumption.
Qed.

Remark Zmult_is_extensional :(bin_fun_strong_ext Z_as_CSetoid Z_as_CSetoid 
Z_as_CSetoid Zmult).
Red.
Simpl.
Unfold ap_Z.
Intros.
Case (dec_eq x1 x2).     (* using auxiliary *)
Intro.
Right.
Red.
Intro.
Exact (H (f_equal2 Z Z Z Zmult x1 x2 y1 y2 H0 H1)).
Intro.
Left.
Assumption.
Qed.

Definition Zmult_is_bin_fun:= (!Build_CSetoid_bin_fun Z_as_CSetoid 
Z_as_CSetoid Z_as_CSetoid Zmult Zmult_is_well_defined
Zmult_is_extensional).

Remark Zmult_is_assoc : (associative Z_as_CSetoid Zmult_is_bin_fun).
Red.
Intros x y z.
Simpl.
Apply (Zmult_assoc_l).     (* using zarith_aux *)
Qed.

(*
Definition Zmult_is_assoc_opern := (!Build_CSetoid_assoc_opern
Z_as_CSetoid 
Zmult_is_bin_fun Zmult_is_assoc).
*)

Definition Z_mul_as_CSemi_grp := (!Build_CSemi_grp Z_as_CSetoid (POS xH)
Zmult_is_bin_fun Zmult_is_assoc).


Remark ONE_as_rht_unit: (!is_rht_unit Z_as_CSetoid Zmult_is_bin_fun 
(POS xH)).
Red.
Simpl.
Exact Zmult_n_1.    (* using zarith_aux *)
Qed.

Remark Zmult_is_commut : (commutes Z_as_CSetoid Zmult_is_bin_fun).
Red.
Simpl.
Exact Zmult_sym.      (* using fast_integer *)
Qed.

Definition Z_mul_is_CMonoid :=(!Build_is_CMonoid Z_mul_as_CSemi_grp 
ONE_as_rht_unit Zmult_is_commut). 

Definition Z_mul_as_CMonoid :=(!Build_CMonoid Z_mul_as_CSemi_grp 
Z_mul_is_CMonoid).

(*
Remark Zmul_is_cmonoid :(is_CMonoid (Build_CSemi_grp Z_as_CSetoid (POS xH)
Zmult_is_assoc_opern)).
Unfold is_CMonoid.
Exact Z_mul_as_CMonoid.
Qed.
*)

Remark Z_mult_plus_is_dist : (Distributive Zmult_is_bin_fun Zplus_is_bin_fun). 
Red.
Simpl.
Exact Zmult_plus_distr_r.   (* using fast_integer *)
Qed.



Remark ONE_neq_O : (ap_Z (POS xH) ZERO).
Apply ap_Z2.
Red.
Apply Zlt_not_eq.  (* using zmisc *)
Apply Zgt_lt.     (* using zarith_aux *)
Exact (POS_gt_ZERO xH).
Qed.


Definition Z_is_CRing:=(!Build_is_CRing Z_as_CGroup (POS xH) Zmult_is_bin_fun 
Zmult_is_assoc Z_mul_is_CMonoid Z_mult_plus_is_dist ONE_neq_O).

Definition Z_as_CRing := (!Build_CRing Z_as_CGroup (POS xH) 
Zmult_is_bin_fun Z_is_CRing). 


Remark Qmult_is_well_defined:(bin_fun_well_def Q_as_CSetoid Q_as_CSetoid
Q_as_CSetoid Qmult).
Red.
Simpl.
Intros.
Apply (Qmult_simpl).
Assumption.
Assumption.
Qed.

Remark Qmult_is_extensional :(bin_fun_strong_ext Q_as_CSetoid Q_as_CSetoid 
Q_as_CSetoid Qmult).
Red.
Simpl.
Unfold ap_Q.
Intros.
Case (dec_EqQ x1 x2).
Intro.
Right.
Red.
Intro.
Apply H.
Exact (Qmult_simpl x1 x2 y1 y2 H0 H1).
Intro.
Left.
Assumption.
Qed.

Definition Qmult_is_bin_fun:=(!Build_CSetoid_bin_fun Q_as_CSetoid
Q_as_CSetoid
Q_as_CSetoid Qmult Qmult_is_well_defined Qmult_is_extensional).

Remark Qmult_is_assoc : (associative Q_as_CSetoid Qmult_is_bin_fun).
Red.
Intros x y z.
Simpl.
Apply (Qmult_assoc).
Qed.

(*
Definition Qmult_is_assoc_opern := (!Build_CSetoid_assoc_opern
Q_as_CSetoid 
Qmult_is_bin_fun Qmult_is_assoc). 
*)

Definition Q_mul_as_CSemi_grp :=(!Build_CSemi_grp Q_as_CSetoid ONEQ 
Qmult_is_bin_fun Qmult_is_assoc).

Remark ONEQ_as_rht_unit :(!is_rht_unit Q_as_CSetoid Qmult_is_bin_fun
ONEQ).
Red.
Simpl.
Exact Qmult_n_1.
Qed.

Remark Qmult_is_commut : (commutes Q_as_CSetoid Qmult_is_bin_fun).
Red.
Simpl.
Exact Qmult_sym.
Qed.

Definition Q_mul_is_CMonoid :=(!Build_is_CMonoid Q_mul_as_CSemi_grp 
ONEQ_as_rht_unit Qmult_is_commut). 

Definition Q_mul_as_CMonoid :=(!Build_CMonoid Q_mul_as_CSemi_grp
Q_mul_is_CMonoid).

Remark Q_mult_plus_is_dist :(Distributive Qmult_is_bin_fun 
Qplus_is_bin_fun).
Red.
Simpl.
Exact Qmult_plus_distr_r.
Qed.

Definition Q_is_CRing :=(!Build_is_CRing Q_as_CGroup ONEQ
Qmult_is_bin_fun Qmult_is_assoc Q_mul_is_CMonoid Q_mult_plus_is_dist 
ONEQ_neq_ZEROQ). 

Definition Q_as_CRing :=(!Build_CRing Q_as_CGroup ONEQ
Qmult_is_bin_fun Q_is_CRing).


(* Omitted after the file CIntDomains was removed from the directory *)

(*


Remark  Z_is_CIntDom : (is_CIntDom Z_as_CRing).
Red.
Simpl.
Unfold ap_Z.
Intros x y.
Intros.
Intro.
Cut (y=`0`).
Assumption.
Cut (`y*x=0`).
Intro.
Exact ((Zmult_eq x y H H2)).   (* using auxiliary *)
Cut (`y*x=x*y`). 
Intro.
Rewrite H2.
Assumption.
Apply Zmult_sym.
Qed.

Definition Z_as_CIntDom := (!Build_CIntDom Z_as_CRing
Z_is_CIntDom).

*)