module Algebra.Ring.Module where

Modules🔗

A module over a ring RR is an abelian group GG equipped with an action by RR. Modules generalise the idea of vector spaces, which may be familiar from linear algebra, by replacing the field of scalars by a ring of scalars. More pertinently, though, modules specialise functors: specifically, Ab\mathbf{Ab}-enriched functors into the category Ab\mathbf{Ab}.

For silly formalisation reasons, when defining modules, we do not take “an Ab\mathbf{Ab}-functor into Ab\mathbf{Ab}” as the definition: this correspondence is a theorem we prove later. Instead, we set up RR-modules as typical algebraic structures, as data (and property) attached to a type.

The structure of an RR-module on a type TT consists of an addition +:T×T→T+ : T \times T \to T and a scalar multiplication ⋆:R×T→T\star : R \times T \to T. In prose, we generally omit the star, writing rxrx rather than the wordlier r⋆xr \star x. These must satisfy the following properties:

  • ++ makes TT into an abelian group. Since we’ve already defined abelian groups, we can take this entire property as “indivisible”, saving some effort.

  • ⋅· is a ring homomorphism of RR onto (T,+)(T, +)’s endomorphism ring. In other words, we have:

    • 1x=x1x = x;
    • (rs)⋅x=r⋅(s⋅x)(rs) \cdot x = r \cdot (s \cdot x);
    • (r+s)x=rx+sx(r + s)x = rx + sx; and
    • r(x+y)=rx+ryr(x + y) = rx + ry.
  record is-module {ℓ'} {T : Type ℓ'} (_+_ : T → T → T) (_⋆_ : ⌞ R ⌟ → T → T) : Type (ℓ ⊔ ℓ') where
    no-eta-equality
    field
      has-is-ab  : is-abelian-group _+_
      ⋆-distribl : ∀ r x y → r ⋆ (x + y)   ≡ (r ⋆ x) + (r ⋆ y)
      ⋆-distribr : ∀ r s x → (r R.+ s) ⋆ x ≡ (r ⋆ x) + (s ⋆ x)
      ⋆-assoc    : ∀ r s x → r ⋆ (s ⋆ x)   ≡ (r R.* s) ⋆ x
      ⋆-id       : ∀ x     → R.1r ⋆ x      ≡ x

Correspondingly, a module structure on a type packages the addition, the scalar multiplication, and the proofs that these behave as we set above. A module is a type equipped with a module structure.

  record Module-on {ℓ'} (T : Type ℓ') : Type (ℓ ⊔ ℓ') where
    no-eta-equality
    field
      _+_        : T → T → T
      _⋆_        : ⌞ R ⌟ → T → T
      has-is-mod : is-module _+_ _⋆_

    infixl 25 _+_
    infixr 27 _⋆_

    open is-module has-is-mod public
  Module : ∀ ℓm → Type (lsuc ℓm ⊔ ℓ)
  Module ℓm = Σ (Set ℓm) λ X → Module-on ∣ X ∣

  record is-linear-map (f : S → T) (M : Module-on S) (N : Module-on T)
    : Type (ℓ ⊔ level-of S ⊔ level-of T) where

Linear maps🔗

The correct notion of morphism between RR-modules is the linear map; in case we need to make the base ring RR clear, we shall call them RR-linear maps. Since the structure of RR-modules are their additions and their scalar multiplications, it stands to reason that these are what homomorphisms should preserve. Rather than separately asking for preservation of addition and of multiplication, the following single assumption suffices:

    field linear : ∀ r s t → f (r ⋆ s + t) ≡ r ⋆ f s + f t

Any map which satisfies this equation must preserve addition, since we have

f(a+b)=f(1a+b)=1f(a)+f(b)=f(a)+f(b), f(a+b) = f(1a+b) = 1f(a)+f(b) = f(a)+f(b)\text{,}

and standard lemmas about group homomorphisms ensure that ff will also preserve negation, and, more importantly, zero. We can then derive that ff preserves the scalar multiplication, by calculating

f(ra)=f(ra+0)=rf(a)+f(0)=rf(a)+0=rf(a). f(ra) = f(ra + 0) = rf(a) + f(0) = rf(a) + 0 = rf(a)\text{.}

  record Linear-map (M : Module ℓm) (N : Module ℓn) : Type (ℓ ⊔ ℓm ⊔ ℓn) where
    no-eta-equality
    field
      map : ⌞ M ⌟ → ⌞ N ⌟
      lin : is-linear-map map (M .snd) (N .snd)
    open is-linear-map lin public

The collection of linear maps forms a set, whose identity type is given by pointwise identity of the underlying maps. Therefore, we may take these to be the morphisms of a category R-Mod{R}\text{-}\mathbf{Mod}. R-Mod{R}\text{-}\mathbf{Mod} is a very standard category, so very standard constructions can set up the category, the functor witnessing its concreteness, and a proof that it is univalent.

  R-Mod-structure : ∀ {ℓ} → Thin-structure _ Module-on
  R-Mod-structure {ℓ} = rms where
    rms : Thin-structure _ Module-on
    ∣ rms .is-hom f M N ∣    = is-linear-map {ℓ} {_} {ℓ} f M N
    rms .is-hom f M N .is-tr = is-linear-map-is-prop

    rms .id-is-hom        .linear r s t = refl
    rms .∘-is-hom f g α β .linear r s t =
      ap f (β .linear r s t) ∙ α .linear _ _ _

    rms .id-hom-unique {s = s} {t = t} α _ = r where
      module s = Module-on s
      module t = Module-on t

      r : s ≡ t
      r i .Module-on._+_ x y = is-linear-map.pres-+ α x y i
      r i .Module-on._⋆_ x y = is-linear-map.pres-⋆ α x y i
      r i .Module-on.has-is-mod =
        is-prop→pathp (λ i → hlevel {T = is-module
          (λ x y → is-linear-map.pres-+ α x y i)
          (λ x y → is-linear-map.pres-⋆ α x y i)} 1)
          (Module-on.has-is-mod s) (Module-on.has-is-mod t) i
  R-Mod : ∀ ℓm → Precategory (lsuc ℓm ⊔ ℓ) (ℓm ⊔ ℓ)
  R-Mod ℓm = Structured-objects (R-Mod-structure {ℓm})

  Forget-module : ∀ ℓm → Functor (R-Mod ℓm) (Sets ℓm)
  Forget-module _ = Forget-structure R-Mod-structure

  record make-module {ℓm} (M : Type ℓm) : Type (ℓm ⊔ ℓ) where
    field
      has-is-set : is-set M
      _+_ : M → M → M
      inv : M → M
      0g  : M

      +-assoc : ∀ x y z → x + (y + z) ≡ (x + y) + z
      +-invl  : ∀ x → inv x + x ≡ 0g
      +-idl   : ∀ x → 0g + x ≡ x
      +-comm  : ∀ x y → x + y ≡ y + x

      _⋆_ : ⌞ R ⌟ → M → M

      ⋆-distribl : ∀ r x y → r ⋆ (x + y)   ≡ (r ⋆ x) + (r ⋆ y)
      ⋆-distribr : ∀ r s x → (r R.+ s) ⋆ x ≡ (r ⋆ x) + (s ⋆ x)
      ⋆-assoc    : ∀ r s x → r ⋆ (s ⋆ x)   ≡ ((r R.* s) ⋆ x)
      ⋆-id       : ∀ x     → R.1r ⋆ x      ≡ x

  to-module-on : ∀ {ℓm} {M : Type ℓm} → make-module M → Module-on M
  to-module-on m .Module-on._+_ = make-module._+_ m
  to-module-on m .Module-on._⋆_ = make-module._⋆_ m
  to-module-on m .Module-on.has-is-mod = mod where
    gr : Group-on _
    gr = to-group-on λ where
      .make-group.group-is-set → make-module.has-is-set m
      .make-group.unit → make-module.0g m
      .make-group.mul → make-module._+_ m
      .make-group.inv → make-module.inv m
      .make-group.assoc → make-module.+-assoc m
      .make-group.invl → make-module.+-invl m
      .make-group.idl → make-module.+-idl m

    mod : is-module _ _
    mod .is-module.has-is-ab .is-abelian-group.has-is-group = gr .Group-on.has-is-group
    mod .is-module.has-is-ab .is-abelian-group.commutes = make-module.+-comm m _ _
    mod .is-module.⋆-distribl = make-module.⋆-distribl m
    mod .is-module.⋆-distribr = make-module.⋆-distribr m
    mod .is-module.⋆-assoc = make-module.⋆-assoc m
    mod .is-module.⋆-id = make-module.⋆-id m

  to-module : ∀ {ℓm} {M : Type ℓm} → make-module M → Module ℓm
  ∣ to-module m .fst ∣ = _
  to-module m .fst .is-tr = make-module.has-is-set m
  to-module m .snd = to-module-on m

“Representable” modules🔗

A prototypical example of RR-module is.. RR itself! A ring has an underlying abelian group, and the multiplication operation can certainly be considered a special kind of “scalar multiplication”. If we treat RR as an Ab\mathbf{Ab}-category with a single object, this construction corresponds to the functor HomR(−,∙)\mathbf{Hom}_R(-,\bull) — the “Yoneda embedding” of RR’s unique object. Stretching the analogy, we refer to RR-as-an-RR-module as the “representable” RR-module.

  representable-module : Module ℓ
  representable-module .fst = R .fst
  representable-module .snd = to-module-on record
    { has-is-set = R.has-is-set
    ; _+_ = R._+_
    ; inv = R.-_
    ; 0g = R.0r
    ; +-assoc = λ x y z → R.+-associative
    ; +-invl = λ x → R.+-invl
    ; +-idl = λ x → R.+-idl
    ; +-comm = λ x y → R.+-commutes
    ; _⋆_ = R._*_
    ; ⋆-distribl = λ x y z → R.*-distribl
    ; ⋆-distribr = λ x y z → R.*-distribr
    ; ⋆-assoc    = λ x y z → R.*-associative
    ; ⋆-id       = λ x → R.*-idl
    }

Another perspective on this construction is that we are regarding RR as the space of “1-dimensional vectors” over itself. Following this line of reasoning one can define the module of nn-dimensional vectors over RR.