diff --git a/src/Init/Data/Array/Lemmas.lean b/src/Init/Data/Array/Lemmas.lean index b3effb086765..047dc4b7cbaa 100644 --- a/src/Init/Data/Array/Lemmas.lean +++ b/src/Init/Data/Array/Lemmas.lean @@ -825,7 +825,7 @@ theorem get_append_right {as bs : Array α} {h : i < (as ++ bs).size} (hle : as. (as ++ bs)[i] = bs[i - as.size] := by simp only [getElem_eq_toList_getElem] have h' : i < (as.toList ++ bs.toList).length := by rwa [← toList_length, append_toList] at h - conv => rhs; rw [← List.getElem_append_right (h' := h') (h := Nat.not_lt_of_ge hle)] + conv => rhs; rw [← List.getElem_append_right (h₁ := hle) (h₂ := h')] apply List.get_of_eq; rw [append_toList] @[simp] theorem append_nil (as : Array α) : as ++ #[] = as := by diff --git a/src/Init/Data/List/BasicAux.lean b/src/Init/Data/List/BasicAux.lean index 90892b72c6c0..e3fa716b9567 100644 --- a/src/Init/Data/List/BasicAux.lean +++ b/src/Init/Data/List/BasicAux.lean @@ -155,7 +155,7 @@ def mapMono (as : List α) (f : α → α) : List α := /-! ## Additional lemmas required for bootstrapping `Array`. -/ -theorem getElem_append_left (as bs : List α) (h : i < as.length) {h'} : (as ++ bs)[i] = as[i] := by +theorem getElem_append_left {as bs : List α} (h : i < as.length) {h'} : (as ++ bs)[i] = as[i] := by induction as generalizing i with | nil => trivial | cons a as ih => @@ -163,12 +163,14 @@ theorem getElem_append_left (as bs : List α) (h : i < as.length) {h'} : (as ++ | zero => rfl | succ i => apply ih -theorem getElem_append_right (as bs : List α) (h : ¬ i < as.length) {h' h''} : (as ++ bs)[i]'h' = bs[i - as.length]'h'' := by +theorem getElem_append_right {as bs : List α} {i : Nat} (h₁ : as.length ≤ i) {h₂} : + (as ++ bs)[i]'h₂ = + bs[i - as.length]'(by rw [length_append] at h₂; exact Nat.sub_lt_left_of_lt_add h₁ h₂) := by induction as generalizing i with | nil => trivial | cons a as ih => - cases i with simp [get, Nat.succ_sub_succ] <;> simp [Nat.succ_sub_succ] at h - | succ i => apply ih; simp [h] + cases i with simp [get, Nat.succ_sub_succ] <;> simp [Nat.succ_sub_succ] at h₁ + | succ i => apply ih; simp [h₁] theorem get_last {as : List α} {i : Fin (length (as ++ [a]))} (h : ¬ i.1 < as.length) : (as ++ [a] : List _).get i = a := by cases i; rename_i i h' diff --git a/src/Init/Data/List/Lemmas.lean b/src/Init/Data/List/Lemmas.lean index efe0ff0e4140..a9637816bda5 100644 --- a/src/Init/Data/List/Lemmas.lean +++ b/src/Init/Data/List/Lemmas.lean @@ -1496,10 +1496,11 @@ theorem filterMap_eq_cons_iff {l} {b} {bs} : /-! ### append -/ -theorem getElem_append : ∀ {l₁ l₂ : List α} (n : Nat) (h : n < l₁.length), - (l₁ ++ l₂)[n]'(length_append .. ▸ Nat.lt_add_right _ h) = l₁[n] -| a :: l, _, 0, h => rfl -| a :: l, _, n+1, h => by simp only [get, cons_append]; apply getElem_append +theorem getElem_append {l₁ l₂ : List α} (n : Nat) (h) : + (l₁ ++ l₂)[n] = if h' : n < l₁.length then l₁[n] else l₂[n - l₁.length]'(by simp at h h'; exact Nat.sub_lt_left_of_lt_add h' h) := by + split <;> rename_i h' + · rw [getElem_append_left h'] + · rw [getElem_append_right (by simpa using h')] theorem getElem?_append_left {l₁ l₂ : List α} {n : Nat} (hn : n < l₁.length) : (l₁ ++ l₂)[n]? = l₁[n]? := by @@ -1525,12 +1526,13 @@ theorem get?_append_right {l₁ l₂ : List α} {n : Nat} (h : l₁.length ≤ n (l₁ ++ l₂).get? n = l₂.get? (n - l₁.length) := by simp [getElem?_append_right, h] -theorem getElem_append_right' {l₁ l₂ : List α} {n : Nat} (h₁ : l₁.length ≤ n) (h₂) : - (l₁ ++ l₂)[n]'h₂ = - l₂[n - l₁.length]'(by rw [length_append] at h₂; exact Nat.sub_lt_left_of_lt_add h₁ h₂) := - Option.some.inj <| by rw [← getElem?_eq_getElem, ← getElem?_eq_getElem, getElem?_append_right h₁] +/-- Variant of `getElem_append_left` useful for rewriting from the small list to the big list. -/ +theorem getElem_append_left' (l₂ : List α) {l₁ : List α} {n : Nat} (hn : n < l₁.length) : + l₁[n] = (l₁ ++ l₂)[n]'(by simpa using Nat.lt_add_right l₂.length hn) := by + rw [getElem_append_left] <;> simp -theorem getElem_append_right'' (l₁ : List α) {l₂ : List α} {n : Nat} (hn : n < l₂.length) : +/-- Variant of `getElem_append_right` useful for rewriting from the small list to the big list. -/ +theorem getElem_append_right' (l₁ : List α) {l₂ : List α} {n : Nat} (hn : n < l₂.length) : l₂[n] = (l₁ ++ l₂)[n + l₁.length]'(by simpa [Nat.add_comm] using Nat.add_lt_add_left hn _) := by rw [getElem_append_right] <;> simp [*, le_add_left] @@ -1541,7 +1543,7 @@ theorem get_append_right_aux {l₁ l₂ : List α} {n : Nat} exact Nat.sub_lt_left_of_lt_add h₁ h₂ set_option linter.deprecated false in -@[deprecated getElem_append_right' (since := "2024-06-12")] +@[deprecated getElem_append_right (since := "2024-06-12")] theorem get_append_right' {l₁ l₂ : List α} {n : Nat} (h₁ : l₁.length ≤ n) (h₂) : (l₁ ++ l₂).get ⟨n, h₂⟩ = l₂.get ⟨n - l₁.length, get_append_right_aux h₁ h₂⟩ := Option.some.inj <| by rw [← get?_eq_get, ← get?_eq_get, get?_append_right h₁] @@ -1633,7 +1635,7 @@ theorem get_append_left (as bs : List α) (h : i < as.length) {h'} : simp [getElem_append_left, h, h'] @[deprecated getElem_append_right (since := "2024-06-12")] -theorem get_append_right (as bs : List α) (h : ¬ i < as.length) {h' h''} : +theorem get_append_right (as bs : List α) (h : as.length ≤ i) {h' h''} : (as ++ bs).get ⟨i, h'⟩ = bs.get ⟨i - as.length, h''⟩ := by simp [getElem_append_right, h, h', h''] diff --git a/src/Init/Data/List/Nat/TakeDrop.lean b/src/Init/Data/List/Nat/TakeDrop.lean index 428f839f759f..ee966d90d933 100644 --- a/src/Init/Data/List/Nat/TakeDrop.lean +++ b/src/Init/Data/List/Nat/TakeDrop.lean @@ -38,7 +38,7 @@ theorem length_take_of_le (h : n ≤ length l) : length (take n l) = n := by sim length `> i`. Version designed to rewrite from the big list to the small list. -/ theorem getElem_take (L : List α) {i j : Nat} (hi : i < L.length) (hj : i < j) : L[i] = (L.take j)[i]'(length_take .. ▸ Nat.lt_min.mpr ⟨hj, hi⟩) := - getElem_of_eq (take_append_drop j L).symm _ ▸ getElem_append .. + getElem_of_eq (take_append_drop j L).symm _ ▸ getElem_append_left .. /-- The `i`-th element of a list coincides with the `i`-th element of any of its prefixes of length `> i`. Version designed to rewrite from the small list to the big list. -/ @@ -227,8 +227,9 @@ dropping the first `i` elements. Version designed to rewrite from the big list t theorem getElem_drop' (L : List α) {i j : Nat} (h : i + j < L.length) : L[i + j] = (L.drop i)[j]'(lt_length_drop L h) := by have : i ≤ L.length := Nat.le_trans (Nat.le_add_right _ _) (Nat.le_of_lt h) - rw [getElem_of_eq (take_append_drop i L).symm h, getElem_append_right'] <;> - simp [Nat.min_eq_left this, Nat.add_sub_cancel_left, Nat.le_add_right] + rw [getElem_of_eq (take_append_drop i L).symm h, getElem_append_right] + · simp [Nat.min_eq_left this, Nat.add_sub_cancel_left] + · simp [Nat.min_eq_left this, Nat.le_add_right] /-- The `i + j`-th element of a list coincides with the `j`-th element of the list obtained by dropping the first `i` elements. Version designed to rewrite from the big list to the small list. -/ diff --git a/src/Init/Data/List/Sublist.lean b/src/Init/Data/List/Sublist.lean index 92366b668208..985923417551 100644 --- a/src/Init/Data/List/Sublist.lean +++ b/src/Init/Data/List/Sublist.lean @@ -667,7 +667,7 @@ theorem IsSuffix.length_le (h : l₁ <:+ l₂) : l₁.length ≤ l₂.length := theorem IsPrefix.getElem {x y : List α} (h : x <+: y) {n} (hn : n < x.length) : x[n] = y[n]'(Nat.le_trans hn h.length_le) := by obtain ⟨_, rfl⟩ := h - exact (List.getElem_append n hn).symm + exact (List.getElem_append_left hn).symm -- See `Init.Data.List.Nat.Sublist` for `IsSuffix.getElem`. diff --git a/src/Std/Data/DHashMap/Internal/Model.lean b/src/Std/Data/DHashMap/Internal/Model.lean index e6d25ef7a4cd..fafade7a841f 100644 --- a/src/Std/Data/DHashMap/Internal/Model.lean +++ b/src/Std/Data/DHashMap/Internal/Model.lean @@ -98,14 +98,14 @@ theorem exists_bucket_of_uset [BEq α] [Hashable α] refine ⟨?_, ?_⟩ · apply List.containsKey_bind_eq_false intro j hj - rw [← List.getElem_append (l₂ := self[i] :: l₂), getElem_congr_coll h₁.symm] + rw [List.getElem_append_left' (l₂ := self[i] :: l₂), getElem_congr_coll h₁.symm] apply (h.hashes_to j _).containsKey_eq_false h₀ k omega · apply List.containsKey_bind_eq_false intro j hj rw [← List.getElem_cons_succ self[i] _ _ (by simp only [Array.ugetElem_eq_getElem, List.length_cons]; omega)] - rw [List.getElem_append_right'' l₁, getElem_congr_coll h₁.symm] + rw [List.getElem_append_right' l₁, getElem_congr_coll h₁.symm] apply (h.hashes_to (j + 1 + l₁.length) _).containsKey_eq_false h₀ k omega