# 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}}