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 Cubical WildCat.Require Import Colimits.Coeq.Require Import Algebra.AbGroups.AbelianGroup.Require Import Modalities.ReflectiveSubuniverse.(** In this file we define what it means for a group homomorphism G -> H into an abelian group H to be an abelianization. We then construct an example of an abelianization. *)LocalOpen Scope mc_scope.LocalOpen Scope mc_mult_scope.LocalOpen Scope wc_iso_scope.(** Definition of Abelianization. A "unit" homomorphism [eta : G -> G_ab], with [G_ab] abelian, is considered an abelianization if and only if for all homomorphisms [G -> A], where [A] is abelian, there exists a unique [g : G_ab -> A] such that [h == g o eta X]. We express this in funext-free form by saying that precomposition with [eta] in the wild 1-category [Group] induces an equivalence of hom 0-groupoids, in the sense of WildCat/EquivGpd. Unfortunately, if [eta : GroupHomomorphism G G_ab] and we write [cat_precomp A eta] then Coq is unable to guess that the relevant 1-category is [Group]. Even writing [cat_precomp (A := Group) A eta] isn't good enough, I guess because the typeclass inference that finds the instance [is01cat_group] doesn't happen until after the type of [eta] would have to be resolved to a [Hom] in some wild category. However, with the following auxiliary definition we can force the typeclass inference to happen first. (It would be worth thinking about whether the design of the wild categories library could be improved to avoid this.) *)Definitiongroup_precomp {ab} := @cat_precomp Group _ _ a b.ClassIsAbelianization {G : Group} (G_ab : AbGroup)
(eta : GroupHomomorphism G G_ab)
:= issurjinj_isabel : forall (A : AbGroup),
IsSurjInj (group_precomp A eta).Global Existing Instanceissurjinj_isabel.(** Here we define abelianization as a HIT. Specifically as a set-coequalizer of the following two maps: (a, b, c) |-> a (b c) and (a, b, c) |-> a (c b).From this we can show that Abel G is an abelian group.In fact this models the following HIT:HIT Abel (G : Group) := | ab : G -> Abel G | ab_comm : forall x y z, ab (x * (y * z)) = ab (x * (z * y)).We also derive ab and ab_comm from our coequalizer definition, and even prove the induction and computation rules for this HIT.This HIT was suggested by Dan Christensen.*)SectionAbel.(** Let G be a group. *)Context (G : Group).(** We locally define a map uncurry2 that lets us uncurry A * B * C -> D twice. *)
G: Group A, B, C, D: Type
(A -> B -> C -> D) -> A * B * C -> D
G: Group A, B, C, D: Type
(A -> B -> C -> D) -> A * B * C -> D
G: Group A, B, C, D: Type f: A -> B -> C -> D a: A b: B c: C
D
byapply f.Defined.(** The type Abel is defined to be the set coequalizer of the following maps G^3 -> G. *)DefinitionAbel
:= Tr 0 (Coeq
(uncurry2 (funabc : G => a * (b * c)))
(uncurry2 (funabc : G => a * (c * b)))).(** We have a natural map from G to Abel G. *)
G: Group
G -> Abel
G: Group
G -> Abel
G: Group g: G
Abel
apply tr, coeq, g.Defined.(** This map satisfies the condition ab_comm. *)
G: Group a, b, c: G
ab (a * (b * c)) = ab (a * (c * b))
G: Group a, b, c: G
ab (a * (b * c)) = ab (a * (c * b))
G: Group a, b, c: G
coeq (a * (b * c)) = coeq (a * (c * b))
exact (cglue (a, b, c)).Defined.(** It is clear that Abel is a set. *)Global Instanceistrunc_abel : IsHSet Abel := _.(** We can derive the induction principle from the ones for truncation and the coequalizer. *)
G: Group P: Abel -> Type H: forallx : Abel, IsHSet (P x) a: forallx : G, P (ab x) c: forallxyz : G,
DPath P (ab_comm x y z) (a (x * (y * z)))
(a (x * (z * y)))
forallx : Abel, P x
G: Group P: Abel -> Type H: forallx : Abel, IsHSet (P x) a: forallx : G, P (ab x) c: forallxyz : G,
DPath P (ab_comm x y z) (a (x * (y * z)))
(a (x * (z * y)))
forallx : Abel, P x
G: Group P: Abel -> Type H: forallx : Abel, IsHSet (P x) a: forallx : G, P (ab x) c: forallxyz : G,
DPath P (ab_comm x y z) (a (x * (y * z)))
(a (x * (z * y)))
foralla : Coeq (uncurry2 (funabc : G => a * (b * c)))
(uncurry2 (funabc : G => a * (c * b))),
P (tr a)
G: Group P: Abel -> Type H: forallx : Abel, IsHSet (P x) a: forallx : G, P (ab x) c: forallxyz : G,
DPath P (ab_comm x y z) (a (x * (y * z)))
(a (x * (z * y)))
foralla : G,
(funw : Coeq
(uncurry2 (funa0bc : G => a0 * (b * c)))
(uncurry2 (funa0bc : G => a0 * (c * b)))
=> P (tr w)) (coeq a)
G: Group P: Abel -> Type H: forallx : Abel, IsHSet (P x) a: forallx : G, P (ab x) c: forallxyz : G,
DPath P (ab_comm x y z) (a (x * (y * z)))
(a (x * (z * y)))
forallb : G * G * G,
transport
(funw : Coeq
(uncurry2 (funab0c : G => a * (b0 * c)))
(uncurry2 (funab0c : G => a * (c * b0)))
=> P (tr w)) (cglue b)
(?coeq'
(uncurry2 (funab0c : G => a * (b0 * c)) b)) =
?coeq' (uncurry2 (funab0c : G => a * (c * b0)) b)
G: Group P: Abel -> Type H: forallx : Abel, IsHSet (P x) a: forallx : G, P (ab x) c: forallxyz : G,
DPath P (ab_comm x y z) (a (x * (y * z)))
(a (x * (z * y)))
forallb : G * G * G,
transport
(funw : Coeq
(uncurry2 (funab0c : G => a * (b0 * c)))
(uncurry2 (funab0c : G => a * (c * b0)))
=> P (tr w)) (cglue b)
(a (uncurry2 (funab0c : G => a * (b0 * c)) b)) =
a (uncurry2 (funab0c : G => a * (c * b0)) b)
G: Group P: Abel -> Type H: forallx : Abel, IsHSet (P x) a: forallx : G, P (ab x) c: forallxyz : G,
DPath P (ab_comm x y z) (a (x * (y * z)))
(a (x * (z * y))) x, y, z: G
transport
(funw : Coeq
(uncurry2 (funabc : G => a * (b * c)))
(uncurry2 (funabc : G => a * (c * b)))
=> P (tr w)) (cglue (x, y, z))
(a
(uncurry2 (funabc : G => a * (b * c))
(x, y, z))) =
a (uncurry2 (funabc : G => a * (c * b)) (x, y, z))
G: Group P: Abel -> Type H: forallx : Abel, IsHSet (P x) a: forallx : G, P (ab x) c: forallxyz : G,
DPath P (ab_comm x y z) (a (x * (y * z)))
(a (x * (z * y))) x, y, z: G
transport P (ap tr (cglue (x, y, z)))
(a
(uncurry2 (funabc : G => a * (b * c))
(x, y, z))) =
a (uncurry2 (funabc : G => a * (c * b)) (x, y, z))
apply c.Defined.(** The computation rule can also be proven. *)
G: Group P: Abel -> Type H: forallx : Abel, IsHSet (P x) a: forallx : G, P (ab x) c: forallxyz : G,
DPath P (ab_comm x y z) (a (x * (y * z)))
(a (x * (z * y))) x, y, z: G
apD (Abel_ind P a c) (ab_comm x y z) = c x y z
G: Group P: Abel -> Type H: forallx : Abel, IsHSet (P x) a: forallx : G, P (ab x) c: forallxyz : G,
DPath P (ab_comm x y z) (a (x * (y * z)))
(a (x * (z * y))) x, y, z: G
apD (Abel_ind P a c) (ab_comm x y z) = c x y z
G: Group P: Abel -> Type H: forallx : Abel, IsHSet (P x) a: forallx : G, P (ab x) c: forallxyz : G,
DPath P (ab_comm x y z) (a (x * (y * z)))
(a (x * (z * y))) x, y, z: G
apD
(funx : Coeq
(uncurry2 (funabc : G => a * (b * c)))
(uncurry2 (funabc : G => a * (c * b)))
=> Abel_ind P a c (tr x)) (cglue (x, y, z)) =
transport_compose P tr (cglue (x, y, z))
(Abel_ind P a c (tr (coeq (x * (y * z))))) @ c x y z
rapply Coeq_ind_beta_cglue.Defined.(** We also have a recursion princple. *)
G: Group P: Type IsHSet0: IsHSet P a: G -> P c: forallxyz : G,
a (x * (y * z)) = a (x * (z * y))
Abel -> P
G: Group P: Type IsHSet0: IsHSet P a: G -> P c: forallxyz : G,
a (x * (y * z)) = a (x * (z * y))
Abel -> P
G: Group P: Type IsHSet0: IsHSet P a: G -> P c: forallxyz : G,
a (x * (y * z)) = a (x * (z * y))
forallxyz : G,
DPath (fun_ : Abel => P) (ab_comm x y z)
(a (x * (y * z))) (a (x * (z * y)))
intros; apply dp_const, c.Defined.(** Here is a simpler version of Abel_ind when our target is an HProp. This lets us discard all the higher paths. *)
G: Group P: Abel -> Type H: forallx : Abel, IsHProp (P x) a: forallx : G, P (ab x)
forallx : Abel, P x
G: Group P: Abel -> Type H: forallx : Abel, IsHProp (P x) a: forallx : G, P (ab x)
forallx : Abel, P x
G: Group P: Abel -> Type H: forallx : Abel, IsHProp (P x) a: forallx : G, P (ab x)
forallxyz : G,
DPath P (ab_comm x y z) (a (x * (y * z)))
(a (x * (z * y)))
intros; apply path_ishprop.Defined.(** And its recursion version. *)
G: Group P: Type IsHProp0: IsHProp P a: G -> P
Abel -> P
G: Group P: Type IsHProp0: IsHProp P a: G -> P
Abel -> P
G: Group P: Type IsHProp0: IsHProp P a: G -> P
forallxyz : G, a (x * (y * z)) = a (x * (z * y))
intros; apply path_ishprop.Defined.EndAbel.(** The [IsHProp] argument of [Abel_ind_hprop] can usually be found by typeclass resolution, but [srapply] is slow, so we use this tactic instead. *)Local LtacAbel_ind_hprop x := snrapply Abel_ind_hprop; [exact _ | intro x].(** We make sure that G is implicit in the arguments of ab and ab_comm. *)Arguments ab {_}.Arguments ab_comm {_}.(** Now we can show that Abel G is in fact an abelian group. *)SectionAbelGroup.Context (G : Group).(** Firstly we derive the operation on Abel G. This is defined as follows: ab x + ab y := ab (x y) But we need to also check that it preserves ab_comm in the appropriate way. *)
forallxyz : G,
(funa : G => ab (a * b)) (x * (y * z)) =
(funa : G => ab (a * b)) (x * (z * y))
G: Group b, a, c, d: G
ab (a * (c * d) * b) = ab (a * (d * c) * b)
(* The pattern seems to be to alternate associativity and ab_comm. *)
G: Group b, a, c, d: G
ab (a * (c * d * b)) = ab (a * (d * c) * b)
G: Group b, a, c, d: G
ab (a * (b * (c * d))) = ab (a * (d * c) * b)
G: Group b, a, c, d: G
ab (a * b * (c * d)) = ab (a * (d * c) * b)
G: Group b, a, c, d: G
ab (a * b * (d * c)) = ab (a * (d * c) * b)
G: Group b, a, c, d: G
ab (a * (b * (d * c))) = ab (a * (d * c) * b)
G: Group b, a, c, d: G
ab (a * (d * c * b)) = ab (a * (d * c) * b)
refine (ap _ (associativity _ _ _)).
G: Group a: Abel G
forallxyz : G,
(funb : G =>
Abel_rec G (Abel G) (funa : G => ab (a * b))
(funacd : G =>
ap ab (associativity a (c * d) b)^ @
(ab_comm a (c * d) b @
(ap ab (associativity a b (c * d)) @
(ab_comm (a * b) c d @
(ap ab (associativity a b (d * c))^ @
(ab_comm a b (d * c) @
ap ab (associativity a (d * c) b))))))
:
(funa0 : G => ab (a0 * b)) (a * (c * d)) =
(funa0 : G => ab (a0 * b)) (a * (d * c))) a)
(x * (y * z)) =
(funb : G =>
Abel_rec G (Abel G) (funa : G => ab (a * b))
(funacd : G =>
ap ab (associativity a (c * d) b)^ @
(ab_comm a (c * d) b @
(ap ab (associativity a b (c * d)) @
(ab_comm (a * b) c d @
(ap ab (associativity a b (d * c))^ @
(ab_comm a b (d * c) @
ap ab (associativity a (d * c) b))))))
:
(funa0 : G => ab (a0 * b)) (a * (c * d)) =
(funa0 : G => ab (a0 * b)) (a * (d * c))) a)
(x * (z * y))
G: Group a: Abel G b, c, d: G
(funb : G =>
Abel_rec G (Abel G) (funa : G => ab (a * b))
(funacd : G =>
ap ab (associativity a (c * d) b)^ @
(ab_comm a (c * d) b @
(ap ab (associativity a b (c * d)) @
(ab_comm (a * b) c d @
(ap ab (associativity a b (d * c))^ @
(ab_comm a b (d * c) @
ap ab (associativity a (d * c) b))))))
:
(funa0 : G => ab (a0 * b)) (a * (c * d)) =
(funa0 : G => ab (a0 * b)) (a * (d * c))) a)
(b * (c * d)) =
(funb : G =>
Abel_rec G (Abel G) (funa : G => ab (a * b))
(funacd : G =>
ap ab (associativity a (c * d) b)^ @
(ab_comm a (c * d) b @
(ap ab (associativity a b (c * d)) @
(ab_comm (a * b) c d @
(ap ab (associativity a b (d * c))^ @
(ab_comm a b (d * c) @
ap ab (associativity a (d * c) b))))))
:
(funa0 : G => ab (a0 * b)) (a * (c * d)) =
(funa0 : G => ab (a0 * b)) (a * (d * c))) a)
(b * (d * c))
G: Group b, c, d: G
foralla : Abel G,
(funb : G =>
Abel_rec G (Abel G) (funa0 : G => ab (a0 * b))
(funa0cd : G =>
ap ab (associativity a0 (c * d) b)^ @
(ab_comm a0 (c * d) b @
(ap ab (associativity a0 b (c * d)) @
(ab_comm (a0 * b) c d @
(ap ab (associativity a0 b (d * c))^ @
(ab_comm a0 b (d * c) @
ap ab (associativity a0 (d * c) b))))))
:
(funa1 : G => ab (a1 * b)) (a0 * (c * d)) =
(funa1 : G => ab (a1 * b)) (a0 * (d * c))) a)
(b * (c * d)) =
(funb : G =>
Abel_rec G (Abel G) (funa0 : G => ab (a0 * b))
(funa0cd : G =>
ap ab (associativity a0 (c * d) b)^ @
(ab_comm a0 (c * d) b @
(ap ab (associativity a0 b (c * d)) @
(ab_comm (a0 * b) c d @
(ap ab (associativity a0 b (d * c))^ @
(ab_comm a0 b (d * c) @
ap ab (associativity a0 (d * c) b))))))
:
(funa1 : G => ab (a1 * b)) (a0 * (c * d)) =
(funa1 : G => ab (a1 * b)) (a0 * (d * c))) a)
(b * (d * c))
G: Group b, c, d, a: G
ab (a * (b * (c * d))) = ab (a * (b * (d * c)))
G: Group b, c, d, a: G
ab (a * b * (c * d)) = ab (a * (b * (d * c)))
G: Group b, c, d, a: G
ab (a * b * (d * c)) = ab (a * (b * (d * c)))
refine (ap _ (associativity _ _ _)^).Defined.(** We can now easily show that this operation is associative by associativity in G and the fact that being associative is a proposition. *)
G: Group
Associative abel_sgop
G: Group
Associative abel_sgop
G: Group x, y: Abel G
forallz : Abel G,
abel_sgop x (abel_sgop y z) =
abel_sgop (abel_sgop x y) z
G: Group x: Abel G z: G
forally : Abel G,
(funx0 : Abel G =>
abel_sgop x (abel_sgop y x0) =
abel_sgop (abel_sgop x y) x0) (ab z)
G: Group z, y: G
forallx : Abel G,
(funx0 : Abel G =>
(funx1 : Abel G =>
abel_sgop x (abel_sgop x0 x1) =
abel_sgop (abel_sgop x x0) x1) (ab z)) (ab y)
G: Group z, y, x: G
ab (x * (y * z)) = ab (x * y * z)
apply ap, associativity.Defined.(** From this we know that Abel G is a semigroup. *)Global Instanceabel_issemigroup : IsSemiGroup (Abel G) := {}.(** We define the unit as ab of the unit of G *)Global Instanceabel_mon_unit : MonUnit (Abel G) := ab mon_unit.(** By using Abel_ind_hprop we can prove the left and right identity laws. *)
G: Group
LeftIdentity abel_sgop abel_mon_unit
G: Group
LeftIdentity abel_sgop abel_mon_unit
G: Group x: G
(funx : Abel G => abel_sgop abel_mon_unit x = x)
(ab x)
simpl; apply ap, left_identity.Defined.
G: Group
RightIdentity abel_sgop abel_mon_unit
G: Group
RightIdentity abel_sgop abel_mon_unit
G: Group x: G
(funx : Abel G => abel_sgop x abel_mon_unit = x)
(ab x)
simpl; apply ap, right_identity.Defined.(** Hence Abel G is a monoid *)Global Instanceismonoid_abel : IsMonoid (Abel G) := {}.(** We can also prove that the operation is commutative! This will come in handy later. *)
G: Group
Commutative abel_sgop
G: Group
Commutative abel_sgop
G: Group x: Abel G
forally : Abel G, abel_sgop x y = abel_sgop y x
G: Group x: Abel G y: G
(funx0 : Abel G => abel_sgop x x0 = abel_sgop x0 x)
(ab y)
G: Group y: G
forallx : Abel G,
(funx0 : Abel G => abel_sgop x x0 = abel_sgop x0 x)
(ab y)
G: Group y, x: G
(funx : Abel G =>
(funx0 : Abel G => abel_sgop x x0 = abel_sgop x0 x)
(ab y)) (ab x)
G: Group y, x: G
ab (mon_unit * (x * y)) = abel_sgop (ab y) (ab x)
G: Group y, x: G
ab (mon_unit * (x * y)) = ab (mon_unit * (y * x))
apply ab_comm.Defined.(** Now we can define the negation. This is just - (ab g) := (ab (g^-1)) However when checking that it respects ab_comm we have to show the following: ab (- z * - y * - x) = ab (- y * - z * - x) there is no obvious way to do this, but we note that ab (x * y) is exactly the definition of ab x + ab y! Hence by commutativity we can show this. *)
forallxyz : G,
(fung : G => ab (- g)) (x * (y * z)) =
(fung : G => ab (- g)) (x * (z * y))
G: Group x, y, z: G
ab (- (x * (y * z))) = ab (- (x * (z * y)))
G: Group x, y, z: G
ab (- z * - y * - x) = ab (- y * - z * - x)
G: Group x, y, z: G
ab (- z) * ab (- y) * ab (- x) =
ab (- y) * ab (- z) * ab (- x)
byrewrite (commutativity (ab (-z)) (ab (-y))).Defined.(** Again by Abel_ind_hprop and the corresponding laws for G we can prove the left and right inverse laws. *)
G: Group
LeftInverse abel_sgop abel_negate abel_mon_unit
G: Group
LeftInverse abel_sgop abel_negate abel_mon_unit
G: Group x: G
ab (- x * x) = abel_mon_unit
apply ap; apply left_inverse.Defined.
G: Group
RightInverse abel_sgop abel_negate abel_mon_unit
G: Group
RightInverse abel_sgop abel_negate abel_mon_unit
G: Group x: G
ab (x * - x) = abel_mon_unit
apply ap; apply right_inverse.Defined.(** Thus Abel G is a group *)Global Instanceisgroup_abel : IsGroup (Abel G) := {}.(** And since the operation is commutative, an abelian group. *)Global Instanceisabgroup_abel : IsAbGroup (Abel G) := {}.(** By definition, the map ab is also a group homomorphism. *)
G: Group
IsSemiGroupPreserving ab
G: Group
IsSemiGroupPreserving ab
byunfold IsSemiGroupPreserving.Defined.EndAbelGroup.(** We can easily prove that ab is a surjection. *)
G: Group
IsConnMap (Tr (-1)) ab
G: Group
IsConnMap (Tr (-1)) ab
G: Group
forallb : Abel G, merely (hfiber ab b)
G: Group x: G
(funx : Abel G =>
trunctype_type (merely (hfiber ab x))) (ab x)
G: Group x: G
Trunc (-1) (hfiber ab (ab x))
G: Group x: G
hfiber ab (ab x)
G: Group x: G
ab x = ab x
reflexivity.Defined.(** Now we finally check that our definition of abelianization satisfies the universal property of being an abelianization. *)(** We define abel to be the abelianization of a group. This is a map from Group to AbGroup. *)
Group -> AbGroup
Group -> AbGroup
G: Group
AbGroup
G: Group
Group
G: Group
Commutative group_sgop
G: Group
Group
srapply (Build_Group (Abel G)).
G: Group
Commutative group_sgop
exact _.Defined.(** The unit of this map is the map ab which typeclasses can pick up to be a homomorphism. We write it out explicitly here. *)
X: Group
GroupHomomorphism X (abel X)
X: Group
GroupHomomorphism X (abel X)
X: Group
X -> abel X
X: Group
IsSemiGroupPreserving ?f
X: Group
X -> abel X
exact ab.
X: Group
IsSemiGroupPreserving ab
exact _.Defined.(** Finally we can prove that our construction abel is an abelianization. *)
G: Group
IsAbelianization (abel G) (abel_unit G)
G: Group
IsAbelianization (abel G) (abel_unit G)
G: Group A: AbGroup
IsSurjInj (group_precomp A (abel_unit G))
G: Group A: AbGroup
SplEssSurj (group_precomp A (abel_unit G))
G: Group A: AbGroup
forallxy : abel G $-> A,
group_precomp A (abel_unit G) x $==
group_precomp A (abel_unit G) y -> x $== y
G: Group A: AbGroup
SplEssSurj (group_precomp A (abel_unit G))
G: Group A: AbGroup h: G $-> A
{a : abel G $-> A &
group_precomp A (abel_unit G) a $== h}
G: Group A: AbGroup h: G $-> A
abel G $-> A
G: Group A: AbGroup h: G $-> A
(funa : abel G $-> A =>
group_precomp A (abel_unit G) a $== h) ?proj1
G: Group A: AbGroup h: G $-> A
abel G $-> A
G: Group A: AbGroup h: G $-> A
abel G -> A
G: Group A: AbGroup h: G $-> A
IsSemiGroupPreserving ?f
G: Group A: AbGroup h: G $-> A
abel G -> A
G: Group A: AbGroup h: G $-> A
forallxyz : G, h (x * (y * z)) = h (x * (z * y))
G: Group A: AbGroup h: G $-> A x, y, z: G
h (x * (y * z)) = h (x * (z * y))
G: Group A: AbGroup h: G $-> A x, y, z: G
h x * h (y * z) = h x * h (z * y)
G: Group A: AbGroup h: G $-> A x, y, z: G
h (y * z) = h (z * y)
G: Group A: AbGroup h: G $-> A x, y, z: G
h y * h z = h z * h y
apply commutativity.
G: Group A: AbGroup h: G $-> A
IsSemiGroupPreserving
(Abel_rec G A h
(funxyz : G =>
(grp_homo_op h x (y * z) @
ap (sg_op (h x))
((grp_homo_op h y z @
commutativity (h y) (h z)) @
(grp_homo_op h z y)^)) @
(grp_homo_op h x (z * y))^))
G: Group A: AbGroup h: G $-> A y: abel G
forally0 : abel G,
Abel_rec G A h
(funxyz : G =>
(grp_homo_op h x (y * z) @
ap (sg_op (h x))
((grp_homo_op h y z @ commutativity (h y) (h z)) @
(grp_homo_op h z y)^)) @
(grp_homo_op h x (z * y))^) (y * y0) =
Abel_rec G A h
(funxyz : G =>
(grp_homo_op h x (y * z) @
ap (sg_op (h x))
((grp_homo_op h y z @ commutativity (h y) (h z)) @
(grp_homo_op h z y)^)) @
(grp_homo_op h x (z * y))^) y *
Abel_rec G A h
(funxyz : G =>
(grp_homo_op h x (y * z) @
ap (sg_op (h x))
((grp_homo_op h y z @ commutativity (h y) (h z)) @
(grp_homo_op h z y)^)) @
(grp_homo_op h x (z * y))^) y0
G: Group A: AbGroup h: G $-> A x: G
forally : abel G,
(funx : Abel G =>
Abel_rec G A h
(funx0y0z : G =>
(grp_homo_op h x0 (y0 * z) @
ap (sg_op (h x0))
((grp_homo_op h y0 z @
commutativity (h y0) (h z)) @
(grp_homo_op h z y0)^)) @
(grp_homo_op h x0 (z * y0))^) (y * x) =
Abel_rec G A h
(funx0y0z : G =>
(grp_homo_op h x0 (y0 * z) @
ap (sg_op (h x0))
((grp_homo_op h y0 z @
commutativity (h y0) (h z)) @
(grp_homo_op h z y0)^)) @
(grp_homo_op h x0 (z * y0))^) y *
Abel_rec G A h
(funx0y0z : G =>
(grp_homo_op h x0 (y0 * z) @
ap (sg_op (h x0))
((grp_homo_op h y0 z @
commutativity (h y0) (h z)) @
(grp_homo_op h z y0)^)) @
(grp_homo_op h x0 (z * y0))^) x) (ab x)
G: Group A: AbGroup h: G $-> A x, y: G
(funx0 : Abel G =>
(funx : Abel G =>
Abel_rec G A h
(funx1yz : G =>
(grp_homo_op h x1 (y * z) @
ap (sg_op (h x1))
((grp_homo_op h y z @
commutativity (h y) (h z)) @
(grp_homo_op h z y)^)) @
(grp_homo_op h x1 (z * y))^) (x0 * x) =
Abel_rec G A h
(funx1yz : G =>
(grp_homo_op h x1 (y * z) @
ap (sg_op (h x1))
((grp_homo_op h y z @
commutativity (h y) (h z)) @
(grp_homo_op h z y)^)) @
(grp_homo_op h x1 (z * y))^) x0 *
Abel_rec G A h
(funx1yz : G =>
(grp_homo_op h x1 (y * z) @
ap (sg_op (h x1))
((grp_homo_op h y z @
commutativity (h y) (h z)) @
(grp_homo_op h z y)^)) @
(grp_homo_op h x1 (z * y))^) x) (ab x)) (ab y)
apply grp_homo_op.
G: Group A: AbGroup h: G $-> A
(funa : abel G $-> A =>
group_precomp A (abel_unit G) a $== h)
(Build_GroupHomomorphism
(Abel_rec G A h
(funxyz : G =>
(grp_homo_op h x (y * z) @
ap (sg_op (h x))
((grp_homo_op h y z @
commutativity (h y) (h z)) @
(grp_homo_op h z y)^)) @
(grp_homo_op h x (z * y))^)))
G: Group A: AbGroup h: G $-> A
(funx : G =>
Coeq_ind
(fun_ : Coeq
(uncurry2 (funabc : G => a * (b * c)))
(uncurry2 (funabc : G => a * (c * b)))
=> A) h
(funb : G * G * G =>
transport_compose
(fun_ : Trunc 0
(Coeq
(uncurry2
(funab0c : G => a * (b0 * c)))
(uncurry2
(funab0c : G => a * (c * b0))))
=> A) tr
(cglue (fst (fst b), snd (fst b), snd b))
(h
(uncurry2 (funab0c : G => a * (b0 * c))
(fst (fst b), snd (fst b), snd b))) @
dp_const
((grp_homo_op h (fst (fst b))
(snd (fst b) * snd b) @
ap (sg_op (h (fst (fst b))))
((grp_homo_op h (snd (fst b)) (snd b) @
commutativity (h (snd (fst b)))
(h (snd b))) @
(grp_homo_op h (snd b) (snd (fst b)))^)) @
(grp_homo_op h (fst (fst b))
(snd b * snd (fst b)))^)) (coeq x)) == h
reflexivity.
G: Group A: AbGroup
forallxy : abel G $-> A,
group_precomp A (abel_unit G) x $==
group_precomp A (abel_unit G) y -> x $== y
G: Group A: AbGroup g, h: abel G $-> A p: group_precomp A (abel_unit G) g $==
group_precomp A (abel_unit G) h
g $== h
G: Group A: AbGroup g, h: abel G $-> A p: group_precomp A (abel_unit G) g $==
group_precomp A (abel_unit G) h x: G
(funx : Abel G =>
(grp_homo_map (abel G) A
:
GroupHomomorphism (abel G) A -> abel G $-> A) g x =
(grp_homo_map (abel G) A
:
GroupHomomorphism (abel G) A -> abel G $-> A) h x)
(ab x)
exact (p x).Defined.
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2
A ≅ B
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2
A ≅ B
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 a: A $-> B ac: group_precomp B eta1 a $== eta2
A ≅ B
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 a: A $-> B ac: group_precomp B eta1 a $== eta2 b: B $-> A bc: group_precomp A eta2 b $== eta1
A ≅ B
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 a: A $-> B ac: group_precomp B eta1 a $== eta2 b: B $-> A bc: group_precomp A eta2 b $== eta1
IsEquiv a
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 a: A $-> B ac: group_precomp B eta1 a $== eta2 b: B $-> A bc: group_precomp A eta2 b $== eta1
a o b == idmap
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 a: A $-> B ac: group_precomp B eta1 a $== eta2 b: B $-> A bc: group_precomp A eta2 b $== eta1
b o a == idmap
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 a: A $-> B ac: group_precomp B eta1 a $== eta2 b: B $-> A bc: group_precomp A eta2 b $== eta1
a o b == idmap
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 a: A $-> B ac: group_precomp B eta1 a $== eta2 b: B $-> A bc: group_precomp A eta2 b $== eta1
group_precomp B eta2 (a $o b) $==
group_precomp B eta2 (Id B)
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 a: GroupHomomorphism A B ac: (funx : G => a (eta1 x)) == eta2 b: GroupHomomorphism B A bc: (funx : G => b (eta2 x)) == eta1 x: G
a (b (eta2 x)) = eta2 x
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 a: GroupHomomorphism A B ac: (funx : G => a (eta1 x)) == eta2 b: GroupHomomorphism B A bc: (funx : G => b (eta2 x)) == eta1 x: G
a (b (eta2 x)) = a (eta1 x)
apply ap, bc.
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 a: A $-> B ac: group_precomp B eta1 a $== eta2 b: B $-> A bc: group_precomp A eta2 b $== eta1
b o a == idmap
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 a: A $-> B ac: group_precomp B eta1 a $== eta2 b: B $-> A bc: group_precomp A eta2 b $== eta1
b o a == idmap
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 a: A $-> B ac: group_precomp B eta1 a $== eta2 b: B $-> A bc: group_precomp A eta2 b $== eta1
group_precomp A eta1 (b $o a) $==
group_precomp A eta1 (Id A)
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 a: GroupHomomorphism A B ac: (funx : G => a (eta1 x)) == eta2 b: GroupHomomorphism B A bc: (funx : G => b (eta2 x)) == eta1 x: G
b (a (eta1 x)) = eta1 x
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 a: GroupHomomorphism A B ac: (funx : G => a (eta1 x)) == eta2 b: GroupHomomorphism B A bc: (funx : G => b (eta2 x)) == eta1 x: G
b (a (eta1 x)) = b (eta2 x)
apply ap, ac.}Defined.
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2
eta2 ==
grp_homo_compose
(groupiso_isabelianization A B eta1 eta2) eta1
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2
eta2 ==
grp_homo_compose
(groupiso_isabelianization A B eta1 eta2) eta1
G: Group A, B: AbGroup eta1: GroupHomomorphism G A eta2: GroupHomomorphism G B isab1: IsAbelianization A eta1 isab2: IsAbelianization B eta2 x: G
eta2 x =
grp_homo_compose
(groupiso_isabelianization A B eta1 eta2) eta1 x
exact (((esssurj (group_precomp B eta1) eta2).2 x)^).Defined.(** Hence any abelianization is surjective. *)
G: Group A: AbGroup eta: GroupHomomorphism G A
IsAbelianization A eta -> IsConnMap (Tr (-1)) eta
G: Group A: AbGroup eta: GroupHomomorphism G A
IsAbelianization A eta -> IsConnMap (Tr (-1)) eta
G: Group A: AbGroup eta: GroupHomomorphism G A k: IsAbelianization A eta
IsConnMap (Tr (-1)) eta
G: Group A: AbGroup eta: GroupHomomorphism G A k: IsAbelianization A eta p:= homotopic_isabelianization A (abel G) eta
(abel_unit G): abel_unit G ==
grp_homo_compose
(groupiso_isabelianization A (abel G) eta
(abel_unit G)) eta