l3lab/ntp-mathlib huggingface dataset:
theorem pullbackConeOfLeftIso_π_app_none : (pullbackConeOfLeftIso f g).π.app none = g := by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso f
⊢ (pullbackConeOfLeftIso f g).π.app none = g

Next tactic:
simp
/-- Verify that the constructed limit cone is indeed a limit. -/
def pullbackConeOfLeftIsoIsLimit : IsLimit (pullbackConeOfLeftIso f g) :=
  PullbackCone.isLimitAux' _ fun s => ⟨s.snd, by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso f
s : PullbackCone f g
⊢ PullbackCone.snd s ≫ PullbackCone.fst (pullbackConeOfLeftIso f g) = PullbackCone.fst s ∧
    PullbackCone.snd s ≫ PullbackCone.snd (pullbackConeOfLeftIso f g) = PullbackCone.snd s ∧
      ∀ {m : s.pt ⟶ (pullbackConeOfLeftIso f g).pt},
        m ≫ PullbackCone.fst (pullbackConeOfLeftIso f g) = PullbackCone.fst s →
          m ≫ PullbackCone.snd (pullbackConeOfLeftIso f g) = PullbackCone.snd s → m = PullbackCone.snd s

Next tactic:
simp [← s.condition_assoc]
instance pullback_snd_iso_of_left_iso : IsIso (pullback.snd : pullback f g ⟶ _) := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso f
⊢ IsIso pullback.snd

Next tactic:
refine' ⟨⟨pullback.lift (g ≫ inv f) (𝟙 _) (by simp), _, by simp⟩⟩
instance pullback_snd_iso_of_left_iso : IsIso (pullback.snd : pullback f g ⟶ _) := by
  refine' ⟨⟨pullback.lift (g ≫ inv f) (𝟙 _) (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso f
⊢ (g ≫ inv f) ≫ f = 𝟙 Y ≫ g

Next tactic:
simp
instance pullback_snd_iso_of_left_iso : IsIso (pullback.snd : pullback f g ⟶ _) := by
  refine' ⟨⟨pullback.lift (g ≫ inv f) (𝟙 _) (by simp), _, by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso f
⊢ pullback.lift (g ≫ inv f) (𝟙 Y) (_ : (g ≫ inv f) ≫ f = 𝟙 Y ≫ g) ≫ pullback.snd = 𝟙 Y

Next tactic:
simp
instance pullback_snd_iso_of_left_iso : IsIso (pullback.snd : pullback f g ⟶ _) := by
  refine' ⟨⟨pullback.lift (g ≫ inv f) (𝟙 _) (by simp), _, by simp⟩⟩
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso f
⊢ pullback.snd ≫ pullback.lift (g ≫ inv f) (𝟙 Y) (_ : (g ≫ inv f) ≫ f = 𝟙 Y ≫ g) = 𝟙 (pullback f g)

Next tactic:
ext
instance pullback_snd_iso_of_left_iso : IsIso (pullback.snd : pullback f g ⟶ _) := by
  refine' ⟨⟨pullback.lift (g ≫ inv f) (𝟙 _) (by simp), _, by simp⟩⟩
  ext
  · 

Proof state:
case h₀
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso f
⊢ (pullback.snd ≫ pullback.lift (g ≫ inv f) (𝟙 Y) (_ : (g ≫ inv f) ≫ f = 𝟙 Y ≫ g)) ≫ pullback.fst =
    𝟙 (pullback f g) ≫ pullback.fst

Next tactic:
simp [← pullback.condition_assoc]
instance pullback_snd_iso_of_left_iso : IsIso (pullback.snd : pullback f g ⟶ _) := by
  refine' ⟨⟨pullback.lift (g ≫ inv f) (𝟙 _) (by simp), _, by simp⟩⟩
  ext
  · simp [← pullback.condition_assoc]
  · 

Proof state:
case h₁
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso f
⊢ (pullback.snd ≫ pullback.lift (g ≫ inv f) (𝟙 Y) (_ : (g ≫ inv f) ≫ f = 𝟙 Y ≫ g)) ≫ pullback.snd =
    𝟙 (pullback f g) ≫ pullback.snd

Next tactic:
simp [pullback.condition_assoc]
instance hasPullback_of_right_factors_mono (f : X ⟶ Z) : HasPullback i (f ≫ i) := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso f✝
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
⊢ HasPullback i (f ≫ i)

Next tactic:
conv =>
    congr
    rw [← Category.id_comp i]
instance hasPullback_of_right_factors_mono (f : X ⟶ Z) : HasPullback i (f ≫ i) := by
  conv =>
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso f✝
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
| HasPullback i (f ≫ i)

Next tactic:
congr
    rw [← Category.id_comp i]
instance hasPullback_of_right_factors_mono (f : X ⟶ Z) : HasPullback i (f ≫ i) := by
  conv =>
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso f✝
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
| HasPullback i (f ≫ i)

Next tactic:
congr
instance hasPullback_of_right_factors_mono (f : X ⟶ Z) : HasPullback i (f ≫ i) := by
  conv =>
    congr
    

Proof state:
case f
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso f✝
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
| i
case g
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso f✝
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
| f ≫ i

Next tactic:
rw [← Category.id_comp i]
instance hasPullback_of_right_factors_mono (f : X ⟶ Z) : HasPullback i (f ≫ i) := by
  conv =>
    congr
    rw [← Category.id_comp i]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso f✝
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
⊢ HasPullback (𝟙 Z ≫ i) (f ≫ i)

Next tactic:
infer_instance
instance pullback_snd_iso_of_right_factors_mono (f : X ⟶ Z) :
    IsIso (pullback.snd : pullback i (f ≫ i) ⟶ _) := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso f✝
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
⊢ IsIso pullback.snd

Next tactic:
convert (congrArg IsIso (show _ ≫ pullback.snd = _ from
    limit.isoLimitCone_hom_π ⟨_, pullbackIsPullbackOfCompMono (𝟙 _) f i⟩ WalkingCospan.right)).mp
    inferInstance
instance pullback_snd_iso_of_right_factors_mono (f : X ⟶ Z) :
    IsIso (pullback.snd : pullback i (f ≫ i) ⟶ _) := by
  convert (congrArg IsIso (show _ ≫ pullback.snd = _ from
    limit.isoLimitCone_hom_π ⟨_, pullbackIsPullbackOfCompMono (𝟙 _) f i⟩ WalkingCospan.right)).mp
    inferInstance;
  · 

Proof state:
case h.e'_3.h.e'_6.h
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso f✝
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
⊢ i = 𝟙 Z ≫ i

Next tactic:
exact (Category.id_comp _).symm
instance pullback_snd_iso_of_right_factors_mono (f : X ⟶ Z) :
    IsIso (pullback.snd : pullback i (f ≫ i) ⟶ _) := by
  convert (congrArg IsIso (show _ ≫ pullback.snd = _ from
    limit.isoLimitCone_hom_π ⟨_, pullbackIsPullbackOfCompMono (𝟙 _) f i⟩ WalkingCospan.right)).mp
    inferInstance;
  · exact (Category.id_comp _).symm
  · 

Proof state:
case h.e'_5.e'_6.h
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso f✝
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
e_3✝ : pullback i (f ≫ i) = limit (cospan (𝟙 Z ≫ i) (f ≫ i))
e_4✝ : X = (cospan (𝟙 Z ≫ i) (f ≫ i)).obj right
⊢ i = 𝟙 Z ≫ i

Next tactic:
exact (Category.id_comp _).symm
/-- If `g : Y ⟶ Z` is iso, then `X ×[Z] Y ≅ X`. This is the explicit limit cone. -/
def pullbackConeOfRightIso : PullbackCone f g :=
  PullbackCone.mk (𝟙 _) (f ≫ inv g) <| by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso g
⊢ 𝟙 X ≫ f = (f ≫ inv g) ≫ g

Next tactic:
simp
theorem pullbackConeOfRightIso_π_app_none : (pullbackConeOfRightIso f g).π.app none = f := by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso g
⊢ (pullbackConeOfRightIso f g).π.app none = f

Next tactic:
simp
/-- Verify that the constructed limit cone is indeed a limit. -/
def pullbackConeOfRightIsoIsLimit : IsLimit (pullbackConeOfRightIso f g) :=
  PullbackCone.isLimitAux' _ fun s => ⟨s.fst, by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso g
s : PullbackCone f g
⊢ PullbackCone.fst s ≫ PullbackCone.fst (pullbackConeOfRightIso f g) = PullbackCone.fst s ∧
    PullbackCone.fst s ≫ PullbackCone.snd (pullbackConeOfRightIso f g) = PullbackCone.snd s ∧
      ∀ {m : s.pt ⟶ (pullbackConeOfRightIso f g).pt},
        m ≫ PullbackCone.fst (pullbackConeOfRightIso f g) = PullbackCone.fst s →
          m ≫ PullbackCone.snd (pullbackConeOfRightIso f g) = PullbackCone.snd s → m = PullbackCone.fst s

Next tactic:
simp [s.condition_assoc]
instance pullback_snd_iso_of_right_iso : IsIso (pullback.fst : pullback f g ⟶ _) := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso g
⊢ IsIso pullback.fst

Next tactic:
refine' ⟨⟨pullback.lift (𝟙 _) (f ≫ inv g) (by simp), _, by simp⟩⟩
instance pullback_snd_iso_of_right_iso : IsIso (pullback.fst : pullback f g ⟶ _) := by
  refine' ⟨⟨pullback.lift (𝟙 _) (f ≫ inv g) (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso g
⊢ 𝟙 X ≫ f = (f ≫ inv g) ≫ g

Next tactic:
simp
instance pullback_snd_iso_of_right_iso : IsIso (pullback.fst : pullback f g ⟶ _) := by
  refine' ⟨⟨pullback.lift (𝟙 _) (f ≫ inv g) (by simp), _, by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso g
⊢ pullback.lift (𝟙 X) (f ≫ inv g) (_ : 𝟙 X ≫ f = (f ≫ inv g) ≫ g) ≫ pullback.fst = 𝟙 X

Next tactic:
simp
instance pullback_snd_iso_of_right_iso : IsIso (pullback.fst : pullback f g ⟶ _) := by
  refine' ⟨⟨pullback.lift (𝟙 _) (f ≫ inv g) (by simp), _, by simp⟩⟩
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso g
⊢ pullback.fst ≫ pullback.lift (𝟙 X) (f ≫ inv g) (_ : 𝟙 X ≫ f = (f ≫ inv g) ≫ g) = 𝟙 (pullback f g)

Next tactic:
ext
instance pullback_snd_iso_of_right_iso : IsIso (pullback.fst : pullback f g ⟶ _) := by
  refine' ⟨⟨pullback.lift (𝟙 _) (f ≫ inv g) (by simp), _, by simp⟩⟩
  ext
  · 

Proof state:
case h₀
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso g
⊢ (pullback.fst ≫ pullback.lift (𝟙 X) (f ≫ inv g) (_ : 𝟙 X ≫ f = (f ≫ inv g) ≫ g)) ≫ pullback.fst =
    𝟙 (pullback f g) ≫ pullback.fst

Next tactic:
simp
instance pullback_snd_iso_of_right_iso : IsIso (pullback.fst : pullback f g ⟶ _) := by
  refine' ⟨⟨pullback.lift (𝟙 _) (f ≫ inv g) (by simp), _, by simp⟩⟩
  ext
  · simp
  · 

Proof state:
case h₁
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
inst✝ : IsIso g
⊢ (pullback.fst ≫ pullback.lift (𝟙 X) (f ≫ inv g) (_ : 𝟙 X ≫ f = (f ≫ inv g) ≫ g)) ≫ pullback.snd =
    𝟙 (pullback f g) ≫ pullback.snd

Next tactic:
simp [pullback.condition_assoc]
instance hasPullback_of_left_factors_mono (f : X ⟶ Z) : HasPullback (f ≫ i) i := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso g
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
⊢ HasPullback (f ≫ i) i

Next tactic:
conv =>
    congr
    case g => rw [← Category.id_comp i]
instance hasPullback_of_left_factors_mono (f : X ⟶ Z) : HasPullback (f ≫ i) i := by
  conv =>
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso g
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
| HasPullback (f ≫ i) i

Next tactic:
congr
    case g => rw [← Category.id_comp i]
instance hasPullback_of_left_factors_mono (f : X ⟶ Z) : HasPullback (f ≫ i) i := by
  conv =>
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso g
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
| HasPullback (f ≫ i) i

Next tactic:
congr
instance hasPullback_of_left_factors_mono (f : X ⟶ Z) : HasPullback (f ≫ i) i := by
  conv =>
    congr
    

Proof state:
case f
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso g
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
| f ≫ i
case g
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso g
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
| i

Next tactic:
case g => rw [← Category.id_comp i]
instance hasPullback_of_left_factors_mono (f : X ⟶ Z) : HasPullback (f ≫ i) i := by
  conv =>
    congr
    case g => 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso g
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
| i

Next tactic:
rw [← Category.id_comp i]
instance hasPullback_of_left_factors_mono (f : X ⟶ Z) : HasPullback (f ≫ i) i := by
  conv =>
    congr
    case g => rw [← Category.id_comp i]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso g
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
⊢ HasPullback (f ≫ i) (𝟙 Z ≫ i)

Next tactic:
infer_instance
instance pullback_snd_iso_of_left_factors_mono (f : X ⟶ Z) :
    IsIso (pullback.fst : pullback (f ≫ i) i ⟶ _) := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso g
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
⊢ IsIso pullback.fst

Next tactic:
convert (congrArg IsIso (show _ ≫ pullback.fst = _ from
    limit.isoLimitCone_hom_π ⟨_, pullbackIsPullbackOfCompMono f (𝟙 _) i⟩ WalkingCospan.left)).mp
    inferInstance
instance pullback_snd_iso_of_left_factors_mono (f : X ⟶ Z) :
    IsIso (pullback.fst : pullback (f ≫ i) i ⟶ _) := by
  convert (congrArg IsIso (show _ ≫ pullback.fst = _ from
    limit.isoLimitCone_hom_π ⟨_, pullbackIsPullbackOfCompMono f (𝟙 _) i⟩ WalkingCospan.left)).mp
    inferInstance;
  · 

Proof state:
case h.e'_3.h.e'_7.h
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso g
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
⊢ i = 𝟙 Z ≫ i

Next tactic:
exact (Category.id_comp _).symm
instance pullback_snd_iso_of_left_factors_mono (f : X ⟶ Z) :
    IsIso (pullback.fst : pullback (f ≫ i) i ⟶ _) := by
  convert (congrArg IsIso (show _ ≫ pullback.fst = _ from
    limit.isoLimitCone_hom_π ⟨_, pullbackIsPullbackOfCompMono f (𝟙 _) i⟩ WalkingCospan.left)).mp
    inferInstance;
  · exact (Category.id_comp _).symm
  · 

Proof state:
case h.e'_5.e'_7.h
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Z
g : Y ⟶ Z
inst✝¹ : IsIso g
i : Z ⟶ W
inst✝ : Mono i
f : X ⟶ Z
e_3✝ : pullback (f ≫ i) i = limit (cospan (f ≫ i) (𝟙 Z ≫ i))
e_4✝ : X = (cospan (f ≫ i) (𝟙 Z ≫ i)).obj left
⊢ i = 𝟙 Z ≫ i

Next tactic:
exact (Category.id_comp _).symm
/-- The pushout of `f, g` is also the pullback of `h ≫ f, h ≫ g` for any epi `h`. -/
noncomputable def pushoutIsPushoutOfEpiComp (f : X ⟶ Y) (g : X ⟶ Z) (h : W ⟶ X) [Epi h]
    [HasPushout f g] : IsColimit (PushoutCocone.mk pushout.inl pushout.inr
    (show (h ≫ f) ≫ pushout.inl = (h ≫ g) ≫ pushout.inr from by
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
h : W ⟶ X
inst✝¹ : Epi h
inst✝ : HasPushout f g
⊢ (h ≫ f) ≫ pushout.inl = (h ≫ g) ≫ pushout.inr

Next tactic:
simp only [Category.assoc]
/-- The pushout of `f, g` is also the pullback of `h ≫ f, h ≫ g` for any epi `h`. -/
noncomputable def pushoutIsPushoutOfEpiComp (f : X ⟶ Y) (g : X ⟶ Z) (h : W ⟶ X) [Epi h]
    [HasPushout f g] : IsColimit (PushoutCocone.mk pushout.inl pushout.inr
    (show (h ≫ f) ≫ pushout.inl = (h ≫ g) ≫ pushout.inr from by
    simp only [Category.assoc]; 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
h : W ⟶ X
inst✝¹ : Epi h
inst✝ : HasPushout f g
⊢ h ≫ f ≫ pushout.inl = h ≫ g ≫ pushout.inr

Next tactic:
rw [cancel_epi]
/-- The pushout of `f, g` is also the pullback of `h ≫ f, h ≫ g` for any epi `h`. -/
noncomputable def pushoutIsPushoutOfEpiComp (f : X ⟶ Y) (g : X ⟶ Z) (h : W ⟶ X) [Epi h]
    [HasPushout f g] : IsColimit (PushoutCocone.mk pushout.inl pushout.inr
    (show (h ≫ f) ≫ pushout.inl = (h ≫ g) ≫ pushout.inr from by
    simp only [Category.assoc]; rw [cancel_epi]; 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
h : W ⟶ X
inst✝¹ : Epi h
inst✝ : HasPushout f g
⊢ f ≫ pushout.inl = g ≫ pushout.inr
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
h : W ⟶ X
inst✝¹ : Epi h
inst✝ : HasPushout f g
⊢ C
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
h : W ⟶ X
inst✝¹ : Epi h
inst✝ : HasPushout f g
⊢ ?m.426345 ⟶ Y
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
h : W ⟶ X
inst✝¹ : Epi h
inst✝ : HasPushout f g
⊢ ?m.426345 ⟶ Z
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
h : W ⟶ X
inst✝¹ : Epi h
inst✝ : HasPushout f g
⊢ HasPushout ?m.426348 ?m.426349

Next tactic:
exact pushout.condition
/-- If `f : X ⟶ Y` is iso, then `Y ⨿[X] Z ≅ Z`. This is the explicit colimit cocone. -/
def pushoutCoconeOfLeftIso : PushoutCocone f g :=
  PushoutCocone.mk (inv f ≫ g) (𝟙 _) <| by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
inst✝ : IsIso f
⊢ f ≫ inv f ≫ g = g ≫ 𝟙 Z

Next tactic:
simp
theorem pushoutCoconeOfLeftIso_ι_app_none : (pushoutCoconeOfLeftIso f g).ι.app none = g := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
inst✝ : IsIso f
⊢ (pushoutCoconeOfLeftIso f g).ι.app none = g

Next tactic:
simp
/-- Verify that the constructed cocone is indeed a colimit. -/
def pushoutCoconeOfLeftIsoIsLimit : IsColimit (pushoutCoconeOfLeftIso f g) :=
  PushoutCocone.isColimitAux' _ fun s => ⟨s.inr, by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
inst✝ : IsIso f
s : PushoutCocone f g
⊢ PushoutCocone.inl (pushoutCoconeOfLeftIso f g) ≫ PushoutCocone.inr s = PushoutCocone.inl s ∧
    PushoutCocone.inr (pushoutCoconeOfLeftIso f g) ≫ PushoutCocone.inr s = PushoutCocone.inr s ∧
      ∀ {m : (pushoutCoconeOfLeftIso f g).pt ⟶ s.pt},
        PushoutCocone.inl (pushoutCoconeOfLeftIso f g) ≫ m = PushoutCocone.inl s →
          PushoutCocone.inr (pushoutCoconeOfLeftIso f g) ≫ m = PushoutCocone.inr s → m = PushoutCocone.inr s

Next tactic:
simp [← s.condition]
instance pushout_inr_iso_of_left_iso : IsIso (pushout.inr : _ ⟶ pushout f g) := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
inst✝ : IsIso f
⊢ IsIso pushout.inr

Next tactic:
refine' ⟨⟨pushout.desc (inv f ≫ g) (𝟙 _) (by simp), by simp, _⟩⟩
instance pushout_inr_iso_of_left_iso : IsIso (pushout.inr : _ ⟶ pushout f g) := by
  refine' ⟨⟨pushout.desc (inv f ≫ g) (𝟙 _) (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
inst✝ : IsIso f
⊢ f ≫ inv f ≫ g = g ≫ 𝟙 Z

Next tactic:
simp
instance pushout_inr_iso_of_left_iso : IsIso (pushout.inr : _ ⟶ pushout f g) := by
  refine' ⟨⟨pushout.desc (inv f ≫ g) (𝟙 _) (by simp), by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
inst✝ : IsIso f
⊢ pushout.inr ≫ pushout.desc (inv f ≫ g) (𝟙 Z) (_ : f ≫ inv f ≫ g = g ≫ 𝟙 Z) = 𝟙 Z

Next tactic:
simp
instance pushout_inr_iso_of_left_iso : IsIso (pushout.inr : _ ⟶ pushout f g) := by
  refine' ⟨⟨pushout.desc (inv f ≫ g) (𝟙 _) (by simp), by simp, _⟩⟩
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
inst✝ : IsIso f
⊢ pushout.desc (inv f ≫ g) (𝟙 Z) (_ : f ≫ inv f ≫ g = g ≫ 𝟙 Z) ≫ pushout.inr = 𝟙 (pushout f g)

Next tactic:
ext
instance pushout_inr_iso_of_left_iso : IsIso (pushout.inr : _ ⟶ pushout f g) := by
  refine' ⟨⟨pushout.desc (inv f ≫ g) (𝟙 _) (by simp), by simp, _⟩⟩
  ext
  · 

Proof state:
case h₀
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
inst✝ : IsIso f
⊢ pushout.inl ≫ pushout.desc (inv f ≫ g) (𝟙 Z) (_ : f ≫ inv f ≫ g = g ≫ 𝟙 Z) ≫ pushout.inr =
    pushout.inl ≫ 𝟙 (pushout f g)

Next tactic:
simp [← pushout.condition]
instance pushout_inr_iso_of_left_iso : IsIso (pushout.inr : _ ⟶ pushout f g) := by
  refine' ⟨⟨pushout.desc (inv f ≫ g) (𝟙 _) (by simp), by simp, _⟩⟩
  ext
  · simp [← pushout.condition]
  · 

Proof state:
case h₁
C : Type u
inst✝² : Category.{v, u} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
W X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
inst✝ : IsIso f
⊢ pushout.inr ≫ pushout.desc (inv f ≫ g) (𝟙 Z) (_ : f ≫ inv f ≫ g = g ≫ 𝟙 Z) ≫ pushout.inr =
    pushout.inr ≫ 𝟙 (pushout f g)

Next tactic:
simp [pushout.condition_assoc]
instance hasPushout_of_right_factors_epi (f : X ⟶ Y) : HasPushout h (h ≫ f) := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Y
g : X ⟶ Z
inst✝¹ : IsIso f✝
h : W ⟶ X
inst✝ : Epi h
f : X ⟶ Y
⊢ HasPushout h (h ≫ f)

Next tactic:
conv =>
    congr
    rw [← Category.comp_id h]
instance hasPushout_of_right_factors_epi (f : X ⟶ Y) : HasPushout h (h ≫ f) := by
  conv =>
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Y
g : X ⟶ Z
inst✝¹ : IsIso f✝
h : W ⟶ X
inst✝ : Epi h
f : X ⟶ Y
| HasPushout h (h ≫ f)

Next tactic:
congr
    rw [← Category.comp_id h]
instance hasPushout_of_right_factors_epi (f : X ⟶ Y) : HasPushout h (h ≫ f) := by
  conv =>
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Y
g : X ⟶ Z
inst✝¹ : IsIso f✝
h : W ⟶ X
inst✝ : Epi h
f : X ⟶ Y
| HasPushout h (h ≫ f)

Next tactic:
congr
instance hasPushout_of_right_factors_epi (f : X ⟶ Y) : HasPushout h (h ≫ f) := by
  conv =>
    congr
    

Proof state:
case f
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Y
g : X ⟶ Z
inst✝¹ : IsIso f✝
h : W ⟶ X
inst✝ : Epi h
f : X ⟶ Y
| h
case g
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Y
g : X ⟶ Z
inst✝¹ : IsIso f✝
h : W ⟶ X
inst✝ : Epi h
f : X ⟶ Y
| h ≫ f

Next tactic:
rw [← Category.comp_id h]
instance hasPushout_of_right_factors_epi (f : X ⟶ Y) : HasPushout h (h ≫ f) := by
  conv =>
    congr
    rw [← Category.comp_id h]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Y
g : X ⟶ Z
inst✝¹ : IsIso f✝
h : W ⟶ X
inst✝ : Epi h
f : X ⟶ Y
⊢ HasPushout (h ≫ 𝟙 X) (h ≫ f)

Next tactic:
infer_instance
instance pushout_inr_iso_of_right_factors_epi (f : X ⟶ Y) :
    IsIso (pushout.inr : _ ⟶ pushout h (h ≫ f)) := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
W X Y Z : C
f✝ : X ⟶ Y
g : X ⟶ Z
inst✝¹ : IsIso f✝
h : W ⟶ X
inst✝ : Epi h
f : X ⟶ Y
⊢ IsIso pushout.inr

Next tactic:
convert (congrArg IsIso (show pushout.inr ≫ _ = _ from colimit.isoColimitCocone_ι_inv
    ⟨_, pushoutIsPushoutOfEpiComp (𝟙 _) f h⟩ WalkingSpan.right)).mp
    inferInstance