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₂
      

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 }
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 }
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 }
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:
any_goals rfl