module Algebra.Group.Ab where

Abelian groupsπŸ”—

A very important class of groups (which includes most familiar examples of groups: the integers, all finite cyclic groups, etc) are those with a commutative group operation, that is, those for which Accordingly, these have a name reflecting their importance and ubiquity: They are called commutative groups. Just kidding! They’re named abelian groups, named after a person, because nothing can have self-explicative names in mathematics. It’s the law.

This module does the usual algebraic structure dance to set up the category of Abelian groups.

record is-abelian-group (_*_ : G β†’ G β†’ G) : Type (level-of G) where
    has-is-group : is-group _*_
    commutes     : βˆ€ {x y} β†’ x * y ≑ y * x
  open is-group has-is-group renaming (unit to 1g) public
record Abelian-group-on (T : Type β„“) : Type β„“ where
    _*_       : T β†’ T β†’ T
    has-is-ab : is-abelian-group _*_
  open is-abelian-group has-is-ab renaming (inverse to infixl 30 _⁻¹) public
Abelian-group-structure : βˆ€ β„“ β†’ Thin-structure β„“ Abelian-group-on
∣ Abelian-group-structure β„“ .is-hom f G₁ Gβ‚‚ ∣ =
  is-group-hom (Abelianβ†’Group-on G₁) (Abelianβ†’Group-on Gβ‚‚) f
Abelian-group-structure β„“ .is-hom f G₁ Gβ‚‚ .is-tr = hlevel 1
Abelian-group-structure β„“ .id-is-hom .is-group-hom.pres-⋆ x y = refl
Abelian-group-structure β„“ .∘-is-hom f g Ξ± Ξ² .is-group-hom.pres-⋆ x y =
  ap f (Ξ² .is-group-hom.pres-⋆ x y) βˆ™ Ξ± .is-group-hom.pres-⋆ (g x) (g y)
Abelian-group-structure β„“ .id-hom-unique {s = s} {t} Ξ± _ = p where
  open Abelian-group-on

  p : s ≑ t
  p i ._*_ x y = Ξ± .is-group-hom.pres-⋆ x y i
  p i .has-is-ab = is-prop→pathp
    (Ξ» i β†’ hlevel {T = is-abelian-group (Ξ» x y β†’ p i ._*_ x y)} 1)
    (s .has-is-ab) (t .has-is-ab) i

Ab : βˆ€ β„“ β†’ Precategory (lsuc β„“) β„“
Ab β„“ = Structured-objects (Abelian-group-structure β„“)

module Ab {β„“} = Cat.Reasoning (Ab β„“)
Abelian-group : (β„“ : Level) β†’ Type (lsuc β„“)
Abelian-group _ = Ab.Ob

Abelianβ†’Group : βˆ€ {β„“} β†’ Abelian-group β„“ β†’ Group β„“
Abelian→Group G = G .fst , Abelian→Group-on (G .snd)

record make-abelian-group (T : Type β„“) : Type β„“ where
    ab-is-set : is-set T
    mul   : T β†’ T β†’ T
    inv   : T β†’ T
    1g    : T
    idl   : βˆ€ x β†’ mul 1g x ≑ x
    assoc : βˆ€ x y z β†’ mul x (mul y z) ≑ mul (mul x y) z
    invl  : βˆ€ x β†’ mul (inv x) x ≑ 1g
    comm  : βˆ€ x y β†’ mul x y ≑ mul y x

  make-abelian-group→make-group : make-group T
  make-abelian-group→make-group = mg where
    mg : make-group T
    mg = ab-is-set
    mg .make-group.unit   = 1g
    mg .make-group.mul    = mul
    mg .make-group.inv    = inv
    mg .make-group.assoc  = assoc
    mg .make-group.invl   = invl
    mg .make-group.idl    = idl

  to-group-on-ab : Group-on T
  to-group-on-ab = to-group-on make-abelian-group→make-group

  to-abelian-group-on : Abelian-group-on T
  to-abelian-group-on .Abelian-group-on._*_ = mul
  to-abelian-group-on .Abelian-group-on.has-is-ab .is-abelian-group.has-is-group =
    Group-on.has-is-group to-group-on-ab
  to-abelian-group-on .Abelian-group-on.has-is-ab .is-abelian-group.commutes =
    comm _ _

  to-ab : Abelian-group β„“
  ∣ to-ab .fst ∣ = T
  to-ab .fst .is-tr = ab-is-set
  to-ab .snd = to-abelian-group-on

is-commutative-group : βˆ€ {β„“} β†’ Group β„“ β†’ Type β„“
is-commutative-group G = Group-on-is-abelian (G .snd)

  : βˆ€ {β„“} (G : Group β„“)
  β†’ is-commutative-group G
  β†’ Abelian-group β„“
from-commutative-group G comm .fst = G .fst
from-commutative-group G comm .snd .Abelian-group-on._*_ =
  Group-on._⋆_ (G .snd)
from-commutative-group G comm .snd .Abelian-group-on.has-is-ab .is-abelian-group.has-is-group =
  Group-on.has-is-group (G .snd)
from-commutative-group G comm .snd .Abelian-group-on.has-is-ab .is-abelian-group.commutes =
  comm _ _

open make-abelian-group using (make-abelian-group→make-group ; to-group-on-ab ; to-abelian-group-on ; to-ab) public

open Functor

Abβ†ͺGrp : βˆ€ {β„“} β†’ Functor (Ab β„“) (Groups β„“)
Abβ†ͺGrp .Fβ‚€ = Abelianβ†’Group
Abβ†ͺGrp .F₁ f .hom = f .hom
Abβ†ͺGrp .F₁ f .preserves = f .preserves
Abβ†ͺGrp .F-id = trivial!
Abβ†ͺGrp .F-∘ f g = trivial!

Abβ†ͺSets : βˆ€ {β„“} β†’ Functor (Ab β„“) (Sets β„“)
Abβ†ͺSets = Grpβ†ͺSets F∘ Abβ†ͺGrp

The fundamental example of abelian group is the integers, under addition. A type-theoretic interjection is necessary: the integers live on the zeroth universe, so to have an group of integers, we must lift it.

β„€-ab : βˆ€ {β„“} β†’ Abelian-group β„“
β„€-ab = to-ab mk-β„€ where
  open make-abelian-group
  mk-β„€ : make-abelian-group (Lift _ Int)
  mk-β„€ .ab-is-set = hlevel 2
  mk-β„€ .mul (lift x) (lift y) = lift (x +β„€ y)
  mk-β„€ .inv (lift x) = lift (negβ„€ x)
  mk-β„€ .1g = lift 0
  mk-β„€ .idl (lift x) = ap lift (+β„€-zerol x)
  mk-β„€ .assoc (lift x) (lift y) (lift z) = ap lift (+β„€-assoc x y z)
  mk-β„€ .invl (lift x) = ap lift (+β„€-invl x)
  mk-β„€ .comm (lift x) (lift y) = ap lift (+β„€-commutative x y)

β„€ : βˆ€ {β„“} β†’ Group β„“
℀ = Abelian→Group ℀-ab