l3lab/ntp-mathlib huggingface dataset:
@[deprecated get_length_sub_one]
theorem nthLe_length_sub_one {l : List α} (h : l.length - 1 < l.length) :
    l.nthLe (l.length - 1) h = l.getLast (by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
h : length l - 1 < length l
⊢ l ≠ []

Next tactic:
rintro rfl
@[deprecated get_length_sub_one]
theorem nthLe_length_sub_one {l : List α} (h : l.length - 1 < l.length) :
    l.nthLe (l.length - 1) h = l.getLast (by rintro rfl; 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : length [] - 1 < length []
⊢ False

Next tactic:
exact Nat.lt_irrefl 0 h
@[deprecated get_cons_length]
theorem nthLe_cons_length : ∀ (x : α) (xs : List α) (n : ℕ) (h : n = xs.length),
    (x :: xs).nthLe n (by 

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

Next tactic:
simp [h]
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
    (l.drop n).take 1 = [l.get ⟨n, h⟩] := by
  

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

Next tactic:
induction' l with x l ih generalizing n
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
    (l.drop n).take 1 = [l.get ⟨n, h⟩] := by
  induction' l with x l ih generalizing n
  · 

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

Next tactic:
cases h
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
    (l.drop n).take 1 = [l.get ⟨n, h⟩] := by
  induction' l with x l ih generalizing n
  · cases h
  · 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
n : ℕ
h : n < length (x :: l)
⊢ take 1 (drop n (x :: l)) = [get (x :: l) { val := n, isLt := h }]

Next tactic:
by_cases h₁ : l = []
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
    (l.drop n).take 1 = [l.get ⟨n, h⟩] := by
  induction' l with x l ih generalizing n
  · cases h
  · by_cases h₁ : l = []
    · 

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
n : ℕ
h : n < length (x :: l)
h₁ : l = []
⊢ take 1 (drop n (x :: l)) = [get (x :: l) { val := n, isLt := h }]

Next tactic:
subst h₁
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
    (l.drop n).take 1 = [l.get ⟨n, h⟩] := by
  induction' l with x l ih generalizing n
  · cases h
  · by_cases h₁ : l = []
    · subst h₁
      

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
n : ℕ
ih : ∀ {n : ℕ} (h : n < length []), take 1 (drop n []) = [get [] { val := n, isLt := h }]
h : n < length [x]
⊢ take 1 (drop n [x]) = [get [x] { val := n, isLt := h }]

Next tactic:
rw [get_singleton]
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
    (l.drop n).take 1 = [l.get ⟨n, h⟩] := by
  induction' l with x l ih generalizing n
  · cases h
  · by_cases h₁ : l = []
    · subst h₁
      rw [get_singleton]
      

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
n : ℕ
ih : ∀ {n : ℕ} (h : n < length []), take 1 (drop n []) = [get [] { val := n, isLt := h }]
h : n < length [x]
⊢ take 1 (drop n [x]) = [x]

Next tactic:
simp only [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at h
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
    (l.drop n).take 1 = [l.get ⟨n, h⟩] := by
  induction' l with x l ih generalizing n
  · cases h
  · by_cases h₁ : l = []
    · subst h₁
      rw [get_singleton]
      simp only [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at h
      

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
n : ℕ
ih : ∀ {n : ℕ} (h : n < length []), take 1 (drop n []) = [get [] { val := n, isLt := h }]
h : n = 0
⊢ take 1 (drop n [x]) = [x]

Next tactic:
subst h
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
    (l.drop n).take 1 = [l.get ⟨n, h⟩] := by
  induction' l with x l ih generalizing n
  · cases h
  · by_cases h₁ : l = []
    · subst h₁
      rw [get_singleton]
      simp only [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at h
      subst h
      

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
ih : ∀ {n : ℕ} (h : n < length []), take 1 (drop n []) = [get [] { val := n, isLt := h }]
⊢ take 1 (drop 0 [x]) = [x]

Next tactic:
simp
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
    (l.drop n).take 1 = [l.get ⟨n, h⟩] := by
  induction' l with x l ih generalizing n
  · cases h
  · by_cases h₁ : l = []
    · subst h₁
      rw [get_singleton]
      simp only [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at h
      subst h
      simp
    

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
n : ℕ
h : n < length (x :: l)
h₁ : ¬l = []
⊢ take 1 (drop n (x :: l)) = [get (x :: l) { val := n, isLt := h }]

Next tactic:
have h₂ := h
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
    (l.drop n).take 1 = [l.get ⟨n, h⟩] := by
  induction' l with x l ih generalizing n
  · cases h
  · by_cases h₁ : l = []
    · subst h₁
      rw [get_singleton]
      simp only [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at h
      subst h
      simp
    have h₂ := h
    

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
n : ℕ
h : n < length (x :: l)
h₁ : ¬l = []
h₂ : n < length (x :: l)
⊢ take 1 (drop n (x :: l)) = [get (x :: l) { val := n, isLt := h }]

Next tactic:
rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
    (l.drop n).take 1 = [l.get ⟨n, h⟩] := by
  induction' l with x l ih generalizing n
  · cases h
  · by_cases h₁ : l = []
    · subst h₁
      rw [get_singleton]
      simp only [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at h
      subst h
      simp
    have h₂ := h
    rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂
    

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
n : ℕ
h : n < length (x :: l)
h₁ : ¬l = []
h₂ : n = length l ∨ n < length l
⊢ take 1 (drop n (x :: l)) = [get (x :: l) { val := n, isLt := h }]

Next tactic:
cases n
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
    (l.drop n).take 1 = [l.get ⟨n, h⟩] := by
  induction' l with x l ih generalizing n
  · cases h
  · by_cases h₁ : l = []
    · subst h₁
      rw [get_singleton]
      simp only [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at h
      subst h
      simp
    have h₂ := h
    rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂
    cases n
    · 

Proof state:
case neg.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
h₁ : ¬l = []
h : zero < length (x :: l)
h₂ : zero = length l ∨ zero < length l
⊢ take 1 (drop zero (x :: l)) = [get (x :: l) { val := zero, isLt := h }]

Next tactic:
simp [get]
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
    (l.drop n).take 1 = [l.get ⟨n, h⟩] := by
  induction' l with x l ih generalizing n
  · cases h
  · by_cases h₁ : l = []
    · subst h₁
      rw [get_singleton]
      simp only [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at h
      subst h
      simp
    have h₂ := h
    rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂
    cases n
    · simp [get]
    

Proof state:
case neg.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
h₁ : ¬l = []
n✝ : ℕ
h : succ n✝ < length (x :: l)
h₂ : succ n✝ = length l ∨ succ n✝ < length l
⊢ take 1 (drop (succ n✝) (x :: l)) = [get (x :: l) { val := succ n✝, isLt := h }]

Next tactic:
rw [drop, get]
theorem take_one_drop_eq_of_lt_length {l : List α} {n : ℕ} (h : n < l.length) :
    (l.drop n).take 1 = [l.get ⟨n, h⟩] := by
  induction' l with x l ih generalizing n
  · cases h
  · by_cases h₁ : l = []
    · subst h₁
      rw [get_singleton]
      simp only [length_singleton, lt_succ_iff, nonpos_iff_eq_zero] at h
      subst h
      simp
    have h₂ := h
    rw [length_cons, Nat.lt_succ_iff, le_iff_eq_or_lt] at h₂
    cases n
    · simp [get]
    rw [drop, get]
    

Proof state:
case neg.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
l : List α
ih : ∀ {n : ℕ} (h : n < length l), take 1 (drop n l) = [get l { val := n, isLt := h }]
h₁ : ¬l = []
n✝ : ℕ
h : succ n✝ < length (x :: l)
h₂ : succ n✝ = length l ∨ succ n✝ < length l
⊢ take 1 (drop n✝ l) = [get l { val := n✝, isLt := (_ : succ n✝ ≤ length l) }]

Next tactic:
apply ih
@[simp]
theorem indexOf_get [DecidableEq α] {a : α} : ∀ {l : List α} (h), get l ⟨indexOf a l, h⟩ = a
  | b :: l, h => by
    

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
h : indexOf a (b :: l) < length (b :: l)
⊢ get (b :: l) { val := indexOf a (b :: l), isLt := h } = a

Next tactic:
by_cases h' : b = a
@[simp]
theorem indexOf_get [DecidableEq α] {a : α} : ∀ {l : List α} (h), get l ⟨indexOf a l, h⟩ = a
  | b :: l, h => by
    by_cases h' : b = a <;>
    

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
h : indexOf a (b :: l) < length (b :: l)
h' : b = a
⊢ get (b :: l) { val := indexOf a (b :: l), isLt := h } = a

Next tactic:
simp only [h', if_pos, if_false, indexOf_cons, get, @indexOf_get _ _ l, cond_eq_if, beq_iff_eq]
@[simp]
theorem indexOf_get [DecidableEq α] {a : α} : ∀ {l : List α} (h), get l ⟨indexOf a l, h⟩ = a
  | b :: l, h => by
    by_cases h' : b = a <;>
    

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
h : indexOf a (b :: l) < length (b :: l)
h' : ¬b = a
⊢ get (b :: l) { val := indexOf a (b :: l), isLt := h } = a

Next tactic:
simp only [h', if_pos, if_false, indexOf_cons, get, @indexOf_get _ _ l, cond_eq_if, beq_iff_eq]
@[simp]
theorem indexOf_get? [DecidableEq α] {a : α} {l : List α} (h : a ∈ l) :
    get? l (indexOf a l) = some a := by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
a : α
l : List α
h : a ∈ l
⊢ get? l (indexOf a l) = some a

Next tactic:
rw [nthLe_get?, indexOf_nthLe (indexOf_lt_length.2 h)]
@[deprecated]
theorem get_reverse_aux₁ :
    ∀ (l r : List α) (i h1 h2), get (reverseAux l r) ⟨i + length l, h1⟩ = get r ⟨i, h2⟩
  | [], r, i => fun h1 _ => rfl
  | a :: l, r, i => by
    

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

Next tactic:
rw [show i + length (a :: l) = i + 1 + length l from add_right_comm i (length l) 1]
@[deprecated]
theorem get_reverse_aux₁ :
    ∀ (l r : List α) (i h1 h2), get (reverseAux l r) ⟨i + length l, h1⟩ = get r ⟨i, h2⟩
  | [], r, i => fun h1 _ => rfl
  | a :: l, r, i => by
    rw [show i + length (a :: l) = i + 1 + length l from add_right_comm i (length l) 1]
    

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

Next tactic:
exact fun h1 h2 => get_reverse_aux₁ l (a :: r) (i + 1) h1 (succ_lt_succ h2)
theorem indexOf_inj [DecidableEq α] {l : List α} {x y : α} (hx : x ∈ l) (hy : y ∈ l) :
    indexOf x l = indexOf y l ↔ x = y :=
  ⟨fun h => by
    

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
l : List α
x y : α
hx : x ∈ l
hy : y ∈ l
h : indexOf x l = indexOf y l
⊢ x = y

Next tactic:
have x_eq_y :
        get l ⟨indexOf x l, indexOf_lt_length.2 hx⟩ =
        get l ⟨indexOf y l, indexOf_lt_length.2 hy⟩ := by
      simp only [h]
theorem indexOf_inj [DecidableEq α] {l : List α} {x y : α} (hx : x ∈ l) (hy : y ∈ l) :
    indexOf x l = indexOf y l ↔ x = y :=
  ⟨fun h => by
    have x_eq_y :
        get l ⟨indexOf x l, indexOf_lt_length.2 hx⟩ =
        get l ⟨indexOf y l, indexOf_lt_length.2 hy⟩ := by
      

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
l : List α
x y : α
hx : x ∈ l
hy : y ∈ l
h : indexOf x l = indexOf y l
⊢ get l { val := indexOf x l, isLt := (_ : indexOf x l < length l) } =
    get l { val := indexOf y l, isLt := (_ : indexOf y l < length l) }

Next tactic:
simp only [h]
theorem indexOf_inj [DecidableEq α] {l : List α} {x y : α} (hx : x ∈ l) (hy : y ∈ l) :
    indexOf x l = indexOf y l ↔ x = y :=
  ⟨fun h => by
    have x_eq_y :
        get l ⟨indexOf x l, indexOf_lt_length.2 hx⟩ =
        get l ⟨indexOf y l, indexOf_lt_length.2 hy⟩ := by
      simp only [h]
    

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
l : List α
x y : α
hx : x ∈ l
hy : y ∈ l
h : indexOf x l = indexOf y l
x_eq_y :
  get l { val := indexOf x l, isLt := (_ : indexOf x l < length l) } =
    get l { val := indexOf y l, isLt := (_ : indexOf y l < length l) }
⊢ x = y

Next tactic:
simp only [indexOf_get] at x_eq_y
theorem indexOf_inj [DecidableEq α] {l : List α} {x y : α} (hx : x ∈ l) (hy : y ∈ l) :
    indexOf x l = indexOf y l ↔ x = y :=
  ⟨fun h => by
    have x_eq_y :
        get l ⟨indexOf x l, indexOf_lt_length.2 hx⟩ =
        get l ⟨indexOf y l, indexOf_lt_length.2 hy⟩ := by
      simp only [h]
    simp only [indexOf_get] at x_eq_y; 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
l : List α
x y : α
hx : x ∈ l
hy : y ∈ l
h : indexOf x l = indexOf y l
x_eq_y : x = y
⊢ x = y

Next tactic:
exact x_eq_y
theorem indexOf_inj [DecidableEq α] {l : List α} {x y : α} (hx : x ∈ l) (hy : y ∈ l) :
    indexOf x l = indexOf y l ↔ x = y :=
  ⟨fun h => by
    have x_eq_y :
        get l ⟨indexOf x l, indexOf_lt_length.2 hx⟩ =
        get l ⟨indexOf y l, indexOf_lt_length.2 hy⟩ := by
      simp only [h]
    simp only [indexOf_get] at x_eq_y; exact x_eq_y, fun h => by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
l : List α
x y : α
hx : x ∈ l
hy : y ∈ l
h : x = y
⊢ indexOf x l = indexOf y l

Next tactic:
subst h
theorem indexOf_inj [DecidableEq α] {l : List α} {x y : α} (hx : x ∈ l) (hy : y ∈ l) :
    indexOf x l = indexOf y l ↔ x = y :=
  ⟨fun h => by
    have x_eq_y :
        get l ⟨indexOf x l, indexOf_lt_length.2 hx⟩ =
        get l ⟨indexOf y l, indexOf_lt_length.2 hy⟩ := by
      simp only [h]
    simp only [indexOf_get] at x_eq_y; exact x_eq_y, fun h => by subst h; 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
l : List α
x : α
hx hy : x ∈ l
⊢ indexOf x l = indexOf x l

Next tactic:
rfl
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
    

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
l r : List α
h1 : length (a :: l) - 1 - 0 < length (reverseAux (a :: l) r)
x✝ : 0 < length (a :: l)
⊢ get (reverseAux (a :: l) r) { val := length (a :: l) - 1 - 0, isLt := h1 } = get (a :: l) { val := 0, isLt := x✝ }

Next tactic:
have aux := get_reverse_aux₁ l (a :: r) 0
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
    

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

Next tactic:
rw [zero_add] at aux
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
    

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

Next tactic:
exact aux _ (zero_lt_succ _)
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
    

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)
⊢ get (reverseAux (a :: l) r) { val := length (a :: l) - 1 - (i + 1), isLt := h1 } =
    get (a :: l) { val := i + 1, isLt := h2 }

Next tactic:
have aux := get_reverse_aux₂ l (a :: r) i
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
    

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 l - 1 - i < length (reverseAux l (a :: r))) (h2 : i < length l),
    get (reverseAux l (a :: r)) { val := length l - 1 - i, isLt := h1 } = get l { val := i, isLt := h2 }
⊢ get (reverseAux (a :: l) r) { val := length (a :: l) - 1 - (i + 1), isLt := h1 } =
    get (a :: l) { val := i + 1, isLt := h2 }

Next tactic:
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]
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 

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 l - 1 - i < length (reverseAux l (a :: r))) (h2 : i < length l),
    get (reverseAux l (a :: r)) { val := length l - 1 - i, isLt := h1 } = get l { val := i, isLt := h2 }
⊢ length (a :: l) - 1 - (i + 1) = length l - (1 + i)

Next tactic:
rw [add_comm]
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]; 

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 l - 1 - i < length (reverseAux l (a :: r))) (h2 : i < length l),
    get (reverseAux l (a :: r)) { val := length l - 1 - i, isLt := h1 } = get l { val := i, isLt := h2 }
⊢ length (a :: l) - 1 - (1 + i) = length l - (1 + i)

Next tactic:
rfl
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 

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 l - 1 - i < length (reverseAux l (a :: r))) (h2 : i < length l),
    get (reverseAux l (a :: r)) { val := length l - 1 - i, isLt := h1 } = get l { val := i, isLt := h2 }
⊢ length l - (1 + i) = length l - 1 - i

Next tactic:
rw [← tsub_add_eq_tsub_tsub]
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]
    

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 l - 1 - i < length (reverseAux l (a :: r))) (h2 : i < length l),
    get (reverseAux l (a :: r)) { val := length l - 1 - i, 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:
rw [← heq] at aux