# Standard pullbacks
```agda
module foundation.standard-pullbacks where
```
<details><summary>Imports</summary>
```agda
open import foundation.action-on-identifications-functions
open import foundation.cones-over-cospan-diagrams
open import foundation.dependent-pair-types
open import foundation.equality-cartesian-product-types
open import foundation.functoriality-cartesian-product-types
open import foundation.identity-types
open import foundation.structure-identity-principle
open import foundation.universe-levels
open import foundation-core.cartesian-product-types
open import foundation-core.commuting-squares-of-maps
open import foundation-core.diagonal-maps-cartesian-products-of-types
open import foundation-core.equality-dependent-pair-types
open import foundation-core.equivalences
open import foundation-core.function-types
open import foundation-core.functoriality-dependent-pair-types
open import foundation-core.homotopies
open import foundation-core.retractions
open import foundation-core.sections
open import foundation-core.type-theoretic-principle-of-choice
open import foundation-core.universal-property-pullbacks
open import foundation-core.whiskering-identifications-concatenation
```
</details>
## Idea
Given a [cospan of types](foundation.cospans.md)
```text
f : A → X ← B : g,
```
we can form the
{{#concept "standard pullback" Disambiguation="types" Agda=standard-pullback}}
`A ×_X B` satisfying
[the universal property of the pullback](foundation-core.universal-property-pullbacks.md)
of the cospan, completing the diagram
```text
A ×_X B ------> B
| ⌟ |
| | g
| |
∨ ∨
A ---------> X.
f
```
The standard pullback consists of [pairs](foundation.dependent-pair-types.md)
`a : A` and `b : B` such that `f a` and `g b` agree:
```text
A ×_X B := Σ (a : A) (b : B), (f a = g b),
```
thus the standard [cone](foundation.cones-over-cospan-diagrams.md) consists of
the canonical projections.
## Definitions
### The standard pullback of a cospan
```agda
module _
{l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3} (f : A → X) (g : B → X)
where
standard-pullback : UU (l1 ⊔ l2 ⊔ l3)
standard-pullback = Σ A (λ x → Σ B (λ y → f x = g y))
module _
{l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3} {f : A → X} {g : B → X}
where
vertical-map-standard-pullback : standard-pullback f g → A
vertical-map-standard-pullback = pr1
horizontal-map-standard-pullback : standard-pullback f g → B
horizontal-map-standard-pullback t = pr1 (pr2 t)
coherence-square-standard-pullback :
coherence-square-maps
( horizontal-map-standard-pullback)
( vertical-map-standard-pullback)
( g)
( f)
coherence-square-standard-pullback t = pr2 (pr2 t)
```
### The cone at the standard pullback
```agda
module _
{l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3} (f : A → X) (g : B → X)
where
cone-standard-pullback : cone f g (standard-pullback f g)
pr1 cone-standard-pullback = vertical-map-standard-pullback
pr1 (pr2 cone-standard-pullback) = horizontal-map-standard-pullback
pr2 (pr2 cone-standard-pullback) = coherence-square-standard-pullback
```
### The gap map into the standard pullback
The {{#concept "standard gap map" Disambiguation="cone over a cospan" Agda=gap}}
of a [commuting square](foundation-core.commuting-squares-of-maps.md) is the map
from the domain of the cone into the standard pullback.
```agda
module _
{l1 l2 l3 l4 : Level} {A : UU l1} {B : UU l2} {X : UU l3} {C : UU l4}
(f : A → X) (g : B → X)
where
gap : cone f g C → C → standard-pullback f g
pr1 (gap c z) = vertical-map-cone f g c z
pr1 (pr2 (gap c z)) = horizontal-map-cone f g c z
pr2 (pr2 (gap c z)) = coherence-square-cone f g c z
```
#### The standard ternary pullback
Given two cospans with a shared vertex `B`:
```text
f g h i
A ----> X <---- B ----> Y <---- C,
```
we call the standard limit of the diagram the
{{#concept "standard ternary pullback" Disambiguation="of types" Agda=standard-ternary-pullback}}.
It is defined as the sum
```text
standard-ternary-pullback f g h i :=
Σ (a : A) (b : B) (c : C), ((f a = g b) × (h b = i c)).
```
```agda
module _
{l1 l2 l3 l4 l5 : Level}
{X : UU l1} {Y : UU l2} {A : UU l3} {B : UU l4} {C : UU l5}
(f : A → X) (g : B → X) (h : B → Y) (i : C → Y)
where
standard-ternary-pullback : UU (l1 ⊔ l2 ⊔ l3 ⊔ l4 ⊔ l5)
standard-ternary-pullback =
Σ A (λ a → Σ B (λ b → Σ C (λ c → (f a = g b) × (h b = i c))))
```
## Properties
### Characterization of the identity type of the standard pullback
```agda
module _
{l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3} (f : A → X) (g : B → X)
where
Eq-standard-pullback : (t t' : standard-pullback f g) → UU (l1 ⊔ l2 ⊔ l3)
Eq-standard-pullback (a , b , p) (a' , b' , p') =
Σ (a = a') (λ α → Σ (b = b') (λ β → ap f α ∙ p' = p ∙ ap g β))
refl-Eq-standard-pullback :
(t : standard-pullback f g) → Eq-standard-pullback t t
pr1 (refl-Eq-standard-pullback (a , b , p)) = refl
pr1 (pr2 (refl-Eq-standard-pullback (a , b , p))) = refl
pr2 (pr2 (refl-Eq-standard-pullback (a , b , p))) = inv right-unit
Eq-eq-standard-pullback :
(s t : standard-pullback f g) → s = t → Eq-standard-pullback s t
Eq-eq-standard-pullback s .s refl = refl-Eq-standard-pullback s
extensionality-standard-pullback :
(t t' : standard-pullback f g) → (t = t') ≃ Eq-standard-pullback t t'
extensionality-standard-pullback (a , b , p) =
extensionality-Σ
( λ bp' α → Σ (b = pr1 bp') (λ β → ap f α ∙ pr2 bp' = p ∙ ap g β))
( refl)
( refl , inv right-unit)
( λ x → id-equiv)
( extensionality-Σ
( λ p' β → p' = p ∙ ap g β)
( refl)
( inv right-unit)
( λ y → id-equiv)
( λ p' → equiv-concat' p' (inv right-unit) ∘e equiv-inv p p'))
map-extensionality-standard-pullback :
{ s t : standard-pullback f g}
( α : vertical-map-standard-pullback s = vertical-map-standard-pullback t)
( β :
horizontal-map-standard-pullback s =
horizontal-map-standard-pullback t) →
( ( ap f α ∙ coherence-square-standard-pullback t) =
( coherence-square-standard-pullback s ∙ ap g β)) →
s = t
map-extensionality-standard-pullback {s} {t} α β γ =
map-inv-equiv (extensionality-standard-pullback s t) (α , β , γ)
```
### The standard pullback satisfies the universal property of pullbacks
```agda
module _
{l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3} (f : A → X) (g : B → X)
where
abstract
universal-property-standard-pullback :
universal-property-pullback f g (cone-standard-pullback f g)
universal-property-standard-pullback C =
is-equiv-comp
( tot (λ _ → map-distributive-Π-Σ))
( mapping-into-Σ)
( is-equiv-mapping-into-Σ)
( is-equiv-tot-is-fiberwise-equiv (λ _ → is-equiv-map-distributive-Π-Σ))
```
### A cone is equal to the value of `cone-map` at its own gap map
```agda
module _
{l1 l2 l3 l4 : Level} {A : UU l1} {B : UU l2} {X : UU l3} {C : UU l4}
(f : A → X) (g : B → X)
where
htpy-cone-up-pullback-standard-pullback :
(c : cone f g C) →
htpy-cone f g (cone-map f g (cone-standard-pullback f g) (gap f g c)) c
pr1 (htpy-cone-up-pullback-standard-pullback c) = refl-htpy
pr1 (pr2 (htpy-cone-up-pullback-standard-pullback c)) = refl-htpy
pr2 (pr2 (htpy-cone-up-pullback-standard-pullback c)) = right-unit-htpy
```
### Standard pullbacks are symmetric
The standard pullback of `f : A -> X <- B : g` is equivalent to the standard
pullback of `g : B -> X <- A : f`.
```agda
map-commutative-standard-pullback :
{l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3}
(f : A → X) (g : B → X) → standard-pullback f g → standard-pullback g f
pr1 (map-commutative-standard-pullback f g x) =
horizontal-map-standard-pullback x
pr1 (pr2 (map-commutative-standard-pullback f g x)) =
vertical-map-standard-pullback x
pr2 (pr2 (map-commutative-standard-pullback f g x)) =
inv (coherence-square-standard-pullback x)
inv-inv-map-commutative-standard-pullback :
{l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3}
(f : A → X) (g : B → X) →
( map-commutative-standard-pullback f g ∘
map-commutative-standard-pullback g f) ~ id
inv-inv-map-commutative-standard-pullback f g x =
eq-pair-eq-fiber
( eq-pair-eq-fiber
( inv-inv (coherence-square-standard-pullback x)))
abstract
is-equiv-map-commutative-standard-pullback :
{l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3}
(f : A → X) (g : B → X) → is-equiv (map-commutative-standard-pullback f g)
is-equiv-map-commutative-standard-pullback f g =
is-equiv-is-invertible
( map-commutative-standard-pullback g f)
( inv-inv-map-commutative-standard-pullback f g)
( inv-inv-map-commutative-standard-pullback g f)
commutative-standard-pullback :
{l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3}
(f : A → X) (g : B → X) →
standard-pullback f g ≃ standard-pullback g f
pr1 (commutative-standard-pullback f g) =
map-commutative-standard-pullback f g
pr2 (commutative-standard-pullback f g) =
is-equiv-map-commutative-standard-pullback f g
```
#### The gap map of the swapped cone computes as the underlying gap map followed by a swap
```agda
triangle-map-commutative-standard-pullback :
{l1 l2 l3 l4 : Level} {A : UU l1} {B : UU l2} {X : UU l3} {C : UU l4}
(f : A → X) (g : B → X) (c : cone f g C) →
gap g f (swap-cone f g c) ~
map-commutative-standard-pullback f g ∘ gap f g c
triangle-map-commutative-standard-pullback f g c = refl-htpy
```
### Standard pullbacks are associative
Consider two cospans with a shared vertex `B`:
```text
f g h i
A ----> X <---- B ----> Y <---- C,
```
then we can construct their limit using standard pullbacks in two equivalent
ways. We can construct it by first forming the standard pullback of `f` and `g`,
and then forming the standard pullback of the resulting `h ∘ f'` and `i`
```text
(A ×_X B) ×_Y C ---------------------> C
| ⌟ |
| | i
∨ ∨
A ×_X B ---------> B ------------> Y
| ⌟ f' | h
| | g
∨ ∨
A ------------> X,
f
```
or we can first form the pullback of `h` and `i`, and then form the pullback of
`f` and the resulting `g ∘ i'`:
```text
A ×_X (B ×_Y C) --> B ×_Y C ---------> C
| ⌟ | ⌟ |
| | i' | i
| ∨ ∨
| B ------------> Y
| | h
| | g
∨ ∨
A ------------> X.
f
```
We show that both of these constructions are equivalent by showing they are
equivalent to the standard ternary pullback.
**Note:** Associativity with respect to ternary cospans
```text
B
|
| g
∨
A ------> X <------ C
f h
```
is a special case of what we consider here that is recovered by using
```text
f g g h
A ----> X <---- B ----> X <---- C.
```
- See also the following relevant stack exchange question:
[Associativity of pullbacks](https://math.stackexchange.com/questions/2046276/associativity-of-pullbacks).
#### Computing the left associated iterated standard pullback
```agda
module _
{l1 l2 l3 l4 l5 : Level}
{X : UU l1} {Y : UU l2} {A : UU l3} {B : UU l4} {C : UU l5}
(f : A → X) (g : B → X) (h : B → Y) (i : C → Y)
where
map-left-associative-standard-pullback :
standard-pullback (h ∘ horizontal-map-standard-pullback {f = f} {g = g}) i →
standard-ternary-pullback f g h i
map-left-associative-standard-pullback ((a , b , p) , c , q) =
( a , b , c , p , q)
map-inv-left-associative-standard-pullback :
standard-ternary-pullback f g h i →
standard-pullback (h ∘ horizontal-map-standard-pullback {f = f} {g = g}) i
map-inv-left-associative-standard-pullback (a , b , c , p , q) =
( ( a , b , p) , c , q)
is-equiv-map-left-associative-standard-pullback :
is-equiv map-left-associative-standard-pullback
is-equiv-map-left-associative-standard-pullback =
is-equiv-is-invertible
( map-inv-left-associative-standard-pullback)
( refl-htpy)
( refl-htpy)
compute-left-associative-standard-pullback :
standard-pullback (h ∘ horizontal-map-standard-pullback {f = f} {g = g}) i ≃
standard-ternary-pullback f g h i
compute-left-associative-standard-pullback =
( map-left-associative-standard-pullback ,
is-equiv-map-left-associative-standard-pullback)
```
#### Computing the right associated iterated dependent pullback
```agda
module _
{l1 l2 l3 l4 l5 : Level}
{X : UU l1} {Y : UU l2} {A : UU l3} {B : UU l4} {C : UU l5}
(f : A → X) (g : B → X) (h : B → Y) (i : C → Y)
where
map-right-associative-standard-pullback :
standard-pullback f (g ∘ vertical-map-standard-pullback {f = h} {g = i}) →
standard-ternary-pullback f g h i
map-right-associative-standard-pullback (a , (b , c , p) , q) =
( a , b , c , q , p)
map-inv-right-associative-standard-pullback :
standard-ternary-pullback f g h i →
standard-pullback f (g ∘ vertical-map-standard-pullback {f = h} {g = i})
map-inv-right-associative-standard-pullback (a , b , c , p , q) =
( a , (b , c , q) , p)
is-equiv-map-right-associative-standard-pullback :
is-equiv map-right-associative-standard-pullback
is-equiv-map-right-associative-standard-pullback =
is-equiv-is-invertible
( map-inv-right-associative-standard-pullback)
( refl-htpy)
( refl-htpy)
compute-right-associative-standard-pullback :
standard-pullback f (g ∘ vertical-map-standard-pullback {f = h} {g = i}) ≃
standard-ternary-pullback f g h i
compute-right-associative-standard-pullback =
( map-right-associative-standard-pullback ,
is-equiv-map-right-associative-standard-pullback)
```
#### Standard pullbacks are associative
```agda
module _
{l1 l2 l3 l4 l5 : Level}
{X : UU l1} {Y : UU l2} {A : UU l3} {B : UU l4} {C : UU l5}
(f : A → X) (g : B → X) (h : B → Y) (i : C → Y)
where
associative-standard-pullback :
standard-pullback (h ∘ horizontal-map-standard-pullback {f = f} {g = g}) i ≃
standard-pullback f (g ∘ vertical-map-standard-pullback {f = h} {g = i})
associative-standard-pullback =
( inv-equiv (compute-right-associative-standard-pullback f g h i)) ∘e
( compute-left-associative-standard-pullback f g h i)
map-associative-standard-pullback :
standard-pullback (h ∘ horizontal-map-standard-pullback {f = f} {g = g}) i →
standard-pullback f (g ∘ vertical-map-standard-pullback {f = h} {g = i})
map-associative-standard-pullback = map-equiv associative-standard-pullback
map-inv-associative-standard-pullback :
standard-pullback f (g ∘ vertical-map-standard-pullback {f = h} {g = i}) →
standard-pullback (h ∘ horizontal-map-standard-pullback {f = f} {g = g}) i
map-inv-associative-standard-pullback =
map-inv-equiv associative-standard-pullback
```
### Pullbacks can be "folded"
Given a standard pullback square
```text
f'
C -------> B
| ⌟ |
g'| | g
∨ ∨
A -------> X
f
```
we can "fold" the vertical edge onto the horizontal one and get a new pullback
square
```text
C ---------> X
| ⌟ |
(f' , g') | |
∨ ∨
A × B -----> X × X,
f × g
```
moreover, this folded square is a pullback if and only if the original one is.
```agda
module _
{l1 l2 l3 : Level}
{A : UU l1} {B : UU l2} {X : UU l3}
(f : A → X) (g : B → X)
where
fold-cone :
{l4 : Level} {C : UU l4} →
cone f g C → cone (map-product f g) (diagonal-product X) C
pr1 (pr1 (fold-cone c) z) = vertical-map-cone f g c z
pr2 (pr1 (fold-cone c) z) = horizontal-map-cone f g c z
pr1 (pr2 (fold-cone c)) = g ∘ horizontal-map-cone f g c
pr2 (pr2 (fold-cone c)) z = eq-pair (coherence-square-cone f g c z) refl
map-fold-cone-standard-pullback :
standard-pullback f g →
standard-pullback (map-product f g) (diagonal-product X)
pr1 (pr1 (map-fold-cone-standard-pullback x)) =
vertical-map-standard-pullback x
pr2 (pr1 (map-fold-cone-standard-pullback x)) =
horizontal-map-standard-pullback x
pr1 (pr2 (map-fold-cone-standard-pullback x)) =
g (horizontal-map-standard-pullback x)
pr2 (pr2 (map-fold-cone-standard-pullback x)) =
eq-pair (coherence-square-standard-pullback x) refl
map-inv-fold-cone-standard-pullback :
standard-pullback (map-product f g) (diagonal-product X) →
standard-pullback f g
pr1 (map-inv-fold-cone-standard-pullback ((a , b) , x , α)) = a
pr1 (pr2 (map-inv-fold-cone-standard-pullback ((a , b) , x , α))) = b
pr2 (pr2 (map-inv-fold-cone-standard-pullback ((a , b) , x , α))) =
ap pr1 α ∙ inv (ap pr2 α)
abstract
is-section-map-inv-fold-cone-standard-pullback :
is-section
( map-fold-cone-standard-pullback)
( map-inv-fold-cone-standard-pullback)
is-section-map-inv-fold-cone-standard-pullback ((a , b) , (x , α)) =
map-extensionality-standard-pullback
( map-product f g)
( diagonal-product X)
( refl)
( ap pr2 α)
( ( inv (is-section-pair-eq α)) ∙
( ap
( λ t → eq-pair t (ap pr2 α))
( ( inv right-unit) ∙
( inv
( left-whisker-concat
( ap pr1 α)
( left-inv (ap pr2 α)))) ∙
( inv (assoc (ap pr1 α) (inv (ap pr2 α)) (ap pr2 α))))) ∙
( eq-pair-concat
( ap pr1 α ∙ inv (ap pr2 α))
( ap pr2 α)
( refl)
( ap pr2 α)) ∙
( ap
( concat (eq-pair (ap pr1 α ∙ inv (ap pr2 α)) refl) (x , x))
( inv (compute-ap-diagonal-product (ap pr2 α)))))
abstract
is-retraction-map-inv-fold-cone-standard-pullback :
is-retraction
( map-fold-cone-standard-pullback)
( map-inv-fold-cone-standard-pullback)
is-retraction-map-inv-fold-cone-standard-pullback (a , b , p) =
map-extensionality-standard-pullback f g
( refl)
( refl)
( inv
( ( right-whisker-concat
( ( right-whisker-concat
( ap-pr1-eq-pair p refl)
( inv (ap pr2 (eq-pair p refl)))) ∙
( ap (λ t → p ∙ inv t) (ap-pr2-eq-pair p refl)) ∙
( right-unit))
( refl)) ∙
( right-unit)))
abstract
is-equiv-map-fold-cone-standard-pullback :
is-equiv map-fold-cone-standard-pullback
is-equiv-map-fold-cone-standard-pullback =
is-equiv-is-invertible
( map-inv-fold-cone-standard-pullback)
( is-section-map-inv-fold-cone-standard-pullback)
( is-retraction-map-inv-fold-cone-standard-pullback)
compute-fold-standard-pullback :
standard-pullback f g ≃
standard-pullback (map-product f g) (diagonal-product X)
compute-fold-standard-pullback =
map-fold-cone-standard-pullback , is-equiv-map-fold-cone-standard-pullback
triangle-map-fold-cone-standard-pullback :
{l4 : Level} {C : UU l4} (c : cone f g C) →
gap (map-product f g) (diagonal-product X) (fold-cone c) ~
map-fold-cone-standard-pullback ∘ gap f g c
triangle-map-fold-cone-standard-pullback c = refl-htpy
```
### The equivalence on standard pullbacks induced by parallel cospans
```agda
module _
{l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3}
{f f' : A → X} (Hf : f ~ f') {g g' : B → X} (Hg : g ~ g')
where
map-equiv-standard-pullback-htpy :
standard-pullback f' g' → standard-pullback f g
map-equiv-standard-pullback-htpy =
tot (λ a → tot (λ b → concat' (f a) (inv (Hg b)) ∘ concat (Hf a) (g' b)))
abstract
is-equiv-map-equiv-standard-pullback-htpy :
is-equiv map-equiv-standard-pullback-htpy
is-equiv-map-equiv-standard-pullback-htpy =
is-equiv-tot-is-fiberwise-equiv
( λ a →
is-equiv-tot-is-fiberwise-equiv
( λ b →
is-equiv-comp
( concat' (f a) (inv (Hg b)))
( concat (Hf a) (g' b))
( is-equiv-concat (Hf a) (g' b))
( is-equiv-concat' (f a) (inv (Hg b)))))
equiv-standard-pullback-htpy :
standard-pullback f' g' ≃ standard-pullback f g
pr1 equiv-standard-pullback-htpy = map-equiv-standard-pullback-htpy
pr2 equiv-standard-pullback-htpy = is-equiv-map-equiv-standard-pullback-htpy
```
## Table of files about pullbacks
The following table lists files that are about pullbacks as a general concept.
{{#include tables/pullbacks.md}}