Skip to content

Commit

Permalink
feat: cleanup of List.getElem_append variants
Browse files Browse the repository at this point in the history
  • Loading branch information
kim-em committed Sep 11, 2024
1 parent 8f899bf commit f956beb
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/Init/Data/Array/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 6 additions & 4 deletions src/Init/Data/List/BasicAux.lean
Original file line number Diff line number Diff line change
Expand Up @@ -155,20 +155,22 @@ 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 =>
cases i with
| 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'
Expand Down
24 changes: 13 additions & 11 deletions src/Init/Data/List/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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]

Expand All @@ -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₁]
Expand Down Expand Up @@ -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'']

Expand Down
7 changes: 4 additions & 3 deletions src/Init/Data/List/Nat/TakeDrop.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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. -/
Expand Down Expand Up @@ -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. -/
Expand Down
2 changes: 1 addition & 1 deletion src/Init/Data/List/Sublist.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

Expand Down
4 changes: 2 additions & 2 deletions src/Std/Data/DHashMap/Internal/Model.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit f956beb

Please sign in to comment.