l3lab/ntp-mathlib huggingface dataset:
@[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 := by
  delta diagonalObjPullbackFstIso
  

Proof state:
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (pullbackRightPullbackFstIso f g fst ≪≫
          congrHom (_ : fst ≫ f = snd ≫ g) (_ : g = g) ≪≫
            pullbackAssoc f g g g ≪≫ pullbackSymmetry f (fst ≫ g) ≪≫ congrHom (_ : fst ≫ g = snd ≫ g) (_ : f = f)).hom ≫
      fst ≫ snd =
    snd ≫ snd

Next tactic:
simp
@[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 := by
  

Proof state:
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (diagonalObjPullbackFstIso f g).hom ≫ snd = fst ≫ fst

Next tactic:
delta diagonalObjPullbackFstIso
@[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 := by
  delta diagonalObjPullbackFstIso
  

Proof state:
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (pullbackRightPullbackFstIso f g fst ≪≫
          congrHom (_ : fst ≫ f = snd ≫ g) (_ : g = g) ≪≫
            pullbackAssoc f g g g ≪≫ pullbackSymmetry f (fst ≫ g) ≪≫ congrHom (_ : fst ≫ g = snd ≫ g) (_ : f = f)).hom ≫
      snd =
    fst ≫ fst

Next tactic:
simp
@[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 := by
  

Proof state:
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (diagonalObjPullbackFstIso f g).inv ≫ fst ≫ fst = snd

Next tactic:
delta diagonalObjPullbackFstIso
@[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 := by
  delta diagonalObjPullbackFstIso
  

Proof state:
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (pullbackRightPullbackFstIso f g fst ≪≫
          congrHom (_ : fst ≫ f = snd ≫ g) (_ : g = g) ≪≫
            pullbackAssoc f g g g ≪≫ pullbackSymmetry f (fst ≫ g) ≪≫ congrHom (_ : fst ≫ g = snd ≫ g) (_ : f = f)).inv ≫
      fst ≫ fst =
    snd

Next tactic:
simp
@[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 := by
  

Proof state:
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (diagonalObjPullbackFstIso f g).inv ≫ fst ≫ snd = fst ≫ fst

Next tactic:
delta diagonalObjPullbackFstIso
@[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 := by
  delta diagonalObjPullbackFstIso
  

Proof state:
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (pullbackRightPullbackFstIso f g fst ≪≫
          congrHom (_ : fst ≫ f = snd ≫ g) (_ : g = g) ≪≫
            pullbackAssoc f g g g ≪≫ pullbackSymmetry f (fst ≫ g) ≪≫ congrHom (_ : fst ≫ g = snd ≫ g) (_ : f = f)).inv ≫
      fst ≫ snd =
    fst ≫ fst

Next tactic:
simp
@[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 := by
  

Proof state:
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (diagonalObjPullbackFstIso f g).inv ≫ snd ≫ fst = snd

Next tactic:
delta diagonalObjPullbackFstIso
@[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 := by
  delta diagonalObjPullbackFstIso
  

Proof state:
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (pullbackRightPullbackFstIso f g fst ≪≫
          congrHom (_ : fst ≫ f = snd ≫ g) (_ : g = g) ≪≫
            pullbackAssoc f g g g ≪≫ pullbackSymmetry f (fst ≫ g) ≪≫ congrHom (_ : fst ≫ g = snd ≫ g) (_ : f = f)).inv ≫
      snd ≫ fst =
    snd

Next tactic:
simp
@[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 := by
  

Proof state:
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (diagonalObjPullbackFstIso f g).inv ≫ snd ≫ snd = fst ≫ snd

Next tactic:
delta diagonalObjPullbackFstIso
@[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 := by
  delta diagonalObjPullbackFstIso
  

Proof state:
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (pullbackRightPullbackFstIso f g fst ≪≫
          congrHom (_ : fst ≫ f = snd ≫ g) (_ : g = g) ≪≫
            pullbackAssoc f g g g ≪≫ pullbackSymmetry f (fst ≫ g) ≪≫ congrHom (_ : fst ≫ g = snd ≫ g) (_ : f = f)).inv ≫
      snd ≫ snd =
    fst ≫ snd

Next tactic:
simp
theorem diagonal_pullback_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    diagonal (pullback.fst : pullback f g ⟶ _) =
      (pullbackSymmetry _ _).hom ≫
        ((baseChange f).map
              (Over.homMk (diagonal g) : Over.mk g ⟶ Over.mk (pullback.snd ≫ g))).left ≫
          (diagonalObjPullbackFstIso f g).inv := by
  

Proof state:
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ diagonal fst =
    (pullbackSymmetry f (Over.mk g).hom).hom ≫
      ((baseChange f).map (Over.homMk (diagonal g))).left ≫ (diagonalObjPullbackFstIso f g).inv

Next tactic:
ext
theorem diagonal_pullback_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    diagonal (pullback.fst : pullback f g ⟶ _) =
      (pullbackSymmetry _ _).hom ≫
        ((baseChange f).map
              (Over.homMk (diagonal g) : Over.mk g ⟶ Over.mk (pullback.snd ≫ g))).left ≫
          (diagonalObjPullbackFstIso f g).inv := by
  ext <;> 

Proof state:
case h₀.h₀
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (diagonal fst ≫ fst) ≫ fst =
    (((pullbackSymmetry f (Over.mk g).hom).hom ≫
          ((baseChange f).map (Over.homMk (diagonal g))).left ≫ (diagonalObjPullbackFstIso f g).inv) ≫
        fst) ≫
      fst

Next tactic:
dsimp
theorem diagonal_pullback_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    diagonal (pullback.fst : pullback f g ⟶ _) =
      (pullbackSymmetry _ _).hom ≫
        ((baseChange f).map
              (Over.homMk (diagonal g) : Over.mk g ⟶ Over.mk (pullback.snd ≫ g))).left ≫
          (diagonalObjPullbackFstIso f g).inv := by
  ext <;> 

Proof state:
case h₀.h₁
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (diagonal fst ≫ fst) ≫ snd =
    (((pullbackSymmetry f (Over.mk g).hom).hom ≫
          ((baseChange f).map (Over.homMk (diagonal g))).left ≫ (diagonalObjPullbackFstIso f g).inv) ≫
        fst) ≫
      snd

Next tactic:
dsimp
theorem diagonal_pullback_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    diagonal (pullback.fst : pullback f g ⟶ _) =
      (pullbackSymmetry _ _).hom ≫
        ((baseChange f).map
              (Over.homMk (diagonal g) : Over.mk g ⟶ Over.mk (pullback.snd ≫ g))).left ≫
          (diagonalObjPullbackFstIso f g).inv := by
  ext <;> 

Proof state:
case h₁.h₀
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (diagonal fst ≫ snd) ≫ fst =
    (((pullbackSymmetry f (Over.mk g).hom).hom ≫
          ((baseChange f).map (Over.homMk (diagonal g))).left ≫ (diagonalObjPullbackFstIso f g).inv) ≫
        snd) ≫
      fst

Next tactic:
dsimp
theorem diagonal_pullback_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    diagonal (pullback.fst : pullback f g ⟶ _) =
      (pullbackSymmetry _ _).hom ≫
        ((baseChange f).map
              (Over.homMk (diagonal g) : Over.mk g ⟶ Over.mk (pullback.snd ≫ g))).left ≫
          (diagonalObjPullbackFstIso f g).inv := by
  ext <;> 

Proof state:
case h₁.h₁
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (diagonal fst ≫ snd) ≫ snd =
    (((pullbackSymmetry f (Over.mk g).hom).hom ≫
          ((baseChange f).map (Over.homMk (diagonal g))).left ≫ (diagonalObjPullbackFstIso f g).inv) ≫
        snd) ≫
      snd

Next tactic:
dsimp
theorem diagonal_pullback_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    diagonal (pullback.fst : pullback f g ⟶ _) =
      (pullbackSymmetry _ _).hom ≫
        ((baseChange f).map
              (Over.homMk (diagonal g) : Over.mk g ⟶ Over.mk (pullback.snd ≫ g))).left ≫
          (diagonalObjPullbackFstIso f g).inv := by
  ext <;> dsimp <;> 

Proof state:
case h₀.h₀
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (diagonal fst ≫ fst) ≫ fst =
    (((pullbackSymmetry f g).hom ≫
          map g f (snd ≫ g) f (diagonal g) (𝟙 X) (𝟙 Z)
              (_ : (Over.mk g).hom ≫ 𝟙 Z = (Over.homMk (diagonal g)).left ≫ (Over.mk (snd ≫ g)).hom)
              (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) ≫
            (diagonalObjPullbackFstIso f g).inv) ≫
        fst) ≫
      fst

Next tactic:
simp
theorem diagonal_pullback_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    diagonal (pullback.fst : pullback f g ⟶ _) =
      (pullbackSymmetry _ _).hom ≫
        ((baseChange f).map
              (Over.homMk (diagonal g) : Over.mk g ⟶ Over.mk (pullback.snd ≫ g))).left ≫
          (diagonalObjPullbackFstIso f g).inv := by
  ext <;> dsimp <;> 

Proof state:
case h₀.h₁
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (diagonal fst ≫ fst) ≫ snd =
    (((pullbackSymmetry f g).hom ≫
          map g f (snd ≫ g) f (diagonal g) (𝟙 X) (𝟙 Z)
              (_ : (Over.mk g).hom ≫ 𝟙 Z = (Over.homMk (diagonal g)).left ≫ (Over.mk (snd ≫ g)).hom)
              (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) ≫
            (diagonalObjPullbackFstIso f g).inv) ≫
        fst) ≫
      snd

Next tactic:
simp
theorem diagonal_pullback_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    diagonal (pullback.fst : pullback f g ⟶ _) =
      (pullbackSymmetry _ _).hom ≫
        ((baseChange f).map
              (Over.homMk (diagonal g) : Over.mk g ⟶ Over.mk (pullback.snd ≫ g))).left ≫
          (diagonalObjPullbackFstIso f g).inv := by
  ext <;> dsimp <;> 

Proof state:
case h₁.h₀
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (diagonal fst ≫ snd) ≫ fst =
    (((pullbackSymmetry f g).hom ≫
          map g f (snd ≫ g) f (diagonal g) (𝟙 X) (𝟙 Z)
              (_ : (Over.mk g).hom ≫ 𝟙 Z = (Over.homMk (diagonal g)).left ≫ (Over.mk (snd ≫ g)).hom)
              (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) ≫
            (diagonalObjPullbackFstIso f g).inv) ≫
        snd) ≫
      fst

Next tactic:
simp
theorem diagonal_pullback_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
    diagonal (pullback.fst : pullback f g ⟶ _) =
      (pullbackSymmetry _ _).hom ≫
        ((baseChange f).map
              (Over.homMk (diagonal g) : Over.mk g ⟶ Over.mk (pullback.snd ≫ g))).left ≫
          (diagonalObjPullbackFstIso f g).inv := by
  ext <;> dsimp <;> 

Proof state:
case h₁.h₁
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
X✝ Y✝ Z✝ : C
inst✝⁴ : HasPullbacks C
S T : C
f✝ : X✝ ⟶ T
g✝ : Y✝ ⟶ T
i : T ⟶ S
inst✝³ : HasPullback i i
inst✝² : HasPullback f✝ g✝
inst✝¹ : HasPullback (f✝ ≫ i) (g✝ ≫ i)
inst✝ :
  HasPullback (diagonal i)
    (map (f✝ ≫ i) (g✝ ≫ i) i i f✝ g✝ (𝟙 S) (_ : (f✝ ≫ i) ≫ 𝟙 S = f✝ ≫ i) (_ : (g✝ ≫ i) ≫ 𝟙 S = g✝ ≫ i))
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
⊢ (diagonal fst ≫ snd) ≫ snd =
    (((pullbackSymmetry f g).hom ≫
          map g f (snd ≫ g) f (diagonal g) (𝟙 X) (𝟙 Z)
              (_ : (Over.mk g).hom ≫ 𝟙 Z = (Over.homMk (diagonal g)).left ≫ (Over.mk (snd ≫ g)).hom)
              (_ : f ≫ 𝟙 Z = 𝟙 X ≫ f) ≫
            (diagonalObjPullbackFstIso f g).inv) ≫
        snd) ≫
      snd

Next tactic:
simp
/-- 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
    where
  hom :=
    pullback.lift (pullback.fst ≫ pullback.snd) (pullback.snd ≫ pullback.snd)
      (by
        

Proof state:
C : Type u_1
inst✝² : Category.{?u.887108, u_1} C
X✝ Y✝ Z : C
inst✝¹ : HasPullbacks C
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'
inst✝ : Mono i₃
⊢ (fst ≫ snd) ≫ f = (snd ≫ snd) ≫ g

Next tactic:
rw [← cancel_mono i₃, Category.assoc, Category.assoc, Category.assoc, Category.assoc, e₁,
          e₂, ← pullback.condition_assoc, pullback.condition_assoc, pullback.condition,
          pullback.condition_assoc]
/-- 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
    where
  hom :=
    pullback.lift (pullback.fst ≫ pullback.snd) (pullback.snd ≫ pullback.snd)
      (by
        rw [← cancel_mono i₃, Category.assoc, Category.assoc, Category.assoc, Category.assoc, e₁,
          e₂, ← pullback.condition_assoc, pullback.condition_assoc, pullback.condition,
          pullback.condition_assoc])
  inv :=
    pullback.lift
      (pullback.lift (pullback.map _ _ _ _ _ _ _ e₁ e₂) pullback.fst (pullback.lift_fst _ _ _))
      (pullback.lift (pullback.map _ _ _ _ _ _ _ e₁ e₂) pullback.snd (pullback.lift_snd _ _ _))
      (by 

Proof state:
C : Type u_1
inst✝² : Category.{?u.887108, u_1} C
X✝ Y✝ Z : C
inst✝¹ : HasPullbacks C
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'
inst✝ : Mono i₃
⊢ lift (map f g f' g' i₁ i₂ i₃ e₁ e₂) fst
        (_ : lift (fst ≫ i₁) (snd ≫ i₂) (_ : (fst ≫ i₁) ≫ f' = (snd ≫ i₂) ≫ g') ≫ fst = fst ≫ i₁) ≫
      fst =
    lift (map f g f' g' i₁ i₂ i₃ e₁ e₂) snd
        (_ : lift (fst ≫ i₁) (snd ≫ i₂) (_ : (fst ≫ i₁) ≫ f' = (snd ≫ i₂) ≫ g') ≫ snd = snd ≫ i₂) ≫
      fst

Next tactic:
rw [pullback.lift_fst, pullback.lift_fst]
/-- 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
    where
  hom :=
    pullback.lift (pullback.fst ≫ pullback.snd) (pullback.snd ≫ pullback.snd)
      (by
        rw [← cancel_mono i₃, Category.assoc, Category.assoc, Category.assoc, Category.assoc, e₁,
          e₂, ← pullback.condition_assoc, pullback.condition_assoc, pullback.condition,
          pullback.condition_assoc])
  inv :=
    pullback.lift
      (pullback.lift (pullback.map _ _ _ _ _ _ _ e₁ e₂) pullback.fst (pullback.lift_fst _ _ _))
      (pullback.lift (pullback.map _ _ _ _ _ _ _ e₁ e₂) pullback.snd (pullback.lift_snd _ _ _))
      (by rw [pullback.lift_fst, pullback.lift_fst])
  hom_inv_id := by
    -- We could use `ext` here to immediately descend to the leaf goals,
    -- but it only obscures the structure.
    

Proof state:
C : Type u_1
inst✝² : Category.{?u.887108, u_1} C
X✝ Y✝ Z : C
inst✝¹ : HasPullbacks C
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'
inst✝ : Mono i₃
⊢ lift (fst ≫ snd) (snd ≫ snd) (_ : (fst ≫ snd) ≫ f = (snd ≫ snd) ≫ g) ≫
      lift
        (lift (map f g f' g' i₁ i₂ i₃ e₁ e₂) fst
          (_ : lift (fst ≫ i₁) (snd ≫ i₂) (_ : (fst ≫ i₁) ≫ f' = (snd ≫ i₂) ≫ g') ≫ fst = fst ≫ i₁))
        (lift (map f g f' g' i₁ i₂ i₃ e₁ e₂) snd
          (_ : lift (fst ≫ i₁) (snd ≫ i₂) (_ : (fst ≫ i₁) ≫ f' = (snd ≫ i₂) ≫ g') ≫ snd = snd ≫ i₂))
        (_ :
          lift (map f g f' g' i₁ i₂ i₃ e₁ e₂) fst
                (_ : lift (fst ≫ i₁) (snd ≫ i₂) (_ : (fst ≫ i₁) ≫ f' = (snd ≫ i₂) ≫ g') ≫ fst = fst ≫ i₁) ≫
              fst =
            lift (map f g f' g' i₁ i₂ i₃ e₁ e₂) snd
                (_ : lift (fst ≫ i₁) (snd ≫ i₂) (_ : (fst ≫ i₁) ≫ f' = (snd ≫ i₂) ≫ g') ≫ snd = snd ≫ i₂) ≫
              fst) =
    𝟙 (pullback fst fst)

Next tactic:
apply pullback.hom_ext