module Cat.Diagram.Coproduct {o h} (C : Precategory o h) where
Coproducts🔗
The coproduct of two objects and (if it exists), is the smallest object equipped with “injection” maps , . It is dual to the product.
We witness this notion of “smallest object” with a universal property; Given any other that also admits injection maps from and , we must have a unique map that factors the injections into . This is best explained by a commutative diagram:
record is-coproduct {A B P} (in₀ : Hom A P) (in₁ : Hom B P) : Type (o ⊔ h) where
field
_,_] : ∀ {Q} (inj0 : Hom A Q) (inj1 : Hom B Q) → Hom P Q
[: ∀ {Q} {inj0 : Hom A Q} {inj1} → [ inj0 , inj1 ] ∘ in₀ ≡ inj0
in₀∘factor : ∀ {Q} {inj0 : Hom A Q} {inj1} → [ inj0 , inj1 ] ∘ in₁ ≡ inj1
in₁∘factor
: ∀ {Q} {inj0 : Hom A Q} {inj1}
unique → (other : Hom P Q)
→ other ∘ in₀ ≡ inj0
→ other ∘ in₁ ≡ inj1
→ other ≡ [ inj0 , inj1 ]
: ∀ {Q} {inj0 : Hom A Q} {inj1}
unique₂ → ∀ o1 (p1 : o1 ∘ in₀ ≡ inj0) (q1 : o1 ∘ in₁ ≡ inj1)
→ ∀ o2 (p2 : o2 ∘ in₀ ≡ inj0) (q2 : o2 ∘ in₁ ≡ inj1)
→ o1 ≡ o2
= unique o1 p1 q1 ∙ sym (unique o2 p2 q2) unique₂ o1 p1 q1 o2 p2 q2
A coproduct of and is an explicit choice of coproduct diagram:
record Coproduct (A B : Ob) : Type (o ⊔ h) where
field
: Ob
coapex : Hom A coapex
in₀ : Hom B coapex
in₁ : is-coproduct in₀ in₁
has-is-coproduct
open is-coproduct has-is-coproduct public
Uniqueness🔗
The uniqueness argument presented here is dual to the argument for the product.
: (c1 c2 : Coproduct A B) → coapex c1 ≅ coapex c2
+-Unique = make-iso c1→c2 c2→c1 c1→c2→c1 c2→c1→c2
+-Unique c1 c2 where
module c1 = Coproduct c1
module c2 = Coproduct c2
: Hom (coapex c1) (coapex c2)
c1→c2 = c1.[ c2.in₀ , c2.in₁ ]
c1→c2
: Hom (coapex c2) (coapex c1)
c2→c1 = c2.[ c1.in₀ , c1.in₁ ] c2→c1
: c1→c2 ∘ c2→c1 ≡ id
c1→c2→c1 =
c1→c2→c1 .unique₂ _
c2(pullr c2.in₀∘factor ∙ c1.in₀∘factor)
(pullr c2.in₁∘factor ∙ c1.in₁∘factor)
(idl _) (idl _)
id
: c2→c1 ∘ c1→c2 ≡ id
c2→c1→c2 =
c2→c1→c2 .unique₂ _
c1(pullr c1.in₀∘factor ∙ c2.in₀∘factor)
(pullr c1.in₁∘factor ∙ c2.in₁∘factor)
(idl _) (idl _) id
Categories with all binary coproducts🔗
Categories with all binary coproducts are quite common, so we define a module for working with them.
: Type _
has-coproducts = ∀ a b → Coproduct a b
has-coproducts
module Binary-coproducts (all-coproducts : has-coproducts) where
module coproduct {a} {b} = Coproduct (all-coproducts a b)
open coproduct renaming
(unique to []-unique; in₀∘factor to in₀∘[]; in₁∘factor to in₁∘[]) public
open Functor
infixr 7 _⊕₀_
infix 50 _⊕₁_
_⊕₀_ : Ob → Ob → Ob
= coproduct.coapex {a} {b}
a ⊕₀ b
_⊕₁_ : ∀ {a b x y} → Hom a x → Hom b y → Hom (a ⊕₀ b) (x ⊕₀ y)
= [ in₀ ∘ f , in₁ ∘ g ] f ⊕₁ g