l3lab/ntp-mathlib huggingface dataset:
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
  induction' l with y l hl generalizing n x
  · 

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

Next tactic:
simp
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
  induction' l with y l hl generalizing n x
  · simp
  · 

Proof state:
case cons.cons
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ y : α
l : List α
hl :
  ∀ (n : ℕ) (x : α),
    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))
n : ℕ
x : α
h : Nodup (x :: y :: l)
hn : n < length (x :: y :: l)
⊢ prev (x :: y :: l) (nthLe (x :: y :: l) n hn) (_ : nthLe (x :: y :: l) n hn ∈ x :: y :: l) =
    nthLe (x :: y :: l) ((n + (length (x :: y :: l) - 1)) % length (x :: y :: l))
      (_ : (n + (length (x :: y :: l) - 1)) % length (x :: y :: l) < length (x :: y :: l))

Next tactic:
rcases n with (_ | _ | n)
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
  induction' l with y l hl generalizing n x
  · simp
  · rcases n with (_ | _ | n)
    · 

Proof state:
case cons.cons.zero
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ y : α
l : List α
hl :
  ∀ (n : ℕ) (x : α),
    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))
x : α
h : Nodup (x :: y :: l)
hn : Nat.zero < length (x :: y :: l)
⊢ prev (x :: y :: l) (nthLe (x :: y :: l) Nat.zero hn) (_ : nthLe (x :: y :: l) Nat.zero hn ∈ x :: y :: l) =
    nthLe (x :: y :: l) ((Nat.zero + (length (x :: y :: l) - 1)) % length (x :: y :: l))
      (_ : (Nat.zero + (length (x :: y :: l) - 1)) % length (x :: y :: l) < length (x :: y :: l))

Next tactic:
simp [Nat.add_succ_sub_one, add_zero, List.prev_cons_cons_eq, Nat.zero_eq, List.length,
        List.nthLe, Nat.succ_add_sub_one, zero_add, getLast_eq_get,
        Nat.mod_eq_of_lt (Nat.succ_lt_succ l.length.lt_succ_self)]
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
  induction' l with y l hl generalizing n x
  · simp
  · rcases n with (_ | _ | n)
    · simp [Nat.add_succ_sub_one, add_zero, List.prev_cons_cons_eq, Nat.zero_eq, List.length,
        List.nthLe, Nat.succ_add_sub_one, zero_add, getLast_eq_get,
        Nat.mod_eq_of_lt (Nat.succ_lt_succ l.length.lt_succ_self)]
    · 

Proof state:
case cons.cons.succ.zero
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ y : α
l : List α
hl :
  ∀ (n : ℕ) (x : α),
    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))
x : α
h : Nodup (x :: y :: l)
hn : Nat.succ Nat.zero < length (x :: y :: l)
⊢ prev (x :: y :: l) (nthLe (x :: y :: l) (Nat.succ Nat.zero) hn)
      (_ : nthLe (x :: y :: l) (Nat.succ Nat.zero) hn ∈ x :: y :: l) =
    nthLe (x :: y :: l) ((Nat.succ Nat.zero + (length (x :: y :: l) - 1)) % length (x :: y :: l))
      (_ : (Nat.succ Nat.zero + (length (x :: y :: l) - 1)) % length (x :: y :: l) < length (x :: y :: l))

Next tactic:
simp only [mem_cons, nodup_cons] at h
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
  induction' l with y l hl generalizing n x
  · simp
  · rcases n with (_ | _ | n)
    · simp [Nat.add_succ_sub_one, add_zero, List.prev_cons_cons_eq, Nat.zero_eq, List.length,
        List.nthLe, Nat.succ_add_sub_one, zero_add, getLast_eq_get,
        Nat.mod_eq_of_lt (Nat.succ_lt_succ l.length.lt_succ_self)]
    · simp only [mem_cons, nodup_cons] at h
      

Proof state:
case cons.cons.succ.zero
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ y : α
l : List α
hl :
  ∀ (n : ℕ) (x : α),
    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))
x : α
hn : Nat.succ Nat.zero < length (x :: y :: l)
h : ¬(x = y ∨ x ∈ l) ∧ y ∉ l ∧ Nodup l
⊢ prev (x :: y :: l) (nthLe (x :: y :: l) (Nat.succ Nat.zero) hn)
      (_ : nthLe (x :: y :: l) (Nat.succ Nat.zero) hn ∈ x :: y :: l) =
    nthLe (x :: y :: l) ((Nat.succ Nat.zero + (length (x :: y :: l) - 1)) % length (x :: y :: l))
      (_ : (Nat.succ Nat.zero + (length (x :: y :: l) - 1)) % length (x :: y :: l) < length (x :: y :: l))

Next tactic:
push_neg at h
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
  induction' l with y l hl generalizing n x
  · simp
  · rcases n with (_ | _ | n)
    · simp [Nat.add_succ_sub_one, add_zero, List.prev_cons_cons_eq, Nat.zero_eq, List.length,
        List.nthLe, Nat.succ_add_sub_one, zero_add, getLast_eq_get,
        Nat.mod_eq_of_lt (Nat.succ_lt_succ l.length.lt_succ_self)]
    · simp only [mem_cons, nodup_cons] at h
      push_neg at h
      

Proof state:
case cons.cons.succ.zero
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ y : α
l : List α
hl :
  ∀ (n : ℕ) (x : α),
    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))
x : α
hn : Nat.succ Nat.zero < length (x :: y :: l)
h : (x ≠ y ∧ x ∉ l) ∧ y ∉ l ∧ Nodup l
⊢ prev (x :: y :: l) (nthLe (x :: y :: l) (Nat.succ Nat.zero) hn)
      (_ : nthLe (x :: y :: l) (Nat.succ Nat.zero) hn ∈ x :: y :: l) =
    nthLe (x :: y :: l) ((Nat.succ Nat.zero + (length (x :: y :: l) - 1)) % length (x :: y :: l))
      (_ : (Nat.succ Nat.zero + (length (x :: y :: l) - 1)) % length (x :: y :: l) < length (x :: y :: l))

Next tactic:
simp only [List.prev_cons_cons_of_ne _ _ _ _ h.left.left.symm, Nat.zero_eq, List.length,
        List.nthLe, add_comm, eq_self_iff_true, Nat.succ_add_sub_one, Nat.mod_self, zero_add,
        List.get]
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
  induction' l with y l hl generalizing n x
  · simp
  · rcases n with (_ | _ | n)
    · simp [Nat.add_succ_sub_one, add_zero, List.prev_cons_cons_eq, Nat.zero_eq, List.length,
        List.nthLe, Nat.succ_add_sub_one, zero_add, getLast_eq_get,
        Nat.mod_eq_of_lt (Nat.succ_lt_succ l.length.lt_succ_self)]
    · simp only [mem_cons, nodup_cons] at h
      push_neg at h
      simp only [List.prev_cons_cons_of_ne _ _ _ _ h.left.left.symm, Nat.zero_eq, List.length,
        List.nthLe, add_comm, eq_self_iff_true, Nat.succ_add_sub_one, Nat.mod_self, zero_add,
        List.get]
    · 

Proof state:
case cons.cons.succ.succ
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ y : α
l : List α
hl :
  ∀ (n : ℕ) (x : α),
    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))
x : α
h : Nodup (x :: y :: l)
n : ℕ
hn : Nat.succ (Nat.succ n) < length (x :: y :: l)
⊢ prev (x :: y :: l) (nthLe (x :: y :: l) (Nat.succ (Nat.succ n)) hn)
      (_ : nthLe (x :: y :: l) (Nat.succ (Nat.succ n)) hn ∈ x :: y :: l) =
    nthLe (x :: y :: l) ((Nat.succ (Nat.succ n) + (length (x :: y :: l) - 1)) % length (x :: y :: l))
      (_ : (Nat.succ (Nat.succ n) + (length (x :: y :: l) - 1)) % length (x :: y :: l) < length (x :: y :: l))

Next tactic:
rw [prev_ne_cons_cons]
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
  induction' l with y l hl generalizing n x
  · simp
  · rcases n with (_ | _ | n)
    · simp [Nat.add_succ_sub_one, add_zero, List.prev_cons_cons_eq, Nat.zero_eq, List.length,
        List.nthLe, Nat.succ_add_sub_one, zero_add, getLast_eq_get,
        Nat.mod_eq_of_lt (Nat.succ_lt_succ l.length.lt_succ_self)]
    · simp only [mem_cons, nodup_cons] at h
      push_neg at h
      simp only [List.prev_cons_cons_of_ne _ _ _ _ h.left.left.symm, Nat.zero_eq, List.length,
        List.nthLe, add_comm, eq_self_iff_true, Nat.succ_add_sub_one, Nat.mod_self, zero_add,
        List.get]
    · rw [prev_ne_cons_cons]
      · 

Proof state:
case cons.cons.succ.succ
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ y : α
l : List α
hl :
  ∀ (n : ℕ) (x : α),
    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))
x : α
h : Nodup (x :: y :: l)
n : ℕ
hn : Nat.succ (Nat.succ n) < length (x :: y :: l)
⊢ prev (y :: l) (nthLe (x :: y :: l) (Nat.succ (Nat.succ n)) hn)
      (_ : nthLe (x :: y :: l) (Nat.succ (Nat.succ n)) hn ∈ y :: l) =
    nthLe (x :: y :: l) ((Nat.succ (Nat.succ n) + (length (x :: y :: l) - 1)) % length (x :: y :: l))
      (_ : (Nat.succ (Nat.succ n) + (length (x :: y :: l) - 1)) % length (x :: y :: l) < length (x :: y :: l))

Next tactic:
convert hl n.succ y h.of_cons (Nat.le_of_succ_le_succ hn) using 1
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
  induction' l with y l hl generalizing n x
  · simp
  · rcases n with (_ | _ | n)
    · simp [Nat.add_succ_sub_one, add_zero, List.prev_cons_cons_eq, Nat.zero_eq, List.length,
        List.nthLe, Nat.succ_add_sub_one, zero_add, getLast_eq_get,
        Nat.mod_eq_of_lt (Nat.succ_lt_succ l.length.lt_succ_self)]
    · simp only [mem_cons, nodup_cons] at h
      push_neg at h
      simp only [List.prev_cons_cons_of_ne _ _ _ _ h.left.left.symm, Nat.zero_eq, List.length,
        List.nthLe, add_comm, eq_self_iff_true, Nat.succ_add_sub_one, Nat.mod_self, zero_add,
        List.get]
    · rw [prev_ne_cons_cons]
      · convert hl n.succ y h.of_cons (Nat.le_of_succ_le_succ hn) using 1
        

Proof state:
case h.e'_3
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ y : α
l : List α
hl :
  ∀ (n : ℕ) (x : α),
    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))
x : α
h : Nodup (x :: y :: l)
n : ℕ
hn : Nat.succ (Nat.succ n) < length (x :: y :: l)
⊢ nthLe (x :: y :: l) ((Nat.succ (Nat.succ n) + (length (x :: y :: l) - 1)) % length (x :: y :: l))
      (_ : (Nat.succ (Nat.succ n) + (length (x :: y :: l) - 1)) % length (x :: y :: l) < length (x :: y :: l)) =
    nthLe (y :: l) ((Nat.succ n + (length (y :: l) - 1)) % length (y :: l))
      (_ : (Nat.succ n + (length (y :: l) - 1)) % length (y :: l) < length (y :: l))

Next tactic:
have : ∀ k hk, (y :: l).nthLe k hk = (x :: y :: l).nthLe (k + 1) (Nat.succ_lt_succ hk) := by
          intros
          simp [List.nthLe]
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
  induction' l with y l hl generalizing n x
  · simp
  · rcases n with (_ | _ | n)
    · simp [Nat.add_succ_sub_one, add_zero, List.prev_cons_cons_eq, Nat.zero_eq, List.length,
        List.nthLe, Nat.succ_add_sub_one, zero_add, getLast_eq_get,
        Nat.mod_eq_of_lt (Nat.succ_lt_succ l.length.lt_succ_self)]
    · simp only [mem_cons, nodup_cons] at h
      push_neg at h
      simp only [List.prev_cons_cons_of_ne _ _ _ _ h.left.left.symm, Nat.zero_eq, List.length,
        List.nthLe, add_comm, eq_self_iff_true, Nat.succ_add_sub_one, Nat.mod_self, zero_add,
        List.get]
    · rw [prev_ne_cons_cons]
      · convert hl n.succ y h.of_cons (Nat.le_of_succ_le_succ hn) using 1
        have : ∀ k hk, (y :: l).nthLe k hk = (x :: y :: l).nthLe (k + 1) (Nat.succ_lt_succ hk) := by
          

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ y : α
l : List α
hl :
  ∀ (n : ℕ) (x : α),
    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))
x : α
h : Nodup (x :: y :: l)
n : ℕ
hn : Nat.succ (Nat.succ n) < length (x :: y :: l)
⊢ ∀ (k : ℕ) (hk : k < length (y :: l)),
    nthLe (y :: l) k hk = nthLe (x :: y :: l) (k + 1) (_ : Nat.succ k < Nat.succ (length (y :: l)))

Next tactic:
intros
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
  induction' l with y l hl generalizing n x
  · simp
  · rcases n with (_ | _ | n)
    · simp [Nat.add_succ_sub_one, add_zero, List.prev_cons_cons_eq, Nat.zero_eq, List.length,
        List.nthLe, Nat.succ_add_sub_one, zero_add, getLast_eq_get,
        Nat.mod_eq_of_lt (Nat.succ_lt_succ l.length.lt_succ_self)]
    · simp only [mem_cons, nodup_cons] at h
      push_neg at h
      simp only [List.prev_cons_cons_of_ne _ _ _ _ h.left.left.symm, Nat.zero_eq, List.length,
        List.nthLe, add_comm, eq_self_iff_true, Nat.succ_add_sub_one, Nat.mod_self, zero_add,
        List.get]
    · rw [prev_ne_cons_cons]
      · convert hl n.succ y h.of_cons (Nat.le_of_succ_le_succ hn) using 1
        have : ∀ k hk, (y :: l).nthLe k hk = (x :: y :: l).nthLe (k + 1) (Nat.succ_lt_succ hk) := by
          intros
          

Proof state:
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ y : α
l : List α
hl :
  ∀ (n : ℕ) (x : α),
    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))
x : α
h : Nodup (x :: y :: l)
n : ℕ
hn : Nat.succ (Nat.succ n) < length (x :: y :: l)
k✝ : ℕ
hk✝ : k✝ < length (y :: l)
⊢ nthLe (y :: l) k✝ hk✝ = nthLe (x :: y :: l) (k✝ + 1) (_ : Nat.succ k✝ < Nat.succ (length (y :: l)))

Next tactic:
simp [List.nthLe]
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
  induction' l with y l hl generalizing n x
  · simp
  · rcases n with (_ | _ | n)
    · simp [Nat.add_succ_sub_one, add_zero, List.prev_cons_cons_eq, Nat.zero_eq, List.length,
        List.nthLe, Nat.succ_add_sub_one, zero_add, getLast_eq_get,
        Nat.mod_eq_of_lt (Nat.succ_lt_succ l.length.lt_succ_self)]
    · simp only [mem_cons, nodup_cons] at h
      push_neg at h
      simp only [List.prev_cons_cons_of_ne _ _ _ _ h.left.left.symm, Nat.zero_eq, List.length,
        List.nthLe, add_comm, eq_self_iff_true, Nat.succ_add_sub_one, Nat.mod_self, zero_add,
        List.get]
    · rw [prev_ne_cons_cons]
      · convert hl n.succ y h.of_cons (Nat.le_of_succ_le_succ hn) using 1
        have : ∀ k hk, (y :: l).nthLe k hk = (x :: y :: l).nthLe (k + 1) (Nat.succ_lt_succ hk) := by
          intros
          simp [List.nthLe]
        

Proof state:
case h.e'_3
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ y : α
l : List α
hl :
  ∀ (n : ℕ) (x : α),
    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))
x : α
h : Nodup (x :: y :: l)
n : ℕ
hn : Nat.succ (Nat.succ n) < length (x :: y :: l)
this :
  ∀ (k : ℕ) (hk : k < length (y :: l)),
    nthLe (y :: l) k hk = nthLe (x :: y :: l) (k + 1) (_ : Nat.succ k < Nat.succ (length (y :: l)))
⊢ nthLe (x :: y :: l) ((Nat.succ (Nat.succ n) + (length (x :: y :: l) - 1)) % length (x :: y :: l))
      (_ : (Nat.succ (Nat.succ n) + (length (x :: y :: l) - 1)) % length (x :: y :: l) < length (x :: y :: l)) =
    nthLe (y :: l) ((Nat.succ n + (length (y :: l) - 1)) % length (y :: l))
      (_ : (Nat.succ n + (length (y :: l) - 1)) % length (y :: l) < length (y :: l))

Next tactic:
rw [this]
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
  induction' l with y l hl generalizing n x
  · simp
  · rcases n with (_ | _ | n)
    · simp [Nat.add_succ_sub_one, add_zero, List.prev_cons_cons_eq, Nat.zero_eq, List.length,
        List.nthLe, Nat.succ_add_sub_one, zero_add, getLast_eq_get,
        Nat.mod_eq_of_lt (Nat.succ_lt_succ l.length.lt_succ_self)]
    · simp only [mem_cons, nodup_cons] at h
      push_neg at h
      simp only [List.prev_cons_cons_of_ne _ _ _ _ h.left.left.symm, Nat.zero_eq, List.length,
        List.nthLe, add_comm, eq_self_iff_true, Nat.succ_add_sub_one, Nat.mod_self, zero_add,
        List.get]
    · rw [prev_ne_cons_cons]
      · convert hl n.succ y h.of_cons (Nat.le_of_succ_le_succ hn) using 1
        have : ∀ k hk, (y :: l).nthLe k hk = (x :: y :: l).nthLe (k + 1) (Nat.succ_lt_succ hk) := by
          intros
          simp [List.nthLe]
        rw [this]
        

Proof state:
case h.e'_3
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ y : α
l : List α
hl :
  ∀ (n : ℕ) (x : α),
    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))
x : α
h : Nodup (x :: y :: l)
n : ℕ
hn : Nat.succ (Nat.succ n) < length (x :: y :: l)
this :
  ∀ (k : ℕ) (hk : k < length (y :: l)),
    nthLe (y :: l) k hk = nthLe (x :: y :: l) (k + 1) (_ : Nat.succ k < Nat.succ (length (y :: l)))
⊢ nthLe (x :: y :: l) ((Nat.succ (Nat.succ n) + (length (x :: y :: l) - 1)) % length (x :: y :: l))
      (_ : (Nat.succ (Nat.succ n) + (length (x :: y :: l) - 1)) % length (x :: y :: l) < length (x :: y :: l)) =
    nthLe (x :: y :: l) ((Nat.succ n + (length (y :: l) - 1)) % length (y :: l) + 1)
      (_ : Nat.succ ((Nat.succ n + (length (y :: l) - 1)) % length (y :: l)) < Nat.succ (length (y :: l)))

Next tactic:
congr
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
  induction' l with y l hl generalizing n x
  · simp
  · rcases n with (_ | _ | n)
    · simp [Nat.add_succ_sub_one, add_zero, List.prev_cons_cons_eq, Nat.zero_eq, List.length,
        List.nthLe, Nat.succ_add_sub_one, zero_add, getLast_eq_get,
        Nat.mod_eq_of_lt (Nat.succ_lt_succ l.length.lt_succ_self)]
    · simp only [mem_cons, nodup_cons] at h
      push_neg at h
      simp only [List.prev_cons_cons_of_ne _ _ _ _ h.left.left.symm, Nat.zero_eq, List.length,
        List.nthLe, add_comm, eq_self_iff_true, Nat.succ_add_sub_one, Nat.mod_self, zero_add,
        List.get]
    · rw [prev_ne_cons_cons]
      · convert hl n.succ y h.of_cons (Nat.le_of_succ_le_succ hn) using 1
        have : ∀ k hk, (y :: l).nthLe k hk = (x :: y :: l).nthLe (k + 1) (Nat.succ_lt_succ hk) := by
          intros
          simp [List.nthLe]
        rw [this]
        congr
        

Proof state:
case h.e'_3.e_n
α : Type u_1
inst✝ : DecidableEq α
l✝ : List α
x✝ y : α
l : List α
hl :
  ∀ (n : ℕ) (x : α),
    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))
x : α
h : Nodup (x :: y :: l)
n : ℕ
hn : Nat.succ (Nat.succ n) < length (x :: y :: l)
this :
  ∀ (k : ℕ) (hk : k < length (y :: l)),
    nthLe (y :: l) k hk = nthLe (x :: y :: l) (k + 1) (_ : Nat.succ k < Nat.succ (length (y :: l)))
⊢ (Nat.succ (Nat.succ n) + (length (x :: y :: l) - 1)) % length (x :: y :: l) =
    (Nat.succ n + (length (y :: l) - 1)) % length (y :: l) + 1

Next tactic:
simp only [Nat.add_succ_sub_one, add_zero, length]