forked from leanprover-community/mathlib4
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathLimits.lean
More file actions
264 lines (213 loc) · 9.54 KB
/
Copy pathLimits.lean
File metadata and controls
264 lines (213 loc) · 9.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
/-
Copyright (c) 2020 Kim Morrison. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kim Morrison
-/
module
public import Mathlib.Algebra.Category.ModuleCat.Basic
public import Mathlib.Algebra.Category.Grp.Limits
public import Mathlib.Algebra.Colimit.Module
public import Mathlib.Algebra.Module.Shrink -- shake: keep (Module R (Shrink.{w, max v w} ↥(sectionsSubmodule F))), cf. lean#13417
/-!
# The category of R-modules has all limits
Further, these limits are preserved by the forgetful functor --- that is,
the underlying types are just the limits in the category of types.
-/
@[expose] public section
open CategoryTheory Limits
universe t v w u
-- `u` is determined by the ring, so can come later
noncomputable section
namespace ModuleCat
variable {R : Type u} [Ring R]
variable {J : Type v} [Category.{t} J] (F : J ⥤ ModuleCat.{w} R)
instance addCommGroupObj (j) :
AddCommGroup ((F ⋙ forget (ModuleCat R)).obj j) :=
inferInstanceAs <| AddCommGroup (F.obj j)
instance moduleObj (j) :
Module.{u, w} R ((F ⋙ forget (ModuleCat R)).obj j) :=
inferInstanceAs <| Module R (F.obj j)
set_option backward.isDefEq.respectTransparency false in
/-- The flat sections of a functor into `ModuleCat R` form a submodule of all sections.
-/
def sectionsSubmodule : Submodule R (∀ j, F.obj j) :=
{ AddGrpCat.sectionsAddSubgroup.{v, w}
(F ⋙ forget₂ (ModuleCat R) AddCommGrpCat.{w} ⋙
forget₂ AddCommGrpCat AddGrpCat.{w}) with
carrier := (F ⋙ forget (ModuleCat R)).sections
smul_mem' := fun r s sh j j' f => by
simpa [Functor.sections] using congr_arg (r • ·) (sh f) }
instance : AddCommMonoid (F ⋙ forget (ModuleCat R)).sections :=
inferInstanceAs <| AddCommMonoid (sectionsSubmodule F)
instance : Module R (F ⋙ forget (ModuleCat R)).sections :=
inferInstanceAs <| Module R (sectionsSubmodule F)
section
variable [Small.{w} (Functor.sections (F ⋙ forget (ModuleCat R)))]
instance : Small.{w} (sectionsSubmodule F) :=
inferInstanceAs <| Small.{w} (Functor.sections (F ⋙ forget (ModuleCat R)))
-- Adding the following instance speeds up `limitModule` noticeably,
-- by preventing a bad unfold of `limitAddCommGroup`.
instance limitAddCommMonoid :
AddCommMonoid (Types.Small.limitCone.{v, w} (F ⋙ forget (ModuleCat.{w} R))).pt :=
inferInstanceAs <| AddCommMonoid (Shrink (sectionsSubmodule F))
instance limitAddCommGroup :
AddCommGroup (Types.Small.limitCone.{v, w} (F ⋙ forget (ModuleCat.{w} R))).pt :=
inferInstanceAs <| AddCommGroup (Shrink.{w} (sectionsSubmodule F))
instance limitModule :
Module R (Types.Small.limitCone.{v, w} (F ⋙ forget (ModuleCat.{w} R))).pt :=
inferInstanceAs <| Module R (Shrink (sectionsSubmodule F))
set_option backward.defeqAttrib.useBackward true in
set_option backward.isDefEq.respectTransparency false in
/-- `limit.π (F ⋙ forget (ModuleCat.{w} R)) j` as an `R`-linear map. -/
def limitπLinearMap (j) :
(Types.Small.limitCone (F ⋙ forget (ModuleCat.{w} R))).pt →ₗ[R]
(F ⋙ forget (ModuleCat R)).obj j where
toFun := (Types.Small.limitCone (F ⋙ forget (ModuleCat R))).π.app j
map_smul' _ _ := by simp; rfl
map_add' _ _ := by simp; rfl
namespace HasLimits
-- The next two definitions are used in the construction of `HasLimits (ModuleCat R)`.
-- After that, the limits should be constructed using the generic limits API,
-- e.g. `limit F`, `limit.cone F`, and `limit.isLimit F`.
/-- Construction of a limit cone in `ModuleCat R`.
(Internal use only; use the limits API.)
-/
def limitCone : Cone F where
pt := ModuleCat.of R (Types.Small.limitCone.{v, w} (F ⋙ forget _)).pt
π :=
{ app j := ofHom (limitπLinearMap F j)
naturality _ _ f := by
ext
simpa using! (Types.Small.limitCone (F ⋙ forget _)).π.naturality_apply f _ }
set_option backward.defeqAttrib.useBackward true in
set_option backward.isDefEq.respectTransparency false in
/-- Witness that the limit cone in `ModuleCat R` is a limit cone.
(Internal use only; use the limits API.)
-/
def limitConeIsLimit : IsLimit (limitCone.{t, v, w} F) := by
refine IsLimit.ofFaithful (forget (ModuleCat R)) (Types.Small.limitConeIsLimit.{v, w} _)
(fun s => ofHom ⟨⟨(Types.Small.limitConeIsLimit.{v, w} _).lift
((forget (ModuleCat R)).mapCone s), ?_⟩, ?_⟩)
(fun s => rfl)
· intro x y
simp [← equivShrink_add]
rfl
· intro r x
simp [← equivShrink_smul]
rfl
end HasLimits
open HasLimits
/-- If `(F ⋙ forget (ModuleCat R)).sections` is `u`-small, `F` has a limit. -/
instance hasLimit : HasLimit F := HasLimit.mk {
cone := limitCone F
isLimit := limitConeIsLimit F
}
/-- If `J` is `u`-small, the category of `R`-modules has limits of shape `J`. -/
lemma hasLimitsOfShape [Small.{w} J] : HasLimitsOfShape J (ModuleCat.{w} R) where
/-- The category of R-modules has all limits. -/
lemma hasLimitsOfSize [UnivLE.{v, w}] : HasLimitsOfSize.{t, v} (ModuleCat.{w} R) where
has_limits_of_shape _ := hasLimitsOfShape
instance hasLimits : HasLimits (ModuleCat.{w} R) :=
ModuleCat.hasLimitsOfSize.{w, w, w, u}
instance (priority := high) hasLimits' : HasLimits (ModuleCat.{u} R) :=
ModuleCat.hasLimitsOfSize.{u, u, u}
/-- An auxiliary declaration to speed up typechecking.
-/
def forget₂AddCommGroup_preservesLimitsAux :
IsLimit ((forget₂ (ModuleCat R) AddCommGrpCat).mapCone (limitCone F)) :=
letI : Small.{w} (Functor.sections ((F ⋙ forget₂ _ AddCommGrpCat) ⋙ forget _)) :=
inferInstanceAs <| Small.{w} (Functor.sections (F ⋙ forget (ModuleCat R)))
AddCommGrpCat.limitConeIsLimit
(F ⋙ forget₂ (ModuleCat.{w} R) _ : J ⥤ AddCommGrpCat.{w})
/-- The forgetful functor from R-modules to abelian groups preserves all limits. -/
instance forget₂AddCommGroup_preservesLimit :
PreservesLimit F (forget₂ (ModuleCat R) AddCommGrpCat) :=
preservesLimit_of_preserves_limit_cone (limitConeIsLimit F)
(forget₂AddCommGroup_preservesLimitsAux F)
/-- The forgetful functor from R-modules to abelian groups preserves all limits.
-/
instance forget₂AddCommGroup_preservesLimitsOfSize [UnivLE.{v, w}] :
PreservesLimitsOfSize.{t, v}
(forget₂ (ModuleCat.{w} R) AddCommGrpCat.{w}) where
preservesLimitsOfShape := { preservesLimit := inferInstance }
instance forget₂AddCommGroup_preservesLimits :
PreservesLimits (forget₂ (ModuleCat R) AddCommGrpCat.{w}) :=
ModuleCat.forget₂AddCommGroup_preservesLimitsOfSize.{w, w}
/-- The forgetful functor from R-modules to types preserves all limits.
-/
instance forget_preservesLimitsOfSize [UnivLE.{v, w}] :
PreservesLimitsOfSize.{t, v} (forget (ModuleCat.{w} R)) where
preservesLimitsOfShape :=
{ preservesLimit := fun {K} ↦ preservesLimit_of_preserves_limit_cone (limitConeIsLimit K)
(Types.Small.limitConeIsLimit.{v} (_ ⋙ forget _)) }
instance forget_preservesLimits : PreservesLimits (forget (ModuleCat.{w} R)) :=
ModuleCat.forget_preservesLimitsOfSize.{w, w}
end
instance forget₂AddCommGroup_reflectsLimit :
ReflectsLimit F (forget₂ (ModuleCat.{w} R) AddCommGrpCat) where
reflects {c} hc := ⟨by
have : HasLimit (F ⋙ forget₂ (ModuleCat R) AddCommGrpCat) := ⟨_, hc⟩
have : Small.{w} (Functor.sections (F ⋙ forget (ModuleCat R))) := by
simpa only [AddCommGrpCat.hasLimit_iff_small_sections] using! this
have := reflectsLimit_of_reflectsIsomorphisms F (forget₂ (ModuleCat R) AddCommGrpCat)
exact isLimitOfReflects _ hc⟩
instance forget₂AddCommGroup_reflectsLimitOfShape :
ReflectsLimitsOfShape J (forget₂ (ModuleCat.{w} R) AddCommGrpCat) where
instance forget₂AddCommGroup_reflectsLimitOfSize :
ReflectsLimitsOfSize.{t, v} (forget₂ (ModuleCat.{w} R) AddCommGrpCat) where
section DirectLimit
open Module
variable {ι : Type v}
variable [DecidableEq ι] [Preorder ι]
variable (G : ι → Type v)
variable [∀ i, AddCommGroup (G i)] [∀ i, Module R (G i)]
variable (f : ∀ i j, i ≤ j → G i →ₗ[R] G j) [DirectedSystem G fun i j h ↦ f i j h]
/-- The diagram (in the sense of `CategoryTheory`) of an unbundled `directLimit` of modules. -/
@[simps]
def directLimitDiagram : ι ⥤ ModuleCat R where
obj i := ModuleCat.of R (G i)
map hij := ofHom (f _ _ hij.le)
map_id i := by
ext
apply Module.DirectedSystem.map_self
map_comp hij hjk := by
ext
symm
apply Module.DirectedSystem.map_map f
/-- The `Cocone` on `directLimitDiagram` corresponding to
the unbundled `directLimit` of modules.
In `directLimitIsColimit` we show that it is a colimit cocone. -/
@[simps]
def directLimitCocone : Cocone (directLimitDiagram G f) where
pt := ModuleCat.of R <| DirectLimit G f
ι :=
{ app := fun x => ofHom (Module.DirectLimit.of R ι G f x)
naturality := fun _ _ hij => by
ext
exact DirectLimit.of_f }
set_option backward.defeqAttrib.useBackward true in
set_option backward.isDefEq.respectTransparency false in
/-- The unbundled `directLimit` of modules is a colimit
in the sense of `CategoryTheory`. -/
@[simps]
def directLimitIsColimit : IsColimit (directLimitCocone G f) where
desc s := ofHom <|
Module.DirectLimit.lift R ι G f (fun i => (s.ι.app i).hom) fun i j h x => by
simp only [Functor.const_obj_obj]
rw [← s.w (homOfLE h)]
rfl
fac s i := by
ext
dsimp only [hom_comp, directLimitCocone, hom_ofHom, LinearMap.comp_apply]
apply DirectLimit.lift_of
uniq s m h := by
have :
s.ι.app = fun i =>
(ofHom (DirectLimit.of R ι (fun i => G i) (fun i j H => f i j H) i)) ≫ m := by
funext i
rw [← h]
rfl
ext
simp [this]
end DirectLimit
end ModuleCat