module Cat.Diagram.Coproduct.Indexed {o ā} (C : Precategory o ā) where
Indexed coproductsš
Indexed coproducts are the dual notion to indexed products, so see there for motivation and exposition.
record is-indexed-coproduct (F : Idx ā C.Ob) (Ī¹ : ā i ā C.Hom (F i) S) : Type (o ā ā ā level-of Idx) where no-eta-equality field match : ā {Y} ā (ā i ā C.Hom (F i) Y) ā C.Hom S Y commute : ā {i} {Y} {f : ā i ā C.Hom (F i) Y} ā match f C.ā Ī¹ i ā” f i unique : ā {Y} {h : C.Hom S Y} (f : ā i ā C.Hom (F i) Y) ā (ā i ā h C.ā Ī¹ i ā” f i) ā h ā” match f eta : ā {Y} (h : C.Hom S Y) ā h ā” match (Ī» i ā h C.ā Ī¹ i) eta h = unique _ Ī» _ ā refl uniqueā : ā {Y} {g h : C.Hom S Y} ā (ā i ā g C.ā Ī¹ i ā” h C.ā Ī¹ i) ā g ā” h uniqueā {g = g} {h} eq = eta g ā ap match (funext eq) ā sym (eta h) hom-iso : ā {Y} ā C.Hom S Y ā (ā i ā C.Hom (F i) Y) hom-iso = (Ī» z i ā z C.ā Ī¹ i) , is-isoāis-equiv Ī» where .is-iso.inv ā match .is-iso.rinv x ā funext Ī» i ā commute .is-iso.linv x ā sym (unique _ Ī» _ ā refl)
A category admits indexed coproducts (of level if, for any type and family there is an indexed coproduct of
record Indexed-coproduct (F : Idx ā C.Ob) : Type (o ā ā ā level-of Idx) where no-eta-equality field {Ī£F} : C.Ob Ī¹ : ā i ā C.Hom (F i) Ī£F has-is-ic : is-indexed-coproduct F Ī¹ open is-indexed-coproduct has-is-ic public
Indexed-coproduct-ā : ā {ā ā'} {I : Type ā} {J : Type ā'} ā (e : I ā J) ā {F : I ā C.Ob} ā Indexed-coproduct (F ā Equiv.from e) ā Indexed-coproduct F Indexed-coproduct-ā e {F} p = Ī» where .Ī£F ā p .Ī£F .Ī¹ j ā p .Ī¹ (e.to j) C.ā C.from (pathāiso (ap F (e.Ī· _))) .has-is-ic .match f ā p .match (f ā e.from) .has-is-ic .commute {f = f} ā C.pulll (p .commute) ā from-pathp-to (C ^op) _ (ap f (e.Ī· _)) .has-is-ic .unique f comm ā p .unique _ Ī» j ā ap (_ C.ā_) (sym (from-pathp-to (C ^op) _ (ap (p .Ī¹) (e.Īµ j))) ā ap (Ī» z ā p .Ī¹ _ C.ā C.from (pathāiso (ap F z))) (e.zag j)) ā comm (e.from j) where open Indexed-coproduct open is-indexed-coproduct module e = Equiv e Lift-Indexed-coproduct : ā {ā} ā' ā {I : Type ā} ā {F : I ā C.Ob} ā Indexed-coproduct {Idx = Lift ā' I} (F ā lower) ā Indexed-coproduct F Lift-Indexed-coproduct _ = Indexed-coproduct-ā (Lift-ā eā»Ā¹) is-indexed-coproduct-is-prop : ā {ā'} {Idx : Type ā'} ā {F : Idx ā C.Ob} {Ī£F : C.Ob} {Ī¹ : ā idx ā C.Hom (F idx) Ī£F} ā is-prop (is-indexed-coproduct F Ī¹) is-indexed-coproduct-is-prop {Idx = Idx} {F} {Ī£F} {Ī¹} P Q = path where open is-indexed-coproduct p : ā {X} ā (f : ā i ā C.Hom (F i) X) ā P .match f ā” Q .match f p f = Q .unique f (Ī» i ā P .commute) path : P ā” Q path i .match f = p f i path i .commute {i = idx} {f = f} = is-propāpathp (Ī» i ā C.Hom-set _ _ (p f i C.ā Ī¹ idx) (f idx)) (P .commute) (Q .commute) i path i .unique {h = h} f q = is-propāpathp (Ī» i ā C.Hom-set _ _ h (p f i)) (P .unique f q) (Q .unique f q) i module _ {ā'} {Idx : Type ā'} {F : Idx ā C.Ob} {P P' : Indexed-coproduct F} where private module P = Indexed-coproduct P module P' = Indexed-coproduct P' Indexed-coproduct-path : (p : P.Ī£F ā” P'.Ī£F) ā (ā idx ā PathP (Ī» i ā C.Hom (F idx) (p i)) (P.Ī¹ idx) (P'.Ī¹ idx)) ā P ā” P' Indexed-coproduct-path p q i .Indexed-coproduct.Ī£F = p i Indexed-coproduct-path p q i .Indexed-coproduct.Ī¹ idx = q idx i Indexed-coproduct-path p q i .Indexed-coproduct.has-is-ic = is-propāpathp (Ī» i ā is-indexed-coproduct-is-prop {Ī£F = p i} {Ī¹ = Ī» idx ā q idx i}) P.has-is-ic P'.has-is-ic i
Uniquenessš
As universal constructions, indexed coproducts are unique up to isomorphism. The proof follows the usual pattern: we use the universal morphisms to construct morphisms in both directions, and uniqueness ensures that these maps form an isomorphism.
is-indexed-coproductāiso : ā {ā'} {Idx : Type ā'} {F : Idx ā C.Ob} ā {Ī£F Ī£F' : C.Ob} ā {Ī¹ : ā i ā C.Hom (F i) Ī£F} {Ī¹' : ā i ā C.Hom (F i) Ī£F'} ā is-indexed-coproduct F Ī¹ ā is-indexed-coproduct F Ī¹' ā Ī£F C.ā Ī£F' is-indexed-coproductāiso {Ī¹ = Ī¹} {Ī¹' = Ī¹'} Ī£F-coprod Ī£F'-coprod = C.make-iso (Ī£F.match Ī¹') (Ī£F'.match Ī¹) (Ī£F'.uniqueā (Ī» i ā C.pullr Ī£F'.commute ā Ī£F.commute ā sym (C.idl _))) (Ī£F.uniqueā (Ī» i ā C.pullr Ī£F.commute ā Ī£F'.commute ā sym (C.idl _))) where module Ī£F = is-indexed-coproduct Ī£F-coprod module Ī£F' = is-indexed-coproduct Ī£F'-coprod
Indexed-coproductāiso : ā {ā'} {Idx : Type ā'} {F : Idx ā C.Ob} ā (P P' : Indexed-coproduct F) ā Indexed-coproduct.Ī£F P C.ā Indexed-coproduct.Ī£F P' Indexed-coproductāiso P P' = is-indexed-coproductāiso (Indexed-coproduct.has-is-ic P) (Indexed-coproduct.has-is-ic P')
Propertiesš
Let be a family of objects in If the the indexed coproducts and exists, then they are isomorphic.
The formal statement of this is a bit of a mouthful, but all of these arguments are just required to ensure that the various coproducts actually exist.
is-indexed-coproduct-assoc : ā {Īŗ Īŗ'} {A : Type Īŗ} {B : A ā Type Īŗ'} ā {X : Ī£ A B ā C.Ob} ā {Ī£įµįµX : C.Ob} {Ī£įµĪ£įµX : C.Ob} {Ī£įµX : A ā C.Ob} ā {Ī¹įµįµ : (ab : Ī£ A B) ā C.Hom (X ab) Ī£įµįµX} ā {Ī¹įµ : ā a ā C.Hom (Ī£įµX a) Ī£įµĪ£įµX} ā {Ī¹įµ : ā a ā (b : B a) ā C.Hom (X (a , b)) (Ī£įµX a)} ā is-indexed-coproduct X Ī¹įµįµ ā is-indexed-coproduct Ī£įµX Ī¹įµ ā (ā a ā is-indexed-coproduct (Ī» b ā X (a , b)) (Ī¹įµ a)) ā Ī£įµįµX C.ā Ī£įµĪ£įµX
Luckily, the proof of this fact is easier than the statement! Indexed coproducts are unique up to isomorphism, so it suffices to show that is an indexed product over which follows almost immediately from our hypotheses.
is-indexed-coproduct-assoc {A = A} {B} {X} {Ī£įµĪ£įµX = Ī£įµĪ£įµX} {Ī¹įµ = Ī¹įµ} {Ī¹įµ} Ī£įµįµ Ī£įµĪ£įµ Ī£įµ = is-indexed-coproductāiso Ī£įµįµ Ī£įµįµ' where open is-indexed-coproduct Ī¹įµįµ' : ā (ab : Ī£ A B) ā C.Hom (X ab) Ī£įµĪ£įµX Ī¹įµįµ' (a , b) = Ī¹įµ a C.ā Ī¹įµ a b Ī£įµįµ' : is-indexed-coproduct X Ī¹įµįµ' Ī£įµįµ' .match f = Ī£įµĪ£įµ .match Ī» a ā Ī£įµ a .match Ī» b ā f (a , b) Ī£įµįµ' .commute = C.pulll (Ī£įµĪ£įµ .commute) ā Ī£įµ _ .commute Ī£įµįµ' .unique {h = h} f p = Ī£įµĪ£įµ .unique _ Ī» a ā Ī£įµ _ .unique _ Ī» b ā sym (C.assoc _ _ _) ā p (a , b)
Categories with all indexed coproductsš
has-coproducts-indexed-by : ā {ā} (I : Type ā) ā Type _ has-coproducts-indexed-by I = ā (F : I ā C.Ob) ā Indexed-coproduct F has-indexed-coproducts : ā ā ā Type _ has-indexed-coproducts ā = ā {I : Type ā} ā has-coproducts-indexed-by I module Indexed-coproducts-by {Īŗ : Level} {Idx : Type Īŗ} (has-ic : has-coproducts-indexed-by Idx) where module ā (F : Idx ā C.Ob) = Indexed-coproduct (has-ic F) open ā renaming (commute to Ī¹-commute; unique to match-unique) public module Indexed-coproducts {Īŗ : Level} (has-ic : has-indexed-coproducts Īŗ) where module ā {Idx : Type Īŗ} (F : Idx ā C.Ob) = Indexed-coproduct (has-ic F) open ā renaming (commute to Ī¹-commute; unique to match-unique) public
Disjoint coproductsš
An indexed coproduct is said to be disjoint if every one of its inclusions is monic, and, for unequal the square below is a pullback with initial apex. Since the maps are monic, the pullback below computes the intersection of and as subobjects of hence the name disjoint coproduct: If is an initial object, then
record is-disjoint-coproduct (F : Idx ā C.Ob) (Ī¹ : ā i ā C.Hom (F i) S) : Type (o ā ā ā level-of Idx) where field has-is-ic : is-indexed-coproduct F Ī¹ injections-are-monic : ā i ā C.is-monic (Ī¹ i) summands-intersect : ā i j ā Pullback C (Ī¹ i) (Ī¹ j) different-images-are-disjoint : ā i j ā Ā¬ i ā” j ā is-initial C (summands-intersect i j .Pullback.apex)
Initial objects are disjointš
We prove that if is an initial object, then it is also an indexed coproduct ā for any family ā and furthermore, it is a disjoint coproduct.
is-initialāis-disjoint-coproduct : ā {ā } {F : ā„ ā C.Ob} {i : ā i ā C.Hom (F i) ā } ā is-initial C ā ā is-disjoint-coproduct F i is-initialāis-disjoint-coproduct {F = F} {i = i} init = is-disjoint where open is-indexed-coproduct is-coprod : is-indexed-coproduct F i is-coprod .match _ = init _ .centre is-coprod .commute {i = i} = absurd i is-coprod .unique {h = h} f p i = init _ .paths h (~ i) open is-disjoint-coproduct is-disjoint : is-disjoint-coproduct F i is-disjoint .has-is-ic = is-coprod is-disjoint .injections-are-monic i = absurd i is-disjoint .summands-intersect i j = absurd i is-disjoint .different-images-are-disjoint i j p = absurd i
Coproducts and zero objectsš
Let be a category with a zero object, and let be a coproduct. If is a discrete type, then every coproduct inclusion has a retract.
module _ {Īŗ} {Idx : Type Īŗ} {P : Idx ā C.Ob} {āP : C.Ob} {Ī¹ : ā i ā C.Hom (P i) āP} (coprod : is-indexed-coproduct P Ī¹) where open is-indexed-coproduct coprod
First, a useful lemma. Suppose that we have a coproduct indexed by a discrete type, and a map for some If there exists maps for every then we can obtain a map
detect : ā {X} ā¦ Idx-Discrete : Discrete Idx ā¦ ā (i : Idx) ā C.Hom (P i) X ā (ā (j : Idx) ā Ā¬ i ā” j ā C.Hom (P j) X) ā C.Hom āP X
The key idea here is to check if when invoking the universal property of if we use otherwise we use
detect {X = X} ā¦ Idx-Discrete ā¦ i tįµ¢ fā±¼ = match probe module detect where probe : ā (j : Idx) ā C.Hom (P j) X probe j with i ā”? j ... | yes i=j = subst _ i=j tįµ¢ ... | no Ā¬i=j = fā±¼ j Ā¬i=j probe-yes : probe i ā” tįµ¢ probe-yes with i ā”? i ... | yes i=i = is-setāsubst-refl (Ī» j ā C.Hom (P j) X) (Discreteāis-set Idx-Discrete) i=i tįµ¢ ... | no Ā¬i=i = absurd (Ā¬i=i refl) probe-no : ā j ā (Ā¬i=j : Ā¬ (i ā” j)) ā probe j ā” fā±¼ j Ā¬i=j probe-no j Ā¬i=j with i ā”? j ... | yes i=j = absurd (Ā¬i=j i=j) ... | no _ = ap (fā±¼ j) prop!
Moreover, we observe that our newly created map interacts nicely with the inclusions into the coproduct.
detect-yes : ā {X} ā¦ Idx-Discrete : Discrete Idx ā¦ ā {i : Idx} ā {tįµ¢ : C.Hom (P i) X} ā {fā±¼ : ā (j : Idx) ā Ā¬ i ā” j ā C.Hom (P j) X} ā detect i tįµ¢ fā±¼ C.ā Ī¹ i ā” tįµ¢ detect-yes = commute ā detect.probe-yes _ _ _ detect-no : ā {X} ā¦ Idx-Discrete : Discrete Idx ā¦ ā {i : Idx} ā {tįµ¢ : C.Hom (P i) X} ā {fā±¼ : ā (j : Idx) ā Ā¬ i ā” j ā C.Hom (P j) X} ā ā j ā (Ā¬i=j : Ā¬ i ā” j) ā detect i tįµ¢ fā±¼ C.ā Ī¹ j ā” fā±¼ j Ā¬i=j detect-no j Ā¬i=j = commute ā detect.probe-no _ _ _ j Ā¬i=j
Refocusing our attention back to our original claim, suppose that has a zero object. This means that there is a canonical choice of morphism between any two objects, so we can apply our previous lemma to obtain a retract
zeroāĪ¹-has-retract : ā ā¦ Idx-Discrete : Discrete Idx ā¦ ā Zero C ā ā i ā C.has-retract (Ī¹ i) zeroāĪ¹-has-retract z i = C.make-retract (detect i C.id (Ī» _ _ ā zeroā)) detect-yes where open Zero z