@@ -47,11 +47,16 @@ open category_theory.limits.walking_parallel_pair
47
47
namespace category_theory.limits
48
48
49
49
variables {C : Type u} [category.{v} C]
50
+ variables [has_zero_morphisms.{v} C]
51
+
52
+ /-- A morphism `f` has a kernel if the functor `parallel_pair f 0` has a limit. -/
53
+ abbreviation has_kernel {X Y : C} (f : X ⟶ Y) : Type (max u v) := has_limit (parallel_pair f 0 )
54
+ /-- A morphism `f` has a cokernel if the functor `parallel_pair f 0` has a colimit. -/
55
+ abbreviation has_cokernel {X Y : C} (f : X ⟶ Y) : Type (max u v) := has_colimit (parallel_pair f 0 )
50
56
51
57
variables {X Y : C} (f : X ⟶ Y)
52
58
53
59
section
54
- variables [has_zero_morphisms.{v} C]
55
60
56
61
/-- A kernel fork is just a fork where the second morphism is a zero morphism. -/
57
62
abbreviation kernel_fork := fork f 0
@@ -77,7 +82,7 @@ def kernel_fork.is_limit.lift' {s : kernel_fork f} (hs : is_limit s) {W : C} (k
77
82
end
78
83
79
84
section
80
- variables [has_zero_morphisms.{v} C] [has_limit (parallel_pair f 0 ) ]
85
+ variables [has_kernel f ]
81
86
82
87
/-- The kernel of a morphism, expressed as the equalizer with the 0 morphism. -/
83
88
abbreviation kernel : C := equalizer f 0
@@ -103,17 +108,27 @@ def kernel.lift' {W : C} (k : W ⟶ X) (h : k ≫ f = 0) : {l : W ⟶ kernel f /
103
108
⟨kernel.lift f k h, kernel.lift_ι _ _ _⟩
104
109
105
110
/-- Every kernel of the zero morphism is an isomorphism -/
106
- def kernel.ι_zero_is_iso [has_limit (parallel_pair ( 0 : X ⟶ Y) 0 )] :
111
+ def kernel.ι_zero_is_iso [has_kernel ( 0 : X ⟶ Y)] :
107
112
is_iso (kernel.ι (0 : X ⟶ Y)) :=
108
113
equalizer.ι_of_self _
109
114
115
+ lemma eq_zero_of_epi_kernel [epi (kernel.ι f)] : f = 0 :=
116
+ (cancel_epi (kernel.ι f)).1 (by simp)
117
+
118
+ variables {f}
119
+
120
+ lemma kernel_not_epi_of_nonzero (w : f ≠ 0 ) : ¬epi (kernel.ι f) :=
121
+ λ I, by exactI w (eq_zero_of_epi_kernel f)
122
+
123
+ lemma kernel_not_iso_of_nonzero (w : f ≠ 0 ) : (is_iso (kernel.ι f)) → false :=
124
+ λ I, kernel_not_epi_of_nonzero w $ by { resetI, apply_instance }
125
+
110
126
end
111
127
112
128
section has_zero_object
113
129
variables [has_zero_object.{v} C]
114
130
115
131
local attribute [instance] has_zero_object.has_zero
116
- variables [has_zero_morphisms.{v} C]
117
132
118
133
/-- The morphism from the zero object determines a cone on a kernel diagram -/
119
134
def kernel.zero_cone : cone (parallel_pair f 0 ) :=
@@ -129,19 +144,18 @@ fork.is_limit.mk _ (λ s, 0)
129
144
(λ _ _ _, has_zero_object.zero_of_to_zero _)
130
145
131
146
/-- The kernel of a monomorphism is isomorphic to the zero object -/
132
- def kernel.of_mono [has_limit (parallel_pair f 0 ) ] [mono f] : kernel f ≅ 0 :=
147
+ def kernel.of_mono [has_kernel f ] [mono f] : kernel f ≅ 0 :=
133
148
functor.map_iso (cones.forget _) $ is_limit.unique_up_to_iso
134
149
(limit.is_limit (parallel_pair f 0 )) (kernel.is_limit_cone_zero_cone f)
135
150
136
151
/-- The kernel morphism of a monomorphism is a zero morphism -/
137
- lemma kernel.ι_of_mono [has_limit (parallel_pair f 0 ) ] [mono f] : kernel.ι f = 0 :=
152
+ lemma kernel.ι_of_mono [has_kernel f ] [mono f] : kernel.ι f = 0 :=
138
153
by rw [←category.id_comp (kernel.ι f), ←iso.hom_inv_id (kernel.of_mono f), category.assoc,
139
154
has_zero_object.zero_of_to_zero (kernel.of_mono f).hom, has_zero_morphisms.zero_comp]
140
155
141
156
end has_zero_object
142
157
143
158
section transport
144
- variables [has_zero_morphisms.{v} C]
145
159
146
160
/-- If `i` is an isomorphism such that `l ≫ i.hom = f`, then any kernel of `f` is a kernel of `l`.-/
147
161
def is_kernel.of_comp_iso {Z : C} (l : X ⟶ Z) (i : Z ≅ Y) (h : l ≫ i.hom = f)
@@ -153,7 +167,7 @@ fork.is_limit.mk _
153
167
(λ s m h, by { apply fork.is_limit.hom_ext hs, simpa using h walking_parallel_pair.zero })
154
168
155
169
/-- If `i` is an isomorphism such that `l ≫ i.hom = f`, then the kernel of `f` is a kernel of `l`.-/
156
- def kernel.of_comp_iso [has_limit (parallel_pair f 0 ) ]
170
+ def kernel.of_comp_iso [has_kernel f ]
157
171
{Z : C} (l : X ⟶ Z) (i : Z ≅ Y) (h : l ≫ i.hom = f) :
158
172
is_limit (kernel_fork.of_ι (kernel.ι f) $
159
173
show kernel.ι f ≫ l = 0 , by simp [←i.comp_inv_eq.2 h.symm]) :=
@@ -168,24 +182,23 @@ is_limit.of_iso_limit hs $ cones.ext i.symm $ λ j,
168
182
by { cases j, { exact (iso.eq_inv_comp i).2 h }, { simp } }
169
183
170
184
/-- If `i` is an isomorphism such that `i.hom ≫ kernel.ι f = l`, then `l` is a kernel of `f`. -/
171
- def kernel.iso_kernel [has_limit (parallel_pair f 0 ) ]
185
+ def kernel.iso_kernel [has_kernel f ]
172
186
{Z : C} (l : Z ⟶ X) (i : Z ≅ kernel f) (h : i.hom ≫ kernel.ι f = l) :
173
187
is_limit (kernel_fork.of_ι l $ by simp [←h]) :=
174
188
is_kernel.iso_kernel f l (limit.is_limit _) i h
175
189
176
190
end transport
177
191
178
192
section
179
- variables (X) (Y) [has_zero_morphisms.{v} C]
193
+ variables (X Y)
180
194
181
195
/-- The kernel morphism of a zero morphism is an isomorphism -/
182
- def kernel.ι_of_zero [has_limit (parallel_pair ( 0 : X ⟶ Y) 0 )] : is_iso (kernel.ι (0 : X ⟶ Y)) :=
196
+ def kernel.ι_of_zero [has_kernel ( 0 : X ⟶ Y)] : is_iso (kernel.ι (0 : X ⟶ Y)) :=
183
197
equalizer.ι_of_self _
184
198
185
199
end
186
200
187
201
section
188
- variables [has_zero_morphisms.{v} C]
189
202
190
203
/-- A cokernel cofork is just a cofork where the second morphism is a zero morphism. -/
191
204
abbreviation cokernel_cofork := cofork f 0
@@ -211,7 +224,7 @@ def cokernel_cofork.is_colimit.desc' {s : cokernel_cofork f} (hs : is_colimit s)
211
224
end
212
225
213
226
section
214
- variables [has_zero_morphisms.{v} C] [has_colimit (parallel_pair f 0 ) ]
227
+ variables [has_cokernel f ]
215
228
216
229
/-- The cokernel of a morphism, expressed as the coequalizer with the 0 morphism. -/
217
230
abbreviation cokernel : C := coequalizer f 0
@@ -238,15 +251,29 @@ def cokernel.desc' {W : C} (k : Y ⟶ W) (h : f ≫ k = 0) :
238
251
{l : cokernel f ⟶ W // cokernel.π f ≫ l = k} :=
239
252
⟨cokernel.desc f k h, cokernel.π_desc _ _ _⟩
240
253
254
+ /-- The cokernel of the zero morphism is an isomorphism -/
255
+ def cokernel.π_zero_is_iso [has_colimit (parallel_pair (0 : X ⟶ Y) 0 )] :
256
+ is_iso (cokernel.π (0 : X ⟶ Y)) :=
257
+ coequalizer.π_of_self _
258
+
259
+ lemma eq_zero_of_mono_cokernel [mono (cokernel.π f)] : f = 0 :=
260
+ (cancel_mono (cokernel.π f)).1 (by simp)
261
+
262
+ variables {f}
263
+
264
+ lemma cokernel_not_mono_of_nonzero (w : f ≠ 0 ) : ¬mono (cokernel.π f) :=
265
+ λ I, by exactI w (eq_zero_of_mono_cokernel f)
266
+
267
+ lemma cokernel_not_iso_of_nonzero (w : f ≠ 0 ) : (is_iso (cokernel.π f)) → false :=
268
+ λ I, cokernel_not_mono_of_nonzero w $ by { resetI, apply_instance }
269
+
241
270
end
242
271
243
272
section has_zero_object
244
273
variables [has_zero_object.{v} C]
245
274
246
275
local attribute [instance] has_zero_object.has_zero
247
276
248
- variable [has_zero_morphisms.{v} C]
249
-
250
277
/-- The morphism to the zero object determines a cocone on a cokernel diagram -/
251
278
def cokernel.zero_cocone : cocone (parallel_pair f 0 ) :=
252
279
{ X := 0 ,
@@ -261,22 +288,22 @@ cofork.is_colimit.mk _ (λ s, 0)
261
288
(λ _ _ _, has_zero_object.zero_of_from_zero _)
262
289
263
290
/-- The cokernel of an epimorphism is isomorphic to the zero object -/
264
- def cokernel.of_epi [has_colimit (parallel_pair f 0 ) ] [epi f] : cokernel f ≅ 0 :=
291
+ def cokernel.of_epi [has_cokernel f ] [epi f] : cokernel f ≅ 0 :=
265
292
functor.map_iso (cocones.forget _) $ is_colimit.unique_up_to_iso
266
293
(colimit.is_colimit (parallel_pair f 0 )) (cokernel.is_colimit_cocone_zero_cocone f)
267
294
268
295
/-- The cokernel morphism if an epimorphism is a zero morphism -/
269
- lemma cokernel.π_of_epi [has_colimit (parallel_pair f 0 ) ] [epi f] : cokernel.π f = 0 :=
296
+ lemma cokernel.π_of_epi [has_cokernel f ] [epi f] : cokernel.π f = 0 :=
270
297
by rw [←category.comp_id (cokernel.π f), ←iso.hom_inv_id (cokernel.of_epi f), ←category.assoc,
271
298
has_zero_object.zero_of_from_zero (cokernel.of_epi f).inv, has_zero_morphisms.comp_zero]
272
299
273
300
end has_zero_object
274
301
275
302
section
276
- variables (X) (Y) [has_zero_morphisms.{v} C]
303
+ variables (X Y)
277
304
278
305
/-- The cokernel of a zero morphism is an isomorphism -/
279
- def cokernel.π_of_zero [has_colimit (parallel_pair ( 0 : X ⟶ Y) 0 )] :
306
+ def cokernel.π_of_zero [has_cokernel ( 0 : X ⟶ Y)] :
280
307
is_iso (cokernel.π (0 : X ⟶ Y)) :=
281
308
coequalizer.π_of_self _
282
309
@@ -287,22 +314,20 @@ section has_zero_object
287
314
variables [has_zero_object.{v} C]
288
315
289
316
local attribute [instance] has_zero_object.has_zero
290
- variables [has_zero_morphisms.{v} C]
291
317
292
318
/-- The kernel of the cokernel of an epimorphism is an isomorphism -/
293
- instance kernel.of_cokernel_of_epi [has_colimit (parallel_pair f 0 ) ]
294
- [has_limit (parallel_pair ( cokernel.π f) 0 )] [epi f] : is_iso (kernel.ι (cokernel.π f)) :=
319
+ instance kernel.of_cokernel_of_epi [has_cokernel f ]
320
+ [has_kernel ( cokernel.π f)] [epi f] : is_iso (kernel.ι (cokernel.π f)) :=
295
321
equalizer.ι_of_eq $ cokernel.π_of_epi f
296
322
297
323
/-- The cokernel of the kernel of a monomorphism is an isomorphism -/
298
- instance cokernel.of_kernel_of_mono [has_limit (parallel_pair f 0 ) ]
299
- [has_colimit (parallel_pair ( kernel.ι f) 0 )] [mono f] : is_iso (cokernel.π (kernel.ι f)) :=
324
+ instance cokernel.of_kernel_of_mono [has_kernel f ]
325
+ [has_cokernel ( kernel.ι f)] [mono f] : is_iso (cokernel.π (kernel.ι f)) :=
300
326
coequalizer.π_of_eq $ kernel.ι_of_mono f
301
327
302
328
end has_zero_object
303
329
304
330
section transport
305
- variables [has_zero_morphisms.{v} C]
306
331
307
332
/-- If `i` is an isomorphism such that `i.hom ≫ l = f`, then any cokernel of `f` is a cokernel of
308
333
`l`. -/
@@ -316,7 +341,7 @@ cofork.is_colimit.mk _
316
341
317
342
/-- If `i` is an isomorphism such that `i.hom ≫ l = f`, then the cokernel of `f` is a cokernel of
318
343
`l`. -/
319
- def cokernel.of_iso_comp [has_colimit (parallel_pair f 0 ) ]
344
+ def cokernel.of_iso_comp [has_cokernel f ]
320
345
{Z : C} (l : Z ⟶ Y) (i : X ≅ Z) (h : i.hom ≫ l = f) :
321
346
is_colimit (cokernel_cofork.of_π (cokernel.π f) $
322
347
show l ≫ cokernel.π f = 0 , by simp [i.eq_inv_comp.2 h]) :=
@@ -330,28 +355,29 @@ def is_cokernel.cokernel_iso {Z : C} (l : Y ⟶ Z) {s : cokernel_cofork f} (hs :
330
355
is_colimit.of_iso_colimit hs $ cocones.ext i $ λ j, by { cases j, { simp }, { exact h } }
331
356
332
357
/-- If `i` is an isomorphism such that `cokernel.π f ≫ i.hom = l`, then `l` is a cokernel of `f`. -/
333
- def cokernel.cokernel_iso [has_colimit (parallel_pair f 0 ) ]
358
+ def cokernel.cokernel_iso [has_cokernel f ]
334
359
{Z : C} (l : Y ⟶ Z) (i : cokernel f ≅ Z) (h : cokernel.π f ≫ i.hom = l) :
335
360
is_colimit (cokernel_cofork.of_π l $ by simp [←h]) :=
336
361
is_cokernel.cokernel_iso f l (colimit.is_colimit _) i h
337
362
338
363
end transport
339
364
340
365
end category_theory.limits
366
+
341
367
namespace category_theory.limits
342
368
variables (C : Type u) [category.{v} C]
343
369
344
370
variables [has_zero_morphisms.{v} C]
345
371
346
372
/-- `has_kernels` represents a choice of kernel for every morphism -/
347
373
class has_kernels :=
348
- (has_limit : Π {X Y : C} (f : X ⟶ Y), has_limit (parallel_pair f 0 ) )
374
+ (has_limit : Π {X Y : C} (f : X ⟶ Y), has_kernel f )
349
375
350
376
/-- `has_cokernels` represents a choice of cokernel for every morphism -/
351
377
class has_cokernels :=
352
- (has_colimit : Π {X Y : C} (f : X ⟶ Y), has_colimit (parallel_pair f 0 ) )
378
+ (has_colimit : Π {X Y : C} (f : X ⟶ Y), has_cokernel f )
353
379
354
- attribute [instance] has_kernels.has_limit has_cokernels.has_colimit
380
+ attribute [instance, priority 100 ] has_kernels.has_limit has_cokernels.has_colimit
355
381
356
382
/-- Kernels are finite limits, so if `C` has all finite limits, it also has all kernels -/
357
383
def has_kernels_of_has_finite_limits [has_finite_limits.{v} C] : has_kernels.{v} C :=
0 commit comments