l3lab/ntp-mathlib huggingface dataset:
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  

Proof state:
case h
α : Type u_1
inst✝ : DecidableEq α
l : List α
y : α
hl : Nodup l
h✝ : getLast (y :: l) (_ : y :: l ≠ []) ∈ l
h : getLast (y :: l) (_ : y :: l ≠ []) ∈ y :: l
hy : getLast (y :: l) (_ : y :: l ≠ []) ≠ y
⊢ getLast (y :: l) (_ : y :: l ≠ []) ∉ dropLast (y :: l)

Next tactic:
intro H
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  

Proof state:
case h
α : Type u_1
inst✝ : DecidableEq α
l : List α
y : α
hl : Nodup l
h✝ : getLast (y :: l) (_ : y :: l ≠ []) ∈ l
h : getLast (y :: l) (_ : y :: l ≠ []) ∈ y :: l
hy : getLast (y :: l) (_ : y :: l ≠ []) ≠ y
H : getLast (y :: l) (_ : y :: l ≠ []) ∈ dropLast (y :: l)
⊢ False

Next tactic:
obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · 

Proof state:
case h.intro.mk.zero
α : Type u_1
inst✝ : DecidableEq α
l : List α
y : α
hl : Nodup l
h✝ : getLast (y :: l) (_ : y :: l ≠ []) ∈ l
h : getLast (y :: l) (_ : y :: l ≠ []) ∈ y :: l
hy : getLast (y :: l) (_ : y :: l ≠ []) ≠ y
H : getLast (y :: l) (_ : y :: l ≠ []) ∈ dropLast (y :: l)
hk : Nat.zero < length (dropLast (y :: l))
hk' : get (dropLast (y :: l)) { val := Nat.zero, isLt := hk } = getLast (y :: l) (_ : y :: l ≠ [])
⊢ False

Next tactic:
rw [← Option.some_inj] at hk'
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    

Proof state:
case h.intro.mk.zero
α : Type u_1
inst✝ : DecidableEq α
l : List α
y : α
hl : Nodup l
h✝ : getLast (y :: l) (_ : y :: l ≠ []) ∈ l
h : getLast (y :: l) (_ : y :: l ≠ []) ∈ y :: l
hy : getLast (y :: l) (_ : y :: l ≠ []) ≠ y
H : getLast (y :: l) (_ : y :: l ≠ []) ∈ dropLast (y :: l)
hk : Nat.zero < length (dropLast (y :: l))
hk' : some (get (dropLast (y :: l)) { val := Nat.zero, isLt := hk }) = some (getLast (y :: l) (_ : y :: l ≠ []))
⊢ False

Next tactic:
rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    

Proof state:
case h.intro.mk.zero
α : Type u_1
inst✝ : DecidableEq α
l : List α
y : α
hl : Nodup l
h✝ : getLast (y :: l) (_ : y :: l ≠ []) ∈ l
h : getLast (y :: l) (_ : y :: l ≠ []) ∈ y :: l
hy : getLast (y :: l) (_ : y :: l ≠ []) ≠ y
H : getLast (y :: l) (_ : y :: l ≠ []) ∈ dropLast (y :: l)
hk : Nat.zero < length (dropLast (y :: l))
hk' : y = getLast (y :: l) (_ : y :: l ≠ [])
⊢ False
case h.intro.mk.zero
α : Type u_1
inst✝ : DecidableEq α
l : List α
y : α
hl : Nodup l
h✝ : getLast (y :: l) (_ : y :: l ≠ []) ∈ l
h : getLast (y :: l) (_ : y :: l ≠ []) ∈ y :: l
hy : getLast (y :: l) (_ : y :: l ≠ []) ≠ y
H : getLast (y :: l) (_ : y :: l ≠ []) ∈ dropLast (y :: l)
hk : Nat.zero < length (dropLast (y :: l))
hk' : get? (take (Nat.pred (length (y :: l))) (y :: l)) Nat.zero = some (getLast (y :: l) (_ : y :: l ≠ []))
⊢ Nat.zero < Nat.pred (length (y :: l))

Next tactic:
exact hy (Eq.symm hk')
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    exact hy (Eq.symm hk')
    

Proof state:
case h.intro.mk.zero
α : Type u_1
inst✝ : DecidableEq α
l : List α
y : α
hl : Nodup l
h✝ : getLast (y :: l) (_ : y :: l ≠ []) ∈ l
h : getLast (y :: l) (_ : y :: l ≠ []) ∈ y :: l
hy : getLast (y :: l) (_ : y :: l ≠ []) ≠ y
H : getLast (y :: l) (_ : y :: l ≠ []) ∈ dropLast (y :: l)
hk : Nat.zero < length (dropLast (y :: l))
hk' : get? (take (Nat.pred (length (y :: l))) (y :: l)) Nat.zero = some (getLast (y :: l) (_ : y :: l ≠ []))
⊢ Nat.zero < Nat.pred (length (y :: l))

Next tactic:
rw [Nat.zero_eq, length_cons, Nat.pred_succ]
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    exact hy (Eq.symm hk')
    rw [Nat.zero_eq, length_cons, Nat.pred_succ]
    

Proof state:
case h.intro.mk.zero
α : Type u_1
inst✝ : DecidableEq α
l : List α
y : α
hl : Nodup l
h✝ : getLast (y :: l) (_ : y :: l ≠ []) ∈ l
h : getLast (y :: l) (_ : y :: l ≠ []) ∈ y :: l
hy : getLast (y :: l) (_ : y :: l ≠ []) ≠ y
H : getLast (y :: l) (_ : y :: l ≠ []) ∈ dropLast (y :: l)
hk : Nat.zero < length (dropLast (y :: l))
hk' : get? (take (Nat.pred (length (y :: l))) (y :: l)) Nat.zero = some (getLast (y :: l) (_ : y :: l ≠ []))
⊢ 0 < length l

Next tactic:
exact length_pos_of_mem (by assumption)
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    exact hy (Eq.symm hk')
    rw [Nat.zero_eq, length_cons, Nat.pred_succ]
    exact length_pos_of_mem (by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l : List α
y : α
hl : Nodup l
h✝ : getLast (y :: l) (_ : y :: l ≠ []) ∈ l
h : getLast (y :: l) (_ : y :: l ≠ []) ∈ y :: l
hy : getLast (y :: l) (_ : y :: l ≠ []) ≠ y
H : getLast (y :: l) (_ : y :: l ≠ []) ∈ dropLast (y :: l)
hk : Nat.zero < length (dropLast (y :: l))
hk' : get? (take (Nat.pred (length (y :: l))) (y :: l)) Nat.zero = some (getLast (y :: l) (_ : y :: l ≠ []))
⊢ ?m.70207 ∈ l

Next tactic:
assumption
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    exact hy (Eq.symm hk')
    rw [Nat.zero_eq, length_cons, Nat.pred_succ]
    exact length_pos_of_mem (by assumption)
  

Proof state:
case h.intro.mk.succ
α : Type u_1
inst✝ : DecidableEq α
l : List α
y : α
hl : Nodup l
h✝ : getLast (y :: l) (_ : y :: l ≠ []) ∈ l
h : getLast (y :: l) (_ : y :: l ≠ []) ∈ y :: l
hy : getLast (y :: l) (_ : y :: l ≠ []) ≠ y
H : getLast (y :: l) (_ : y :: l ≠ []) ∈ dropLast (y :: l)
k : ℕ
hk : Nat.succ k < length (dropLast (y :: l))
hk' : get (dropLast (y :: l)) { val := Nat.succ k, isLt := hk } = getLast (y :: l) (_ : y :: l ≠ [])
⊢ False

Next tactic:
suffices k.succ = l.length by simp [this] at hk
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    exact hy (Eq.symm hk')
    rw [Nat.zero_eq, length_cons, Nat.pred_succ]
    exact length_pos_of_mem (by assumption)
  suffices k.succ = l.length by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l : List α
y : α
hl : Nodup l
h✝ : getLast (y :: l) (_ : y :: l ≠ []) ∈ l
h : getLast (y :: l) (_ : y :: l ≠ []) ∈ y :: l
hy : getLast (y :: l) (_ : y :: l ≠ []) ≠ y
H : getLast (y :: l) (_ : y :: l ≠ []) ∈ dropLast (y :: l)
k : ℕ
hk : Nat.succ k < length (dropLast (y :: l))
hk' : get (dropLast (y :: l)) { val := Nat.succ k, isLt := hk } = getLast (y :: l) (_ : y :: l ≠ [])
this : Nat.succ k = length l
⊢ False

Next tactic:
simp [this] at hk
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    exact hy (Eq.symm hk')
    rw [Nat.zero_eq, length_cons, Nat.pred_succ]
    exact length_pos_of_mem (by assumption)
  suffices k.succ = l.length by simp [this] at hk
  

Proof state:
case h.intro.mk.succ
α : Type u_1
inst✝ : DecidableEq α
l : List α
y : α
hl : Nodup l
h✝ : getLast (y :: l) (_ : y :: l ≠ []) ∈ l
h : getLast (y :: l) (_ : y :: l ≠ []) ∈ y :: l
hy : getLast (y :: l) (_ : y :: l ≠ []) ≠ y
H : getLast (y :: l) (_ : y :: l ≠ []) ∈ dropLast (y :: l)
k : ℕ
hk : Nat.succ k < length (dropLast (y :: l))
hk' : get (dropLast (y :: l)) { val := Nat.succ k, isLt := hk } = getLast (y :: l) (_ : y :: l ≠ [])
⊢ Nat.succ k = length l

Next tactic:
cases' l with hd tl
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    exact hy (Eq.symm hk')
    rw [Nat.zero_eq, length_cons, Nat.pred_succ]
    exact length_pos_of_mem (by assumption)
  suffices k.succ = l.length by simp [this] at hk
  cases' l with hd tl
  · 

Proof state:
case h.intro.mk.succ.nil
α : Type u_1
inst✝ : DecidableEq α
y : α
k : ℕ
hl : Nodup []
h✝ : getLast [y] (_ : [y] ≠ []) ∈ []
h : getLast [y] (_ : [y] ≠ []) ∈ [y]
hy : getLast [y] (_ : [y] ≠ []) ≠ y
H : getLast [y] (_ : [y] ≠ []) ∈ dropLast [y]
hk : Nat.succ k < length (dropLast [y])
hk' : get (dropLast [y]) { val := Nat.succ k, isLt := hk } = getLast [y] (_ : [y] ≠ [])
⊢ Nat.succ k = length []

Next tactic:
simp at hk
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    exact hy (Eq.symm hk')
    rw [Nat.zero_eq, length_cons, Nat.pred_succ]
    exact length_pos_of_mem (by assumption)
  suffices k.succ = l.length by simp [this] at hk
  cases' l with hd tl
  · simp at hk
  · 

Proof state:
case h.intro.mk.succ.cons
α : Type u_1
inst✝ : DecidableEq α
y : α
k : ℕ
hd : α
tl : List α
hl : Nodup (hd :: tl)
h✝ : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ hd :: tl
h : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ y :: hd :: tl
hy : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ≠ y
H : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ dropLast (y :: hd :: tl)
hk : Nat.succ k < length (dropLast (y :: hd :: tl))
hk' :
  get (dropLast (y :: hd :: tl)) { val := Nat.succ k, isLt := hk } = getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ [])
⊢ Nat.succ k = length (hd :: tl)

Next tactic:
rw [nodup_iff_injective_get] at hl
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    exact hy (Eq.symm hk')
    rw [Nat.zero_eq, length_cons, Nat.pred_succ]
    exact length_pos_of_mem (by assumption)
  suffices k.succ = l.length by simp [this] at hk
  cases' l with hd tl
  · simp at hk
  · rw [nodup_iff_injective_get] at hl
    

Proof state:
case h.intro.mk.succ.cons
α : Type u_1
inst✝ : DecidableEq α
y : α
k : ℕ
hd : α
tl : List α
hl : Function.Injective (get (hd :: tl))
h✝ : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ hd :: tl
h : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ y :: hd :: tl
hy : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ≠ y
H : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ dropLast (y :: hd :: tl)
hk : Nat.succ k < length (dropLast (y :: hd :: tl))
hk' :
  get (dropLast (y :: hd :: tl)) { val := Nat.succ k, isLt := hk } = getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ [])
⊢ Nat.succ k = length (hd :: tl)

Next tactic:
rw [length, Nat.succ_inj']
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    exact hy (Eq.symm hk')
    rw [Nat.zero_eq, length_cons, Nat.pred_succ]
    exact length_pos_of_mem (by assumption)
  suffices k.succ = l.length by simp [this] at hk
  cases' l with hd tl
  · simp at hk
  · rw [nodup_iff_injective_get] at hl
    rw [length, Nat.succ_inj']
    

Proof state:
case h.intro.mk.succ.cons
α : Type u_1
inst✝ : DecidableEq α
y : α
k : ℕ
hd : α
tl : List α
hl : Function.Injective (get (hd :: tl))
h✝ : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ hd :: tl
h : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ y :: hd :: tl
hy : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ≠ y
H : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ dropLast (y :: hd :: tl)
hk : Nat.succ k < length (dropLast (y :: hd :: tl))
hk' :
  get (dropLast (y :: hd :: tl)) { val := Nat.succ k, isLt := hk } = getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ [])
⊢ k = length tl

Next tactic:
refine' Fin.veq_of_eq (@hl ⟨k, Nat.lt_of_succ_lt <| by simpa using hk⟩ ⟨tl.length, by simp⟩ _)
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    exact hy (Eq.symm hk')
    rw [Nat.zero_eq, length_cons, Nat.pred_succ]
    exact length_pos_of_mem (by assumption)
  suffices k.succ = l.length by simp [this] at hk
  cases' l with hd tl
  · simp at hk
  · rw [nodup_iff_injective_get] at hl
    rw [length, Nat.succ_inj']
    refine' Fin.veq_of_eq (@hl ⟨k, Nat.lt_of_succ_lt <| by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
y : α
k : ℕ
hd : α
tl : List α
hl : Function.Injective (get (hd :: tl))
h✝ : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ hd :: tl
h : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ y :: hd :: tl
hy : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ≠ y
H : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ dropLast (y :: hd :: tl)
hk : Nat.succ k < length (dropLast (y :: hd :: tl))
hk' :
  get (dropLast (y :: hd :: tl)) { val := Nat.succ k, isLt := hk } = getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ [])
⊢ Nat.succ k < length (hd :: tl)

Next tactic:
simpa using hk
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    exact hy (Eq.symm hk')
    rw [Nat.zero_eq, length_cons, Nat.pred_succ]
    exact length_pos_of_mem (by assumption)
  suffices k.succ = l.length by simp [this] at hk
  cases' l with hd tl
  · simp at hk
  · rw [nodup_iff_injective_get] at hl
    rw [length, Nat.succ_inj']
    refine' Fin.veq_of_eq (@hl ⟨k, Nat.lt_of_succ_lt <| by simpa using hk⟩ ⟨tl.length, by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
y : α
k : ℕ
hd : α
tl : List α
hl : Function.Injective (get (hd :: tl))
h✝ : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ hd :: tl
h : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ y :: hd :: tl
hy : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ≠ y
H : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ dropLast (y :: hd :: tl)
hk : Nat.succ k < length (dropLast (y :: hd :: tl))
hk' :
  get (dropLast (y :: hd :: tl)) { val := Nat.succ k, isLt := hk } = getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ [])
⊢ length tl < length (hd :: tl)

Next tactic:
simp
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    exact hy (Eq.symm hk')
    rw [Nat.zero_eq, length_cons, Nat.pred_succ]
    exact length_pos_of_mem (by assumption)
  suffices k.succ = l.length by simp [this] at hk
  cases' l with hd tl
  · simp at hk
  · rw [nodup_iff_injective_get] at hl
    rw [length, Nat.succ_inj']
    refine' Fin.veq_of_eq (@hl ⟨k, Nat.lt_of_succ_lt <| by simpa using hk⟩ ⟨tl.length, by simp⟩ _)
    

Proof state:
case h.intro.mk.succ.cons
α : Type u_1
inst✝ : DecidableEq α
y : α
k : ℕ
hd : α
tl : List α
hl : Function.Injective (get (hd :: tl))
h✝ : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ hd :: tl
h : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ y :: hd :: tl
hy : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ≠ y
H : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ dropLast (y :: hd :: tl)
hk : Nat.succ k < length (dropLast (y :: hd :: tl))
hk' :
  get (dropLast (y :: hd :: tl)) { val := Nat.succ k, isLt := hk } = getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ [])
⊢ get (hd :: tl) { val := k, isLt := (_ : k < length (hd :: tl)) } =
    get (hd :: tl) { val := length tl, isLt := (_ : length tl < Nat.succ (length tl)) }

Next tactic:
rw [← Option.some_inj] at hk'
theorem next_getLast_cons (h : x ∈ l) (y : α) (h : x ∈ y :: l) (hy : x ≠ y)
    (hx : x = getLast (y :: l) (cons_ne_nil _ _)) (hl : Nodup l) : next (y :: l) x h = y := by
  rw [next, get, ← dropLast_append_getLast (cons_ne_nil y l), hx, nextOr_concat]
  subst hx
  intro H
  obtain ⟨⟨_ | k, hk⟩, hk'⟩ := get_of_mem H
  · rw [← Option.some_inj] at hk'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?_zero, head?_cons,
      Option.some_inj] at hk'
    exact hy (Eq.symm hk')
    rw [Nat.zero_eq, length_cons, Nat.pred_succ]
    exact length_pos_of_mem (by assumption)
  suffices k.succ = l.length by simp [this] at hk
  cases' l with hd tl
  · simp at hk
  · rw [nodup_iff_injective_get] at hl
    rw [length, Nat.succ_inj']
    refine' Fin.veq_of_eq (@hl ⟨k, Nat.lt_of_succ_lt <| by simpa using hk⟩ ⟨tl.length, by simp⟩ _)
    rw [← Option.some_inj] at hk'
    

Proof state:
case h.intro.mk.succ.cons
α : Type u_1
inst✝ : DecidableEq α
y : α
k : ℕ
hd : α
tl : List α
hl : Function.Injective (get (hd :: tl))
h✝ : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ hd :: tl
h : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ y :: hd :: tl
hy : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ≠ y
H : getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) ∈ dropLast (y :: hd :: tl)
hk : Nat.succ k < length (dropLast (y :: hd :: tl))
hk' :
  some (get (dropLast (y :: hd :: tl)) { val := Nat.succ k, isLt := hk }) =
    some (getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []))
⊢ get (hd :: tl) { val := k, isLt := (_ : k < length (hd :: tl)) } =
    get (hd :: tl) { val := length tl, isLt := (_ : length tl < Nat.succ (length tl)) }

Next tactic:
rw [← get?_eq_get, dropLast_eq_take, get?_take, get?, get?_eq_get, Option.some_inj] at hk'