-- Mathlib/Data/Set/Enumerate.lean
theorem enumerate_inj {n₁ n₂ : ℕ} {a : α} {s : Set α} (h_sel : ∀ s a, sel s = some a → a ∈ s)
    (h₁ : enumerate sel s n₁ = some a) (h₂ : enumerate sel s n₂ = some a) : n₁ = n₂

Proof state:
case inr.intro.succ.some
α : Type u_1
sel : Set α → Option α
a : α
h_sel : ∀ (s : Set α) (a : α), sel s = some a → a ∈ s
m k : ℕ
ih : ∀ {s : Set α}, enumerate sel s k = some a → enumerate sel s (k + m) = some a → k + m = k
s : Set α
h₁ : enumerate sel s (k + 1) = some a
h₂ : enumerate sel s (k + 1 + m) = some a
val✝ : α
h : sel s = some val✝
⊢ k + 1 + m = k + 1

Tactic:
simp_all only [add_comm, self_eq_add_left, enumerate, Option.some.injEq,
               Nat.add_succ, Nat.succ.injEq]

Result:
case inr.intro.succ.some
α : Type u_1
sel : Set α → Option α
a : α
h_sel : ∀ (s : Set α) (a : α), sel s = some a → a ∈ s
m k : ℕ
s : Set α
val✝ : α
ih : ∀ {s : Set α}, enumerate sel s k = some a → enumerate sel s (m + k) = some a → m + k = k
h₁ :
  (do
      let a ← some val✝
      enumerate sel (s \ {a}) k) =
    some a
h₂ :
  (do
      let a ← some val✝
      enumerate sel (s \ {a}) (m + k)) =
    some a
h : sel s = some val✝
⊢ m + k = k

Proof state:
case inr
α : Type u_1
sel : Set α → Option α
n₁ n₂ : ℕ
a : α
s : Set α
h_sel : ∀ (s : Set α) (a : α), sel s = some a → a ∈ s
h₁ : enumerate sel s n₁ = some a
h₂ : enumerate sel s n₂ = some a
hn : n₂ ≤ n₁
⊢ n₁ = n₂

Tactic:
swap_var n₁ ↔ n₂, h₁ ↔ h₂

Result:
case inr
α : Type u_1
sel : Set α → Option α
n₂ n₁ : ℕ
a : α
s : Set α
h_sel : ∀ (s : Set α) (a : α), sel s = some a → a ∈ s
h₂ : enumerate sel s n₂ = some a
h₁ : enumerate sel s n₁ = some a
hn : n₁ ≤ n₂
⊢ n₂ = n₁

Proof state:
case inl
α : Type u_1
sel : Set α → Option α
n₁ n₂ : ℕ
a : α
s : Set α
h_sel : ∀ (s : Set α) (a : α), sel s = some a → a ∈ s
h₁ : enumerate sel s n₁ = some a
h₂ : enumerate sel s n₂ = some a
hn : n₁ ≤ n₂
⊢ n₁ = n₂

case inr
α : Type u_1
sel : Set α → Option α
n₁ n₂ : ℕ
a : α
s : Set α
h_sel : ∀ (s : Set α) (a : α), sel s = some a → a ∈ s
h₁ : enumerate sel s n₁ = some a
h₂ : enumerate sel s n₂ = some a
hn : n₂ ≤ n₁
⊢ n₁ = n₂

Tactic:
on_goal 2 => swap_var n₁ ↔ n₂, h₁ ↔ h₂

Result:
case inl
α : Type u_1
sel : Set α → Option α
n₁ n₂ : ℕ
a : α
s : Set α
h_sel : ∀ (s : Set α) (a : α), sel s = some a → a ∈ s
h₁ : enumerate sel s n₁ = some a
h₂ : enumerate sel s n₂ = some a
hn : n₁ ≤ n₂
⊢ n₁ = n₂

case inr
α : Type u_1
sel : Set α → Option α
n₂ n₁ : ℕ
a : α
s : Set α
h_sel : ∀ (s : Set α) (a : α), sel s = some a → a ∈ s
h₂ : enumerate sel s n₂ = some a
h₁ : enumerate sel s n₁ = some a
hn : n₁ ≤ n₂
⊢ n₂ = n₁

Proof state:
α : Type u_1
sel : Set α → Option α
a : α
h_sel : ∀ (s : Set α) (a : α), sel s = some a → a ∈ s
s : Set α
m : ℕ
h₁ : sel s = some a
h₂ :
  (do
      let a ← some a
      enumerate sel (s \ {a}) m) =
    some a
⊢ enumerate sel (s \ {a}) m = some a

Tactic:
exact h₂

Result:
no goals

Proof state:
case inr.intro.zero.succ
α : Type u_1
sel : Set α → Option α
a : α
h_sel : ∀ (s : Set α) (a : α), sel s = some a → a ∈ s
s : Set α
h₁ : enumerate sel s 0 = some a
m : ℕ
h₂ : enumerate sel s (0 + (m + 1)) = some a
h' : enumerate sel (s \ {a}) m = some a
⊢ 0 + (m + 1) = 0

Tactic:
have : a ∈ s \ {a} := enumerate_mem sel h_sel h'

Result:
case inr.intro.zero.succ
α : Type u_1
sel : Set α → Option α
a : α
h_sel : ∀ (s : Set α) (a : α), sel s = some a → a ∈ s
s : Set α
h₁ : enumerate sel s 0 = some a
m : ℕ
h₂ : enumerate sel s (0 + (m + 1)) = some a
h' : enumerate sel (s \ {a}) m = some a
this : a ∈ s \ {a}
⊢ 0 + (m + 1) = 0