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⟩ _)
      

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Function.Injective (get (x :: y :: l))
i : ℕ
hi : i + 1 < length (x :: y :: l)
H : get (x :: y :: l) { val := i + 1, isLt := hi } = x
⊢ get (x :: y :: l) { val := i + 1, isLt := hi } =
    get (x :: y :: l) { val := 0, isLt := (_ : 0 < Nat.succ (length l + 1)) }

Next tactic:
simpa using 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
    

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
⊢ next (x :: y :: l) (get (x :: y :: l) { val := i + 1, isLt := hi })
      (_ :
        get (x :: y :: l)
            { val := ↑{ val := i + 1, isLt := hi },
              isLt := (_ : ↑{ val := i + 1, isLt := hi } < length (x :: y :: l)) } ∈
          x :: y :: l) =
    get (x :: y :: l)
      { val := (↑{ val := i + 1, isLt := hi } + 1) % length (x :: y :: l),
        isLt := (_ : (↑{ val := i + 1, isLt := hi } + 1) % length (x :: y :: l) < length (x :: y :: l)) }

Next tactic:
have hi' : i ≤ l.length := Nat.le_of_lt_succ (Nat.succ_lt_succ_iff.1 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)
    

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
⊢ next (x :: y :: l) (get (x :: y :: l) { val := i + 1, isLt := hi })
      (_ :
        get (x :: y :: l)
            { val := ↑{ val := i + 1, isLt := hi },
              isLt := (_ : ↑{ val := i + 1, isLt := hi } < length (x :: y :: l)) } ∈
          x :: y :: l) =
    get (x :: y :: l)
      { val := (↑{ val := i + 1, isLt := hi } + 1) % length (x :: y :: l),
        isLt := (_ : (↑{ val := i + 1, isLt := hi } + 1) % length (x :: y :: l) < length (x :: y :: l)) }

Next tactic:
rcases hi'.eq_or_lt with (hi' | 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')
    · 

Proof state:
case inl
α : 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
⊢ next (x :: y :: l) (get (x :: y :: l) { val := i + 1, isLt := hi })
      (_ :
        get (x :: y :: l)
            { val := ↑{ val := i + 1, isLt := hi },
              isLt := (_ : ↑{ val := i + 1, isLt := hi } < length (x :: y :: l)) } ∈
          x :: y :: l) =
    get (x :: y :: l)
      { val := (↑{ val := i + 1, isLt := hi } + 1) % length (x :: y :: l),
        isLt := (_ : (↑{ val := i + 1, isLt := hi } + 1) % length (x :: y :: l) < length (x :: y :: l)) }

Next tactic:
subst 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'
      

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

Next tactic:
rw [next_getLast_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]
      · 

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

Next tactic:
simp [hi', 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]
      · 

Proof state:
case inl.h
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
hi : length l + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := length l + 1, isLt := hi } ≠ x
hi' : length l ≤ length l
⊢ get (x :: y :: l) { val := length l + 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]; 

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

Next tactic:
exact get_mem _ _ _
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 _ _ _
      · 

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

Next tactic:
exact hx'
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'
      · 

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

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

Proof state:
case inl.hl
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
hn : Nodup (x :: y :: l)
hi : length l + 1 < length (x :: y :: l)
hx' : get (x :: y :: l) { val := length l + 1, isLt := hi } ≠ x
hi' : length l ≤ 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
    · 

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
⊢ next (x :: y :: l) (get (x :: y :: l) { val := i + 1, isLt := hi })
      (_ :
        get (x :: y :: l)
            { val := ↑{ val := i + 1, isLt := hi },
              isLt := (_ : ↑{ val := i + 1, isLt := hi } < length (x :: y :: l)) } ∈
          x :: y :: l) =
    get (x :: y :: l)
      { val := (↑{ val := i + 1, isLt := hi } + 1) % length (x :: y :: l),
        isLt := (_ : (↑{ val := i + 1, isLt := hi } + 1) % length (x :: y :: l) < length (x :: y :: l)) }

Next tactic:
rw [next_ne_head_ne_getLast _ _ _ _ _ hx']
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']
      

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
⊢ next (y :: l) (get (x :: y :: l) { val := i + 1, isLt := hi })
      (_ : get (x :: y :: l) { val := i + 1, isLt := hi } ∈ y :: l) =
    get (x :: y :: l)
      { val := (↑{ val := i + 1, isLt := hi } + 1) % length (x :: y :: l),
        isLt := (_ : (↑{ val := i + 1, isLt := hi } + 1) % length (x :: y :: l) < length (x :: 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:
simp only [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]
      

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
⊢ next (y :: l) (get (y :: l) { val := i, isLt := (_ : i < length (y :: l)) })
      (_ : get (y :: l) { val := i, isLt := (_ : i < length (y :: l)) } ∈ y :: l) =
    get (x :: y :: l)
      { val := (i + 1 + 1) % length (x :: y :: l),
        isLt := (_ : (↑{ val := i + 1, isLt := hi } + 1) % length (x :: y :: l) < length (x :: 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 [next_get (y::l), ← get_cons_succ (a := x)]
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)]
      

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 := (↑{ val := i, isLt := (_ : i < length (y :: l)) } + 1) % length (y :: l) + 1, isLt := ?m.109156 } =
    get (x :: y :: l)
      { val := (i + 1 + 1) % length (x :: y :: l),
        isLt := (_ : (↑{ val := i + 1, isLt := hi } + 1) % length (x :: y :: l) < 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:
congr