module Cat.Diagram.Pullback {ℓ ℓ'} (C : Precategory ℓ ℓ') where
Pullbacks🔗
A pullback of and is the product of and in the category , the category of objects fibred over . We note that the fibre of over some element of is the product of the fibres of and over ; Hence the pullback is also called the fibred product.
record is-pullback {P} (p₁ : Hom P X) (f : Hom X Z) (p₂ : Hom P Y) (g : Hom Y Z)
: Type (ℓ ⊔ ℓ') where
no-eta-equality
field
: f ∘ p₁ ≡ g ∘ p₂ square
The concrete incarnation of the abstract nonsense above is that a pullback turns out to be a universal square like the one below. Since it is a product, it comes equipped with projections and onto its factors; Since isn’t merely a product of and , but rather of and considered as objects over in a specified way, overall square has to commute.
: ∀ {P'} {p₁' : Hom P' X} {p₂' : Hom P' Y}
universal → f ∘ p₁' ≡ g ∘ p₂' → Hom P' P
: {p : f ∘ p₁' ≡ g ∘ p₂'} → p₁ ∘ universal p ≡ p₁'
p₁∘universal : {p : f ∘ p₁' ≡ g ∘ p₂'} → p₂ ∘ universal p ≡ p₂'
p₂∘universal
: {p : f ∘ p₁' ≡ g ∘ p₂'} {lim' : Hom P' P}
unique → p₁ ∘ lim' ≡ p₁'
→ p₂ ∘ lim' ≡ p₂'
→ lim' ≡ universal p
unique₂: {p : f ∘ p₁' ≡ g ∘ p₂'} {lim' lim'' : Hom P' P}
→ p₁ ∘ lim' ≡ p₁' → p₂ ∘ lim' ≡ p₂'
→ p₁ ∘ lim'' ≡ p₁' → p₂ ∘ lim'' ≡ p₂'
→ lim' ≡ lim''
{p = o} p q r s = unique {p = o} p q ∙ sym (unique r s) unique₂
By universal, we mean that any other “square” (here the second “square” has corners , , , — it’s a bit bent) admits a unique factorisation that passes through ; We can draw the whole situation as in the diagram below. Note the little corner on , indicating that the square is a pullback.
We provide a convenient packaging of the pullback and the projection maps:
record Pullback {X Y Z} (f : Hom X Z) (g : Hom Y Z) : Type (ℓ ⊔ ℓ') where
no-eta-equality
field
{apex} : Ob
: Hom apex X
p₁ : Hom apex Y
p₂ : is-pullback p₁ f p₂ g
has-is-pb
open is-pullback has-is-pb public
Categories with all pullbacks🔗
We also provide a helper module for working with categories that have all pullbacks.
: Type _
has-pullbacks = ∀ {A B X} (f : Hom A X) (g : Hom B X) → Pullback f g
has-pullbacks
module Pullbacks (all-pullbacks : has-pullbacks) where
module pullback {x y z} (f : Hom x z) (g : Hom y z) =
(all-pullbacks f g)
Pullback
: ∀ {x y z} → Hom x z → Hom y z → Ob
Pb = pullback.apex Pb
Stability🔗
Pullbacks, in addition to their nature as limits, serve as the way of “changing the base” of a family of objects: if we think of an arrow as encoding the data of a family over (think of the special case where , and ), then we can think of pulling back along as “the universal solution to making a family over , via ”. One way of making this intuition formal is through the fundamental fibration of a category with pullbacks.
In that framing, there is a canonical choice for “the” pullback of an
arrow along another: We put the arrow
we want to pullback on the right side of the diagram, and the pullback
is the right arrow. Using the type is-pullback
defined above, the arrow
which results from pulling back is adjacent to the adjustment:
is-pullback f⁺ g _ f
. To help keep this straight, we define
what it means for a class of arrows to be stable under
pullback: If f
has a given property, then so does
f⁺
, for any pullback of f
.
is-pullback-stable: ∀ {ℓ'} → (∀ {a b} → Hom a b → Type ℓ') → Type _
=
is-pullback-stable P ∀ {p A B X} (f : Hom A B) (g : Hom X B) {f⁺ : Hom p X} {p2}
→ P f → is-pullback f⁺ g p2 f → P f⁺