(* (c) Copyright 2006-2016 Microsoft Corporation and Inria.                  *)
(* Distributed under the terms of CeCILL-B.                                  *)
From mathcomp
From mathcomp
(******************************************************************************)
(*          This file describes quotients of algebraic structures.            *)
(*                                                                            *)
(* It defines a  join hierarchy mxing the structures defined  in file ssralg  *)
(* (up to  unit ring type)  and the  quotType quotient structure  defined in  *)
(* file  generic_quotient.   Every structure  in  that  (join) hierarchy  is  *)
(* parametrized by  a base type  T and the  constants and operations  on the  *)
(* base type  that will  be used  to confer its  algebraic structure  to the  *)
(* quotient.  Note  that T  itself  is  in general  not  an  instance of  an  *)
(* algebraic structure.  The  canonical surjection from T  onto its quotient  *)
(* should be compatible with the parameter operations.                        *)
(*                                                                            *)
(* The  second part  of  the file  provides a  definition  of (non  trivial)  *)
(* decidable ideals  (resp. prime ideals)  of an arbitrary instance  of ring  *)
(* structure and a construction of the quotient  of a ring by such an ideal.  *)
(* These definitions extend the hierarchy  of sub-structures defined in file  *)
(* ssralg (see Module Pred in ssralg), following a similar methodology.       *)
(* Although the definition of the (structure of) quotient of a ring by an     *)
(* ideal is a general one, we do not provide infrastructure for the case of   *)
(* non commutative ring and left or two-sided ideals.                         *)
(*                                                                            *)
(* The file defines the following Structures:                                 *)
(* zmodQuotType T e z n a     == Z-module  obtained  by  quotienting type  T  *)
(*                               with  the  relation  e  and  whose neutral,  *)
(*                               opposite and addition are the images in the  *)
(*                               quotient  of  the  parameters  z,  n and a,  *)
(*                               respectively.                                *)
(* ringQuotType T e z n a o m == ring  obtained  by quotienting  type T with  *)
(*                               the relation e  and  whose zero opposite,    *)
(*                               addition, one, and multiplication are  the   *)
(*                               images  in  the  quotient  of the parameters *)
(*                               z, n, a, o, m, respectively.                 *)
(*   unitRingQuotType ... u i == As in the previous cases, instance of unit   *)
(*                               ring whose unit predicate  is obtained from  *)
(*                               u and the inverse from i.                    *)
(*                 idealr R S == (S : pred R) is a non-trivial, decidable,    *)
(*                               right ideal of the ring R.                   *)
(*           prime_idealr R S == (S : pred R) is a non-trivial, decidable,    *)
(*                               right, prime ideal of the ring R.            *)
(*                                                                            *)
(* The formalization of ideals features the following constructions:          *)
(*       proper_ideal S == the  collective predicate (S : pred R) on the      *)
(*                             ring R is stable by the ring product and does  *)
(*                             contain R's one.                               *)
(*   prime_idealr_closed S  := u * v \in S -> (u \in S) || (v \in S)          *)
(*          idealr_closed S == the collective predicate (S : pred R) on the   *)
(*                             ring  R  represents  a  (right) ideal.  This   *)
(*                             implies its being a proper_ideal.              *)
(*                                                                            *)
(*           MkIdeal idealS == packs   idealS : proper_ideal S   into  an     *)
(*                             idealr S  interface structure  associating the *)
(*                             idealr_closed   property   to  the   canonical *)
(*                             pred_key S  (see ssrbool), which  must already *)
(*                             be an zmodPred (see ssralg).                   *)
(*     MkPrimeIdeal pidealS == packs  pidealS : prime_idealr_closed S  into a *)
(*                             prime_idealr S interface structure associating *)
(*                             the  prime_idealr_closed   property   to   the *)
(*                             canonical pred_key S (see ssrbool), which must *)
(*                             already be an idealr (see above).              *)
(*          {ideal_quot kI} == quotient by the keyed (right) ideal predicate  *)
(*                             kI of a commutative ring R. Note that we indeed*)
(*                             only provide canonical structures of ring      *)
(*                             quotients for the case of commutative rings,   *)
(*                             for which a right ideal is obviously a         *)
(*                             two-sided ideal.                               *)
(*                                                                            *)
(* Note :                                                                     *)
(* if (I : pred R) is a predicate over a ring R and (ideal : idealr I) is an  *)
(* instance of (right) ideal, in order to quantify over an arbitrary (keyed)  *)
(* predicate describing  ideal, use  type (keyed_pred  ideal), as  in:        *)
(*     forall (kI : keyed_pred ideal),...                                     *)
(******************************************************************************)
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Local Open Scope ring_scope.
Local Open Scope quotient_scope.
Reserved Notation "{ideal_quot I }" (at level 0, format "{ideal_quot  I }").
Reserved Notation "m = n %[mod_ideal I ]" (at level 70, n at next level,
format "'[hv ' m '/'  =  n '/'  %[mod_ideal  I ] ']'").
Reserved Notation "m == n %[mod_ideal I ]" (at level 70, n at next level,
format "'[hv ' m '/'  ==  n '/'  %[mod_ideal  I ] ']'").
Reserved Notation "m <> n %[mod_ideal I ]" (at level 70, n at next level,
format "'[hv ' m '/'  <>  n '/'  %[mod_ideal  I ] ']'").
Reserved Notation "m != n %[mod_ideal I ]" (at level 70, n at next level,
format "'[hv ' m '/'  !=  n '/'  %[mod_ideal  I ] ']'").
Section ZmodQuot.
Variable (T : Type).
Variable eqT : rel T.
Variables (zeroT : T) (oppT : T -> T) (addT : T -> T -> T).
Record zmod_quot_mixin_of (Q : Type) (qc : quot_class_of T Q)
(zc : GRing.Zmodule.class_of Q) := ZmodQuotMixinPack {
zmod_eq_quot_mixin :> eq_quot_mixin_of eqT qc zc;
_ : \pi_(QuotTypePack qc) zeroT = 0 :> GRing.Zmodule.Pack zc;
_ : {morph \pi_(QuotTypePack qc) : x /
oppT x >-> @GRing.opp (GRing.Zmodule.Pack zc) x};
_ : {morph \pi_(QuotTypePack qc) : x y /
addT x y >-> @GRing.add (GRing.Zmodule.Pack zc) x y}
}.
Record zmod_quot_class_of (Q : Type) : Type := ZmodQuotClass {
zmod_quot_quot_class :> quot_class_of T Q;
zmod_quot_zmod_class :> GRing.Zmodule.class_of Q;
zmod_quot_mixin :> zmod_quot_mixin_of
zmod_quot_quot_class zmod_quot_zmod_class
}.
Structure zmodQuotType : Type := ZmodQuotTypePack {
zmod_quot_sort :> Type;
_ : zmod_quot_class_of zmod_quot_sort;
}.
Implicit Type zqT : zmodQuotType.
Definition zmod_quot_class zqT : zmod_quot_class_of zqT :=
let: ZmodQuotTypePack _ cT as qT' := zqT return zmod_quot_class_of qT' in cT.
Definition zmod_eq_quot_class zqT (zqc : zmod_quot_class_of zqT) :
eq_quot_class_of eqT zqT := EqQuotClass zqc.
Canonical zmodQuotType_eqType zqT := Equality.Pack (zmod_quot_class zqT).
Canonical zmodQuotType_choiceType zqT :=
Choice.Pack (zmod_quot_class zqT).
Canonical zmodQuotType_zmodType zqT :=
GRing.Zmodule.Pack (zmod_quot_class zqT).
Canonical zmodQuotType_quotType zqT := QuotTypePack (zmod_quot_class zqT).
Canonical zmodQuotType_eqQuotType zqT := EqQuotTypePack
(zmod_eq_quot_class (zmod_quot_class zqT)).
Coercion zmodQuotType_eqType : zmodQuotType >-> eqType.
Coercion zmodQuotType_choiceType : zmodQuotType >-> choiceType.
Coercion zmodQuotType_zmodType : zmodQuotType >-> zmodType.
Coercion zmodQuotType_quotType : zmodQuotType >-> quotType.
Coercion zmodQuotType_eqQuotType : zmodQuotType >-> eqQuotType.
Definition ZmodQuotType_pack Q :=
fun (qT : quotType T) (zT : zmodType) qc zc
of phant_id (quot_class qT) qc & phant_id (GRing.Zmodule.class zT) zc =>
fun m => ZmodQuotTypePack (@ZmodQuotClass Q qc zc m).
Definition ZmodQuotMixin_pack Q :=
fun (qT : eqQuotType eqT) (qc : eq_quot_class_of eqT Q)
of phant_id (eq_quot_class qT) qc =>
fun (zT : zmodType) zc of phant_id (GRing.Zmodule.class zT) zc =>
fun e m0 mN mD => @ZmodQuotMixinPack Q qc zc e m0 mN mD.
Definition ZmodQuotType_clone (Q : Type) qT cT
of phant_id (zmod_quot_class qT) cT := @ZmodQuotTypePack Q cT.

Lemma zmod_quot_mixinP zqT :
zmod_quot_mixin_of (zmod_quot_class zqT) (zmod_quot_class zqT).