module Cat.Diagram.Coproduct 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} (ι₁ : Hom A P) (ΞΉβ‚‚ : 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 ] ∘ ι₁ ≑ inj0
      []βˆ˜ΞΉβ‚‚ : βˆ€ {Q} {inj0 : Hom A Q} {inj1} β†’ [ inj0 , inj1 ] ∘ ΞΉβ‚‚ ≑ inj1

      unique
        : βˆ€ {Q} {inj0 : Hom A Q} {inj1} {other : Hom P Q}
        β†’ other ∘ ι₁ ≑ inj0 β†’ other ∘ ΞΉβ‚‚ ≑ inj1
        β†’ [ inj0 , inj1 ] ≑ other

    uniqueβ‚‚
      : βˆ€ {Q} {inj0 : Hom A Q} {inj1}
      β†’ βˆ€ {o1} (p1 : o1 ∘ ι₁ ≑ inj0) (q1 : o1 ∘ ΞΉβ‚‚ ≑ inj1)
      β†’ βˆ€ {o2} (p2 : o2 ∘ ι₁ ≑ inj0) (q2 : o2 ∘ ΞΉβ‚‚ ≑ inj1)
      β†’ o1 ≑ o2
    uniqueβ‚‚ p1 q1 p2 q2 = sym (unique p1 q1) βˆ™ unique p2 q2

A coproduct of and is an explicit choice of coproduct diagram:

  record Coproduct (A B : Ob) : Type (o βŠ” h) where
    field
      coapex : Ob
      ι₁ : Hom A coapex
      ΞΉβ‚‚ : Hom B coapex
      has-is-coproduct : is-coproduct ι₁ ΞΉβ‚‚

    open is-coproduct has-is-coproduct public

UniquenessπŸ”—

The uniqueness argument presented here is dual to the argument for the product.

  +-Unique : (c1 c2 : Coproduct C A B) β†’ coapex c1 β‰… coapex c2
  +-Unique c1 c2 = make-iso c1β†’c2 c2β†’c1 c1β†’c2β†’c1 c2β†’c1β†’c2 where
    module c1 = Coproduct c1
    module c2 = Coproduct c2

    c1β†’c2 : Hom (coapex c1) (coapex c2)
    c1β†’c2 = c1.[ c2.ι₁ , c2.ΞΉβ‚‚ ]

    c2β†’c1 : Hom (coapex c2) (coapex c1)
    c2β†’c1 = c2.[ c1.ι₁ , c1.ΞΉβ‚‚ ]
    c1β†’c2β†’c1 : c1β†’c2 ∘ c2β†’c1 ≑ id
    c1β†’c2β†’c1 = c2.uniqueβ‚‚
      (pullr c2.[]βˆ˜ΞΉβ‚ βˆ™ c1.[]βˆ˜ΞΉβ‚)
      (pullr c2.[]βˆ˜ΞΉβ‚‚ βˆ™ c1.[]βˆ˜ΞΉβ‚‚)
      (idl _) (idl _)

    c2β†’c1β†’c2 : c2β†’c1 ∘ c1β†’c2 ≑ id
    c2β†’c1β†’c2 = c1.uniqueβ‚‚
      (pullr c1.[]βˆ˜ΞΉβ‚ βˆ™ c2.[]βˆ˜ΞΉβ‚)
      (pullr c1.[]βˆ˜ΞΉβ‚‚ βˆ™ c2.[]βˆ˜ΞΉβ‚‚)
      (idl _) (idl _)
  is-coproduct-iso
    : βˆ€ {A A' B B' P} {ι₁ : Hom A P} {ΞΉβ‚‚ : Hom B P}
        {f : Hom A' A} {g : Hom B' B}
    β†’ is-invertible f
    β†’ is-invertible g
    β†’ is-coproduct C ι₁ ΞΉβ‚‚
    β†’ is-coproduct C (ι₁ ∘ f) (ΞΉβ‚‚ ∘ g)
  is-coproduct-iso f-iso g-iso coprod = coprod' where
    module fi = is-invertible f-iso
    module gi = is-invertible g-iso

    open is-coproduct
    coprod' : is-coproduct C _ _
    coprod' .[_,_] qa qb = coprod .[_,_] (qa ∘ fi.inv) (qb ∘ gi.inv)
    coprod' .[]βˆ˜ΞΉβ‚ = pulll (coprod .[]βˆ˜ΞΉβ‚) βˆ™ cancelr fi.invr
    coprod' .[]βˆ˜ΞΉβ‚‚ = pulll (coprod .[]βˆ˜ΞΉβ‚‚) βˆ™ cancelr gi.invr
    coprod' .unique p q = coprod .unique
      (sym (rswizzle (sym p βˆ™ assoc _ _ _) fi.invl))
      (sym (rswizzle (sym q βˆ™ assoc _ _ _) gi.invl))

  is-coproduct-iso-coapex
    : βˆ€ {A B P P'} {ι₁ : Hom A P} {ΞΉβ‚‚ : Hom B P}
        {ι₁' : Hom A P'} {ΞΉβ‚‚' : Hom B P'}
        {f : Hom P P'}
    β†’ is-invertible f
    β†’ f ∘ ι₁ ≑ ι₁'
    β†’ f ∘ ΞΉβ‚‚ ≑ ΞΉβ‚‚'
    β†’ is-coproduct C ι₁ ΞΉβ‚‚
    β†’ is-coproduct C ι₁' ΞΉβ‚‚'
  is-coproduct-iso-coapex {f = f} f-iso f-ι₁ f-ΞΉβ‚‚ coprod = coprod' where
    module fi = is-invertible f-iso

    open is-coproduct
    coprod' : is-coproduct C _ _
    coprod' .[_,_] qa qb = coprod .[_,_] qa qb ∘ fi.inv
    coprod' .[]βˆ˜ΞΉβ‚ = pullr (lswizzle (sym f-ι₁) fi.invr) βˆ™ coprod .[]βˆ˜ΞΉβ‚
    coprod' .[]βˆ˜ΞΉβ‚‚ = pullr (lswizzle (sym f-ΞΉβ‚‚) fi.invr) βˆ™ coprod .[]βˆ˜ΞΉβ‚‚
    coprod' .unique p q = rswizzle
      (coprod .unique (pullr f-ι₁ βˆ™ p) (pullr f-ΞΉβ‚‚ βˆ™ q)) fi.invl

  Coproduct-is-prop
    : βˆ€ {A B}
    β†’ is-category C
    β†’ is-prop (Coproduct C A B)
  Coproduct-is-prop cat inj1 inj2 = Coproduct-path
    (cat .to-path (+-Unique inj1 inj2))
    (Univalent.Hom-pathp-reflr-iso cat (inj1 .[]βˆ˜ΞΉβ‚))
    (Univalent.Hom-pathp-reflr-iso cat (inj1 .[]βˆ˜ΞΉβ‚‚))

Categories with all binary coproductsπŸ”—

Categories with all binary coproducts are quite common, so we define a module for working with them.

has-coproducts : βˆ€ {o β„“} β†’ Precategory o β„“ β†’ Type _
has-coproducts C = βˆ€ a b β†’ Coproduct C a b

module Binary-coproducts
  {o β„“} (C : Precategory o β„“) (all-coproducts : has-coproducts C) where

  open Cat.Reasoning C

  module _ {a b} where open Coproduct (all-coproducts a b) renaming (unique to []-unique) hiding (coapex) public
  module _ a b where open Coproduct (all-coproducts a b) renaming (coapex to infixr 7 _βŠ•β‚€_) using () public
  open Functor

  infix 50 _βŠ•β‚_

  _βŠ•β‚_ : βˆ€ {a b x y} β†’ Hom a x β†’ Hom b y β†’ Hom (a βŠ•β‚€ b) (x βŠ•β‚€ y)
  f βŠ•β‚ g = [ ι₁ ∘ f , ΞΉβ‚‚ ∘ g ]

  βŠ•-functor : Functor (C Γ—αΆœ C) C
  βŠ•-functor .Fβ‚€ (a , b) = a βŠ•β‚€ b
  βŠ•-functor .F₁ (f , g) = f βŠ•β‚ g
  βŠ•-functor .F-id = []-unique id-comm-sym id-comm-sym
  βŠ•-functor .F-∘ (f , g) (h , i) = []-unique
    (pullr []βˆ˜ΞΉβ‚ βˆ™ extendl []βˆ˜ΞΉβ‚)
    (pullr []βˆ˜ΞΉβ‚‚ βˆ™ extendl []βˆ˜ΞΉβ‚‚)

  βˆ‡ : βˆ€ {a} β†’ Hom (a βŠ•β‚€ a) a
  βˆ‡ = [ id , id ]

  coswap : βˆ€ {a b} β†’ Hom (a βŠ•β‚€ b) (b βŠ•β‚€ a)
  coswap = [ ΞΉβ‚‚ , ι₁ ]

  βŠ•-assoc : βˆ€ {a b c} β†’ Hom (a βŠ•β‚€ (b βŠ•β‚€ c)) ((a βŠ•β‚€ b) βŠ•β‚€ c)
  βŠ•-assoc = [ ι₁ ∘ ι₁ , [ ι₁ ∘ ΞΉβ‚‚ , ΞΉβ‚‚ ] ]