l3lab/ntp-mathlib huggingface dataset:
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      intro y
      exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
    let φ : Y → X := fun y => (H y).some.1
    have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
    refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩
    

Proof state:
case refine'_1
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
⊢ Monotone φ
case refine'_2
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
⊢ { toFun := φ, monotone' := ?refine'_1 } ≫ f = 𝟙 Y

Next tactic:
swap
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      intro y
      exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
    let φ : Y → X := fun y => (H y).some.1
    have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
    refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩
    swap
    · 

Proof state:
case refine'_2
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
⊢ { toFun := φ, monotone' := ?refine'_1 } ≫ f = 𝟙 Y

Next tactic:
ext b
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      intro y
      exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
    let φ : Y → X := fun y => (H y).some.1
    have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
    refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩
    swap
    · ext b
      

Proof state:
case refine'_2.w
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
b : (forget NonemptyFinLinOrd).obj Y
⊢ ({ toFun := φ, monotone' := ?refine'_1 } ≫ f) b = (𝟙 Y) b

Next tactic:
apply hφ
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      intro y
      exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
    let φ : Y → X := fun y => (H y).some.1
    have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
    refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩
    swap
    · ext b
      apply hφ
    · 

Proof state:
case refine'_1
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
⊢ Monotone φ

Next tactic:
intro a b
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      intro y
      exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
    let φ : Y → X := fun y => (H y).some.1
    have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
    refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩
    swap
    · ext b
      apply hφ
    · intro a b
      

Proof state:
case refine'_1
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
a b : ↑Y
⊢ a ≤ b → φ a ≤ φ b

Next tactic:
contrapose
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      intro y
      exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
    let φ : Y → X := fun y => (H y).some.1
    have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
    refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩
    swap
    · ext b
      apply hφ
    · intro a b
      contrapose
      

Proof state:
case refine'_1
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
a b : ↑Y
⊢ ¬φ a ≤ φ b → ¬a ≤ b

Next tactic:
intro h
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      intro y
      exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
    let φ : Y → X := fun y => (H y).some.1
    have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
    refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩
    swap
    · ext b
      apply hφ
    · intro a b
      contrapose
      intro h
      

Proof state:
case refine'_1
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
a b : ↑Y
h : ¬φ a ≤ φ b
⊢ ¬a ≤ b

Next tactic:
simp only [not_le] at h ⊢
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      intro y
      exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
    let φ : Y → X := fun y => (H y).some.1
    have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
    refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩
    swap
    · ext b
      apply hφ
    · intro a b
      contrapose
      intro h
      simp only [not_le] at h ⊢
      

Proof state:
case refine'_1
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
a b : ↑Y
h : ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {b}))) < ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {a})))
⊢ b < a

Next tactic:
suffices b ≤ a by
        apply lt_of_le_of_ne this
        rintro rfl
        exfalso
        simp at h
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      intro y
      exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
    let φ : Y → X := fun y => (H y).some.1
    have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
    refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩
    swap
    · ext b
      apply hφ
    · intro a b
      contrapose
      intro h
      simp only [not_le] at h ⊢
      suffices b ≤ a by
        

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
a b : ↑Y
h : ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {b}))) < ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {a})))
this : b ≤ a
⊢ b < a

Next tactic:
apply lt_of_le_of_ne this
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      intro y
      exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
    let φ : Y → X := fun y => (H y).some.1
    have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
    refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩
    swap
    · ext b
      apply hφ
    · intro a b
      contrapose
      intro h
      simp only [not_le] at h ⊢
      suffices b ≤ a by
        apply lt_of_le_of_ne this
        

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
a b : ↑Y
h : ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {b}))) < ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {a})))
this : b ≤ a
⊢ b ≠ a

Next tactic:
rintro rfl
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      intro y
      exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
    let φ : Y → X := fun y => (H y).some.1
    have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
    refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩
    swap
    · ext b
      apply hφ
    · intro a b
      contrapose
      intro h
      simp only [not_le] at h ⊢
      suffices b ≤ a by
        apply lt_of_le_of_ne this
        rintro rfl
        

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
b : ↑Y
h : ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {b}))) < ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {b})))
this : b ≤ b
⊢ False

Next tactic:
exfalso
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      intro y
      exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
    let φ : Y → X := fun y => (H y).some.1
    have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
    refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩
    swap
    · ext b
      apply hφ
    · intro a b
      contrapose
      intro h
      simp only [not_le] at h ⊢
      suffices b ≤ a by
        apply lt_of_le_of_ne this
        rintro rfl
        exfalso
        

Proof state:
case h
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
b : ↑Y
h : ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {b}))) < ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {b})))
this : b ≤ b
⊢ False

Next tactic:
simp at h
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      intro y
      exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
    let φ : Y → X := fun y => (H y).some.1
    have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
    refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩
    swap
    · ext b
      apply hφ
    · intro a b
      contrapose
      intro h
      simp only [not_le] at h ⊢
      suffices b ≤ a by
        apply lt_of_le_of_ne this
        rintro rfl
        exfalso
        simp at h
      

Proof state:
case refine'_1
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
a b : ↑Y
h : ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {b}))) < ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {a})))
⊢ b ≤ a

Next tactic:
have H : f (φ b) ≤ f (φ a) := f.monotone (le_of_lt h)
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      intro y
      exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
    let φ : Y → X := fun y => (H y).some.1
    have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
    refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩
    swap
    · ext b
      apply hφ
    · intro a b
      contrapose
      intro h
      simp only [not_le] at h ⊢
      suffices b ≤ a by
        apply lt_of_le_of_ne this
        rintro rfl
        exfalso
        simp at h
      have H : f (φ b) ≤ f (φ a) := f.monotone (le_of_lt h)
      

Proof state:
case refine'_1
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H✝ : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
φ : ↑Y → ↑X := fun y => ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {y})))
hφ : ∀ (y : ↑Y), f (φ y) = y
a b : ↑Y
h : ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {b}))) < ↑(Nonempty.some (_ : Nonempty ↑(⇑f ⁻¹' {a})))
H : f (φ b) ≤ f (φ a)
⊢ b ≤ a

Next tactic:
simpa only [hφ] using H
instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f => by
    

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
⊢ Nonempty (StrongEpiMonoFactorisation f)

Next tactic:
letI : NonemptyFiniteLinearOrder (Set.image f ⊤) := ⟨by infer_instance⟩
instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f => by
    letI : NonemptyFiniteLinearOrder (Set.image f ⊤) := ⟨by 

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
⊢ Nonempty ↑(⇑f '' ⊤)

Next tactic:
infer_instance
instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f => by
    letI : NonemptyFiniteLinearOrder (Set.image f ⊤) := ⟨by infer_instance⟩
    

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
this : NonemptyFiniteLinearOrder ↑(⇑f '' ⊤) := NonemptyFiniteLinearOrder.mk
⊢ Nonempty (StrongEpiMonoFactorisation f)

Next tactic:
let I := NonemptyFinLinOrd.of (Set.image f ⊤)
instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f => by
    letI : NonemptyFiniteLinearOrder (Set.image f ⊤) := ⟨by infer_instance⟩
    let I := NonemptyFinLinOrd.of (Set.image f ⊤)
    

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
this : NonemptyFiniteLinearOrder ↑(⇑f '' ⊤) := NonemptyFiniteLinearOrder.mk
I : NonemptyFinLinOrd := of ↑(⇑f '' ⊤)
⊢ Nonempty (StrongEpiMonoFactorisation f)

Next tactic:
let e : X ⟶ I := ⟨fun x => ⟨f x, ⟨x, by tauto⟩⟩, fun x₁ x₂ h => f.monotone h⟩
instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f => by
    letI : NonemptyFiniteLinearOrder (Set.image f ⊤) := ⟨by infer_instance⟩
    let I := NonemptyFinLinOrd.of (Set.image f ⊤)
    let e : X ⟶ I := ⟨fun x => ⟨f x, ⟨x, by 

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
this : NonemptyFiniteLinearOrder ↑(⇑f '' ⊤) := NonemptyFiniteLinearOrder.mk
I : NonemptyFinLinOrd := of ↑(⇑f '' ⊤)
x : ↑X
⊢ x ∈ ⊤ ∧ f x = f x

Next tactic:
tauto
instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f => by
    letI : NonemptyFiniteLinearOrder (Set.image f ⊤) := ⟨by infer_instance⟩
    let I := NonemptyFinLinOrd.of (Set.image f ⊤)
    let e : X ⟶ I := ⟨fun x => ⟨f x, ⟨x, by tauto⟩⟩, fun x₁ x₂ h => f.monotone h⟩
    

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
this : NonemptyFiniteLinearOrder ↑(⇑f '' ⊤) := NonemptyFiniteLinearOrder.mk
I : NonemptyFinLinOrd := of ↑(⇑f '' ⊤)
e : X ⟶ I :=
  { toFun := fun x => { val := f x, property := (_ : ∃ a ∈ ⊤, f a = f x) },
    monotone' := (_ : ∀ (x₁ x₂ : ↑X), x₁ ≤ x₂ → f x₁ ≤ f x₂) }
⊢ Nonempty (StrongEpiMonoFactorisation f)

Next tactic:
let m : I ⟶ Y := ⟨fun y => y.1, by tauto⟩
instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f => by
    letI : NonemptyFiniteLinearOrder (Set.image f ⊤) := ⟨by infer_instance⟩
    let I := NonemptyFinLinOrd.of (Set.image f ⊤)
    let e : X ⟶ I := ⟨fun x => ⟨f x, ⟨x, by tauto⟩⟩, fun x₁ x₂ h => f.monotone h⟩
    let m : I ⟶ Y := ⟨fun y => y.1, by 

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
this : NonemptyFiniteLinearOrder ↑(⇑f '' ⊤) := NonemptyFiniteLinearOrder.mk
I : NonemptyFinLinOrd := of ↑(⇑f '' ⊤)
e : X ⟶ I :=
  { toFun := fun x => { val := f x, property := (_ : ∃ a ∈ ⊤, f a = f x) },
    monotone' := (_ : ∀ (x₁ x₂ : ↑X), x₁ ≤ x₂ → f x₁ ≤ f x₂) }
⊢ Monotone fun y => ↑y

Next tactic:
tauto
instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f => by
    letI : NonemptyFiniteLinearOrder (Set.image f ⊤) := ⟨by infer_instance⟩
    let I := NonemptyFinLinOrd.of (Set.image f ⊤)
    let e : X ⟶ I := ⟨fun x => ⟨f x, ⟨x, by tauto⟩⟩, fun x₁ x₂ h => f.monotone h⟩
    let m : I ⟶ Y := ⟨fun y => y.1, by tauto⟩
    

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
this : NonemptyFiniteLinearOrder ↑(⇑f '' ⊤) := NonemptyFiniteLinearOrder.mk
I : NonemptyFinLinOrd := of ↑(⇑f '' ⊤)
e : X ⟶ I :=
  { toFun := fun x => { val := f x, property := (_ : ∃ a ∈ ⊤, f a = f x) },
    monotone' := (_ : ∀ (x₁ x₂ : ↑X), x₁ ≤ x₂ → f x₁ ≤ f x₂) }
m : I ⟶ Y := { toFun := fun y => ↑y, monotone' := (_ : ∀ ⦃a b : ↑I⦄, a ≤ b → a ≤ b) }
⊢ Nonempty (StrongEpiMonoFactorisation f)

Next tactic:
haveI : Epi e := by
      rw [epi_iff_surjective]
      rintro ⟨_, y, h, rfl⟩
      exact ⟨y, rfl⟩
instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f => by
    letI : NonemptyFiniteLinearOrder (Set.image f ⊤) := ⟨by infer_instance⟩
    let I := NonemptyFinLinOrd.of (Set.image f ⊤)
    let e : X ⟶ I := ⟨fun x => ⟨f x, ⟨x, by tauto⟩⟩, fun x₁ x₂ h => f.monotone h⟩
    let m : I ⟶ Y := ⟨fun y => y.1, by tauto⟩
    haveI : Epi e := by
      

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
this : NonemptyFiniteLinearOrder ↑(⇑f '' ⊤) := NonemptyFiniteLinearOrder.mk
I : NonemptyFinLinOrd := of ↑(⇑f '' ⊤)
e : X ⟶ I :=
  { toFun := fun x => { val := f x, property := (_ : ∃ a ∈ ⊤, f a = f x) },
    monotone' := (_ : ∀ (x₁ x₂ : ↑X), x₁ ≤ x₂ → f x₁ ≤ f x₂) }
m : I ⟶ Y := { toFun := fun y => ↑y, monotone' := (_ : ∀ ⦃a b : ↑I⦄, a ≤ b → a ≤ b) }
⊢ Epi e

Next tactic:
rw [epi_iff_surjective]
instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f => by
    letI : NonemptyFiniteLinearOrder (Set.image f ⊤) := ⟨by infer_instance⟩
    let I := NonemptyFinLinOrd.of (Set.image f ⊤)
    let e : X ⟶ I := ⟨fun x => ⟨f x, ⟨x, by tauto⟩⟩, fun x₁ x₂ h => f.monotone h⟩
    let m : I ⟶ Y := ⟨fun y => y.1, by tauto⟩
    haveI : Epi e := by
      rw [epi_iff_surjective]
      

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
this : NonemptyFiniteLinearOrder ↑(⇑f '' ⊤) := NonemptyFiniteLinearOrder.mk
I : NonemptyFinLinOrd := of ↑(⇑f '' ⊤)
e : X ⟶ I :=
  { toFun := fun x => { val := f x, property := (_ : ∃ a ∈ ⊤, f a = f x) },
    monotone' := (_ : ∀ (x₁ x₂ : ↑X), x₁ ≤ x₂ → f x₁ ≤ f x₂) }
m : I ⟶ Y := { toFun := fun y => ↑y, monotone' := (_ : ∀ ⦃a b : ↑I⦄, a ≤ b → a ≤ b) }
⊢ Function.Surjective ⇑e

Next tactic:
rintro ⟨_, y, h, rfl⟩
instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f => by
    letI : NonemptyFiniteLinearOrder (Set.image f ⊤) := ⟨by infer_instance⟩
    let I := NonemptyFinLinOrd.of (Set.image f ⊤)
    let e : X ⟶ I := ⟨fun x => ⟨f x, ⟨x, by tauto⟩⟩, fun x₁ x₂ h => f.monotone h⟩
    let m : I ⟶ Y := ⟨fun y => y.1, by tauto⟩
    haveI : Epi e := by
      rw [epi_iff_surjective]
      rintro ⟨_, y, h, rfl⟩
      

Proof state:
case mk.intro.intro
X Y : NonemptyFinLinOrd
f : X ⟶ Y
this : NonemptyFiniteLinearOrder ↑(⇑f '' ⊤) := NonemptyFiniteLinearOrder.mk
I : NonemptyFinLinOrd := of ↑(⇑f '' ⊤)
e : X ⟶ I :=
  { toFun := fun x => { val := f x, property := (_ : ∃ a ∈ ⊤, f a = f x) },
    monotone' := (_ : ∀ (x₁ x₂ : ↑X), x₁ ≤ x₂ → f x₁ ≤ f x₂) }
m : I ⟶ Y := { toFun := fun y => ↑y, monotone' := (_ : ∀ ⦃a b : ↑I⦄, a ≤ b → a ≤ b) }
y : ↑X
h : y ∈ ⊤
⊢ ∃ a, e a = { val := f y, property := (_ : ∃ a ∈ ⊤, f a = f y) }

Next tactic:
exact ⟨y, rfl⟩
instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f => by
    letI : NonemptyFiniteLinearOrder (Set.image f ⊤) := ⟨by infer_instance⟩
    let I := NonemptyFinLinOrd.of (Set.image f ⊤)
    let e : X ⟶ I := ⟨fun x => ⟨f x, ⟨x, by tauto⟩⟩, fun x₁ x₂ h => f.monotone h⟩
    let m : I ⟶ Y := ⟨fun y => y.1, by tauto⟩
    haveI : Epi e := by
      rw [epi_iff_surjective]
      rintro ⟨_, y, h, rfl⟩
      exact ⟨y, rfl⟩
    

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
this✝ : NonemptyFiniteLinearOrder ↑(⇑f '' ⊤) := NonemptyFiniteLinearOrder.mk
I : NonemptyFinLinOrd := of ↑(⇑f '' ⊤)
e : X ⟶ I :=
  { toFun := fun x => { val := f x, property := (_ : ∃ a ∈ ⊤, f a = f x) },
    monotone' := (_ : ∀ (x₁ x₂ : ↑X), x₁ ≤ x₂ → f x₁ ≤ f x₂) }
m : I ⟶ Y := { toFun := fun y => ↑y, monotone' := (_ : ∀ ⦃a b : ↑I⦄, a ≤ b → a ≤ b) }
this : Epi e
⊢ Nonempty (StrongEpiMonoFactorisation f)

Next tactic:
haveI : StrongEpi e := strongEpi_of_epi e
instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f => by
    letI : NonemptyFiniteLinearOrder (Set.image f ⊤) := ⟨by infer_instance⟩
    let I := NonemptyFinLinOrd.of (Set.image f ⊤)
    let e : X ⟶ I := ⟨fun x => ⟨f x, ⟨x, by tauto⟩⟩, fun x₁ x₂ h => f.monotone h⟩
    let m : I ⟶ Y := ⟨fun y => y.1, by tauto⟩
    haveI : Epi e := by
      rw [epi_iff_surjective]
      rintro ⟨_, y, h, rfl⟩
      exact ⟨y, rfl⟩
    haveI : StrongEpi e := strongEpi_of_epi e
    

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
this✝¹ : NonemptyFiniteLinearOrder ↑(⇑f '' ⊤) := NonemptyFiniteLinearOrder.mk
I : NonemptyFinLinOrd := of ↑(⇑f '' ⊤)
e : X ⟶ I :=
  { toFun := fun x => { val := f x, property := (_ : ∃ a ∈ ⊤, f a = f x) },
    monotone' := (_ : ∀ (x₁ x₂ : ↑X), x₁ ≤ x₂ → f x₁ ≤ f x₂) }
m : I ⟶ Y := { toFun := fun y => ↑y, monotone' := (_ : ∀ ⦃a b : ↑I⦄, a ≤ b → a ≤ b) }
this✝ : Epi e
this : StrongEpi e
⊢ Nonempty (StrongEpiMonoFactorisation f)

Next tactic:
haveI : Mono m := ConcreteCategory.mono_of_injective _ (fun x y h => Subtype.ext h)
instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f => by
    letI : NonemptyFiniteLinearOrder (Set.image f ⊤) := ⟨by infer_instance⟩
    let I := NonemptyFinLinOrd.of (Set.image f ⊤)
    let e : X ⟶ I := ⟨fun x => ⟨f x, ⟨x, by tauto⟩⟩, fun x₁ x₂ h => f.monotone h⟩
    let m : I ⟶ Y := ⟨fun y => y.1, by tauto⟩
    haveI : Epi e := by
      rw [epi_iff_surjective]
      rintro ⟨_, y, h, rfl⟩
      exact ⟨y, rfl⟩
    haveI : StrongEpi e := strongEpi_of_epi e
    haveI : Mono m := ConcreteCategory.mono_of_injective _ (fun x y h => Subtype.ext h)
    

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
this✝² : NonemptyFiniteLinearOrder ↑(⇑f '' ⊤) := NonemptyFiniteLinearOrder.mk
I : NonemptyFinLinOrd := of ↑(⇑f '' ⊤)
e : X ⟶ I :=
  { toFun := fun x => { val := f x, property := (_ : ∃ a ∈ ⊤, f a = f x) },
    monotone' := (_ : ∀ (x₁ x₂ : ↑X), x₁ ≤ x₂ → f x₁ ≤ f x₂) }
m : I ⟶ Y := { toFun := fun y => ↑y, monotone' := (_ : ∀ ⦃a b : ↑I⦄, a ≤ b → a ≤ b) }
this✝¹ : Epi e
this✝ : StrongEpi e
this : Mono m
⊢ Nonempty (StrongEpiMonoFactorisation f)

Next tactic:
exact ⟨⟨I, m, e, rfl⟩⟩
theorem mersenne_pos {p : ℕ} (h : 0 < p) : 0 < mersenne p := by
  

Proof state:
p : ℕ
h : 0 < p
⊢ 0 < mersenne p

Next tactic:
dsimp [mersenne]
theorem mersenne_pos {p : ℕ} (h : 0 < p) : 0 < mersenne p := by
  dsimp [mersenne]
  

Proof state:
p : ℕ
h : 0 < p
⊢ 0 < 2 ^ p - 1

Next tactic:
calc
    0 < 2 ^ 1 - 1 := by norm_num
    _ ≤ 2 ^ p - 1 := Nat.sub_le_sub_right (Nat.pow_le_pow_of_le_right (Nat.succ_pos 1) h) 1
theorem mersenne_pos {p : ℕ} (h : 0 < p) : 0 < mersenne p := by
  dsimp [mersenne]
  calc
    0 < 2 ^ 1 - 1 := by 

Proof state:
p : ℕ
h : 0 < p
⊢ 0 < 2 ^ 1 - 1

Next tactic:
norm_num
theorem one_lt_mersenne {p : ℕ} (hp : 1 < p) : 1 < mersenne p :=
  lt_tsub_iff_right.2 <|
    calc 1 + 1 = 2 ^ 1 := by 

Proof state:
p : ℕ
hp : 1 < p
⊢ 1 + 1 = 2 ^ 1

Next tactic:
rw [one_add_one_eq_two, pow_one]
@[simp]
theorem succ_mersenne (k : ℕ) : mersenne k + 1 = 2 ^ k := by
  

Proof state:
k : ℕ
⊢ mersenne k + 1 = 2 ^ k

Next tactic:
rw [mersenne, tsub_add_cancel_of_le]
@[simp]
theorem succ_mersenne (k : ℕ) : mersenne k + 1 = 2 ^ k := by
  rw [mersenne, tsub_add_cancel_of_le]
  

Proof state:
k : ℕ
⊢ 1 ≤ 2 ^ k

Next tactic:
exact one_le_pow_of_one_le (by norm_num) k
@[simp]
theorem succ_mersenne (k : ℕ) : mersenne k + 1 = 2 ^ k := by
  rw [mersenne, tsub_add_cancel_of_le]
  exact one_le_pow_of_one_le (by 

Proof state:
k : ℕ
⊢ 1 ≤ 2

Next tactic:
norm_num
theorem sMod_nonneg (p : ℕ) (hp : p ≠ 0) (i : ℕ) : 0 ≤ sMod p i := by
  

Proof state:
p : ℕ
hp : p ≠ 0
i : ℕ
⊢ 0 ≤ sMod p i

Next tactic:
cases i
theorem sMod_nonneg (p : ℕ) (hp : p ≠ 0) (i : ℕ) : 0 ≤ sMod p i := by
  cases i <;> 

Proof state:
case zero
p : ℕ
hp : p ≠ 0
⊢ 0 ≤ sMod p zero

Next tactic:
dsimp [sMod]
theorem sMod_nonneg (p : ℕ) (hp : p ≠ 0) (i : ℕ) : 0 ≤ sMod p i := by
  cases i <;> 

Proof state:
case succ
p : ℕ
hp : p ≠ 0
n✝ : ℕ
⊢ 0 ≤ sMod p (succ n✝)

Next tactic:
dsimp [sMod]
theorem sMod_nonneg (p : ℕ) (hp : p ≠ 0) (i : ℕ) : 0 ≤ sMod p i := by
  cases i <;> dsimp [sMod]
  · 

Proof state:
case zero
p : ℕ
hp : p ≠ 0
⊢ 0 ≤ 4 % (2 ^ p - 1)

Next tactic:
exact sup_eq_right.mp rfl
theorem sMod_nonneg (p : ℕ) (hp : p ≠ 0) (i : ℕ) : 0 ≤ sMod p i := by
  cases i <;> dsimp [sMod]
  · exact sup_eq_right.mp rfl
  · 

Proof state:
case succ
p : ℕ
hp : p ≠ 0
n✝ : ℕ
⊢ 0 ≤ (sMod p n✝ ^ 2 - 2) % (2 ^ p - 1)

Next tactic:
apply Int.emod_nonneg
theorem sMod_nonneg (p : ℕ) (hp : p ≠ 0) (i : ℕ) : 0 ≤ sMod p i := by
  cases i <;> dsimp [sMod]
  · exact sup_eq_right.mp rfl
  · apply Int.emod_nonneg
    

Proof state:
case succ.a
p : ℕ
hp : p ≠ 0
n✝ : ℕ
⊢ 2 ^ p - 1 ≠ 0

Next tactic:
exact mersenne_int_ne_zero p hp