Theorem: List.injOn_insertNth_index_of_not_mem
File: Mathlib/Data/List/Lemmas.lean

tactic: induction' l with hd tl IH
state_before: α : Type u_1
β : Type u_2
γ : Type u_3
l : List α
x : α
hx : x ∉ l
⊢ Set.InjOn (fun k => insertNth k x l) {n | n ≤ l.length}
state_after: case nil
α : Type u_1
β : Type u_2
γ : Type u_3
x : α
hx : x ∉ []
⊢ Set.InjOn (fun k => insertNth k x []) {n | n ≤ [].length}

case cons
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : x ∉ hd :: tl
⊢ Set.InjOn (fun k => insertNth k x (hd :: tl)) {n | n ≤ (hd :: tl).length}

tactic: intro n hn m hm _
state_before: case nil
α : Type u_1
β : Type u_2
γ : Type u_3
x : α
hx : x ∉ []
⊢ Set.InjOn (fun k => insertNth k x []) {n | n ≤ [].length}
state_after: case nil
α : Type u_1
β : Type u_2
γ : Type u_3
x : α
hx : x ∉ []
n : ℕ
hn : n ∈ {n | n ≤ [].length}
m : ℕ
hm : m ∈ {n | n ≤ [].length}
a✝ : (fun k => insertNth k x []) n = (fun k => insertNth k x []) m
⊢ n = m

tactic: simp only [Set.mem_singleton_iff, Set.setOf_eq_eq_singleton,
  length] at hn hm
state_before: case nil
α : Type u_1
β : Type u_2
γ : Type u_3
x : α
hx : x ∉ []
n : ℕ
hn : n ∈ {n | n ≤ [].length}
m : ℕ
hm : m ∈ {n | n ≤ [].length}
a✝ : (fun k => insertNth k x []) n = (fun k => insertNth k x []) m
⊢ n = m
state_after: case nil
α : Type u_1
β : Type u_2
γ : Type u_3
x : α
hx : x ∉ []
n : ℕ
hn : n ∈ {n | n ≤ 0}
m : ℕ
hm : m ∈ {n | n ≤ 0}
a✝ : (fun k => insertNth k x []) n = (fun k => insertNth k x []) m
⊢ n = m

tactic: simp_all [hn, hm]
state_before: case nil
α : Type u_1
β : Type u_2
γ : Type u_3
x : α
hx : x ∉ []
n : ℕ
hn : n ∈ {n | n ≤ 0}
m : ℕ
hm : m ∈ {n | n ≤ 0}
a✝ : (fun k => insertNth k x []) n = (fun k => insertNth k x []) m
⊢ n = m
state_after: no goals

tactic: intro n hn m hm h
state_before: case cons
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : x ∉ hd :: tl
⊢ Set.InjOn (fun k => insertNth k x (hd :: tl)) {n | n ≤ (hd :: tl).length}
state_after: case cons
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : x ∉ hd :: tl
n : ℕ
hn : n ∈ {n | n ≤ (hd :: tl).length}
m : ℕ
hm : m ∈ {n | n ≤ (hd :: tl).length}
h : (fun k => insertNth k x (hd :: tl)) n = (fun k => insertNth k x (hd :: tl)) m
⊢ n = m

tactic: simp only [length, Set.mem_setOf_eq] at hn hm
state_before: case cons
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : x ∉ hd :: tl
n : ℕ
hn : n ∈ {n | n ≤ (hd :: tl).length}
m : ℕ
hm : m ∈ {n | n ≤ (hd :: tl).length}
h : (fun k => insertNth k x (hd :: tl)) n = (fun k => insertNth k x (hd :: tl)) m
⊢ n = m
state_after: case cons
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : x ∉ hd :: tl
n : ℕ
hn : n ≤ tl.length + 1
m : ℕ
hm : m ≤ tl.length + 1
h : (fun k => insertNth k x (hd :: tl)) n = (fun k => insertNth k x (hd :: tl)) m
⊢ n = m

tactic: simp only [mem_cons, not_or] at hx
state_before: case cons
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : x ∉ hd :: tl
n : ℕ
hn : n ≤ tl.length + 1
m : ℕ
hm : m ≤ tl.length + 1
h : (fun k => insertNth k x (hd :: tl)) n = (fun k => insertNth k x (hd :: tl)) m
⊢ n = m
state_after: case cons
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
n : ℕ
hn : n ≤ tl.length + 1
m : ℕ
hm : m ≤ tl.length + 1
h : (fun k => insertNth k x (hd :: tl)) n = (fun k => insertNth k x (hd :: tl)) m
hx : ¬x = hd ∧ x ∉ tl
⊢ n = m

tactic: cases n <;> cases m
state_before: case cons
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
n : ℕ
hn : n ≤ tl.length + 1
m : ℕ
hm : m ≤ tl.length + 1
h : (fun k => insertNth k x (hd :: tl)) n = (fun k => insertNth k x (hd :: tl)) m
hx : ¬x = hd ∧ x ∉ tl
⊢ n = m
state_after: case cons.zero.zero
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
hn hm : 0 ≤ tl.length + 1
h : (fun k => insertNth k x (hd :: tl)) 0 = (fun k => insertNth k x (hd :: tl)) 0
⊢ 0 = 0

case cons.zero.succ
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
hn : 0 ≤ tl.length + 1
n✝ : ℕ
hm : n✝ + 1 ≤ tl.length + 1
h : (fun k => insertNth k x (hd :: tl)) 0 = (fun k => insertNth k x (hd :: tl)) (n✝ + 1)
⊢ 0 = n✝ + 1

case cons.succ.zero
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
n✝ : ℕ
hn : n✝ + 1 ≤ tl.length + 1
hm : 0 ≤ tl.length + 1
h : (fun k => insertNth k x (hd :: tl)) (n✝ + 1) = (fun k => insertNth k x (hd :: tl)) 0
⊢ n✝ + 1 = 0

case cons.succ.succ
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
n✝¹ : ℕ
hn : n✝¹ + 1 ≤ tl.length + 1
n✝ : ℕ
hm : n✝ + 1 ≤ tl.length + 1
h : (fun k => insertNth k x (hd :: tl)) (n✝¹ + 1) = (fun k => insertNth k x (hd :: tl)) (n✝ + 1)
⊢ n✝¹ + 1 = n✝ + 1

tactic: rfl
state_before: case cons.zero.zero
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
hn hm : 0 ≤ tl.length + 1
h : (fun k => insertNth k x (hd :: tl)) 0 = (fun k => insertNth k x (hd :: tl)) 0
⊢ 0 = 0
state_after: no goals

tactic: simp [hx.left] at h
state_before: case cons.zero.succ
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
hn : 0 ≤ tl.length + 1
n✝ : ℕ
hm : n✝ + 1 ≤ tl.length + 1
h : (fun k => insertNth k x (hd :: tl)) 0 = (fun k => insertNth k x (hd :: tl)) (n✝ + 1)
⊢ 0 = n✝ + 1
state_after: no goals

tactic: simp [Ne.symm hx.left] at h
state_before: case cons.succ.zero
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
n✝ : ℕ
hn : n✝ + 1 ≤ tl.length + 1
hm : 0 ≤ tl.length + 1
h : (fun k => insertNth k x (hd :: tl)) (n✝ + 1) = (fun k => insertNth k x (hd :: tl)) 0
⊢ n✝ + 1 = 0
state_after: no goals

tactic: simp only [true_and_iff, eq_self_iff_true, insertNth_succ_cons] at h
state_before: case cons.succ.succ
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
n✝¹ : ℕ
hn : n✝¹ + 1 ≤ tl.length + 1
n✝ : ℕ
hm : n✝ + 1 ≤ tl.length + 1
h : (fun k => insertNth k x (hd :: tl)) (n✝¹ + 1) = (fun k => insertNth k x (hd :: tl)) (n✝ + 1)
⊢ n✝¹ + 1 = n✝ + 1
state_after: case cons.succ.succ
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
n✝¹ : ℕ
hn : n✝¹ + 1 ≤ tl.length + 1
n✝ : ℕ
hm : n✝ + 1 ≤ tl.length + 1
h : hd :: insertNth n✝¹ x tl = hd :: insertNth n✝ x tl
⊢ n✝¹ + 1 = n✝ + 1

tactic: rw [Nat.succ_inj']
state_before: case cons.succ.succ
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
n✝¹ : ℕ
hn : n✝¹ + 1 ≤ tl.length + 1
n✝ : ℕ
hm : n✝ + 1 ≤ tl.length + 1
h : hd :: insertNth n✝¹ x tl = hd :: insertNth n✝ x tl
⊢ n✝¹ + 1 = n✝ + 1
state_after: case cons.succ.succ
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
n✝¹ : ℕ
hn : n✝¹ + 1 ≤ tl.length + 1
n✝ : ℕ
hm : n✝ + 1 ≤ tl.length + 1
h : hd :: insertNth n✝¹ x tl = hd :: insertNth n✝ x tl
⊢ n✝¹ = n✝

tactic: refine IH hx.right ?_ ?_ (by injection h)
state_before: case cons.succ.succ
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
n✝¹ : ℕ
hn : n✝¹ + 1 ≤ tl.length + 1
n✝ : ℕ
hm : n✝ + 1 ≤ tl.length + 1
h : hd :: insertNth n✝¹ x tl = hd :: insertNth n✝ x tl
⊢ n✝¹ = n✝
state_after: case cons.succ.succ.refine_1
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
n✝¹ : ℕ
hn : n✝¹ + 1 ≤ tl.length + 1
n✝ : ℕ
hm : n✝ + 1 ≤ tl.length + 1
h : hd :: insertNth n✝¹ x tl = hd :: insertNth n✝ x tl
⊢ n✝¹ ∈ {n | n ≤ tl.length}

case cons.succ.succ.refine_2
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
n✝¹ : ℕ
hn : n✝¹ + 1 ≤ tl.length + 1
n✝ : ℕ
hm : n✝ + 1 ≤ tl.length + 1
h : hd :: insertNth n✝¹ x tl = hd :: insertNth n✝ x tl
⊢ n✝ ∈ {n | n ≤ tl.length}

tactic: injection h
state_before: α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
n✝¹ : ℕ
hn : n✝¹ + 1 ≤ tl.length + 1
n✝ : ℕ
hm : n✝ + 1 ≤ tl.length + 1
h : hd :: insertNth n✝¹ x tl = hd :: insertNth n✝ x tl
⊢ (fun k => insertNth k x tl) n✝¹ = (fun k => insertNth k x tl) n✝
state_after: no goals

tactic: simpa [Nat.succ_le_succ_iff] using hn
state_before: case cons.succ.succ.refine_1
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
n✝¹ : ℕ
hn : n✝¹ + 1 ≤ tl.length + 1
n✝ : ℕ
hm : n✝ + 1 ≤ tl.length + 1
h : hd :: insertNth n✝¹ x tl = hd :: insertNth n✝ x tl
⊢ n✝¹ ∈ {n | n ≤ tl.length}
state_after: no goals

tactic: simpa [Nat.succ_le_succ_iff] using hm
state_before: case cons.succ.succ.refine_2
α : Type u_1
β : Type u_2
γ : Type u_3
x hd : α
tl : List α
IH : x ∉ tl → Set.InjOn (fun k => insertNth k x tl) {n | n ≤ tl.length}
hx : ¬x = hd ∧ x ∉ tl
n✝¹ : ℕ
hn : n✝¹ + 1 ≤ tl.length + 1
n✝ : ℕ
hm : n✝ + 1 ≤ tl.length + 1
h : hd :: insertNth n✝¹ x tl = hd :: insertNth n✝ x tl
⊢ n✝ ∈ {n | n ≤ tl.length}
state_after: no goals