module Cat.Diagram.Limit.Finite where
Finitely complete categories🔗
A category is said to be finitely complete if it admits limits for every diagram with a finite shape.
: Typeω
is-finitely-complete = ∀ {o ℓ} {D : Precategory o ℓ} → is-finite-precategory D
is-finitely-complete → (F : Functor D C) → Limit F
Similarly to the case with arbitrary limits, we can get away with only the following common shapes of limits:
- A terminal object (limit over the empty diagram)
- Binary products (limits over diagrams of the form that is, two points)
- Binary equalisers (limits over diagrams of the form
- Binary pullbacks (limits over diagrams of the form
In reality, the list above has some redundancy. Since we can build products out of pullbacks and a terminal object, and conversely we can build pullbacks out of products and equalisers, either of the following subsets suffices:
- A terminal object, binary products, binary equalisers;
- A terminal object and binary pullbacks.
For proving that a thin category is finitely complete, given that equalisers are trivial and pullbacks coincide with products, it suffices to give a terminal object and binary products.
record Finitely-complete : Type (ℓ ⊔ ℓ') where
no-eta-equality
field
: Terminal C
terminal : Binary-products C
products : Equalisers C
equalisers : Pullbacks C
pullbacks
open Terminal terminal public
open Binary-products products public
open Equalisers equalisers public
open Pullbacks pullbacks public
As promised, the two definitions imply each other, assuming that is a univalent category (which is required to go from binary products to finite products).
Finitely-complete→is-finitely-complete: is-category C
→ Finitely-complete → is-finitely-complete
=
Finitely-complete→is-finitely-complete cat Flim finite
limit-as-equaliser-of-product(Cartesian→finite-products terminal products cat (finite .has-finite-Ob))
(Cartesian→finite-products terminal products cat (finite .has-finite-Arrows))
equaliserswhere open Finitely-complete Flim
is-finitely-complete→Finitely-complete: is-finitely-complete → Finitely-complete
= Flim where
is-finitely-complete→Finitely-complete flim open Finitely-complete
: Finitely-complete
Flim .terminal = Limit→Terminal C (flim finite-cat _)
Flim .products = all-products→binary-products λ a b →
Flim (flim Disc-finite _)
Limit→Product C .equalisers = all-equalisers→equalisers λ f g →
Flim (flim ·⇉·-finite _)
Limit→Equaliser C .pullbacks = all-pullbacks→pullbacks λ f g →
Flim {lzero} {lzero} (flim ·→·←·-finite _) Limit→Pullback C
With equalisers🔗
We now prove that having products and equalisers suffices to have all pullbacks; Thus a terminal object, binary products and binary equalisers suffice for finite completeness.
The main result is as follows: Let be a (the) product of and with its projections called and Letting be a cospan, if the composites and have an equaliser then the square
is a pullback. Now, that description is almost entirely abstract-nonsensical, because (for generality) we do not use any “canonical” products or equalisers If we work slightly more concretely, then this can be read as building the pullback as the largest subobject of where agree. In particular, the pullback we want is the object in the commutative diagram below.
product+equaliser→pullback: ∀ {E P X Y Z} {p1 : Hom P X} {p2 : Hom P Y} {f : Hom X Z}
{g : Hom Y Z} {e : Hom E P}
→ is-product C p1 p2
→ is-equaliser C (f ∘ p1) (g ∘ p2) e
→ is-pullback C (p1 ∘ e) f (p2 ∘ e) g
{p1 = p1} {p2} {f} {g} {e} prod eq = pb where
product+equaliser→pullback open is-pullback
module eq = is-equaliser eq
module pr = is-product prod
: is-pullback C _ _ _ _
pb .square = assoc _ _ _ ∙ eq.equal ∙ sym (assoc _ _ _) pb
To show that this object really is a pullback of and note that we can factor any pair of arrows and through the Cartesian product and use the universal property of equalisers to factor that as a unique arrow
.universal {p₁' = p₁'} {p₂' = p₂'} p =
pb .universal {e' = pr.⟨ p₁' , p₂' ⟩} (
eq(f ∘ p1) ∘ pr.⟨ p₁' , p₂' ⟩ ≡⟨ pullr pr.π₁∘⟨⟩ ⟩
f ∘ p₁' ≡⟨ p ⟩.π₂∘⟨⟩ ⟩
g ∘ p₂' ≡˘⟨ pullr pr(g ∘ p2) ∘ pr.⟨ p₁' , p₂' ⟩ ∎
)
.p₁∘universal = pullr eq.factors ∙ pr.π₁∘⟨⟩
pb .p₂∘universal = pullr eq.factors ∙ pr.π₂∘⟨⟩
pb .unique p q =
pb .unique (pr.unique (assoc _ _ _ ∙ p) (assoc _ _ _ ∙ q)) eq
Hence, assuming that a category has a terminal object, binary products and binary equalisers means it also admits pullbacks.
with-equalisers: Terminal C
→ Binary-products C
→ Equalisers C
→ Finitely-complete
.Finitely-complete.terminal = top
with-equalisers top prods eqs .Finitely-complete.products = prods
with-equalisers top prods eqs .Finitely-complete.equalisers = eqs
with-equalisers top prods eqs .Finitely-complete.pullbacks =
with-equalisers top prods eqs products+equalisers→pullbacks prods eqs
With pullbacks🔗
We’ll now prove the converse: That a terminal object and pullbacks implies having all products, and all equalisers. We’ll start with the products, since those are simpler. Observe that we can complete a product diagram (like the one on the left) to a pullback diagram (like the one on the right) by adding in the unique arrows into the terminal object
terminal+pullback→product: ∀ {P X Y T} {p1 : Hom P X} {p2 : Hom P Y} {f : Hom X T} {g : Hom Y T}
→ is-terminal C T → is-pullback C p1 f p2 g → is-product C p1 p2
{p1 = p1} {p2} {f} {g} term pb = prod where terminal+pullback→product
module Pb = is-pullback pb
: is-product C p1 p2
prod .is-product.⟨_,_⟩ p1' p2' =
prod .universal {p₁' = p1'} {p₂' = p2'} (is-contr→is-prop (term _) _ _)
Pb.is-product.π₁∘⟨⟩ = Pb.p₁∘universal
prod .is-product.π₂∘⟨⟩ = Pb.p₂∘universal
prod .is-product.unique p q = Pb.unique p q prod
For equalisers, the situation is a bit more complicated. Recall that, by analogy with the case in Set, we can consider the equaliser to be the solution set of for some We can consider the two sides of this equation as a single map The equation is solved where this pairing map equals some We can thus build equalisers by pulling back along the diagonal map:
product+pullback→equaliser: ∀ {E X Y Y²}
→ {f g : Hom X Y} {e : Hom E X} {π₁ π₂ : Hom Y² Y} {p₁ : Hom E Y}
→ (is-prod : is-product C π₁ π₂) (let open is-product is-prod)
→ (is-pb : is-pullback C p₁ ⟨ id , id ⟩ e ⟨ f , g ⟩)
→ is-equaliser C f g e
{f = f} {g} {e} {π₁} {π₂} {p₁} is-prod is-pb = is-eq where
product+pullback→equaliser open is-product is-prod renaming (unique₂ to ⟨⟩-unique₂)
open is-pullback is-pb renaming (unique to pb-unique)
The actual equaliser map is the top, horizontal face (what the code
calls e
, so we must show that, composed with this map,
and
become equal. Here’s where we use the fact that pullback squares, well,
commute: We know that
is
and that
(since the square above is a pullback).
But both projections out of are equal, so we can apply commutativity of the square above again to conclude that
: is-equaliser C f g e
is-eq .is-equaliser.equal =
is-eq
f ∘ e ≡˘⟨ pulll π₁∘⟨⟩ ⟩_∘_ refl square ⟩
π₁ ∘ ⟨ f , g ⟩ ∘ e ≡˘⟨ ap₂ (π₁∘⟨⟩ ∙ sym (π₂∘⟨⟩)) ⟩
π₁ ∘ ⟨ id , id ⟩ ∘ p₁ ≡⟨ extendl _∘_ refl square ⟩
π₂ ∘ ⟨ id , id ⟩ ∘ p₁ ≡⟨ ap₂
π₂ ∘ ⟨ f , g ⟩ ∘ e ≡⟨ pulll π₂∘⟨⟩ ⟩ g ∘ e ∎
We must now show that if is another map which equalises and then it fits into a commutative diagram like the one below, so that we may conclude the dashed arrow exists and is unique.
A bit of boring limit-chasing lets us conclude that this diagram does commute, hence the dashed arrow does exist (uniquely!), so that the top face in our pullback diagram is indeed the equaliser of and
.is-equaliser.universal {e' = e'} p =
is-eq {p₁' = f ∘ e'} {p₂' = e'} comm
universal where abstract
: ⟨ id , id ⟩ ∘ f ∘ e' ≡ (⟨ f , g ⟩ ∘ e')
comm =
comm
⟨⟩-unique₂(cancell π₁∘⟨⟩) (cancell π₂∘⟨⟩)
(pulll π₁∘⟨⟩) (pulll π₂∘⟨⟩ ∙ sym p)
.is-equaliser.factors = p₂∘universal
is-eq .is-equaliser.unique {e' = e'} {p = p} {other = other} e∘other=e' =
is-eq
pb-unique
p₁∘other=f∘e'
e∘other=e'where
: p₁ ∘ other ≡ f ∘ e'
p₁∘other=f∘e' =
p₁∘other=f∘e'
p₁ ∘ other ≡⟨ insertl π₁∘⟨⟩ ⟩_∘_ refl (extendl square) ⟩
π₁ ∘ ⟨ id , id ⟩ ∘ p₁ ∘ other ≡⟨ ap₂
π₁ ∘ ⟨ f , g ⟩ ∘ e ∘ other ≡⟨ pulll π₁∘⟨⟩ ⟩_∘_ refl e∘other=e' ⟩
f ∘ e ∘ other ≡⟨ ap₂ f ∘ e' ∎
Putting it all together into a record we get our proof of finite completeness:
with-pullbacks: Terminal C
→ Pullbacks C
→ Finitely-complete
= fc where
with-pullbacks top pbs : Binary-products C
prods = terminal+pullbacks→products top pbs
prods
: Finitely-complete
fc .Finitely-complete.terminal = top
fc .Finitely-complete.products = prods
fc .Finitely-complete.equalisers = products+pullbacks→equalisers prods pbs
fc .Finitely-complete.pullbacks = pbs fc
–
Lex functors🔗
A functor is said to be left exact, abbreviated lex, when it preserves finite limits. These functors aren’t called “finite-limit-preserving functors” by historical accident, and for brevity. By the characterisations above, it suffices for a functor to preserve the terminal object and pullbacks.
record is-lex (F : Functor C D) : Type (o ⊔ ℓ ⊔ o' ⊔ ℓ') where
private module F = Functor F
field
: ∀ {T} → is-terminal C T → is-terminal D (F.₀ T)
pres-⊤
pres-pullback: ∀ {P X Y Z} {p1 : C.Hom P X} {p2 : C.Hom P Y}
{f : C.Hom X Z} {g : C.Hom Y Z}
→ is-pullback C p1 f p2 g
→ is-pullback D (F.₁ p1) (F.₁ f) (F.₁ p2) (F.₁ g)
Since (if a terminal object exists), products can be identified with pullbacks if has a terminal object, then a lex functor also preserves products.
pres-product: ∀ {P A B T} {p1 : C.Hom P A} {p2 : C.Hom P B}
→ is-terminal C T
→ is-product C p1 p2
→ is-product D (F.₁ p1) (F.₁ p2)
= terminal+pullback→product D (pres-⊤ term)
pres-product term pr (pres-pullback {f = term _ .centre} {g = term _ .centre}
(product→terminal-pullback C term pr))
Since being a monomorphism is equivalent to certain squares being pullbacks, a lex functor preserves monomorphisms.
: ∀ {A B} {f : C.Hom A B} → C.is-monic f → D.is-monic (F.₁ f)
pres-monos {f = f} mono = is-pullback→is-monic
pres-monos (subst (λ x → is-pullback D x _ x _) F.F-id
(pres-pullback
(is-monic→is-pullback mono)))