module Cat.Diagram.Product.Indexed {o β„“} (C : Precategory o β„“) where

Indexed productsπŸ”—

If a category admits a terminal object and binary products, then it admits products of any finite cardinality: iterate the binary product, and use the terminal object when there aren’t any objects. However, these two classes of limit do not let us speak of products of arbitrary cardinality, or, in the univalent context, indexed by types which are not sets.

That’s where II-indexed products come in: Rather than having a functor giving the objects to take the limit over, we have an arbitrary map FF from II to the space of objects of C\mathcal{C}. An indexed product for this β€œdiagram” is then an object admitting an universal family of maps Ο€i:(∏F)β†’Fi\pi_i : (\prod F) \to F_i.

record is-indexed-product (F : Idx β†’ C.Ob) (Ο€ : βˆ€ i β†’ C.Hom P (F i))
  : Type (o βŠ” β„“ βŠ” level-of Idx) where
    tuple   : βˆ€ {Y} β†’ (βˆ€ i β†’ C.Hom Y (F i)) β†’ C.Hom Y P
    commute : βˆ€ {i} {Y} {f : βˆ€ i β†’ C.Hom Y (F i)} β†’ Ο€ i C.∘ tuple f ≑ f i
    unique  : βˆ€ {Y} {h : C.Hom Y P} (f : βˆ€ i β†’ C.Hom Y (F i))
            β†’ (βˆ€ i β†’ Ο€ i C.∘ h ≑ f i)
            β†’ h ≑ tuple f

  eta : βˆ€ {Y} (h : C.Hom Y P) β†’ h ≑ tuple Ξ» i β†’ Ο€ i C.∘ h
  eta h = unique _ Ξ» _ β†’ refl

  hom-iso : βˆ€ {Y} β†’ C.Hom Y P ≃ (βˆ€ i β†’ C.Hom Y (F i))
  hom-iso = (Ξ» f i β†’ Ο€ i C.∘ f) , is-isoβ†’is-equiv Ξ» where
    .is-iso.inv β†’ tuple
    .is-iso.rinv x β†’ funext Ξ» i β†’ commute
    .is-iso.linv x β†’ sym (unique _ Ξ» _ β†’ refl)

A category C\mathcal{C} admits indexed products (of level ℓ\ell) if, for any type I:Type ℓI : \mathrm{Type}\ \ell and family F:I→CF : I \to \mathcal{C}, there is an indexed product of FF.

record Indexed-product (F : Idx β†’ C.Ob) : Type (o βŠ” β„“ βŠ” level-of Idx) where
    {Ξ F}      : C.Ob
    Ο€         : βˆ€ i β†’ C.Hom Ξ F (F i)
    has-is-ip : is-indexed-product F Ο€
  open is-indexed-product has-is-ip public

has-indexed-products : βˆ€ β„“ β†’ Type _
has-indexed-products β„“ = βˆ€ {I : Type β„“} (F : I β†’ C.Ob) β†’ Indexed-product F

As limitsπŸ”—

In the particular case where II is a groupoid, e.g. because it arises as the space of objects of a univalent category, an indexed product for F:I→CF : I \to \mathcal{C} is the same thing as a limit over FF, considered as a functor DiscI→C\mathrm{Disc}{I} \to \mathcal{C}. We can not lift this restriction: If II is not a groupoid, then its path spaces x=yx = y are not necessarily sets, and so the Disc construction does not apply to it.

module _ {I : Type β„“'} (i-is-grpd : is-groupoid I) (F : I β†’ C.Ob) where
  open _=>_

  Projβ†’Cone : βˆ€ {x} β†’ (βˆ€ i β†’ C.Hom x (F i))
            β†’ Const x => Disc-adjunct {C = C} {iss = i-is-grpd} F
  Proj→Cone π .η i = π i
  Proj→Cone π .is-natural i j p =
    J (Ξ» j p β†’  Ο€ j C.∘ ≑ subst (C.Hom (F i) βŠ™ F) p C.∘ Ο€ i)
      (C.idr _ βˆ™ C.introl (transport-refl

    : βˆ€ {x} {Ο€ : βˆ€ i β†’ C.Hom x (F i)}
    β†’ is-indexed-product F Ο€
    → is-limit (Disc-adjunct F) x (Proj→Cone π)
  is-indexed-product→is-limit {x = x} {π} ip =
    to-is-limitp ml refl
      module ip = is-indexed-product ip
      open make-is-limit

      ml : make-is-limit (Disc-adjunct F) x
      ml .ψ j = Ο€ j
      ml .commutes {i} {j} p =
        J (Ξ» j p β†’ subst (C.Hom (F i) βŠ™ F) p C.∘ Ο€ i ≑ Ο€ j)
          (C.eliml (transport-refl _))
      ml .universal eta p = ip.tuple eta
      ml .factors eta p = ip.commute
      ml .unique eta p other q = ip.unique eta q

    : βˆ€ {K : Functor ⊀Cat C}
    β†’ {eta : K F∘ !F => Disc-adjunct {iss = i-is-grpd} F}
    β†’ is-ran !F (Disc-adjunct F) K eta
    β†’ is-indexed-product F (eta .Ξ·)
  is-limit→is-indexed-product {K = K} {eta} lim = ip where
    module lim = is-limit lim
    open is-indexed-product hiding (eta)

    ip : is-indexed-product F (eta .Ξ·)
    ip .tuple k =
      lim.universal k
        (J (Ξ» j p β†’ subst (C.Hom (F _) βŠ™ F) p C.∘ k _ ≑ k j)
           (C.eliml (transport-refl _)))
    ip .commute =
      lim.factors _ _
    ip .unique k comm =
      lim.unique _ _ _ comm

  IP→Limit : Indexed-product F → Limit {C = C} (Disc-adjunct {iss = i-is-grpd} F)
  IP→Limit ip =
    to-limit (is-indexed-product→is-limit has-is-ip)
    where open Indexed-product ip

  Limit→IP : Limit {C = C} (Disc-adjunct {iss = i-is-grpd} F) → Indexed-product F
  Limit→IP lim .Indexed-product.ΠF = _
  Limit→IP lim .Indexed-product.π = _
  Limit→IP lim .Indexed-product.has-is-ip =
    is-limit→is-indexed-product (Limit.has-limit lim)


As is traditional with universal constructions, β€œhaving an indexed product for a diagram” is property of a category, not structure: Put another way, for any particular diagram, in a univalent category, there is (at most) a contractible space of indexed products of that diagram. And again as is traditional with universal constructions, the proof is surprisingly straightforward!

  : βˆ€ {β„“β€²} {I : Type β„“β€²} (F : I β†’ C.Ob)
  β†’ is-category C β†’ is-prop (Indexed-product F)
Indexed-product-unique {I = I} F c-cat x y = p where
  module x = Indexed-product x
  module y = Indexed-product y

All we have to do β€” β€œall” β€” is exhibit an isomorphism between the apices which commutes with the projection function in one direction, and with the product with morphisms in the other. That’s it! The isomorphism is induced by the universal properties, and is readily seen to commute with both projections:

  apices : x.Ξ F C.β‰… y.Ξ F
  apices = C.make-iso (y.tuple x.Ο€) (x.tuple y.Ο€)
    ( y.unique y.Ο€ (Ξ» i β†’ C.pulll y.commute βˆ™ x.commute)
    βˆ™ sym (y.unique y.Ο€ Ξ» i β†’ C.idr _) )
    ( x.unique x.Ο€ (Ξ» i β†’ C.pulll x.commute βˆ™ y.commute)
    βˆ™ sym (x.unique x.Ο€ Ξ» i β†’ C.idr _))

By the characterisation of paths-over in Hom-sets, we get paths-over between the projection maps and the product maps:

  module apices = C._β‰…_ apices
    pres : βˆ€ j β†’ PathP (Ξ» i β†’ C.Hom (c-cat .to-path apices i) (F j)) (x.Ο€ j) (y.Ο€ j)
    pres j = Univalent.Hom-pathp-refll-iso c-cat x.commute

    presβ€² : βˆ€ {Y} (f : βˆ€ j β†’ C.Hom Y (F j))
      β†’ PathP (Ξ» i β†’ C.Hom Y (c-cat .to-path apices i)) (x.tuple f) (y.tuple f)
    presβ€² f =
      Univalent.Hom-pathp-reflr-iso c-cat (y.unique f Ξ» j β†’ C.pulll y.commute βˆ™ x.commute)

And after some munging (dealing with the axioms), that’s exactly what we need to prove that indexed products are unique.

  open Indexed-product
  open is-indexed-product
  p : x ≑ y
  p i .Ξ F = c-cat .to-path apices i
  p i .Ο€ j = pres j i
  p i .has-is-ip .tuple f = presβ€² f i
  p i .has-is-ip .commute {i = j} {f = f} =
    is-propβ†’pathp (Ξ» i β†’ C.Hom-set _ (F j) (pres j i C.∘ presβ€² f i) _)
     (x .has-is-ip .commute) (y .has-is-ip .commute) i
  p i .has-is-ip .unique {h = h} f =
      (Ξ» i β†’ Ξ -is-hlevel {A = C.Hom _ (c-cat .to-path apices i)} 1
       Ξ» h β†’ Ξ -is-hlevel {A = βˆ€ j β†’ pres j i C.∘ h ≑ f j} 1
       Ξ» p β†’ C.Hom-set _ (c-cat .to-path apices i) h (presβ€² f i))
      (Ξ» h β†’ x.unique {h = h} f) (Ξ» h β†’ y.unique {h = h} f) i h