Pullback

Martin Escardo, 23rd May 2025.

Homotopy pullbacks and some basic properties to begin with.

This is loosely based on

[1] Jeremy Avigad, Chris Kapulkin, Peter LeFanu Lumsdaine.
    Homotopy limits in type theory, 2015 (first version 2013).
    https://arxiv.org/abs/1304.0680


{-# OPTIONS --safe --without-K #-}

module UF.Pullback where

open import MLTT.Spartan
open import UF.Embeddings
open import UF.Equiv
open import UF.Subsingletons


We assume a cospan

                 Y
                 │
                 │ g
                 │
                 ↓
      X ───────→ C
           f


module pullback
        {𝓤 𝓥 𝓦 : Universe}
        {X : 𝓤 ̇ } {Y : 𝓥 ̇ } {Z : 𝓦 ̇ }
        (f : X → Z) (g : Y → Z)
       where


And we consider commutative squares of the form

           q
      A ───────→ X
      │          │
    p │          │ g
      │          │
      ↓          ↓
      Y ───────→ Z
            f

completing the cospan.


 commutative-square : {A : 𝓣 ̇ } → (A → X) × (A → Y) → 𝓦 ⊔ 𝓣 ̇
 commutative-square (p , q) = f ∘ p ∼ g ∘ q


A cone over the cospan is the totality of these data.


 cone : 𝓣 ̇ → 𝓤 ⊔ 𝓥 ⊔ 𝓦 ⊔ 𝓣 ̇
 cone A = Σ pq ꞉ ((A → X) × (A → Y)) , commutative-square pq


It is convenient to collect all cones in a universe into a single
type.


 Cone : (𝓣 : Universe) → 𝓤 ⊔ 𝓥 ⊔ 𝓦 ⊔ (𝓣 ⁺) ̇
 Cone 𝓣 = Σ A ꞉ 𝓣 ̇ , cone A

 source : Cone 𝓣 → 𝓣 ̇
 source (P , c) = P

 cone-of : (𝓒 : Cone 𝓣) → cone (source 𝓒)
 cone-of (P , c) = c


If we have a cone

            q
      P ───────→ Y
      │          │
    p │          │ g
      │          │
      ↓          ↓
      X ───────→ Z
            f

and a map u : A → P, we get a cone

          q ∘ u
      A ───────→ Y
      │          │
p ∘ u │          │ g
      │          │
      ↓          ↓
      X ───────→ Z
            f


 cone-map : {P : 𝓣' ̇ } (A : 𝓣 ̇ ) → cone P → (A → P) → cone A
 cone-map X ((p , q) , e) u = (p ∘ u , q ∘ u) , e ∘ u


We say that a cone

            q
      P ───────→ Y
      │          │
    p │          │ g
      │          │
      ↓          ↓
      X ───────→ Z
            f

is a (homotopy) pullback if the cone map is an equivalence for every A.


 is-pullback : Cone 𝓣 → 𝓤ω
 is-pullback (P , c) = {𝓣' : Universe} (A : 𝓣' ̇ ) → is-equiv (cone-map A c)


We record the equivalence explicitly.


 module _ (𝓒@(P , c@((p₁ , p₂) , s)) : Cone 𝓣)
          (i : is-pullback 𝓒)
        where

  pullback-equivalence : (A : 𝓣' ̇ ) → (A → P) ≃ cone A
  pullback-equivalence A = cone-map A c , i A


And we can formulate the universal property of pullbacks in terms of
(homotopy) unique existence.


  module _ (𝓓@(A , d@((h₁ , h₂) , t)) : Cone 𝓣') where

   universal-property
    : ∃! u ꞉ (A → P) , ((p₁ ∘ u , p₂ ∘ u) , s ∘ u) = ((h₁ , h₂) , t)
   universal-property
    = equivs-are-vv-equivs (cone-map A c) (i A) d


It is convenient to name the uniquely existing u as the "mediating
map", and record the equations it satisfies.


   mediating-map : (A → P)
   mediating-map = pr₁ (center universal-property)

   _ : mediating-map = ⌜ pullback-equivalence A ⌝⁻¹ d
   _ = refl

   mediating-map-eq₁ : p₁ ∘ mediating-map = h₁
   mediating-map-eq₁ = ap (pr₁ ∘ pr₁) (pr₂ (center universal-property))

   mediating-map-eq₂ : p₂ ∘ mediating-map = h₂
   mediating-map-eq₂ = ap (pr₂ ∘ pr₁) (pr₂ (center universal-property))


We now show that pullbacks exist, and call them simply pullbacks,
although perhaps we should call them standard pullbacks, or chosen
pullbacks.

The construction is illustrated in the following diagram.

                                   pb₂
 Σ (x , y) ꞉ X × Y , f x = g y  ───────→ Y
           │                              │
      pb₁  │                              │ g
           │                              │
           ↓                              ↓
           X --------------------───────→ Z
                                  f

 pullback : 𝓤 ⊔ 𝓥 ⊔ 𝓦 ̇
 pullback = Σ (x , y) ꞉ X × Y , f x = g y

 private
  P = pullback

 pb₁ : P → X
 pb₁ ((x , y) , s) = x

 pb₂ : P → Y
 pb₂ ((x , y) , s) = y

 pullback-square : commutative-square (pb₁ , pb₂)
 pullback-square ((x , y) , s) = s

 pullback-cone : cone P
 pullback-cone = ((pb₁ , pb₂) , pullback-square)

 Pullback-Cone : Cone (𝓤 ⊔ 𝓥 ⊔ 𝓦)
 Pullback-Cone = P , pullback-cone

 pullback-cone-map : (A : 𝓣' ̇ ) → (A → P) → cone A
 pullback-cone-map A = cone-map A pullback-cone

 pullback-mediating-map : {A : 𝓣 ̇ } → cone A → (A → P)
 pullback-mediating-map ((p , q) , s) a = (p a , q a) , s a

 pullback-Cone-is-pullback : is-pullback Pullback-Cone
 pullback-Cone-is-pullback A =
  qinvs-are-equivs
   (pullback-cone-map A)
   (pullback-mediating-map , (λ u → refl) , (λ c → refl))

 _ : (A : 𝓣' ̇ ) (c : cone A)
   → pullback-mediating-map c
   = mediating-map Pullback-Cone pullback-Cone-is-pullback (A , c)
 _ = λ A c → refl


Pullbacks of embeddings are embeddings.


 pb₂-is-embedding : is-embedding f → is-embedding pb₂
 pb₂-is-embedding f-is-embedding y = I
   where
    I : is-prop (fiber pb₂ y)
    I (((x₁ , y) , e₁) , refl) (((x₂ , y) , e₂) , refl) = III II
     where
      II : (x₁ , e₁) = (x₂ , e₂)
      II = f-is-embedding (g y) (x₁ , e₁) (x₂ , e₂)

      III : {(x₁ , e₁) (x₂ , e₂) : fiber f (g y)}
          → (x₁ , e₁) = (x₂ , e₂)
          → (((x₁ , y) , e₁) , refl) =[ fiber pb₂ y ] (((x₂ , y) , e₂) , refl)
      III refl = refl

 𝕡𝕓₂ : is-embedding f → P ↪ Y
 𝕡𝕓₂ e = pb₂ , (pb₂-is-embedding e)


We have a pullback

           fiber f c ────→ 𝟙
              │            │
  fiber-point │            │ c
              │            │
              ↓            ↓
              X --───────→ Z
                     f


module _ {𝓤 𝓥 𝓦 : Universe}
         {X : 𝓤 ̇ }
         {Z : 𝓦 ̇ }
         (f : X → Z)
         (z : Z)
       where

 open pullback f (λ (_ : 𝟙 {𝓥}) → z)

 fiber-is-pullback
  : is-pullback (fiber f z , (fiber-point , unique-to-𝟙) , fiber-identification)
 fiber-is-pullback A
  = qinvs-are-equivs ϕ (γ , (λ u → refl) , (λ c → refl))
  where
   ϕ : (A → fiber f z) → cone A
   ϕ = cone-map A ((fiber-point , unique-to-𝟙) , fiber-identification)

   γ : cone A → (A → fiber f z)
   γ ((p , q) , s) a = p a , s a


TODO. Implement other results from [1].