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 Spaces.Nat.Core Spaces.Int.Require Export Classes.interfaces.canonical_names (Zero, zero, Plus, plus, Negate, negate, Involutive, involutive).Require Export Classes.interfaces.abstract_algebra (IsAbGroup(..), abgroup_group, abgroup_commutative).Require Export Algebra.Groups.Group.Require Export Algebra.Groups.Subgroup.Require Import Algebra.Groups.QuotientGroup.Require Import WildCat.Local Set Polymorphic Inductive Cumulativity.LocalOpen Scope mc_scope.LocalOpen Scope mc_add_scope.(** * Abelian groups *)(** Definition of an abelian group *)RecordAbGroup := {
abgroup_group : Group;
abgroup_commutative :: @Commutative abgroup_group _ (+);
}.Coercionabgroup_group : AbGroup >-> Group.Definitionzero_abgroup (A : AbGroup) : Zero A := mon_unit.Definitionnegate_abgroup (A : AbGroup) : Negate A := inv.Definitionplus_abgroup (A : AbGroup) : Plus A := sg_op.(** Sometimes we want an abelian group to act as if it has a [Plus], [Zero] and [Negate] operation. For example, when working with rings. We therefore make this module of hints available for import so that consumers can control the way the abelian group operation is treated.Files about abelian groups (apart from this one) typically don't have these instances available, whereas files about rings do. *)ModuleImport AdditiveInstances.#[export] Hint Immediate zero_abgroup : typeclass_instances.#[export] Hint Immediate negate_abgroup : typeclass_instances.#[export] Hint Immediate plus_abgroup : typeclass_instances.EndAdditiveInstances.
A: AbGroup
IsAbGroup A
A: AbGroup
IsAbGroup A
split; exact _.Defined.(** Easier way to build abelian groups without redundant information. *)
G: Type H: MonUnit G H0: Inverse G H1: SgOp G IsHSet0: IsHSet G comm: Commutative sg_op assoc: Associative sg_op unit_l: LeftIdentity sg_op 0 inv_l: LeftInverse sg_op inv 0
AbGroup
G: Type H: MonUnit G H0: Inverse G H1: SgOp G IsHSet0: IsHSet G comm: Commutative sg_op assoc: Associative sg_op unit_l: LeftIdentity sg_op 0 inv_l: LeftInverse sg_op inv 0
AbGroup
G: Type H: MonUnit G H0: Inverse G H1: SgOp G IsHSet0: IsHSet G comm: Commutative sg_op assoc: Associative sg_op unit_l: LeftIdentity sg_op 0 inv_l: LeftInverse sg_op inv 0
Group
G: Type H: MonUnit G H0: Inverse G H1: SgOp G IsHSet0: IsHSet G comm: Commutative sg_op assoc: Associative sg_op unit_l: LeftIdentity sg_op 0 inv_l: LeftInverse sg_op inv 0
Commutative sg_op
G: Type H: MonUnit G H0: Inverse G H1: SgOp G IsHSet0: IsHSet G comm: Commutative sg_op assoc: Associative sg_op unit_l: LeftIdentity sg_op 0 inv_l: LeftInverse sg_op inv 0
Group
rapply (Build_Group' G).
G: Type H: MonUnit G H0: Inverse G H1: SgOp G IsHSet0: IsHSet G comm: Commutative sg_op assoc: Associative sg_op unit_l: LeftIdentity sg_op 0 inv_l: LeftInverse sg_op inv 0
apply commutativity.Defined.(** ** Paths between abelian groups *)
H: Univalence A, B: AbGroup
GroupIsomorphism A B <~> A = B
H: Univalence A, B: AbGroup
GroupIsomorphism A B <~> A = B
H: Univalence A, B: AbGroup
GroupIsomorphism A B <~>
issig_abgroup^-1 A = issig_abgroup^-1 B
H: Univalence A, B: AbGroup
GroupIsomorphism A B <~>
(issig_abgroup^-1 A).1 = (issig_abgroup^-1 B).1
exact equiv_path_group.Defined.Definitionequiv_path_abgroup_group `{Univalence} {A B : AbGroup}
: (A = B :> AbGroup) <~> (A = B :> Group)
:= equiv_path_group oE equiv_path_abgroup^-1.(** ** Subgroups of abelian groups *)LocalHint Immediate canonical_names.inverse_is_negate : typeclass_instances.(** Subgroups of abelian groups are abelian *)
G: AbGroup H: Subgroup G
IsAbGroup H
G: AbGroup H: Subgroup G
IsAbGroup H
G: AbGroup H: Subgroup G
IsGroup H
G: AbGroup H: Subgroup G
Commutative group_sgop
G: AbGroup H: Subgroup G
Commutative group_sgop
G: AbGroup H: Subgroup G x, y: H
group_sgop x y = group_sgop y x
G: AbGroup H: Subgroup G x, y: H
(group_sgop x y).1 = (group_sgop y x).1
G: AbGroup H: Subgroup G x, y: H
x.1 + y.1 = y.1 + x.1
apply commutativity.Defined.(** Given any subgroup of an abelian group, we can coerce it to an abelian group. Note that Coq complains this coercion doesn't satisfy the uniform-inheritance condition, but in practice it works and doesn't cause any issue, so we ignore it. *)Definitionabgroup_subgroup (G : AbGroup) : Subgroup G -> AbGroup
:= funH => Build_AbGroup H _.#[warnings="-uniform-inheritance"]
Coercionabgroup_subgroup : Subgroup >-> AbGroup.
G: AbGroup H: Subgroup G
IsNormalSubgroup H
G: AbGroup H: Subgroup G
IsNormalSubgroup H
G: AbGroup H: Subgroup G x, y: G h: H (x + y)
H (y + x)
byrewrite commutativity.Defined.(** ** Quotients of abelian groups *)
G: AbGroup H: Subgroup G
IsAbGroup
(QuotientGroup' G H (isnormal_ab_subgroup G H))
G: AbGroup H: Subgroup G
IsAbGroup
(QuotientGroup' G H (isnormal_ab_subgroup G H))
G: AbGroup H: Subgroup G
IsGroup
(QuotientGroup' G H (isnormal_ab_subgroup G H))
G: AbGroup H: Subgroup G
Commutative group_sgop
G: AbGroup H: Subgroup G
Commutative group_sgop
G: AbGroup H: Subgroup G x, y: G
(funxy : G /
in_cosetL
{|
normalsubgroup_subgroup := H;
normalsubgroup_isnormal :=
isnormal_ab_subgroup G H
|} => group_sgop x y = group_sgop y x)
(class_of
(in_cosetL
{|
normalsubgroup_subgroup := H;
normalsubgroup_isnormal :=
isnormal_ab_subgroup G H
|}) x)
(class_of
(in_cosetL
{|
normalsubgroup_subgroup := H;
normalsubgroup_isnormal :=
isnormal_ab_subgroup G H
|}) y)
G: AbGroup H: Subgroup G x, y: G
x + y = y + x
apply commutativity.Defined.DefinitionQuotientAbGroup (G : AbGroup) (H : Subgroup G) : AbGroup
:= (Build_AbGroup (QuotientGroup' G H (isnormal_ab_subgroup G H)) _).Arguments QuotientAbGroup G H : simpl never.Definitionquotient_abgroup_rec {G : AbGroup}
(N : Subgroup G) (H : AbGroup)
(f : GroupHomomorphism G H) (h : foralln : G, N n -> f n = mon_unit)
: GroupHomomorphism (QuotientAbGroup G N) H
:= grp_quotient_rec G (Build_NormalSubgroup G N _) f h.
F: Funext G: AbGroup N: Subgroup G H: Group
{f : GroupHomomorphism G H &
foralln : G, N n -> f n = 0} <~>
GroupHomomorphism (QuotientAbGroup G N) H
F: Funext G: AbGroup N: Subgroup G H: Group
{f : GroupHomomorphism G H &
foralln : G, N n -> f n = 0} <~>
GroupHomomorphism (QuotientAbGroup G N) H
exact (equiv_grp_quotient_ump (Build_NormalSubgroup G N _) _).Defined.(** ** The wild category of abelian groups *)Instanceisgraph_abgroup : IsGraph AbGroup
:= isgraph_induced abgroup_group.Instanceis01cat_abgroup : Is01Cat AbGroup
:= is01cat_induced abgroup_group.Instanceis2graph_abgroup : Is2Graph AbGroup
:= is2graph_induced abgroup_group.Instanceisgraph_abgrouphomomorphism {AB : AbGroup} : IsGraph (A $-> B)
:= is2graph_induced abgroup_group A B.Instanceis01cat_abgrouphomomorphism {AB : AbGroup} : Is01Cat (A $-> B)
:= is01cat_induced (@grp_homo_map A B).Instanceis0gpd_abgrouphomomorphism {AB : AbGroup} : Is0Gpd (A $-> B)
:= is0gpd_induced (@grp_homo_map A B).(** [AbGroup] forms a 1Cat *)Instanceis1cat_abgroup : Is1Cat AbGroup
:= is1cat_induced _.Instancehasmorext_abgroup `{Funext} : HasMorExt AbGroup
:= hasmorext_induced _.Instancehasequivs_abgroup : HasEquivs AbGroup
:= hasequivs_induced _.(** Zero object of [AbGroup] *)
AbGroup
AbGroup
Commutative sg_op
byintros [].Defined.(** [AbGroup] is a pointed category *)
IsPointedCat AbGroup
IsPointedCat AbGroup
IsInitial abgroup_trivial
IsTerminal abgroup_trivial
all: intro A; apply ispointedcat_group.Defined.(** [abgroup_group] is a functor *)Instanceis0functor_abgroup_group : Is0Functor abgroup_group
:= is0functor_induced _.Instanceis1functor_abgroup_group : Is1Functor abgroup_group
:= is1functor_induced _.(** Image of group homomorphisms between abelian groups *)Definitionabgroup_image {AB : AbGroup} (f : A $-> B) : AbGroup
:= Build_AbGroup (grp_image f) _.(** First isomorphism theorem of abelian groups *)
H: Funext A, B: AbGroup f: A $-> B
GroupIsomorphism (QuotientAbGroup A (grp_kernel f))
(abgroup_image f)
H: Funext A, B: AbGroup f: A $-> B
GroupIsomorphism (QuotientAbGroup A (grp_kernel f))
(abgroup_image f)
H: Funext A, B: AbGroup f: A $-> B
GroupIsomorphism (QuotientAbGroup A (grp_kernel f))
?Goal
H: Funext A, B: AbGroup f: A $-> B
GroupIsomorphism ?Goal (abgroup_image f)
H: Funext A, B: AbGroup f: A $-> B
GroupIsomorphism (QuotientAbGroup A (grp_kernel f))
(QuotientGroup A (grp_kernel f))
apply grp_iso_quotient_normal.Defined.(** ** Kernels of abelian groups *)Definitionab_kernel {AB : AbGroup} (f : A $-> B) : AbGroup
:= Build_AbGroup (grp_kernel f) _.(** ** Transporting in families related to abelian groups *)
H: Univalence A, B, B': AbGroup p: B = B' f: GroupHomomorphism A B
transport (Hom A) p f =
grp_homo_compose (equiv_path_abgroup^-1 p) f
H: Univalence A, B, B': AbGroup p: B = B' f: GroupHomomorphism A B
transport (Hom A) p f =
grp_homo_compose (equiv_path_abgroup^-1 p) f
H: Univalence A, B: AbGroup f: GroupHomomorphism A B
transport (Hom A) 1 f =
grp_homo_compose (equiv_path_abgroup^-11%path) f
byapply equiv_path_grouphomomorphism.Defined.
H: Univalence A, B, B': AbGroup phi: GroupIsomorphism B B' f: GroupHomomorphism A B
transport (Hom A) (equiv_path_abgroup phi) f =
grp_homo_compose phi f
H: Univalence A, B, B': AbGroup phi: GroupIsomorphism B B' f: GroupHomomorphism A B
transport (Hom A) (equiv_path_abgroup phi) f =
grp_homo_compose phi f
H: Univalence A, B, B': AbGroup phi: GroupIsomorphism B B' f: GroupHomomorphism A B
grp_homo_compose
(equiv_path_abgroup^-1 (equiv_path_abgroup phi)) f =
grp_homo_compose phi f
byrewrite eissect.Defined.
H: Univalence A, A', B: AbGroup p: A = A' f: GroupHomomorphism A B
transport (funG : AbGroup => G $-> B) p f =
grp_homo_compose f
(grp_iso_inverse (equiv_path_abgroup^-1 p))
H: Univalence A, A', B: AbGroup p: A = A' f: GroupHomomorphism A B
transport (funG : AbGroup => G $-> B) p f =
grp_homo_compose f
(grp_iso_inverse (equiv_path_abgroup^-1 p))
H: Univalence A, B: AbGroup f: GroupHomomorphism A B
f =
grp_homo_compose f
{|
grp_homo_map := idmap;
issemigrouppreserving_grp_homo :=
abstract_algebra.invert_sg_morphism idmap
abstract_algebra.id_sg_morphism
|}
byapply equiv_path_grouphomomorphism.Defined.
H: Univalence A, A', B: AbGroup phi: GroupIsomorphism A A' f: GroupHomomorphism A B
transport (funG : AbGroup => G $-> B)
(equiv_path_abgroup phi) f =
grp_homo_compose f (grp_iso_inverse phi)
H: Univalence A, A', B: AbGroup phi: GroupIsomorphism A A' f: GroupHomomorphism A B
transport (funG : AbGroup => G $-> B)
(equiv_path_abgroup phi) f =
grp_homo_compose f (grp_iso_inverse phi)
H: Univalence A, A', B: AbGroup phi: GroupIsomorphism A A' f: GroupHomomorphism A B
grp_homo_compose f
(grp_iso_inverse
(equiv_path_abgroup^-1 (equiv_path_abgroup phi))) =
grp_homo_compose f (grp_iso_inverse phi)
byrewrite eissect.Defined.(** ** Operations on abelian groups *)(** The negation automorphism of an abelian group *)
A: AbGroup
GroupIsomorphism A A
A: AbGroup
GroupIsomorphism A A
A: AbGroup
GroupHomomorphism A A
A: AbGroup
IsEquiv ?grp_iso_homo
A: AbGroup
GroupHomomorphism A A
A: AbGroup
A -> A
A: AbGroup
IsSemiGroupPreserving ?grp_homo_map
A: AbGroup
A -> A
exact (funa => -a).
A: AbGroup
IsSemiGroupPreserving (funa : A => - a)
A: AbGroup x, y: A
- (x + y) = - x - y
A: AbGroup x, y: A
- y - x = - x - y
apply commutativity.
A: AbGroup
IsEquiv
{|
grp_homo_map := funa : A => - a;
issemigrouppreserving_grp_homo :=
(funxy : A =>
grp_inv_op x y @ commutativity (- y) (- x))
:
IsSemiGroupPreserving (funa : A => - a)
|}
A: AbGroup
A -> A
A: AbGroup
{|
grp_homo_map := funa : A => - a;
issemigrouppreserving_grp_homo :=
(funxy : A =>
grp_inv_op x y @ commutativity (- y) (- x))
:
IsSemiGroupPreserving (funa : A => - a)
|} o ?g == idmap
A: AbGroup
?g
o {|
grp_homo_map := funa : A => - a;
issemigrouppreserving_grp_homo :=
(funxy : A =>
grp_inv_op x y @ commutativity (- y) (- x))
:
IsSemiGroupPreserving (funa : A => - a)
|} == idmap
A: AbGroup
{|
grp_homo_map := funa : A => - a;
issemigrouppreserving_grp_homo :=
(funxy : A =>
grp_inv_op x y @ commutativity (- y) (- x))
:
IsSemiGroupPreserving (funa : A => - a)
|} o (funa : A => - a) == idmap
A: AbGroup
(funa : A => - a)
o {|
grp_homo_map := funa : A => - a;
issemigrouppreserving_grp_homo :=
(funxy : A =>
grp_inv_op x y @ commutativity (- y) (- x))
:
IsSemiGroupPreserving (funa : A => - a)
|} == idmap
1-2: exact inverse_involutive.Defined.(** Multiplication by [n : Int] defines an endomorphism of any abelian group [A]. *)
A: AbGroup n: Int
GroupHomomorphism A A
A: AbGroup n: Int
GroupHomomorphism A A
A: AbGroup n: Int
A -> A
A: AbGroup n: Int
IsSemiGroupPreserving ?grp_homo_map
A: AbGroup n: Int
IsSemiGroupPreserving (funa : A => grp_pow a n)
A: AbGroup n: Int a, b: A
grp_pow (a + b) n = grp_pow a n + grp_pow b n
apply grp_pow_mul, commutativity.Defined.(** [ab_mul n] is natural. *)Definitionab_mul_natural {AB : AbGroup}
(f : GroupHomomorphism A B) (n : Int)
: f o ab_mul n == ab_mul n o f
:= grp_pow_natural f n.(** The image of an inclusion is a normal subgroup. *)Definitionab_image_embedding {AB : AbGroup} (f : A $-> B) `{IsEmbedding f} : NormalSubgroup B
:= {| normalsubgroup_subgroup := grp_image_embedding f; normalsubgroup_isnormal := _ |}.Definitionab_image_in_embedding {AB : AbGroup} (f : A $-> B) `{IsEmbedding f}
: GroupIsomorphism A (ab_image_embedding f)
:= grp_image_in_embedding f.(** The cokernel of a homomorphism into an abelian group. *)Definitionab_cokernel {G : Group@{u}} {A : AbGroup@{u}} (f : GroupHomomorphism G A)
: AbGroup := QuotientAbGroup _ (grp_image f).Definitionab_cokernel_embedding {G : Group} {A : AbGroup} (f : G $-> A) `{IsEmbedding f}
: AbGroup := QuotientAbGroup _ (grp_image_embedding f).
G: Group A, B: AbGroup f: G $-> A IsEmbedding0: IsEmbedding f h: A $-> B p: grp_homo_compose h f $== grp_homo_const
ab_cokernel_embedding f $-> B
G: Group A, B: AbGroup f: G $-> A IsEmbedding0: IsEmbedding f h: A $-> B p: grp_homo_compose h f $== grp_homo_const
ab_cokernel_embedding f $-> B
G: Group A, B: AbGroup f: G $-> A IsEmbedding0: IsEmbedding f h: A $-> B p: grp_homo_compose h f $== grp_homo_const
foralln : A,
{|
normalsubgroup_subgroup := grp_image_embedding f;
normalsubgroup_isnormal :=
isnormal_ab_subgroup A (grp_image_embedding f)
|} n -> h n = 0
G: Group A, B: AbGroup f: G $-> A IsEmbedding0: IsEmbedding f h: A $-> B p: grp_homo_compose h f $== grp_homo_const a: A g: G q: f g = a
h a = 0
G: Group A, B: AbGroup f: G $-> A IsEmbedding0: IsEmbedding f h: A $-> B p: grp_homo_compose h f $== grp_homo_const g: G