Built with Alectryon, running Coq+SerAPI v8.19.0+0.19.3. 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.
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
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.Require Import WildCat.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'
(funxy : G => class_of R (x * y)) x y =
(funxy : G => class_of R (x * y)) 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'
(funxy : G => class_of R (x * y)) x y =
(funxy : G => class_of R (x * y)) 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
(funxyz : G / R =>
congquot_sgop x (congquot_sgop y z) =
congquot_sgop (congquot_sgop x y) z) (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: foralln : G, N n -> f n = 1 x, y: G n: N (x^ * y)
f x = f y
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1 x, y: G n: N (x^ * y)
1 = (f x)^ * f y
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 1 x, y: G n: N (x^ * y)
1 = f x^ * f y
G: Group N: NormalSubgroup G A: Group f: G $-> A h: foralln : G, N n -> f n = 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 (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)))
(x * 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)))
x *
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)))
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 (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)))
(x * class_of (in_cosetL N) a) =
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)))
x *
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)))
(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 (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)))
(x * class_of (in_cosetL N) y) =
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)))
x *
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)))
(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 (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) y) =
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) 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 (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)))
(class_of (in_cosetL N) a * class_of (in_cosetL N) y) =
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)))
(class_of (in_cosetL N) a) *
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)))
(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
(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
(qglue
(internal_paths_rew_r (fung : G => N g)
(issubgroup_in_inv n h)
(right_identity (inv n))
:
in_cosetL N n mon_unit)) @ grp_homo_unit f
:
(f $o grp_quotient_map) n = 1)) == 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
(qglue
(internal_paths_rew_r (fung : G => N g)
(issubgroup_in_inv n h)
(right_identity (inv n)))) @
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
(qglue
(internal_paths_rew_r (fung : G => N g)
(issubgroup_in_inv n h)
(right_identity (inv n)))) @
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
(qglue
(internal_paths_rew_r (fung : G => N g)
(issubgroup_in_inv n h)
(right_identity (inv n))
:
in_cosetL N n mon_unit)) @ grp_homo_unit f
:
(f $o grp_quotient_map) n = 1))
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)
(qglue
(internal_paths_rew_r (fung : G => N g)
(issubgroup_in_inv n h)
(right_identity (inv n)))) @
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: forallx : G, Decidable (H x)
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
class_of (funxy : G => N (x^ * y)) x.1 = group_unit
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 =>
qglue
(issubgroup_in_op (x0.1)^ 1
(issubgroup_in_inv x0.1 x0.2)
issubgroup_in_unit)) 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 =>
qglue
(issubgroup_in_op (x0.1)^ 1
(issubgroup_in_inv x0.1 x0.2)
issubgroup_in_unit)) 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 =>
qglue
(issubgroup_in_op (x.1)^ 1
(issubgroup_in_inv x.1 x.2)
issubgroup_in_unit))
(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