File: Mathlib/CategoryTheory/Limits/Shapes/Diagonal.lean

full_name: CategoryTheory.Limits.pullback.diagonalObj
code: /-- The diagonal object of a morphism `f : X ⟶ Y` is `Δ_{X/Y} := pullback f f`. -/
abbrev diagonalObj : C 
goal: C

full_name: CategoryTheory.Limits.pullback.diagonal
code: /-- The diagonal morphism `X ⟶ Δ_{X/Y}` for a morphism `f : X ⟶ Y`. -/
def diagonal : X ⟶ diagonalObj f 
goal: X ⟶ CategoryTheory.Limits.pullback.diagonalObj f

full_name: CategoryTheory.Limits.pullback.diagonal_fst
code: @[reassoc (attr := simp)]
theorem diagonal_fst : diagonal f ≫ pullback.fst _ _ = 𝟙 _ 
goal: CategoryTheory.Limits.pullback.diagonal f ≫ CategoryTheory.Limits.pullback.fst f f = 𝟙 X

full_name: CategoryTheory.Limits.pullback.diagonal_snd
code: @[reassoc (attr := simp)]
theorem diagonal_snd : diagonal f ≫ pullback.snd _ _ = 𝟙 _ 
goal: CategoryTheory.Limits.pullback.diagonal f ≫ CategoryTheory.Limits.pullback.snd f f = 𝟙 X

full_name: CategoryTheory.Limits.pullback.instIsSplitMonoDiagonal
code: instance : IsSplitMono (diagonal f) 
goal: CategoryTheory.IsSplitMono (CategoryTheory.Limits.pullback.diagonal f)

full_name: CategoryTheory.Limits.pullback.instIsSplitEpiFst
code: instance : IsSplitEpi (pullback.fst f f) 
goal: CategoryTheory.IsSplitEpi (CategoryTheory.Limits.pullback.fst f f)

full_name: CategoryTheory.Limits.pullback.instIsSplitEpiSnd
code: instance : IsSplitEpi (pullback.snd f f) 
goal: CategoryTheory.IsSplitEpi (CategoryTheory.Limits.pullback.snd f f)

full_name: CategoryTheory.Limits.pullback.instIsIsoDiagonalOfMono
code: instance [Mono f] : IsIso (diagonal f) 
goal: CategoryTheory.IsIso (CategoryTheory.Limits.pullback.diagonal f)

full_name: CategoryTheory.Limits.pullback.diagonal_isKernelPair
code: /-- The two projections `Δ_{X/Y} ⟶ X` form a kernel pair for `f : X ⟶ Y`. -/
theorem diagonal_isKernelPair : IsKernelPair f (pullback.fst f f) (pullback.snd f f) 
goal: CategoryTheory.IsKernelPair f (CategoryTheory.Limits.pullback.fst f f) (CategoryTheory.Limits.pullback.snd f f)

full_name: CategoryTheory.Limits.pullback_diagonal_map_snd_fst_fst
code: @[reassoc (attr := simp)]
theorem pullback_diagonal_map_snd_fst_fst :
    (pullback.snd (diagonal f)
      (map (i₁ ≫ snd f i) (i₂ ≫ snd f i) f f (i₁ ≫ fst f i) (i₂ ≫ fst f i) i
        (by simp [condition]) (by simp [condition]))) ≫
      fst _ _ ≫ i₁ ≫ fst _ _ =
      pullback.fst _ _ 
goal: CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.diagonal f)
      (CategoryTheory.Limits.pullback.map (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
        (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) f f (i₁ ≫ CategoryTheory.Limits.pullback.fst f i)
        (i₂ ≫ CategoryTheory.Limits.pullback.fst f i) i ⋯ ⋯) ≫
    CategoryTheory.Limits.pullback.fst (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
        (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) ≫
      i₁ ≫ CategoryTheory.Limits.pullback.fst f i =
  CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.diagonal f)
    (CategoryTheory.Limits.pullback.map (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
      (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) f f (i₁ ≫ CategoryTheory.Limits.pullback.fst f i)
      (i₂ ≫ CategoryTheory.Limits.pullback.fst f i) i ⋯ ⋯)

full_name: CategoryTheory.Limits.pullback_diagonal_map_snd_snd_fst
code: @[reassoc (attr := simp)]
theorem pullback_diagonal_map_snd_snd_fst :
    (pullback.snd (diagonal f)
      (map (i₁ ≫ snd f i) (i₂ ≫ snd f i) f f (i₁ ≫ fst f i) (i₂ ≫ fst f i) i
        (by simp [condition]) (by simp [condition]))) ≫
      snd _ _ ≫ i₂ ≫ fst _ _ =
      pullback.fst _ _ 
goal: CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.diagonal f)
      (CategoryTheory.Limits.pullback.map (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
        (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) f f (i₁ ≫ CategoryTheory.Limits.pullback.fst f i)
        (i₂ ≫ CategoryTheory.Limits.pullback.fst f i) i ⋯ ⋯) ≫
    CategoryTheory.Limits.pullback.snd (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
        (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) ≫
      i₂ ≫ CategoryTheory.Limits.pullback.fst f i =
  CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.diagonal f)
    (CategoryTheory.Limits.pullback.map (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
      (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) f f (i₁ ≫ CategoryTheory.Limits.pullback.fst f i)
      (i₂ ≫ CategoryTheory.Limits.pullback.fst f i) i ⋯ ⋯)

full_name: CategoryTheory.Limits.pullbackDiagonalMapIso
code: /-- This iso witnesses the fact that
given `f : X ⟶ Y`, `i : U ⟶ Y`, and `i₁ : V₁ ⟶ X ×[Y] U`, `i₂ : V₂ ⟶ X ×[Y] U`, the diagram

```
V₁ ×[X ×[Y] U] V₂ ⟶ V₁ ×[U] V₂
        |                 |
        |                 |
        ↓                 ↓
        X         ⟶   X ×[Y] X
```

is a pullback square.
Also see `pullback_fst_map_snd_isPullback`.
-/
def pullbackDiagonalMapIso :
    pullback (diagonal f)
        (map (i₁ ≫ snd _ _) (i₂ ≫ snd _ _) f f (i₁ ≫ fst _ _) (i₂ ≫ fst _ _) i
          (by simp only [Category.assoc, condition])
          (by simp only [Category.assoc, condition])) ≅
      pullback i₁ i₂ 
goal: CategoryTheory.Limits.pullback (CategoryTheory.Limits.pullback.diagonal f)
    (CategoryTheory.Limits.pullback.map (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
      (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) f f (i₁ ≫ CategoryTheory.Limits.pullback.fst f i)
      (i₂ ≫ CategoryTheory.Limits.pullback.fst f i) i ⋯ ⋯) ≅
  CategoryTheory.Limits.pullback i₁ i₂

full_name: CategoryTheory.Limits.pullbackDiagonalMapIso_hom_fst
code: @[reassoc (attr := simp)]
theorem pullbackDiagonalMapIso_hom_fst :
    (pullbackDiagonalMapIso f i i₁ i₂).hom ≫ pullback.fst _ _ =
      pullback.snd _ _ ≫ pullback.fst _ _ 
goal: (CategoryTheory.Limits.pullbackDiagonalMapIso f i i₁ i₂).hom ≫ CategoryTheory.Limits.pullback.fst i₁ i₂ =
  CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.diagonal f)
      (CategoryTheory.Limits.pullback.map (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
        (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) f f (i₁ ≫ CategoryTheory.Limits.pullback.fst f i)
        (i₂ ≫ CategoryTheory.Limits.pullback.fst f i) i ⋯ ⋯) ≫
    CategoryTheory.Limits.pullback.fst (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
      (i₂ ≫ CategoryTheory.Limits.pullback.snd f i)

full_name: CategoryTheory.Limits.pullbackDiagonalMapIso_hom_snd
code: @[reassoc (attr := simp)]
theorem pullbackDiagonalMapIso_hom_snd :
    (pullbackDiagonalMapIso f i i₁ i₂).hom ≫ pullback.snd _ _ =
      pullback.snd _ _ ≫ pullback.snd _ _ 
goal: (CategoryTheory.Limits.pullbackDiagonalMapIso f i i₁ i₂).hom ≫ CategoryTheory.Limits.pullback.snd i₁ i₂ =
  CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.diagonal f)
      (CategoryTheory.Limits.pullback.map (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
        (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) f f (i₁ ≫ CategoryTheory.Limits.pullback.fst f i)
        (i₂ ≫ CategoryTheory.Limits.pullback.fst f i) i ⋯ ⋯) ≫
    CategoryTheory.Limits.pullback.snd (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
      (i₂ ≫ CategoryTheory.Limits.pullback.snd f i)

full_name: CategoryTheory.Limits.pullbackDiagonalMapIso_inv_fst
code: @[reassoc (attr := simp)]
theorem pullbackDiagonalMapIso_inv_fst :
    (pullbackDiagonalMapIso f i i₁ i₂).inv ≫ pullback.fst _ _ =
      pullback.fst _ _ ≫ i₁ ≫ pullback.fst _ _ 
goal: (CategoryTheory.Limits.pullbackDiagonalMapIso f i i₁ i₂).inv ≫
    CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.diagonal f)
      (CategoryTheory.Limits.pullback.map (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
        (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) f f (i₁ ≫ CategoryTheory.Limits.pullback.fst f i)
        (i₂ ≫ CategoryTheory.Limits.pullback.fst f i) i ⋯ ⋯) =
  CategoryTheory.Limits.pullback.fst i₁ i₂ ≫ i₁ ≫ CategoryTheory.Limits.pullback.fst f i

full_name: CategoryTheory.Limits.pullbackDiagonalMapIso_inv_snd_fst
code: @[reassoc (attr := simp)]
theorem pullbackDiagonalMapIso_inv_snd_fst :
    (pullbackDiagonalMapIso f i i₁ i₂).inv ≫ pullback.snd _ _ ≫ pullback.fst _ _ =
      pullback.fst _ _ 
goal: (CategoryTheory.Limits.pullbackDiagonalMapIso f i i₁ i₂).inv ≫
    CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.diagonal f)
        (CategoryTheory.Limits.pullback.map (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
          (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) f f (i₁ ≫ CategoryTheory.Limits.pullback.fst f i)
          (i₂ ≫ CategoryTheory.Limits.pullback.fst f i) i ⋯ ⋯) ≫
      CategoryTheory.Limits.pullback.fst (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
        (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) =
  CategoryTheory.Limits.pullback.fst i₁ i₂

full_name: CategoryTheory.Limits.pullbackDiagonalMapIso_inv_snd_snd
code: @[reassoc (attr := simp)]
theorem pullbackDiagonalMapIso_inv_snd_snd :
    (pullbackDiagonalMapIso f i i₁ i₂).inv ≫ pullback.snd _ _ ≫ pullback.snd _ _ =
      pullback.snd _ _ 
goal: (CategoryTheory.Limits.pullbackDiagonalMapIso f i i₁ i₂).inv ≫
    CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.diagonal f)
        (CategoryTheory.Limits.pullback.map (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
          (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) f f (i₁ ≫ CategoryTheory.Limits.pullback.fst f i)
          (i₂ ≫ CategoryTheory.Limits.pullback.fst f i) i ⋯ ⋯) ≫
      CategoryTheory.Limits.pullback.snd (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
        (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) =
  CategoryTheory.Limits.pullback.snd i₁ i₂

full_name: CategoryTheory.Limits.pullback_fst_map_snd_isPullback
code: theorem pullback_fst_map_snd_isPullback :
    IsPullback (fst _ _ ≫ i₁ ≫ fst _ _)
      (map i₁ i₂ (i₁ ≫ snd _ _) (i₂ ≫ snd _ _) _ _ _
        (Category.id_comp _).symm (Category.id_comp _).symm)
      (diagonal f)
      (map (i₁ ≫ snd _ _) (i₂ ≫ snd _ _) f f (i₁ ≫ fst _ _) (i₂ ≫ fst _ _) i (by simp [condition])
        (by simp [condition])) 
goal: CategoryTheory.IsPullback (CategoryTheory.Limits.pullback.fst i₁ i₂ ≫ i₁ ≫ CategoryTheory.Limits.pullback.fst f i)
  (CategoryTheory.Limits.pullback.map i₁ i₂ (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
    (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) (𝟙 V₁) (𝟙 V₂) (CategoryTheory.Limits.pullback.snd f i) ⋯ ⋯)
  (CategoryTheory.Limits.pullback.diagonal f)
  (CategoryTheory.Limits.pullback.map (i₁ ≫ CategoryTheory.Limits.pullback.snd f i)
    (i₂ ≫ CategoryTheory.Limits.pullback.snd f i) f f (i₁ ≫ CategoryTheory.Limits.pullback.fst f i)
    (i₂ ≫ CategoryTheory.Limits.pullback.fst f i) i ⋯ ⋯)

full_name: CategoryTheory.Limits.pullbackDiagonalMapIdIso
code: /-- This iso witnesses the fact that
given `f : X ⟶ T`, `g : Y ⟶ T`, and `i : T ⟶ S`, the diagram

```
X ×ₜ Y ⟶ X ×ₛ Y
  |         |
  |         |
  ↓         ↓
  T    ⟶  T ×ₛ T
```

is a pullback square.
Also see `pullback_map_diagonal_isPullback`.
-/
def pullbackDiagonalMapIdIso :
    pullback (diagonal i)
        (pullback.map (f ≫ i) (g ≫ i) i i f g (𝟙 _) (Category.comp_id _) (Category.comp_id _)) ≅
      pullback f g 
goal: CategoryTheory.Limits.pullback (CategoryTheory.Limits.pullback.diagonal i)
    (CategoryTheory.Limits.pullback.map (f ≫ i) (g ≫ i) i i f g (𝟙 S) ⋯ ⋯) ≅
  CategoryTheory.Limits.pullback f g

full_name: CategoryTheory.Limits.pullbackDiagonalMapIdIso_hom_fst
code: @[reassoc (attr := simp)]
theorem pullbackDiagonalMapIdIso_hom_fst :
    (pullbackDiagonalMapIdIso f g i).hom ≫ pullback.fst _ _ =
      pullback.snd _ _ ≫ pullback.fst _ _ 
goal: (CategoryTheory.Limits.pullbackDiagonalMapIdIso f g i).hom ≫ CategoryTheory.Limits.pullback.fst f g =
  CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.diagonal i)
      (CategoryTheory.Limits.pullback.map (f ≫ i) (g ≫ i) i i f g (𝟙 S) ⋯ ⋯) ≫
    CategoryTheory.Limits.pullback.fst (f ≫ i) (g ≫ i)

full_name: CategoryTheory.Limits.pullbackDiagonalMapIdIso_hom_snd
code: @[reassoc (attr := simp)]
theorem pullbackDiagonalMapIdIso_hom_snd :
    (pullbackDiagonalMapIdIso f g i).hom ≫ pullback.snd _ _ =
      pullback.snd _ _ ≫ pullback.snd _ _ 
goal: (CategoryTheory.Limits.pullbackDiagonalMapIdIso f g i).hom ≫ CategoryTheory.Limits.pullback.snd f g =
  CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.diagonal i)
      (CategoryTheory.Limits.pullback.map (f ≫ i) (g ≫ i) i i f g (𝟙 S) ⋯ ⋯) ≫
    CategoryTheory.Limits.pullback.snd (f ≫ i) (g ≫ i)

full_name: CategoryTheory.Limits.pullbackDiagonalMapIdIso_inv_fst
code: @[reassoc (attr := simp)]
theorem pullbackDiagonalMapIdIso_inv_fst :
    (pullbackDiagonalMapIdIso f g i).inv ≫ pullback.fst _ _ = pullback.fst _ _ ≫ f 
goal: (CategoryTheory.Limits.pullbackDiagonalMapIdIso f g i).inv ≫
    CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.diagonal i)
      (CategoryTheory.Limits.pullback.map (f ≫ i) (g ≫ i) i i f g (𝟙 S) ⋯ ⋯) =
  CategoryTheory.Limits.pullback.fst f g ≫ f

full_name: CategoryTheory.Limits.pullbackDiagonalMapIdIso_inv_snd_fst
code: @[reassoc (attr := simp)]
theorem pullbackDiagonalMapIdIso_inv_snd_fst :
    (pullbackDiagonalMapIdIso f g i).inv ≫ pullback.snd _ _ ≫ pullback.fst _ _ =
      pullback.fst _ _ 
goal: (CategoryTheory.Limits.pullbackDiagonalMapIdIso f g i).inv ≫
    CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.diagonal i)
        (CategoryTheory.Limits.pullback.map (f ≫ i) (g ≫ i) i i f g (𝟙 S) ⋯ ⋯) ≫
      CategoryTheory.Limits.pullback.fst (f ≫ i) (g ≫ i) =
  CategoryTheory.Limits.pullback.fst f g

full_name: CategoryTheory.Limits.pullbackDiagonalMapIdIso_inv_snd_snd
code: @[reassoc (attr := simp)]
theorem pullbackDiagonalMapIdIso_inv_snd_snd :
    (pullbackDiagonalMapIdIso f g i).inv ≫ pullback.snd _ _ ≫ pullback.snd _ _ =
      pullback.snd _ _ 
goal: (CategoryTheory.Limits.pullbackDiagonalMapIdIso f g i).inv ≫
    CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.diagonal i)
        (CategoryTheory.Limits.pullback.map (f ≫ i) (g ≫ i) i i f g (𝟙 S) ⋯ ⋯) ≫
      CategoryTheory.Limits.pullback.snd (f ≫ i) (g ≫ i) =
  CategoryTheory.Limits.pullback.snd f g

full_name: CategoryTheory.Limits.pullback.diagonal_comp
code: theorem pullback.diagonal_comp (f : X ⟶ Y) (g : Y ⟶ Z) [HasPullback f f] [HasPullback g g]
    [HasPullback (f ≫ g) (f ≫ g)] :
    diagonal (f ≫ g) = diagonal f ≫ (pullbackDiagonalMapIdIso f f g).inv ≫ pullback.snd _ _ 
goal: CategoryTheory.Limits.pullback.diagonal (f ≫ g) =
  CategoryTheory.Limits.pullback.diagonal f ≫
    (CategoryTheory.Limits.pullbackDiagonalMapIdIso f f g).inv ≫
      CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.diagonal g)
        (CategoryTheory.Limits.pullback.map (f ≫ g) (f ≫ g) g g f f (𝟙 Z) ⋯ ⋯)

full_name: CategoryTheory.Limits.pullback_map_diagonal_isPullback
code: theorem pullback_map_diagonal_isPullback :
    IsPullback (pullback.fst _ _ ≫ f)
      (pullback.map f g (f ≫ i) (g ≫ i) _ _ i (Category.id_comp _).symm (Category.id_comp _).symm)
      (diagonal i)
      (pullback.map (f ≫ i) (g ≫ i) i i f g (𝟙 _) (Category.comp_id _) (Category.comp_id _)) 
goal: CategoryTheory.IsPullback (CategoryTheory.Limits.pullback.fst f g ≫ f)
  (CategoryTheory.Limits.pullback.map f g (f ≫ i) (g ≫ i) (𝟙 X) (𝟙 Y) i ⋯ ⋯) (CategoryTheory.Limits.pullback.diagonal i)
  (CategoryTheory.Limits.pullback.map (f ≫ i) (g ≫ i) i i f g (𝟙 S) ⋯ ⋯)

full_name: CategoryTheory.Limits.diagonalObjPullbackFstIso
code: /-- The diagonal object of `X ×[Z] Y ⟶ X` is isomorphic to `Δ_{Y/Z} ×[Z] X`. -/
def diagonalObjPullbackFstIso {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    diagonalObj (pullback.fst f g) ≅
      pullback (pullback.snd _ _ ≫ g : diagonalObj g ⟶ Z) f 
goal: CategoryTheory.Limits.pullback.diagonalObj (CategoryTheory.Limits.pullback.fst f g) ≅
  CategoryTheory.Limits.pullback (CategoryTheory.Limits.pullback.snd g g ≫ g) f

full_name: CategoryTheory.Limits.diagonalObjPullbackFstIso_hom_fst_fst
code: @[reassoc (attr := simp)]
theorem diagonalObjPullbackFstIso_hom_fst_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    (diagonalObjPullbackFstIso f g).hom ≫ pullback.fst _ _ ≫ pullback.fst _ _ =
      pullback.fst _ _ ≫ pullback.snd _ _ 
goal: (CategoryTheory.Limits.diagonalObjPullbackFstIso f g).hom ≫
    CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.snd g g ≫ g) f ≫
      CategoryTheory.Limits.pullback.fst g g =
  CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.fst f g) (CategoryTheory.Limits.pullback.fst f g) ≫
    CategoryTheory.Limits.pullback.snd f g

full_name: CategoryTheory.Limits.diagonalObjPullbackFstIso_hom_fst_snd
code: @[reassoc (attr := simp)]
theorem diagonalObjPullbackFstIso_hom_fst_snd {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    (diagonalObjPullbackFstIso f g).hom ≫ pullback.fst _ _ ≫ pullback.snd _ _ =
      pullback.snd _ _ ≫ pullback.snd _ _ 
goal: (CategoryTheory.Limits.diagonalObjPullbackFstIso f g).hom ≫
    CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.snd g g ≫ g) f ≫
      CategoryTheory.Limits.pullback.snd g g =
  CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.fst f g) (CategoryTheory.Limits.pullback.fst f g) ≫
    CategoryTheory.Limits.pullback.snd f g

full_name: CategoryTheory.Limits.diagonalObjPullbackFstIso_hom_snd
code: @[reassoc (attr := simp)]
theorem diagonalObjPullbackFstIso_hom_snd {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    (diagonalObjPullbackFstIso f g).hom ≫ pullback.snd _ _ =
      pullback.fst _ _ ≫ pullback.fst _ _ 
goal: (CategoryTheory.Limits.diagonalObjPullbackFstIso f g).hom ≫
    CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.snd g g ≫ g) f =
  CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.fst f g) (CategoryTheory.Limits.pullback.fst f g) ≫
    CategoryTheory.Limits.pullback.fst f g

full_name: CategoryTheory.Limits.diagonalObjPullbackFstIso_inv_fst_fst
code: @[reassoc (attr := simp)]
theorem diagonalObjPullbackFstIso_inv_fst_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    (diagonalObjPullbackFstIso f g).inv ≫ pullback.fst _ _ ≫ pullback.fst _ _ =
      pullback.snd _ _ 
goal: (CategoryTheory.Limits.diagonalObjPullbackFstIso f g).inv ≫
    CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.fst f g)
        (CategoryTheory.Limits.pullback.fst f g) ≫
      CategoryTheory.Limits.pullback.fst f g =
  CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.snd g g ≫ g) f

full_name: CategoryTheory.Limits.diagonalObjPullbackFstIso_inv_fst_snd
code: @[reassoc (attr := simp)]
theorem diagonalObjPullbackFstIso_inv_fst_snd {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    (diagonalObjPullbackFstIso f g).inv ≫ pullback.fst _ _ ≫ pullback.snd _ _ =
      pullback.fst _ _ ≫ pullback.fst _ _ 
goal: (CategoryTheory.Limits.diagonalObjPullbackFstIso f g).inv ≫
    CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.fst f g)
        (CategoryTheory.Limits.pullback.fst f g) ≫
      CategoryTheory.Limits.pullback.snd f g =
  CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.snd g g ≫ g) f ≫
    CategoryTheory.Limits.pullback.fst g g

full_name: CategoryTheory.Limits.diagonalObjPullbackFstIso_inv_snd_fst
code: @[reassoc (attr := simp)]
theorem diagonalObjPullbackFstIso_inv_snd_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    (diagonalObjPullbackFstIso f g).inv ≫ pullback.snd _ _ ≫ pullback.fst _ _ =
      pullback.snd _ _ 
goal: (CategoryTheory.Limits.diagonalObjPullbackFstIso f g).inv ≫
    CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.fst f g)
        (CategoryTheory.Limits.pullback.fst f g) ≫
      CategoryTheory.Limits.pullback.fst f g =
  CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.snd g g ≫ g) f

full_name: CategoryTheory.Limits.diagonalObjPullbackFstIso_inv_snd_snd
code: @[reassoc (attr := simp)]
theorem diagonalObjPullbackFstIso_inv_snd_snd {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    (diagonalObjPullbackFstIso f g).inv ≫ pullback.snd _ _ ≫ pullback.snd _ _ =
      pullback.fst _ _ ≫ pullback.snd _ _ 
goal: (CategoryTheory.Limits.diagonalObjPullbackFstIso f g).inv ≫
    CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.fst f g)
        (CategoryTheory.Limits.pullback.fst f g) ≫
      CategoryTheory.Limits.pullback.snd f g =
  CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.snd g g ≫ g) f ≫
    CategoryTheory.Limits.pullback.snd g g

full_name: CategoryTheory.Limits.diagonal_pullback_fst
code: theorem diagonal_pullback_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    diagonal (pullback.fst f g) =
      (pullbackSymmetry _ _).hom ≫
        ((Over.pullback f).map
              (Over.homMk (diagonal g) : Over.mk g ⟶ Over.mk (pullback.snd _ _ ≫ g))).left ≫
          (diagonalObjPullbackFstIso f g).inv 
goal: CategoryTheory.Limits.pullback.diagonal (CategoryTheory.Limits.pullback.fst f g) =
  (CategoryTheory.Limits.pullbackSymmetry f (CategoryTheory.Over.mk g).hom).hom ≫
    ((CategoryTheory.Over.pullback f).map
          (CategoryTheory.Over.homMk (CategoryTheory.Limits.pullback.diagonal g) ⋯)).left ≫
      (CategoryTheory.Limits.diagonalObjPullbackFstIso f g).inv

full_name: CategoryTheory.Limits.pullbackFstFstIso
code: /-- Given the following diagram with `S ⟶ S'` a monomorphism,

```
    X ⟶ X'
      ↘      ↘
        S ⟶ S'
      ↗      ↗
    Y ⟶ Y'
```

This iso witnesses the fact that

```
      X ×[S] Y ⟶ (X' ×[S'] Y') ×[Y'] Y
          |                  |
          |                  |
          ↓                  ↓
(X' ×[S'] Y') ×[X'] X ⟶ X' ×[S'] Y'
```

is a pullback square. The diagonal map of this square is `pullback.map`.
Also see `pullback_lift_map_is_pullback`.
-/
@[simps]
def pullbackFstFstIso {X Y S X' Y' S' : C} (f : X ⟶ S) (g : Y ⟶ S) (f' : X' ⟶ S') (g' : Y' ⟶ S')
    (i₁ : X ⟶ X') (i₂ : Y ⟶ Y') (i₃ : S ⟶ S') (e₁ : f ≫ i₃ = i₁ ≫ f') (e₂ : g ≫ i₃ = i₂ ≫ g')
    [Mono i₃] :
    pullback (pullback.fst _ _ : pullback (pullback.fst _ _ : pullback f' g' ⟶ _) i₁ ⟶ _)
        (pullback.fst _ _ : pullback (pullback.snd _ _ : pullback f' g' ⟶ _) i₂ ⟶ _) ≅
      pullback f g 
goal: CategoryTheory.Limits.pullback (CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.fst f' g') i₁)
    (CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.snd f' g') i₂) ≅
  CategoryTheory.Limits.pullback f g

full_name: CategoryTheory.Limits.pullbackFstFstIso_inv
code: /-- Given the following diagram with `S ⟶ S'` a monomorphism,

```
    X ⟶ X'
      ↘      ↘
        S ⟶ S'
      ↗      ↗
    Y ⟶ Y'
```

This iso witnesses the fact that

```
      X ×[S] Y ⟶ (X' ×[S'] Y') ×[Y'] Y
          |                  |
          |                  |
          ↓                  ↓
(X' ×[S'] Y') ×[X'] X ⟶ X' ×[S'] Y'
```

is a pullback square. The diagonal map of this square is `pullback.map`.
Also see `pullback_lift_map_is_pullback`.
-/
@[simps]
def pullbackFstFstIso {X Y S X' Y' S' : C} (f : X ⟶ S) (g : Y ⟶ S) (f' : X' ⟶ S') (g' : Y' ⟶ S')
    (i₁ : X ⟶ X') (i₂ : Y ⟶ Y') (i₃ : S ⟶ S') (e₁ : f ≫ i₃ = i₁ ≫ f') (e₂ : g ≫ i₃ = i₂ ≫ g')
    [Mono i₃] :
    pullback (pullback.fst _ _ : pullback (pullback.fst _ _ : pullback f' g' ⟶ _) i₁ ⟶ _)
        (pullback.fst _ _ : pullback (pullback.snd _ _ : pullback f' g' ⟶ _) i₂ ⟶ _) ≅
      pullback f g 
goal: (CategoryTheory.Limits.pullbackFstFstIso f g f' g' i₁ i₂ i₃ e₁ e₂).inv =
  CategoryTheory.Limits.pullback.lift
    (CategoryTheory.Limits.pullback.lift (CategoryTheory.Limits.pullback.map f g f' g' i₁ i₂ i₃ e₁ e₂)
      (CategoryTheory.Limits.pullback.fst f g) ⋯)
    (CategoryTheory.Limits.pullback.lift (CategoryTheory.Limits.pullback.map f g f' g' i₁ i₂ i₃ e₁ e₂)
      (CategoryTheory.Limits.pullback.snd f g) ⋯)
    ⋯

full_name: CategoryTheory.Limits.pullbackFstFstIso_hom
code: /-- Given the following diagram with `S ⟶ S'` a monomorphism,

```
    X ⟶ X'
      ↘      ↘
        S ⟶ S'
      ↗      ↗
    Y ⟶ Y'
```

This iso witnesses the fact that

```
      X ×[S] Y ⟶ (X' ×[S'] Y') ×[Y'] Y
          |                  |
          |                  |
          ↓                  ↓
(X' ×[S'] Y') ×[X'] X ⟶ X' ×[S'] Y'
```

is a pullback square. The diagonal map of this square is `pullback.map`.
Also see `pullback_lift_map_is_pullback`.
-/
@[simps]
def pullbackFstFstIso {X Y S X' Y' S' : C} (f : X ⟶ S) (g : Y ⟶ S) (f' : X' ⟶ S') (g' : Y' ⟶ S')
    (i₁ : X ⟶ X') (i₂ : Y ⟶ Y') (i₃ : S ⟶ S') (e₁ : f ≫ i₃ = i₁ ≫ f') (e₂ : g ≫ i₃ = i₂ ≫ g')
    [Mono i₃] :
    pullback (pullback.fst _ _ : pullback (pullback.fst _ _ : pullback f' g' ⟶ _) i₁ ⟶ _)
        (pullback.fst _ _ : pullback (pullback.snd _ _ : pullback f' g' ⟶ _) i₂ ⟶ _) ≅
      pullback f g 
goal: (CategoryTheory.Limits.pullbackFstFstIso f g f' g' i₁ i₂ i₃ e₁ e₂).hom =
  CategoryTheory.Limits.pullback.lift
    (CategoryTheory.Limits.pullback.fst
        (CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.fst f' g') i₁)
        (CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.snd f' g') i₂) ≫
      CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.fst f' g') i₁)
    (CategoryTheory.Limits.pullback.snd
        (CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.fst f' g') i₁)
        (CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.snd f' g') i₂) ≫
      CategoryTheory.Limits.pullback.snd (CategoryTheory.Limits.pullback.snd f' g') i₂)
    ⋯

full_name: CategoryTheory.Limits.pullback_map_eq_pullbackFstFstIso_inv
code: theorem pullback_map_eq_pullbackFstFstIso_inv {X Y S X' Y' S' : C} (f : X ⟶ S) (g : Y ⟶ S)
    (f' : X' ⟶ S') (g' : Y' ⟶ S') (i₁ : X ⟶ X') (i₂ : Y ⟶ Y') (i₃ : S ⟶ S')
    (e₁ : f ≫ i₃ = i₁ ≫ f') (e₂ : g ≫ i₃ = i₂ ≫ g') [Mono i₃] :
    pullback.map f g f' g' i₁ i₂ i₃ e₁ e₂ =
      (pullbackFstFstIso f g f' g' i₁ i₂ i₃ e₁ e₂).inv ≫ pullback.snd _ _ ≫ pullback.fst _ _ 
goal: CategoryTheory.Limits.pullback.map f g f' g' i₁ i₂ i₃ e₁ e₂ =
  (CategoryTheory.Limits.pullbackFstFstIso f g f' g' i₁ i₂ i₃ e₁ e₂).inv ≫
    CategoryTheory.Limits.pullback.snd
        (CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.fst f' g') i₁)
        (CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.snd f' g') i₂) ≫
      CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.snd f' g') i₂

full_name: CategoryTheory.Limits.pullback_lift_map_isPullback
code: theorem pullback_lift_map_isPullback {X Y S X' Y' S' : C} (f : X ⟶ S) (g : Y ⟶ S) (f' : X' ⟶ S')
    (g' : Y' ⟶ S') (i₁ : X ⟶ X') (i₂ : Y ⟶ Y') (i₃ : S ⟶ S') (e₁ : f ≫ i₃ = i₁ ≫ f')
    (e₂ : g ≫ i₃ = i₂ ≫ g') [Mono i₃] :
    IsPullback (pullback.lift (pullback.map f g f' g' i₁ i₂ i₃ e₁ e₂) (fst _ _) (lift_fst _ _ _))
      (pullback.lift (pullback.map f g f' g' i₁ i₂ i₃ e₁ e₂) (snd _ _) (lift_snd _ _ _))
      (pullback.fst _ _) (pullback.fst _ _) 
goal: CategoryTheory.IsPullback
  (CategoryTheory.Limits.pullback.lift (CategoryTheory.Limits.pullback.map f g f' g' i₁ i₂ i₃ e₁ e₂)
    (CategoryTheory.Limits.pullback.fst f g) ⋯)
  (CategoryTheory.Limits.pullback.lift (CategoryTheory.Limits.pullback.map f g f' g' i₁ i₂ i₃ e₁ e₂)
    (CategoryTheory.Limits.pullback.snd f g) ⋯)
  (CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.fst f' g') i₁)
  (CategoryTheory.Limits.pullback.fst (CategoryTheory.Limits.pullback.snd f' g') i₂)