module Algebra.Ring.Module.Free {β} (R : Ring β) where
Free modulesπ
For a finite set of generators, we can define free modules very directly: for example, using vectors. For infinite sets, this definition does not work as well: rings do not admit infinite sums, so we would need a way to βtameβ the vectors so only a finite amount of information needs to be summed at a time. The usual definition, of being zero in all but finitely many indices, is problematic since we can not (unless the indexing set admits decidable equality) define the map
Note: even if is not, strictly speaking, built on an underlying (sub)set of functions into we will stick to the exponential notation for definiteness.
Fortunately, free objects have a very straightforward definition in type theory: they are initial objects in certain categories of algebras, so they can be presented as1 inductive types.
data Free-mod {β'} (A : Type β') : Type (β β β') where inc : A β Free-mod A _+_ : Free-mod A β Free-mod A β Free-mod A neg : Free-mod A β Free-mod A 0m : Free-mod A _Β·_ : β R β β Free-mod A β Free-mod A
The free module on
is generated by elements of
(the inc
) constructor,
the operations of an Abelian group (which we
write with _+_
), together with a
scalar multiplication operation
The equations imposed are precisely those necessary to make _+_
into an abelian
group, and the scalar multiplication into an action by
We also add a squash
constructor,
since modules must have an underlying set.
+-comm : β x y β x + y β‘ y + x +-assoc : β x y z β x + (y + z) β‘ (x + y) + z +-invl : β x β neg x + x β‘ 0m +-idl : β x β 0m + x β‘ x Β·-id : β x β R.1r Β· x β‘ x Β·-distribl : β x y z β x Β· (y + z) β‘ x Β· y + x Β· z Β·-distribr : β x y z β (x R.+ y) Β· z β‘ x Β· z + y Β· z Β·-assoc : β x y z β x Β· y Β· z β‘ (x R.* y) Β· z squash : is-set (Free-mod A)
In passing, we define a record to package together the data of a predicate on free modules: as long as it is prop-valued, we can prove something for all of by treating the group operations, the ring action, and the generators.
record Free-elim-prop {β' β''} {A : Type β'} (P : Free-mod A β Type β'') : Type (β β β' β β'') where no-eta-equality field has-is-prop : β x β is-prop (P x) P-0m : P 0m P-neg : β x β P x β P (neg x) P-inc : β x β P (inc x) P-Β· : β x y β P y β P (x Β· y) P-+ : β x y β P x β P y β P (x + y) elim : β x β P x
elim (inc x) = P-inc x elim (x Β· y) = P-Β· x y (elim y) elim (x + y) = P-+ x y (elim x) (elim y) elim (neg x) = P-neg x (elim x) elim 0m = P-0m elim (+-comm x y i) = is-propβpathp (Ξ» j β has-is-prop (+-comm x y j)) (P-+ x y (elim x) (elim y)) (P-+ y x (elim y) (elim x)) i elim (+-assoc x y z i) = is-propβpathp (Ξ» j β has-is-prop (+-assoc x y z j)) (P-+ _ _ (elim x) (P-+ _ _ (elim y) (elim z))) (P-+ _ _ (P-+ _ _ (elim x) (elim y)) (elim z)) i elim (+-invl x i) = is-propβpathp (Ξ» j β has-is-prop (+-invl x j)) (P-+ _ _ (P-neg _ (elim x)) (elim x)) P-0m i elim (+-idl x i) = is-propβpathp (Ξ» j β has-is-prop (+-idl x j)) (P-+ _ _ P-0m (elim x)) (elim x) i elim (Β·-id x i) = is-propβpathp (Ξ» j β has-is-prop (Β·-id x j)) (P-Β· R.1r _ (elim x)) (elim x) i elim (Β·-distribl x y z i) = is-propβpathp (Ξ» j β has-is-prop (Β·-distribl x y z j)) (P-Β· x _ (P-+ _ _ (elim y) (elim z))) (P-+ _ _ (P-Β· x _ (elim y)) (P-Β· x _ (elim z))) i elim (Β·-distribr x y z i) = is-propβpathp (Ξ» j β has-is-prop (Β·-distribr x y z j )) (P-Β· (x R.+ y) _ (elim z)) (P-+ _ _ (P-Β· x _ (elim z)) (P-Β· y _ (elim z))) i elim (Β·-assoc x y z i) = is-propβpathp (Ξ» j β has-is-prop (Β·-assoc x y z j)) (P-Β· x (y Β· z) (P-Β· y _ (elim z))) (P-Β· (x R.* y) z (elim z)) i elim (squash x y p q i j) = is-propβsquarep (Ξ» i j β has-is-prop (squash x y p q i j)) (Ξ» _ β elim x) (Ξ» j β elim (p j)) (Ξ» j β elim (q j)) (Ξ» _ β elim y) i j
Iβll leave the definition of the group, Abelian group, and
structures on
in this <details>
tag, since theyβre not particularly interesting. For every operation
and law, we simply use the corresponding constructors.
open Module-on hiding (_+_) open make-module hiding (_+_) Module-on-free-mod : β {β'} (A : Type β') β Module-on R (Free-mod A) Module-on-free-mod A = to-module-on mk module Module-on-free-mod where mk : make-module R (Free-mod A) mk .has-is-set = squash mk .make-module._+_ = _+_ mk .inv = neg mk .0g = 0m mk .make-module.+-assoc = Free-mod.+-assoc mk .make-module.+-invl = Free-mod.+-invl mk .make-module.+-idl = Free-mod.+-idl mk .make-module.+-comm = Free-mod.+-comm mk ._β_ = _Β·_ mk .β-distribl = Free-mod.Β·-distribl mk .β-distribr = Free-mod.Β·-distribr mk .β-assoc x y z = Free-mod.Β·-assoc x y z mk .β-id = Free-mod.Β·-id Free-Mod : β {β'} β Type β' β Module R (β β β') Free-Mod T = to-module (Module-on-free-mod.mk T) open Functor
fold-free-mod : β {β β'} {A : Type β} (N : Module R β') β (A β β N β) β Linear-map (Free-Mod A) N fold-free-mod {A = A} N f = go-linear module fold-free-mod where private module N = Module-on (N .snd)
The endless constructors of Free-mod
are powerless in the
face of a function from the generators into the underlying type of an
actual
Each operation is mapped to the corresponding operation on
so the path constructors are also handled by the witnesses that
is an actual module. This function, annoying though it may be to write,
is definitionally a linear map β saving us a bit of effort.
-- Rough: go : Free-mod A β β N β go (inc x) = f x go (x Β· y) = x N.β go y go (x + y) = go x N.+ go y go (neg x) = N.- (go x) go 0m = N.0g go (+-comm x y i) = N.+-comm {go x} {go y} i go (+-assoc x y z i) = N.+-assoc {go x} {go y} {go z} i go (+-invl x i) = N.+-invl {go x} i go (+-idl x i) = N.+-idl {go x} i go (Β·-id x i) = N.β-id (go x) i go (Β·-distribl x y z i) = N.β-distribl x (go y) (go z) i go (Β·-distribr x y z i) = N.β-distribr x y (go z) i go (Β·-assoc x y z i) = N.β-assoc x y (go z) i go (squash a b p q i j) = N.has-is-set (go a) (go b) (Ξ» i β go (p i)) (Ξ» i β go (q i)) i j go-linear : Linear-map (Free-Mod A) N go-linear .map = go go-linear .lin .linear r s t = refl {-# DISPLAY fold-free-mod.go = fold-free-mod #-} {-# DISPLAY fold-free-mod.go-linear = fold-free-mod #-}
open Free-elim-prop equal-on-basis : β {βb βg} {T : Type βb} (M : Module R βg) β {f g : Linear-map (Free-Mod T) M} β ((x : T) β f .map (inc x) β‘ g .map (inc x)) β f β‘ g equal-on-basis M {f} {g} p = ext $ Free-elim-prop.elim Ξ» where .has-is-prop x β M .fst .is-tr _ _ .P-0m β f.pres-0 β sym g.pres-0 .P-neg x Ξ± β f.pres-neg Β·Β· ap M.-_ Ξ± Β·Β· sym g.pres-neg .P-inc β p .P-Β· x y Ξ± β f.pres-β _ _ Β·Β· ap (x M.β_) Ξ± Β·Β· sym (g.pres-β _ _) .P-+ x y Ξ± Ξ² β f.pres-+ _ _ Β·Β· apβ M._+_ Ξ± Ξ² Β·Β· sym (g.pres-+ _ _) where module f = Linear-map f module g = Linear-map g module M = Module-on (M .snd) instance Extensional-linear-map-free : β {βb βg βr} {T : Type βb} {M : Module R βg} β β¦ ext : Extensional (T β β M β) βr β¦ β Extensional (Linear-map (Free-Mod T) M) βr Extensional-linear-map-free {M = M} β¦ ext β¦ = injectionβextensional! {f = Ξ» m x β m .map (inc x)} (Ξ» p β equal-on-basis M (happly p)) ext {-# OVERLAPS Extensional-linear-map-free #-}
To prove that free modules have the expected universal property, it remains to show that if then Since weβre eliminating into a proposition, all we have to handle are the operation constructors, which is.. inductive, but manageable. Iβll leave the computation here if youβre interested:
make-free-module : β {β'} (S : Set (β β β')) β Free-object (R-ModβͺSets R (β β β')) S make-free-module {β' = β'} S = go where open Free-object go : Free-object (R-ModβͺSets R (β β β')) S go .free = Free-Mod β S β go .unit = inc go .fold {b} f = linear-mapβhom (fold-free-mod b f) go .commute = refl go .unique {M} {f} g p = reext! p
After that calculation, we can β¨ just β¨ conclude that Free-module
has the right
universal property: that is, we can rearrange the proof above into the
form of a functor and an adjunction.
Free-module : β {β'} β Functor (Sets (β β β')) (R-Mod R (β β β')) Free-module {β' = β'} = free-objectsβfunctor (make-free-module {β' = β'}) Freeβ£Forget : β {β'} β Free-module {β'} β£ R-ModβͺSets R (β β β') Freeβ£Forget {β'} = free-objectsβleft-adjoint (make-free-module {β' = β'})
equal-on-basis' : β {βb βg} {T : Type βb} {G : Type βg} (M : Module-on R G) β (let module M = Module-on M) β {f : Free-mod T β G} β (β r x y β f (r Β· x + y) β‘ r M.β f x M.+ f y) β {g : Free-mod T β G} β (β r x y β g (r Β· x + y) β‘ r M.β g x M.+ g y) β ((x : T) β f (inc x) β‘ g (inc x)) β f β‘ g equal-on-basis' M l1 l2 p = ap map $ equal-on-basis (el _ (Module-on.has-is-set M) , M) {f = record { lin = record { linear = l1 } }} {g = record { lin = record { linear = l2 } }} p module _ (cring : is-commutative-ring R) where open Algebra.Ring.Module.Multilinear R cring multilinear-extension : β {n} {ββ} {ββ : Fin (suc n) β Level} {Ms : (i : Fin (suc n)) β Type (ββ i)} {N : Module R ββ} β (f : ArrαΆ Ms β N β) β Multilinear-map (suc n) (Ξ» i β Free-Mod (Ms i)) N multilinear-extension {zero} {N = N} f = 1-linear-map (fold-free-mod N f) multilinear-extension {suc n} f = Uncurry.from $ fold-free-mod _ Ξ» x β multilinear-extension (f x) multi-equal-on-bases : β {n} {ββ} {ββ : Fin n β Level} {Ms : (i : Fin n) β Type (ββ i)} {N : Module R ββ} β {f g : Multilinear-map n (Ξ» i β Free-Mod (Ms i)) N} β (β (as : Ξ αΆ Ms) β applyαΆ (f .map) (mapβ (Ξ» _ β inc) as) β‘ applyαΆ (g .map) (mapβ (Ξ» _ β inc) as)) β f β‘ g multi-equal-on-bases {n = zero} p = Multilinear-map-path (p tt) multi-equal-on-bases {n = suc n} {f = f} {g} p = Uncurry.injective $ equal-on-basis _ Ξ» x β multi-equal-on-bases Ξ» as β p (x , as)
truncated, higherβ©οΈ