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 products come in: Rather than having a functor giving the objects to take the limit over, we have an arbitrary map from to the space of objects of An indexed product for this βdiagramβ is then an object admitting an universal family of maps
record is-indexed-product (F : Idx β C.Ob) (Ο : β i β C.Hom P (F i)) : Type (o β β β level-of Idx) where no-eta-equality field 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 uniqueβ : β {Y} {g h : C.Hom Y P} β (β i β Ο i C.β g β‘ Ο i C.β h) β g β‘ h uniqueβ {g = g} {h} eq = eta g β ap tuple (funext eq) β sym (eta h) 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 admits indexed products (of level if, for any type and family there is an indexed product of
record Indexed-product (F : Idx β C.Ob) : Type (o β β β level-of Idx) where no-eta-equality field {Ξ F} : C.Ob Ο : β i β C.Hom Ξ F (F i) has-is-ip : is-indexed-product F Ο open is-indexed-product has-is-ip public
module _ {β'} {I : Type β'} (F : I β C .Precategory.Ob) (ip : Indexed-product F) where private module ip = Indexed-product ip tupleβ : β {A B} (f : β i β C.Hom B (F i)) {g : C.Hom A B} β ip.tuple f C.β g β‘ ip.tuple Ξ» i β f i C.β g tupleβ f = ip.unique _ Ξ» i β C.pulll ip.commute Indexed-product-β : β {β β'} {I : Type β} {J : Type β'} β (e : I β J) β {F : I β C.Ob} β Indexed-product (F β Equiv.from e) β Indexed-product F Indexed-product-β e {F} p = Ξ» where .Ξ F β p .Ξ F .Ο j β C.to (pathβiso (ap F (e.Ξ· _))) C.β p .Ο (e.to j) .has-is-ip .tuple f β p .tuple (f β e.from) .has-is-ip .commute {f = f} β C.pullr (p .commute) β from-pathp-to C _ (ap f (e.Ξ· _)) .has-is-ip .unique f comm β p .unique _ Ξ» j β ap (C._β _) (sym (from-pathp-to C _ (ap (p .Ο) (e.Ξ΅ j))) β ap (Ξ» z β C.to (pathβiso (ap F z)) C.β p .Ο _) (e.zag j)) β comm (e.from j) where open Indexed-product open is-indexed-product module e = Equiv e Lift-Indexed-product : β {β} β' β {I : Type β} β {F : I β C.Ob} β Indexed-product {Idx = Lift β' I} (F β lower) β Indexed-product F Lift-Indexed-product _ = Indexed-product-β (Lift-β eβ»ΒΉ) is-indexed-product-is-prop : β {β'} {Idx : Type β'} β {F : Idx β C.Ob} {Ξ F : C.Ob} {Ο : β idx β C.Hom Ξ F (F idx)} β is-prop (is-indexed-product F Ο) is-indexed-product-is-prop {Idx = Idx} {F = F} {Ξ F = Ξ F} {Ο = Ο} P Q = path where open is-indexed-product p : β {X} β (f : (i : Idx) β C.Hom X (F i)) β P .tuple f β‘ Q .tuple f p f = Q .unique f (Ξ» idx β P .commute) path : P β‘ Q path i .tuple f = p f i path i .commute {i = idx} {f = f} = is-propβpathp (Ξ» i β C.Hom-set _ _ (Ο idx C.β p f i) (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-product F} where private module P = Indexed-product P module P' = Indexed-product P' Indexed-product-path : (p : P.Ξ F β‘ P'.Ξ F) β (β idx β PathP (Ξ» i β C.Hom (p i) (F idx)) (P.Ο idx) (P'.Ο idx)) β P β‘ P' Indexed-product-path p q i .Indexed-product.Ξ F = p i Indexed-product-path p q i .Indexed-product.Ο idx = q idx i Indexed-product-path p q i .Indexed-product.has-is-ip = is-propβpathp (Ξ» i β is-indexed-product-is-prop {Ξ F = p i} {Ο = Ξ» idx β q idx i}) P.has-is-ip P'.has-is-ip i
Uniquenessπ
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!
First, a general result: if two objects are both indexed products over the same family of objects, then those objects are isomorphic. This isomorphism is induced by the universal properties, and is readily seen to commute with both projections:
is-indexed-productβiso : β {β'} {Idx : Type β'} {F : Idx β C.Ob} β {Ξ F Ξ F' : C.Ob} β {Ο : β i β C.Hom Ξ F (F i)} {Ο' : β i β C.Hom Ξ F' (F i)} β is-indexed-product F Ο β is-indexed-product F Ο' β Ξ F C.β Ξ F' is-indexed-productβiso {Ο = Ο} {Ο' = Ο'} Ξ F-prod Ξ F'-prod = C.make-iso (Ξ F'.tuple Ο) (Ξ F.tuple Ο') (Ξ F'.uniqueβ (Ξ» i β C.pulll Ξ F'.commute β Ξ F.commute β sym (C.idr _))) (Ξ F.uniqueβ Ξ» i β C.pulll Ξ F.commute β Ξ F'.commute β sym (C.idr _)) where module Ξ F = is-indexed-product Ξ F-prod module Ξ F' = is-indexed-product Ξ F'-prod
Indexed-productβiso : β {β'} {Idx : Type β'} {F : Idx β C.Ob} β (P P' : Indexed-product F) β Indexed-product.Ξ F P C.β Indexed-product.Ξ F P' Indexed-productβiso P P' = is-indexed-productβiso (Indexed-product.has-is-ip P) (Indexed-product.has-is-ip P')
With that out of the way, we can proceed to show our original result! First, note that paths between indexed products are determined by a path between apices, and a corresponding path-over between projections. We can upgrade the iso from our previous lemma into a path, so all that remains is to construct the path-over.
Indexed-product-unique : β {β'} {I : Type β'} (F : I β C.Ob) β is-category C β is-prop (Indexed-product F) Indexed-product-unique {I = I} F c-cat x y = Indexed-product-path (c-cat .to-path apices) pres where module x = Indexed-product x module y = Indexed-product y apices : x.Ξ F C.β y.Ξ F apices = Indexed-productβiso x y
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 abstract 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
We can also prove the converse direction: if indexed products in are unique, then is univalent. In fact, we only need limits of one-object diagrams to be unique.
unique-productsβis-category : ({x : C.Ob} β is-prop (Indexed-product {Idx = β€} (Ξ» _ β x))) β is-category C unique-productsβis-category prop = cat where
Given an isomorphism we build two products for the one-object diagram one with apex itself and identity as projection, and one with apex and the given isomorphism as projection.
module _ {a b : C.Ob} (is : a C.β b) where open Indexed-product open is-indexed-product Pa : Indexed-product {Idx = β€} (Ξ» _ β a) Pa .Ξ F = a Pa .Ο _ = C.id Pa .has-is-ip .tuple f = f _ Pa .has-is-ip .commute = C.idl _ Pa .has-is-ip .unique f p = sym (C.idl _) β p _ Pb : Indexed-product {Idx = β€} (Ξ» _ β a) Pb .Ξ F = b Pb .Ο _ = is .C.from Pb .has-is-ip .tuple f = is .C.to C.β f _ Pb .has-is-ip .commute = C.cancell (is .C.invr) Pb .has-is-ip .unique f p = sym (C.lswizzle (sym (p _)) (is .C.invl))
By uniqueness, the two products are equal, which gives us an equality lying over our isomorphism.
path : a β‘ b path = ap Ξ F (prop Pa Pb) path-over : PathP (Ξ» i β a C.β path i) C.id-iso is path-over = C.β -pathp-from _ _ (ap (Ξ» p β p .Ο _) (prop Pa Pb)) cat : is-category C cat .to-path = path cat .to-path-over = path-over
Propertiesπ
Let be a family of objects in If the the indexed products and exists, then they are isomorphic.
is-indexed-product-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 (X ab)} β {Οα΅ : β a β C.Hom Ξ α΅Ξ α΅X (Ξ α΅X a)} β {Οα΅ : β a β (b : B a) β C.Hom (Ξ α΅X a) (X (a , b))} β is-indexed-product X Οα΅α΅ β is-indexed-product Ξ α΅X Οα΅ β (β a β is-indexed-product (Ξ» b β X (a , b)) (Οα΅ a)) β Ξ α΅α΅X C.β Ξ α΅Ξ α΅X
The proof is surprisingly straightforward: as indexed products are unique up to iso, it suffices to show that is an indexed product over
is-indexed-product-assoc {A = A} {B} {X} {Ξ α΅Ξ α΅X = Ξ α΅Ξ α΅X} {Οα΅ = Οα΅} {Οα΅} Ξ α΅α΅ Ξ α΅Ξ α΅ Ξ α΅ = is-indexed-productβiso Ξ α΅α΅ Ξ α΅α΅' where open is-indexed-product
We can construct projections by composing the projections out of each successive product.
Οα΅α΅' : β (ab : Ξ£ A B) β C.Hom Ξ α΅Ξ α΅X (X ab) Οα΅α΅' (a , b) = Οα΅ a b C.β Οα΅ a
The rest of the structure follows a similar pattern.
Ξ α΅α΅' : is-indexed-product X Οα΅α΅' Ξ α΅α΅' .tuple f = Ξ α΅Ξ α΅ .tuple Ξ» a β Ξ α΅ a .tuple Ξ» b β f (a , b) Ξ α΅α΅' .commute = C.pullr (Ξ α΅Ξ α΅ .commute) β Ξ α΅ _ .commute Ξ α΅α΅' .unique {h = h} f p = Ξ α΅Ξ α΅ .unique _ Ξ» a β Ξ α΅ _ .unique _ Ξ» b β C.assoc _ _ _ β p (a , b)
Categories with all indexed productsπ
has-products-indexed-by : β {β} (I : Type β) β Type _ has-products-indexed-by I = β (F : I β C.Ob) β Indexed-product F has-indexed-products : β β β Type _ has-indexed-products β = β {I : Type β} β has-products-indexed-by I module Indexed-products {ΞΊ : Level} (has-ip : has-indexed-products ΞΊ) where module β {Idx : Type ΞΊ} (F : Idx β C.Ob) = Indexed-product (has-ip F) open β renaming (commute to Ο-commute; unique to tuple-unique) public