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
  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'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?, get?_eq_get, Option.some_inj] at hk'
    rw [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'✝ : get? (hd :: tl) k = some (getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []))
hk' :
  get (hd :: tl) { val := k, isLt := (_ : k < length (hd :: tl)) } = getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ [])
⊢ getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []) =
    get (hd :: tl) { val := length tl, isLt := (_ : length tl < Nat.succ (length tl)) }
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? (take (Nat.pred (length (y :: hd :: tl))) (y :: hd :: tl)) (Nat.succ k) =
    some (getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []))
⊢ Nat.succ k < Nat.pred (length (y :: hd :: tl))

Next tactic:
simp only [getLast_eq_get, length_cons, ge_iff_le, Nat.succ_sub_succ_eq_sub,
      nonpos_iff_eq_zero, add_eq_zero_iff, and_false, tsub_zero, get_cons_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]
    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'
    rw [← get?_eq_get, dropLast_eq_take, get?_take, get?, get?_eq_get, Option.some_inj] at hk'
    rw [hk']
    simp only [getLast_eq_get, length_cons, ge_iff_le, Nat.succ_sub_succ_eq_sub,
      nonpos_iff_eq_zero, add_eq_zero_iff, and_false, tsub_zero, get_cons_succ]
    

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? (take (Nat.pred (length (y :: hd :: tl))) (y :: hd :: tl)) (Nat.succ k) =
    some (getLast (y :: hd :: tl) (_ : y :: hd :: tl ≠ []))
⊢ Nat.succ k < Nat.pred (length (y :: hd :: tl))

Next tactic:
simpa using hk
theorem prev_getLast_cons' (y : α) (hxy : x ∈ y :: l) (hx : x = y) :
    prev (y :: l) x hxy = getLast (y :: l) (cons_ne_nil _ _) := by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l : List α
x y : α
hxy : x ∈ y :: l
hx : x = y
⊢ prev (y :: l) x hxy = getLast (y :: l) (_ : y :: l ≠ [])

Next tactic:
cases l
theorem prev_getLast_cons' (y : α) (hxy : x ∈ y :: l) (hx : x = y) :
    prev (y :: l) x hxy = getLast (y :: l) (cons_ne_nil _ _) := by cases l <;> 

Proof state:
case nil
α : Type u_1
inst✝ : DecidableEq α
x y : α
hx : x = y
hxy : x ∈ [y]
⊢ prev [y] x hxy = getLast [y] (_ : [y] ≠ [])

Next tactic:
simp [prev, hx]
theorem prev_getLast_cons' (y : α) (hxy : x ∈ y :: l) (hx : x = y) :
    prev (y :: l) x hxy = getLast (y :: l) (cons_ne_nil _ _) := by cases l <;> 

Proof state:
case cons
α : Type u_1
inst✝ : DecidableEq α
x y : α
hx : x = y
head✝ : α
tail✝ : List α
hxy : x ∈ y :: head✝ :: tail✝
⊢ prev (y :: head✝ :: tail✝) x hxy = getLast (y :: head✝ :: tail✝) (_ : y :: head✝ :: tail✝ ≠ [])

Next tactic:
simp [prev, hx]
theorem prev_cons_cons_eq' (y z : α) (h : x ∈ y :: z :: l) (hx : x = y) :
    prev (y :: z :: l) x h = getLast (z :: l) (cons_ne_nil _ _) := by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l : List α
x y z : α
h : x ∈ y :: z :: l
hx : x = y
⊢ prev (y :: z :: l) x h = getLast (z :: l) (_ : z :: l ≠ [])

Next tactic:
rw [prev, dif_pos hx]
theorem prev_cons_cons_of_ne' (y z : α) (h : x ∈ y :: z :: l) (hy : x ≠ y) (hz : x = z) :
    prev (y :: z :: l) x h = y := by
  

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l : List α
x y z : α
h : x ∈ y :: z :: l
hy : x ≠ y
hz : x = z
⊢ prev (y :: z :: l) x h = y

Next tactic:
cases l
theorem prev_cons_cons_of_ne' (y z : α) (h : x ∈ y :: z :: l) (hy : x ≠ y) (hz : x = z) :
    prev (y :: z :: l) x h = y := by
  cases l
  · 

Proof state:
case nil
α : Type u_1
inst✝ : DecidableEq α
x y z : α
hy : x ≠ y
hz : x = z
h : x ∈ [y, z]
⊢ prev [y, z] x h = y

Next tactic:
simp [prev, hy, hz]
theorem prev_cons_cons_of_ne' (y z : α) (h : x ∈ y :: z :: l) (hy : x ≠ y) (hz : x = z) :
    prev (y :: z :: l) x h = y := by
  cases l
  · simp [prev, hy, hz]
  · 

Proof state:
case cons
α : Type u_1
inst✝ : DecidableEq α
x y z : α
hy : x ≠ y
hz : x = z
head✝ : α
tail✝ : List α
h : x ∈ y :: z :: head✝ :: tail✝
⊢ prev (y :: z :: head✝ :: tail✝) x h = y

Next tactic:
rw [prev, dif_neg hy, if_pos hz]
theorem prev_ne_cons_cons (y z : α) (h : x ∈ y :: z :: l) (hy : x ≠ y) (hz : x ≠ z) :
    prev (y :: z :: l) x h = prev (z :: l) x (by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l : List α
x y z : α
h : x ∈ y :: z :: l
hy : x ≠ y
hz : x ≠ z
⊢ x ∈ z :: l

Next tactic:
simpa [hy] using h
theorem prev_ne_cons_cons (y z : α) (h : x ∈ y :: z :: l) (hy : x ≠ y) (hz : x ≠ z) :
    prev (y :: z :: l) x h = prev (z :: l) x (by simpa [hy] using h) := by
  

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l : List α
x y z : α
h : x ∈ y :: z :: l
hy : x ≠ y
hz : x ≠ z
⊢ prev (y :: z :: l) x h = prev (z :: l) x (_ : x ∈ z :: l)

Next tactic:
cases l
theorem prev_ne_cons_cons (y z : α) (h : x ∈ y :: z :: l) (hy : x ≠ y) (hz : x ≠ z) :
    prev (y :: z :: l) x h = prev (z :: l) x (by simpa [hy] using h) := by
  cases l
  · 

Proof state:
case nil
α : Type u_1
inst✝ : DecidableEq α
x y z : α
hy : x ≠ y
hz : x ≠ z
h : x ∈ [y, z]
⊢ prev [y, z] x h = prev [z] x (_ : x ∈ [z])

Next tactic:
simp [hy, hz] at h
theorem prev_ne_cons_cons (y z : α) (h : x ∈ y :: z :: l) (hy : x ≠ y) (hz : x ≠ z) :
    prev (y :: z :: l) x h = prev (z :: l) x (by simpa [hy] using h) := by
  cases l
  · simp [hy, hz] at h
  · 

Proof state:
case cons
α : Type u_1
inst✝ : DecidableEq α
x y z : α
hy : x ≠ y
hz : x ≠ z
head✝ : α
tail✝ : List α
h : x ∈ y :: z :: head✝ :: tail✝
⊢ prev (y :: z :: head✝ :: tail✝) x h = prev (z :: head✝ :: tail✝) x (_ : x ∈ z :: head✝ :: tail✝)

Next tactic:
rw [prev, dif_neg hy, if_neg hz]
theorem prev_mem (h : x ∈ l) : l.prev x h ∈ l := by
  

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l : List α
x : α
h : x ∈ l
⊢ prev l x h ∈ l

Next tactic:
cases' l with hd tl
theorem prev_mem (h : x ∈ l) : l.prev x h ∈ l := by
  cases' l with hd tl
  · 

Proof state:
case nil
α : Type u_1
inst✝ : DecidableEq α
x : α
h : x ∈ []
⊢ prev [] x h ∈ []

Next tactic:
simp at h
theorem prev_mem (h : x ∈ l) : l.prev x h ∈ l := by
  cases' l with hd tl
  · simp at h
  

Proof state:
case cons
α : Type u_1
inst✝ : DecidableEq α
x hd : α
tl : List α
h : x ∈ hd :: tl
⊢ prev (hd :: tl) x h ∈ hd :: tl

Next tactic:
induction' tl with hd' tl hl generalizing hd
theorem prev_mem (h : x ∈ l) : l.prev x h ∈ l := by
  cases' l with hd tl
  · simp at h
  induction' tl with hd' tl hl generalizing hd
  · 

Proof state:
case cons.nil
α : Type u_1
inst✝ : DecidableEq α
x hd : α
h : x ∈ [hd]
⊢ prev [hd] x h ∈ [hd]

Next tactic:
simp
theorem prev_mem (h : x ∈ l) : l.prev x h ∈ l := by
  cases' l with hd tl
  · simp at h
  induction' tl with hd' tl hl generalizing hd
  · simp
  · 

Proof state:
case cons.cons
α : Type u_1
inst✝ : DecidableEq α
x hd' : α
tl : List α
hl : ∀ (hd : α) (h : x ∈ hd :: tl), prev (hd :: tl) x h ∈ hd :: tl
hd : α
h : x ∈ hd :: hd' :: tl
⊢ prev (hd :: hd' :: tl) x h ∈ hd :: hd' :: tl

Next tactic:
by_cases hx : x = hd
theorem prev_mem (h : x ∈ l) : l.prev x h ∈ l := by
  cases' l with hd tl
  · simp at h
  induction' tl with hd' tl hl generalizing hd
  · simp
  · by_cases hx : x = hd
    · 

Proof state:
case pos
α : Type u_1
inst✝ : DecidableEq α
x hd' : α
tl : List α
hl : ∀ (hd : α) (h : x ∈ hd :: tl), prev (hd :: tl) x h ∈ hd :: tl
hd : α
h : x ∈ hd :: hd' :: tl
hx : x = hd
⊢ prev (hd :: hd' :: tl) x h ∈ hd :: hd' :: tl

Next tactic:
simp only [hx, prev_cons_cons_eq]
theorem prev_mem (h : x ∈ l) : l.prev x h ∈ l := by
  cases' l with hd tl
  · simp at h
  induction' tl with hd' tl hl generalizing hd
  · simp
  · by_cases hx : x = hd
    · simp only [hx, prev_cons_cons_eq]
      

Proof state:
case pos
α : Type u_1
inst✝ : DecidableEq α
x hd' : α
tl : List α
hl : ∀ (hd : α) (h : x ∈ hd :: tl), prev (hd :: tl) x h ∈ hd :: tl
hd : α
h : x ∈ hd :: hd' :: tl
hx : x = hd
⊢ getLast (hd' :: tl) (_ : hd' :: tl ≠ []) ∈ hd :: hd' :: tl

Next tactic:
exact mem_cons_of_mem _ (getLast_mem _)
theorem prev_mem (h : x ∈ l) : l.prev x h ∈ l := by
  cases' l with hd tl
  · simp at h
  induction' tl with hd' tl hl generalizing hd
  · simp
  · by_cases hx : x = hd
    · simp only [hx, prev_cons_cons_eq]
      exact mem_cons_of_mem _ (getLast_mem _)
    · 

Proof state:
case neg
α : Type u_1
inst✝ : DecidableEq α
x hd' : α
tl : List α
hl : ∀ (hd : α) (h : x ∈ hd :: tl), prev (hd :: tl) x h ∈ hd :: tl
hd : α
h : x ∈ hd :: hd' :: tl
hx : ¬x = hd
⊢ prev (hd :: hd' :: tl) x h ∈ hd :: hd' :: tl

Next tactic:
rw [prev, dif_neg hx]
theorem prev_mem (h : x ∈ l) : l.prev x h ∈ l := by
  cases' l with hd tl
  · simp at h
  induction' tl with hd' tl hl generalizing hd
  · simp
  · by_cases hx : x = hd
    · simp only [hx, prev_cons_cons_eq]
      exact mem_cons_of_mem _ (getLast_mem _)
    · rw [prev, dif_neg hx]
      

Proof state:
case neg
α : Type u_1
inst✝ : DecidableEq α
x hd' : α
tl : List α
hl : ∀ (hd : α) (h : x ∈ hd :: tl), prev (hd :: tl) x h ∈ hd :: tl
hd : α
h : x ∈ hd :: hd' :: tl
hx : ¬x = hd
⊢ (if x = hd' then hd else prev (hd' :: tl) x (_ : x ∈ hd' :: tl)) ∈ hd :: hd' :: tl

Next tactic:
split_ifs with hm
theorem prev_mem (h : x ∈ l) : l.prev x h ∈ l := by
  cases' l with hd tl
  · simp at h
  induction' tl with hd' tl hl generalizing hd
  · simp
  · by_cases hx : x = hd
    · simp only [hx, prev_cons_cons_eq]
      exact mem_cons_of_mem _ (getLast_mem _)
    · rw [prev, dif_neg hx]
      split_ifs with hm
      · 

Proof state:
case pos
α : Type u_1
inst✝ : DecidableEq α
x hd' : α
tl : List α
hl : ∀ (hd : α) (h : x ∈ hd :: tl), prev (hd :: tl) x h ∈ hd :: tl
hd : α
h : x ∈ hd :: hd' :: tl
hx : ¬x = hd
hm : x = hd'
⊢ hd ∈ hd :: hd' :: tl

Next tactic:
exact mem_cons_self _ _
theorem prev_mem (h : x ∈ l) : l.prev x h ∈ l := by
  cases' l with hd tl
  · simp at h
  induction' tl with hd' tl hl generalizing hd
  · simp
  · by_cases hx : x = hd
    · simp only [hx, prev_cons_cons_eq]
      exact mem_cons_of_mem _ (getLast_mem _)
    · rw [prev, dif_neg hx]
      split_ifs with hm
      · exact mem_cons_self _ _
      · 

Proof state:
case neg
α : Type u_1
inst✝ : DecidableEq α
x hd' : α
tl : List α
hl : ∀ (hd : α) (h : x ∈ hd :: tl), prev (hd :: tl) x h ∈ hd :: tl
hd : α
h : x ∈ hd :: hd' :: tl
hx : ¬x = hd
hm : ¬x = hd'
⊢ prev (hd' :: tl) x (_ : x ∈ hd' :: tl) ∈ hd :: hd' :: tl

Next tactic:
exact mem_cons_of_mem _ (hl _ _)
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 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l : List α
x : α
x✝ : Nodup []
i : Fin (length [])
⊢ next [] (get [] i) (_ : get [] { val := ↑i, isLt := (_ : ↑i < length []) } ∈ []) =
    get [] { val := (↑i + 1) % length [], isLt := (_ : (↑i + 1) % length [] < length []) }

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

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l : List α
x head✝ : α
x✝¹ : Nodup [head✝]
x✝ : Fin (length [head✝])
⊢ next [head✝] (get [head✝] x✝) (_ : get [head✝] { val := ↑x✝, isLt := (_ : ↑x✝ < length [head✝]) } ∈ [head✝]) =
    get [head✝] { val := (↑x✝ + 1) % length [head✝], isLt := (_ : (↑x✝ + 1) % length [head✝] < length [head✝]) }

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

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
_h : Nodup (x :: y :: l)
h0 : 0 < length (x :: y :: l)
⊢ next (x :: y :: l) (get (x :: y :: l) { val := 0, isLt := h0 })
      (_ :
        get (x :: y :: l)
            { val := ↑{ val := 0, isLt := h0 }, isLt := (_ : ↑{ val := 0, isLt := h0 } < length (x :: y :: l)) } ∈
          x :: y :: l) =
    get (x :: y :: l)
      { val := (↑{ val := 0, isLt := h0 } + 1) % length (x :: y :: l),
        isLt := (_ : (↑{ val := 0, isLt := h0 } + 1) % length (x :: y :: l) < length (x :: y :: l)) }

Next tactic:
have h₁ : get (x :: y :: l) { val := 0, isLt := h0 } = x := by simp
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 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
_h : Nodup (x :: y :: l)
h0 : 0 < length (x :: y :: l)
⊢ get (x :: y :: l) { val := 0, isLt := h0 } = x

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

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
_h : Nodup (x :: y :: l)
h0 : 0 < length (x :: y :: l)
h₁ : get (x :: y :: l) { val := 0, isLt := h0 } = x
⊢ next (x :: y :: l) (get (x :: y :: l) { val := 0, isLt := h0 })
      (_ :
        get (x :: y :: l)
            { val := ↑{ val := 0, isLt := h0 }, isLt := (_ : ↑{ val := 0, isLt := h0 } < length (x :: y :: l)) } ∈
          x :: y :: l) =
    get (x :: y :: l)
      { val := (↑{ val := 0, isLt := h0 } + 1) % length (x :: y :: l),
        isLt := (_ : (↑{ val := 0, isLt := h0 } + 1) % length (x :: y :: l) < length (x :: y :: l)) }

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

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
_h : Nodup (x :: y :: l)
h0 : 0 < length (x :: y :: l)
h₁ : get (x :: y :: l) { val := 0, isLt := h0 } = x
⊢ y =
    get (x :: y :: l)
      { val := (↑{ val := 0, isLt := h0 } + 1) % length (x :: y :: l),
        isLt := (_ : (↑{ val := 0, isLt := h0 } + 1) % length (x :: y :: l) < length (x :: y :: l)) }

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

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)
⊢ 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 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
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
      

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)
⊢ get (x :: y :: l) { val := i + 1, isLt := hi } ≠ x

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
      

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)
H : get (x :: y :: l) { val := i + 1, isLt := hi } = x
⊢ False

Next tactic:
suffices (i + 1 : ℕ) = 0 by simpa
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 

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)
H : get (x :: y :: l) { val := i + 1, isLt := hi } = x
this : i + 1 = 0
⊢ False

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

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)
H : get (x :: y :: l) { val := i + 1, isLt := hi } = x
⊢ i + 1 = 0

Next tactic:
rw [nodup_iff_injective_get] at hn
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
      

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
⊢ i + 1 = 0

Next tactic:
refine' Fin.veq_of_eq (@hn ⟨i + 1, hi⟩ ⟨0, by simp⟩ _)
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 

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
⊢ 0 < length (x :: y :: l)

Next tactic:
simp