l3lab/ntp-mathlib huggingface dataset:
/-- The fork obtained by postcomposing an equalizer fork with a monomorphism is an equalizer. -/
def isEqualizerCompMono {c : Fork f g} (i : IsLimit c) {Z : C} (h : Y ⟶ Z) [hm : Mono h] :
    have : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h := by
      simp only [← Category.assoc]
      exact congrArg (· ≫ h) c.condition;
    IsLimit (Fork.ofι c.ι (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Fork f g
i : IsLimit c
Z : C
h : Y ⟶ Z
hm : Mono h
this : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h
⊢ Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h

Next tactic:
simp [this]
/-- The fork obtained by postcomposing an equalizer fork with a monomorphism is an equalizer. -/
def isEqualizerCompMono {c : Fork f g} (i : IsLimit c) {Z : C} (h : Y ⟶ Z) [hm : Mono h] :
    have : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h := by
      simp only [← Category.assoc]
      exact congrArg (· ≫ h) c.condition;
    IsLimit (Fork.ofι c.ι (by simp [this]) : Fork (f ≫ h) (g ≫ h)) :=
  Fork.IsLimit.mk' _ fun s =>
    let s' : Fork f g := Fork.ofι s.ι (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Fork f g
i : IsLimit c
Z : C
h : Y ⟶ Z
hm : Mono h
s : Fork (f ≫ h) (g ≫ h)
⊢ Fork.ι s ≫ f = Fork.ι s ≫ g

Next tactic:
apply hm.right_cancellation
/-- The fork obtained by postcomposing an equalizer fork with a monomorphism is an equalizer. -/
def isEqualizerCompMono {c : Fork f g} (i : IsLimit c) {Z : C} (h : Y ⟶ Z) [hm : Mono h] :
    have : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h := by
      simp only [← Category.assoc]
      exact congrArg (· ≫ h) c.condition;
    IsLimit (Fork.ofι c.ι (by simp [this]) : Fork (f ≫ h) (g ≫ h)) :=
  Fork.IsLimit.mk' _ fun s =>
    let s' : Fork f g := Fork.ofι s.ι (by apply hm.right_cancellation; 

Proof state:
case a
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Fork f g
i : IsLimit c
Z : C
h : Y ⟶ Z
hm : Mono h
s : Fork (f ≫ h) (g ≫ h)
⊢ (Fork.ι s ≫ f) ≫ h = (Fork.ι s ≫ g) ≫ h

Next tactic:
simp [s.condition]
/-- The fork obtained by postcomposing an equalizer fork with a monomorphism is an equalizer. -/
def isEqualizerCompMono {c : Fork f g} (i : IsLimit c) {Z : C} (h : Y ⟶ Z) [hm : Mono h] :
    have : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h := by
      simp only [← Category.assoc]
      exact congrArg (· ≫ h) c.condition;
    IsLimit (Fork.ofι c.ι (by simp [this]) : Fork (f ≫ h) (g ≫ h)) :=
  Fork.IsLimit.mk' _ fun s =>
    let s' : Fork f g := Fork.ofι s.ι (by apply hm.right_cancellation; simp [s.condition])
    let l := Fork.IsLimit.lift' i s'.ι s'.condition
    ⟨l.1, l.2, fun hm => by
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Fork f g
i : IsLimit c
Z : C
h : Y ⟶ Z
hm✝ : Mono h
s : Fork (f ≫ h) (g ≫ h)
s' : Fork f g := Fork.ofι (Fork.ι s) (_ : Fork.ι s ≫ f = Fork.ι s ≫ g)
l : { l // l ≫ Fork.ι c = Fork.ι s' } := Fork.IsLimit.lift' i (Fork.ι s') (_ : Fork.ι s' ≫ f = Fork.ι s' ≫ g)
m✝ :
  ((Functor.const WalkingParallelPair).obj s.pt).obj zero ⟶
    ((Functor.const WalkingParallelPair).obj (Fork.ofι (Fork.ι c) (_ : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h)).pt).obj
      zero
hm : m✝ ≫ Fork.ι (Fork.ofι (Fork.ι c) (_ : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h)) = Fork.ι s
⊢ m✝ = ↑l

Next tactic:
apply Fork.IsLimit.hom_ext i
/-- The fork obtained by postcomposing an equalizer fork with a monomorphism is an equalizer. -/
def isEqualizerCompMono {c : Fork f g} (i : IsLimit c) {Z : C} (h : Y ⟶ Z) [hm : Mono h] :
    have : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h := by
      simp only [← Category.assoc]
      exact congrArg (· ≫ h) c.condition;
    IsLimit (Fork.ofι c.ι (by simp [this]) : Fork (f ≫ h) (g ≫ h)) :=
  Fork.IsLimit.mk' _ fun s =>
    let s' : Fork f g := Fork.ofι s.ι (by apply hm.right_cancellation; simp [s.condition])
    let l := Fork.IsLimit.lift' i s'.ι s'.condition
    ⟨l.1, l.2, fun hm => by
      apply Fork.IsLimit.hom_ext i; 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Fork f g
i : IsLimit c
Z : C
h : Y ⟶ Z
hm✝ : Mono h
s : Fork (f ≫ h) (g ≫ h)
s' : Fork f g := Fork.ofι (Fork.ι s) (_ : Fork.ι s ≫ f = Fork.ι s ≫ g)
l : { l // l ≫ Fork.ι c = Fork.ι s' } := Fork.IsLimit.lift' i (Fork.ι s') (_ : Fork.ι s' ≫ f = Fork.ι s' ≫ g)
m✝ :
  ((Functor.const WalkingParallelPair).obj s.pt).obj zero ⟶
    ((Functor.const WalkingParallelPair).obj (Fork.ofι (Fork.ι c) (_ : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h)).pt).obj
      zero
hm : m✝ ≫ Fork.ι (Fork.ofι (Fork.ι c) (_ : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h)) = Fork.ι s
⊢ m✝ ≫ Fork.ι c = ↑l ≫ Fork.ι c

Next tactic:
rw [Fork.ι_ofι] at hm
/-- The fork obtained by postcomposing an equalizer fork with a monomorphism is an equalizer. -/
def isEqualizerCompMono {c : Fork f g} (i : IsLimit c) {Z : C} (h : Y ⟶ Z) [hm : Mono h] :
    have : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h := by
      simp only [← Category.assoc]
      exact congrArg (· ≫ h) c.condition;
    IsLimit (Fork.ofι c.ι (by simp [this]) : Fork (f ≫ h) (g ≫ h)) :=
  Fork.IsLimit.mk' _ fun s =>
    let s' : Fork f g := Fork.ofι s.ι (by apply hm.right_cancellation; simp [s.condition])
    let l := Fork.IsLimit.lift' i s'.ι s'.condition
    ⟨l.1, l.2, fun hm => by
      apply Fork.IsLimit.hom_ext i; rw [Fork.ι_ofι] at hm; 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Fork f g
i : IsLimit c
Z : C
h : Y ⟶ Z
hm✝ : Mono h
s : Fork (f ≫ h) (g ≫ h)
s' : Fork f g := Fork.ofι (Fork.ι s) (_ : Fork.ι s ≫ f = Fork.ι s ≫ g)
l : { l // l ≫ Fork.ι c = Fork.ι s' } := Fork.IsLimit.lift' i (Fork.ι s') (_ : Fork.ι s' ≫ f = Fork.ι s' ≫ g)
m✝ :
  ((Functor.const WalkingParallelPair).obj s.pt).obj zero ⟶
    ((Functor.const WalkingParallelPair).obj (Fork.ofι (Fork.ι c) (_ : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h)).pt).obj
      zero
hm : m✝ ≫ Fork.ι c = Fork.ι s
⊢ m✝ ≫ Fork.ι c = ↑l ≫ Fork.ι c

Next tactic:
rw [hm]
/-- The fork obtained by postcomposing an equalizer fork with a monomorphism is an equalizer. -/
def isEqualizerCompMono {c : Fork f g} (i : IsLimit c) {Z : C} (h : Y ⟶ Z) [hm : Mono h] :
    have : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h := by
      simp only [← Category.assoc]
      exact congrArg (· ≫ h) c.condition;
    IsLimit (Fork.ofι c.ι (by simp [this]) : Fork (f ≫ h) (g ≫ h)) :=
  Fork.IsLimit.mk' _ fun s =>
    let s' : Fork f g := Fork.ofι s.ι (by apply hm.right_cancellation; simp [s.condition])
    let l := Fork.IsLimit.lift' i s'.ι s'.condition
    ⟨l.1, l.2, fun hm => by
      apply Fork.IsLimit.hom_ext i; rw [Fork.ι_ofι] at hm; rw [hm]; 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Fork f g
i : IsLimit c
Z : C
h : Y ⟶ Z
hm✝ : Mono h
s : Fork (f ≫ h) (g ≫ h)
s' : Fork f g := Fork.ofι (Fork.ι s) (_ : Fork.ι s ≫ f = Fork.ι s ≫ g)
l : { l // l ≫ Fork.ι c = Fork.ι s' } := Fork.IsLimit.lift' i (Fork.ι s') (_ : Fork.ι s' ≫ f = Fork.ι s' ≫ g)
m✝ :
  ((Functor.const WalkingParallelPair).obj s.pt).obj zero ⟶
    ((Functor.const WalkingParallelPair).obj (Fork.ofι (Fork.ι c) (_ : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h)).pt).obj
      zero
hm : m✝ ≫ Fork.ι c = Fork.ι s
⊢ Fork.ι s = ↑l ≫ Fork.ι c

Next tactic:
exact l.2.symm
/-- An equalizer of an idempotent morphism and the identity is split mono. -/
@[simps]
def splitMonoOfIdempotentOfIsLimitFork {X : C} {f : X ⟶ X} (hf : f ≫ f = f) {c : Fork (𝟙 X) f}
    (i : IsLimit c) : SplitMono c.ι where
  retraction := i.lift (Fork.ofι f (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
f✝ g : X✝ ⟶ Y
X : C
f : X ⟶ X
hf : f ≫ f = f
c : Fork (𝟙 X) f
i : IsLimit c
⊢ f ≫ 𝟙 X = f ≫ f

Next tactic:
simp [hf]
/-- An equalizer of an idempotent morphism and the identity is split mono. -/
@[simps]
def splitMonoOfIdempotentOfIsLimitFork {X : C} {f : X ⟶ X} (hf : f ≫ f = f) {c : Fork (𝟙 X) f}
    (i : IsLimit c) : SplitMono c.ι where
  retraction := i.lift (Fork.ofι f (by simp [hf]))
  id := by
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
f✝ g : X✝ ⟶ Y
X : C
f : X ⟶ X
hf : f ≫ f = f
c : Fork (𝟙 X) f
i : IsLimit c
⊢ Fork.ι c ≫ IsLimit.lift i (Fork.ofι f (_ : f ≫ 𝟙 X = f ≫ f)) =
    𝟙 (((Functor.const WalkingParallelPair).obj c.pt).obj zero)

Next tactic:
letI := mono_of_isLimit_fork i
/-- An equalizer of an idempotent morphism and the identity is split mono. -/
@[simps]
def splitMonoOfIdempotentOfIsLimitFork {X : C} {f : X ⟶ X} (hf : f ≫ f = f) {c : Fork (𝟙 X) f}
    (i : IsLimit c) : SplitMono c.ι where
  retraction := i.lift (Fork.ofι f (by simp [hf]))
  id := by
    letI := mono_of_isLimit_fork i
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
f✝ g : X✝ ⟶ Y
X : C
f : X ⟶ X
hf : f ≫ f = f
c : Fork (𝟙 X) f
i : IsLimit c
this : Mono (Fork.ι c) := mono_of_isLimit_fork i
⊢ Fork.ι c ≫ IsLimit.lift i (Fork.ofι f (_ : f ≫ 𝟙 X = f ≫ f)) =
    𝟙 (((Functor.const WalkingParallelPair).obj c.pt).obj zero)

Next tactic:
rw [← cancel_mono_id c.ι, Category.assoc, Fork.IsLimit.lift_ι, Fork.ι_ofι, ← c.condition]
/-- An equalizer of an idempotent morphism and the identity is split mono. -/
@[simps]
def splitMonoOfIdempotentOfIsLimitFork {X : C} {f : X ⟶ X} (hf : f ≫ f = f) {c : Fork (𝟙 X) f}
    (i : IsLimit c) : SplitMono c.ι where
  retraction := i.lift (Fork.ofι f (by simp [hf]))
  id := by
    letI := mono_of_isLimit_fork i
    rw [← cancel_mono_id c.ι, Category.assoc, Fork.IsLimit.lift_ι, Fork.ι_ofι, ← c.condition]
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
f✝ g : X✝ ⟶ Y
X : C
f : X ⟶ X
hf : f ≫ f = f
c : Fork (𝟙 X) f
i : IsLimit c
this : Mono (Fork.ι c) := mono_of_isLimit_fork i
⊢ Fork.ι c ≫ 𝟙 X = Fork.ι c

Next tactic:
exact Category.comp_id c.ι
/-- A split epi `f` coequalizes `(f ≫ section_ f)` and `(𝟙 X)`.
Here we build the cocone, and show in `isSplitEpiCoequalizes` that it is a colimit cocone.
-/
-- @[simps (config := { rhsMd := semireducible })] Porting note: no semireducible
@[simps!]
noncomputable def coconeOfIsSplitEpi : Cofork (𝟙 X) (f ≫ section_ f) :=
  Cofork.ofπ f (by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
inst✝ : IsSplitEpi f
⊢ 𝟙 X ≫ f = (f ≫ section_ f) ≫ f

Next tactic:
simp
/-- A split epi `f` coequalizes `(f ≫ section_ f)` and `(𝟙 X)`.
-/
noncomputable def isSplitEpiCoequalizes {X Y : C} (f : X ⟶ Y) [IsSplitEpi f] :
    IsColimit (coconeOfIsSplitEpi f) :=
  Cofork.IsColimit.mk' _ fun s =>
    ⟨section_ f ≫ s.π, by
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X✝ Y✝ : C
f✝ g : X✝ ⟶ Y✝
inst✝¹ : IsSplitEpi f✝
X Y : C
f : X ⟶ Y
inst✝ : IsSplitEpi f
s : Cofork (𝟙 X) (f ≫ section_ f)
⊢ Cofork.π (coconeOfIsSplitEpi f) ≫ section_ f ≫ Cofork.π s = Cofork.π s

Next tactic:
dsimp
/-- A split epi `f` coequalizes `(f ≫ section_ f)` and `(𝟙 X)`.
-/
noncomputable def isSplitEpiCoequalizes {X Y : C} (f : X ⟶ Y) [IsSplitEpi f] :
    IsColimit (coconeOfIsSplitEpi f) :=
  Cofork.IsColimit.mk' _ fun s =>
    ⟨section_ f ≫ s.π, by
      dsimp
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X✝ Y✝ : C
f✝ g : X✝ ⟶ Y✝
inst✝¹ : IsSplitEpi f✝
X Y : C
f : X ⟶ Y
inst✝ : IsSplitEpi f
s : Cofork (𝟙 X) (f ≫ section_ f)
⊢ f ≫ section_ f ≫ Cofork.π s = Cofork.π s

Next tactic:
rw [← Category.assoc, ← s.condition, Category.id_comp]
/-- A split epi `f` coequalizes `(f ≫ section_ f)` and `(𝟙 X)`.
-/
noncomputable def isSplitEpiCoequalizes {X Y : C} (f : X ⟶ Y) [IsSplitEpi f] :
    IsColimit (coconeOfIsSplitEpi f) :=
  Cofork.IsColimit.mk' _ fun s =>
    ⟨section_ f ≫ s.π, by
      dsimp
      rw [← Category.assoc, ← s.condition, Category.id_comp], fun hm => by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X✝ Y✝ : C
f✝ g : X✝ ⟶ Y✝
inst✝¹ : IsSplitEpi f✝
X Y : C
f : X ⟶ Y
inst✝ : IsSplitEpi f
s : Cofork (𝟙 X) (f ≫ section_ f)
m✝ :
  ((Functor.const WalkingParallelPair).obj (coconeOfIsSplitEpi f).pt).obj one ⟶
    ((Functor.const WalkingParallelPair).obj s.pt).obj one
hm : Cofork.π (coconeOfIsSplitEpi f) ≫ m✝ = Cofork.π s
⊢ m✝ = section_ f ≫ Cofork.π s

Next tactic:
simp [← hm]
/-- The cofork obtained by precomposing a coequalizer cofork with an epimorphism is
a coequalizer. -/
def isCoequalizerEpiComp {c : Cofork f g} (i : IsColimit c) {W : C} (h : W ⟶ X) [hm : Epi h] :
    have : (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c := by
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Cofork f g
i : IsColimit c
W : C
h : W ⟶ X
hm : Epi h
⊢ (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c

Next tactic:
simp only [Category.assoc]
/-- The cofork obtained by precomposing a coequalizer cofork with an epimorphism is
a coequalizer. -/
def isCoequalizerEpiComp {c : Cofork f g} (i : IsColimit c) {W : C} (h : W ⟶ X) [hm : Epi h] :
    have : (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c := by
      simp only [Category.assoc]
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Cofork f g
i : IsColimit c
W : C
h : W ⟶ X
hm : Epi h
⊢ h ≫ f ≫ Cofork.π c = h ≫ g ≫ Cofork.π c

Next tactic:
exact congrArg (h ≫ ·) c.condition
/-- The cofork obtained by precomposing a coequalizer cofork with an epimorphism is
a coequalizer. -/
def isCoequalizerEpiComp {c : Cofork f g} (i : IsColimit c) {W : C} (h : W ⟶ X) [hm : Epi h] :
    have : (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c := by
      simp only [Category.assoc]
      exact congrArg (h ≫ ·) c.condition
    IsColimit (Cofork.ofπ c.π (this) : Cofork (h ≫ f) (h ≫ g)) :=
  Cofork.IsColimit.mk' _ fun s =>
    let s' : Cofork f g :=
      Cofork.ofπ s.π (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Cofork f g
i : IsColimit c
W : C
h : W ⟶ X
hm : Epi h
s : Cofork (h ≫ f) (h ≫ g)
⊢ f ≫ Cofork.π s = g ≫ Cofork.π s

Next tactic:
apply hm.left_cancellation
/-- The cofork obtained by precomposing a coequalizer cofork with an epimorphism is
a coequalizer. -/
def isCoequalizerEpiComp {c : Cofork f g} (i : IsColimit c) {W : C} (h : W ⟶ X) [hm : Epi h] :
    have : (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c := by
      simp only [Category.assoc]
      exact congrArg (h ≫ ·) c.condition
    IsColimit (Cofork.ofπ c.π (this) : Cofork (h ≫ f) (h ≫ g)) :=
  Cofork.IsColimit.mk' _ fun s =>
    let s' : Cofork f g :=
      Cofork.ofπ s.π (by apply hm.left_cancellation; 

Proof state:
case a
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Cofork f g
i : IsColimit c
W : C
h : W ⟶ X
hm : Epi h
s : Cofork (h ≫ f) (h ≫ g)
⊢ h ≫ f ≫ Cofork.π s = h ≫ g ≫ Cofork.π s

Next tactic:
simp_rw [← Category.assoc, s.condition]
/-- The cofork obtained by precomposing a coequalizer cofork with an epimorphism is
a coequalizer. -/
def isCoequalizerEpiComp {c : Cofork f g} (i : IsColimit c) {W : C} (h : W ⟶ X) [hm : Epi h] :
    have : (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c := by
      simp only [Category.assoc]
      exact congrArg (h ≫ ·) c.condition
    IsColimit (Cofork.ofπ c.π (this) : Cofork (h ≫ f) (h ≫ g)) :=
  Cofork.IsColimit.mk' _ fun s =>
    let s' : Cofork f g :=
      Cofork.ofπ s.π (by apply hm.left_cancellation; simp_rw [← Category.assoc, s.condition])
    let l := Cofork.IsColimit.desc' i s'.π s'.condition
    ⟨l.1, l.2, fun hm => by
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Cofork f g
i : IsColimit c
W : C
h : W ⟶ X
hm✝ : Epi h
s : Cofork (h ≫ f) (h ≫ g)
s' : Cofork f g := Cofork.ofπ (Cofork.π s) (_ : f ≫ Cofork.π s = g ≫ Cofork.π s)
l : { l // Cofork.π c ≫ l = Cofork.π s' } :=
  Cofork.IsColimit.desc' i (Cofork.π s') (_ : f ≫ Cofork.π s' = g ≫ Cofork.π s')
m✝ :
  ((Functor.const WalkingParallelPair).obj
          (Cofork.ofπ (Cofork.π c) (_ : (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c)).pt).obj
      one ⟶
    ((Functor.const WalkingParallelPair).obj s.pt).obj one
hm : Cofork.π (Cofork.ofπ (Cofork.π c) (_ : (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c)) ≫ m✝ = Cofork.π s
⊢ m✝ = ↑l

Next tactic:
apply Cofork.IsColimit.hom_ext i
/-- The cofork obtained by precomposing a coequalizer cofork with an epimorphism is
a coequalizer. -/
def isCoequalizerEpiComp {c : Cofork f g} (i : IsColimit c) {W : C} (h : W ⟶ X) [hm : Epi h] :
    have : (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c := by
      simp only [Category.assoc]
      exact congrArg (h ≫ ·) c.condition
    IsColimit (Cofork.ofπ c.π (this) : Cofork (h ≫ f) (h ≫ g)) :=
  Cofork.IsColimit.mk' _ fun s =>
    let s' : Cofork f g :=
      Cofork.ofπ s.π (by apply hm.left_cancellation; simp_rw [← Category.assoc, s.condition])
    let l := Cofork.IsColimit.desc' i s'.π s'.condition
    ⟨l.1, l.2, fun hm => by
      apply Cofork.IsColimit.hom_ext i; 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Cofork f g
i : IsColimit c
W : C
h : W ⟶ X
hm✝ : Epi h
s : Cofork (h ≫ f) (h ≫ g)
s' : Cofork f g := Cofork.ofπ (Cofork.π s) (_ : f ≫ Cofork.π s = g ≫ Cofork.π s)
l : { l // Cofork.π c ≫ l = Cofork.π s' } :=
  Cofork.IsColimit.desc' i (Cofork.π s') (_ : f ≫ Cofork.π s' = g ≫ Cofork.π s')
m✝ :
  ((Functor.const WalkingParallelPair).obj
          (Cofork.ofπ (Cofork.π c) (_ : (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c)).pt).obj
      one ⟶
    ((Functor.const WalkingParallelPair).obj s.pt).obj one
hm : Cofork.π (Cofork.ofπ (Cofork.π c) (_ : (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c)) ≫ m✝ = Cofork.π s
⊢ Cofork.π c ≫ m✝ = Cofork.π c ≫ ↑l

Next tactic:
rw [Cofork.π_ofπ] at hm
/-- The cofork obtained by precomposing a coequalizer cofork with an epimorphism is
a coequalizer. -/
def isCoequalizerEpiComp {c : Cofork f g} (i : IsColimit c) {W : C} (h : W ⟶ X) [hm : Epi h] :
    have : (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c := by
      simp only [Category.assoc]
      exact congrArg (h ≫ ·) c.condition
    IsColimit (Cofork.ofπ c.π (this) : Cofork (h ≫ f) (h ≫ g)) :=
  Cofork.IsColimit.mk' _ fun s =>
    let s' : Cofork f g :=
      Cofork.ofπ s.π (by apply hm.left_cancellation; simp_rw [← Category.assoc, s.condition])
    let l := Cofork.IsColimit.desc' i s'.π s'.condition
    ⟨l.1, l.2, fun hm => by
      apply Cofork.IsColimit.hom_ext i; rw [Cofork.π_ofπ] at hm; 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Cofork f g
i : IsColimit c
W : C
h : W ⟶ X
hm✝ : Epi h
s : Cofork (h ≫ f) (h ≫ g)
s' : Cofork f g := Cofork.ofπ (Cofork.π s) (_ : f ≫ Cofork.π s = g ≫ Cofork.π s)
l : { l // Cofork.π c ≫ l = Cofork.π s' } :=
  Cofork.IsColimit.desc' i (Cofork.π s') (_ : f ≫ Cofork.π s' = g ≫ Cofork.π s')
m✝ :
  ((Functor.const WalkingParallelPair).obj
          (Cofork.ofπ (Cofork.π c) (_ : (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c)).pt).obj
      one ⟶
    ((Functor.const WalkingParallelPair).obj s.pt).obj one
hm : Cofork.π c ≫ m✝ = Cofork.π s
⊢ Cofork.π c ≫ m✝ = Cofork.π c ≫ ↑l

Next tactic:
rw [hm]
/-- The cofork obtained by precomposing a coequalizer cofork with an epimorphism is
a coequalizer. -/
def isCoequalizerEpiComp {c : Cofork f g} (i : IsColimit c) {W : C} (h : W ⟶ X) [hm : Epi h] :
    have : (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c := by
      simp only [Category.assoc]
      exact congrArg (h ≫ ·) c.condition
    IsColimit (Cofork.ofπ c.π (this) : Cofork (h ≫ f) (h ≫ g)) :=
  Cofork.IsColimit.mk' _ fun s =>
    let s' : Cofork f g :=
      Cofork.ofπ s.π (by apply hm.left_cancellation; simp_rw [← Category.assoc, s.condition])
    let l := Cofork.IsColimit.desc' i s'.π s'.condition
    ⟨l.1, l.2, fun hm => by
      apply Cofork.IsColimit.hom_ext i; rw [Cofork.π_ofπ] at hm; rw [hm]; 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f g : X ⟶ Y
c : Cofork f g
i : IsColimit c
W : C
h : W ⟶ X
hm✝ : Epi h
s : Cofork (h ≫ f) (h ≫ g)
s' : Cofork f g := Cofork.ofπ (Cofork.π s) (_ : f ≫ Cofork.π s = g ≫ Cofork.π s)
l : { l // Cofork.π c ≫ l = Cofork.π s' } :=
  Cofork.IsColimit.desc' i (Cofork.π s') (_ : f ≫ Cofork.π s' = g ≫ Cofork.π s')
m✝ :
  ((Functor.const WalkingParallelPair).obj
          (Cofork.ofπ (Cofork.π c) (_ : (h ≫ f) ≫ Cofork.π c = (h ≫ g) ≫ Cofork.π c)).pt).obj
      one ⟶
    ((Functor.const WalkingParallelPair).obj s.pt).obj one
hm : Cofork.π c ≫ m✝ = Cofork.π s
⊢ Cofork.π s = Cofork.π c ≫ ↑l

Next tactic:
exact l.2.symm
/-- A coequalizer of an idempotent morphism and the identity is split epi. -/
@[simps]
def splitEpiOfIdempotentOfIsColimitCofork {X : C} {f : X ⟶ X} (hf : f ≫ f = f) {c : Cofork (𝟙 X) f}
    (i : IsColimit c) : SplitEpi c.π where
  section_ := i.desc (Cofork.ofπ f (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
f✝ g : X✝ ⟶ Y
X : C
f : X ⟶ X
hf : f ≫ f = f
c : Cofork (𝟙 X) f
i : IsColimit c
⊢ 𝟙 X ≫ f = f ≫ f

Next tactic:
simp [hf]
/-- A coequalizer of an idempotent morphism and the identity is split epi. -/
@[simps]
def splitEpiOfIdempotentOfIsColimitCofork {X : C} {f : X ⟶ X} (hf : f ≫ f = f) {c : Cofork (𝟙 X) f}
    (i : IsColimit c) : SplitEpi c.π where
  section_ := i.desc (Cofork.ofπ f (by simp [hf]))
  id := by
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
f✝ g : X✝ ⟶ Y
X : C
f : X ⟶ X
hf : f ≫ f = f
c : Cofork (𝟙 X) f
i : IsColimit c
⊢ IsColimit.desc i (Cofork.ofπ f (_ : 𝟙 X ≫ f = f ≫ f)) ≫ Cofork.π c =
    𝟙 (((Functor.const WalkingParallelPair).obj c.pt).obj one)

Next tactic:
letI := epi_of_isColimit_cofork i
/-- A coequalizer of an idempotent morphism and the identity is split epi. -/
@[simps]
def splitEpiOfIdempotentOfIsColimitCofork {X : C} {f : X ⟶ X} (hf : f ≫ f = f) {c : Cofork (𝟙 X) f}
    (i : IsColimit c) : SplitEpi c.π where
  section_ := i.desc (Cofork.ofπ f (by simp [hf]))
  id := by
    letI := epi_of_isColimit_cofork i
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
f✝ g : X✝ ⟶ Y
X : C
f : X ⟶ X
hf : f ≫ f = f
c : Cofork (𝟙 X) f
i : IsColimit c
this : Epi (Cofork.π c) := epi_of_isColimit_cofork i
⊢ IsColimit.desc i (Cofork.ofπ f (_ : 𝟙 X ≫ f = f ≫ f)) ≫ Cofork.π c =
    𝟙 (((Functor.const WalkingParallelPair).obj c.pt).obj one)

Next tactic:
rw [← cancel_epi_id c.π, ← Category.assoc, Cofork.IsColimit.π_desc, Cofork.π_ofπ, ←
      c.condition]
/-- A coequalizer of an idempotent morphism and the identity is split epi. -/
@[simps]
def splitEpiOfIdempotentOfIsColimitCofork {X : C} {f : X ⟶ X} (hf : f ≫ f = f) {c : Cofork (𝟙 X) f}
    (i : IsColimit c) : SplitEpi c.π where
  section_ := i.desc (Cofork.ofπ f (by simp [hf]))
  id := by
    letI := epi_of_isColimit_cofork i
    rw [← cancel_epi_id c.π, ← Category.assoc, Cofork.IsColimit.π_desc, Cofork.π_ofπ, ←
      c.condition]
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
f✝ g : X✝ ⟶ Y
X : C
f : X ⟶ X
hf : f ≫ f = f
c : Cofork (𝟙 X) f
i : IsColimit c
this : Epi (Cofork.π c) := epi_of_isColimit_cofork i
⊢ 𝟙 X ≫ Cofork.π c = Cofork.π c

Next tactic:
exact Category.id_comp _
instance [Preorder α] : @Topology.IsUpperSet α (upperSet α) _ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : Preorder α
⊢ Topology.IsUpperSet α

Next tactic:
letI := upperSet α
instance [Preorder α] : @Topology.IsUpperSet α (upperSet α) _ := by
  letI := upperSet α
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : Preorder α
this : TopologicalSpace α := upperSet α
⊢ Topology.IsUpperSet α

Next tactic:
exact ⟨rfl⟩
instance [Preorder α] : @Topology.IsLowerSet α (lowerSet α) _ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : Preorder α
⊢ Topology.IsLowerSet α

Next tactic:
letI := lowerSet α
instance [Preorder α] : @Topology.IsLowerSet α (lowerSet α) _ := by
  letI := lowerSet α
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : Preorder α
this : TopologicalSpace α := lowerSet α
⊢ Topology.IsLowerSet α

Next tactic:
exact ⟨rfl⟩
instance _root_.OrderDual.instIsLowerSet [Preorder α] [TopologicalSpace α] [Topology.IsUpperSet α] :
    Topology.IsLowerSet αᵒᵈ where
  topology_eq_lowerSetTopology := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁵ : Preorder α
inst✝⁴ : TopologicalSpace α
inst✝³ : Topology.IsUpperSet α
s : Set α
inst✝² : Preorder α
inst✝¹ : TopologicalSpace α
inst✝ : Topology.IsUpperSet α
⊢ instTopologicalSpaceOrderDual = lowerSet αᵒᵈ

Next tactic:
ext
instance _root_.OrderDual.instIsLowerSet [Preorder α] [TopologicalSpace α] [Topology.IsUpperSet α] :
    Topology.IsLowerSet αᵒᵈ where
  topology_eq_lowerSetTopology := by ext; 

Proof state:
case a.h.a
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁵ : Preorder α
inst✝⁴ : TopologicalSpace α
inst✝³ : Topology.IsUpperSet α
s : Set α
inst✝² : Preorder α
inst✝¹ : TopologicalSpace α
inst✝ : Topology.IsUpperSet α
x✝ : Set αᵒᵈ
⊢ IsOpen x✝ ↔ IsOpen x✝

Next tactic:
rw [IsUpperSet.topology_eq α]