Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 8d2ffb8

Browse files
javraTwoFX
andcommitted
feat(category_theory): (co)kernels of biproduct projection and inclusion (#12394)
add kernels and cokernels of biproduct projections and inclusions Co-authored-by: Markus Himmel <markus@himmel-villmar.de> Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
1 parent 85a415e commit 8d2ffb8

File tree

1 file changed

+218
-8
lines changed

1 file changed

+218
-8
lines changed

src/category_theory/limits/shapes/biproducts.lean

Lines changed: 218 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import algebra.group.ext
77
import category_theory.limits.shapes.finite_products
88
import category_theory.limits.shapes.binary_products
99
import category_theory.preadditive
10+
import category_theory.limits.shapes.kernels
1011

1112
/-!
1213
# Biproducts and binary biproducts
@@ -286,13 +287,13 @@ lemma biproduct.ι_desc {f : J → C} [has_biproduct f] {P : C} (p : Π b, f b
286287

287288
/-- Given a collection of maps between corresponding summands of a pair of biproducts
288289
indexed by the same type, we obtain a map between the biproducts. -/
289-
abbreviation biproduct.map [fintype J] {f g : J → C} [has_finite_biproducts C]
290+
abbreviation biproduct.map {f g : J → C} [has_biproduct f] [has_biproduct g]
290291
(p : Π b, f b ⟶ g b) : ⨁ f ⟶ ⨁ g :=
291292
is_limit.map (biproduct.bicone f).to_cone (biproduct.is_limit g) (discrete.nat_trans p)
292293

293294
/-- An alternative to `biproduct.map` constructed via colimits.
294295
This construction only exists in order to show it is equal to `biproduct.map`. -/
295-
abbreviation biproduct.map' [fintype J] {f g : J → C} [has_finite_biproducts C]
296+
abbreviation biproduct.map' {f g : J → C} [has_biproduct f] [has_biproduct g]
296297
(p : Π b, f b ⟶ g b) : ⨁ f ⟶ ⨁ g :=
297298
is_colimit.map (biproduct.is_colimit f) (biproduct.bicone g).to_cocone (discrete.nat_trans p)
298299

@@ -306,7 +307,7 @@ is_colimit.map (biproduct.is_colimit f) (biproduct.bicone g).to_cocone (discrete
306307
(w : ∀ j, biproduct.ι f j ≫ g = biproduct.ι f j ≫ h) : g = h :=
307308
(biproduct.is_colimit f).hom_ext w
308309

309-
lemma biproduct.map_eq_map' [fintype J] {f g : J → C} [has_finite_biproducts C]
310+
lemma biproduct.map_eq_map' {f g : J → C} [has_biproduct f] [has_biproduct g]
310311
(p : Π b, f b ⟶ g b) : biproduct.map p = biproduct.map' p :=
311312
begin
312313
ext j j',
@@ -320,13 +321,13 @@ begin
320321
end
321322

322323
@[simp, reassoc]
323-
lemma biproduct.map_π [fintype J] {f g : J → C} [has_finite_biproducts C]
324+
lemma biproduct.map_π {f g : J → C} [has_biproduct f] [has_biproduct g]
324325
(p : Π j, f j ⟶ g j) (j : J) :
325326
biproduct.map p ≫ biproduct.π g j = biproduct.π f j ≫ p j :=
326327
limits.is_limit.map_π _ _ _ _
327328

328329
@[simp, reassoc]
329-
lemma biproduct.ι_map [fintype J] {f g : J → C} [has_finite_biproducts C]
330+
lemma biproduct.ι_map {f g : J → C} [has_biproduct f] [has_biproduct g]
330331
(p : Π j, f j ⟶ g j) (j : J) :
331332
biproduct.ι f j ≫ biproduct.map p = p j ≫ biproduct.ι g j :=
332333
begin
@@ -335,25 +336,176 @@ begin
335336
end
336337

337338
@[simp, reassoc]
338-
lemma biproduct.map_desc [fintype J] {f g : J → C} [has_finite_biproducts C]
339+
lemma biproduct.map_desc {f g : J → C} [has_biproduct f] [has_biproduct g]
339340
(p : Π j, f j ⟶ g j) {P : C} (k : Π j, g j ⟶ P) :
340341
biproduct.map p ≫ biproduct.desc k = biproduct.desc (λ j, p j ≫ k j) :=
341342
by { ext, simp, }
342343

343344
@[simp, reassoc]
344-
lemma biproduct.lift_map [fintype J] {f g : J → C} [has_finite_biproducts C]
345+
lemma biproduct.lift_map {f g : J → C} [has_biproduct f] [has_biproduct g]
345346
{P : C} (k : Π j, P ⟶ f j) (p : Π j, f j ⟶ g j) :
346347
biproduct.lift k ≫ biproduct.map p = biproduct.lift (λ j, k j ≫ p j) :=
347348
by { ext, simp, }
348349

349350
/-- Given a collection of isomorphisms between corresponding summands of a pair of biproducts
350351
indexed by the same type, we obtain an isomorphism between the biproducts. -/
351352
@[simps]
352-
def biproduct.map_iso [fintype J] {f g : J → C} [has_finite_biproducts C]
353+
def biproduct.map_iso {f g : J → C} [has_biproduct f] [has_biproduct g]
353354
(p : Π b, f b ≅ g b) : ⨁ f ≅ ⨁ g :=
354355
{ hom := biproduct.map (λ b, (p b).hom),
355356
inv := biproduct.map (λ b, (p b).inv), }
356357

358+
section π_kernel
359+
360+
section
361+
variables (f : J → C) [has_biproduct f]
362+
variables (p : J → Prop) [has_biproduct (subtype.restrict f p)]
363+
364+
/-- The canonical morphism from the biproduct over a restricted index type to the biproduct of
365+
the full index type. -/
366+
def biproduct.from_subtype : ⨁ subtype.restrict f p ⟶ ⨁ f :=
367+
biproduct.desc $ λ j, biproduct.ι _ _
368+
369+
/-- The canonical morophism from a biproduct to the biproduct over a restriction of its index
370+
type. -/
371+
def biproduct.to_subtype : ⨁ f ⟶ ⨁ subtype.restrict f p :=
372+
biproduct.lift $ λ j, biproduct.π _ _
373+
374+
@[simp, reassoc]
375+
lemma biproduct.from_subtype_π (j : J) [decidable (p j)] :
376+
biproduct.from_subtype f p ≫ biproduct.π f j =
377+
if h : p j then biproduct.π (subtype.restrict f p) ⟨j, h⟩ else 0 :=
378+
begin
379+
ext i,
380+
rw [biproduct.from_subtype, biproduct.ι_desc_assoc, biproduct.ι_π],
381+
by_cases h : p j,
382+
{ rw [dif_pos h, biproduct.ι_π],
383+
split_ifs with h₁ h₂ h₂,
384+
exacts [rfl, false.elim (h₂ (subtype.ext h₁)),
385+
false.elim (h₁ (congr_arg subtype.val h₂)), rfl] },
386+
{ rw [dif_neg h, dif_neg (show (i : J) ≠ j, from λ h₂, h (h₂ ▸ i.2)), comp_zero] }
387+
end
388+
389+
lemma biproduct.from_subtype_eq_lift [decidable_pred p] : biproduct.from_subtype f p =
390+
biproduct.lift (λ j, if h : p j then biproduct.π (subtype.restrict f p) ⟨j, h⟩ else 0) :=
391+
biproduct.hom_ext _ _ (by simp)
392+
393+
@[simp, reassoc]
394+
lemma biproduct.from_subtype_π_subtype (j : subtype p) :
395+
biproduct.from_subtype f p ≫ biproduct.π f j = biproduct.π (subtype.restrict f p) j :=
396+
begin
397+
ext i,
398+
rw [biproduct.from_subtype, biproduct.ι_desc_assoc, biproduct.ι_π, biproduct.ι_π],
399+
split_ifs with h₁ h₂ h₂,
400+
exacts [rfl, false.elim (h₂ (subtype.ext h₁)), false.elim (h₁ (congr_arg subtype.val h₂)), rfl]
401+
end
402+
403+
@[simp, reassoc]
404+
lemma biproduct.to_subtype_π (j : subtype p) :
405+
biproduct.to_subtype f p ≫ biproduct.π (subtype.restrict f p) j = biproduct.π f j :=
406+
biproduct.lift_π _ _
407+
408+
@[simp, reassoc]
409+
lemma biproduct.ι_to_subtype (j : J) [decidable (p j)] :
410+
biproduct.ι f j ≫ biproduct.to_subtype f p =
411+
if h : p j then biproduct.ι (subtype.restrict f p) ⟨j, h⟩ else 0 :=
412+
begin
413+
ext i,
414+
rw [biproduct.to_subtype, category.assoc, biproduct.lift_π, biproduct.ι_π],
415+
by_cases h : p j,
416+
{ rw [dif_pos h, biproduct.ι_π],
417+
split_ifs with h₁ h₂ h₂,
418+
exacts [rfl, false.elim (h₂ (subtype.ext h₁)),
419+
false.elim (h₁ (congr_arg subtype.val h₂)), rfl] },
420+
{ rw [dif_neg h, dif_neg (show j ≠ i, from λ h₂, h (h₂.symm ▸ i.2)), zero_comp] }
421+
end
422+
423+
lemma biproduct.to_subtype_eq_desc [decidable_pred p] : biproduct.to_subtype f p =
424+
biproduct.desc (λ j, if h : p j then biproduct.ι (subtype.restrict f p) ⟨j, h⟩ else 0) :=
425+
biproduct.hom_ext' _ _ (by simp)
426+
427+
@[simp, reassoc]
428+
lemma biproduct.ι_to_subtype_subtype (j : subtype p) :
429+
biproduct.ι f j ≫ biproduct.to_subtype f p = biproduct.ι (subtype.restrict f p) j :=
430+
begin
431+
ext i,
432+
rw [biproduct.to_subtype, category.assoc, biproduct.lift_π, biproduct.ι_π, biproduct.ι_π],
433+
split_ifs with h₁ h₂ h₂,
434+
exacts [rfl, false.elim (h₂ (subtype.ext h₁)), false.elim (h₁ (congr_arg subtype.val h₂)), rfl]
435+
end
436+
437+
@[simp, reassoc]
438+
lemma biproduct.ι_from_subtype (j : subtype p) :
439+
biproduct.ι (subtype.restrict f p) j ≫ biproduct.from_subtype f p = biproduct.ι f j :=
440+
biproduct.ι_desc _ _
441+
442+
@[simp, reassoc]
443+
lemma biproduct.from_subtype_to_subtype :
444+
biproduct.from_subtype f p ≫ biproduct.to_subtype f p = 𝟙 (⨁ subtype.restrict f p) :=
445+
begin
446+
refine biproduct.hom_ext _ _ (λ j, _),
447+
rw [category.assoc, biproduct.to_subtype_π, biproduct.from_subtype_π_subtype, category.id_comp]
448+
end
449+
450+
@[simp, reassoc]
451+
lemma biproduct.to_subtype_from_subtype [decidable_pred p] :
452+
biproduct.to_subtype f p ≫ biproduct.from_subtype f p =
453+
biproduct.map (λ j, if p j then 𝟙 (f j) else 0) :=
454+
begin
455+
ext1 i,
456+
by_cases h : p i,
457+
{ simp [h], congr },
458+
{ simp [h] }
459+
end
460+
461+
end
462+
463+
variables (f : J → C) (i : J) [has_biproduct f] [has_biproduct (subtype.restrict f (λ j, i ≠ j))]
464+
465+
/-- The kernel of `biproduct.π f i` is the inclusion from the biproduct which omits `i`
466+
from the index set `J` into the biproduct over `J`. -/
467+
def biproduct.is_limit_from_subtype : is_limit
468+
(kernel_fork.of_ι (biproduct.from_subtype f (λ j, i ≠ j))
469+
(by simp) : kernel_fork (biproduct.π f i)) :=
470+
fork.is_limit.mk' _ $ λ s,
471+
⟨s.ι ≫ biproduct.to_subtype _ _,
472+
begin
473+
ext j,
474+
rw [kernel_fork.ι_of_ι, category.assoc, category.assoc,
475+
biproduct.to_subtype_from_subtype_assoc, biproduct.map_π],
476+
rcases em (i = j) with (rfl|h),
477+
{ rw [if_neg (not_not.2 rfl), comp_zero, comp_zero, kernel_fork.condition] },
478+
{ rw [if_pos h, category.comp_id] }
479+
end,
480+
begin
481+
intros m hm,
482+
rw [← hm, kernel_fork.ι_of_ι, category.assoc, biproduct.from_subtype_to_subtype],
483+
exact (category.comp_id _).symm
484+
end
485+
486+
/-- The cokernel of `biproduct.ι f i` is the projection from the biproduct over the index set `J`
487+
onto the biproduct omitting `i`. -/
488+
def biproduct.is_colimit_to_subtype : is_colimit
489+
(cokernel_cofork.of_π (biproduct.to_subtype f (λ j, i ≠ j))
490+
(by simp) : cokernel_cofork (biproduct.ι f i)) :=
491+
cofork.is_colimit.mk' _ $ λ s,
492+
⟨biproduct.from_subtype _ _ ≫ s.π,
493+
begin
494+
ext j,
495+
rw [cokernel_cofork.π_of_π, biproduct.to_subtype_from_subtype_assoc,
496+
biproduct.ι_map_assoc],
497+
rcases em (i = j) with (rfl|h),
498+
{ rw [if_neg (not_not.2 rfl), zero_comp, cokernel_cofork.condition] },
499+
{ rw [if_pos h, category.id_comp] }
500+
end,
501+
begin
502+
intros m hm,
503+
rw [← hm, cokernel_cofork.π_of_π, ← category.assoc, biproduct.from_subtype_to_subtype],
504+
exact (category.id_comp _).symm
505+
end
506+
507+
end π_kernel
508+
357509
section
358510
variables [fintype J] {K : Type v} [fintype K] [decidable_eq K] {f : J → C} {g : K → C}
359511
[has_finite_biproducts C]
@@ -906,6 +1058,64 @@ def biprod.unique_up_to_iso (X Y : C) [has_binary_biproduct X Y] {b : binary_bic
9061058
inv_hom_id' := by rw [← biprod.cone_point_unique_up_to_iso_hom X Y hb,
9071059
← biprod.cone_point_unique_up_to_iso_inv X Y hb, iso.inv_hom_id] }
9081060

1061+
section biprod_kernel
1062+
1063+
variables (X Y : C) [has_binary_biproduct X Y]
1064+
1065+
/-- A kernel fork for the kernel of `biprod.fst`. It consists of the
1066+
morphism `biprod.inr`. -/
1067+
def biprod.fst_kernel_fork : kernel_fork (biprod.fst : X ⊞ Y ⟶ X) :=
1068+
kernel_fork.of_ι biprod.inr biprod.inr_fst
1069+
1070+
@[simp]
1071+
lemma biprod.fst_kernel_fork_ι : fork.ι (biprod.fst_kernel_fork X Y) = biprod.inr :=
1072+
rfl
1073+
1074+
/-- The fork `biprod.fst_kernel_fork` is indeed a limit. -/
1075+
def biprod.is_kernel_fst_kernel_fork : is_limit (biprod.fst_kernel_fork X Y) :=
1076+
fork.is_limit.mk' _ $ λ s, ⟨s.ι ≫ biprod.snd, by ext; simp, λ m hm, by simp [← hm]⟩
1077+
1078+
/-- A kernel fork for the kernel of `biprod.snd`. It consists of the
1079+
morphism `biprod.inl`. -/
1080+
def biprod.snd_kernel_fork : kernel_fork (biprod.snd : X ⊞ Y ⟶ Y) :=
1081+
kernel_fork.of_ι biprod.inl biprod.inl_snd
1082+
1083+
@[simp]
1084+
lemma biprod.snd_kernel_fork_ι : fork.ι (biprod.snd_kernel_fork X Y) = biprod.inl :=
1085+
rfl
1086+
1087+
/-- The fork `biprod.snd_kernel_fork` is indeed a limit. -/
1088+
def biprod.is_kernel_snd_kernel_fork : is_limit (biprod.snd_kernel_fork X Y) :=
1089+
fork.is_limit.mk' _ $ λ s, ⟨s.ι ≫ biprod.fst, by ext; simp, λ m hm, by simp [← hm]⟩
1090+
1091+
/-- A cokernel cofork for the cokernel of `biprod.inl`. It consists of the
1092+
morphism `biprod.snd`. -/
1093+
def biprod.inl_cokernel_fork : cokernel_cofork (biprod.inl : X ⟶ X ⊞ Y) :=
1094+
cokernel_cofork.of_π biprod.snd biprod.inl_snd
1095+
1096+
@[simp]
1097+
lemma biprod.inl_cokernel_fork_π : cofork.π (biprod.inl_cokernel_fork X Y) = biprod.snd :=
1098+
rfl
1099+
1100+
/-- The cofork `biprod.inl_cokernel_fork` is indeed a colimit. -/
1101+
def biprod.is_cokernel_inl_cokernel_fork : is_colimit (biprod.inl_cokernel_fork X Y) :=
1102+
cofork.is_colimit.mk' _ $ λ s, ⟨biprod.inr ≫ s.π, by ext; simp, λ m hm, by simp [← hm]⟩
1103+
1104+
/-- A cokernel cofork for the cokernel of `biprod.inr`. It consists of the
1105+
morphism `biprod.fst`. -/
1106+
def biprod.inr_cokernel_fork : cokernel_cofork (biprod.inr : Y ⟶ X ⊞ Y) :=
1107+
cokernel_cofork.of_π biprod.fst biprod.inr_fst
1108+
1109+
@[simp]
1110+
lemma biprod.inr_cokernel_fork_π : cofork.π (biprod.inr_cokernel_fork X Y) = biprod.fst :=
1111+
rfl
1112+
1113+
/-- The cofork `biprod.inr_cokernel_fork` is indeed a colimit. -/
1114+
def biprod.is_cokernel_inr_cokernel_fork : is_colimit (biprod.inr_cokernel_fork X Y) :=
1115+
cofork.is_colimit.mk' _ $ λ s, ⟨biprod.inl ≫ s.π, by ext; simp, λ m hm, by simp [← hm]⟩
1116+
1117+
end biprod_kernel
1118+
9091119
section
9101120
variables [has_binary_biproducts C]
9111121

0 commit comments

Comments
 (0)