l3lab/ntp-mathlib huggingface dataset:
theorem next_get : ∀ (l : List α) (_h : Nodup l) (i : Fin l.length),
    next l (l.get i) (get_mem _ _ _) = l.get ⟨(i + 1) % l.length,
      Nat.mod_lt _ (i.1.zero_le.trans_lt i.2)⟩
  | [], _, i => by simpa using i.2
  | [_], _, _ => by simp
  | x::y::l, _h, ⟨0, h0⟩ => by
    have h₁ : get (x :: y :: l) { val := 0, isLt := h0 } = x := by simp
    rw [next_cons_cons_eq' _ _ _ _ _ h₁]
    simp
  | x::y::l, hn, ⟨i+1, hi⟩ => by
    have hx' : (x :: y :: l).get ⟨i+1, hi⟩ ≠ x := by
      intro H
      suffices (i + 1 : ℕ) = 0 by simpa
      rw [nodup_iff_injective_get] at hn
      refine' Fin.veq_of_eq (@hn ⟨i + 1, hi⟩ ⟨0, by simp⟩ _)
      simpa using H
    have hi' : i ≤ l.length := Nat.le_of_lt_succ (Nat.succ_lt_succ_iff.1 hi)
    rcases hi'.eq_or_lt with (hi' | hi')
    · subst hi'
      rw [next_getLast_cons]
      · simp [hi', get]
      · rw [get_cons_succ]; exact get_mem _ _ _
      · exact hx'
      · simp [getLast_eq_get]
      · exact hn.of_cons
    · rw [next_ne_head_ne_getLast _ _ _ _ _ hx']
      simp only [get_cons_succ]
      rw [next_get (y::l), ← get_cons_succ (a := x)]
      congr
      

Proof state:
case inr.e_a.e_val
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ (↑{ val := i, isLt := (_ : i < length (y :: l)) } + 1) % length (y :: l) + 1 = (i + 1 + 1) % length (x :: y :: l)
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ (↑{ val := i, isLt := (_ : i < length (y :: l)) } + 1) % length (y :: l) + 1 < length (x :: y :: l)
case inr._h
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ Nodup (y :: l)
case inr
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ get (x :: y :: l) { val := i + 1, isLt := hi } ≠ getLast (x :: y :: l) (_ : x :: y :: l ≠ [])
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ get (x :: y :: l) { val := i + 1, isLt := hi } ∈ y :: l

Next tactic:
dsimp
theorem next_get : ∀ (l : List α) (_h : Nodup l) (i : Fin l.length),
    next l (l.get i) (get_mem _ _ _) = l.get ⟨(i + 1) % l.length,
      Nat.mod_lt _ (i.1.zero_le.trans_lt i.2)⟩
  | [], _, i => by simpa using i.2
  | [_], _, _ => by simp
  | x::y::l, _h, ⟨0, h0⟩ => by
    have h₁ : get (x :: y :: l) { val := 0, isLt := h0 } = x := by simp
    rw [next_cons_cons_eq' _ _ _ _ _ h₁]
    simp
  | x::y::l, hn, ⟨i+1, hi⟩ => by
    have hx' : (x :: y :: l).get ⟨i+1, hi⟩ ≠ x := by
      intro H
      suffices (i + 1 : ℕ) = 0 by simpa
      rw [nodup_iff_injective_get] at hn
      refine' Fin.veq_of_eq (@hn ⟨i + 1, hi⟩ ⟨0, by simp⟩ _)
      simpa using H
    have hi' : i ≤ l.length := Nat.le_of_lt_succ (Nat.succ_lt_succ_iff.1 hi)
    rcases hi'.eq_or_lt with (hi' | hi')
    · subst hi'
      rw [next_getLast_cons]
      · simp [hi', get]
      · rw [get_cons_succ]; exact get_mem _ _ _
      · exact hx'
      · simp [getLast_eq_get]
      · exact hn.of_cons
    · rw [next_ne_head_ne_getLast _ _ _ _ _ hx']
      simp only [get_cons_succ]
      rw [next_get (y::l), ← get_cons_succ (a := x)]
      congr
      dsimp
      

Proof state:
case inr.e_a.e_val
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ (i + 1) % Nat.succ (length l) + 1 = (i + 1 + 1) % Nat.succ (Nat.succ (length l))
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ (↑{ val := i, isLt := (_ : i < length (y :: l)) } + 1) % length (y :: l) + 1 < length (x :: y :: l)
case inr._h
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ Nodup (y :: l)
case inr
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ get (x :: y :: l) { val := i + 1, isLt := hi } ≠ getLast (x :: y :: l) (_ : x :: y :: l ≠ [])
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ get (x :: y :: l) { val := i + 1, isLt := hi } ∈ y :: l

Next tactic:
rw [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'),
        Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 (Nat.succ_lt_succ_iff.2 hi'))]
theorem next_get : ∀ (l : List α) (_h : Nodup l) (i : Fin l.length),
    next l (l.get i) (get_mem _ _ _) = l.get ⟨(i + 1) % l.length,
      Nat.mod_lt _ (i.1.zero_le.trans_lt i.2)⟩
  | [], _, i => by simpa using i.2
  | [_], _, _ => by simp
  | x::y::l, _h, ⟨0, h0⟩ => by
    have h₁ : get (x :: y :: l) { val := 0, isLt := h0 } = x := by simp
    rw [next_cons_cons_eq' _ _ _ _ _ h₁]
    simp
  | x::y::l, hn, ⟨i+1, hi⟩ => by
    have hx' : (x :: y :: l).get ⟨i+1, hi⟩ ≠ x := by
      intro H
      suffices (i + 1 : ℕ) = 0 by simpa
      rw [nodup_iff_injective_get] at hn
      refine' Fin.veq_of_eq (@hn ⟨i + 1, hi⟩ ⟨0, by simp⟩ _)
      simpa using H
    have hi' : i ≤ l.length := Nat.le_of_lt_succ (Nat.succ_lt_succ_iff.1 hi)
    rcases hi'.eq_or_lt with (hi' | hi')
    · subst hi'
      rw [next_getLast_cons]
      · simp [hi', get]
      · rw [get_cons_succ]; exact get_mem _ _ _
      · exact hx'
      · simp [getLast_eq_get]
      · exact hn.of_cons
    · rw [next_ne_head_ne_getLast _ _ _ _ _ hx']
      simp only [get_cons_succ]
      rw [next_get (y::l), ← get_cons_succ (a := x)]
      congr
      dsimp
      rw [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'),
        Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 (Nat.succ_lt_succ_iff.2 hi'))]
      · 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ (↑{ val := i, isLt := (_ : i < length (y :: l)) } + 1) % length (y :: l) + 1 < length (x :: y :: l)

Next tactic:
simp [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'), Nat.succ_eq_add_one, hi']
theorem next_get : ∀ (l : List α) (_h : Nodup l) (i : Fin l.length),
    next l (l.get i) (get_mem _ _ _) = l.get ⟨(i + 1) % l.length,
      Nat.mod_lt _ (i.1.zero_le.trans_lt i.2)⟩
  | [], _, i => by simpa using i.2
  | [_], _, _ => by simp
  | x::y::l, _h, ⟨0, h0⟩ => by
    have h₁ : get (x :: y :: l) { val := 0, isLt := h0 } = x := by simp
    rw [next_cons_cons_eq' _ _ _ _ _ h₁]
    simp
  | x::y::l, hn, ⟨i+1, hi⟩ => by
    have hx' : (x :: y :: l).get ⟨i+1, hi⟩ ≠ x := by
      intro H
      suffices (i + 1 : ℕ) = 0 by simpa
      rw [nodup_iff_injective_get] at hn
      refine' Fin.veq_of_eq (@hn ⟨i + 1, hi⟩ ⟨0, by simp⟩ _)
      simpa using H
    have hi' : i ≤ l.length := Nat.le_of_lt_succ (Nat.succ_lt_succ_iff.1 hi)
    rcases hi'.eq_or_lt with (hi' | hi')
    · subst hi'
      rw [next_getLast_cons]
      · simp [hi', get]
      · rw [get_cons_succ]; exact get_mem _ _ _
      · exact hx'
      · simp [getLast_eq_get]
      · exact hn.of_cons
    · rw [next_ne_head_ne_getLast _ _ _ _ _ hx']
      simp only [get_cons_succ]
      rw [next_get (y::l), ← get_cons_succ (a := x)]
      congr
      dsimp
      rw [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'),
        Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 (Nat.succ_lt_succ_iff.2 hi'))]
      · simp [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'), Nat.succ_eq_add_one, hi']
      · 

Proof state:
case inr._h
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ Nodup (y :: l)

Next tactic:
exact hn.of_cons
theorem next_get : ∀ (l : List α) (_h : Nodup l) (i : Fin l.length),
    next l (l.get i) (get_mem _ _ _) = l.get ⟨(i + 1) % l.length,
      Nat.mod_lt _ (i.1.zero_le.trans_lt i.2)⟩
  | [], _, i => by simpa using i.2
  | [_], _, _ => by simp
  | x::y::l, _h, ⟨0, h0⟩ => by
    have h₁ : get (x :: y :: l) { val := 0, isLt := h0 } = x := by simp
    rw [next_cons_cons_eq' _ _ _ _ _ h₁]
    simp
  | x::y::l, hn, ⟨i+1, hi⟩ => by
    have hx' : (x :: y :: l).get ⟨i+1, hi⟩ ≠ x := by
      intro H
      suffices (i + 1 : ℕ) = 0 by simpa
      rw [nodup_iff_injective_get] at hn
      refine' Fin.veq_of_eq (@hn ⟨i + 1, hi⟩ ⟨0, by simp⟩ _)
      simpa using H
    have hi' : i ≤ l.length := Nat.le_of_lt_succ (Nat.succ_lt_succ_iff.1 hi)
    rcases hi'.eq_or_lt with (hi' | hi')
    · subst hi'
      rw [next_getLast_cons]
      · simp [hi', get]
      · rw [get_cons_succ]; exact get_mem _ _ _
      · exact hx'
      · simp [getLast_eq_get]
      · exact hn.of_cons
    · rw [next_ne_head_ne_getLast _ _ _ _ _ hx']
      simp only [get_cons_succ]
      rw [next_get (y::l), ← get_cons_succ (a := x)]
      congr
      dsimp
      rw [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'),
        Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 (Nat.succ_lt_succ_iff.2 hi'))]
      · simp [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'), Nat.succ_eq_add_one, hi']
      · exact hn.of_cons
      · 

Proof state:
case inr
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ get (x :: y :: l) { val := i + 1, isLt := hi } ≠ getLast (x :: y :: l) (_ : x :: y :: l ≠ [])

Next tactic:
rw [getLast_eq_get]
theorem next_get : ∀ (l : List α) (_h : Nodup l) (i : Fin l.length),
    next l (l.get i) (get_mem _ _ _) = l.get ⟨(i + 1) % l.length,
      Nat.mod_lt _ (i.1.zero_le.trans_lt i.2)⟩
  | [], _, i => by simpa using i.2
  | [_], _, _ => by simp
  | x::y::l, _h, ⟨0, h0⟩ => by
    have h₁ : get (x :: y :: l) { val := 0, isLt := h0 } = x := by simp
    rw [next_cons_cons_eq' _ _ _ _ _ h₁]
    simp
  | x::y::l, hn, ⟨i+1, hi⟩ => by
    have hx' : (x :: y :: l).get ⟨i+1, hi⟩ ≠ x := by
      intro H
      suffices (i + 1 : ℕ) = 0 by simpa
      rw [nodup_iff_injective_get] at hn
      refine' Fin.veq_of_eq (@hn ⟨i + 1, hi⟩ ⟨0, by simp⟩ _)
      simpa using H
    have hi' : i ≤ l.length := Nat.le_of_lt_succ (Nat.succ_lt_succ_iff.1 hi)
    rcases hi'.eq_or_lt with (hi' | hi')
    · subst hi'
      rw [next_getLast_cons]
      · simp [hi', get]
      · rw [get_cons_succ]; exact get_mem _ _ _
      · exact hx'
      · simp [getLast_eq_get]
      · exact hn.of_cons
    · rw [next_ne_head_ne_getLast _ _ _ _ _ hx']
      simp only [get_cons_succ]
      rw [next_get (y::l), ← get_cons_succ (a := x)]
      congr
      dsimp
      rw [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'),
        Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 (Nat.succ_lt_succ_iff.2 hi'))]
      · simp [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'), Nat.succ_eq_add_one, hi']
      · exact hn.of_cons
      · rw [getLast_eq_get]
        

Proof state:
case inr
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ get (x :: y :: l) { val := i + 1, isLt := hi } ≠
    get (x :: y :: l) { val := length (x :: y :: l) - 1, isLt := (_ : length (x :: y :: l) - 1 < length (x :: y :: l)) }

Next tactic:
intro h
theorem next_get : ∀ (l : List α) (_h : Nodup l) (i : Fin l.length),
    next l (l.get i) (get_mem _ _ _) = l.get ⟨(i + 1) % l.length,
      Nat.mod_lt _ (i.1.zero_le.trans_lt i.2)⟩
  | [], _, i => by simpa using i.2
  | [_], _, _ => by simp
  | x::y::l, _h, ⟨0, h0⟩ => by
    have h₁ : get (x :: y :: l) { val := 0, isLt := h0 } = x := by simp
    rw [next_cons_cons_eq' _ _ _ _ _ h₁]
    simp
  | x::y::l, hn, ⟨i+1, hi⟩ => by
    have hx' : (x :: y :: l).get ⟨i+1, hi⟩ ≠ x := by
      intro H
      suffices (i + 1 : ℕ) = 0 by simpa
      rw [nodup_iff_injective_get] at hn
      refine' Fin.veq_of_eq (@hn ⟨i + 1, hi⟩ ⟨0, by simp⟩ _)
      simpa using H
    have hi' : i ≤ l.length := Nat.le_of_lt_succ (Nat.succ_lt_succ_iff.1 hi)
    rcases hi'.eq_or_lt with (hi' | hi')
    · subst hi'
      rw [next_getLast_cons]
      · simp [hi', get]
      · rw [get_cons_succ]; exact get_mem _ _ _
      · exact hx'
      · simp [getLast_eq_get]
      · exact hn.of_cons
    · rw [next_ne_head_ne_getLast _ _ _ _ _ hx']
      simp only [get_cons_succ]
      rw [next_get (y::l), ← get_cons_succ (a := x)]
      congr
      dsimp
      rw [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'),
        Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 (Nat.succ_lt_succ_iff.2 hi'))]
      · simp [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'), Nat.succ_eq_add_one, hi']
      · exact hn.of_cons
      · rw [getLast_eq_get]
        intro h
        

Proof state:
case inr
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
h :
  get (x :: y :: l) { val := i + 1, isLt := hi } =
    get (x :: y :: l) { val := length (x :: y :: l) - 1, isLt := (_ : length (x :: y :: l) - 1 < length (x :: y :: l)) }
⊢ False

Next tactic:
have := nodup_iff_injective_get.1 hn h
theorem next_get : ∀ (l : List α) (_h : Nodup l) (i : Fin l.length),
    next l (l.get i) (get_mem _ _ _) = l.get ⟨(i + 1) % l.length,
      Nat.mod_lt _ (i.1.zero_le.trans_lt i.2)⟩
  | [], _, i => by simpa using i.2
  | [_], _, _ => by simp
  | x::y::l, _h, ⟨0, h0⟩ => by
    have h₁ : get (x :: y :: l) { val := 0, isLt := h0 } = x := by simp
    rw [next_cons_cons_eq' _ _ _ _ _ h₁]
    simp
  | x::y::l, hn, ⟨i+1, hi⟩ => by
    have hx' : (x :: y :: l).get ⟨i+1, hi⟩ ≠ x := by
      intro H
      suffices (i + 1 : ℕ) = 0 by simpa
      rw [nodup_iff_injective_get] at hn
      refine' Fin.veq_of_eq (@hn ⟨i + 1, hi⟩ ⟨0, by simp⟩ _)
      simpa using H
    have hi' : i ≤ l.length := Nat.le_of_lt_succ (Nat.succ_lt_succ_iff.1 hi)
    rcases hi'.eq_or_lt with (hi' | hi')
    · subst hi'
      rw [next_getLast_cons]
      · simp [hi', get]
      · rw [get_cons_succ]; exact get_mem _ _ _
      · exact hx'
      · simp [getLast_eq_get]
      · exact hn.of_cons
    · rw [next_ne_head_ne_getLast _ _ _ _ _ hx']
      simp only [get_cons_succ]
      rw [next_get (y::l), ← get_cons_succ (a := x)]
      congr
      dsimp
      rw [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'),
        Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 (Nat.succ_lt_succ_iff.2 hi'))]
      · simp [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'), Nat.succ_eq_add_one, hi']
      · exact hn.of_cons
      · rw [getLast_eq_get]
        intro h
        have := nodup_iff_injective_get.1 hn h
        

Proof state:
case inr
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
h :
  get (x :: y :: l) { val := i + 1, isLt := hi } =
    get (x :: y :: l) { val := length (x :: y :: l) - 1, isLt := (_ : length (x :: y :: l) - 1 < length (x :: y :: l)) }
this :
  { val := i + 1, isLt := hi } =
    { val := length (x :: y :: l) - 1, isLt := (_ : length (x :: y :: l) - 1 < length (x :: y :: l)) }
⊢ False

Next tactic:
simp at this
theorem next_get : ∀ (l : List α) (_h : Nodup l) (i : Fin l.length),
    next l (l.get i) (get_mem _ _ _) = l.get ⟨(i + 1) % l.length,
      Nat.mod_lt _ (i.1.zero_le.trans_lt i.2)⟩
  | [], _, i => by simpa using i.2
  | [_], _, _ => by simp
  | x::y::l, _h, ⟨0, h0⟩ => by
    have h₁ : get (x :: y :: l) { val := 0, isLt := h0 } = x := by simp
    rw [next_cons_cons_eq' _ _ _ _ _ h₁]
    simp
  | x::y::l, hn, ⟨i+1, hi⟩ => by
    have hx' : (x :: y :: l).get ⟨i+1, hi⟩ ≠ x := by
      intro H
      suffices (i + 1 : ℕ) = 0 by simpa
      rw [nodup_iff_injective_get] at hn
      refine' Fin.veq_of_eq (@hn ⟨i + 1, hi⟩ ⟨0, by simp⟩ _)
      simpa using H
    have hi' : i ≤ l.length := Nat.le_of_lt_succ (Nat.succ_lt_succ_iff.1 hi)
    rcases hi'.eq_or_lt with (hi' | hi')
    · subst hi'
      rw [next_getLast_cons]
      · simp [hi', get]
      · rw [get_cons_succ]; exact get_mem _ _ _
      · exact hx'
      · simp [getLast_eq_get]
      · exact hn.of_cons
    · rw [next_ne_head_ne_getLast _ _ _ _ _ hx']
      simp only [get_cons_succ]
      rw [next_get (y::l), ← get_cons_succ (a := x)]
      congr
      dsimp
      rw [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'),
        Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 (Nat.succ_lt_succ_iff.2 hi'))]
      · simp [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'), Nat.succ_eq_add_one, hi']
      · exact hn.of_cons
      · rw [getLast_eq_get]
        intro h
        have := nodup_iff_injective_get.1 hn h
        simp at this; 

Proof state:
case inr
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
h :
  get (x :: y :: l) { val := i + 1, isLt := hi } =
    get (x :: y :: l) { val := length (x :: y :: l) - 1, isLt := (_ : length (x :: y :: l) - 1 < length (x :: y :: l)) }
this : i = length l
⊢ False

Next tactic:
simp [this] at hi'
theorem next_get : ∀ (l : List α) (_h : Nodup l) (i : Fin l.length),
    next l (l.get i) (get_mem _ _ _) = l.get ⟨(i + 1) % l.length,
      Nat.mod_lt _ (i.1.zero_le.trans_lt i.2)⟩
  | [], _, i => by simpa using i.2
  | [_], _, _ => by simp
  | x::y::l, _h, ⟨0, h0⟩ => by
    have h₁ : get (x :: y :: l) { val := 0, isLt := h0 } = x := by simp
    rw [next_cons_cons_eq' _ _ _ _ _ h₁]
    simp
  | x::y::l, hn, ⟨i+1, hi⟩ => by
    have hx' : (x :: y :: l).get ⟨i+1, hi⟩ ≠ x := by
      intro H
      suffices (i + 1 : ℕ) = 0 by simpa
      rw [nodup_iff_injective_get] at hn
      refine' Fin.veq_of_eq (@hn ⟨i + 1, hi⟩ ⟨0, by simp⟩ _)
      simpa using H
    have hi' : i ≤ l.length := Nat.le_of_lt_succ (Nat.succ_lt_succ_iff.1 hi)
    rcases hi'.eq_or_lt with (hi' | hi')
    · subst hi'
      rw [next_getLast_cons]
      · simp [hi', get]
      · rw [get_cons_succ]; exact get_mem _ _ _
      · exact hx'
      · simp [getLast_eq_get]
      · exact hn.of_cons
    · rw [next_ne_head_ne_getLast _ _ _ _ _ hx']
      simp only [get_cons_succ]
      rw [next_get (y::l), ← get_cons_succ (a := x)]
      congr
      dsimp
      rw [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'),
        Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 (Nat.succ_lt_succ_iff.2 hi'))]
      · simp [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'), Nat.succ_eq_add_one, hi']
      · exact hn.of_cons
      · rw [getLast_eq_get]
        intro h
        have := nodup_iff_injective_get.1 hn h
        simp at this; simp [this] at hi'
      · 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ get (x :: y :: l) { val := i + 1, isLt := hi } ∈ y :: l

Next tactic:
rw [get_cons_succ]
theorem next_get : ∀ (l : List α) (_h : Nodup l) (i : Fin l.length),
    next l (l.get i) (get_mem _ _ _) = l.get ⟨(i + 1) % l.length,
      Nat.mod_lt _ (i.1.zero_le.trans_lt i.2)⟩
  | [], _, i => by simpa using i.2
  | [_], _, _ => by simp
  | x::y::l, _h, ⟨0, h0⟩ => by
    have h₁ : get (x :: y :: l) { val := 0, isLt := h0 } = x := by simp
    rw [next_cons_cons_eq' _ _ _ _ _ h₁]
    simp
  | x::y::l, hn, ⟨i+1, hi⟩ => by
    have hx' : (x :: y :: l).get ⟨i+1, hi⟩ ≠ x := by
      intro H
      suffices (i + 1 : ℕ) = 0 by simpa
      rw [nodup_iff_injective_get] at hn
      refine' Fin.veq_of_eq (@hn ⟨i + 1, hi⟩ ⟨0, by simp⟩ _)
      simpa using H
    have hi' : i ≤ l.length := Nat.le_of_lt_succ (Nat.succ_lt_succ_iff.1 hi)
    rcases hi'.eq_or_lt with (hi' | hi')
    · subst hi'
      rw [next_getLast_cons]
      · simp [hi', get]
      · rw [get_cons_succ]; exact get_mem _ _ _
      · exact hx'
      · simp [getLast_eq_get]
      · exact hn.of_cons
    · rw [next_ne_head_ne_getLast _ _ _ _ _ hx']
      simp only [get_cons_succ]
      rw [next_get (y::l), ← get_cons_succ (a := x)]
      congr
      dsimp
      rw [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'),
        Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 (Nat.succ_lt_succ_iff.2 hi'))]
      · simp [Nat.mod_eq_of_lt (Nat.succ_lt_succ_iff.2 hi'), Nat.succ_eq_add_one, hi']
      · exact hn.of_cons
      · rw [getLast_eq_get]
        intro h
        have := nodup_iff_injective_get.1 hn h
        simp at this; simp [this] at hi'
      · rw [get_cons_succ]; 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
i : ℕ
hi : i + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x
hi'✝ : i ≤ length l
hi' : i < length l
⊢ get (y :: l) { val := i, isLt := (_ : i < length (y :: l)) } ∈ y :: l

Next tactic:
exact get_mem _ _ _
set_option linter.deprecated false in
theorem prev_nthLe (l : List α) (h : Nodup l) (n : ℕ) (hn : n < l.length) :
    prev l (l.nthLe n hn) (nthLe_mem _ _ _) =
      l.nthLe ((n + (l.length - 1)) % l.length) (Nat.mod_lt _ (n.zero_le.trans_lt hn)) := by
  

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
n : ℕ
hn : n < length l
⊢ prev l (nthLe l n hn) (_ : nthLe l n hn ∈ l) =
    nthLe l ((n + (length l - 1)) % length l) (_ : (n + (length l - 1)) % length l < length l)

Next tactic:
cases' l with x l
set_option linter.deprecated false in
theorem prev_nthLe (l : List α) (h : Nodup l) (n : ℕ) (hn : n < l.length) :
    prev l (l.nthLe n hn) (nthLe_mem _ _ _) =
      l.nthLe ((n + (l.length - 1)) % l.length) (Nat.mod_lt _ (n.zero_le.trans_lt hn)) := by
  cases' l with x l
  · 

Proof state:
case nil
α : Type u_1
inst✝ : DecidableEq α
l : List α
x : α
n : ℕ
h : Nodup []
hn : n < length []
⊢ prev [] (nthLe [] n hn) (_ : nthLe [] n hn ∈ []) =
    nthLe [] ((n + (length [] - 1)) % length []) (_ : (n + (length [] - 1)) % length [] < length [])

Next tactic:
simp at hn
set_option linter.deprecated false in
theorem prev_nthLe (l : List α) (h : Nodup l) (n : ℕ) (hn : n < l.length) :
    prev l (l.nthLe n hn) (nthLe_mem _ _ _) =
      l.nthLe ((n + (l.length - 1)) % l.length) (Nat.mod_lt _ (n.zero_le.trans_lt hn)) := by
  cases' l with x l
  · simp at hn
  

Proof state:
case cons
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ : α
n : ℕ
x : α
l : List α
h : Nodup (x :: l)
hn : n < length (x :: l)
⊢ prev (x :: l) (nthLe (x :: l) n hn) (_ : nthLe (x :: l) n hn ∈ x :: l) =
    nthLe (x :: l) ((n + (length (x :: l) - 1)) % length (x :: l))
      (_ : (n + (length (x :: l) - 1)) % length (x :: l) < length (x :: l))

Next tactic:
induction' l with y l hl generalizing n x