module Cat.Diagram.Pullback where
Pullbacks🔗
module _ {o ℓ} (C : Precategory o ℓ) where open Cat.Reasoning C private variable P' X Y Z : Ob h p₁' p₂' : Hom X Y
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 (o ⊔ ℓ) where no-eta-equality field square : f ∘ p₁ ≡ g ∘ p₂
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.
universal : ∀ {P'} {p₁' : Hom P' X} {p₂' : Hom P' Y} → f ∘ p₁' ≡ g ∘ p₂' → Hom P' P p₁∘universal : {p : f ∘ p₁' ≡ g ∘ p₂'} → p₁ ∘ universal p ≡ p₁' p₂∘universal : {p : f ∘ p₁' ≡ g ∘ p₂'} → p₂ ∘ universal p ≡ p₂' unique : {p : f ∘ p₁' ≡ g ∘ p₂'} {lim' : Hom P' P} → 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'' unique₂ {p = o} p q r s = unique {p = o} p q ∙ sym (unique r s)
pullback-univ : ∀ {O} → Hom O P ≃ (Σ (Hom O X) λ h → Σ (Hom O Y) λ h' → f ∘ h ≡ g ∘ h') pullback-univ .fst h = p₁ ∘ h , p₂ ∘ h , extendl square pullback-univ .snd = is-iso→is-equiv λ where .is-iso.inv (f , g , α) → universal α .is-iso.rinv x → Σ-pathp p₁∘universal $ Σ-prop-pathp (λ _ _ → hlevel 1) p₂∘universal .is-iso.linv x → sym (unique refl refl)
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 (o ⊔ ℓ) where no-eta-equality field {apex} : Ob p₁ : Hom apex X p₂ : Hom apex Y has-is-pb : is-pullback p₁ f p₂ g open is-pullback has-is-pb public
module _ {o ℓ} {C : Precategory o ℓ} where open Cat.Reasoning C private variable P' X Y Z : Ob h p₁' p₂' : Hom X Y is-pullback-is-prop : ∀ {P} {p₁ : Hom P X} {f : Hom X Z} {p₂ : Hom P Y} {g : Hom Y Z} → is-prop (is-pullback C p₁ f p₂ g) is-pullback-is-prop {X = X} {Y = Y} {p₁ = p₁} {f} {p₂} {g} x y = q where open is-pullback p : Path (∀ {P'} {p₁' : Hom P' X} {p₂' : Hom P' Y} → f ∘ p₁' ≡ g ∘ p₂' → _) (x .universal) (y .universal) p i sq = y .unique {p = sq} (x .p₁∘universal {p = sq}) (x .p₂∘universal) i q : x ≡ y q i .square = Hom-set _ _ _ _ (x .square) (y .square) i q i .universal = p i q i .p₁∘universal {p₁' = p₁'} {p = sq} = is-prop→pathp (λ i → Hom-set _ _ (p₁ ∘ p i sq) p₁') (x .p₁∘universal) (y .p₁∘universal) i q i .p₂∘universal {p = sq} = is-prop→pathp (λ i → Hom-set _ _ (p₂ ∘ p i sq) _) (x .p₂∘universal) (y .p₂∘universal) i q i .unique {p = sq} {lim' = lim'} c₁ c₂ = is-prop→pathp (λ i → Hom-set _ _ lim' (p i sq)) (x .unique c₁ c₂) (y .unique c₁ c₂) i instance H-Level-is-pullback : ∀ {P} {p₁ : Hom P X} {f : Hom X Z} {p₂ : Hom P Y} {g : Hom Y Z} {n} → H-Level (is-pullback C p₁ f p₂ g) (suc n) H-Level-is-pullback = prop-instance is-pullback-is-prop
Kernel pairs🔗
The kernel pair of a morphism (if it exists) is the pullback of along itself. Intuitively, one should think of a kernel pair as a partition of induced by the preimage of
is-kernel-pair : ∀ {P X Y} → Hom P X → Hom P X → Hom X Y → Type _ is-kernel-pair p1 p2 f = is-pullback C p1 f p2 f
Note that each of the projections out of the kernel pair of are epimorphisms. Without loss of generality, we will focus our attention on the first projection.
is-kernel-pair→epil : ∀ {p1 p2 : Hom P X} {f : Hom X Y} → is-kernel-pair C p1 p2 f → is-epic p1
Recall that a morphism is epic if it has a section; that is, some morphism such that We can construct such a by applying the universal property of the pullback to the following diagram.
is-kernel-pair→epil {p1 = p1} is-kp = has-section→epic $ make-section (universal refl) p₁∘universal where open is-pullback is-kp
is-kernel-pair→epir : ∀ {P} {p1 p2 : Hom P X} {f : Hom X Y} → is-kernel-pair C p1 p2 f → is-epic p2 is-kernel-pair→epir {p2 = p2} is-kp = has-section→epic $ make-section (universal refl) p₂∘universal where open is-pullback is-kp
If is a monomorphism, then its kernel pair always exists, and is given by
monic→id-kernel-pair : ∀ {f : Hom X Y} → is-monic f → is-kernel-pair C id id f
Clearly, the square commutes, so the tricky bit will be constructing a universal morphism. If for some then we can simply use one of or for our universal map; the choice we make does not matter, as we can obtain from the fact that is monic! The rest of the universal property follows directly from this lovely little observation.
monic→id-kernel-pair {f = f} f-monic = id-kp where open is-pullback id-kp : is-kernel-pair C id id f id-kp .square = refl id-kp .universal {p₁' = p₁'} _ = p₁' id-kp .p₁∘universal = idl _ id-kp .p₂∘universal {p = p} = idl _ ∙ f-monic _ _ p id-kp .unique p q = sym (idl _) ∙ p
Conversely, if is the kernel pair of then is monic. Suppose that for some and note that both and are equal to the universal map obtained via the square
id-kernel-pair→monic : ∀ {f : Hom X Y} → is-kernel-pair C id id f → is-monic f id-kernel-pair→monic {f = f} id-kp g h p = g ≡˘⟨ p₁∘universal ⟩≡˘ id ∘ universal p ≡⟨ p₂∘universal ⟩≡ h ∎ where open is-pullback id-kp
We can strengthen this result by noticing that if is the kernel pair of for some then is also a kernel pair of
same-kernel-pair→id-kernel-pair : ∀ {P} {p : Hom P X} {f : Hom X Y} → is-kernel-pair C p p f → is-kernel-pair C id id f
As usual, the difficulty is constructing the universal map. Suppose that for some as in the following diagram:
This diagram is conspicuously missing a morphism, so let’s fill it in by using the universal property of the kernel pair.
Next, note that factorizes both and moreover, it is the unique such map!
same-kernel-pair→id-kernel-pair {p = p} {f = f} p-kp = id-kp where open is-pullback id-kp : is-kernel-pair C id id f id-kp .square = refl id-kp .universal q = p ∘ p-kp .universal q id-kp .p₁∘universal {p = q} = idl _ ∙ p-kp .p₁∘universal id-kp .p₂∘universal {p = q} = idl _ ∙ p-kp .p₂∘universal id-kp .unique q r = (sym (idl _)) ∙ q ∙ sym (p-kp .p₁∘universal)
Categories with all pullbacks🔗
We also provide a helper module for working with categories that have all pullbacks.
has-pullbacks : ∀ {o ℓ} → Precategory o ℓ → Type _ has-pullbacks C = ∀ {A B X} (f : Hom A X) (g : Hom B X) → Pullback C f g where open Precategory C module Pullbacks {o ℓ} (C : Precategory o ℓ) (all-pullbacks : has-pullbacks C) where open Precategory C module pullback {x y z} (f : Hom x z) (g : Hom y z) = Pullback (all-pullbacks f g) Pb : ∀ {x y z} → Hom x z → Hom y z → Ob Pb = pullback.apex
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 left 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 C f⁺ g p2 f → P f⁺