l3lab/ntp-mathlib huggingface dataset:
theorem epi_iff_surjective {A B : NonemptyFinLinOrd.{u}} (f : A ⟶ B) :
    Epi f ↔ Function.Surjective f := by
  constructor
  · intro
    dsimp only [Function.Surjective]
    by_contra! hf'
    rcases hf' with ⟨m, hm⟩
    let Y := NonemptyFinLinOrd.of (ULift (Fin 2))
    let p₁ : B ⟶ Y :=
      ⟨fun b => if b < m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (lt_of_le_of_lt h h₂)
        · rfl⟩
    let p₂ : B ⟶ Y :=
      ⟨fun b => if b ≤ m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (h.trans h₂)
        · rfl⟩
    have h : p₁ m = p₂ m := by
      congr
      rw [← cancel_epi f]
      ext a
      simp only [coe_of, comp_apply]
      change ite _ _ _ = ite _ _ _
      

Proof state:
case e_a.w
A B : NonemptyFinLinOrd
f : A ⟶ B
a✝ : Epi f
m : ↑B
hm : ∀ (a : ↑A), f a ≠ m
Y : NonemptyFinLinOrd := of (ULift.{u, 0} (Fin 2))
p₁ : B ⟶ Y :=
  { toFun := fun b => if b < m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b < m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b < m then { down := 0 } else { down := 1 }) x₂) }
p₂ : B ⟶ Y :=
  { toFun := fun b => if b ≤ m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₂) }
a : (forget NonemptyFinLinOrd).obj A
⊢ (if f a < m then { down := 0 } else { down := 1 }) = if f a ≤ m then { down := 0 } else { down := 1 }

Next tactic:
split_ifs with h₁ h₂ h₂
theorem epi_iff_surjective {A B : NonemptyFinLinOrd.{u}} (f : A ⟶ B) :
    Epi f ↔ Function.Surjective f := by
  constructor
  · intro
    dsimp only [Function.Surjective]
    by_contra! hf'
    rcases hf' with ⟨m, hm⟩
    let Y := NonemptyFinLinOrd.of (ULift (Fin 2))
    let p₁ : B ⟶ Y :=
      ⟨fun b => if b < m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (lt_of_le_of_lt h h₂)
        · rfl⟩
    let p₂ : B ⟶ Y :=
      ⟨fun b => if b ≤ m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (h.trans h₂)
        · rfl⟩
    have h : p₁ m = p₂ m := by
      congr
      rw [← cancel_epi f]
      ext a
      simp only [coe_of, comp_apply]
      change ite _ _ _ = ite _ _ _
      split_ifs with h₁ h₂ h₂
      any_goals 

Proof state:
case pos
A B : NonemptyFinLinOrd
f : A ⟶ B
a✝ : Epi f
m : ↑B
hm : ∀ (a : ↑A), f a ≠ m
Y : NonemptyFinLinOrd := of (ULift.{u, 0} (Fin 2))
p₁ : B ⟶ Y :=
  { toFun := fun b => if b < m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b < m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b < m then { down := 0 } else { down := 1 }) x₂) }
p₂ : B ⟶ Y :=
  { toFun := fun b => if b ≤ m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₂) }
a : (forget NonemptyFinLinOrd).obj A
h₁ : f a < m
h₂ : f a ≤ m
⊢ { down := 0 } = { down := 0 }

Next tactic:
rfl
theorem epi_iff_surjective {A B : NonemptyFinLinOrd.{u}} (f : A ⟶ B) :
    Epi f ↔ Function.Surjective f := by
  constructor
  · intro
    dsimp only [Function.Surjective]
    by_contra! hf'
    rcases hf' with ⟨m, hm⟩
    let Y := NonemptyFinLinOrd.of (ULift (Fin 2))
    let p₁ : B ⟶ Y :=
      ⟨fun b => if b < m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (lt_of_le_of_lt h h₂)
        · rfl⟩
    let p₂ : B ⟶ Y :=
      ⟨fun b => if b ≤ m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (h.trans h₂)
        · rfl⟩
    have h : p₁ m = p₂ m := by
      congr
      rw [← cancel_epi f]
      ext a
      simp only [coe_of, comp_apply]
      change ite _ _ _ = ite _ _ _
      split_ifs with h₁ h₂ h₂
      any_goals 

Proof state:
case neg
A B : NonemptyFinLinOrd
f : A ⟶ B
a✝ : Epi f
m : ↑B
hm : ∀ (a : ↑A), f a ≠ m
Y : NonemptyFinLinOrd := of (ULift.{u, 0} (Fin 2))
p₁ : B ⟶ Y :=
  { toFun := fun b => if b < m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b < m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b < m then { down := 0 } else { down := 1 }) x₂) }
p₂ : B ⟶ Y :=
  { toFun := fun b => if b ≤ m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₂) }
a : (forget NonemptyFinLinOrd).obj A
h₁ : f a < m
h₂ : ¬f a ≤ m
⊢ { down := 0 } = { down := 1 }

Next tactic:
rfl
theorem epi_iff_surjective {A B : NonemptyFinLinOrd.{u}} (f : A ⟶ B) :
    Epi f ↔ Function.Surjective f := by
  constructor
  · intro
    dsimp only [Function.Surjective]
    by_contra! hf'
    rcases hf' with ⟨m, hm⟩
    let Y := NonemptyFinLinOrd.of (ULift (Fin 2))
    let p₁ : B ⟶ Y :=
      ⟨fun b => if b < m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (lt_of_le_of_lt h h₂)
        · rfl⟩
    let p₂ : B ⟶ Y :=
      ⟨fun b => if b ≤ m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (h.trans h₂)
        · rfl⟩
    have h : p₁ m = p₂ m := by
      congr
      rw [← cancel_epi f]
      ext a
      simp only [coe_of, comp_apply]
      change ite _ _ _ = ite _ _ _
      split_ifs with h₁ h₂ h₂
      any_goals 

Proof state:
case pos
A B : NonemptyFinLinOrd
f : A ⟶ B
a✝ : Epi f
m : ↑B
hm : ∀ (a : ↑A), f a ≠ m
Y : NonemptyFinLinOrd := of (ULift.{u, 0} (Fin 2))
p₁ : B ⟶ Y :=
  { toFun := fun b => if b < m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b < m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b < m then { down := 0 } else { down := 1 }) x₂) }
p₂ : B ⟶ Y :=
  { toFun := fun b => if b ≤ m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₂) }
a : (forget NonemptyFinLinOrd).obj A
h₁ : ¬f a < m
h₂ : f a ≤ m
⊢ { down := 1 } = { down := 0 }

Next tactic:
rfl
theorem epi_iff_surjective {A B : NonemptyFinLinOrd.{u}} (f : A ⟶ B) :
    Epi f ↔ Function.Surjective f := by
  constructor
  · intro
    dsimp only [Function.Surjective]
    by_contra! hf'
    rcases hf' with ⟨m, hm⟩
    let Y := NonemptyFinLinOrd.of (ULift (Fin 2))
    let p₁ : B ⟶ Y :=
      ⟨fun b => if b < m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (lt_of_le_of_lt h h₂)
        · rfl⟩
    let p₂ : B ⟶ Y :=
      ⟨fun b => if b ≤ m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (h.trans h₂)
        · rfl⟩
    have h : p₁ m = p₂ m := by
      congr
      rw [← cancel_epi f]
      ext a
      simp only [coe_of, comp_apply]
      change ite _ _ _ = ite _ _ _
      split_ifs with h₁ h₂ h₂
      any_goals 

Proof state:
case neg
A B : NonemptyFinLinOrd
f : A ⟶ B
a✝ : Epi f
m : ↑B
hm : ∀ (a : ↑A), f a ≠ m
Y : NonemptyFinLinOrd := of (ULift.{u, 0} (Fin 2))
p₁ : B ⟶ Y :=
  { toFun := fun b => if b < m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b < m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b < m then { down := 0 } else { down := 1 }) x₂) }
p₂ : B ⟶ Y :=
  { toFun := fun b => if b ≤ m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₂) }
a : (forget NonemptyFinLinOrd).obj A
h₁ : ¬f a < m
h₂ : ¬f a ≤ m
⊢ { down := 1 } = { down := 1 }

Next tactic:
rfl
theorem epi_iff_surjective {A B : NonemptyFinLinOrd.{u}} (f : A ⟶ B) :
    Epi f ↔ Function.Surjective f := by
  constructor
  · intro
    dsimp only [Function.Surjective]
    by_contra! hf'
    rcases hf' with ⟨m, hm⟩
    let Y := NonemptyFinLinOrd.of (ULift (Fin 2))
    let p₁ : B ⟶ Y :=
      ⟨fun b => if b < m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (lt_of_le_of_lt h h₂)
        · rfl⟩
    let p₂ : B ⟶ Y :=
      ⟨fun b => if b ≤ m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (h.trans h₂)
        · rfl⟩
    have h : p₁ m = p₂ m := by
      congr
      rw [← cancel_epi f]
      ext a
      simp only [coe_of, comp_apply]
      change ite _ _ _ = ite _ _ _
      split_ifs with h₁ h₂ h₂
      any_goals rfl
      · 

Proof state:
case neg
A B : NonemptyFinLinOrd
f : A ⟶ B
a✝ : Epi f
m : ↑B
hm : ∀ (a : ↑A), f a ≠ m
Y : NonemptyFinLinOrd := of (ULift.{u, 0} (Fin 2))
p₁ : B ⟶ Y :=
  { toFun := fun b => if b < m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b < m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b < m then { down := 0 } else { down := 1 }) x₂) }
p₂ : B ⟶ Y :=
  { toFun := fun b => if b ≤ m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₂) }
a : (forget NonemptyFinLinOrd).obj A
h₁ : f a < m
h₂ : ¬f a ≤ m
⊢ { down := 0 } = { down := 1 }

Next tactic:
exfalso
theorem epi_iff_surjective {A B : NonemptyFinLinOrd.{u}} (f : A ⟶ B) :
    Epi f ↔ Function.Surjective f := by
  constructor
  · intro
    dsimp only [Function.Surjective]
    by_contra! hf'
    rcases hf' with ⟨m, hm⟩
    let Y := NonemptyFinLinOrd.of (ULift (Fin 2))
    let p₁ : B ⟶ Y :=
      ⟨fun b => if b < m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (lt_of_le_of_lt h h₂)
        · rfl⟩
    let p₂ : B ⟶ Y :=
      ⟨fun b => if b ≤ m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (h.trans h₂)
        · rfl⟩
    have h : p₁ m = p₂ m := by
      congr
      rw [← cancel_epi f]
      ext a
      simp only [coe_of, comp_apply]
      change ite _ _ _ = ite _ _ _
      split_ifs with h₁ h₂ h₂
      any_goals rfl
      · exfalso
        

Proof state:
case neg.h
A B : NonemptyFinLinOrd
f : A ⟶ B
a✝ : Epi f
m : ↑B
hm : ∀ (a : ↑A), f a ≠ m
Y : NonemptyFinLinOrd := of (ULift.{u, 0} (Fin 2))
p₁ : B ⟶ Y :=
  { toFun := fun b => if b < m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b < m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b < m then { down := 0 } else { down := 1 }) x₂) }
p₂ : B ⟶ Y :=
  { toFun := fun b => if b ≤ m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₂) }
a : (forget NonemptyFinLinOrd).obj A
h₁ : f a < m
h₂ : ¬f a ≤ m
⊢ False

Next tactic:
exact h₂ (le_of_lt h₁)
theorem epi_iff_surjective {A B : NonemptyFinLinOrd.{u}} (f : A ⟶ B) :
    Epi f ↔ Function.Surjective f := by
  constructor
  · intro
    dsimp only [Function.Surjective]
    by_contra! hf'
    rcases hf' with ⟨m, hm⟩
    let Y := NonemptyFinLinOrd.of (ULift (Fin 2))
    let p₁ : B ⟶ Y :=
      ⟨fun b => if b < m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (lt_of_le_of_lt h h₂)
        · rfl⟩
    let p₂ : B ⟶ Y :=
      ⟨fun b => if b ≤ m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (h.trans h₂)
        · rfl⟩
    have h : p₁ m = p₂ m := by
      congr
      rw [← cancel_epi f]
      ext a
      simp only [coe_of, comp_apply]
      change ite _ _ _ = ite _ _ _
      split_ifs with h₁ h₂ h₂
      any_goals rfl
      · exfalso
        exact h₂ (le_of_lt h₁)
      · 

Proof state:
case pos
A B : NonemptyFinLinOrd
f : A ⟶ B
a✝ : Epi f
m : ↑B
hm : ∀ (a : ↑A), f a ≠ m
Y : NonemptyFinLinOrd := of (ULift.{u, 0} (Fin 2))
p₁ : B ⟶ Y :=
  { toFun := fun b => if b < m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b < m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b < m then { down := 0 } else { down := 1 }) x₂) }
p₂ : B ⟶ Y :=
  { toFun := fun b => if b ≤ m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₂) }
a : (forget NonemptyFinLinOrd).obj A
h₁ : ¬f a < m
h₂ : f a ≤ m
⊢ { down := 1 } = { down := 0 }

Next tactic:
exfalso
theorem epi_iff_surjective {A B : NonemptyFinLinOrd.{u}} (f : A ⟶ B) :
    Epi f ↔ Function.Surjective f := by
  constructor
  · intro
    dsimp only [Function.Surjective]
    by_contra! hf'
    rcases hf' with ⟨m, hm⟩
    let Y := NonemptyFinLinOrd.of (ULift (Fin 2))
    let p₁ : B ⟶ Y :=
      ⟨fun b => if b < m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (lt_of_le_of_lt h h₂)
        · rfl⟩
    let p₂ : B ⟶ Y :=
      ⟨fun b => if b ≤ m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (h.trans h₂)
        · rfl⟩
    have h : p₁ m = p₂ m := by
      congr
      rw [← cancel_epi f]
      ext a
      simp only [coe_of, comp_apply]
      change ite _ _ _ = ite _ _ _
      split_ifs with h₁ h₂ h₂
      any_goals rfl
      · exfalso
        exact h₂ (le_of_lt h₁)
      · exfalso
        

Proof state:
case pos.h
A B : NonemptyFinLinOrd
f : A ⟶ B
a✝ : Epi f
m : ↑B
hm : ∀ (a : ↑A), f a ≠ m
Y : NonemptyFinLinOrd := of (ULift.{u, 0} (Fin 2))
p₁ : B ⟶ Y :=
  { toFun := fun b => if b < m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b < m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b < m then { down := 0 } else { down := 1 }) x₂) }
p₂ : B ⟶ Y :=
  { toFun := fun b => if b ≤ m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₂) }
a : (forget NonemptyFinLinOrd).obj A
h₁ : ¬f a < m
h₂ : f a ≤ m
⊢ False

Next tactic:
exact hm a (eq_of_le_of_not_lt h₂ h₁)
theorem epi_iff_surjective {A B : NonemptyFinLinOrd.{u}} (f : A ⟶ B) :
    Epi f ↔ Function.Surjective f := by
  constructor
  · intro
    dsimp only [Function.Surjective]
    by_contra! hf'
    rcases hf' with ⟨m, hm⟩
    let Y := NonemptyFinLinOrd.of (ULift (Fin 2))
    let p₁ : B ⟶ Y :=
      ⟨fun b => if b < m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (lt_of_le_of_lt h h₂)
        · rfl⟩
    let p₂ : B ⟶ Y :=
      ⟨fun b => if b ≤ m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (h.trans h₂)
        · rfl⟩
    have h : p₁ m = p₂ m := by
      congr
      rw [← cancel_epi f]
      ext a
      simp only [coe_of, comp_apply]
      change ite _ _ _ = ite _ _ _
      split_ifs with h₁ h₂ h₂
      any_goals rfl
      · exfalso
        exact h₂ (le_of_lt h₁)
      · exfalso
        exact hm a (eq_of_le_of_not_lt h₂ h₁)
    

Proof state:
case mp.intro
A B : NonemptyFinLinOrd
f : A ⟶ B
a✝ : Epi f
m : ↑B
hm : ∀ (a : ↑A), f a ≠ m
Y : NonemptyFinLinOrd := of (ULift.{u, 0} (Fin 2))
p₁ : B ⟶ Y :=
  { toFun := fun b => if b < m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b < m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b < m then { down := 0 } else { down := 1 }) x₂) }
p₂ : B ⟶ Y :=
  { toFun := fun b => if b ≤ m then { down := 0 } else { down := 1 },
    monotone' :=
      (_ :
        ∀ (x₁ x₂ : ↑B),
          x₁ ≤ x₂ →
            (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₁ ≤
              (fun b => if b ≤ m then { down := 0 } else { down := 1 }) x₂) }
h : p₁ m = p₂ m
⊢ False

Next tactic:
simp [FunLike.coe] at h
theorem epi_iff_surjective {A B : NonemptyFinLinOrd.{u}} (f : A ⟶ B) :
    Epi f ↔ Function.Surjective f := by
  constructor
  · intro
    dsimp only [Function.Surjective]
    by_contra! hf'
    rcases hf' with ⟨m, hm⟩
    let Y := NonemptyFinLinOrd.of (ULift (Fin 2))
    let p₁ : B ⟶ Y :=
      ⟨fun b => if b < m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (lt_of_le_of_lt h h₂)
        · rfl⟩
    let p₂ : B ⟶ Y :=
      ⟨fun b => if b ≤ m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (h.trans h₂)
        · rfl⟩
    have h : p₁ m = p₂ m := by
      congr
      rw [← cancel_epi f]
      ext a
      simp only [coe_of, comp_apply]
      change ite _ _ _ = ite _ _ _
      split_ifs with h₁ h₂ h₂
      any_goals rfl
      · exfalso
        exact h₂ (le_of_lt h₁)
      · exfalso
        exact hm a (eq_of_le_of_not_lt h₂ h₁)
    simp [FunLike.coe] at h
  · 

Proof state:
case mpr
A B : NonemptyFinLinOrd
f : A ⟶ B
⊢ Function.Surjective ⇑f → Epi f

Next tactic:
intro h
theorem epi_iff_surjective {A B : NonemptyFinLinOrd.{u}} (f : A ⟶ B) :
    Epi f ↔ Function.Surjective f := by
  constructor
  · intro
    dsimp only [Function.Surjective]
    by_contra! hf'
    rcases hf' with ⟨m, hm⟩
    let Y := NonemptyFinLinOrd.of (ULift (Fin 2))
    let p₁ : B ⟶ Y :=
      ⟨fun b => if b < m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (lt_of_le_of_lt h h₂)
        · rfl⟩
    let p₂ : B ⟶ Y :=
      ⟨fun b => if b ≤ m then ULift.up 0 else ULift.up 1, fun x₁ x₂ h => by
        simp only
        split_ifs with h₁ h₂ h₂
        any_goals apply Fin.zero_le
        · exfalso
          exact h₁ (h.trans h₂)
        · rfl⟩
    have h : p₁ m = p₂ m := by
      congr
      rw [← cancel_epi f]
      ext a
      simp only [coe_of, comp_apply]
      change ite _ _ _ = ite _ _ _
      split_ifs with h₁ h₂ h₂
      any_goals rfl
      · exfalso
        exact h₂ (le_of_lt h₁)
      · exfalso
        exact hm a (eq_of_le_of_not_lt h₂ h₁)
    simp [FunLike.coe] at h
  · intro h
    

Proof state:
case mpr
A B : NonemptyFinLinOrd
f : A ⟶ B
h : Function.Surjective ⇑f
⊢ Epi f

Next tactic:
exact ConcreteCategory.epi_of_surjective f h
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
⊢ IsSplitEpi f

Next tactic:
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⟩
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
⊢ ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})

Next tactic:
rw [epi_iff_surjective] at hf
instance : SplitEpiCategory NonemptyFinLinOrd.{u} :=
  ⟨fun {X Y} f hf => by
    have H : ∀ y : Y, Nonempty (f ⁻¹' {y}) := by
      rw [epi_iff_surjective] at hf
      

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Function.Surjective ⇑f
⊢ ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})

Next tactic:
intro y
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
      

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Function.Surjective ⇑f
y : ↑Y
⊢ Nonempty ↑(⇑f ⁻¹' {y})

Next tactic:
exact Nonempty.intro ⟨(hf y).choose, (hf y).choose_spec⟩
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⟩
    

Proof state:
X Y : NonemptyFinLinOrd
f : X ⟶ Y
hf : Epi f
H : ∀ (y : ↑Y), Nonempty ↑(⇑f ⁻¹' {y})
⊢ IsSplitEpi f

Next tactic:
let φ : Y → X := fun y => (H y).some.1
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
    

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})))
⊢ IsSplitEpi f

Next tactic:
have hφ : ∀ y : Y, f (φ y) = y := fun y => (H y).some.2
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
    

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
⊢ IsSplitEpi f

Next tactic:
refine' IsSplitEpi.mk' ⟨⟨φ, _⟩, _⟩