(Joint Center)Library MathComp.finalg

(* (c) Copyright Microsoft Corporation and Inria.                       
 You may distribute this file under the terms of the CeCILL-B license *)

Require Import ssreflect ssrfun ssrbool eqtype ssrnat seq choice fintype.
Require Import ssralg finset fingroup morphism perm action.

This file clones the entire ssralg hierachy for finite types; this allows type inference to function properly on expressions that mix combinatorial and algebraic operators (e.g., [set x + y | x in A, y in A]). finZmodType, finRingType, finComRingType, finUnitRingType, finComUnitRingType, finIdomType, finFieldType finLmodType, finLalgType finAlgType finUnitAlgType == the finite counterparts of zmodType, etc. Note that a finFieldType is canonically decidable. All these structures can be derived using [xxxType of T] forms, e.g., if R has both canonical finType and ringType structures, then Canonical R_finRingType := Eval hnf in [finRingType of R]. declares the derived finRingType structure for R. As the implementation of the derivation is somewhat involved, the Eval hnf normalization is strongly recommended. This file also provides direct tie-ins with finite group theory: [baseFinGroupType of R for +%R] == the (canonical) additive group [finGroupType of R for +%R] structures for R {unit R} == the type of units of R, which has a canonical group structure. FinRing.unit R Ux == the element of {unit R} corresponding to x, where Ux : x \in GRing.unit. 'U%act == the action by right multiplication of {unit R} on R, via FinRing.unit_act. (This is also a group action.)

Local Open Scope ring_scope.

Set Implicit Arguments.

Module FinRing.

Local Notation mixin_of T b := (Finite.mixin_of (EqType T b)).

Section Generic.

Implicits
Variables (type base_type : Type) (class_of base_of : TypeType).
Variable to_choice : T, base_of TChoice.class_of T.
Variable base_sort : base_typeType.

Explicits
Variable Pack : T, class_of TTypetype.
Variable Class : T b, mixin_of T (to_choice b) → class_of T.
Variable base_class : bT, base_of (base_sort bT).

Definition gen_pack T :=
  fun bT b & phant_id (base_class bT) b
  fun fT m & phant_id (Finite.class fT) (Finite.Class m) ⇒
  Pack (@Class T b m) T.

End Generic.

Implicit Arguments
  gen_pack [type base_type class_of base_of to_choice base_sort].
Local Notation fin_ c := (@Finite.Class _ c c).
Local Notation do_pack pack T := (pack T _ _ id _ _ id).
Import GRing.Theory.

Definition groupMixin V := FinGroup.Mixin (@addrA V) (@add0r V) (@addNr V).
Local Notation base_group T vT fT :=
  (@FinGroup.PackBase T (groupMixin vT) (Finite.class fT)).
Local Notation fin_group B V := (@FinGroup.Pack B (@addNr V)).

Module Zmodule.

Section ClassDef.

Record class_of M :=
  Class { base : GRing.Zmodule.class_of M; mixin : mixin_of M base }.
Local Coercion base : class_of >-> GRing.Zmodule.class_of.
Local Coercion mixin : class_of >-> mixin_of.

Structure type := Pack {sort; _ : class_of sort; _ : Type}.
Local Coercion sort : type >-> Sortclass.
Definition pack := gen_pack Pack Class GRing.Zmodule.class.
Variable cT : type.
Definition class := let: Pack _ c _ as cT' := cT return class_of cT' in c.
Let xT := let: Pack T _ _ := cT in T.
Notation xclass := (class : class_of xT).

Definition eqType := @Equality.Pack cT xclass xT.
Definition choiceType := @Choice.Pack cT xclass xT.
Definition countType := @Countable.Pack cT (fin_ xclass) xT.
Definition finType := @Finite.Pack cT (fin_ xclass) xT.
Definition zmodType := @GRing.Zmodule.Pack cT xclass xT.

Definition join_finType := @Finite.Pack zmodType (fin_ xclass) xT.

Definition baseFinGroupType := base_group cT zmodType finType.
Definition finGroupType := fin_group baseFinGroupType zmodType.
Definition join_baseFinGroupType := base_group zmodType zmodType finType.
Definition join_finGroupType := fin_group join_baseFinGroupType zmodType.

End ClassDef.

Module Exports.
Coercion base : class_of >-> GRing.Zmodule.class_of.
Coercion mixin : class_of >-> mixin_of.
Coercion sort : type >-> Sortclass.
Coercion eqType : type >-> Equality.type.
Canonical eqType.
Coercion choiceType : type >-> Choice.type.
Canonical choiceType.
Coercion countType : type >-> Countable.type.
Canonical countType.
Coercion finType : type >-> Finite.type.
Canonical finType.
Coercion zmodType : type >-> GRing.Zmodule.type.
Canonical zmodType.
Canonical join_finType.
Notation finZmodType := type.
Notation "[ 'finZmodType' 'of' T ]" := (do_pack pack T)
  (at level 0, format "[ 'finZmodType' 'of' T ]") : form_scope.
Coercion baseFinGroupType : type >-> FinGroup.base_type.
Canonical baseFinGroupType.
Coercion finGroupType : type >-> FinGroup.type.
Canonical finGroupType.
Canonical join_baseFinGroupType.
Canonical join_finGroupType.
Notation "[ 'baseFinGroupType' 'of' R 'for' +%R ]" :=
    (BaseFinGroupType R (groupMixin _))
  (at level 0, format "[ 'baseFinGroupType' 'of' R 'for' +%R ]")
    : form_scope.
Notation "[ 'finGroupType' 'of' R 'for' +%R ]" :=
    (@FinGroup.clone R _ (finGroupType _) id _ id)
  (at level 0, format "[ 'finGroupType' 'of' R 'for' +%R ]") : form_scope.
End Exports.

End Zmodule.
Import Zmodule.Exports.

Section AdditiveGroup.

Variable U : finZmodType.
Implicit Types x y : U.

Lemma zmod1gE : 1%g = 0 :> U.
Lemma zmodVgE x : x^-1%g = - x.
Lemma zmodMgE x y : (x × y)%g = x + y.
Lemma zmodXgE n x : (x ^+ n)%g = x *+ n.
Lemma zmod_mulgC x y : commute x y.
Lemma zmod_abelian (A : {set U}) : abelian A.

End AdditiveGroup.

Module Ring.

Section ClassDef.

Record class_of R :=
  Class { base : GRing.Ring.class_of R; mixin : mixin_of R base }.
Definition base2 R (c : class_of R) := Zmodule.Class (mixin c).
Local Coercion base : class_of >-> GRing.Ring.class_of.
Local Coercion base2 : class_of >-> Zmodule.class_of.

Structure type := Pack {sort; _ : class_of sort; _ : Type}.
Local Coercion sort : type >-> Sortclass.
Definition pack := gen_pack Pack Class GRing.Ring.class.
Variable cT : type.
Definition class := let: Pack _ c _ as cT' := cT return class_of cT' in c.
Let xT := let: Pack T _ _ := cT in T.
Notation xclass := (class : class_of xT).

Definition eqType := @Equality.Pack cT xclass xT.
Definition choiceType := @Choice.Pack cT xclass xT.
Definition countType := @Countable.Pack cT (fin_ xclass) xT.
Definition finType := @Finite.Pack cT (fin_ xclass) cT.
Definition zmodType := @GRing.Zmodule.Pack cT xclass cT.
Definition finZmodType := @Zmodule.Pack cT xclass xT.
Definition ringType := @GRing.Ring.Pack cT xclass xT.
Definition join_finType := @Finite.Pack ringType (fin_ xclass) xT.
Definition join_finZmodType := @Zmodule.Pack ringType xclass xT.

Definition baseFinGroupType := base_group cT zmodType finType.
Definition finGroupType := fin_group baseFinGroupType zmodType.
Definition join_baseFinGroupType := base_group zmodType zmodType finType.
Definition join_finGroupType := fin_group join_baseFinGroupType zmodType.

End ClassDef.

Module Import Exports.
Coercion base : class_of >-> GRing.Ring.class_of.
Coercion base2 : class_of >-> Zmodule.class_of.
Coercion sort : type >-> Sortclass.
Coercion eqType : type >-> Equality.type.
Canonical eqType.
Coercion choiceType : type >-> Choice.type.
Canonical choiceType.
Coercion countType : type >-> Countable.type.
Canonical countType.
Coercion finType : type >-> Finite.type.
Canonical finType.
Coercion zmodType : type >-> GRing.Zmodule.type.
Canonical zmodType.
Coercion finZmodType : type >-> Zmodule.type.
Canonical finZmodType.
Coercion ringType : type >-> GRing.Ring.type.
Canonical ringType.
Canonical join_finType.
Canonical join_finZmodType.
Notation finRingType := type.
Notation "[ 'finRingType' 'of' T ]" := (do_pack pack T)
  (at level 0, format "[ 'finRingType' 'of' T ]") : form_scope.
Canonical baseFinGroupType.
Canonical finGroupType.
Canonical join_baseFinGroupType.
Canonical join_finGroupType.
End Exports.

Section Unit.

Variable R : finRingType.

Definition is_inv (x y : R) := (x × y == 1) && (y × x == 1).
Definition unit := [qualify a x : R | [ y, is_inv x y]].
Definition inv x := odflt x (pick (is_inv x)).

Lemma mulVr : {in unit, left_inverse 1 inv *%R}.

Lemma mulrV : {in unit, right_inverse 1 inv *%R}.

Lemma intro_unit x y : y × x = 1 x × y = 1 → x \is a unit.

Lemma invr_out : {in [predC unit], inv =1 id}.

Definition UnitMixin := GRing.UnitRing.Mixin mulVr mulrV intro_unit invr_out.

End Unit.

End Ring.
Import Ring.Exports.

Module ComRing.

Section ClassDef.

Record class_of R :=
  Class { base : GRing.ComRing.class_of R; mixin : mixin_of R base }.
Definition base2 R (c : class_of R) := Ring.Class (mixin c).
Local Coercion base : class_of >-> GRing.ComRing.class_of.
Local Coercion base2 : class_of >-> Ring.class_of.

Structure type := Pack {sort; _ : class_of sort; _ : Type}.
Local Coercion sort : type >-> Sortclass.
Definition pack := gen_pack Pack Class GRing.ComRing.class.
Variable cT : type.
Definition class := let: Pack _ c _ as cT' := cT return class_of cT' in c.
Let xT := let: Pack T _ _ := cT in T.
Notation xclass := (class : class_of xT).

Definition eqType := @Equality.Pack cT xclass xT.
Definition choiceType := @Choice.Pack cT xclass xT.
Definition countType := @Countable.Pack cT (fin_ xclass) xT.
Definition finType := @Finite.Pack cT (fin_ xclass) xT.
Definition zmodType := @GRing.Zmodule.Pack cT xclass xT.
Definition finZmodType := @Zmodule.Pack cT xclass xT.
Definition ringType := @GRing.Ring.Pack cT xclass xT.
Definition finRingType := @Ring.Pack cT xclass xT.
Definition comRingType := @GRing.ComRing.Pack cT xclass xT.
Definition join_finType := @Finite.Pack comRingType (fin_ xclass) xT.
Definition join_finZmodType := @Zmodule.Pack comRingType xclass xT.
Definition join_finRingType := @Ring.Pack comRingType xclass xT.

Definition baseFinGroupType := base_group cT zmodType finType.
Definition finGroupType := fin_group baseFinGroupType zmodType.
Definition join_baseFinGroupType := base_group zmodType zmodType finType.
Definition join_finGroupType := fin_group join_baseFinGroupType zmodType.

End ClassDef.

Module Exports.
Coercion base : class_of >-> GRing.ComRing.class_of.
Coercion base2 : class_of >-> Ring.class_of.
Coercion sort : type >-> Sortclass.
Coercion eqType : type >-> Equality.type.
Canonical eqType.
Coercion choiceType : type >-> Choice.type.
Canonical choiceType.
Coercion countType : type >-> Countable.type.
Canonical countType.
Coercion finType : type >-> Finite.type.
Canonical finType.
Coercion zmodType : type >-> GRing.Zmodule.type.
Canonical zmodType.
Coercion finZmodType : type >-> Zmodule.type.
Canonical finZmodType.
Coercion ringType : type >-> GRing.Ring.type.
Canonical ringType.
Coercion finRingType : type >-> Ring.type.
Canonical finRingType.
Coercion comRingType : type >-> GRing.ComRing.type.
Canonical comRingType.
Canonical join_finType.
Canonical join_finZmodType.
Canonical join_finRingType.
Notation finComRingType := FinRing.ComRing.type.
Notation "[ 'finComRingType' 'of' T ]" := (do_pack pack T)
  (at level 0, format "[ 'finComRingType' 'of' T ]") : form_scope.
Canonical baseFinGroupType.
Canonical finGroupType.
Canonical join_baseFinGroupType.
Canonical join_finGroupType.
End Exports.

End ComRing.
Import ComRing.Exports.

Module UnitRing.

Section ClassDef.

Record class_of R :=
  Class { base : GRing.UnitRing.class_of R; mixin : mixin_of R base }.
Definition base2 R (c : class_of R) := Ring.Class (mixin c).
Local Coercion base : class_of >-> GRing.UnitRing.class_of.
Local Coercion base2 : class_of >-> Ring.class_of.

Structure type := Pack {sort; _ : class_of sort; _ : Type}.
Local Coercion sort : type >-> Sortclass.
Definition pack := gen_pack Pack Class GRing.UnitRing.class.
Variable cT : type.
Definition class := let: Pack _ c _ as cT' := cT return class_of cT' in c.
Let xT := let: Pack T _ _ := cT in T.
Notation xclass := (class : class_of xT).

Definition eqType := @Equality.Pack cT xclass xT.
Definition choiceType := @Choice.Pack cT xclass xT.
Definition countType := @Countable.Pack cT (fin_ xclass) xT.
Definition finType := @Finite.Pack cT (fin_ xclass) xT.
Definition zmodType := @GRing.Zmodule.Pack cT xclass xT.
Definition finZmodType := @Zmodule.Pack cT xclass xT.
Definition ringType := @GRing.Ring.Pack cT xclass xT.
Definition finRingType := @Ring.Pack cT xclass xT.
Definition unitRingType := @GRing.UnitRing.Pack cT xclass xT.

Definition join_finType := @Finite.Pack unitRingType (fin_ xclass) xT.
Definition join_finZmodType := @Zmodule.Pack unitRingType xclass xT.
Definition join_finRingType := @Ring.Pack unitRingType xclass xT.

Definition baseFinGroupType := base_group cT zmodType finType.
Definition finGroupType := fin_group baseFinGroupType zmodType.
Definition join_baseFinGroupType := base_group zmodType zmodType finType.
Definition join_finGroupType := fin_group join_baseFinGroupType zmodType.

End ClassDef.

Module Exports.
Coercion base : class_of >-> GRing.UnitRing.class_of.
Coercion base2 : class_of >-> Ring.class_of.
Coercion sort : type >-> Sortclass.
Coercion eqType : type >-> Equality.type.
Canonical eqType.
Coercion choiceType : type >-> Choice.type.
Canonical choiceType.
Coercion countType : type >-> Countable.type.
Canonical countType.
Coercion finType : type >-> Finite.type.
Canonical finType.
Coercion zmodType : type >-> GRing.Zmodule.type.
Canonical zmodType.
Coercion finZmodType : type >-> Zmodule.type.
Canonical finZmodType.
Coercion ringType : type >-> GRing.Ring.type.
Canonical ringType.
Coercion finRingType : type >-> Ring.type.
Canonical finRingType.
Coercion unitRingType : type >-> GRing.UnitRing.type.
Canonical unitRingType.
Canonical join_finType.
Canonical join_finZmodType.
Canonical join_finRingType.
Notation finUnitRingType := FinRing.UnitRing.type.
Notation "[ 'finUnitRingType' 'of' T ]" := (do_pack pack T)
  (at level 0, format "[ 'finUnitRingType' 'of' T ]") : form_scope.
Canonical baseFinGroupType.
Canonical finGroupType.
Canonical join_baseFinGroupType.
Canonical join_finGroupType.
End Exports.

End UnitRing.
Import UnitRing.Exports.

Section UnitsGroup.

Variable R : finUnitRingType.

Inductive unit_of (phR : phant R) := Unit (x : R) of x \is a GRing.unit.

Let phR := Phant R.
Local Notation uT := (unit_of phR).
Implicit Types u v : uT.
Definition uval u := let: Unit x _ := u in x.

Canonical unit_subType := [subType for uval].
Definition unit_eqMixin := Eval hnf in [eqMixin of uT by <:].
Canonical unit_eqType := Eval hnf in EqType uT unit_eqMixin.
Definition unit_choiceMixin := [choiceMixin of uT by <:].
Canonical unit_choiceType := Eval hnf in ChoiceType uT unit_choiceMixin.
Definition unit_countMixin := [countMixin of uT by <:].
Canonical unit_countType := Eval hnf in CountType uT unit_countMixin.
Canonical unit_subCountType := Eval hnf in [subCountType of uT].
Definition unit_finMixin := [finMixin of uT by <:].
Canonical unit_finType := Eval hnf in FinType uT unit_finMixin.
Canonical unit_subFinType := Eval hnf in [subFinType of uT].

Definition unit1 := Unit phR (@GRing.unitr1 _).
Lemma unit_inv_proof u : (val u)^-1 \is a GRing.unit.
Definition unit_inv u := Unit phR (unit_inv_proof u).
Lemma unit_mul_proof u v : val u × val v \is a GRing.unit.
Definition unit_mul u v := Unit phR (unit_mul_proof u v).
Lemma unit_muluA : associative unit_mul.
Lemma unit_mul1u : left_id unit1 unit_mul.
Lemma unit_mulVu : left_inverse unit1 unit_inv unit_mul.

Definition unit_GroupMixin := FinGroup.Mixin unit_muluA unit_mul1u unit_mulVu.
Canonical unit_baseFinGroupType :=
  Eval hnf in BaseFinGroupType uT unit_GroupMixin.
Canonical unit_finGroupType := Eval hnf in FinGroupType unit_mulVu.

Lemma val_unit1 : val (1%g : uT) = 1.
Lemma val_unitM x y : val (x × y : uT)%g = val x × val y.
Lemma val_unitV x : val (x^-1 : uT)%g = (val x)^-1.
Lemma val_unitX n x : val (x ^+ n : uT)%g = val x ^+ n.

Definition unit_act x u := x × val u.
Lemma unit_actE x u : unit_act x u = x × val u.

Canonical unit_action :=
  @TotalAction _ _ unit_act (@GRing.mulr1 _) (fun _ _ _GRing.mulrA _ _ _).
Lemma unit_is_groupAction : @is_groupAction _ R setT setT unit_action.
Canonical unit_groupAction := GroupAction unit_is_groupAction.

End UnitsGroup.

Module Import UnitsGroupExports.
Canonical unit_subType.
Canonical unit_eqType.
Canonical unit_choiceType.
Canonical unit_countType.
Canonical unit_subCountType.
Canonical unit_finType.
Canonical unit_subFinType.
Canonical unit_baseFinGroupType.
Canonical unit_finGroupType.
Canonical unit_action.
Canonical unit_groupAction.
End UnitsGroupExports.

Notation unit R Ux := (Unit (Phant R) Ux).

Module ComUnitRing.

Section ClassDef.

Record class_of R :=
  Class { base : GRing.ComUnitRing.class_of R; mixin : mixin_of R base }.
Definition base2 R (c : class_of R) := ComRing.Class (mixin c).
Definition base3 R (c : class_of R) := @UnitRing.Class R (base c) (mixin c).
Local Coercion base : class_of >-> GRing.ComUnitRing.class_of.
Local Coercion base2 : class_of >-> ComRing.class_of.
Local Coercion base3 : class_of >-> UnitRing.class_of.

Structure type := Pack {sort; _ : class_of sort; _ : Type}.
Local Coercion sort : type >-> Sortclass.
Definition pack := gen_pack Pack Class GRing.ComUnitRing.class.
Variable cT : type.
Definition class := let: Pack _ c _ as cT' := cT return class_of cT' in c.
Let xT := let: Pack T _ _ := cT in T.
Notation xclass := (class : class_of xT).

Definition eqType := @Equality.Pack cT xclass xT.
Definition choiceType := @Choice.Pack cT xclass xT.
Definition countType := @Countable.Pack cT (fin_ xclass) xT.
Definition finType := @Finite.Pack cT (fin_ xclass) xT.
Definition zmodType := @GRing.Zmodule.Pack cT xclass xT.
Definition finZmodType := @Zmodule.Pack cT xclass xT.
Definition ringType := @GRing.Ring.Pack cT xclass xT.
Definition finRingType := @Ring.Pack cT xclass xT.
Definition comRingType := @GRing.ComRing.Pack cT xclass xT.
Definition finComRingType := @ComRing.Pack cT xclass xT.
Definition unitRingType := @GRing.UnitRing.Pack cT xclass xT.
Definition finUnitRingType := @UnitRing.Pack cT xclass xT.
Definition comUnitRingType := @GRing.ComUnitRing.Pack cT xclass xT.

Definition join_finType := @Finite.Pack comUnitRingType (fin_ xclass) xT.
Definition join_finZmodType := @Zmodule.Pack comUnitRingType xclass xT.
Definition join_finRingType := @Ring.Pack comUnitRingType xclass xT.
Definition join_finComRingType := @ComRing.Pack comUnitRingType xclass xT.
Definition join_finUnitRingType := @UnitRing.Pack comUnitRingType xclass xT.
Definition ujoin_finComRingType := @ComRing.Pack unitRingType xclass xT.
Definition cjoin_finUnitRingType := @UnitRing.Pack comRingType xclass xT.
Definition fcjoin_finUnitRingType := @UnitRing.Pack finComRingType xclass xT.

Definition baseFinGroupType := base_group cT zmodType finType.
Definition finGroupType := fin_group baseFinGroupType zmodType.
Definition join_baseFinGroupType := base_group zmodType zmodType finType.
Definition join_finGroupType := fin_group join_baseFinGroupType zmodType.

End ClassDef.

Module Exports.
Coercion base : class_of >-> GRing.ComUnitRing.class_of.
Coercion base2 : class_of >-> ComRing.class_of.
Coercion base3 : class_of >-> UnitRing.class_of.
Coercion sort : type >-> Sortclass.
Coercion eqType : type >-> Equality.type.
Canonical eqType.
Coercion choiceType : type >-> Choice.type.
Canonical choiceType.
Coercion countType : type >-> Countable.type.
Canonical countType.
Coercion finType : type >-> Finite.type.
Canonical finType.
Coercion zmodType : type >-> GRing.Zmodule.type.
Canonical zmodType.
Coercion finZmodType : type >-> Zmodule.type.
Canonical finZmodType.
Coercion ringType : type >-> GRing.Ring.type.
Canonical ringType.
Coercion finRingType : type >-> Ring.type.
Canonical finRingType.
Coercion comRingType : type >-> GRing.ComRing.type.
Canonical comRingType.
Coercion finComRingType : type >-> ComRing.type.
Canonical finComRingType.
Coercion unitRingType : type >-> GRing.UnitRing.type.
Canonical unitRingType.
Coercion finUnitRingType : type >-> UnitRing.type.
Canonical finUnitRingType.
Coercion comUnitRingType : type >-> GRing.ComUnitRing.type.
Canonical comUnitRingType.
Canonical join_finType.
Canonical join_finZmodType.
Canonical join_finRingType.
Canonical join_finComRingType.
Canonical join_finUnitRingType.
Canonical ujoin_finComRingType.
Canonical cjoin_finUnitRingType.
Canonical fcjoin_finUnitRingType.
Notation finComUnitRingType := FinRing.ComUnitRing.type.
Notation "[ 'finComUnitRingType' 'of' T ]" := (do_pack pack T)
  (at level 0, format "[ 'finComUnitRingType' 'of' T ]") : form_scope.
Canonical baseFinGroupType.
Canonical finGroupType.
Canonical join_baseFinGroupType.
Canonical join_finGroupType.
End Exports.

End ComUnitRing.
Import ComUnitRing.Exports.

Module IntegralDomain.

Section ClassDef.

Record class_of R :=
  Class { base : GRing.IntegralDomain.class_of R; mixin : mixin_of R base }.
Definition base2 R (c : class_of R) := ComUnitRing.Class (mixin c).
Local Coercion base : class_of >-> GRing.IntegralDomain.class_of.
Local Coercion base2 : class_of >-> ComUnitRing.class_of.

Structure type := Pack {sort; _ : class_of sort; _ : Type}.
Local Coercion sort : type >-> Sortclass.
Definition pack := gen_pack Pack Class GRing.IntegralDomain.class.
Variable cT : type.
Definition class := let: Pack _ c _ as cT' := cT return class_of cT' in c.
Let xT := let: Pack T _ _ := cT in T.
Notation xclass := (class : class_of xT).

Definition eqType := @Equality.Pack cT xclass xT.
Definition choiceType := @Choice.Pack cT xclass xT.
Definition countType := @Countable.Pack cT (fin_ xclass) xT.
Definition finType := @Finite.Pack cT (fin_ xclass) xT.
Definition zmodType := @GRing.Zmodule.Pack cT xclass xT.
Definition finZmodType := @Zmodule.Pack cT xclass xT.
Definition ringType := @GRing.Ring.Pack cT xclass xT.
Definition finRingType := @Ring.Pack cT xclass xT.
Definition comRingType := @GRing.ComRing.Pack cT xclass xT.
Definition finComRingType := @ComRing.Pack cT xclass xT.
Definition unitRingType := @GRing.UnitRing.Pack cT xclass xT.
Definition finUnitRingType := @UnitRing.Pack cT xclass xT.
Definition comUnitRingType := @GRing.ComUnitRing.Pack cT xclass xT.
Definition finComUnitRingType := @ComUnitRing.Pack cT xclass xT.
Definition idomainType := @GRing.IntegralDomain.Pack cT xclass xT.

Definition join_finType := @Finite.Pack idomainType (fin_ xclass) xT.
Definition join_finZmodType := @Zmodule.Pack idomainType xclass xT.
Definition join_finRingType := @Ring.Pack idomainType xclass xT.
Definition join_finUnitRingType := @UnitRing.Pack idomainType xclass xT.
Definition join_finComRingType := @ComRing.Pack idomainType xclass xT.
Definition join_finComUnitRingType := @ComUnitRing.Pack idomainType xclass xT.

Definition baseFinGroupType := base_group cT zmodType finType.
Definition finGroupType := fin_group baseFinGroupType zmodType.
Definition join_baseFinGroupType := base_group zmodType zmodType finType.
Definition join_finGroupType := fin_group join_baseFinGroupType zmodType.

End ClassDef.

Module Exports.
Coercion base : class_of >-> GRing.IntegralDomain.class_of.
Coercion base2 : class_of >-> ComUnitRing.class_of.
Coercion sort : type >-> Sortclass.
Coercion eqType : type >-> Equality.type.
Canonical eqType.
Coercion choiceType : type >-> Choice.type.
Canonical choiceType.
Coercion countType : type >-> Countable.type.
Canonical countType.
Coercion finType : type >-> Finite.type.
Canonical finType.
Coercion zmodType : type >-> GRing.Zmodule.type.
Canonical zmodType.
Coercion finZmodType : type >-> Zmodule.type.
Canonical finZmodType.
Coercion ringType : type >-> GRing.Ring.type.
Canonical ringType.
Coercion finRingType : type >-> Ring.type.
Canonical finRingType.
Coercion comRingType : type >-> GRing.ComRing.type.
Canonical comRingType.
Coercion finComRingType : type >-> ComRing.type.
Canonical finComRingType.
Coercion unitRingType : type >-> GRing.UnitRing.type.
Canonical unitRingType.
Coercion finUnitRingType : type >-> UnitRing.type.
Canonical finUnitRingType.
Coercion comUnitRingType : type >-> GRing.ComUnitRing.type.
Canonical comUnitRingType.
Coercion finComUnitRingType : type >-> ComUnitRing.type.
Canonical finComUnitRingType.
Coercion idomainType : type >-> GRing.IntegralDomain.type.
Canonical idomainType.
Canonical join_finType.
Canonical join_finZmodType.
Canonical join_finRingType.
Canonical join_finComRingType.
Canonical join_finUnitRingType.
Canonical join_finComUnitRingType.
Notation finIdomainType := FinRing.IntegralDomain.type.
Notation "[ 'finIdomainType' 'of' T ]" := (do_pack pack T)
  (at level 0, format "[ 'finIdomainType' 'of' T ]") : form_scope.
Canonical baseFinGroupType.
Canonical finGroupType.
Canonical join_baseFinGroupType.
Canonical join_finGroupType.
End Exports.

End IntegralDomain.
Import IntegralDomain.Exports.

Module Field.

Section ClassDef.

Record class_of R :=
  Class { base : GRing.Field.class_of R; mixin : mixin_of R base }.
Definition base2 R (c : class_of R) := IntegralDomain.Class (mixin c).
Local Coercion base : class_of >-> GRing.Field.class_of.
Local Coercion base2 : class_of >-> IntegralDomain.class_of.

Structure type := Pack {sort; _ : class_of sort; _ : Type}.
Local Coercion sort : type >-> Sortclass.
Definition pack := gen_pack Pack Class GRing.Field.class.
Variable cT : type.
Definition class := let: Pack _ c _ as cT' := cT return class_of cT' in c.
Let xT := let: Pack T _ _ := cT in T.
Notation xclass := (class : class_of xT).

Definition eqType := @Equality.Pack cT xclass xT.
Definition choiceType := @Choice.Pack cT xclass xT.
Definition countType := @Countable.Pack cT (fin_ xclass) xT.
Definition finType := @Finite.Pack cT (fin_ xclass) xT.
Definition zmodType := @GRing.Zmodule.Pack cT xclass xT.
Definition finZmodType := @Zmodule.Pack cT xclass xT.
Definition ringType := @GRing.Ring.Pack cT xclass xT.
Definition finRingType := @Ring.Pack cT xclass xT.
Definition comRingType := @GRing.ComRing.Pack cT xclass xT.
Definition finComRingType := @ComRing.Pack cT xclass xT.
Definition unitRingType := @GRing.UnitRing.Pack cT xclass xT.
Definition finUnitRingType := @UnitRing.Pack cT xclass xT.
Definition comUnitRingType := @GRing.ComUnitRing.Pack cT xclass xT.
Definition finComUnitRingType := @ComUnitRing.Pack cT xclass xT.
Definition idomainType := @GRing.IntegralDomain.Pack cT xclass xT.
Definition finIdomainType := @IntegralDomain.Pack cT xclass xT.
Definition fieldType := @GRing.Field.Pack cT xclass xT.

Definition join_finType := @Finite.Pack fieldType (fin_ xclass) xT.
Definition join_finZmodType := @Zmodule.Pack fieldType xclass xT.
Definition join_finRingType := @Ring.Pack fieldType xclass xT.
Definition join_finUnitRingType := @UnitRing.Pack fieldType xclass xT.
Definition join_finComRingType := @ComRing.Pack fieldType xclass xT.
Definition join_finComUnitRingType := @ComUnitRing.Pack fieldType xclass xT.
Definition join_finIdomainType := @IntegralDomain.Pack fieldType xclass xT.

Definition baseFinGroupType := base_group cT zmodType finType.
Definition finGroupType := fin_group baseFinGroupType zmodType.
Definition join_baseFinGroupType := base_group zmodType zmodType finType.
Definition join_finGroupType := fin_group join_baseFinGroupType zmodType.

End ClassDef.

Module Exports.
Coercion base : class_of >-> GRing.Field.class_of.
Coercion base2 : class_of >-> IntegralDomain.class_of.
Coercion sort : type >-> Sortclass.
Coercion eqType : type >-> Equality.type.
Canonical eqType.
Coercion choiceType : type >-> Choice.type.
Canonical choiceType.
Coercion countType : type >-> Countable.type.
Canonical countType.
Coercion finType : type >-> Finite.type.
Canonical finType.
Coercion zmodType : type >-> GRing.Zmodule.type.
Canonical zmodType.
Coercion finZmodType : type >-> Zmodule.type.
Canonical finZmodType.
Coercion ringType : type >-> GRing.Ring.type.
Canonical ringType.
Coercion finRingType : type >-> Ring.type.
Canonical finRingType.
Coercion comRingType : type >-> GRing.ComRing.type.
Canonical comRingType.
Coercion finComRingType : type >-> ComRing.type.
Canonical finComRingType.
Coercion unitRingType : type >-> GRing.UnitRing.type.
Canonical unitRingType.
Coercion finUnitRingType : type >-> UnitRing.type.
Canonical finUnitRingType.
Coercion comUnitRingType : type >-> GRing.ComUnitRing.type.
Canonical comUnitRingType.
Coercion finComUnitRingType : type >-> ComUnitRing.type.
Canonical finComUnitRingType.
Coercion idomainType : type >-> GRing.IntegralDomain.type.
Canonical idomainType.
Coercion finIdomainType : type >-> IntegralDomain.type.
Canonical finIdomainType.
Coercion fieldType : type >-> GRing.Field.type.
Canonical fieldType.
Canonical join_finType.
Canonical join_finZmodType.
Canonical join_finRingType.
Canonical join_finComRingType.
Canonical join_finUnitRingType.
Canonical join_finComUnitRingType.
Canonical join_finIdomainType.
Notation finFieldType := FinRing.Field.type.
Notation "[ 'finFieldType' 'of' T ]" := (do_pack pack T)
  (at level 0, format "[ 'finFieldType' 'of' T ]") : form_scope.
Canonical baseFinGroupType.
Canonical finGroupType.
Canonical join_baseFinGroupType.
Canonical join_finGroupType.
End Exports.

End Field.
Import Field.Exports.

Section DecideField.

Variable F : Field.type.

Fixpoint sat e f :=
  match f with
  | GRing.Bool bb
  | t1 == t2 ⇒ (GRing.eval e t1 == GRing.eval e t2)%bool
  | GRing.Unit tGRing.eval e t \is a GRing.unit
  | f1 f2sat e f1 && sat e f2
  | f1 f2sat e f1 || sat e f2
  | f1 ==> f2 ⇒ (sat e f1 ==> sat e f2)%bool
  | ¬ f1~~ sat e f1
  | (' 'X_k, f1) ⇒ [ x : F, sat (set_nth 0%R e k x) f1]
  | (' 'X_k, f1) ⇒ [ x : F, sat (set_nth 0%R e k x) f1]
  end%T.

Lemma decidable : GRing.DecidableField.axiom sat.

Definition DecidableFieldMixin := DecFieldMixin decidable.

End DecideField.

Module DecField.

Section Joins.

Variable cT : Field.type.
Let xT := let: Field.Pack T _ _ := cT in T.
Let xclass : Field.class_of xT := Field.class cT.

Definition type := Eval hnf in DecFieldType cT (DecidableFieldMixin cT).
Definition finType := @Finite.Pack type (fin_ xclass) xT.
Definition finZmodType := @Zmodule.Pack type xclass xT.
Definition finRingType := @Ring.Pack type xclass xT.
Definition finUnitRingType := @UnitRing.Pack type xclass xT.
Definition finComRingType := @ComRing.Pack type xclass xT.
Definition finComUnitRingType := @ComUnitRing.Pack type xclass xT.
Definition finIdomainType := @IntegralDomain.Pack type xclass xT.
Definition baseFinGroupType := base_group type finZmodType finZmodType.
Definition finGroupType := fin_group baseFinGroupType cT.

End Joins.

Module Exports.
Coercion type : Field.type >-> GRing.DecidableField.type.
Canonical type.
Canonical finType.
Canonical finZmodType.
Canonical finRingType.
Canonical finUnitRingType.
Canonical finComRingType.
Canonical finComUnitRingType.
Canonical finIdomainType.
Canonical baseFinGroupType.
Canonical finGroupType.
End Exports.

End DecField.

Module Lmodule.

Section ClassDef.

Variable R : ringType.

Record class_of M :=
  Class { base : GRing.Lmodule.class_of R M ; mixin : mixin_of M base }.
Definition base2 R (c : class_of R) := Zmodule.Class (mixin c).
Local Coercion base : class_of >-> GRing.Lmodule.class_of.
Local Coercion base2 : class_of >-> Zmodule.class_of.

Structure type (phR : phant R) := Pack {sort; _ : class_of sort; _ : Type}.
Local Coercion sort : type >-> Sortclass.
Variables (phR : phant R) (cT : type phR).
Definition class := let: Pack _ c _ as cT' := cT return class_of cT' in c.
Definition pack := gen_pack (Pack phR) Class (@GRing.Lmodule.class R phR).
Let xT := let: Pack T _ _ := cT in T.
Notation xclass := (class : class_of xT).

Definition eqType := @Equality.Pack cT xclass xT.
Definition choiceType := @Choice.Pack cT xclass xT.
Definition countType := @Countable.Pack cT (fin_ xclass) xT.
Definition finType := @Finite.Pack cT (fin_ xclass) xT.
Definition zmodType := @GRing.Zmodule.Pack cT xclass xT.
Definition finZmodType := @Zmodule.Pack cT xclass xT.
Definition lmodType := @GRing.Lmodule.Pack R phR cT xclass xT.
Definition join_finType := @Finite.Pack lmodType (fin_ xclass) xT.
Definition join_finZmodType := @Zmodule.Pack lmodType xclass xT.

Definition baseFinGroupType := base_group cT zmodType finType.
Definition finGroupType := fin_group baseFinGroupType zmodType.
Definition join_baseFinGroupType := base_group zmodType zmodType finType.
Definition join_finGroupType := fin_group join_baseFinGroupType zmodType.

End ClassDef.

Module Import Exports.
Coercion base : class_of >-> GRing.Lmodule.class_of.
Coercion base2 : class_of >-> Zmodule.class_of.
Coercion sort : type >-> Sortclass.
Coercion eqType : type >-> Equality.type.
Canonical eqType.
Coercion choiceType : type >-> Choice.type.
Canonical choiceType.
Coercion countType : type >-> Countable.type.
Canonical countType.
Coercion finType : type >-> Finite.type.
Canonical finType.
Coercion zmodType : type >-> GRing.Zmodule.type.
Canonical zmodType.
Coercion finZmodType : type >-> Zmodule.type.
Canonical finZmodType.
Coercion lmodType : type >-> GRing.Lmodule.type.
Canonical lmodType.
Canonical join_finType.
Canonical join_finZmodType.
Notation finLmodType R := (FinRing.Lmodule.type (Phant R)).
Notation "[ 'finLmodType' R 'of' T ]" := (do_pack (@pack _ (Phant R)) T)
  (at level 0, format "[ 'finLmodType' R 'of' T ]") : form_scope.
Canonical baseFinGroupType.
Canonical finGroupType.
Canonical join_baseFinGroupType.
Canonical join_finGroupType.
End Exports.

End Lmodule.
Import Lmodule.Exports.

Module Lalgebra.

Section ClassDef.

Variable R : ringType.

Record class_of M :=
  Class { base : GRing.Lalgebra.class_of R M; mixin : mixin_of M base }.
Definition base2 M (c : class_of M) := Ring.Class (mixin c).
Definition base3 M (c : class_of M) := @Lmodule.Class _ _ (base c) (mixin c).
Local Coercion base : class_of >-> GRing.Lalgebra.class_of.
Local Coercion base2 : class_of >-> Ring.class_of.
Local Coercion base3 : class_of >-> Lmodule.class_of.

Structure type (phR : phant R) := Pack {sort; _ : class_of sort; _ : Type}.
Local Coercion sort : type >-> Sortclass.
Variables (phR : phant R) (cT : type phR).
Definition pack := gen_pack (Pack phR) Class (@GRing.Lalgebra.class R phR).
Definition class := let: Pack _ c _ as cT' := cT return class_of cT' in c.
Let xT := let: Pack T _ _ := cT in T.
Notation xclass := (class : class_of xT).

Definition eqType := @Equality.Pack cT xclass xT.
Definition choiceType := @Choice.Pack cT xclass xT.
Definition countType := @Countable.Pack cT (fin_ xclass) xT.
Definition finType := @Finite.Pack cT (fin_ xclass) xT.
Definition zmodType := @GRing.Zmodule.Pack cT xclass xT.
Definition finZmodType := @Zmodule.Pack cT xclass xT.
Definition ringType := @GRing.Ring.Pack cT xclass xT.
Definition finRingType := @Ring.Pack cT xclass xT.
Definition lmodType := @GRing.Lmodule.Pack R phR cT xclass xT.
Definition finLmodType := @Lmodule.Pack R phR cT xclass xT.
Definition lalgType := @GRing.Lalgebra.Pack R phR cT xclass xT.

Definition join_finType := @Finite.Pack lalgType (fin_ xclass) xT.
Definition join_finZmodType := @Zmodule.Pack lalgType xclass xT.
Definition join_finLmodType := @Lmodule.Pack R phR lalgType xclass xT.
Definition join_finRingType := @Ring.Pack lalgType xclass xT.
Definition rjoin_finLmodType := @Lmodule.Pack R phR ringType xclass xT.
Definition ljoin_finRingType := @Ring.Pack lmodType xclass xT.
Definition fljoin_finRingType := @Ring.Pack finLmodType xclass xT.

Definition baseFinGroupType := base_group cT zmodType finType.
Definition finGroupType := fin_group baseFinGroupType zmodType.
Definition join_baseFinGroupType := base_group zmodType zmodType finType.
Definition join_finGroupType := fin_group join_baseFinGroupType zmodType.

End ClassDef.

Module Exports.
Coercion base : class_of >-> GRing.Lalgebra.class_of.
Coercion base2 : class_of >-> Ring.class_of.
Coercion base3 : class_of >-> Lmodule.class_of.
Coercion sort : type >-> Sortclass.
Coercion eqType : type >-> Equality.type.
Canonical eqType.
Coercion choiceType : type >-> Choice.type.
Canonical choiceType.
Coercion countType : type >-> Countable.type.
Canonical countType.
Coercion finType : type >-> Finite.type.
Canonical finType.
Coercion zmodType : type >-> GRing.Zmodule.type.
Canonical zmodType.
Coercion finZmodType : type >-> Zmodule.type.
Canonical finZmodType.
Coercion ringType : type >-> GRing.Ring.type.
Canonical ringType.
Coercion finRingType : type >-> Ring.type.
Canonical finRingType.
Coercion lmodType : type >-> GRing.Lmodule.type.
Canonical lmodType.
Coercion finLmodType : type >-> Lmodule.type.
Canonical finLmodType.
Coercion lalgType : type >-> GRing.Lalgebra.type.
Canonical lalgType.
Canonical join_finType.
Canonical join_finZmodType.
Canonical join_finLmodType.
Canonical join_finRingType.
Canonical rjoin_finLmodType.
Canonical ljoin_finRingType.
Canonical fljoin_finRingType.
Notation finLalgType R := (FinRing.Lalgebra.type (Phant R)).
Notation "[ 'finLalgType' R 'of' T ]" := (do_pack (@pack _ (Phant R)) T)
  (at level 0, format "[ 'finLalgType' R 'of' T ]") : form_scope.
Canonical baseFinGroupType.
Canonical finGroupType.
Canonical join_baseFinGroupType.
Canonical join_finGroupType.
End Exports.

End Lalgebra.
Import Lalgebra.Exports.

Module Algebra.

Section ClassDef.

Variable R : ringType.

Record class_of M :=
  Class { base : GRing.Algebra.class_of R M; mixin : mixin_of M base }.
Definition base2 M (c : class_of M) := Lalgebra.Class (mixin c).
Local Coercion base : class_of >-> GRing.Algebra.class_of.
Local Coercion base2 : class_of >->Lalgebra.class_of.

Structure type (phR : phant R) := Pack {sort; _ : class_of sort; _ : Type}.
Local Coercion sort : type >-> Sortclass.
Variables (phR : phant R) (cT : type phR).
Definition pack := gen_pack (Pack phR) Class (@GRing.Algebra.class R phR).
Definition class := let: Pack _ c _ as cT' := cT return class_of cT' in c.
Let xT := let: Pack T _ _ := cT in T.
Notation xclass := (class : class_of xT).

Definition eqType := @Equality.Pack cT xclass xT.
Definition choiceType := @Choice.Pack cT xclass xT.
Definition countType := @Countable.Pack cT (fin_ xclass) xT.
Definition finType := @Finite.Pack cT (fin_ xclass) xT.
Definition zmodType := @GRing.Zmodule.Pack cT xclass xT.
Definition finZmodType := @Zmodule.Pack cT xclass xT.
Definition ringType := @GRing.Ring.Pack cT xclass xT.
Definition finRingType := @Ring.Pack cT xclass xT.
Definition lmodType := @GRing.Lmodule.Pack R phR cT xclass xT.
Definition finLmodType := @Lmodule.Pack R phR cT xclass xT.
Definition lalgType := @GRing.Lalgebra.Pack R phR cT xclass xT.
Definition finLalgType := @Lalgebra.Pack R phR cT xclass xT.
Definition algType := @GRing.Algebra.Pack R phR cT xclass xT.

Definition join_finType := @Finite.Pack algType (fin_ xclass) xT.
Definition join_finZmodType := @Zmodule.Pack algType xclass xT.
Definition join_finRingType := @Ring.Pack algType xclass xT.
Definition join_finLmodType := @Lmodule.Pack R phR algType xclass xT.
Definition join_finLalgType := @Lalgebra.Pack R phR algType xclass xT.

Definition baseFinGroupType := base_group cT zmodType finType.
Definition finGroupType := fin_group baseFinGroupType zmodType.
Definition join_baseFinGroupType := base_group zmodType zmodType finType.
Definition join_finGroupType := fin_group join_baseFinGroupType zmodType.

End ClassDef.

Module Exports.
Coercion base : class_of >-> GRing.Algebra.class_of.
Coercion base2 : class_of >-> Lalgebra.class_of.
Coercion sort : type >-> Sortclass.
Coercion eqType : type >-> Equality.type.
Canonical eqType.
Coercion choiceType : type >-> Choice.type.
Canonical choiceType.
Coercion countType : type >-> Countable.type.
Canonical countType.
Coercion finType : type >-> Finite.type.
Canonical finType.
Coercion zmodType : type >-> GRing.Zmodule.type.
Canonical zmodType.
Coercion finZmodType : type >-> Zmodule.type.
Canonical finZmodType.
Coercion ringType : type >-> GRing.Ring.type.
Canonical ringType.
Coercion finRingType : type >-> Ring.type.
Canonical finRingType.
Coercion lmodType : type >-> GRing.Lmodule.type.
Canonical lmodType.
Coercion finLmodType : type >-> Lmodule.type.
Canonical finLmodType.
Coercion lalgType : type >-> GRing.Lalgebra.type.
Canonical lalgType.
Coercion finLalgType : type >-> Lalgebra.type.
Canonical finLalgType.
Coercion algType : type >-> GRing.Algebra.type.
Canonical algType.
Canonical join_finType.
Canonical join_finZmodType.
Canonical join_finLmodType.
Canonical join_finRingType.
Canonical join_finLalgType.
Notation finAlgType R := (type (Phant R)).
Notation "[ 'finAlgType' R 'of' T ]" := (do_pack (@pack _ (Phant R)) T)
  (at level 0, format "[ 'finAlgType' R 'of' T ]") : form_scope.
Canonical baseFinGroupType.
Canonical finGroupType.
Canonical join_baseFinGroupType.
Canonical join_finGroupType.
End Exports.

End Algebra.
Import Algebra.Exports.

Module UnitAlgebra.

Section ClassDef.

Variable R : unitRingType.

Record class_of M :=
  Class { base : GRing.UnitAlgebra.class_of R M ; mixin : mixin_of M base }.
Definition base2 M (c : class_of M) := Algebra.Class (mixin c).
Definition base3 M (c : class_of M) := @UnitRing.Class _ (base c) (mixin c).

Local Coercion base : class_of >-> GRing.UnitAlgebra.class_of.
Local Coercion base2 : class_of >-> Algebra.class_of.
Local Coercion base3 : class_of >-> UnitRing.class_of.

Structure type (phR : phant R) := Pack {sort; _ : class_of sort; _ : Type}.
Local Coercion sort : type >-> Sortclass.
Variables (phR : phant R) (cT : type phR).
Definition pack := gen_pack (Pack phR) Class (@GRing.UnitAlgebra.class R phR).
Definition class := let: Pack _ c _ as cT' := cT return class_of cT' in c.
Let xT := let: Pack T _ _ := cT in T.
Notation xclass := (class : class_of xT).

Definition eqType := @Equality.Pack cT xclass xT.
Definition choiceType := @Choice.Pack cT xclass xT.
Definition countType := @Countable.Pack cT (fin_ xclass) xT.
Definition finType := @Finite.Pack cT (fin_ xclass) xT.
Definition zmodType := @GRing.Zmodule.Pack cT xclass xT.
Definition finZmodType := @Zmodule.Pack cT xclass xT.
Definition ringType := @GRing.Ring.Pack cT xclass xT.
Definition finRingType := @Ring.Pack cT xclass xT.
Definition unitRingType := @GRing.UnitRing.Pack cT xclass xT.
Definition finUnitRingType := @UnitRing.Pack cT xclass xT.
Definition lmodType := @GRing.Lmodule.Pack R phR cT xclass xT.
Definition finLmodType := @Lmodule.Pack R phR cT xclass xT.
Definition lalgType := @GRing.Lalgebra.Pack R phR cT xclass xT.
Definition finLalgType := @Lalgebra.Pack R phR cT xclass xT.
Definition algType := @GRing.Algebra.Pack R phR cT xclass xT.
Definition finAlgType := @Algebra.Pack R phR cT xclass xT.
Definition unitAlgType := @GRing.UnitAlgebra.Pack R phR cT xclass xT.

Definition join_finType := @Finite.Pack unitAlgType (fin_ xclass) xT.
Definition join_finZmodType := @Zmodule.Pack unitAlgType xclass xT.
Definition join_finRingType := @Ring.Pack unitAlgType xclass xT.
Definition join_finUnitRingType := @UnitRing.Pack unitAlgType xclass xT.
Definition join_finLmodType := @Lmodule.Pack R phR unitAlgType xclass xT.
Definition join_finLalgType := @Lalgebra.Pack R phR unitAlgType xclass xT.
Definition join_finAlgType := @Algebra.Pack R phR unitAlgType xclass xT.
Definition ljoin_finUnitRingType := @UnitRing.Pack lmodType xclass xT.
Definition fljoin_finUnitRingType := @UnitRing.Pack finLmodType xclass xT.
Definition njoin_finUnitRingType := @UnitRing.Pack lalgType xclass xT.
Definition fnjoin_finUnitRingType := @UnitRing.Pack finLalgType xclass xT.
Definition ajoin_finUnitRingType := @UnitRing.Pack algType xclass xT.
Definition fajoin_finUnitRingType := @UnitRing.Pack finAlgType xclass xT.
Definition ujoin_finLmodType := @Lmodule.Pack R phR unitRingType xclass xT.
Definition ujoin_finLalgType := @Lalgebra.Pack R phR unitRingType xclass xT.
Definition ujoin_finAlgType := @Algebra.Pack R phR unitRingType xclass xT.

Definition baseFinGroupType := base_group cT zmodType finType.
Definition finGroupType := fin_group baseFinGroupType zmodType.
Definition join_baseFinGroupType := base_group zmodType zmodType finType.
Definition join_finGroupType := fin_group join_baseFinGroupType zmodType.

End ClassDef.

Module Exports.
Coercion base : class_of >-> GRing.UnitAlgebra.class_of.
Coercion base2 : class_of >-> Algebra.class_of.
Coercion base3 : class_of >-> UnitRing.class_of.
Coercion sort : type >-> Sortclass.
Coercion eqType : type >-> Equality.type.
Canonical eqType.
Coercion choiceType : type >-> Choice.type.
Canonical choiceType.
Coercion countType : type >-> Countable.type.
Canonical countType.
Coercion finType : type >-> Finite.type.
Canonical finType.
Coercion zmodType : type >-> GRing.Zmodule.type.
Canonical zmodType.
Coercion finZmodType : type >-> Zmodule.type.
Canonical finZmodType.
Coercion ringType : type >-> GRing.Ring.type.
Canonical ringType.
Coercion finRingType : type >-> Ring.type.
Canonical finRingType.
Coercion unitRingType : type >-> GRing.UnitRing.type.
Canonical unitRingType.
Coercion finUnitRingType : type >-> UnitRing.type.
Canonical finUnitRingType.
Coercion lmodType : type >-> GRing.Lmodule.type.
Canonical lmodType.
Coercion finLmodType : type >-> Lmodule.type.
Canonical finLmodType.
Coercion lalgType : type >-> GRing.Lalgebra.type.
Canonical lalgType.
Coercion finLalgType : type >-> Lalgebra.type.
Canonical finLalgType.
Coercion algType : type >-> GRing.Algebra.type.
Canonical algType.
Coercion finAlgType : type >-> Algebra.type.
Canonical finAlgType.
Coercion unitAlgType : type >-> GRing.UnitAlgebra.type.
Canonical unitAlgType.
Canonical join_finType.
Canonical join_finZmodType.
Canonical join_finLmodType.
Canonical join_finRingType.
Canonical join_finLalgType.
Canonical join_finAlgType.
Canonical ljoin_finUnitRingType.
Canonical fljoin_finUnitRingType.
Canonical njoin_finUnitRingType.
Canonical fnjoin_finUnitRingType.
Canonical ajoin_finUnitRingType.
Canonical fajoin_finUnitRingType.
Canonical ujoin_finLmodType.
Canonical ujoin_finLalgType.
Canonical ujoin_finAlgType.
Notation finUnitAlgType R := (type (Phant R)).
Notation "[ 'finUnitAlgType' R 'of' T ]" := (do_pack (@pack _ (Phant R)) T)
  (at level 0, format "[ 'finUnitAlgType' R 'of' T ]") : form_scope.
Canonical baseFinGroupType.
Canonical finGroupType.
Canonical join_baseFinGroupType.
Canonical join_finGroupType.
End Exports.

End UnitAlgebra.
Import UnitAlgebra.Exports.

Module Theory.

Definition zmod1gE := zmod1gE.
Definition zmodVgE := zmodVgE.
Definition zmodMgE := zmodMgE.
Definition zmodXgE := zmodXgE.
Definition zmod_mulgC := zmod_mulgC.
Definition zmod_abelian := zmod_abelian.
Definition val_unit1 := val_unit1.
Definition val_unitM := val_unitM.
Definition val_unitX := val_unitX.
Definition val_unitV := val_unitV.
Definition unit_actE := unit_actE.

End Theory.

End FinRing.

Import FinRing.
Export Zmodule.Exports Ring.Exports ComRing.Exports.
Export UnitRing.Exports UnitsGroupExports ComUnitRing.Exports.
Export IntegralDomain.Exports Field.Exports DecField.Exports.
Export Lmodule.Exports Lalgebra.Exports Algebra.Exports UnitAlgebra.Exports.

Notation "{ 'unit' R }" := (unit_of (Phant R))
  (at level 0, format "{ 'unit' R }") : type_scope.
Notation "''U'" := (unit_action _) (at level 8) : action_scope.
Notation "''U'" := (unit_groupAction _) (at level 8) : groupAction_scope.