l3lab/ntp-mathlib huggingface dataset:
theorem get_reverse_aux₂ :
    ∀ (l r : List α) (i : Nat) (h1) (h2),
      get (reverseAux l r) ⟨length l - 1 - i, h1⟩ = get l ⟨i, h2⟩
  | [], r, i, h1, h2 => absurd h2 (Nat.not_lt_zero _)
  | a :: l, r, 0, h1, _ => by
    have aux := get_reverse_aux₁ l (a :: r) 0
    rw [zero_add] at aux
    exact aux _ (zero_lt_succ _)
  | a :: l, r, i + 1, h1, h2 => by
    have aux := get_reverse_aux₂ l (a :: r) i
    have heq :=
      calc
        length (a :: l) - 1 - (i + 1) = length l - (1 + i) := by rw [add_comm]; rfl
        _ = length l - 1 - i := by rw [← tsub_add_eq_tsub_tsub]
    rw [← heq] at aux
    

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
l r : List α
i : ℕ
h1 : length (a :: l) - 1 - (i + 1) < length (reverseAux (a :: l) r)
h2 : i + 1 < length (a :: l)
aux :
  ∀ (h1 : length (a :: l) - 1 - (i + 1) < length (reverseAux l (a :: r))) (h2 : i < length l),
    get (reverseAux l (a :: r)) { val := length (a :: l) - 1 - (i + 1), isLt := h1 } = get l { val := i, isLt := h2 }
heq : length (a :: l) - 1 - (i + 1) = length l - 1 - i
⊢ get (reverseAux (a :: l) r) { val := length (a :: l) - 1 - (i + 1), isLt := h1 } =
    get (a :: l) { val := i + 1, isLt := h2 }

Next tactic:
apply aux
theorem nthLe_reverse' (l : List α) (n : ℕ) (hn : n < l.reverse.length) (hn') :
    l.reverse.nthLe n hn = l.nthLe (l.length - 1 - n) hn' := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
n : ℕ
hn : n < length (reverse l)
hn' : length l - 1 - n < length l
⊢ nthLe (reverse l) n hn = nthLe l (length l - 1 - n) hn'

Next tactic:
rw [eq_comm]
theorem nthLe_reverse' (l : List α) (n : ℕ) (hn : n < l.reverse.length) (hn') :
    l.reverse.nthLe n hn = l.nthLe (l.length - 1 - n) hn' := by
  rw [eq_comm]
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
n : ℕ
hn : n < length (reverse l)
hn' : length l - 1 - n < length l
⊢ nthLe l (length l - 1 - n) hn' = nthLe (reverse l) n hn

Next tactic:
convert nthLe_reverse l.reverse n (by simpa) hn using 1
theorem nthLe_reverse' (l : List α) (n : ℕ) (hn : n < l.reverse.length) (hn') :
    l.reverse.nthLe n hn = l.nthLe (l.length - 1 - n) hn' := by
  rw [eq_comm]
  convert nthLe_reverse l.reverse n (by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
n : ℕ
hn : n < length (reverse l)
hn' : length l - 1 - n < length l
⊢ length (reverse l) - 1 - n < length (reverse (reverse l))

Next tactic:
simpa
theorem nthLe_reverse' (l : List α) (n : ℕ) (hn : n < l.reverse.length) (hn') :
    l.reverse.nthLe n hn = l.nthLe (l.length - 1 - n) hn' := by
  rw [eq_comm]
  convert nthLe_reverse l.reverse n (by simpa) hn using 1
  

Proof state:
case h.e'_2
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
n : ℕ
hn : n < length (reverse l)
hn' : length l - 1 - n < length l
⊢ nthLe l (length l - 1 - n) hn' =
    nthLe (reverse (reverse l)) (length (reverse l) - 1 - n)
      (_ : length (reverse l) - 1 - n < length (reverse (reverse l)))

Next tactic:
simp
theorem eq_cons_of_length_one {l : List α} (h : l.length = 1) :
    l = [l.nthLe 0 (h.symm ▸ zero_lt_one)] := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
h : length l = 1
⊢ l = [nthLe l 0 (_ : 0 < length l)]

Next tactic:
refine' ext_get (by convert h) fun n h₁ h₂ => _
theorem eq_cons_of_length_one {l : List α} (h : l.length = 1) :
    l = [l.nthLe 0 (h.symm ▸ zero_lt_one)] := by
  refine' ext_get (by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
h : length l = 1
⊢ length l = length [nthLe l 0 (_ : 0 < length l)]

Next tactic:
convert h
theorem eq_cons_of_length_one {l : List α} (h : l.length = 1) :
    l = [l.nthLe 0 (h.symm ▸ zero_lt_one)] := by
  refine' ext_get (by convert h) fun n h₁ h₂ => _
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
h : length l = 1
n : ℕ
h₁ : n < length l
h₂ : n < length [nthLe l 0 (_ : 0 < length l)]
⊢ get l { val := n, isLt := h₁ } = get [nthLe l 0 (_ : 0 < length l)] { val := n, isLt := h₂ }

Next tactic:
simp only [get_singleton]
theorem eq_cons_of_length_one {l : List α} (h : l.length = 1) :
    l = [l.nthLe 0 (h.symm ▸ zero_lt_one)] := by
  refine' ext_get (by convert h) fun n h₁ h₂ => _
  simp only [get_singleton]
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
h : length l = 1
n : ℕ
h₁ : n < length l
h₂ : n < length [nthLe l 0 (_ : 0 < length l)]
⊢ get l { val := n, isLt := h₁ } = nthLe l 0 (_ : 0 < length l)

Next tactic:
congr
theorem eq_cons_of_length_one {l : List α} (h : l.length = 1) :
    l = [l.nthLe 0 (h.symm ▸ zero_lt_one)] := by
  refine' ext_get (by convert h) fun n h₁ h₂ => _
  simp only [get_singleton]
  congr
  

Proof state:
case e_a.e_val
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
h : length l = 1
n : ℕ
h₁ : n < length l
h₂ : n < length [nthLe l 0 (_ : 0 < length l)]
⊢ n = 0

Next tactic:
exact eq_bot_iff.mpr (Nat.lt_succ_iff.mp h₂)
theorem get_eq_iff {l : List α} {n : Fin l.length} {x : α} : l.get n = x ↔ l.get? n.1 = some x := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
n : Fin (length l)
x : α
⊢ get l n = x ↔ get? l ↑n = some x

Next tactic:
rw [get?_eq_some]
theorem get_eq_iff {l : List α} {n : Fin l.length} {x : α} : l.get n = x ↔ l.get? n.1 = some x := by
  rw [get?_eq_some]
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
n : Fin (length l)
x : α
⊢ get l n = x ↔ ∃ h, get l { val := ↑n, isLt := h } = x

Next tactic:
simp [n.2]
theorem modifyNthTail_modifyNthTail_le {f g : List α → List α} (m n : ℕ) (l : List α)
    (h : n ≤ m) :
    (l.modifyNthTail f n).modifyNthTail g m =
      l.modifyNthTail (fun l => (f l).modifyNthTail g (m - n)) n := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f g : List α → List α
m n : ℕ
l : List α
h : n ≤ m
⊢ modifyNthTail g m (modifyNthTail f n l) = modifyNthTail (fun l => modifyNthTail g (m - n) (f l)) n l

Next tactic:
rcases exists_add_of_le h with ⟨m, rfl⟩
theorem modifyNthTail_modifyNthTail_le {f g : List α → List α} (m n : ℕ) (l : List α)
    (h : n ≤ m) :
    (l.modifyNthTail f n).modifyNthTail g m =
      l.modifyNthTail (fun l => (f l).modifyNthTail g (m - n)) n := by
  rcases exists_add_of_le h with ⟨m, rfl⟩
  

Proof state:
case intro
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f g : List α → List α
n : ℕ
l : List α
m : ℕ
h : n ≤ n + m
⊢ modifyNthTail g (n + m) (modifyNthTail f n l) = modifyNthTail (fun l => modifyNthTail g (n + m - n) (f l)) n l

Next tactic:
rw [@add_tsub_cancel_left, add_comm, modifyNthTail_modifyNthTail]
theorem modifyNthTail_modifyNthTail_same {f g : List α → List α} (n : ℕ) (l : List α) :
    (l.modifyNthTail f n).modifyNthTail g n = l.modifyNthTail (g ∘ f) n := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f g : List α → List α
n : ℕ
l : List α
⊢ modifyNthTail g n (modifyNthTail f n l) = modifyNthTail (g ∘ f) n l

Next tactic:
rw [modifyNthTail_modifyNthTail_le n n l (le_refl n), tsub_self]
theorem modifyNthTail_modifyNthTail_same {f g : List α → List α} (n : ℕ) (l : List α) :
    (l.modifyNthTail f n).modifyNthTail g n = l.modifyNthTail (g ∘ f) n := by
  rw [modifyNthTail_modifyNthTail_le n n l (le_refl n), tsub_self]; 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f g : List α → List α
n : ℕ
l : List α
⊢ modifyNthTail (fun l => modifyNthTail g 0 (f l)) n l = modifyNthTail (g ∘ f) n l

Next tactic:
rfl
theorem removeNth_eq_nthTail : ∀ (n) (l : List α), removeNth l n = modifyNthTail tail n l
  | 0, l => by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
⊢ removeNth l 0 = modifyNthTail tail 0 l

Next tactic:
cases l
theorem removeNth_eq_nthTail : ∀ (n) (l : List α), removeNth l n = modifyNthTail tail n l
  | 0, l => by cases l <;> 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
⊢ removeNth [] 0 = modifyNthTail tail 0 []

Next tactic:
rfl
theorem removeNth_eq_nthTail : ∀ (n) (l : List α), removeNth l n = modifyNthTail tail n l
  | 0, l => by cases l <;> 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
head✝ : α
tail✝ : List α
⊢ removeNth (head✝ :: tail✝) 0 = modifyNthTail tail 0 (head✝ :: tail✝)

Next tactic:
rfl
theorem modifyNth_eq_set (f : α → α) :
    ∀ (n) (l : List α), modifyNth f n l = ((fun a => set l n (f a)) <$> get? l n).getD l
  | 0, l => by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → α
l : List α
⊢ modifyNth f 0 l = Option.getD ((fun a => set l 0 (f a)) <$> get? l 0) l

Next tactic:
cases l
theorem modifyNth_eq_set (f : α → α) :
    ∀ (n) (l : List α), modifyNth f n l = ((fun a => set l n (f a)) <$> get? l n).getD l
  | 0, l => by cases l <;> 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → α
⊢ modifyNth f 0 [] = Option.getD ((fun a => set [] 0 (f a)) <$> get? [] 0) []

Next tactic:
rfl
theorem modifyNth_eq_set (f : α → α) :
    ∀ (n) (l : List α), modifyNth f n l = ((fun a => set l n (f a)) <$> get? l n).getD l
  | 0, l => by cases l <;> 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → α
head✝ : α
tail✝ : List α
⊢ modifyNth f 0 (head✝ :: tail✝) =
    Option.getD ((fun a => set (head✝ :: tail✝) 0 (f a)) <$> get? (head✝ :: tail✝) 0) (head✝ :: tail✝)

Next tactic:
rfl
theorem modifyNth_eq_set (f : α → α) :
    ∀ (n) (l : List α), modifyNth f n l = ((fun a => set l n (f a)) <$> get? l n).getD l
  | 0, l => by cases l <;> rfl
  | n + 1, [] => rfl
  | n + 1, b :: l =>
    (congr_arg (cons b) (modifyNth_eq_set f n l)).trans <| by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → α
n : ℕ
b : α
l : List α
⊢ b :: Option.getD ((fun a => set l n (f a)) <$> get? l n) l =
    Option.getD ((fun a => set (b :: l) (n + 1) (f a)) <$> get? (b :: l) (n + 1)) (b :: l)

Next tactic:
cases get? l n
theorem modifyNth_eq_set (f : α → α) :
    ∀ (n) (l : List α), modifyNth f n l = ((fun a => set l n (f a)) <$> get? l n).getD l
  | 0, l => by cases l <;> rfl
  | n + 1, [] => rfl
  | n + 1, b :: l =>
    (congr_arg (cons b) (modifyNth_eq_set f n l)).trans <| by cases get? l n <;> 

Proof state:
case none
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → α
n : ℕ
b : α
l : List α
⊢ b :: Option.getD ((fun a => set l n (f a)) <$> none) l =
    Option.getD ((fun a => set (b :: l) (n + 1) (f a)) <$> none) (b :: l)

Next tactic:
rfl
theorem modifyNth_eq_set (f : α → α) :
    ∀ (n) (l : List α), modifyNth f n l = ((fun a => set l n (f a)) <$> get? l n).getD l
  | 0, l => by cases l <;> rfl
  | n + 1, [] => rfl
  | n + 1, b :: l =>
    (congr_arg (cons b) (modifyNth_eq_set f n l)).trans <| by cases get? l n <;> 

Proof state:
case some
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → α
n : ℕ
b : α
l : List α
val✝ : α
⊢ b :: Option.getD ((fun a => set l n (f a)) <$> some val✝) l =
    Option.getD ((fun a => set (b :: l) (n + 1) (f a)) <$> some val✝) (b :: l)

Next tactic:
rfl
@[simp]
theorem get_set_of_ne {l : List α} {i j : ℕ} (h : i ≠ j) (a : α)
    (hj : j < (l.set i a).length) :
    (l.set i a).get ⟨j, hj⟩ = l.get ⟨j, by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
i j : ℕ
h : i ≠ j
a : α
hj : j < length (set l i a)
⊢ j < length l

Next tactic:
simpa using hj
@[simp]
theorem get_set_of_ne {l : List α} {i j : ℕ} (h : i ≠ j) (a : α)
    (hj : j < (l.set i a).length) :
    (l.set i a).get ⟨j, hj⟩ = l.get ⟨j, by simpa using hj⟩ := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
i j : ℕ
h : i ≠ j
a : α
hj : j < length (set l i a)
⊢ get (set l i a) { val := j, isLt := hj } = get l { val := j, isLt := (_ : j < length l) }

Next tactic:
rw [← Option.some_inj, ← List.get?_eq_get, List.get?_set_ne _ _ h, List.get?_eq_get]
@[simp, deprecated get_set_of_ne]
theorem nthLe_set_of_ne {l : List α} {i j : ℕ} (h : i ≠ j) (a : α)
    (hj : j < (l.set i a).length) :
    (l.set i a).nthLe j hj = l.nthLe j (by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
i j : ℕ
h : i ≠ j
a : α
hj : j < length (set l i a)
⊢ j < length l

Next tactic:
simpa using hj
theorem removeNth_insertNth (n : ℕ) (l : List α) : (l.insertNth n a).removeNth n = l := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
n : ℕ
l : List α
⊢ removeNth (insertNth n a l) n = l

Next tactic:
rw [removeNth_eq_nth_tail, insertNth, modifyNthTail_modifyNthTail_same]
theorem removeNth_insertNth (n : ℕ) (l : List α) : (l.insertNth n a).removeNth n = l := by
  rw [removeNth_eq_nth_tail, insertNth, modifyNthTail_modifyNthTail_same]
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
n : ℕ
l : List α
⊢ modifyNthTail (tail ∘ cons a) n l = l

Next tactic:
exact modifyNthTail_id _ _
theorem insertNth_removeNth_of_ge :
    ∀ n m as,
      n < length as → n ≤ m → insertNth m a (as.removeNth n) = (as.insertNth (m + 1) a).removeNth n
  | 0, 0, [], has, _ => (lt_irrefl _ has).elim
  | 0, 0, _ :: as, _, _ => by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a head✝ : α
as : List α
x✝¹ : 0 < length (head✝ :: as)
x✝ : 0 ≤ 0
⊢ insertNth 0 a (removeNth (head✝ :: as) 0) = removeNth (insertNth (0 + 1) a (head✝ :: as)) 0

Next tactic:
simp [removeNth, insertNth]
theorem insertNth_comm (a b : α) :
    ∀ (i j : ℕ) (l : List α) (_ : i ≤ j) (_ : j ≤ length l),
      (l.insertNth i a).insertNth (j + 1) b = (l.insertNth j b).insertNth i a
  | 0, j, l => by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a✝ a b : α
j : ℕ
l : List α
⊢ 0 ≤ j → j ≤ length l → insertNth (j + 1) b (insertNth 0 a l) = insertNth 0 a (insertNth j b l)

Next tactic:
simp [insertNth]
theorem insertNth_comm (a b : α) :
    ∀ (i j : ℕ) (l : List α) (_ : i ≤ j) (_ : j ≤ length l),
      (l.insertNth i a).insertNth (j + 1) b = (l.insertNth j b).insertNth i a
  | 0, j, l => by simp [insertNth]
  | i + 1, 0, l => fun h => (Nat.not_lt_zero _ h).elim
  | i + 1, j + 1, [] => by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a✝ a b : α
i j : ℕ
⊢ i + 1 ≤ j + 1 →
    j + 1 ≤ length [] → insertNth (j + 1 + 1) b (insertNth (i + 1) a []) = insertNth (i + 1) a (insertNth (j + 1) b [])

Next tactic:
simp
theorem insertNth_comm (a b : α) :
    ∀ (i j : ℕ) (l : List α) (_ : i ≤ j) (_ : j ≤ length l),
      (l.insertNth i a).insertNth (j + 1) b = (l.insertNth j b).insertNth i a
  | 0, j, l => by simp [insertNth]
  | i + 1, 0, l => fun h => (Nat.not_lt_zero _ h).elim
  | i + 1, j + 1, [] => by simp
  | i + 1, j + 1, c :: l => fun h₀ h₁ => by
    

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a✝ a b : α
i j : ℕ
c : α
l : List α
h₀ : i + 1 ≤ j + 1
h₁ : j + 1 ≤ length (c :: l)
⊢ insertNth (j + 1 + 1) b (insertNth (i + 1) a (c :: l)) = insertNth (i + 1) a (insertNth (j + 1) b (c :: l))

Next tactic:
simp only [insertNth_succ_cons, insertNth._eq_1, cons.injEq, true_and]
theorem insertNth_comm (a b : α) :
    ∀ (i j : ℕ) (l : List α) (_ : i ≤ j) (_ : j ≤ length l),
      (l.insertNth i a).insertNth (j + 1) b = (l.insertNth j b).insertNth i a
  | 0, j, l => by simp [insertNth]
  | i + 1, 0, l => fun h => (Nat.not_lt_zero _ h).elim
  | i + 1, j + 1, [] => by simp
  | i + 1, j + 1, c :: l => fun h₀ h₁ => by
    simp only [insertNth_succ_cons, insertNth._eq_1, cons.injEq, true_and]
    

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a✝ a b : α
i j : ℕ
c : α
l : List α
h₀ : i + 1 ≤ j + 1
h₁ : j + 1 ≤ length (c :: l)
⊢ modifyNthTail (cons b) (j + 1) (modifyNthTail (cons a) i l) = modifyNthTail (cons a) i (modifyNthTail (cons b) j l)

Next tactic:
exact insertNth_comm a b i j l (Nat.le_of_succ_le_succ h₀) (Nat.le_of_succ_le_succ h₁)
theorem mem_insertNth {a b : α} :
    ∀ {n : ℕ} {l : List α} (_ : n ≤ l.length), a ∈ l.insertNth n b ↔ a = b ∨ a ∈ l
  | 0, as, _ => by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a✝ a b : α
as : List α
x✝ : 0 ≤ length as
⊢ a ∈ insertNth 0 b as ↔ a = b ∨ a ∈ as

Next tactic:
simp
theorem mem_insertNth {a b : α} :
    ∀ {n : ℕ} {l : List α} (_ : n ≤ l.length), a ∈ l.insertNth n b ↔ a = b ∨ a ∈ l
  | 0, as, _ => by simp
  | n + 1, [], h => (Nat.not_succ_le_zero _ h).elim
  | n + 1, a' :: as, h => by
    

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a✝ a b : α
n : ℕ
a' : α
as : List α
h : n + 1 ≤ length (a' :: as)
⊢ a ∈ insertNth (n + 1) b (a' :: as) ↔ a = b ∨ a ∈ a' :: as

Next tactic:
rw [List.insertNth_succ_cons, mem_cons, mem_insertNth (Nat.le_of_succ_le_succ h),
      ← or_assoc, @or_comm (a = a'), or_assoc, mem_cons]
theorem insertNth_of_length_lt (l : List α) (x : α) (n : ℕ) (h : l.length < n) :
    insertNth n x l = l := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
h : length l < n
⊢ insertNth n x l = l

Next tactic:
induction' l with hd tl IH generalizing n
theorem insertNth_of_length_lt (l : List α) (x : α) (n : ℕ) (h : l.length < n) :
    insertNth n x l = l := by
  induction' l with hd tl IH generalizing n
  · 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a x : α
n : ℕ
h : length [] < n
⊢ insertNth n x [] = []

Next tactic:
cases n
theorem insertNth_of_length_lt (l : List α) (x : α) (n : ℕ) (h : l.length < n) :
    insertNth n x l = l := by
  induction' l with hd tl IH generalizing n
  · cases n
    · 

Proof state:
case nil.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a x : α
h : length [] < zero
⊢ insertNth zero x [] = []

Next tactic:
simp at h
theorem insertNth_of_length_lt (l : List α) (x : α) (n : ℕ) (h : l.length < n) :
    insertNth n x l = l := by
  induction' l with hd tl IH generalizing n
  · cases n
    · simp at h
    · 

Proof state:
case nil.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a x : α
n✝ : ℕ
h : length [] < succ n✝
⊢ insertNth (succ n✝) x [] = []

Next tactic:
simp
theorem insertNth_of_length_lt (l : List α) (x : α) (n : ℕ) (h : l.length < n) :
    insertNth n x l = l := by
  induction' l with hd tl IH generalizing n
  · cases n
    · simp at h
    · simp
  · 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a x hd : α
tl : List α
IH : ∀ (n : ℕ), length tl < n → insertNth n x tl = tl
n : ℕ
h : length (hd :: tl) < n
⊢ insertNth n x (hd :: tl) = hd :: tl

Next tactic:
cases n
theorem insertNth_of_length_lt (l : List α) (x : α) (n : ℕ) (h : l.length < n) :
    insertNth n x l = l := by
  induction' l with hd tl IH generalizing n
  · cases n
    · simp at h
    · simp
  · cases n
    · 

Proof state:
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a x hd : α
tl : List α
IH : ∀ (n : ℕ), length tl < n → insertNth n x tl = tl
h : length (hd :: tl) < zero
⊢ insertNth zero x (hd :: tl) = hd :: tl

Next tactic:
simp at h
theorem insertNth_of_length_lt (l : List α) (x : α) (n : ℕ) (h : l.length < n) :
    insertNth n x l = l := by
  induction' l with hd tl IH generalizing n
  · cases n
    · simp at h
    · simp
  · cases n
    · simp at h
    · 

Proof state:
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a x hd : α
tl : List α
IH : ∀ (n : ℕ), length tl < n → insertNth n x tl = tl
n✝ : ℕ
h : length (hd :: tl) < succ n✝
⊢ insertNth (succ n✝) x (hd :: tl) = hd :: tl

Next tactic:
simp only [Nat.succ_lt_succ_iff, length] at h
theorem insertNth_of_length_lt (l : List α) (x : α) (n : ℕ) (h : l.length < n) :
    insertNth n x l = l := by
  induction' l with hd tl IH generalizing n
  · cases n
    · simp at h
    · simp
  · cases n
    · simp at h
    · simp only [Nat.succ_lt_succ_iff, length] at h
      

Proof state:
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a x hd : α
tl : List α
IH : ∀ (n : ℕ), length tl < n → insertNth n x tl = tl
n✝ : ℕ
h : length tl < n✝
⊢ insertNth (succ n✝) x (hd :: tl) = hd :: tl

Next tactic:
simpa using IH _ h
@[simp]
theorem insertNth_length_self (l : List α) (x : α) : insertNth l.length x l = l ++ [x] := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
l : List α
x : α
⊢ insertNth (length l) x l = l ++ [x]

Next tactic:
induction' l with hd tl IH
@[simp]
theorem insertNth_length_self (l : List α) (x : α) : insertNth l.length x l = l ++ [x] := by
  induction' l with hd tl IH
  · 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a x : α
⊢ insertNth (length []) x [] = [] ++ [x]

Next tactic:
simp
@[simp]
theorem insertNth_length_self (l : List α) (x : α) : insertNth l.length x l = l ++ [x] := by
  induction' l with hd tl IH
  · simp
  · 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a x hd : α
tl : List α
IH : insertNth (length tl) x tl = tl ++ [x]
⊢ insertNth (length (hd :: tl)) x (hd :: tl) = hd :: tl ++ [x]

Next tactic:
simpa using IH
theorem length_le_length_insertNth (l : List α) (x : α) (n : ℕ) :
    l.length ≤ (insertNth n x l).length := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
⊢ length l ≤ length (insertNth n x l)

Next tactic:
rcases le_or_lt n l.length with hn | hn
theorem length_le_length_insertNth (l : List α) (x : α) (n : ℕ) :
    l.length ≤ (insertNth n x l).length := by
  rcases le_or_lt n l.length with hn | hn
  · 

Proof state:
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : n ≤ length l
⊢ length l ≤ length (insertNth n x l)

Next tactic:
rw [length_insertNth _ _ hn]
theorem length_le_length_insertNth (l : List α) (x : α) (n : ℕ) :
    l.length ≤ (insertNth n x l).length := by
  rcases le_or_lt n l.length with hn | hn
  · rw [length_insertNth _ _ hn]
    

Proof state:
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : n ≤ length l
⊢ length l ≤ length l + 1

Next tactic:
exact (Nat.lt_succ_self _).le
theorem length_le_length_insertNth (l : List α) (x : α) (n : ℕ) :
    l.length ≤ (insertNth n x l).length := by
  rcases le_or_lt n l.length with hn | hn
  · rw [length_insertNth _ _ hn]
    exact (Nat.lt_succ_self _).le
  · 

Proof state:
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : length l < n
⊢ length l ≤ length (insertNth n x l)

Next tactic:
rw [insertNth_of_length_lt _ _ _ hn]
theorem length_insertNth_le_succ (l : List α) (x : α) (n : ℕ) :
    (insertNth n x l).length ≤ l.length + 1 := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
⊢ length (insertNth n x l) ≤ length l + 1

Next tactic:
rcases le_or_lt n l.length with hn | hn
theorem length_insertNth_le_succ (l : List α) (x : α) (n : ℕ) :
    (insertNth n x l).length ≤ l.length + 1 := by
  rcases le_or_lt n l.length with hn | hn
  · 

Proof state:
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : n ≤ length l
⊢ length (insertNth n x l) ≤ length l + 1

Next tactic:
rw [length_insertNth _ _ hn]
theorem length_insertNth_le_succ (l : List α) (x : α) (n : ℕ) :
    (insertNth n x l).length ≤ l.length + 1 := by
  rcases le_or_lt n l.length with hn | hn
  · rw [length_insertNth _ _ hn]
  · 

Proof state:
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : length l < n
⊢ length (insertNth n x l) ≤ length l + 1

Next tactic:
rw [insertNth_of_length_lt _ _ _ hn]
theorem length_insertNth_le_succ (l : List α) (x : α) (n : ℕ) :
    (insertNth n x l).length ≤ l.length + 1 := by
  rcases le_or_lt n l.length with hn | hn
  · rw [length_insertNth _ _ hn]
  · rw [insertNth_of_length_lt _ _ _ hn]
    

Proof state:
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
l : List α
x : α
n : ℕ
hn : length l < n
⊢ length l ≤ length l + 1

Next tactic:
exact (Nat.lt_succ_self _).le