Built with Alectryon, running Coq+SerAPI v8.18.0+0.18.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.Groups.Group TruncType.LocalOpen Scope mc_scope.LocalOpen Scope mc_mult_scope.Generalizable VariablesG H A B C N f g.(** * Subgroups *)(** A subgroup H of a group G is a predicate (i.e. an hProp-valued type family) on G which is closed under the group operations. The group underlying H is given by the total space { g : G & H g }, defined in [subgroup_group] below. *)ClassIsSubgroup {G : Group} (H : G -> Type) := {
issubgroup_predicate : forallx, IsHProp (H x) ;
issubgroup_in_unit : H mon_unit ;
issubgroup_in_op : forallxy, H x -> H y -> H (x * y) ;
issubgroup_in_inv : forallx, H x -> H (- x) ;
}.Global Existing Instanceissubgroup_predicate.(** Smart constructor for subgroups. *)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit c: forallxy : G, H x -> H y -> H (x * - y)
IsSubgroup H
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit c: forallxy : G, H x -> H y -> H (x * - y)
IsSubgroup H
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit c: forallxy : G, H x -> H y -> H (x * - y)
forallxy : G, H x -> H y -> H (x * y)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit c: forallxy : G, H x -> H y -> H (x * - y)
forallx : G, H x -> H (- x)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit c: forallxy : G, H x -> H y -> H (x * - y)
forallxy : G, H x -> H y -> H (x * y)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit c: forallxy : G, H x -> H y -> H (x * - y) x, y: G
H x -> H y -> H (x * y)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit c: forallxy : G, H x -> H y -> H (x * - y) x, y: G hx: H x hy: H y
H (x * y)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit c: forallxy : G, H x -> H y -> H (x * - y) x, y: G hx: H x hy: H y c':= c mon_unit y: H mon_unit -> H y -> H (mon_unit * - y)
H (x * y)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit c: forallxy : G, H x -> H y -> H (x * - y) x, y: G hx: H x hy: H y c': H y -> H (mon_unit * - y)
H (x * y)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit x, y: G c: H x -> H (- y) -> H (x * - - y) hx: H x hy: H y c': H y -> H (mon_unit * - y)
H (x * y)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit x, y: G c: H x -> H (- y) -> H (x * y) hx: H x hy: H y c': H y -> H (mon_unit * - y)
H (x * y)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit x, y: G c: H x -> H (- y) -> H (x * y) hx: H x hy: H y c': H y -> H (- y)
H (x * y)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit x, y: G c: H x -> H (- y) -> H (x * y) hx: H x hy: H y c': H y -> H (- y)
H x
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit x, y: G c: H x -> H (- y) -> H (x * y) hx: H x hy: H y c': H y -> H (- y)
H (- y)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit x, y: G c: H x -> H (- y) -> H (x * y) hx: H x hy: H y c': H y -> H (- y)
H (- y)
exact (c' hy).
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit c: forallxy : G, H x -> H y -> H (x * - y)
forallx : G, H x -> H (- x)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit c: forallxy : G, H x -> H y -> H (x * - y) g: G
H g -> H (- g)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit g: G c: H g -> H (mon_unit * - g)
H g -> H (- g)
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit g: G c: H g -> H (- g)
H g -> H (- g)
assumption.Defined.(** Additional lemmas about being elements in a subgroup *)SectionIsSubgroupElements.Context {G : Group} {H : G -> Type} `{IsSubgroup G H}.
G: Group H: G -> Type H0: IsSubgroup H x, y: G
H x -> H y -> H (x * - y)
G: Group H: G -> Type H0: IsSubgroup H x, y: G
H x -> H y -> H (x * - y)
G: Group H: G -> Type H0: IsSubgroup H x, y: G p: H x q: H y
H (x * - y)
G: Group H: G -> Type H0: IsSubgroup H x, y: G p: H x q: H y
H x
G: Group H: G -> Type H0: IsSubgroup H x, y: G p: H x q: H y
H (- y)
G: Group H: G -> Type H0: IsSubgroup H x, y: G p: H x q: H y
H (- y)
byapply issubgroup_in_inv.Defined.
G: Group H: G -> Type H0: IsSubgroup H x: G
H (- x) -> H x
G: Group H: G -> Type H0: IsSubgroup H x: G
H (- x) -> H x
G: Group H: G -> Type H0: IsSubgroup H x: G
H (- x) -> H (- - x)
apply issubgroup_in_inv.Defined.
G: Group H: G -> Type H0: IsSubgroup H x, y: G
H x -> H y -> H (- x * y)
G: Group H: G -> Type H0: IsSubgroup H x, y: G
H x -> H y -> H (- x * y)
G: Group H: G -> Type H0: IsSubgroup H x, y: G p: H x q: H y
H (- x * y)
G: Group H: G -> Type H0: IsSubgroup H x, y: G p: H x q: H y
H (- x * - - y)
G: Group H: G -> Type H0: IsSubgroup H x, y: G p: H x q: H y
H (- x)
G: Group H: G -> Type H0: IsSubgroup H x, y: G p: H x q: H y
H (- y)
1,2: byapply issubgroup_in_inv.Defined.
G: Group H: G -> Type H0: IsSubgroup H x, y: G
H (x * y) -> H y -> H x
G: Group H: G -> Type H0: IsSubgroup H x, y: G
H (x * y) -> H y -> H x
G: Group H: G -> Type H0: IsSubgroup H x, y: G p: H (x * y) q: H y
H x
G: Group H: G -> Type H0: IsSubgroup H x, y: G p: H (x * y) q: H y
H (x * mon_unit)
G: Group H: G -> Type H0: IsSubgroup H x, y: G
H (x * y) -> H y -> H (x * mon_unit)
G: Group H: G -> Type H0: IsSubgroup H x, y: G
H (x * y) -> H y -> H (x * (y * - y))
G: Group H: G -> Type H0: IsSubgroup H x, y: G
H (x * y) -> H y -> H (x * y * - y)
apply issubgroup_in_op_inv.Defined.
G: Group H: G -> Type H0: IsSubgroup H x, y: G
H (x * y) -> H x -> H y
G: Group H: G -> Type H0: IsSubgroup H x, y: G
H (x * y) -> H x -> H y
G: Group H: G -> Type H0: IsSubgroup H x, y: G p: H (x * y) q: H x
H y
G: Group H: G -> Type H0: IsSubgroup H x, y: G p: H (x * y) q: H x
H (mon_unit * y)
G: Group H: G -> Type H0: IsSubgroup H x, y: G
H x -> H (x * y) -> H (mon_unit * y)
G: Group H: G -> Type H0: IsSubgroup H x, y: G
H x -> H (x * y) -> H (- x * x * y)
G: Group H: G -> Type H0: IsSubgroup H x, y: G
H x -> H (x * y) -> H (- x * (x * y))
apply issubgroup_in_inv_op.Defined.EndIsSubgroupElements.Definitionissig_issubgroup {G : Group} (H : G -> Type) : _ <~> IsSubgroup H
:= ltac:(issig).(** Given a predicate H on a group G, being a subgroup is a property. *)
F: Funext G: Group H: G -> Type
IsHProp (IsSubgroup H)
F: Funext G: Group H: G -> Type
IsHProp (IsSubgroup H)
exact (istrunc_equiv_istrunc _ (issig_issubgroup H)).Defined.(** The type (set) of subgroups of a group G. *)RecordSubgroup (G : Group) := {
subgroup_pred : G -> Type ;
subgroup_issubgroup : IsSubgroup subgroup_pred ;
}.Coercionsubgroup_pred : Subgroup >-> Funclass.Global Existing Instancesubgroup_issubgroup.
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit c: forallxy : G, H x -> H y -> H (x * - y)
Subgroup G
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit c: forallxy : G, H x -> H y -> H (x * - y)
Subgroup G
G: Group H: G -> Type H0: forallx : G, IsHProp (H x) unit: H mon_unit c: forallxy : G, H x -> H y -> H (x * - y)
IsSubgroup H
rapply Build_IsSubgroup'; assumption.Defined.SectionSubgroupElements.Context {G : Group} (H : Subgroup G) (xy : G).Definitionsubgroup_in_unit : H mon_unit := issubgroup_in_unit.Definitionsubgroup_in_inv : H x -> H (- x) := issubgroup_in_inv x.Definitionsubgroup_in_inv' : H (- x) -> H x := issubgroup_in_inv' x.Definitionsubgroup_in_op : H x -> H y -> H (x * y) := issubgroup_in_op x y.Definitionsubgroup_in_op_inv : H x -> H y -> H (x * -y) := issubgroup_in_op_inv x y.Definitionsubgroup_in_inv_op : H x -> H y -> H (-x * y) := issubgroup_in_inv_op x y.Definitionsubgroup_in_op_l : H (x * y) -> H y -> H x := issubgroup_in_op_l x y.Definitionsubgroup_in_op_r : H (x * y) -> H x -> H y := issubgroup_in_op_r x y.EndSubgroupElements.
G: Group H: Subgroup G x: G
IsEquiv (subgroup_in_inv H x)
G: Group H: Subgroup G x: G
IsEquiv (subgroup_in_inv H x)
G: Group H: Subgroup G x: G
H (- x) -> H x
apply subgroup_in_inv'.Defined.Definitionequiv_subgroup_inverse {G : Group} (H : Subgroup G) (x : G)
: H x <~> H (-x) := Build_Equiv _ _ (subgroup_in_inv H x) _.(** The group given by a subgroup *)
forallxy : G,
x = mon_unit -> y = mon_unit -> x * - y = mon_unit
G: Group
forallxy : G,
x = mon_unit -> y = mon_unit -> x * - y = mon_unit
G: Group x, y: G p: x = mon_unit q: y = mon_unit
x * - y = mon_unit
G: Group x, y: G p: x = mon_unit q: y = mon_unit
mon_unit * - mon_unit = mon_unit
G: Group x, y: G p: x = mon_unit q: y = mon_unit
- mon_unit = mon_unit
apply negate_mon_unit.Defined.(** Every group is a (maximal) subgroup of itself *)
G: Group
Subgroup G
G: Group
Subgroup G
G: Group
IsSubgroup (fun_ : G => Unit)
split; auto; exact _.Defined.(** Paths between subgroups correspond to homotopies between the underlying predicates. *)
F: Funext G: Group H, K: Subgroup G
H == K <~> H = K
F: Funext G: Group H, K: Subgroup G
H == K <~> H = K
F: Funext G: Group H, K: Subgroup G
H == K <~>
(H; subgroup_issubgroup G H) =
(K; subgroup_issubgroup G K)
F: Funext G: Group H, K: Subgroup G
H == K <~> H = K
apply equiv_path_arrow.Defined.
U: Univalence G: Group H, K: Subgroup G
(forallg : G, H g <-> K g) <~> H = K
U: Univalence G: Group H, K: Subgroup G
(forallg : G, H g <-> K g) <~> H = K
U: Univalence G: Group H, K: Subgroup G
(forallg : G, H g <-> K g) <~> H == K
U: Univalence G: Group H, K: Subgroup G g: G
(H g <-> K g) <~> H g = K g
exact equiv_path_iff_ishprop.Defined.
H: Univalence G: Group
IsHSet (Subgroup G)
H: Univalence G: Group
IsHSet (Subgroup G)
H: Univalence G: Group
IsHSet {H : G -> Type & IsSubgroup H}
H: Univalence G: Group
foralla : G -> Type, ?Goal a <~> IsSubgroup a
H: Univalence G: Group
IsHSet {x : _ & ?Goal x}
H: Univalence G: Group
foralla : G -> Type, ?Goal a <~> IsSubgroup a
intro P; apply issig_issubgroup.
H: Univalence G: Group
IsHSet
{P : G -> Type &
{_ : forallx : G, IsHProp (P x) &
{_ : P mon_unit &
{_ : forallxy : G, P x -> P y -> P (x * y) &
forallx : G, P x -> P (- x)}}}}
H: Univalence G: Group
IsHSet
{ap : {a : G -> Type & forallx : G, IsHProp (a x)}
&
{_ : ap.1 mon_unit &
{_
: forallxy : G, ap.1 x -> ap.1 y -> ap.1 (x * y) &
forallx : G, ap.1 x -> ap.1 (- x)}}}
H: Univalence G: Group
IsHSet {a : G -> Type & forallx : G, IsHProp (a x)}
H: Univalence G: Group
foralla : {a : G -> Type & forallx : G, IsHProp (a x)},
IsHSet
{_ : a.1 mon_unit &
{_ : forallxy : G, a.1 x -> a.1 y -> a.1 (x * y) &
forallx : G, a.1 x -> a.1 (- x)}}
H: Univalence G: Group
IsHSet {a : G -> Type & forallx : G, IsHProp (a x)}
H: Univalence G: Group
IsHSet (G -> {x : Type & IsHProp x})
apply istrunc_forall.Defined.SectionCosets.(** Left and right cosets give equivalence relations. *)Context {G : Group} (H : Subgroup G).(** The relation of being in a left coset represented by an element. *)Definitionin_cosetL : Relation G := funxy => H (-x * y).(** The relation of being in a right coset represented by an element. *)Definitionin_cosetR : Relation G := funxy => H (x * -y).Hint Extern4 => progressunfold in_cosetL : typeclass_instances.Hint Extern4 => progressunfold in_cosetR : typeclass_instances.GlobalArguments in_cosetL /.GlobalArguments in_cosetR /.(** These are props *)Global Instanceishprop_in_cosetL : is_mere_relation G in_cosetL := _.Global Instanceishprop_in_cosetR : is_mere_relation G in_cosetR := _.(** In fact, they are both equivalence relations. *)
G: Group H: Subgroup G
Reflexive in_cosetL
G: Group H: Subgroup G
Reflexive in_cosetL
G: Group H: Subgroup G x: G
H (- x * x)
G: Group H: Subgroup G x: G
H mon_unit
apply issubgroup_in_unit.Defined.
G: Group H: Subgroup G
Reflexive in_cosetR
G: Group H: Subgroup G
Reflexive in_cosetR
G: Group H: Subgroup G x: G
H (x * - x)
G: Group H: Subgroup G x: G
H mon_unit
apply issubgroup_in_unit.Defined.
G: Group H: Subgroup G
Symmetric in_cosetL
G: Group H: Subgroup G
Symmetric in_cosetL
G: Group H: Subgroup G x, y: G h: H (- x * y)
H (- y * x)
G: Group H: Subgroup G x, y: G h: H (- x * y)
H (- y * - - x)
G: Group H: Subgroup G x, y: G h: H (- x * y)
H (- (- x * y))
apply issubgroup_in_inv; assumption.Defined.
G: Group H: Subgroup G
Symmetric in_cosetR
G: Group H: Subgroup G
Symmetric in_cosetR
G: Group H: Subgroup G x, y: G h: H (x * - y)
H (y * - x)
G: Group H: Subgroup G x, y: G h: H (x * - y)
H (- - y * - x)
G: Group H: Subgroup G x, y: G h: H (x * - y)
H (- (x * - y))
apply issubgroup_in_inv; assumption.Defined.
G: Group H: Subgroup G
Transitive in_cosetL
G: Group H: Subgroup G
Transitive in_cosetL
G: Group H: Subgroup G x, y, z: G h: H (- x * y) k: H (- y * z)
H (- x * z)
G: Group H: Subgroup G x, y, z: G h: H (- x * y) k: H (- y * z)
H (- x * mon_unit * z)
G: Group H: Subgroup G x, y, z: G h: H (- x * y) k: H (- y * z)
H (- x * (y * - y) * z)
G: Group H: Subgroup G x, y, z: G h: H (- x * y) k: H (- y * z)
H (- x * y * - y * z)
G: Group H: Subgroup G x, y, z: G h: H (- x * y) k: H (- y * z)
H (- x * y * (- y * z))
apply issubgroup_in_op; assumption.Defined.
G: Group H: Subgroup G
Transitive in_cosetR
G: Group H: Subgroup G
Transitive in_cosetR
G: Group H: Subgroup G x, y, z: G h: H (x * - y) k: H (y * - z)
H (x * - z)
G: Group H: Subgroup G x, y, z: G h: H (x * - y) k: H (y * - z)
H (x * mon_unit * - z)
G: Group H: Subgroup G x, y, z: G h: H (x * - y) k: H (y * - z)
H (x * (- y * y) * - z)
G: Group H: Subgroup G x, y, z: G h: H (x * - y) k: H (y * - z)
H (x * - y * y * - z)
G: Group H: Subgroup G x, y, z: G h: H (x * - y) k: H (y * - z)
H (x * - y * (y * - z))
apply issubgroup_in_op; assumption.Defined.EndCosets.(** Identities related to the left and right cosets. *)
G: Group N: Subgroup G
forallxy : G,
in_cosetL N (- x * y) mon_unit <~> in_cosetL N x y
G: Group N: Subgroup G
forallxy : G,
in_cosetL N (- x * y) mon_unit <~> in_cosetL N x y
forallxy : G,
in_cosetR N (x * - y) mon_unit <~> in_cosetR N x y
G: Group N: Subgroup G
forallxy : G,
in_cosetR N (x * - y) mon_unit <~> in_cosetR N x y
G: Group N: Subgroup G x, y: G
N (x * - y * - mon_unit) <~> N (x * - y)
G: Group N: Subgroup G x, y: G
N (x * - y * mon_unit) <~> N (x * - y)
G: Group N: Subgroup G x, y: G
N (x * - y) <~> N (x * - y)
reflexivity.Defined.(** Symmetry is an equivalence. *)
G: Group N: Subgroup G
forallxy : G, in_cosetL N x y <~> in_cosetL N y x
G: Group N: Subgroup G
forallxy : G, in_cosetL N x y <~> in_cosetL N y x
G: Group N: Subgroup G x, y: G
in_cosetL N x y <~> in_cosetL N y x
G: Group N: Subgroup G x, y: G
in_cosetL N x y -> in_cosetL N y x
G: Group N: Subgroup G x, y: G
in_cosetL N y x -> in_cosetL N x y
all: byintro.Defined.
G: Group N: Subgroup G
forallxy : G, in_cosetR N x y <~> in_cosetR N y x
G: Group N: Subgroup G
forallxy : G, in_cosetR N x y <~> in_cosetR N y x
G: Group N: Subgroup G x, y: G
in_cosetR N x y <~> in_cosetR N y x
G: Group N: Subgroup G x, y: G
in_cosetR N x y -> in_cosetR N y x
G: Group N: Subgroup G x, y: G
in_cosetR N y x -> in_cosetR N x y
all: byintro.Defined.(** A subgroup is normal if being in a left coset is equivalent to being in a right coset represented by the same element. *)ClassIsNormalSubgroup {G : Group} (N : Subgroup G)
:= isnormal : forall {xy}, in_cosetL N x y <~> in_cosetR N x y.RecordNormalSubgroup (G : Group) := {
normalsubgroup_subgroup : Subgroup G ;
normalsubgroup_isnormal : IsNormalSubgroup normalsubgroup_subgroup ;
}.Coercionnormalsubgroup_subgroup : NormalSubgroup >-> Subgroup.Global Existing Instancenormalsubgroup_isnormal.(* Inverses are then respected *)
G: Group N: NormalSubgroup G
forallxy : G,
in_cosetL N (- x) (- y) <~> in_cosetL N x y
G: Group N: NormalSubgroup G
forallxy : G,
in_cosetL N (- x) (- y) <~> in_cosetL N x y
G: Group N: NormalSubgroup G x, y: G
in_cosetL N (- x) (- y) <~> in_cosetL N x y
G: Group N: NormalSubgroup G x, y: G
N (- - x * - y) <~> N (- x * y)
G: Group N: NormalSubgroup G x, y: G
N (x * - y) <~> N (- x * y)
symmetry; apply isnormal.Defined.
G: Group N: NormalSubgroup G
forallxy : G,
in_cosetR N (- x) (- y) <~> in_cosetR N x y
G: Group N: NormalSubgroup G
forallxy : G,
in_cosetR N (- x) (- y) <~> in_cosetR N x y
G: Group N: NormalSubgroup G x, y: G
in_cosetR N (- x) (- y) <~> in_cosetR N x y
G: Group N: NormalSubgroup G x, y: G
in_cosetR N (- x * - - y) mon_unit <~> in_cosetR N x y
G: Group N: NormalSubgroup G x, y: G
in_cosetL N (- x * - - y) mon_unit <~> in_cosetR N x y
G: Group N: NormalSubgroup G x, y: G
in_cosetL N x (- - y) <~> in_cosetR N x y
G: Group N: NormalSubgroup G x, y: G
in_cosetR N x (- - y) <~> in_cosetR N x y
byrewrite negate_involutive.Defined.(** This lets us prove that left and right coset relations are congruences. *)
G: Group N: NormalSubgroup G x, x', y, y': G
in_cosetL N x y ->
in_cosetL N x' y' -> in_cosetL N (x * x') (y * y')
G: Group N: NormalSubgroup G x, x', y, y': G
in_cosetL N x y ->
in_cosetL N x' y' -> in_cosetL N (x * x') (y * y')
G: Group N: NormalSubgroup G x, x', y, y': G p: N (- x * y) q: N (- x' * y')
N (- (x * x') * (y * y'))
(** rewrite goal before applying subgroup_op *)
G: Group N: NormalSubgroup G x, x', y, y': G p: N (- x * y) q: N (- x' * y')
N (- x' * (- x * (y * y')))
G: Group N: NormalSubgroup G x, x', y, y': G p: N (- x * y) q: N (- x' * y')
N (- (- x * (y * y')) * x')
G: Group N: NormalSubgroup G x, x', y, y': G p: N (- x * y) q: N (- x' * y')
N (- (- x * y * y') * x')
G: Group N: NormalSubgroup G x, x', y, y': G p: N (- x * y) q: N (- x' * y')
N (- x * y * y' * - x')
G: Group N: NormalSubgroup G x, x', y, y': G p: N (- x * y) q: N (- x' * y')
N (- x * y * (y' * - x'))
G: Group N: NormalSubgroup G x, x', y, y': G p: N (- x * y) q: N (- x' * y')
N (- x * y)
G: Group N: NormalSubgroup G x, x', y, y': G p: N (- x * y) q: N (- x' * y')
N (y' * - x')
G: Group N: NormalSubgroup G x, x', y, y': G p: N (- x * y) q: N (- x' * y')
N (y' * - x')
byapply isnormal, symmetric_in_cosetL.Defined.
G: Group N: NormalSubgroup G x, x', y, y': G
in_cosetR N x y ->
in_cosetR N x' y' -> in_cosetR N (x * x') (y * y')
G: Group N: NormalSubgroup G x, x', y, y': G
in_cosetR N x y ->
in_cosetR N x' y' -> in_cosetR N (x * x') (y * y')
G: Group N: NormalSubgroup G x, x', y, y': G p: N (x * - y) q: N (x' * - y')
N (x * x' * - (y * y'))
(** rewrite goal before applying subgroup_op *)
G: Group N: NormalSubgroup G x, x', y, y': G p: N (x * - y) q: N (x' * - y')
N (x * x' * - y' * - y)
G: Group N: NormalSubgroup G x, x', y, y': G p: N (x * - y) q: N (x' * - y')
N (y * - (x * x' * - y'))
G: Group N: NormalSubgroup G x, x', y, y': G p: N (x * - y) q: N (x' * - y')
N (y * - (x * (x' * - y')))
G: Group N: NormalSubgroup G x, x', y, y': G p: N (x * - y) q: N (x' * - y')
N (- y * (x * (x' * - y')))
G: Group N: NormalSubgroup G x, x', y, y': G p: N (x * - y) q: N (x' * - y')
N (- y * x * (x' * - y'))
G: Group N: NormalSubgroup G x, x', y, y': G p: N (x * - y) q: N (x' * - y')
N (- y * x)
G: Group N: NormalSubgroup G x, x', y, y': G p: N (x * - y) q: N (x' * - y')
N (x' * - y')
G: Group N: NormalSubgroup G x, x', y, y': G p: N (x * - y) q: N (x' * - y')
N (- y * x)
byapply isnormal, symmetric_in_cosetR.Defined.(** The property of being the trivial subgroup is useful. *)DefinitionIsTrivialSubgroup {G : Group} (H : Subgroup G) : Type :=
forallx, H x <-> trivial_subgroup x.Existing ClassIsTrivialSubgroup.Global Instanceistrivialsubgroup_trivial_subgroup {G : Group}
: IsTrivialSubgroup (@trivial_subgroup G)
:= ltac:(hnf; reflexivity).(** Intersection of two subgroups *)
G: Group H, K: Subgroup G
Subgroup G
G: Group H, K: Subgroup G
Subgroup G
G: Group H, K: Subgroup G
G -> Type
G: Group H, K: Subgroup G
forallx : G, IsHProp (?H x)
G: Group H, K: Subgroup G
?H mon_unit
G: Group H, K: Subgroup G
forallxy : G, ?H x -> ?H y -> ?H (x * - y)
G: Group H, K: Subgroup G
forallx : G,
IsHProp ((fung : G => (H g * K g)%type) x)
G: Group H, K: Subgroup G
(fung : G => (H g * K g)%type) mon_unit
G: Group H, K: Subgroup G
forallxy : G,
(fung : G => (H g * K g)%type) x ->
(fung : G => (H g * K g)%type) y ->
(fung : G => (H g * K g)%type) (x * - y)
G: Group H, K: Subgroup G
(fung : G => (H g * K g)%type) mon_unit
G: Group H, K: Subgroup G
forallxy : G,
(fung : G => (H g * K g)%type) x ->
(fung : G => (H g * K g)%type) y ->
(fung : G => (H g * K g)%type) (x * - y)
G: Group H, K: Subgroup G
forallxy : G,
(fung : G => (H g * K g)%type) x ->
(fung : G => (H g * K g)%type) y ->
(fung : G => (H g * K g)%type) (x * - y)
G: Group H, K: Subgroup G x, y: G fst: H x snd: K x fst0: H y snd0: K y
(H (sg_op x (- y)) * K (sg_op x (- y)))%type
split; byapply subgroup_in_op_inv.Defined.(** *** The subgroup generated by a subset *)(** Underlying type family of a subgroup generated by subset *)Inductivesubgroup_generated_type {G : Group} (X : G -> Type) : G -> Type :=
(** The subgroup should contain all elements of the original family. *)
| sgt_in (g : G) : X g -> subgroup_generated_type X g
(** It should contain the unit. *)
| sgt_unit : subgroup_generated_type X mon_unit
(** Finally, it should be closed under inverses and operation. *)
| sgt_op (g h : G)
: subgroup_generated_type X g
-> subgroup_generated_type X h
-> subgroup_generated_type X (g * - h)
.Arguments sgt_in {G X g}.Arguments sgt_unit {G X}.Arguments sgt_op {G X g h}.(** Note that [subgroup_generated_type] will not automatically land in [HProp]. For example, if [X] already "contains" the unit of the group, then there are at least two different inhabitants of this family at the unit (given by [sgt_unit] and [sgt_in group_unit _]). Therefore, we propositionally truncate in [subgroup_generated] below. *)(** Subgroups are closed under inverses. *)
G: Group X: G -> Type g: G
subgroup_generated_type X g ->
subgroup_generated_type X (- g)
G: Group X: G -> Type g: G
subgroup_generated_type X g ->
subgroup_generated_type X (- g)
G: Group X: G -> Type g: G p: subgroup_generated_type X g
subgroup_generated_type X (- g)
G: Group X: G -> Type g: G p: subgroup_generated_type X g
subgroup_generated_type X (mon_unit * - g)
exact (sgt_op sgt_unit p).Defined.
G: Group X: G -> Type g, h: G
subgroup_generated_type X g ->
subgroup_generated_type X h ->
subgroup_generated_type X (g * h)
G: Group X: G -> Type g, h: G
subgroup_generated_type X g ->
subgroup_generated_type X h ->
subgroup_generated_type X (g * h)
G: Group X: G -> Type g, h: G p: subgroup_generated_type X g q: subgroup_generated_type X h
subgroup_generated_type X (g * h)
G: Group X: G -> Type g, h: G p: subgroup_generated_type X g q: subgroup_generated_type X h
subgroup_generated_type X (g * - - h)
exact (sgt_op p (sgt_inv q)).Defined.(** The subgroup generated by a subset *)
G: Group X: G -> Type
Subgroup G
G: Group X: G -> Type
Subgroup G
G: Group X: G -> Type
forallxy : G,
merely (subgroup_generated_type X x) ->
merely (subgroup_generated_type X y) ->
merely (subgroup_generated_type X (x * - y))
G: Group X: G -> Type x, y: G q: subgroup_generated_type X y p: subgroup_generated_type X x
merely (subgroup_generated_type X (x * - y))
exact (tr (sgt_op p q)).Defined.(** The inclusion of generators into the generated subgroup. *)Definitionsubgroup_generated_gen_incl {G : Group} {X : G -> Type} (g : G) (H : X g)
: subgroup_generated X
:= (g; tr (sgt_in H)).(** If [f : G $-> H] is a group homomorphism and [X] and [Y] are subsets of [G] and [H] such that [f] maps [X] into [Y], then [f] sends the subgroup generated by [X] into the subgroup generated by [Y]. *)
G, H: Group X: G -> Type Y: H -> Type f: G $-> H preserves: forallg : G, X g -> Y (f g)
forallg : G,
subgroup_generated X g -> subgroup_generated Y (f g)
G, H: Group X: G -> Type Y: H -> Type f: G $-> H preserves: forallg : G, X g -> Y (f g)
forallg : G,
subgroup_generated X g -> subgroup_generated Y (f g)
G, H: Group X: G -> Type Y: H -> Type f: G $-> H preserves: forallg : G, X g -> Y (f g) g: G
subgroup_generated X g -> subgroup_generated Y (f g)
G, H: Group X: G -> Type Y: H -> Type f: G $-> H preserves: forallg : G, X g -> Y (f g) g: G
subgroup_generated_type X g ->
subgroup_generated_type Y (f g)
G, H: Group X: G -> Type Y: H -> Type f: G $-> H preserves: forallg : G, X g -> Y (f g) g: G p: subgroup_generated_type X g
subgroup_generated_type Y (f g)
G, H: Group X: G -> Type Y: H -> Type f: G $-> H preserves: forallg : G, X g -> Y (f g) g: G i: X g
subgroup_generated_type Y (f g)
G, H: Group X: G -> Type Y: H -> Type f: G $-> H preserves: forallg : G, X g -> Y (f g)
subgroup_generated_type Y (f mon_unit)
G, H: Group X: G -> Type Y: H -> Type f: G $-> H preserves: forallg : G, X g -> Y (f g) g, h: G p1: subgroup_generated_type X g p2: subgroup_generated_type X h IHp1: subgroup_generated_type Y (f g) IHp2: subgroup_generated_type Y (f h)
subgroup_generated_type Y (f (g * - h))
G, H: Group X: G -> Type Y: H -> Type f: G $-> H preserves: forallg : G, X g -> Y (f g) g: G i: X g
subgroup_generated_type Y (f g)
apply sgt_in, preserves, i.
G, H: Group X: G -> Type Y: H -> Type f: G $-> H preserves: forallg : G, X g -> Y (f g)
subgroup_generated_type Y (f mon_unit)
G, H: Group X: G -> Type Y: H -> Type f: G $-> H preserves: forallg : G, X g -> Y (f g)
subgroup_generated_type Y mon_unit
apply sgt_unit.
G, H: Group X: G -> Type Y: H -> Type f: G $-> H preserves: forallg : G, X g -> Y (f g) g, h: G p1: subgroup_generated_type X g p2: subgroup_generated_type X h IHp1: subgroup_generated_type Y (f g) IHp2: subgroup_generated_type Y (f h)
subgroup_generated_type Y (f (g * - h))
G, H: Group X: G -> Type Y: H -> Type f: G $-> H preserves: forallg : G, X g -> Y (f g) g, h: G p1: subgroup_generated_type X g p2: subgroup_generated_type X h IHp1: subgroup_generated_type Y (f g) IHp2: subgroup_generated_type Y (f h)
subgroup_generated_type Y (f g * - f h)
byapply sgt_op.Defined.(** The product of two subgroups. *)Definitionsubgroup_product {G : Group} (HK : Subgroup G) : Subgroup G
:= subgroup_generated (funx => ((H x) + (K x))%type).(** The induction principle for the product. *)
G: Group H, K: Subgroup G P: forallx : G, subgroup_product H K x -> Type P_H_in: forall (x : G) (y : H x),
P x (tr (sgt_in (inl y))) P_K_in: forall (x : G) (y : K x),
P x (tr (sgt_in (inr y))) P_unit: P mon_unit (tr sgt_unit) P_op: forall (xy : G)
(h : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) x)
(k : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) y),
P x (tr h) ->
P y (tr k) -> P (x * - y) (tr (sgt_op h k)) H0: forall (x : G) (y : subgroup_product H K x),
IsHProp (P x y)
forall (x : G) (p : subgroup_product H K x), P x p
G: Group H, K: Subgroup G P: forallx : G, subgroup_product H K x -> Type P_H_in: forall (x : G) (y : H x),
P x (tr (sgt_in (inl y))) P_K_in: forall (x : G) (y : K x),
P x (tr (sgt_in (inr y))) P_unit: P mon_unit (tr sgt_unit) P_op: forall (xy : G)
(h : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) x)
(k : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) y),
P x (tr h) ->
P y (tr k) -> P (x * - y) (tr (sgt_op h k)) H0: forall (x : G) (y : subgroup_product H K x),
IsHProp (P x y)
forall (x : G) (p : subgroup_product H K x), P x p
G: Group H, K: Subgroup G P: forallx : G, subgroup_product H K x -> Type P_H_in: forall (x : G) (y : H x),
P x (tr (sgt_in (inl y))) P_K_in: forall (x : G) (y : K x),
P x (tr (sgt_in (inr y))) P_unit: P mon_unit (tr sgt_unit) P_op: forall (xy : G)
(h : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) x)
(k : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) y),
P x (tr h) ->
P y (tr k) -> P (x * - y) (tr (sgt_op h k)) H0: forall (x : G) (y : subgroup_product H K x),
IsHProp (P x y) x: G p: subgroup_product H K x
P x p
G: Group H, K: Subgroup G P: forallx : G, subgroup_product H K x -> Type P_H_in: forall (x : G) (y : H x),
P x (tr (sgt_in (inl y))) P_K_in: forall (x : G) (y : K x),
P x (tr (sgt_in (inr y))) P_unit: P mon_unit (tr sgt_unit) P_op: forall (xy : G)
(h : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) x)
(k : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) y),
P x (tr h) ->
P y (tr k) -> P (x * - y) (tr (sgt_op h k)) H0: forall (x : G) (y : subgroup_product H K x),
IsHProp (P x y) x: G p: subgroup_generated_type
(funx : G => (H x + K x)%type) x
P x (tr p)
G: Group H, K: Subgroup G P: forallx : G, subgroup_product H K x -> Type P_H_in: forall (x : G) (y : H x),
P x (tr (sgt_in (inl y))) P_K_in: forall (x : G) (y : K x),
P x (tr (sgt_in (inr y))) P_unit: P mon_unit (tr sgt_unit) P_op: forall (xy : G)
(h : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) x)
(k : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) y),
P x (tr h) ->
P y (tr k) -> P (x * - y) (tr (sgt_op h k)) H0: forall (x : G) (y : subgroup_product H K x),
IsHProp (P x y) x: G s: (H x + K x)%type
P x (tr (sgt_in s))
G: Group H, K: Subgroup G P: forallx : G, subgroup_product H K x -> Type P_H_in: forall (x : G) (y : H x),
P x (tr (sgt_in (inl y))) P_K_in: forall (x : G) (y : K x),
P x (tr (sgt_in (inr y))) P_unit: P mon_unit (tr sgt_unit) P_op: forall (xy : G)
(h : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) x)
(k : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) y),
P x (tr h) ->
P y (tr k) -> P (x * - y) (tr (sgt_op h k)) H0: forall (x : G) (y : subgroup_product H K x),
IsHProp (P x y)
P mon_unit (tr sgt_unit)
G: Group H, K: Subgroup G P: forallx : G, subgroup_product H K x -> Type P_H_in: forall (x : G) (y : H x),
P x (tr (sgt_in (inl y))) P_K_in: forall (x : G) (y : K x),
P x (tr (sgt_in (inr y))) P_unit: P mon_unit (tr sgt_unit) P_op: forall (xy : G)
(h : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) x)
(k : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) y),
P x (tr h) ->
P y (tr k) -> P (x * - y) (tr (sgt_op h k)) H0: forall (x : G) (y : subgroup_product H K x),
IsHProp (P x y) x, y: G h: subgroup_generated_type
(funx : G => (H x + K x)%type) x k: subgroup_generated_type
(funx : G => (H x + K x)%type) y IHh: P x (tr h) IHk: P y (tr k)
P (x * - y) (tr (sgt_op h k))
G: Group H, K: Subgroup G P: forallx : G, subgroup_product H K x -> Type P_H_in: forall (x : G) (y : H x),
P x (tr (sgt_in (inl y))) P_K_in: forall (x : G) (y : K x),
P x (tr (sgt_in (inr y))) P_unit: P mon_unit (tr sgt_unit) P_op: forall (xy : G)
(h : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) x)
(k : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) y),
P x (tr h) ->
P y (tr k) -> P (x * - y) (tr (sgt_op h k)) H0: forall (x : G) (y : subgroup_product H K x),
IsHProp (P x y) x: G s: (H x + K x)%type
P x (tr (sgt_in s))
G: Group H, K: Subgroup G P: forallx : G, subgroup_product H K x -> Type P_H_in: forall (x : G) (y : H x),
P x (tr (sgt_in (inl y))) P_K_in: forall (x : G) (y : K x),
P x (tr (sgt_in (inr y))) P_unit: P mon_unit (tr sgt_unit) P_op: forall (xy : G)
(h : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) x)
(k : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) y),
P x (tr h) ->
P y (tr k) -> P (x * - y) (tr (sgt_op h k)) H0: forall (x : G) (y : subgroup_product H K x),
IsHProp (P x y) x: G s: H x
P x (tr (sgt_in (inl s)))
G: Group H, K: Subgroup G P: forallx : G, subgroup_product H K x -> Type P_H_in: forall (x : G) (y : H x),
P x (tr (sgt_in (inl y))) P_K_in: forall (x : G) (y : K x),
P x (tr (sgt_in (inr y))) P_unit: P mon_unit (tr sgt_unit) P_op: forall (xy : G)
(h : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) x)
(k : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) y),
P x (tr h) ->
P y (tr k) -> P (x * - y) (tr (sgt_op h k)) H0: forall (x : G) (y : subgroup_product H K x),
IsHProp (P x y) x: G s: K x
P x (tr (sgt_in (inr s)))
G: Group H, K: Subgroup G P: forallx : G, subgroup_product H K x -> Type P_H_in: forall (x : G) (y : H x),
P x (tr (sgt_in (inl y))) P_K_in: forall (x : G) (y : K x),
P x (tr (sgt_in (inr y))) P_unit: P mon_unit (tr sgt_unit) P_op: forall (xy : G)
(h : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) x)
(k : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) y),
P x (tr h) ->
P y (tr k) -> P (x * - y) (tr (sgt_op h k)) H0: forall (x : G) (y : subgroup_product H K x),
IsHProp (P x y) x: G s: H x
P x (tr (sgt_in (inl s)))
apply P_H_in.
G: Group H, K: Subgroup G P: forallx : G, subgroup_product H K x -> Type P_H_in: forall (x : G) (y : H x),
P x (tr (sgt_in (inl y))) P_K_in: forall (x : G) (y : K x),
P x (tr (sgt_in (inr y))) P_unit: P mon_unit (tr sgt_unit) P_op: forall (xy : G)
(h : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) x)
(k : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) y),
P x (tr h) ->
P y (tr k) -> P (x * - y) (tr (sgt_op h k)) H0: forall (x : G) (y : subgroup_product H K x),
IsHProp (P x y) x: G s: K x
P x (tr (sgt_in (inr s)))
apply P_K_in.
G: Group H, K: Subgroup G P: forallx : G, subgroup_product H K x -> Type P_H_in: forall (x : G) (y : H x),
P x (tr (sgt_in (inl y))) P_K_in: forall (x : G) (y : K x),
P x (tr (sgt_in (inr y))) P_unit: P mon_unit (tr sgt_unit) P_op: forall (xy : G)
(h : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) x)
(k : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) y),
P x (tr h) ->
P y (tr k) -> P (x * - y) (tr (sgt_op h k)) H0: forall (x : G) (y : subgroup_product H K x),
IsHProp (P x y)
P mon_unit (tr sgt_unit)
exact P_unit.
G: Group H, K: Subgroup G P: forallx : G, subgroup_product H K x -> Type P_H_in: forall (x : G) (y : H x),
P x (tr (sgt_in (inl y))) P_K_in: forall (x : G) (y : K x),
P x (tr (sgt_in (inr y))) P_unit: P mon_unit (tr sgt_unit) P_op: forall (xy : G)
(h : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) x)
(k : subgroup_generated_type
(funx0 : G => (H x0 + K x0)%type) y),
P x (tr h) ->
P y (tr k) -> P (x * - y) (tr (sgt_op h k)) H0: forall (x : G) (y : subgroup_product H K x),
IsHProp (P x y) x, y: G h: subgroup_generated_type
(funx : G => (H x + K x)%type) x k: subgroup_generated_type
(funx : G => (H x + K x)%type) y IHh: P x (tr h) IHk: P y (tr k)
P (x * - y) (tr (sgt_op h k))
byapply P_op.Defined.(* **** Paths between generated subgroups *)(* This gets used twice in [path_subgroup_generated], so we factor it out here. *)
G: Group X, Y: G -> Type K: forallg : G, merely (X g) -> merely (Y g)
forallg : G,
Trunc (-1) (subgroup_generated_type X g) ->
Trunc (-1) (subgroup_generated_type Y g)
G: Group X, Y: G -> Type K: forallg : G, merely (X g) -> merely (Y g)
forallg : G,
Trunc (-1) (subgroup_generated_type X g) ->
Trunc (-1) (subgroup_generated_type Y g)
G: Group X, Y: G -> Type K: forallg : G, merely (X g) -> merely (Y g) g: G ing: subgroup_generated_type X g
Trunc (-1) (subgroup_generated_type Y g)
G: Group X, Y: G -> Type K: forallg : G, merely (X g) -> merely (Y g) g: G x: X g
Trunc (-1) (subgroup_generated_type Y g)
G: Group X, Y: G -> Type K: forallg : G, merely (X g) -> merely (Y g)
Trunc (-1) (subgroup_generated_type Y mon_unit)
G: Group X, Y: G -> Type K: forallg : G, merely (X g) -> merely (Y g) g, h: G Xg: subgroup_generated_type X g Xh: subgroup_generated_type X h IHYg: Trunc (-1) (subgroup_generated_type Y g) IHYh: Trunc (-1) (subgroup_generated_type Y h)
Trunc (-1) (subgroup_generated_type Y (g * - h))
G: Group X, Y: G -> Type K: forallg : G, merely (X g) -> merely (Y g) g: G x: X g
Trunc (-1) (subgroup_generated_type Y g)
exact (Trunc_functor (-1) sgt_in (K g (tr x))).
G: Group X, Y: G -> Type K: forallg : G, merely (X g) -> merely (Y g)
Trunc (-1) (subgroup_generated_type Y mon_unit)
exact (tr sgt_unit).
G: Group X, Y: G -> Type K: forallg : G, merely (X g) -> merely (Y g) g, h: G Xg: subgroup_generated_type X g Xh: subgroup_generated_type X h IHYg: Trunc (-1) (subgroup_generated_type Y g) IHYh: Trunc (-1) (subgroup_generated_type Y h)
Trunc (-1) (subgroup_generated_type Y (g * - h))
G: Group X, Y: G -> Type K: forallg : G, merely (X g) -> merely (Y g) g, h: G Xg: subgroup_generated_type X g Xh: subgroup_generated_type X h IHYh: subgroup_generated_type Y h IHYg: subgroup_generated_type Y g
Trunc (-1) (subgroup_generated_type Y (g * - h))
byapply tr, sgt_op.Defined.(* If the predicates selecting the generators are merely equivalent, then the generated subgroups are equal. (One could probably prove that the generated subgroup are isomorphic without using univalence.) *)
H: Univalence G: Group X, Y: G -> Type K: forallg : G,
Trunc (-1) (X g) <-> Trunc (-1) (Y g)
subgroup_generated X = subgroup_generated Y
H: Univalence G: Group X, Y: G -> Type K: forallg : G,
Trunc (-1) (X g) <-> Trunc (-1) (Y g)
subgroup_generated X = subgroup_generated Y
H: Univalence G: Group X, Y: G -> Type K: forallg : G,
Trunc (-1) (X g) <-> Trunc (-1) (Y g)
forallg : G,
subgroup_generated X g <-> subgroup_generated Y g
H: Univalence G: Group X, Y: G -> Type K: forallg : G,
Trunc (-1) (X g) <-> Trunc (-1) (Y g) g: G
subgroup_generated X g -> subgroup_generated Y g
H: Univalence G: Group X, Y: G -> Type K: forallg : G,
Trunc (-1) (X g) <-> Trunc (-1) (Y g) g: G
subgroup_generated Y g -> subgroup_generated X g
H: Univalence G: Group X, Y: G -> Type K: forallg : G,
Trunc (-1) (X g) <-> Trunc (-1) (Y g) g: G