feat: prove xs.extract start stop = (xs.take stop).drop start for lists (#12359)

This PR deprecates `extract_eq_drop_take` in favor of the more correct
name `extract_eq_take_drop`, so that we'll be able to use the old name
for a lemma `xs.extract start stop = (xs.take stop).drop start`. Until
the deprecation deadline has passed, this new lemma will be called
`extract_eq_drop_take'`.
This commit is contained in:
Paul Reichert 2026-02-16 23:43:44 +01:00 committed by GitHub
parent bf8ca518e7
commit af7b3866b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 29 additions and 9 deletions

View file

@ -329,7 +329,7 @@ theorem eraseIdx_eq_take_drop_succ {xs : Array α} {i : Nat} (h) :
rcases xs with ⟨xs⟩
simp only [List.size_toArray] at h
simp only [List.eraseIdx_toArray, List.eraseIdx_eq_take_drop_succ, take_eq_extract,
List.extract_toArray, List.extract_eq_drop_take, Nat.sub_zero, List.drop_zero, drop_eq_extract,
List.extract_toArray, List.extract_eq_take_drop, Nat.sub_zero, List.drop_zero, drop_eq_extract,
List.size_toArray, List.append_toArray, mk.injEq, List.append_cancel_left_eq]
rw [List.take_of_length_le]
simp

View file

@ -4148,7 +4148,7 @@ variable [LawfulBEq α]
(xs.replace a b)[i]? = if xs[i]? == some a then if a ∈ xs.take i then some a else some b else xs[i]? := by
rcases xs with ⟨xs⟩
simp only [List.replace_toArray, List.getElem?_toArray, List.getElem?_replace, take_eq_extract,
List.extract_toArray, List.extract_eq_drop_take, Nat.sub_zero, List.drop_zero, List.mem_toArray]
List.extract_toArray, List.extract_eq_take_drop, Nat.sub_zero, List.drop_zero, List.mem_toArray]
theorem getElem?_replace_of_ne {xs : Array α} {i : Nat} (h : xs[i]? ≠ some a) :
(xs.replace a b)[i]? = xs[i]? := by

View file

@ -89,7 +89,7 @@ public theorem _root_.List.min_toArray [Min α] {l : List α} {h} :
· rename_i x xs
simp only [List.getElem_toArray, List.getElem_cons_zero, List.size_toArray, List.length_cons]
rw [List.toArray_cons, foldl_eq_foldl_extract]
rw [← Array.foldl_toList, Array.toList_extract, List.extract_eq_drop_take]
rw [← Array.foldl_toList, Array.toList_extract, List.extract_eq_take_drop]
simp [List.min]
public theorem _root_.List.min_eq_min_toArray [Min α] {l : List α} {h} :
@ -129,7 +129,7 @@ public theorem _root_.List.max_toArray [Max α] {l : List α} {h} :
· rename_i x xs
simp only [List.getElem_toArray, List.getElem_cons_zero, List.size_toArray, List.length_cons]
rw [List.toArray_cons, foldl_eq_foldl_extract]
rw [← Array.foldl_toList, Array.toList_extract, List.extract_eq_drop_take]
rw [← Array.foldl_toList, Array.toList_extract, List.extract_eq_take_drop]
simp [List.max]
public theorem _root_.List.max_eq_max_toArray [Max α] {l : List α} {h} :

View file

@ -135,7 +135,7 @@ theorem extract {xs ys : Array α} (h : xs ~ ys) {lo hi : Nat}
rcases xs with ⟨xs⟩
rcases ys with ⟨ys⟩
simp_all only [perm_iff_toList_perm, List.getElem?_toArray, List.extract_toArray,
List.extract_eq_drop_take]
List.extract_eq_take_drop]
apply List.Perm.take_of_getElem? (w := fun i h => by simpa using whi (lo + i) (by omega))
apply List.Perm.drop_of_getElem? (w := wlo)
exact h

View file

@ -955,9 +955,13 @@ Examples:
abbrev extract (l : List α) (start : Nat := 0) (stop : Nat := l.length) : List α :=
(l.drop start).take (stop - start)
@[simp] theorem extract_eq_drop_take {l : List α} {start stop : Nat} :
@[simp] theorem extract_eq_take_drop {l : List α} {start stop : Nat} :
l.extract start stop = (l.drop start).take (stop - start) := rfl
set_option linter.missingDocs false in
@[deprecated extract_eq_take_drop (since := "2026-02-06")]
def extract_eq_drop_take := @extract_eq_take_drop
/-! ### takeWhile -/
/--

View file

@ -387,6 +387,22 @@ theorem drop_take : ∀ {i j : Nat} {l : List α}, drop i (take j l) = take (j -
rw [drop_take]
simp
set_option doc.verso true in
/--
This lemma will be renamed to {lit}`List.extract_eq_drop_take` as soon as the current deprecated
lemma {name}`List.extract_eq_drop_take` has been removed.
-/
theorem extract_eq_drop_take' {l : List α} {start stop : Nat} :
l.extract start stop = (l.take stop).drop start := by
simp only [take_drop]
by_cases start ≤ stop
· rw [add_sub_of_le _]
· have h₁ : stop - start = 0 := by omega
have h₂ : min stop l.length ≤ stop := by omega
simp only [Nat.add_zero, List.drop_take_self, List.nil_eq, List.drop_eq_nil_iff,
List.length_take, ge_iff_le, h₁]
omega
@[simp]
theorem drop_eq_drop_iff :
∀ {l : List α} {i j : Nat}, l.drop i = l.drop j ↔ min i l.length = min j l.length

View file

@ -268,7 +268,7 @@ theorem drop_eq_extract {l : List α} {k : Nat} :
| 0 => simp
| _ + 1 =>
simp only [List.drop_succ_cons, List.length_cons, ih]
simp only [List.extract_eq_drop_take, List.drop_succ_cons, Nat.succ_sub_succ]
simp only [List.extract_eq_take_drop, List.drop_succ_cons, Nat.succ_sub_succ]
/-! ### takeWhile and dropWhile -/

View file

@ -348,7 +348,7 @@ public theorem toList_mkSlice_rco {xs : Array α} {lo hi : Nat} :
public theorem toArray_mkSlice_rco {xs : Array α} {lo hi : Nat} :
xs[lo...hi].toArray = xs.extract lo hi := by
simp only [← Subarray.toArray_toList, toList_mkSlice_rco]
rw [show xs = xs.toList.toArray by simp, List.extract_toArray, List.extract_eq_drop_take]
rw [show xs = xs.toList.toArray by simp, List.extract_toArray, List.extract_eq_take_drop]
simp only [List.take_drop, mk.injEq]
by_cases h : lo ≤ hi
· congr 1

View file

@ -72,7 +72,7 @@ theorem _root_.Array.Perm.extract' {xs ys : Array α} (h : xs ~ ys) {lo hi : Nat
rcases xs with ⟨xs⟩
rcases ys with ⟨ys⟩
simp_all only [perm_iff_toList_perm, List.getElem?_toArray, List.extract_toArray,
List.extract_eq_drop_take]
List.extract_eq_take_drop]
apply List.Perm.take_of_getElem (w := fun i h₁ h₂ => by simpa using whi (lo + i) (by omega) sorry)
apply List.Perm.drop_of_getElem (w := wlo)
simpa using List.perm_iff_toArray_perm.mpr h