l3lab/ntp-mathlib huggingface dataset:
theorem take_eq_take :
    ∀ {l : List α} {m n : ℕ}, l.take m = l.take n ↔ min m l.length = min n l.length
  | [], m, n => by simp
  | _ :: xs, 0, 0 => by simp
  | x :: xs, m + 1, 0 => by simp
  | x :: xs, 0, n + 1 => by simp [@eq_comm ℕ 0]
  | x :: xs, m + 1, n + 1 => by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
xs : List α
m n : ℕ
⊢ take (m + 1) (x :: xs) = take (n + 1) (x :: xs) ↔ min (m + 1) (length (x :: xs)) = min (n + 1) (length (x :: xs))

Next tactic:
simp [Nat.succ_min_succ, take_eq_take]
theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
m n : ℕ
⊢ take (m + n) l = take m l ++ take n (drop m l)

Next tactic:
convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
  convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
  · 

Proof state:
case h.e'_2
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
m n : ℕ
⊢ take (m + n) l = take (m + n) (take m l ++ drop m l)

Next tactic:
rw [take_append_drop]
theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
  convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
  · rw [take_append_drop]
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
m n : ℕ
⊢ take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)

Next tactic:
rw [take_append_eq_append_take, take_all_of_le, append_right_inj]
theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
  convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
  · rw [take_append_drop]
  rw [take_append_eq_append_take, take_all_of_le, append_right_inj]
  · 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
m n : ℕ
⊢ take (m + n - length (take m l)) (drop m l) = take n (drop m l)

Next tactic:
simp only [take_eq_take, length_take, length_drop]
theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
  convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
  · rw [take_append_drop]
  rw [take_append_eq_append_take, take_all_of_le, append_right_inj]
  · simp only [take_eq_take, length_take, length_drop]
    

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
m n : ℕ
⊢ min (m + n - min m (length l)) (length l - m) = min n (length l - m)

Next tactic:
generalize l.length = k
theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
  convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
  · rw [take_append_drop]
  rw [take_append_eq_append_take, take_all_of_le, append_right_inj]
  · simp only [take_eq_take, length_take, length_drop]
    generalize l.length = k; 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
m n k : ℕ
⊢ min (m + n - min m k) (k - m) = min n (k - m)

Next tactic:
by_cases h : m ≤ k
theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
  convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
  · rw [take_append_drop]
  rw [take_append_eq_append_take, take_all_of_le, append_right_inj]
  · simp only [take_eq_take, length_take, length_drop]
    generalize l.length = k; by_cases h : m ≤ k
    · 

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
m n k : ℕ
h : m ≤ k
⊢ min (m + n - min m k) (k - m) = min n (k - m)

Next tactic:
simp [min_eq_left_iff.mpr h]
theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
  convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
  · rw [take_append_drop]
  rw [take_append_eq_append_take, take_all_of_le, append_right_inj]
  · simp only [take_eq_take, length_take, length_drop]
    generalize l.length = k; by_cases h : m ≤ k
    · simp [min_eq_left_iff.mpr h]
    · 

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
m n k : ℕ
h : ¬m ≤ k
⊢ min (m + n - min m k) (k - m) = min n (k - m)

Next tactic:
push_neg at h
theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
  convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
  · rw [take_append_drop]
  rw [take_append_eq_append_take, take_all_of_le, append_right_inj]
  · simp only [take_eq_take, length_take, length_drop]
    generalize l.length = k; by_cases h : m ≤ k
    · simp [min_eq_left_iff.mpr h]
    · push_neg at h
      

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
m n k : ℕ
h : k < m
⊢ min (m + n - min m k) (k - m) = min n (k - m)

Next tactic:
simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
  convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
  · rw [take_append_drop]
  rw [take_append_eq_append_take, take_all_of_le, append_right_inj]
  · simp only [take_eq_take, length_take, length_drop]
    generalize l.length = k; by_cases h : m ≤ k
    · simp [min_eq_left_iff.mpr h]
    · push_neg at h
      simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
  · 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
m n : ℕ
⊢ length (take m l) ≤ m + n

Next tactic:
trans m
theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
  convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
  · rw [take_append_drop]
  rw [take_append_eq_append_take, take_all_of_le, append_right_inj]
  · simp only [take_eq_take, length_take, length_drop]
    generalize l.length = k; by_cases h : m ≤ k
    · simp [min_eq_left_iff.mpr h]
    · push_neg at h
      simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
  · trans m
    · 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
m n : ℕ
⊢ length (take m l) ≤ m

Next tactic:
apply length_take_le
theorem take_add (l : List α) (m n : ℕ) : l.take (m + n) = l.take m ++ (l.drop m).take n := by
  convert_to take (m + n) (take m l ++ drop m l) = take m l ++ take n (drop m l)
  · rw [take_append_drop]
  rw [take_append_eq_append_take, take_all_of_le, append_right_inj]
  · simp only [take_eq_take, length_take, length_drop]
    generalize l.length = k; by_cases h : m ≤ k
    · simp [min_eq_left_iff.mpr h]
    · push_neg at h
      simp [Nat.sub_eq_zero_of_le (le_of_lt h)]
  · trans m
    · apply length_take_le
    · 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
m n : ℕ
⊢ m ≤ m + n

Next tactic:
simp
theorem dropLast_eq_take (l : List α) : l.dropLast = l.take l.length.pred := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
⊢ dropLast l = take (pred (length l)) l

Next tactic:
cases' l with x l
theorem dropLast_eq_take (l : List α) : l.dropLast = l.take l.length.pred := by
  cases' l with x l
  · 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
⊢ dropLast [] = take (pred (length [])) []

Next tactic:
simp [dropLast]
theorem dropLast_eq_take (l : List α) : l.dropLast = l.take l.length.pred := by
  cases' l with x l
  · simp [dropLast]
  · 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
l : List α
⊢ dropLast (x :: l) = take (pred (length (x :: l))) (x :: l)

Next tactic:
induction' l with hd tl hl generalizing x
theorem dropLast_eq_take (l : List α) : l.dropLast = l.take l.length.pred := by
  cases' l with x l
  · simp [dropLast]
  · induction' l with hd tl hl generalizing x
    · 

Proof state:
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
x : α
⊢ dropLast [x] = take (pred (length [x])) [x]

Next tactic:
simp [dropLast]
theorem dropLast_eq_take (l : List α) : l.dropLast = l.take l.length.pred := by
  cases' l with x l
  · simp [dropLast]
  · induction' l with hd tl hl generalizing x
    · simp [dropLast]
    · 

Proof state:
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hd : α
tl : List α
hl : ∀ (x : α), dropLast (x :: tl) = take (pred (length (x :: tl))) (x :: tl)
x : α
⊢ dropLast (x :: hd :: tl) = take (pred (length (x :: hd :: tl))) (x :: hd :: tl)

Next tactic:
simp [dropLast, hl]
theorem dropLast_take {n : ℕ} {l : List α} (h : n < l.length) :
    (l.take n).dropLast = l.take n.pred := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
n : ℕ
l : List α
h : n < length l
⊢ dropLast (take n l) = take (pred n) l

Next tactic:
simp [dropLast_eq_take, min_eq_left_of_lt h, take_take, pred_le]
theorem dropLast_cons_of_ne_nil {α : Type*} {x : α}
    {l : List α} (h : l ≠ []) : (x :: l).dropLast = x :: l.dropLast := by 

Proof state:
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
x : α
l : List α
h : l ≠ []
⊢ dropLast (x :: l) = x :: dropLast l

Next tactic:
simp [h, dropLast]
@[simp]
theorem dropLast_append_of_ne_nil {α : Type*} {l : List α} :
    ∀ (l' : List α) (_ : l ≠ []), (l' ++ l).dropLast = l' ++ l.dropLast
  | [], _ => by 

Proof state:
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
l : List α
x✝ : l ≠ []
⊢ dropLast ([] ++ l) = [] ++ dropLast l

Next tactic:
simp only [nil_append]
@[simp]
theorem dropLast_append_of_ne_nil {α : Type*} {l : List α} :
    ∀ (l' : List α) (_ : l ≠ []), (l' ++ l).dropLast = l' ++ l.dropLast
  | [], _ => by simp only [nil_append]
  | a :: l', h => by
    

Proof state:
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
l : List α
a : α
l' : List α
h : l ≠ []
⊢ dropLast (a :: l' ++ l) = a :: l' ++ dropLast l

Next tactic:
rw [cons_append, dropLast, dropLast_append_of_ne_nil l' h, cons_append]
@[simp]
theorem dropLast_append_of_ne_nil {α : Type*} {l : List α} :
    ∀ (l' : List α) (_ : l ≠ []), (l' ++ l).dropLast = l' ++ l.dropLast
  | [], _ => by simp only [nil_append]
  | a :: l', h => by
    rw [cons_append, dropLast, dropLast_append_of_ne_nil l' h, cons_append]
    

Proof state:
case x_2
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
l : List α
a : α
l' : List α
h : l ≠ []
⊢ l' ++ l = [] → False

Next tactic:
simp [h]
theorem drop_eq_nil_iff_le {l : List α} {k : ℕ} : l.drop k = [] ↔ l.length ≤ k := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
k : ℕ
⊢ drop k l = [] ↔ length l ≤ k

Next tactic:
refine' ⟨fun h => _, drop_eq_nil_of_le⟩
theorem drop_eq_nil_iff_le {l : List α} {k : ℕ} : l.drop k = [] ↔ l.length ≤ k := by
  refine' ⟨fun h => _, drop_eq_nil_of_le⟩
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
k : ℕ
h : drop k l = []
⊢ length l ≤ k

Next tactic:
induction' k with k hk generalizing l
theorem drop_eq_nil_iff_le {l : List α} {k : ℕ} : l.drop k = [] ↔ l.length ≤ k := by
  refine' ⟨fun h => _, drop_eq_nil_of_le⟩
  induction' k with k hk generalizing l
  · 

Proof state:
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
h : drop zero l = []
⊢ length l ≤ zero

Next tactic:
simp only [drop] at h
theorem drop_eq_nil_iff_le {l : List α} {k : ℕ} : l.drop k = [] ↔ l.length ≤ k := by
  refine' ⟨fun h => _, drop_eq_nil_of_le⟩
  induction' k with k hk generalizing l
  · simp only [drop] at h
    

Proof state:
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
h : l = []
⊢ length l ≤ zero

Next tactic:
simp [h]
theorem drop_eq_nil_iff_le {l : List α} {k : ℕ} : l.drop k = [] ↔ l.length ≤ k := by
  refine' ⟨fun h => _, drop_eq_nil_of_le⟩
  induction' k with k hk generalizing l
  · simp only [drop] at h
    simp [h]
  · 

Proof state:
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
k : ℕ
hk : ∀ {l : List α}, drop k l = [] → length l ≤ k
l : List α
h : drop (succ k) l = []
⊢ length l ≤ succ k

Next tactic:
cases l
theorem drop_eq_nil_iff_le {l : List α} {k : ℕ} : l.drop k = [] ↔ l.length ≤ k := by
  refine' ⟨fun h => _, drop_eq_nil_of_le⟩
  induction' k with k hk generalizing l
  · simp only [drop] at h
    simp [h]
  · cases l
    · 

Proof state:
case succ.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
k : ℕ
hk : ∀ {l : List α}, drop k l = [] → length l ≤ k
h : drop (succ k) [] = []
⊢ length [] ≤ succ k

Next tactic:
simp
theorem drop_eq_nil_iff_le {l : List α} {k : ℕ} : l.drop k = [] ↔ l.length ≤ k := by
  refine' ⟨fun h => _, drop_eq_nil_of_le⟩
  induction' k with k hk generalizing l
  · simp only [drop] at h
    simp [h]
  · cases l
    · simp
    · 

Proof state:
case succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
k : ℕ
hk : ∀ {l : List α}, drop k l = [] → length l ≤ k
head✝ : α
tail✝ : List α
h : drop (succ k) (head✝ :: tail✝) = []
⊢ length (head✝ :: tail✝) ≤ succ k

Next tactic:
simp only [drop] at h
theorem drop_eq_nil_iff_le {l : List α} {k : ℕ} : l.drop k = [] ↔ l.length ≤ k := by
  refine' ⟨fun h => _, drop_eq_nil_of_le⟩
  induction' k with k hk generalizing l
  · simp only [drop] at h
    simp [h]
  · cases l
    · simp
    · simp only [drop] at h
      

Proof state:
case succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
k : ℕ
hk : ∀ {l : List α}, drop k l = [] → length l ≤ k
head✝ : α
tail✝ : List α
h : drop k tail✝ = []
⊢ length (head✝ :: tail✝) ≤ succ k

Next tactic:
simpa [Nat.succ_le_succ_iff] using hk h
@[simp]
theorem tail_drop (l : List α) (n : ℕ) : (l.drop n).tail = l.drop (n + 1) := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
n : ℕ
⊢ tail (drop n l) = drop (n + 1) l

Next tactic:
induction' l with hd tl hl generalizing n
@[simp]
theorem tail_drop (l : List α) (n : ℕ) : (l.drop n).tail = l.drop (n + 1) := by
  induction' l with hd tl hl generalizing n
  · 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
n : ℕ
⊢ tail (drop n []) = drop (n + 1) []

Next tactic:
simp
@[simp]
theorem tail_drop (l : List α) (n : ℕ) : (l.drop n).tail = l.drop (n + 1) := by
  induction' l with hd tl hl generalizing n
  · simp
  · 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hd : α
tl : List α
hl : ∀ (n : ℕ), tail (drop n tl) = drop (n + 1) tl
n : ℕ
⊢ tail (drop n (hd :: tl)) = drop (n + 1) (hd :: tl)

Next tactic:
cases n
@[simp]
theorem tail_drop (l : List α) (n : ℕ) : (l.drop n).tail = l.drop (n + 1) := by
  induction' l with hd tl hl generalizing n
  · simp
  · cases n
    · 

Proof state:
case cons.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hd : α
tl : List α
hl : ∀ (n : ℕ), tail (drop n tl) = drop (n + 1) tl
⊢ tail (drop zero (hd :: tl)) = drop (zero + 1) (hd :: tl)

Next tactic:
simp
@[simp]
theorem tail_drop (l : List α) (n : ℕ) : (l.drop n).tail = l.drop (n + 1) := by
  induction' l with hd tl hl generalizing n
  · simp
  · cases n
    · simp
    · 

Proof state:
case cons.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hd : α
tl : List α
hl : ∀ (n : ℕ), tail (drop n tl) = drop (n + 1) tl
n✝ : ℕ
⊢ tail (drop (succ n✝) (hd :: tl)) = drop (succ n✝ + 1) (hd :: tl)

Next tactic:
simp [hl]
@[simp]
theorem drop_tail (l : List α) (n : ℕ) : l.tail.drop n = l.drop (n + 1) := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
n : ℕ
⊢ drop n (tail l) = drop (n + 1) l

Next tactic:
induction' l
@[simp]
theorem drop_tail (l : List α) (n : ℕ) : l.tail.drop n = l.drop (n + 1) := by
  induction' l <;> 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
n : ℕ
⊢ drop n (tail []) = drop (n + 1) []

Next tactic:
simp
@[simp]
theorem drop_tail (l : List α) (n : ℕ) : l.tail.drop n = l.drop (n + 1) := by
  induction' l <;> 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
n : ℕ
head✝ : α
tail✝ : List α
tail_ih✝ : drop n (tail tail✝) = drop (n + 1) tail✝
⊢ drop n (tail (head✝ :: tail✝)) = drop (n + 1) (head✝ :: tail✝)

Next tactic:
simp
theorem cons_get_drop_succ {l : List α} {n} :
    l.get n :: l.drop (n.1 + 1) = l.drop n.1 := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
n : Fin (length l)
⊢ get l n :: drop (↑n + 1) l = drop (↑n) l

Next tactic:
induction' l with hd tl hl
theorem cons_get_drop_succ {l : List α} {n} :
    l.get n :: l.drop (n.1 + 1) = l.drop n.1 := by
  induction' l with hd tl hl
  · 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
n : Fin (length [])
⊢ get [] n :: drop (↑n + 1) [] = drop ↑n []

Next tactic:
exact absurd n.1.zero_le (not_le_of_lt (nomatch n))
theorem cons_get_drop_succ {l : List α} {n} :
    l.get n :: l.drop (n.1 + 1) = l.drop n.1 := by
  induction' l with hd tl hl
  · exact absurd n.1.zero_le (not_le_of_lt (nomatch n))
  · 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hd : α
tl : List α
hl : ∀ {n : Fin (length tl)}, get tl n :: drop (↑n + 1) tl = drop (↑n) tl
n : Fin (length (hd :: tl))
⊢ get (hd :: tl) n :: drop (↑n + 1) (hd :: tl) = drop (↑n) (hd :: tl)

Next tactic:
match n with
    | ⟨0, _⟩ => simp [get]
    | ⟨n+1, hn⟩ =>
      simp only [Nat.succ_lt_succ_iff, List.length] at hn
      simpa [List.get, List.drop] using hl
theorem cons_get_drop_succ {l : List α} {n} :
    l.get n :: l.drop (n.1 + 1) = l.drop n.1 := by
  induction' l with hd tl hl
  · exact absurd n.1.zero_le (not_le_of_lt (nomatch n))
  · match n with
    | ⟨0, _⟩ => 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hd : α
tl : List α
hl : ∀ {n : Fin (length tl)}, get tl n :: drop (↑n + 1) tl = drop (↑n) tl
n : Fin (length (hd :: tl))
isLt✝ : 0 < length (hd :: tl)
⊢ get (hd :: tl) { val := 0, isLt := isLt✝ } :: drop (↑{ val := 0, isLt := isLt✝ } + 1) (hd :: tl) =
    drop (↑{ val := 0, isLt := isLt✝ }) (hd :: tl)

Next tactic:
simp [get]
theorem cons_get_drop_succ {l : List α} {n} :
    l.get n :: l.drop (n.1 + 1) = l.drop n.1 := by
  induction' l with hd tl hl
  · exact absurd n.1.zero_le (not_le_of_lt (nomatch n))
  · match n with
    | ⟨0, _⟩ => simp [get]
    | ⟨n+1, hn⟩ =>
      

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hd : α
tl : List α
hl : ∀ {n : Fin (length tl)}, get tl n :: drop (↑n + 1) tl = drop (↑n) tl
n✝ : Fin (length (hd :: tl))
n : ℕ
hn : n + 1 < length (hd :: tl)
⊢ get (hd :: tl) { val := n + 1, isLt := hn } :: drop (↑{ val := n + 1, isLt := hn } + 1) (hd :: tl) =
    drop (↑{ val := n + 1, isLt := hn }) (hd :: tl)

Next tactic:
simp only [Nat.succ_lt_succ_iff, List.length] at hn
theorem cons_get_drop_succ {l : List α} {n} :
    l.get n :: l.drop (n.1 + 1) = l.drop n.1 := by
  induction' l with hd tl hl
  · exact absurd n.1.zero_le (not_le_of_lt (nomatch n))
  · match n with
    | ⟨0, _⟩ => simp [get]
    | ⟨n+1, hn⟩ =>
      simp only [Nat.succ_lt_succ_iff, List.length] at hn
      

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hd : α
tl : List α
hl : ∀ {n : Fin (length tl)}, get tl n :: drop (↑n + 1) tl = drop (↑n) tl
n✝ : Fin (length (hd :: tl))
n : ℕ
hn✝ : n + 1 < length (hd :: tl)
hn : n < length tl
⊢ get (hd :: tl) { val := n + 1, isLt := hn✝ } :: drop (↑{ val := n + 1, isLt := hn✝ } + 1) (hd :: tl) =
    drop (↑{ val := n + 1, isLt := hn✝ }) (hd :: tl)

Next tactic:
simpa [List.get, List.drop] using hl
theorem drop_length_cons {l : List α} (h : l ≠ []) (a : α) :
    (a :: l).drop l.length = [l.getLast h] := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
h : l ≠ []
a : α
⊢ drop (length l) (a :: l) = [getLast l h]

Next tactic:
induction' l with y l ih generalizing a
theorem drop_length_cons {l : List α} (h : l ≠ []) (a : α) :
    (a :: l).drop l.length = [l.getLast h] := by
  induction' l with y l ih generalizing a
  · 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : [] ≠ []
a : α
⊢ drop (length []) [a] = [getLast [] h]

Next tactic:
cases h rfl
theorem drop_length_cons {l : List α} (h : l ≠ []) (a : α) :
    (a :: l).drop l.length = [l.getLast h] := by
  induction' l with y l ih generalizing a
  · cases h rfl
  · 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
y : α
l : List α
ih : ∀ (h : l ≠ []) (a : α), drop (length l) (a :: l) = [getLast l h]
h : y :: l ≠ []
a : α
⊢ drop (length (y :: l)) (a :: y :: l) = [getLast (y :: l) h]

Next tactic:
simp only [drop, length]
theorem drop_length_cons {l : List α} (h : l ≠ []) (a : α) :
    (a :: l).drop l.length = [l.getLast h] := by
  induction' l with y l ih generalizing a
  · cases h rfl
  · simp only [drop, length]
    

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
y : α
l : List α
ih : ∀ (h : l ≠ []) (a : α), drop (length l) (a :: l) = [getLast l h]
h : y :: l ≠ []
a : α
⊢ drop (Nat.add (length l) 0) (y :: l) = [getLast (y :: l) h]

Next tactic:
by_cases h₁ : l = []
theorem drop_length_cons {l : List α} (h : l ≠ []) (a : α) :
    (a :: l).drop l.length = [l.getLast h] := by
  induction' l with y l ih generalizing a
  · cases h rfl
  · simp only [drop, length]
    by_cases h₁ : l = []
    · 

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
y : α
l : List α
ih : ∀ (h : l ≠ []) (a : α), drop (length l) (a :: l) = [getLast l h]
h : y :: l ≠ []
a : α
h₁ : l = []
⊢ drop (Nat.add (length l) 0) (y :: l) = [getLast (y :: l) h]

Next tactic:
simp [h₁]
theorem drop_length_cons {l : List α} (h : l ≠ []) (a : α) :
    (a :: l).drop l.length = [l.getLast h] := by
  induction' l with y l ih generalizing a
  · cases h rfl
  · simp only [drop, length]
    by_cases h₁ : l = []
    · simp [h₁]
    

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
y : α
l : List α
ih : ∀ (h : l ≠ []) (a : α), drop (length l) (a :: l) = [getLast l h]
h : y :: l ≠ []
a : α
h₁ : ¬l = []
⊢ drop (Nat.add (length l) 0) (y :: l) = [getLast (y :: l) h]

Next tactic:
rw [getLast_cons h₁]
theorem drop_length_cons {l : List α} (h : l ≠ []) (a : α) :
    (a :: l).drop l.length = [l.getLast h] := by
  induction' l with y l ih generalizing a
  · cases h rfl
  · simp only [drop, length]
    by_cases h₁ : l = []
    · simp [h₁]
    rw [getLast_cons h₁]
    

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
y : α
l : List α
ih : ∀ (h : l ≠ []) (a : α), drop (length l) (a :: l) = [getLast l h]
h : y :: l ≠ []
a : α
h₁ : ¬l = []
⊢ drop (Nat.add (length l) 0) (y :: l) = [getLast l h₁]

Next tactic:
exact ih h₁ y
/-- Dropping the elements up to `l₁.length + i` in `l₁ + l₂` is the same as dropping the elements
up to `i` in `l₂`. -/
theorem drop_append {l₁ l₂ : List α} (i : ℕ) : drop (l₁.length + i) (l₁ ++ l₂) = drop i l₂ := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁✝ l₂✝ l₁ l₂ : List α
i : ℕ
⊢ drop (length l₁ + i) (l₁ ++ l₂) = drop i l₂

Next tactic:
rw [drop_append_eq_append_drop, drop_eq_nil_of_le]
/-- Dropping the elements up to `l₁.length + i` in `l₁ + l₂` is the same as dropping the elements
up to `i` in `l₂`. -/
theorem drop_append {l₁ l₂ : List α} (i : ℕ) : drop (l₁.length + i) (l₁ ++ l₂) = drop i l₂ := by
  rw [drop_append_eq_append_drop, drop_eq_nil_of_le] <;> 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁✝ l₂✝ l₁ l₂ : List α
i : ℕ
⊢ [] ++ drop (length l₁ + i - length l₁) l₂ = drop i l₂

Next tactic:
simp
/-- Dropping the elements up to `l₁.length + i` in `l₁ + l₂` is the same as dropping the elements
up to `i` in `l₂`. -/
theorem drop_append {l₁ l₂ : List α} (i : ℕ) : drop (l₁.length + i) (l₁ ++ l₂) = drop i l₂ := by
  rw [drop_append_eq_append_drop, drop_eq_nil_of_le] <;> 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁✝ l₂✝ l₁ l₂ : List α
i : ℕ
⊢ length l₁ ≤ length l₁ + i

Next tactic:
simp
theorem drop_sizeOf_le [SizeOf α] (l : List α) : ∀ n : ℕ, sizeOf (l.drop n) ≤ sizeOf l := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : SizeOf α
l : List α
⊢ ∀ (n : ℕ), sizeOf (drop n l) ≤ sizeOf l

Next tactic:
induction' l with _ _ lih