l3lab/ntp-mathlib huggingface dataset:
/-- The second leg of a pullback cone is a regular monomorphism if the right component is too.

See also `Pullback.sndOfMono` for the basic monomorphism version, and
`regularOfIsPullbackFstOfRegular` for the flipped version.
-/
def regularOfIsPullbackSndOfRegular {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h : Q ⟶ S} {k : R ⟶ S}
    [hr : RegularMono h] (comm : f ≫ h = g ≫ k) (t : IsLimit (PullbackCone.mk _ _ comm)) :
    RegularMono g where
  Z := hr.Z
  left := k ≫ hr.left
  right := k ≫ hr.right
  w := by
    repeat (rw [← Category.assoc, ← eq_whisker comm])
    simp only [Category.assoc, hr.w]
  isLimit := by
    apply Fork.IsLimit.mk' _ _
    intro s
    have l₁ : (Fork.ι s ≫ k) ≫ RegularMono.left = (Fork.ι s ≫ k) ≫ hr.right := by
      rw [Category.assoc, s.condition, Category.assoc]
    obtain ⟨l, hl⟩ := Fork.IsLimit.lift' hr.isLimit _ l₁
    obtain ⟨p, _, hp₂⟩ := PullbackCone.IsLimit.lift' t _ _ hl
    refine' ⟨p, hp₂, _⟩
    intro m w
    have z : m ≫ g = p ≫ g := w.trans hp₂.symm
    

Proof state:
case mk.mk.intro
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y P Q R S : C
f : P ⟶ Q
g : P ⟶ R
h : Q ⟶ S
k : R ⟶ S
hr : RegularMono h
comm : f ≫ h = g ≫ k
t : IsLimit (PullbackCone.mk f g comm)
s : Fork (k ≫ RegularMono.left) (k ≫ RegularMono.right)
l₁ : (Fork.ι s ≫ k) ≫ RegularMono.left = (Fork.ι s ≫ k) ≫ RegularMono.right
l :
  ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶
    (Fork.ofι h (_ : h ≫ RegularMono.left = h ≫ RegularMono.right)).pt
hl : l ≫ Fork.ι (Fork.ofι h (_ : h ≫ RegularMono.left = h ≫ RegularMono.right)) = Fork.ι s ≫ k
p : ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶ (PullbackCone.mk f g comm).pt
left✝ : p ≫ PullbackCone.fst (PullbackCone.mk f g comm) = l
hp₂ : p ≫ PullbackCone.snd (PullbackCone.mk f g comm) = Fork.ι s
m :
  ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶
    ((Functor.const WalkingParallelPair).obj
          (Fork.ofι g (_ : g ≫ k ≫ RegularMono.left = g ≫ k ≫ RegularMono.right)).pt).obj
      WalkingParallelPair.zero
w : m ≫ Fork.ι (Fork.ofι g (_ : g ≫ k ≫ RegularMono.left = g ≫ k ≫ RegularMono.right)) = Fork.ι s
z : m ≫ g = p ≫ g
⊢ m = p

Next tactic:
apply t.hom_ext
/-- The second leg of a pullback cone is a regular monomorphism if the right component is too.

See also `Pullback.sndOfMono` for the basic monomorphism version, and
`regularOfIsPullbackFstOfRegular` for the flipped version.
-/
def regularOfIsPullbackSndOfRegular {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h : Q ⟶ S} {k : R ⟶ S}
    [hr : RegularMono h] (comm : f ≫ h = g ≫ k) (t : IsLimit (PullbackCone.mk _ _ comm)) :
    RegularMono g where
  Z := hr.Z
  left := k ≫ hr.left
  right := k ≫ hr.right
  w := by
    repeat (rw [← Category.assoc, ← eq_whisker comm])
    simp only [Category.assoc, hr.w]
  isLimit := by
    apply Fork.IsLimit.mk' _ _
    intro s
    have l₁ : (Fork.ι s ≫ k) ≫ RegularMono.left = (Fork.ι s ≫ k) ≫ hr.right := by
      rw [Category.assoc, s.condition, Category.assoc]
    obtain ⟨l, hl⟩ := Fork.IsLimit.lift' hr.isLimit _ l₁
    obtain ⟨p, _, hp₂⟩ := PullbackCone.IsLimit.lift' t _ _ hl
    refine' ⟨p, hp₂, _⟩
    intro m w
    have z : m ≫ g = p ≫ g := w.trans hp₂.symm
    apply t.hom_ext
    

Proof state:
case mk.mk.intro
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y P Q R S : C
f : P ⟶ Q
g : P ⟶ R
h : Q ⟶ S
k : R ⟶ S
hr : RegularMono h
comm : f ≫ h = g ≫ k
t : IsLimit (PullbackCone.mk f g comm)
s : Fork (k ≫ RegularMono.left) (k ≫ RegularMono.right)
l₁ : (Fork.ι s ≫ k) ≫ RegularMono.left = (Fork.ι s ≫ k) ≫ RegularMono.right
l :
  ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶
    (Fork.ofι h (_ : h ≫ RegularMono.left = h ≫ RegularMono.right)).pt
hl : l ≫ Fork.ι (Fork.ofι h (_ : h ≫ RegularMono.left = h ≫ RegularMono.right)) = Fork.ι s ≫ k
p : ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶ (PullbackCone.mk f g comm).pt
left✝ : p ≫ PullbackCone.fst (PullbackCone.mk f g comm) = l
hp₂ : p ≫ PullbackCone.snd (PullbackCone.mk f g comm) = Fork.ι s
m :
  ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶
    ((Functor.const WalkingParallelPair).obj
          (Fork.ofι g (_ : g ≫ k ≫ RegularMono.left = g ≫ k ≫ RegularMono.right)).pt).obj
      WalkingParallelPair.zero
w : m ≫ Fork.ι (Fork.ofι g (_ : g ≫ k ≫ RegularMono.left = g ≫ k ≫ RegularMono.right)) = Fork.ι s
z : m ≫ g = p ≫ g
⊢ ∀ (j : WalkingCospan), m ≫ (PullbackCone.mk f g comm).π.app j = p ≫ (PullbackCone.mk f g comm).π.app j

Next tactic:
apply (PullbackCone.mk f g comm).equalizer_ext
/-- The second leg of a pullback cone is a regular monomorphism if the right component is too.

See also `Pullback.sndOfMono` for the basic monomorphism version, and
`regularOfIsPullbackFstOfRegular` for the flipped version.
-/
def regularOfIsPullbackSndOfRegular {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h : Q ⟶ S} {k : R ⟶ S}
    [hr : RegularMono h] (comm : f ≫ h = g ≫ k) (t : IsLimit (PullbackCone.mk _ _ comm)) :
    RegularMono g where
  Z := hr.Z
  left := k ≫ hr.left
  right := k ≫ hr.right
  w := by
    repeat (rw [← Category.assoc, ← eq_whisker comm])
    simp only [Category.assoc, hr.w]
  isLimit := by
    apply Fork.IsLimit.mk' _ _
    intro s
    have l₁ : (Fork.ι s ≫ k) ≫ RegularMono.left = (Fork.ι s ≫ k) ≫ hr.right := by
      rw [Category.assoc, s.condition, Category.assoc]
    obtain ⟨l, hl⟩ := Fork.IsLimit.lift' hr.isLimit _ l₁
    obtain ⟨p, _, hp₂⟩ := PullbackCone.IsLimit.lift' t _ _ hl
    refine' ⟨p, hp₂, _⟩
    intro m w
    have z : m ≫ g = p ≫ g := w.trans hp₂.symm
    apply t.hom_ext
    apply (PullbackCone.mk f g comm).equalizer_ext
    · 

Proof state:
case mk.mk.intro.h₀
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y P Q R S : C
f : P ⟶ Q
g : P ⟶ R
h : Q ⟶ S
k : R ⟶ S
hr : RegularMono h
comm : f ≫ h = g ≫ k
t : IsLimit (PullbackCone.mk f g comm)
s : Fork (k ≫ RegularMono.left) (k ≫ RegularMono.right)
l₁ : (Fork.ι s ≫ k) ≫ RegularMono.left = (Fork.ι s ≫ k) ≫ RegularMono.right
l :
  ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶
    (Fork.ofι h (_ : h ≫ RegularMono.left = h ≫ RegularMono.right)).pt
hl : l ≫ Fork.ι (Fork.ofι h (_ : h ≫ RegularMono.left = h ≫ RegularMono.right)) = Fork.ι s ≫ k
p : ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶ (PullbackCone.mk f g comm).pt
left✝ : p ≫ PullbackCone.fst (PullbackCone.mk f g comm) = l
hp₂ : p ≫ PullbackCone.snd (PullbackCone.mk f g comm) = Fork.ι s
m :
  ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶
    ((Functor.const WalkingParallelPair).obj
          (Fork.ofι g (_ : g ≫ k ≫ RegularMono.left = g ≫ k ≫ RegularMono.right)).pt).obj
      WalkingParallelPair.zero
w : m ≫ Fork.ι (Fork.ofι g (_ : g ≫ k ≫ RegularMono.left = g ≫ k ≫ RegularMono.right)) = Fork.ι s
z : m ≫ g = p ≫ g
⊢ m ≫ PullbackCone.fst (PullbackCone.mk f g comm) = p ≫ PullbackCone.fst (PullbackCone.mk f g comm)

Next tactic:
erw [← cancel_mono h, Category.assoc, Category.assoc, comm]
/-- The second leg of a pullback cone is a regular monomorphism if the right component is too.

See also `Pullback.sndOfMono` for the basic monomorphism version, and
`regularOfIsPullbackFstOfRegular` for the flipped version.
-/
def regularOfIsPullbackSndOfRegular {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h : Q ⟶ S} {k : R ⟶ S}
    [hr : RegularMono h] (comm : f ≫ h = g ≫ k) (t : IsLimit (PullbackCone.mk _ _ comm)) :
    RegularMono g where
  Z := hr.Z
  left := k ≫ hr.left
  right := k ≫ hr.right
  w := by
    repeat (rw [← Category.assoc, ← eq_whisker comm])
    simp only [Category.assoc, hr.w]
  isLimit := by
    apply Fork.IsLimit.mk' _ _
    intro s
    have l₁ : (Fork.ι s ≫ k) ≫ RegularMono.left = (Fork.ι s ≫ k) ≫ hr.right := by
      rw [Category.assoc, s.condition, Category.assoc]
    obtain ⟨l, hl⟩ := Fork.IsLimit.lift' hr.isLimit _ l₁
    obtain ⟨p, _, hp₂⟩ := PullbackCone.IsLimit.lift' t _ _ hl
    refine' ⟨p, hp₂, _⟩
    intro m w
    have z : m ≫ g = p ≫ g := w.trans hp₂.symm
    apply t.hom_ext
    apply (PullbackCone.mk f g comm).equalizer_ext
    · erw [← cancel_mono h, Category.assoc, Category.assoc, comm]
      

Proof state:
case mk.mk.intro.h₀
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y P Q R S : C
f : P ⟶ Q
g : P ⟶ R
h : Q ⟶ S
k : R ⟶ S
hr : RegularMono h
comm : f ≫ h = g ≫ k
t : IsLimit (PullbackCone.mk f g comm)
s : Fork (k ≫ RegularMono.left) (k ≫ RegularMono.right)
l₁ : (Fork.ι s ≫ k) ≫ RegularMono.left = (Fork.ι s ≫ k) ≫ RegularMono.right
l :
  ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶
    (Fork.ofι h (_ : h ≫ RegularMono.left = h ≫ RegularMono.right)).pt
hl : l ≫ Fork.ι (Fork.ofι h (_ : h ≫ RegularMono.left = h ≫ RegularMono.right)) = Fork.ι s ≫ k
p : ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶ (PullbackCone.mk f g comm).pt
left✝ : p ≫ PullbackCone.fst (PullbackCone.mk f g comm) = l
hp₂ : p ≫ PullbackCone.snd (PullbackCone.mk f g comm) = Fork.ι s
m :
  ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶
    ((Functor.const WalkingParallelPair).obj
          (Fork.ofι g (_ : g ≫ k ≫ RegularMono.left = g ≫ k ≫ RegularMono.right)).pt).obj
      WalkingParallelPair.zero
w : m ≫ Fork.ι (Fork.ofι g (_ : g ≫ k ≫ RegularMono.left = g ≫ k ≫ RegularMono.right)) = Fork.ι s
z : m ≫ g = p ≫ g
⊢ m ≫ g ≫ k = p ≫ g ≫ k

Next tactic:
simp only [← Category.assoc, eq_whisker z]
/-- The second leg of a pullback cone is a regular monomorphism if the right component is too.

See also `Pullback.sndOfMono` for the basic monomorphism version, and
`regularOfIsPullbackFstOfRegular` for the flipped version.
-/
def regularOfIsPullbackSndOfRegular {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h : Q ⟶ S} {k : R ⟶ S}
    [hr : RegularMono h] (comm : f ≫ h = g ≫ k) (t : IsLimit (PullbackCone.mk _ _ comm)) :
    RegularMono g where
  Z := hr.Z
  left := k ≫ hr.left
  right := k ≫ hr.right
  w := by
    repeat (rw [← Category.assoc, ← eq_whisker comm])
    simp only [Category.assoc, hr.w]
  isLimit := by
    apply Fork.IsLimit.mk' _ _
    intro s
    have l₁ : (Fork.ι s ≫ k) ≫ RegularMono.left = (Fork.ι s ≫ k) ≫ hr.right := by
      rw [Category.assoc, s.condition, Category.assoc]
    obtain ⟨l, hl⟩ := Fork.IsLimit.lift' hr.isLimit _ l₁
    obtain ⟨p, _, hp₂⟩ := PullbackCone.IsLimit.lift' t _ _ hl
    refine' ⟨p, hp₂, _⟩
    intro m w
    have z : m ≫ g = p ≫ g := w.trans hp₂.symm
    apply t.hom_ext
    apply (PullbackCone.mk f g comm).equalizer_ext
    · erw [← cancel_mono h, Category.assoc, Category.assoc, comm]
      simp only [← Category.assoc, eq_whisker z]
    · 

Proof state:
case mk.mk.intro.h₁
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y P Q R S : C
f : P ⟶ Q
g : P ⟶ R
h : Q ⟶ S
k : R ⟶ S
hr : RegularMono h
comm : f ≫ h = g ≫ k
t : IsLimit (PullbackCone.mk f g comm)
s : Fork (k ≫ RegularMono.left) (k ≫ RegularMono.right)
l₁ : (Fork.ι s ≫ k) ≫ RegularMono.left = (Fork.ι s ≫ k) ≫ RegularMono.right
l :
  ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶
    (Fork.ofι h (_ : h ≫ RegularMono.left = h ≫ RegularMono.right)).pt
hl : l ≫ Fork.ι (Fork.ofι h (_ : h ≫ RegularMono.left = h ≫ RegularMono.right)) = Fork.ι s ≫ k
p : ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶ (PullbackCone.mk f g comm).pt
left✝ : p ≫ PullbackCone.fst (PullbackCone.mk f g comm) = l
hp₂ : p ≫ PullbackCone.snd (PullbackCone.mk f g comm) = Fork.ι s
m :
  ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.zero ⟶
    ((Functor.const WalkingParallelPair).obj
          (Fork.ofι g (_ : g ≫ k ≫ RegularMono.left = g ≫ k ≫ RegularMono.right)).pt).obj
      WalkingParallelPair.zero
w : m ≫ Fork.ι (Fork.ofι g (_ : g ≫ k ≫ RegularMono.left = g ≫ k ≫ RegularMono.right)) = Fork.ι s
z : m ≫ g = p ≫ g
⊢ m ≫ PullbackCone.snd (PullbackCone.mk f g comm) = p ≫ PullbackCone.snd (PullbackCone.mk f g comm)

Next tactic:
exact z
instance (priority := 100) strongMono_of_regularMono (f : X ⟶ Y) [RegularMono f] : StrongMono f :=
  StrongMono.mk' (by
      

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : RegularMono f
⊢ ∀ (X_1 Y_1 : C) (z : X_1 ⟶ Y_1), Epi z → ∀ (u : X_1 ⟶ X) (v : Y_1 ⟶ Y) (sq : CommSq u z f v), CommSq.HasLift sq

Next tactic:
intro A B z hz u v sq
instance (priority := 100) strongMono_of_regularMono (f : X ⟶ Y) [RegularMono f] : StrongMono f :=
  StrongMono.mk' (by
      intro A B z hz u v sq
      

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : RegularMono f
A B : C
z : A ⟶ B
hz : Epi z
u : A ⟶ X
v : B ⟶ Y
sq : CommSq u z f v
⊢ CommSq.HasLift sq

Next tactic:
have : v ≫ (RegularMono.left : Y ⟶ RegularMono.Z f) = v ≫ RegularMono.right := by
        apply (cancel_epi z).1
        repeat (rw [← Category.assoc, ← eq_whisker sq.w])
        simp only [Category.assoc, RegularMono.w]
instance (priority := 100) strongMono_of_regularMono (f : X ⟶ Y) [RegularMono f] : StrongMono f :=
  StrongMono.mk' (by
      intro A B z hz u v sq
      have : v ≫ (RegularMono.left : Y ⟶ RegularMono.Z f) = v ≫ RegularMono.right := by
        

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : RegularMono f
A B : C
z : A ⟶ B
hz : Epi z
u : A ⟶ X
v : B ⟶ Y
sq : CommSq u z f v
⊢ v ≫ RegularMono.left = v ≫ RegularMono.right

Next tactic:
apply (cancel_epi z).1
instance (priority := 100) strongMono_of_regularMono (f : X ⟶ Y) [RegularMono f] : StrongMono f :=
  StrongMono.mk' (by
      intro A B z hz u v sq
      have : v ≫ (RegularMono.left : Y ⟶ RegularMono.Z f) = v ≫ RegularMono.right := by
        apply (cancel_epi z).1
        

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : RegularMono f
A B : C
z : A ⟶ B
hz : Epi z
u : A ⟶ X
v : B ⟶ Y
sq : CommSq u z f v
⊢ z ≫ v ≫ RegularMono.left = z ≫ v ≫ RegularMono.right

Next tactic:
repeat (rw [← Category.assoc, ← eq_whisker sq.w])
instance (priority := 100) strongMono_of_regularMono (f : X ⟶ Y) [RegularMono f] : StrongMono f :=
  StrongMono.mk' (by
      intro A B z hz u v sq
      have : v ≫ (RegularMono.left : Y ⟶ RegularMono.Z f) = v ≫ RegularMono.right := by
        apply (cancel_epi z).1
        repeat (

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : RegularMono f
A B : C
z : A ⟶ B
hz : Epi z
u : A ⟶ X
v : B ⟶ Y
sq : CommSq u z f v
⊢ z ≫ v ≫ RegularMono.left = z ≫ v ≫ RegularMono.right

Next tactic:
rw [← Category.assoc, ← eq_whisker sq.w]
instance (priority := 100) strongMono_of_regularMono (f : X ⟶ Y) [RegularMono f] : StrongMono f :=
  StrongMono.mk' (by
      intro A B z hz u v sq
      have : v ≫ (RegularMono.left : Y ⟶ RegularMono.Z f) = v ≫ RegularMono.right := by
        apply (cancel_epi z).1
        repeat (

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : RegularMono f
A B : C
z : A ⟶ B
hz : Epi z
u : A ⟶ X
v : B ⟶ Y
sq : CommSq u z f v
⊢ (u ≫ f) ≫ RegularMono.left = z ≫ v ≫ RegularMono.right

Next tactic:
rw [← Category.assoc, ← eq_whisker sq.w]
instance (priority := 100) strongMono_of_regularMono (f : X ⟶ Y) [RegularMono f] : StrongMono f :=
  StrongMono.mk' (by
      intro A B z hz u v sq
      have : v ≫ (RegularMono.left : Y ⟶ RegularMono.Z f) = v ≫ RegularMono.right := by
        apply (cancel_epi z).1
        repeat (

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : RegularMono f
A B : C
z : A ⟶ B
hz : Epi z
u : A ⟶ X
v : B ⟶ Y
sq : CommSq u z f v
⊢ (u ≫ f) ≫ RegularMono.left = (u ≫ f) ≫ RegularMono.right

Next tactic:
rw [← Category.assoc, ← eq_whisker sq.w]
instance (priority := 100) strongMono_of_regularMono (f : X ⟶ Y) [RegularMono f] : StrongMono f :=
  StrongMono.mk' (by
      intro A B z hz u v sq
      have : v ≫ (RegularMono.left : Y ⟶ RegularMono.Z f) = v ≫ RegularMono.right := by
        apply (cancel_epi z).1
        repeat (rw [← Category.assoc, ← eq_whisker sq.w])
        

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : RegularMono f
A B : C
z : A ⟶ B
hz : Epi z
u : A ⟶ X
v : B ⟶ Y
sq : CommSq u z f v
⊢ (u ≫ f) ≫ RegularMono.left = (u ≫ f) ≫ RegularMono.right

Next tactic:
simp only [Category.assoc, RegularMono.w]
instance (priority := 100) strongMono_of_regularMono (f : X ⟶ Y) [RegularMono f] : StrongMono f :=
  StrongMono.mk' (by
      intro A B z hz u v sq
      have : v ≫ (RegularMono.left : Y ⟶ RegularMono.Z f) = v ≫ RegularMono.right := by
        apply (cancel_epi z).1
        repeat (rw [← Category.assoc, ← eq_whisker sq.w])
        simp only [Category.assoc, RegularMono.w]
      

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : RegularMono f
A B : C
z : A ⟶ B
hz : Epi z
u : A ⟶ X
v : B ⟶ Y
sq : CommSq u z f v
this : v ≫ RegularMono.left = v ≫ RegularMono.right
⊢ CommSq.HasLift sq

Next tactic:
obtain ⟨t, ht⟩ := RegularMono.lift' _ _ this
instance (priority := 100) strongMono_of_regularMono (f : X ⟶ Y) [RegularMono f] : StrongMono f :=
  StrongMono.mk' (by
      intro A B z hz u v sq
      have : v ≫ (RegularMono.left : Y ⟶ RegularMono.Z f) = v ≫ RegularMono.right := by
        apply (cancel_epi z).1
        repeat (rw [← Category.assoc, ← eq_whisker sq.w])
        simp only [Category.assoc, RegularMono.w]
      obtain ⟨t, ht⟩ := RegularMono.lift' _ _ this
      

Proof state:
case mk
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : RegularMono f
A B : C
z : A ⟶ B
hz : Epi z
u : A ⟶ X
v : B ⟶ Y
sq : CommSq u z f v
this : v ≫ RegularMono.left = v ≫ RegularMono.right
t : B ⟶ X
ht : t ≫ f = v
⊢ CommSq.HasLift sq

Next tactic:
refine' CommSq.HasLift.mk' ⟨t, (cancel_mono f).1 _, ht⟩
instance (priority := 100) strongMono_of_regularMono (f : X ⟶ Y) [RegularMono f] : StrongMono f :=
  StrongMono.mk' (by
      intro A B z hz u v sq
      have : v ≫ (RegularMono.left : Y ⟶ RegularMono.Z f) = v ≫ RegularMono.right := by
        apply (cancel_epi z).1
        repeat (rw [← Category.assoc, ← eq_whisker sq.w])
        simp only [Category.assoc, RegularMono.w]
      obtain ⟨t, ht⟩ := RegularMono.lift' _ _ this
      refine' CommSq.HasLift.mk' ⟨t, (cancel_mono f).1 _, ht⟩
      

Proof state:
case mk
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : RegularMono f
A B : C
z : A ⟶ B
hz : Epi z
u : A ⟶ X
v : B ⟶ Y
sq : CommSq u z f v
this : v ≫ RegularMono.left = v ≫ RegularMono.right
t : B ⟶ X
ht : t ≫ f = v
⊢ (z ≫ t) ≫ f = u ≫ f

Next tactic:
simp only [Arrow.mk_hom, Arrow.homMk'_left, Category.assoc, ht, sq.w]
instance (priority := 100) regularMonoCategoryOfSplitMonoCategory [SplitMonoCategory C] :
    RegularMonoCategory C where
  regularMonoOfMono f _ := by
    

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
inst✝ : SplitMonoCategory C
X✝ Y✝ : C
f : X✝ ⟶ Y✝
x✝ : Mono f
⊢ RegularMono f

Next tactic:
haveI := isSplitMono_of_mono f
instance (priority := 100) regularMonoCategoryOfSplitMonoCategory [SplitMonoCategory C] :
    RegularMonoCategory C where
  regularMonoOfMono f _ := by
    haveI := isSplitMono_of_mono f
    

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
inst✝ : SplitMonoCategory C
X✝ Y✝ : C
f : X✝ ⟶ Y✝
x✝ : Mono f
this : IsSplitMono f
⊢ RegularMono f

Next tactic:
infer_instance
instance (priority := 100) strongMonoCategory_of_regularMonoCategory [RegularMonoCategory C] :
    StrongMonoCategory C where
  strongMono_of_mono f _ := by
    

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
inst✝ : RegularMonoCategory C
X✝ Y✝ : C
f : X✝ ⟶ Y✝
x✝ : Mono f
⊢ StrongMono f

Next tactic:
haveI := regularMonoOfMono f
instance (priority := 100) strongMonoCategory_of_regularMonoCategory [RegularMonoCategory C] :
    StrongMonoCategory C where
  strongMono_of_mono f _ := by
    haveI := regularMonoOfMono f
    

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
inst✝ : RegularMonoCategory C
X✝ Y✝ : C
f : X✝ ⟶ Y✝
x✝ : Mono f
this : RegularMono f
⊢ StrongMono f

Next tactic:
infer_instance
instance coequalizerRegular (g h : X ⟶ Y) [HasColimit (parallelPair g h)] :
    RegularEpi (coequalizer.π g h) where
  W := X
  left := g
  right := h
  w := coequalizer.condition g h
  isColimit :=
    Cofork.IsColimit.mk _ (fun s => colimit.desc _ s) (by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
g h : X ⟶ Y
inst✝ : HasColimit (parallelPair g h)
⊢ ∀ (s : Cofork g h),
    Cofork.π (Cofork.ofπ (coequalizer.π g h) (_ : g ≫ coequalizer.π g h = h ≫ coequalizer.π g h)) ≫
        (fun s => colimit.desc (parallelPair g h) s) s =
      Cofork.π s

Next tactic:
simp
instance coequalizerRegular (g h : X ⟶ Y) [HasColimit (parallelPair g h)] :
    RegularEpi (coequalizer.π g h) where
  W := X
  left := g
  right := h
  w := coequalizer.condition g h
  isColimit :=
    Cofork.IsColimit.mk _ (fun s => colimit.desc _ s) (by simp) fun s m w => by
      

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
g h : X ⟶ Y
inst✝ : HasColimit (parallelPair g h)
s : Cofork g h
m : (Cofork.ofπ (coequalizer.π g h) (_ : g ≫ coequalizer.π g h = h ≫ coequalizer.π g h)).pt ⟶ s.pt
w : Cofork.π (Cofork.ofπ (coequalizer.π g h) (_ : g ≫ coequalizer.π g h = h ≫ coequalizer.π g h)) ≫ m = Cofork.π s
⊢ m = (fun s => colimit.desc (parallelPair g h) s) s

Next tactic:
apply coequalizer.hom_ext
instance coequalizerRegular (g h : X ⟶ Y) [HasColimit (parallelPair g h)] :
    RegularEpi (coequalizer.π g h) where
  W := X
  left := g
  right := h
  w := coequalizer.condition g h
  isColimit :=
    Cofork.IsColimit.mk _ (fun s => colimit.desc _ s) (by simp) fun s m w => by
      apply coequalizer.hom_ext
      

Proof state:
case h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
g h : X ⟶ Y
inst✝ : HasColimit (parallelPair g h)
s : Cofork g h
m : (Cofork.ofπ (coequalizer.π g h) (_ : g ≫ coequalizer.π g h = h ≫ coequalizer.π g h)).pt ⟶ s.pt
w : Cofork.π (Cofork.ofπ (coequalizer.π g h) (_ : g ≫ coequalizer.π g h = h ≫ coequalizer.π g h)) ≫ m = Cofork.π s
⊢ coequalizer.π g h ≫ m = coequalizer.π g h ≫ (fun s => colimit.desc (parallelPair g h) s) s

Next tactic:
simp [← w]
/-- The second leg of a pushout cocone is a regular epimorphism if the right component is too.

See also `Pushout.sndOfEpi` for the basic epimorphism version, and
`regularOfIsPushoutFstOfRegular` for the flipped version.
-/
def regularOfIsPushoutSndOfRegular {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h : Q ⟶ S} {k : R ⟶ S}
    [gr : RegularEpi g] (comm : f ≫ h = g ≫ k) (t : IsColimit (PushoutCocone.mk _ _ comm)) :
    RegularEpi h where
  W := gr.W
  left := gr.left ≫ f
  right := gr.right ≫ f
  w := by 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y P Q R S : C
f : P ⟶ Q
g : P ⟶ R
h : Q ⟶ S
k : R ⟶ S
gr : RegularEpi g
comm : f ≫ h = g ≫ k
t : IsColimit (PushoutCocone.mk h k comm)
⊢ (RegularEpi.left ≫ f) ≫ h = (RegularEpi.right ≫ f) ≫ h

Next tactic:
rw [Category.assoc, Category.assoc, comm]
/-- The second leg of a pushout cocone is a regular epimorphism if the right component is too.

See also `Pushout.sndOfEpi` for the basic epimorphism version, and
`regularOfIsPushoutFstOfRegular` for the flipped version.
-/
def regularOfIsPushoutSndOfRegular {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h : Q ⟶ S} {k : R ⟶ S}
    [gr : RegularEpi g] (comm : f ≫ h = g ≫ k) (t : IsColimit (PushoutCocone.mk _ _ comm)) :
    RegularEpi h where
  W := gr.W
  left := gr.left ≫ f
  right := gr.right ≫ f
  w := by rw [Category.assoc, Category.assoc, comm]; 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y P Q R S : C
f : P ⟶ Q
g : P ⟶ R
h : Q ⟶ S
k : R ⟶ S
gr : RegularEpi g
comm : f ≫ h = g ≫ k
t : IsColimit (PushoutCocone.mk h k comm)
⊢ RegularEpi.left ≫ g ≫ k = RegularEpi.right ≫ g ≫ k

Next tactic:
simp only [← Category.assoc, eq_whisker gr.w]