# Pullbacks
```agda
module foundation.pullbacks where
open import foundation-core.pullbacks public
```
<details><summary>Imports</summary>
```agda
open import foundation.action-on-identifications-functions
open import foundation.commuting-cubes-of-maps
open import foundation.cones-over-cospan-diagrams
open import foundation.dependent-pair-types
open import foundation.dependent-sums-pullbacks
open import foundation.descent-equivalences
open import foundation.equivalences
open import foundation.function-extensionality
open import foundation.functoriality-coproduct-types
open import foundation.functoriality-function-types
open import foundation.standard-pullbacks
open import foundation.unit-type
open import foundation.universe-levels
open import foundation.whiskering-homotopies-composition
open import foundation-core.cartesian-product-types
open import foundation-core.constant-maps
open import foundation-core.contractible-types
open import foundation-core.diagonal-maps-cartesian-products-of-types
open import foundation-core.equality-dependent-pair-types
open import foundation-core.function-types
open import foundation-core.functoriality-dependent-function-types
open import foundation-core.functoriality-dependent-pair-types
open import foundation-core.homotopies
open import foundation-core.identity-types
open import foundation-core.postcomposition-functions
open import foundation-core.propositions
open import foundation-core.retractions
open import foundation-core.sections
open import foundation-core.torsorial-type-families
open import foundation-core.transport-along-identifications
open import foundation-core.whiskering-identifications-concatenation
```
</details>
## Idea
Consider a [cone](foundation.cones-over-cospan-diagrams.md) over a
[cospan diagram of types](foundation.cospan-diagrams.md) `f : A -> X <- B : g,`
```text
C ------> B
| |
| | g
∨ ∨
A ------> X.
f
```
we want to pose the question of whether this cone is a
{{#concept "pullback cone" Disambiguation="types" Agda=is-pullback}}. Although
this concept is captured by
[the universal property of the pullback](foundation-core.universal-property-pullbacks.md),
this is a large proposition, which is not suitable for all purposes. Therefore,
as our main definition of a pullback cone we consider the
{{#concept "small predicate of being a pullback" Agda=is-pullback}}: given the
existence of the [standard pullback type](foundation.standard-pullbacks.md)
`A ×_X B`, a cone is a _pullback_ if the gap map into the standard pullback is
an [equivalence](foundation-core.equivalences.md).
## Properties
### Being a pullback is a property
```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
is-prop-is-pullback : (c : cone f g C) → is-prop (is-pullback f g c)
is-prop-is-pullback c = is-property-is-equiv (gap f g c)
is-pullback-Prop : (c : cone f g C) → Prop (l1 ⊔ l2 ⊔ l3 ⊔ l4)
pr1 (is-pullback-Prop c) = is-pullback f g c
pr2 (is-pullback-Prop c) = is-prop-is-pullback c
```
### In a commuting cube where the front faces are pullbacks, either back face is a pullback iff the other back face is
```agda
module _
{l1 l2 l3 l4 l1' l2' l3' l4' : Level}
{A : UU l1} {B : UU l2} {C : UU l3} {D : UU l4}
{f : A → B} {g : A → C} {h : B → D} {k : C → D}
{A' : UU l1'} {B' : UU l2'} {C' : UU l3'} {D' : UU l4'}
{f' : A' → B'} {g' : A' → C'} {h' : B' → D'} {k' : C' → D'}
{hA : A' → A} {hB : B' → B} {hC : C' → C} {hD : D' → D}
(top : h' ∘ f' ~ k' ∘ g')
(back-left : f ∘ hA ~ hB ∘ f')
(back-right : g ∘ hA ~ hC ∘ g')
(front-left : h ∘ hB ~ hD ∘ h')
(front-right : k ∘ hC ~ hD ∘ k')
(bottom : h ∘ f ~ k ∘ g)
(c :
coherence-cube-maps
f g h k f' g' h' k' hA hB hC hD
top back-left back-right front-left front-right bottom)
where
is-pullback-back-left-is-pullback-back-right-cube :
is-pullback h hD (hB , h' , front-left) →
is-pullback k hD (hC , k' , front-right) →
is-pullback g hC (hA , g' , back-right) →
is-pullback f hB (hA , f' , back-left)
is-pullback-back-left-is-pullback-back-right-cube
is-pb-front-left is-pb-front-right is-pb-back-right =
is-pullback-left-square-is-pullback-rectangle f h hD
( hB , h' , front-left)
( hA , f' , back-left)
( is-pb-front-left)
( is-pullback-htpy
( bottom)
( refl-htpy)
( triple
( hA)
( k' ∘ g')
( rectangle-right-cube
f g h k f' g' h' k' hA hB hC hD
top back-left back-right front-left front-right bottom))
( triple
( refl-htpy)
( top)
( coherence-htpy-parallel-cone-rectangle-left-rectangle-right-cube
f g h k f' g' h' k' hA hB hC hD
top back-left back-right front-left front-right bottom c))
( is-pullback-rectangle-is-pullback-left-square g k hD
( hC , k' , front-right)
( hA , g' , back-right)
( is-pb-front-right)
( is-pb-back-right)))
is-pullback-back-right-is-pullback-back-left-cube :
is-pullback h hD (hB , h' , front-left) →
is-pullback k hD (hC , k' , front-right) →
is-pullback f hB (hA , f' , back-left) →
is-pullback g hC (hA , g' , back-right)
is-pullback-back-right-is-pullback-back-left-cube
is-pb-front-left is-pb-front-right is-pb-back-left =
is-pullback-left-square-is-pullback-rectangle g k hD
( hC , k' , front-right)
( hA , g' , back-right)
( is-pb-front-right)
( is-pullback-htpy'
( bottom)
( refl-htpy)
( triple
( hA)
( h' ∘ f')
( rectangle-left-cube
f g h k f' g' h' k' hA hB hC hD
top back-left back-right front-left front-right bottom))
( triple
( refl-htpy)
( top)
( coherence-htpy-parallel-cone-rectangle-left-rectangle-right-cube
f g h k f' g' h' k' hA hB hC hD
top back-left back-right front-left front-right bottom c))
( is-pullback-rectangle-is-pullback-left-square f h hD
( hB , h' , front-left)
( hA , f' , back-left)
( is-pb-front-left)
( is-pb-back-left)))
```
### In a commuting cube where the vertical maps are equivalences, the bottom square is a pullback if and only if the top square is a pullback
```agda
module _
{l1 l2 l3 l4 l1' l2' l3' l4' : Level}
{A : UU l1} {B : UU l2} {C : UU l3} {D : UU l4}
(f : A → B) (g : A → C) (h : B → D) (k : C → D)
{A' : UU l1'} {B' : UU l2'} {C' : UU l3'} {D' : UU l4'}
(f' : A' → B') (g' : A' → C') (h' : B' → D') (k' : C' → D')
(hA : A' → A) (hB : B' → B) (hC : C' → C) (hD : D' → D)
(top : h' ∘ f' ~ k' ∘ g')
(back-left : f ∘ hA ~ hB ∘ f')
(back-right : g ∘ hA ~ hC ∘ g')
(front-left : h ∘ hB ~ hD ∘ h')
(front-right : k ∘ hC ~ hD ∘ k')
(bottom : h ∘ f ~ k ∘ g)
(c :
coherence-cube-maps
f g h k f' g' h' k' hA hB hC hD
top back-left back-right front-left front-right bottom)
where
is-pullback-bottom-is-pullback-top-cube-is-equiv :
is-equiv hA → is-equiv hB → is-equiv hC → is-equiv hD →
is-pullback h' k' (f' , g' , top) →
is-pullback h k (f , g , bottom)
is-pullback-bottom-is-pullback-top-cube-is-equiv
is-equiv-hA is-equiv-hB is-equiv-hC is-equiv-hD is-pb-top =
descent-is-equiv hB h k
( f , g , bottom)
( f' , hA , inv-htpy (back-left))
( is-equiv-hB)
( is-equiv-hA)
( is-pullback-htpy
( front-left)
( refl-htpy' k)
( triple
( f')
( hC ∘ g')
( rectangle-top-front-right-cube
f g h k f' g' h' k' hA hB hC hD
top back-left back-right front-left front-right bottom))
( triple
( refl-htpy' f')
( back-right)
( coherence-htpy-parallel-cone-coherence-cube-maps
f g h k f' g' h' k' hA hB hC hD
top back-left back-right front-left front-right bottom c))
( is-pullback-rectangle-is-pullback-left-square
( h')
( hD)
( k)
( k' , hC , inv-htpy front-right)
( f' , g' , top)
( is-pullback-is-equiv-horizontal-maps hD k
( k' , hC , inv-htpy front-right)
( is-equiv-hD)
( is-equiv-hC))
( is-pb-top)))
is-pullback-top-is-pullback-bottom-cube-is-equiv :
is-equiv hA → is-equiv hB → is-equiv hC → is-equiv hD →
is-pullback h k (f , g , bottom) →
is-pullback h' k' (f' , g' , top)
is-pullback-top-is-pullback-bottom-cube-is-equiv
is-equiv-hA is-equiv-hB is-equiv-hC is-equiv-hD is-pb-bottom =
is-pullback-top-square-is-pullback-rectangle h hD k'
( hB , h' , front-left)
( f' , g' , top)
( is-pullback-is-equiv-vertical-maps h hD
( hB , h' , front-left)
is-equiv-hD is-equiv-hB)
( is-pullback-htpy' refl-htpy front-right
( pasting-vertical-cone h k hC
( f , g , bottom)
( hA , g' , back-right))
( triple
( back-left)
( refl-htpy)
( ( assoc-htpy
( bottom ·r hA)
( k ·l back-right)
( front-right ·r g')) ∙h
( inv-htpy c) ∙h
( assoc-htpy (h ·l back-left) (front-left ·r f') (hD ·l top)) ∙h
( ap-concat-htpy'
( (front-left ·r f') ∙h (hD ·l top))
( inv-htpy-right-unit-htpy {H = h ·l back-left}))))
( is-pullback-rectangle-is-pullback-top-square h k hC
( f , g , bottom)
( hA , g' , back-right)
( is-pb-bottom)
( is-pullback-is-equiv-vertical-maps g hC
( hA , g' , back-right)
is-equiv-hC is-equiv-hA)))
```
### In a commuting cube where the maps from back-right to front-left are equivalences, the back-right square is a pullback if and only if the front-left square is a pullback
```agda
module _
{l1 l2 l3 l4 l1' l2' l3' l4' : Level}
{A : UU l1} {B : UU l2} {C : UU l3} {D : UU l4}
(f : A → B) (g : A → C) (h : B → D) (k : C → D)
{A' : UU l1'} {B' : UU l2'} {C' : UU l3'} {D' : UU l4'}
(f' : A' → B') (g' : A' → C') (h' : B' → D') (k' : C' → D')
(hA : A' → A) (hB : B' → B) (hC : C' → C) (hD : D' → D)
(top : h' ∘ f' ~ k' ∘ g')
(back-left : f ∘ hA ~ hB ∘ f')
(back-right : g ∘ hA ~ hC ∘ g')
(front-left : h ∘ hB ~ hD ∘ h')
(front-right : k ∘ hC ~ hD ∘ k')
(bottom : h ∘ f ~ k ∘ g)
(c :
coherence-cube-maps
f g h k f' g' h' k' hA hB hC hD
top back-left back-right front-left front-right bottom)
where
is-pullback-front-left-is-pullback-back-right-cube-is-equiv :
is-equiv f' → is-equiv f → is-equiv k' → is-equiv k →
is-pullback g hC (hA , g' , back-right) →
is-pullback h hD (hB , h' , front-left)
is-pullback-front-left-is-pullback-back-right-cube-is-equiv
is-equiv-f' is-equiv-f is-equiv-k' is-equiv-k is-pb-back-right =
is-pullback-bottom-is-pullback-top-cube-is-equiv
hB h' h hD hA g' g hC f' f k' k
back-right (inv-htpy back-left) top bottom (inv-htpy front-right)
( front-left)
( coherence-cube-maps-mirror-B f g h k f' g' h' k' hA hB hC hD top
back-left back-right front-left front-right bottom c)
is-equiv-f' is-equiv-f is-equiv-k' is-equiv-k is-pb-back-right
is-pullback-front-right-is-pullback-back-left-cube-is-equiv :
is-equiv g' → is-equiv h' → is-equiv g → is-equiv h →
is-pullback f hB (hA , f' , back-left) →
is-pullback k hD (hC , k' , front-right)
is-pullback-front-right-is-pullback-back-left-cube-is-equiv
is-equiv-g' is-equiv-h' is-equiv-g is-equiv-h is-pb-back-left =
is-pullback-bottom-is-pullback-top-cube-is-equiv
hC k' k hD hA f' f hB g' g h' h
back-left (inv-htpy back-right) (inv-htpy top)
( inv-htpy bottom) (inv-htpy front-left) front-right
( coherence-cube-maps-rotate-120 f g h k f' g' h' k' hA hB hC hD
top back-left back-right front-left front-right bottom c)
is-equiv-g' is-equiv-g is-equiv-h' is-equiv-h is-pb-back-left
```
### Identity types commute with pullbacks
Given a pullback square
```text
f'
C -------> B
| ⌟ |
g'| | g
∨ ∨
A -------> X
f
```
and two elements `u` and `v` of `C`, then the induced square
```text
ap f'
(u = v) --------> (f' u = f' v)
| |
ap g' | |
∨ ∨
(g' u = g' v) -> (f (g' u) = g (f' v))
```
is also a 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) (c : cone f g C)
where
cone-ap :
(u v : C) →
cone
( λ (α : vertical-map-cone f g c u = vertical-map-cone f g c v) →
ap f α ∙ coherence-square-cone f g c v)
( λ (β : horizontal-map-cone f g c u = horizontal-map-cone f g c v) →
coherence-square-cone f g c u ∙ ap g β)
( u = v)
pr1 (cone-ap u v) = ap (vertical-map-cone f g c)
pr1 (pr2 (cone-ap u v)) = ap (horizontal-map-cone f g c)
pr2 (pr2 (cone-ap u v)) γ =
( right-whisker-concat
( inv (ap-comp f (vertical-map-cone f g c) γ))
( coherence-square-cone f g c v)) ∙
( ( inv-nat-htpy (coherence-square-cone f g c) γ) ∙
( left-whisker-concat
( coherence-square-cone f g c u)
( ap-comp g (horizontal-map-cone f g c) γ)))
cone-ap' :
(u v : C) →
cone
( λ (α : vertical-map-cone f g c u = vertical-map-cone f g c v) →
tr
( f (vertical-map-cone f g c u) =_)
( coherence-square-cone f g c v)
( ap f α))
( λ (β : horizontal-map-cone f g c u = horizontal-map-cone f g c v) →
coherence-square-cone f g c u ∙ ap g β)
( u = v)
pr1 (cone-ap' u v) = ap (vertical-map-cone f g c)
pr1 (pr2 (cone-ap' u v)) = ap (horizontal-map-cone f g c)
pr2 (pr2 (cone-ap' u v)) γ =
( tr-Id-right
( coherence-square-cone f g c v)
( ap f (ap (vertical-map-cone f g c) γ))) ∙
( ( right-whisker-concat
( inv (ap-comp f (vertical-map-cone f g c) γ))
( coherence-square-cone f g c v)) ∙
( ( inv-nat-htpy (coherence-square-cone f g c) γ) ∙
( left-whisker-concat
( coherence-square-cone f g c u)
( ap-comp g (horizontal-map-cone f g c) γ))))
abstract
is-pullback-cone-ap :
is-pullback f g c →
(u v : C) →
is-pullback
( λ (α : vertical-map-cone f g c u = vertical-map-cone f g c v) →
ap f α ∙ coherence-square-cone f g c v)
( λ (β : horizontal-map-cone f g c u = horizontal-map-cone f g c v) →
coherence-square-cone f g c u ∙ ap g β)
( cone-ap u v)
is-pullback-cone-ap is-pb-c u v =
is-pullback-htpy'
( λ α → tr-Id-right (coherence-square-cone f g c v) (ap f α))
( refl-htpy)
( cone-ap' u v)
( refl-htpy , refl-htpy , right-unit-htpy)
( is-pullback-family-is-pullback-tot
( f (vertical-map-cone f g c u) =_)
( λ a → ap f {x = vertical-map-cone f g c u} {y = a})
( λ b β → coherence-square-cone f g c u ∙ ap g β)
( c)
( cone-ap' u)
( is-pb-c)
( is-pullback-is-equiv-vertical-maps
( map-Σ _ f (λ a α → ap f α))
( map-Σ _ g (λ b β → coherence-square-cone f g c u ∙ ap g β))
( tot-cone-cone-family
( f (vertical-map-cone f g c u) =_)
( λ a → ap f)
( λ b β → coherence-square-cone f g c u ∙ ap g β)
( c)
( cone-ap' u))
( is-equiv-is-contr _
( is-torsorial-Id (horizontal-map-cone f g c u))
( is-torsorial-Id (f (vertical-map-cone f g c u))))
( is-equiv-is-contr _
( is-torsorial-Id u)
( is-torsorial-Id (vertical-map-cone f g c u))))
( v))
```
## Table of files about pullbacks
The following table lists files that are about pullbacks as a general concept.
{{#include tables/pullbacks.md}}