Built with Alectryon. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
From HoTT Require Import Basics Types.From HoTT Require Import Basics Types.Require Import Truncations.Core.Require Import Algebra.Congruence.Require Import Algebra.Groups.Group.Require Import Algebra.Groups.Subgroup.Require Export Colimits.Quotient.Require Import HSet.Require Import Spaces.Finite.Finite.From HoTT.WildCat Require Import Core Equiv.Require Import Modalities.Modality.(** * Quotient groups *)LocalOpen Scope mc_scope.LocalOpen Scope mc_mult_scope.LocalOpen Scope wc_iso_scope.(** ** Congruence quotients *)SectionGroupCongruenceQuotient.(** A congruence on a group is a relation satisfying [R x x' -> R y y' -> R (x * y) (x' * y')]. Because we also require that [R] is reflexive, we also know that [R y y' -> R (x * y) (x * y')] for any [x], and similarly for multiplication on the right by [x]. We don't need to assume that [R] is symmetric or transitive. *)Context {G : Group} {R : Relation G} `{!IsCongruence R, !Reflexive R}.(** The type underlying the quotient group is [Quotient R]. *)DefinitionCongruenceQuotient := G / R.
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
SgOp CongruenceQuotient
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
SgOp CongruenceQuotient
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
G -> G -> CongruenceQuotient
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
forallaa'b : G, R a a' -> ?dclass a b = ?dclass a' b
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
forallabb' : G, R b b' -> ?dclass a b = ?dclass a b'
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
G -> G -> CongruenceQuotient
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G
CongruenceQuotient
exact (class_of _ (x * y)).
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
forallaa'b : G,
R a a' ->
(funxy : G => class_of R (x * y)) a b =
(funxy : G => class_of R (x * y)) a' b
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, x', y: G p: R x x'
(funx0y0 : G => class_of R (x0 * y0)) x y =
(funx0y0 : G => class_of R (x0 * y0)) x' y
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, x', y: G p: R x x'
R (x * y) (x' * y)
byapply iscong.
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
forallabb' : G,
R b b' ->
(funxy : G => class_of R (x * y)) a b =
(funxy : G => class_of R (x * y)) a b'
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y, y': G q: R y y'
(funx0y0 : G => class_of R (x0 * y0)) x y =
(funx0y0 : G => class_of R (x0 * y0)) x y'
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y, y': G q: R y y'
R (x * y) (x * y')
byapply iscong.Defined.
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
MonUnit CongruenceQuotient
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
MonUnit CongruenceQuotient
apply class_of, mon_unit.Defined.
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
Inverse CongruenceQuotient
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
Inverse CongruenceQuotient
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
G -> CongruenceQuotient
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
forallab : G, R a b -> ?pclass a = ?pclass b
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
forallab : G, R a b -> (class_of R o inv) a = (class_of R o inv) b
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
class_of R x^ = class_of R y^
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
class_of R x^ = class_of R (y^ * (y * x^))
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
class_of R (y^ * (y * x^)) = class_of R y^
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
class_of R x^ = class_of R (y^ * (y * x^))
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
class_of R x^ = class_of R (y^ * y * x^)
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
class_of R x^ = class_of R (1 * x^)
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
class_of R x^ = class_of R x^
reflexivity.
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
class_of R (y^ * (y * x^)) = class_of R y^
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
class_of R (y^ * (y * x^)) = class_of R (y^ * (x * x^))
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
class_of R (y^ * (x * x^)) = class_of R y^
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
class_of R (y^ * (y * x^)) = class_of R (y^ * (x * x^))
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
R y^ y^
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
R x y
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
R x^ x^
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
R x y
exact p.
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
class_of R (y^ * (x * x^)) = class_of R y^
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
class_of R (y^ * 1) = class_of R y^
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y: G p: R x y
class_of R y^ = class_of R y^
reflexivity.Defined.
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
Associative congquot_sgop
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
Associative congquot_sgop
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y, z: G
(funx0y0z0 : G / R =>
congquot_sgop x0 (congquot_sgop y0 z0) =
congquot_sgop (congquot_sgop x0 y0) z0) (class_of R x)
(class_of R y) (class_of R z)
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x, y, z: G
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
RightInverse sg_op inv 1
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R
RightInverse sg_op inv 1
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x: G
class_of R x * (class_of R x)^ = 1
G: Group R: Relation G IsCongruence0: IsCongruence R Reflexive0: Reflexive R x: G
x * x^ = 1
rapply right_inverse.Defined.GlobalOpaque quotientgroup_rightinverse.#[export] Instanceisgroup_quotientgroup : IsGroup CongruenceQuotient := {}.EndGroupCongruenceQuotient.(** ** Sets of cosets *)SectionCosets.Context (G : Group) (H : Subgroup G).DefinitionLeftCoset := G / in_cosetL H.(** TODO: Way too many universes, needs fixing *)(** The set of left cosets of a finite subgroup of a finite group is finite. *)
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H
Finite LeftCoset
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H
Finite LeftCoset
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H
Finite G
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H
is_mere_relation G (in_cosetL H)
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H
Reflexive (in_cosetL H)
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H
Transitive (in_cosetL H)
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H
Symmetric (in_cosetL H)
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H
forallxy : G, Decidable (in_cosetL H x y)
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H
forallxy : G, Decidable (in_cosetL H x y)
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H x, y: G
Decidable (in_cosetL H x y)
apply (detachable_finite_subset H).Defined.(** The index of a subgroup is the number of cosets of the subgroup. *)Definitionsubgroup_index `{Univalence, Finite G, Finite H} : nat
:= fcard LeftCoset.DefinitionRightCoset := G / in_cosetR H.(** The set of left cosets is equivalent to the set of right coset. *)
G: Group H: Subgroup G
LeftCoset <~> RightCoset
G: Group H: Subgroup G
LeftCoset <~> RightCoset
G: Group H: Subgroup G
G -> G
G: Group H: Subgroup G
IsEquiv ?f
G: Group H: Subgroup G
forallab : G, in_cosetL H a b <-> in_cosetR H (?f a) (?f b)
G: Group H: Subgroup G
G -> G
exact inv.
G: Group H: Subgroup G
IsEquiv inv
exact _.
G: Group H: Subgroup G
forallab : G, in_cosetL H a b <-> in_cosetR H a^ b^
G: Group H: Subgroup G x, y: G
H (x^ * y) <-> H (x^ * (y^)^)
byrewrite grp_inv_inv.Defined.(** The set of right cosets of a finite subgroup of a finite group is finite since it is equivalent to the set of left cosets. *)
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H
Finite RightCoset
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H
Finite RightCoset
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H
?Goal <~> RightCoset
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H
Finite ?Goal
G: Group H: Subgroup G H0: Univalence H1: Finite G H2: Finite H
Finite LeftCoset
exact _.Defined.EndCosets.(** ** Quotient groups *)(** Now we can define the quotient group by a normal subgroup. *)SectionQuotientGroup.Context (G : Group) (N : NormalSubgroup G).
G: Group N: NormalSubgroup G
IsCongruence (in_cosetL N)
G: Group N: NormalSubgroup G
IsCongruence (in_cosetL N)
G: Group N: NormalSubgroup G
forallxx'yy' : G,
in_cosetL N x x' -> in_cosetL N y y' -> in_cosetL N (x * y) (x' * y')
intros; byapply in_cosetL_cong.Defined.
G: Group N: NormalSubgroup G
IsCongruence (in_cosetR N)
G: Group N: NormalSubgroup G
IsCongruence (in_cosetR N)
G: Group N: NormalSubgroup G
forallxx'yy' : G,
in_cosetR N x x' -> in_cosetR N y y' -> in_cosetR N (x * y) (x' * y')
intros; byapply in_cosetR_cong.Defined.(** Now we have to make a choice whether to pick the left or right cosets. Due to existing convention we shall pick left cosets but we note that we could equally have picked right. *)DefinitionQuotientGroup : Group
:= Build_Group (LeftCoset G N) _ _ _ _.
G: Group N: NormalSubgroup G
G $-> QuotientGroup
G: Group N: NormalSubgroup G
G $-> QuotientGroup
G: Group N: NormalSubgroup G
G -> QuotientGroup
G: Group N: NormalSubgroup G
IsSemiGroupPreserving ?grp_homo_map
G: Group N: NormalSubgroup G
IsSemiGroupPreserving (class_of (in_cosetL N))
intros ??; reflexivity.Defined.
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1
QuotientGroup $-> A
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1
QuotientGroup $-> A
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1
QuotientGroup -> A
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1
IsSemiGroupPreserving ?grp_homo_map
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1
QuotientGroup -> A
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1
G -> A
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1
forallab : G, in_cosetL N a b -> ?pclass a = ?pclass b
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1
G -> A
exact f.
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1
forallab : G, in_cosetL N a b -> f a = f b
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln0 : G, N n0 -> f n0 = 1 x, y: G n: N (x^ * y)
f x = f y
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln0 : G, N n0 -> f n0 = 1 x, y: G n: N (x^ * y)
1 = (f x)^ * f y
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln0 : G, N n0 -> f n0 = 1 x, y: G n: N (x^ * y)
1 = f x^ * f y
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln0 : G, N n0 -> f n0 = 1 x, y: G n: N (x^ * y)
1 = f (x^ * y)
symmetry; apply h; assumption.
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1
IsSemiGroupPreserving
(Quotient_rec (in_cosetL N) A f
((fun (xy : G) (n : N (x^ * y)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x * y) n)^ @ grp_homo_op f (inv x) y) @
ap (funy0 : A => y0 * f y) (grp_homo_inv f x)))
:
forallab : G, in_cosetL N a b -> f a = f b))
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1 x: QuotientGroup
forally : QuotientGroup,
Quotient_rec (in_cosetL N) A f
(fun (x0y0 : G) (n : N (x0^ * y0)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x0 * y0) n)^ @ grp_homo_op f (inv x0) y0) @
ap (funy1 : A => y1 * f y0) (grp_homo_inv f x0)))
(x * y) =
Quotient_rec (in_cosetL N) A f
(fun (x0y0 : G) (n : N (x0^ * y0)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x0 * y0) n)^ @ grp_homo_op f (inv x0) y0) @
ap (funy1 : A => y1 * f y0) (grp_homo_inv f x0)))
x *
Quotient_rec (in_cosetL N) A f
(fun (x0y0 : G) (n : N (x0^ * y0)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x0 * y0) n)^ @ grp_homo_op f (inv x0) y0) @
ap (funy1 : A => y1 * f y0) (grp_homo_inv f x0)))
y
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1 x: QuotientGroup
foralla : G,
Quotient_rec (in_cosetL N) A f
(fun (x0y : G) (n : N (x0^ * y)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x0 * y) n)^ @ grp_homo_op f (inv x0) y) @
ap (funy0 : A => y0 * f y) (grp_homo_inv f x0)))
(x * class_of (in_cosetL N) a) =
Quotient_rec (in_cosetL N) A f
(fun (x0y : G) (n : N (x0^ * y)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x0 * y) n)^ @ grp_homo_op f (inv x0) y) @
ap (funy0 : A => y0 * f y) (grp_homo_inv f x0)))
x *
Quotient_rec (in_cosetL N) A f
(fun (x0y : G) (n : N (x0^ * y)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x0 * y) n)^ @ grp_homo_op f (inv x0) y) @
ap (funy0 : A => y0 * f y) (grp_homo_inv f x0)))
(class_of (in_cosetL N) a)
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1 x: QuotientGroup y: G
Quotient_rec (in_cosetL N) A f
(fun (x0y0 : G) (n : N (x0^ * y0)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x0 * y0) n)^ @ grp_homo_op f (inv x0) y0) @
ap (funy1 : A => y1 * f y0) (grp_homo_inv f x0)))
(x * class_of (in_cosetL N) y) =
Quotient_rec (in_cosetL N) A f
(fun (x0y0 : G) (n : N (x0^ * y0)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x0 * y0) n)^ @ grp_homo_op f (inv x0) y0) @
ap (funy1 : A => y1 * f y0) (grp_homo_inv f x0)))
x *
Quotient_rec (in_cosetL N) A f
(fun (x0y0 : G) (n : N (x0^ * y0)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x0 * y0) n)^ @ grp_homo_op f (inv x0) y0) @
ap (funy1 : A => y1 * f y0) (grp_homo_inv f x0)))
(class_of (in_cosetL N) y)
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1 y: G
forallx : QuotientGroup,
Quotient_rec (in_cosetL N) A f
(fun (x0y0 : G) (n : N (x0^ * y0)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x0 * y0) n)^ @ grp_homo_op f (inv x0) y0) @
ap (funy1 : A => y1 * f y0) (grp_homo_inv f x0)))
(x * class_of (in_cosetL N) y) =
Quotient_rec (in_cosetL N) A f
(fun (x0y0 : G) (n : N (x0^ * y0)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x0 * y0) n)^ @ grp_homo_op f (inv x0) y0) @
ap (funy1 : A => y1 * f y0) (grp_homo_inv f x0)))
x *
Quotient_rec (in_cosetL N) A f
(fun (x0y0 : G) (n : N (x0^ * y0)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x0 * y0) n)^ @ grp_homo_op f (inv x0) y0) @
ap (funy1 : A => y1 * f y0) (grp_homo_inv f x0)))
(class_of (in_cosetL N) y)
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1 y: G
foralla : G,
Quotient_rec (in_cosetL N) A f
(fun (xy0 : G) (n : N (x^ * y0)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x * y0) n)^ @ grp_homo_op f (inv x) y0) @
ap (funy1 : A => y1 * f y0) (grp_homo_inv f x)))
(class_of (in_cosetL N) a * class_of (in_cosetL N) y) =
Quotient_rec (in_cosetL N) A f
(fun (xy0 : G) (n : N (x^ * y0)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x * y0) n)^ @ grp_homo_op f (inv x) y0) @
ap (funy1 : A => y1 * f y0) (grp_homo_inv f x)))
(class_of (in_cosetL N) a) *
Quotient_rec (in_cosetL N) A f
(fun (xy0 : G) (n : N (x^ * y0)) =>
letX := equiv_fun grp_moveR_M1 in
X
(((h (inv x * y0) n)^ @ grp_homo_op f (inv x) y0) @
ap (funy1 : A => y1 * f y0) (grp_homo_inv f x)))
(class_of (in_cosetL N) y)
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1 y, x: G
f (x * y) = f x * f y
apply grp_homo_op.Defined.
G: Group N: NormalSubgroup G P: QuotientGroup -> Type H: forallx : QuotientGroup, IsHProp (P x) H1: forallx : G, P (grp_quotient_map x)
forallx : QuotientGroup, P x
G: Group N: NormalSubgroup G P: QuotientGroup -> Type H: forallx : QuotientGroup, IsHProp (P x) H1: forallx : G, P (grp_quotient_map x)
forallx : QuotientGroup, P x
G: Group N: NormalSubgroup G P: QuotientGroup -> Type H: forallx : QuotientGroup, IsHProp (P x) H1: forallx : G, P (grp_quotient_map x)
foralla : G, P (class_of (in_cosetL N) a)
exact H1.Defined.EndQuotientGroup.Arguments QuotientGroup G N : simpl never.Arguments grp_quotient_map {_ _}.Notation"G / N" := (QuotientGroup G N) : group_scope.(** Rephrasing that lets you specify the normality proof *)DefinitionQuotientGroup' (G : Group) (N : Subgroup G) (H : IsNormalSubgroup N)
:= QuotientGroup G (Build_NormalSubgroup G N H).LocalOpen Scope group_scope.(** Computation rule for [grp_quotient_rec]. *)
F: Funext G: Group N: NormalSubgroup G H, A: Group f: G $-> A h: foralln : G, N n -> f n = 1
grp_quotient_rec G N f h $o grp_quotient_map = f
F: Funext G: Group N: NormalSubgroup G H, A: Group f: G $-> A h: foralln : G, N n -> f n = 1
grp_quotient_rec G N f h $o grp_quotient_map = f
apply equiv_path_grouphomomorphism; reflexivity.Defined.(** Computation rule for [grp_quotient_rec]. *)Definitiongrp_quotient_rec_beta' {G : Group}
(N : NormalSubgroup G) (H : Group)
{A : Group} (f : G $-> A)
(h : foralln:G, N n -> f n = mon_unit)
: (grp_quotient_rec G N f h) $o grp_quotient_map == f
:= fun_ => idpath.(** The proof of normality is irrelevant up to equivalence. It is unfortunate that it doesn't hold definitionally. *)
G: Group H: Subgroup G k, k': IsNormalSubgroup H
QuotientGroup' G H k ≅ QuotientGroup' G H k'
G: Group H: Subgroup G k, k': IsNormalSubgroup H
QuotientGroup' G H k ≅ QuotientGroup' G H k'
G: Group H: Subgroup G k, k': IsNormalSubgroup H
QuotientGroup' G H k <~> QuotientGroup' G H k'
G: Group H: Subgroup G k, k': IsNormalSubgroup H
IsSemiGroupPreserving ?f
G: Group H: Subgroup G k, k': IsNormalSubgroup H
IsSemiGroupPreserving 1%equiv
G: Group H: Subgroup G k, k': IsNormalSubgroup H x: QuotientGroup' G H k
forally : QuotientGroup' G H k, 1%equiv (x * y) = 1%equiv x * 1%equiv y
G: Group H: Subgroup G k, k': IsNormalSubgroup H y: G
forallx : QuotientGroup' G H k,
(funx0 : Quotient
(in_cosetL
{| normalsubgroup_subgroup := H; normalsubgroup_isnormal := k |}) =>
1%equiv (x * x0) = 1%equiv x * 1%equiv x0)
(class_of
(in_cosetL
{| normalsubgroup_subgroup := H; normalsubgroup_isnormal := k |})
y)
G: Group H: Subgroup G k, k': IsNormalSubgroup H y, x: G
reflexivity.Defined.(** The quotient map is trivial on the normal subgroup. *)
G: Group N: NormalSubgroup G n: G inN: N n
grp_quotient_map n = 1
G: Group N: NormalSubgroup G n: G inN: N n
grp_quotient_map n = 1
G: Group N: NormalSubgroup G n: G inN: N n
N (n^ * 1)
G: Group N: NormalSubgroup G n: G inN: N n
N n^
byapply issubgroup_in_inv.Defined.(** The universal mapping property for groups *)
F: Funext G: Group N: NormalSubgroup G H: Group
{f : G $-> H & foralln : G, N n -> f n = 1} <~> (G / N $-> H)
F: Funext G: Group N: NormalSubgroup G H: Group
{f : G $-> H & foralln : G, N n -> f n = 1} <~> (G / N $-> H)
F: Funext G: Group N: NormalSubgroup G H: Group
{f : G $-> H & foralln : G, N n -> f n = 1} -> G / N $-> H
F: Funext G: Group N: NormalSubgroup G H: Group
(G / N $-> H) -> {f : G $-> H & foralln : G, N n -> f n = 1}
F: Funext G: Group N: NormalSubgroup G H: Group
?f o ?g == idmap
F: Funext G: Group N: NormalSubgroup G H: Group
?g o ?f == idmap
F: Funext G: Group N: NormalSubgroup G H: Group
{f : G $-> H & foralln : G, N n -> f n = 1} -> G / N $-> H
F: Funext G: Group N: NormalSubgroup G H: Group f: G $-> H p: foralln : G, N n -> f n = 1
G / N $-> H
exact (grp_quotient_rec _ _ f p).
F: Funext G: Group N: NormalSubgroup G H: Group
(G / N $-> H) -> {f : G $-> H & foralln : G, N n -> f n = 1}
F: Funext G: Group N: NormalSubgroup G H: Group f: G / N $-> H
{f0 : G $-> H & foralln : G, N n -> f0 n = 1}
F: Funext G: Group N: NormalSubgroup G H: Group f: G / N $-> H
foralln : G, N n -> (f $o grp_quotient_map) n = 1
F: Funext G: Group N: NormalSubgroup G H: Group f: G / N $-> H n: G h: N n
(f $o grp_quotient_map) n = 1
F: Funext G: Group N: NormalSubgroup G H: Group f: G / N $-> H n: G h: N n
(f $o grp_quotient_map) n = f 1
F: Funext G: Group N: NormalSubgroup G H: Group f: G / N $-> H n: G h: N n
grp_quotient_map n = 1
byapply grp_quotient_map_trivial.
F: Funext G: Group N: NormalSubgroup G H: Group
(funX : {f : G $-> H & foralln : G, N n -> f n = 1} =>
(fun (f : G $-> H) (p : foralln : G, N n -> f n = 1) =>
grp_quotient_rec G N f p) X.1 X.2)
o (funf : G / N $-> H =>
(f $o grp_quotient_map;
fun (n : G) (h : N n) =>
ap f (grp_quotient_map_trivial N n h) @ grp_homo_unit f)) ==
idmap
F: Funext G: Group N: NormalSubgroup G H: Group f: G / N $-> H
grp_quotient_rec G N (f $o grp_quotient_map)
(fun (n : G) (h : N n) =>
ap f (grp_quotient_map_trivial N n h) @ grp_homo_unit f) =
f
F: Funext G: Group N: NormalSubgroup G H: Group f: G / N $-> H
grp_quotient_rec G N (f $o grp_quotient_map)
(fun (n : G) (h : N n) =>
ap f (grp_quotient_map_trivial N n h) @ grp_homo_unit f) ==
f
by srapply Quotient_ind_hprop.
F: Funext G: Group N: NormalSubgroup G H: Group
(funf : G / N $-> H =>
(f $o grp_quotient_map;
fun (n : G) (h : N n) =>
ap f (grp_quotient_map_trivial N n h) @ grp_homo_unit f))
o (funX : {f : G $-> H & foralln : G, N n -> f n = 1} =>
(fun (f : G $-> H) (p : foralln : G, N n -> f n = 1) =>
grp_quotient_rec G N f p) X.1 X.2) ==
idmap
F: Funext G: Group N: NormalSubgroup G H: Group f: G $-> H p: foralln : G, N n -> f n = 1
(grp_quotient_rec G N f p $o grp_quotient_map;
fun (n : G) (h : N n) =>
ap (grp_quotient_rec G N f p) (grp_quotient_map_trivial N n h) @
grp_homo_unit (grp_quotient_rec G N f p)) = (f; p)
F: Funext G: Group N: NormalSubgroup G H: Group f: G $-> H p: foralln : G, N n -> f n = 1
grp_homo_compose (grp_quotient_rec G N f p) grp_quotient_map = f
exact (grp_quotient_rec_beta N H f p).Defined.SectionFirstIso.Context `{Funext} {A B : Group} (phi : A $-> B).(** First we define a map from the quotient by the kernel of phi into the image of phi *)
H: Funext A, B: Group phi: A $-> B
A / grp_kernel phi $-> grp_image phi
H: Funext A, B: Group phi: A $-> B
A / grp_kernel phi $-> grp_image phi
H: Funext A, B: Group phi: A $-> B
A $-> grp_image phi
H: Funext A, B: Group phi: A $-> B
foralln : A, grp_kernel phi n -> ?f n = 1
H: Funext A, B: Group phi: A $-> B
A $-> grp_image phi
srapply grp_homo_image_in.
H: Funext A, B: Group phi: A $-> B
foralln : A, grp_kernel phi n -> grp_homo_image_in phi n = 1
H: Funext A, B: Group phi: A $-> B n: A x: grp_kernel phi n
grp_homo_image_in phi n = 1
byapply path_sigma_hprop.Defined.(** The underlying map of this homomorphism is an equivalence *)
H: Funext A, B: Group phi: A $-> B
IsEquiv grp_image_quotient
H: Funext A, B: Group phi: A $-> B
IsEquiv grp_image_quotient
H: Funext A, B: Group phi: A $-> B
IsConnMap (Tr (-1)) grp_image_quotient
H: Funext A, B: Group phi: A $-> B
IsEmbedding grp_image_quotient
H: Funext A, B: Group phi: A $-> B
IsEmbedding grp_image_quotient
H: Funext A, B: Group phi: A $-> B
IsInjective grp_image_quotient
H: Funext A, B: Group phi: A $-> B
forallab : A,
(funxy : Quotient (in_cosetL (grp_kernel phi)) =>
grp_image_quotient x = grp_image_quotient y -> x = y)
(class_of (in_cosetL (grp_kernel phi)) a)
(class_of (in_cosetL (grp_kernel phi)) b)
H: Funext A, B: Group phi: A $-> B x, y: A h: (phi x; grp_image_in phi x) = (phi y; grp_image_in phi y)
class_of (in_cosetL (grp_kernel phi)) x =
class_of (in_cosetL (grp_kernel phi)) y
H: Funext A, B: Group phi: A $-> B x, y: A h: (phi x; grp_image_in phi x) = (phi y; grp_image_in phi y)
phi (x^ * y) = 1
H: Funext A, B: Group phi: A $-> B x, y: A h: phi x = phi y
phi (x^ * y) = 1
H: Funext A, B: Group phi: A $-> B x, y: A h: phi x = phi y
phi (x^ * y) = 1
H: Funext A, B: Group phi: A $-> B x, y: A h: phi x = phi y
(phi y)^ * phi y = 1
apply grp_inv_l.Defined.(** First isomorphism theorem for groups *)
H: Funext A, B: Group phi: A $-> B
A / grp_kernel phi ≅ grp_image phi
H: Funext A, B: Group phi: A $-> B
A / grp_kernel phi ≅ grp_image phi
exact (Build_GroupIsomorphism _ _ grp_image_quotient _).Defined.EndFirstIso.(** Quotient groups are finite. *)(** Note that we cannot constructively conclude that the normal subgroup [H] must be finite since [G] is, therefore we keep it as an assumption. *)
U: Univalence G: Group H: NormalSubgroup G fin_G: Finite G fin_H: Finite H
Finite (G / H)
U: Univalence G: Group H: NormalSubgroup G fin_G: Finite G fin_H: Finite H
Finite (G / H)
U: Univalence G: Group H: NormalSubgroup G fin_G: Finite G fin_H: Finite H
Finite G
U: Univalence G: Group H: NormalSubgroup G fin_G: Finite G fin_H: Finite H
is_mere_relation G (in_cosetL H)
U: Univalence G: Group H: NormalSubgroup G fin_G: Finite G fin_H: Finite H
Reflexive (in_cosetL H)
U: Univalence G: Group H: NormalSubgroup G fin_G: Finite G fin_H: Finite H
Transitive (in_cosetL H)
U: Univalence G: Group H: NormalSubgroup G fin_G: Finite G fin_H: Finite H
Symmetric (in_cosetL H)
U: Univalence G: Group H: NormalSubgroup G fin_G: Finite G fin_H: Finite H
forallxy : G, Decidable (in_cosetL H x y)
U: Univalence G: Group H: NormalSubgroup G fin_G: Finite G fin_H: Finite H
forallxy : G, Decidable (in_cosetL H x y)
U: Univalence G: Group H: NormalSubgroup G fin_G: Finite G fin_H: Finite H x, y: G
Decidable (in_cosetL H x y)
U: Univalence G: Group H: NormalSubgroup G fin_G: Finite G fin_H: Finite H x, y: G dec_H:= detachable_finite_subset H: forallx0 : G, Decidable (H x0)
Decidable (in_cosetL H x y)
apply dec_H.Defined.
H: Univalence G: Group N: NormalSubgroup G
GroupIsomorphism N (grp_kernel grp_quotient_map)
H: Univalence G: Group N: NormalSubgroup G
GroupIsomorphism N (grp_kernel grp_quotient_map)
H: Univalence G: Group N: NormalSubgroup G
GroupHomomorphism N (grp_kernel grp_quotient_map)
H: Univalence G: Group N: NormalSubgroup G
IsEquiv ?grp_iso_homo
H: Univalence G: Group N: NormalSubgroup G
GroupHomomorphism N (grp_kernel grp_quotient_map)
H: Univalence G: Group N: NormalSubgroup G
grp_quotient_map $o subgroup_incl N == grp_homo_const
H: Univalence G: Group N: NormalSubgroup G x: N
(grp_quotient_map $o subgroup_incl N) x = grp_homo_const x
H: Univalence G: Group N: NormalSubgroup G x: N
N (subgroup_incl N x)
exact x.2.
H: Univalence G: Group N: NormalSubgroup G
IsEquiv
(grp_kernel_corec (subgroup_incl N)
((funx : N => grp_quotient_map_trivial N (subgroup_incl N x) x.2)
:
grp_quotient_map $o subgroup_incl N == grp_homo_const))
H: Univalence G: Group N: NormalSubgroup G
IsConnMap (Tr (-1))
(grp_kernel_corec (subgroup_incl N)
(funx : N => grp_quotient_map_trivial N (subgroup_incl N x) x.2))
H: Univalence G: Group N: NormalSubgroup G
IsEmbedding
(grp_kernel_corec (subgroup_incl N)
(funx : N => grp_quotient_map_trivial N (subgroup_incl N x) x.2))
H: Univalence G: Group N: NormalSubgroup G
IsConnMap (Tr (-1))
(grp_kernel_corec (subgroup_incl N)
(funx : N => grp_quotient_map_trivial N (subgroup_incl N x) x.2))
H: Univalence G: Group N: NormalSubgroup G g: G p: grp_kernel grp_quotient_map g
IsConnected (Tr (-1))
(hfiber
(grp_kernel_corec (subgroup_incl N)
(funx : N => grp_quotient_map_trivial N (subgroup_incl N x) x.2))
(g; p))
H: Univalence G: Group N: NormalSubgroup G g: G p: grp_kernel grp_quotient_map g
Tr (-1)
(hfiber
(grp_kernel_corec (subgroup_incl N)
(funx : N => grp_quotient_map_trivial N (subgroup_incl N x) x.2))
(g; p))
H: Univalence G: Group N: NormalSubgroup G g: G p: grp_kernel grp_quotient_map g
N g
H: Univalence G: Group N: NormalSubgroup G g: G p: grp_kernel grp_quotient_map g
(funx : N =>
grp_kernel_corec (subgroup_incl N)
(funx0 : N => grp_quotient_map_trivial N (subgroup_incl N x0) x0.2) x =
(g; p)) (g; ?proj2)
H: Univalence G: Group N: NormalSubgroup G g: G p: grp_kernel grp_quotient_map g
N g
H: Univalence G: Group N: NormalSubgroup G g: G p: grp_kernel grp_quotient_map g
N (1^ * g)
H: Univalence G: Group N: NormalSubgroup G g: G p: grp_kernel grp_quotient_map g
class_of (funxy : G => N (x^ * y)) 1 =
class_of (funxy : G => N (x^ * y)) g
exact p^%path.
H: Univalence G: Group N: NormalSubgroup G g: G p: grp_kernel grp_quotient_map g
(funx : N =>
grp_kernel_corec (subgroup_incl N)
(funx0 : N => grp_quotient_map_trivial N (subgroup_incl N x0) x0.2) x =
(g; p))
(g;
internal_paths_rew N
(internal_paths_rew (fung0 : G => N (g0 * g))
(related_quotient_paths (funxy : G => N (x^ * y)) 1 g p^)
inverse_mon_unit)
(grp_unit_l g))
H: Univalence G: Group N: NormalSubgroup G g: G p: grp_kernel grp_quotient_map g
(grp_kernel_corec (subgroup_incl N)
(funx : N => grp_quotient_map_trivial N (subgroup_incl N x) x.2)
(g;
internal_paths_rew N
(internal_paths_rew (fung0 : G => N (g0 * g))
(related_quotient_paths (funxy : G => N (x^ * y)) 1 g p^)
inverse_mon_unit)
(grp_unit_l g))).1 =
(g; p).1
reflexivity.Defined.(** When the normal subgroup [N] is trivial, the inclusion map [G $-> G / N] is an isomorphism. *)
G: Group N: NormalSubgroup G triv: IsTrivialGroup N
CatIsEquiv grp_quotient_map
G: Group N: NormalSubgroup G triv: IsTrivialGroup N
CatIsEquiv grp_quotient_map
G: Group N: NormalSubgroup G triv: IsTrivialGroup N
G / N $-> G
G: Group N: NormalSubgroup G triv: IsTrivialGroup N
grp_quotient_map $o ?g $== Id (G / N)
G: Group N: NormalSubgroup G triv: IsTrivialGroup N
?g $o grp_quotient_map $== Id G
G: Group N: NormalSubgroup G triv: IsTrivialGroup N
G / N $-> G
G: Group N: NormalSubgroup G triv: IsTrivialGroup N
foralln : G, N n -> Id G n = 1
exact triv.
G: Group N: NormalSubgroup G triv: IsTrivialGroup N
grp_quotient_map $o grp_quotient_rec G N (Id G) triv $== Id (G / N)
by srapply grp_quotient_ind_hprop.
G: Group N: NormalSubgroup G triv: IsTrivialGroup N
grp_quotient_rec G N (Id G) triv $o grp_quotient_map $== Id G
reflexivity.Defined.(** The group quotient by a trivial group is isomorphic to the original group. *)Definitiongrp_quotient_trivial (G : Group) (N : NormalSubgroup G)
(triv : IsTrivialGroup N)
: G $<~> G / N
:= Build_CatEquiv grp_quotient_map.(** A quotient by a maximal subgroup is trivial. *)
G: Group N: NormalSubgroup G
IsMaximalSubgroup N -> IsTrivialGroup (maximal_subgroup (G / N))
G: Group N: NormalSubgroup G
IsMaximalSubgroup N -> IsTrivialGroup (maximal_subgroup (G / N))
G: Group N: NormalSubgroup G max: IsMaximalSubgroup N
forallx : G / N, trivial_subgroup (G / N) x
G: Group N: NormalSubgroup G max: IsMaximalSubgroup N
G: Group N: NormalSubgroup G max: IsMaximalSubgroup N x: G
trivial_subgroup (G / N) (grp_quotient_map x)
apply qglue, max.Defined.(** Conversely, a trivial quotient means the subgroup is maximal. First a version where we only assume that the quotient map is trivial. *)
H: Univalence G: Group N: NormalSubgroup G triv: forallx : G, grp_quotient_map x = 1
IsMaximalSubgroup N
H: Univalence G: Group N: NormalSubgroup G triv: forallx : G, grp_quotient_map x = 1
IsMaximalSubgroup N
H: Univalence G: Group N: NormalSubgroup G triv: forallx0 : G, grp_quotient_map x0 = 1 x: G
N x
H: Univalence G: Group N: NormalSubgroup G x: G triv: grp_quotient_map x = 1
N x
H: Univalence G: Group N: NormalSubgroup G x: G triv: in_cosetL N x 1
N x
H: Univalence G: Group N: NormalSubgroup G x: G triv: grp_quotient_map x = 1
is_mere_relation G (in_cosetL N)
H: Univalence G: Group N: NormalSubgroup G x: G triv: grp_quotient_map x = 1
Transitive (in_cosetL N)
H: Univalence G: Group N: NormalSubgroup G x: G triv: grp_quotient_map x = 1
Symmetric (in_cosetL N)
H: Univalence G: Group N: NormalSubgroup G x: G triv: grp_quotient_map x = 1
Reflexive (in_cosetL N)
H: Univalence G: Group N: NormalSubgroup G x: G triv: in_cosetL N x 1
N x
H: Univalence G: Group N: NormalSubgroup G x: G triv: in_cosetL N x 1
N x^
H: Univalence G: Group N: NormalSubgroup G x: G triv: in_cosetL N x 1
N 1
apply subgroup_in_unit.Defined.
H: Univalence G: Group N: NormalSubgroup G triv: IsTrivialGroup (maximal_subgroup (G / N))
IsMaximalSubgroup N
H: Univalence G: Group N: NormalSubgroup G triv: IsTrivialGroup (maximal_subgroup (G / N))
IsMaximalSubgroup N
H: Univalence G: Group N: NormalSubgroup G triv: IsTrivialGroup (maximal_subgroup (G / N))
forallx : G, grp_quotient_map x = 1
H: Univalence G: Group N: NormalSubgroup G triv: IsTrivialGroup (maximal_subgroup (G / N)) x: G