Skip to content

Commit bcec192

Browse files
committed
feat: generic GetElem lemmas
1 parent d5060e9 commit bcec192

File tree

6 files changed

+84
-30
lines changed

6 files changed

+84
-30
lines changed

src/Init/Data/Array/Lemmas.lean

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,11 @@ abbrev size_eq_one := @size_eq_one_iff
116116

117117
/-! ## L[i] and L[i]? -/
118118

119-
@[simp] theorem getElem?_eq_none_iff {xs : Array α} : xs[i]? = none ↔ xs.size ≤ i := by
120-
by_cases h : i < xs.size
121-
· simp [getElem?_pos, h]
122-
· rw [getElem?_neg xs i h]
123-
simp_all
119+
theorem getElem?_eq_none_iff {xs : Array α} : xs[i]? = none ↔ xs.size ≤ i := by
120+
simp
124121

125-
@[simp] theorem none_eq_getElem?_iff {xs : Array α} {i : Nat} : none = xs[i]? ↔ xs.size ≤ i := by
126-
simp [eq_comm (a := none)]
122+
theorem none_eq_getElem?_iff {xs : Array α} {i : Nat} : none = xs[i]? ↔ xs.size ≤ i := by
123+
simp
127124

128125
theorem getElem?_eq_none {xs : Array α} (h : xs.size ≤ i) : xs[i]? = none := by
129126
simp [getElem?_eq_none_iff, h]
@@ -133,8 +130,8 @@ grind_pattern Array.getElem?_eq_none => xs.size ≤ i, xs[i]?
133130
@[simp] theorem getElem?_eq_getElem {xs : Array α} {i : Nat} (h : i < xs.size) : xs[i]? = some xs[i] :=
134131
getElem?_pos ..
135132

136-
theorem getElem?_eq_some_iff {xs : Array α} : xs[i]? = some b ↔ ∃ h : i < xs.size, xs[i] = b := by
137-
simp [getElem?_def]
133+
theorem getElem?_eq_some_iff {xs : Array α} : xs[i]? = some b ↔ ∃ h : i < xs.size, xs[i] = b :=
134+
_root_.getElem?_eq_some_iff
138135

139136
@[grind →]
140137
theorem getElem_of_getElem? {xs : Array α} : xs[i]? = some a → ∃ h : i < xs.size, xs[i] = a :=

src/Init/Data/BitVec/Lemmas.lean

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ theorem lt_of_getMsbD {x : BitVec w} {i : Nat} : getMsbD x i = true → i < w :=
6868
@[simp] theorem getElem?_eq_getElem {l : BitVec w} {n} (h : n < w) : l[n]? = some l[n] := by
6969
simp only [getElem?_def, h, ↓reduceDIte]
7070

71-
theorem getElem?_eq_some_iff {l : BitVec w} : l[n]? = some a ↔ ∃ h : n < w, l[n] = a := by
72-
simp only [getElem?_def]
73-
split
74-
· simp_all
75-
· simp; omega
71+
theorem getElem?_eq_some_iff {l : BitVec w} : l[n]? = some a ↔ ∃ h : n < w, l[n] = a :=
72+
_root_.getElem?_eq_some_iff
73+
74+
theorem some_eq_getElem?_iff {l : BitVec w} : some a = l[n]? ↔ ∃ h : n < w, l[n] = a :=
75+
_root_.some_eq_getElem?_iff
7676

7777
theorem getElem_of_getElem? {l : BitVec w} : l[n]? = some a → ∃ h : n < w, l[n] = a :=
7878
getElem?_eq_some_iff.mp
@@ -81,11 +81,11 @@ set_option linter.missingDocs false in
8181
@[deprecated getElem?_eq_some_iff (since := "2025-02-17")]
8282
abbrev getElem?_eq_some := @getElem?_eq_some_iff
8383

84-
@[simp] theorem getElem?_eq_none_iff {l : BitVec w} : l[n]? = none ↔ w ≤ n := by
85-
simp only [getElem?_def]
86-
split
87-
· simp_all
88-
· simp; omega
84+
theorem getElem?_eq_none_iff {l : BitVec w} : l[n]? = none ↔ w ≤ n := by
85+
simp
86+
87+
theorem none_eq_getElem?_iff {l : BitVec w} : none = l[n]? ↔ w ≤ n := by
88+
simp
8989

9090
theorem getElem?_eq_none {l : BitVec w} (h : w ≤ n) : l[n]? = none := getElem?_eq_none_iff.mpr h
9191

src/Init/Data/Vector/Lemmas.lean

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -816,14 +816,11 @@ abbrev mkVector_eq_mk_mkArray := @replicate_eq_mk_replicate
816816

817817
/-! ## L[i] and L[i]? -/
818818

819-
@[simp] theorem getElem?_eq_none_iff {xs : Vector α n} : xs[i]? = none ↔ n ≤ i := by
820-
by_cases h : i < n
821-
· simp [getElem?_pos, h]
822-
· rw [getElem?_neg xs i h]
823-
simp_all
819+
theorem getElem?_eq_none_iff {xs : Vector α n} : xs[i]? = none ↔ n ≤ i := by
820+
simp
824821

825-
@[simp] theorem none_eq_getElem?_iff {xs : Vector α n} {i : Nat} : none = xs[i]? ↔ n ≤ i := by
826-
simp [eq_comm (a := none)]
822+
theorem none_eq_getElem?_iff {xs : Vector α n} {i : Nat} : none = xs[i]? ↔ n ≤ i := by
823+
simp
827824

828825
theorem getElem?_eq_none {xs : Vector α n} (h : n ≤ i) : xs[i]? = none := by
829826
simp [getElem?_eq_none_iff, h]
@@ -835,15 +832,15 @@ grind_pattern Vector.getElem?_eq_none => n ≤ i, xs[i]?
835832
@[simp] theorem getElem?_eq_getElem {xs : Vector α n} {i : Nat} (h : i < n) : xs[i]? = some xs[i] :=
836833
getElem?_pos ..
837834

838-
theorem getElem?_eq_some_iff {xs : Vector α n} : xs[i]? = some b ↔ ∃ h : i < n, xs[i] = b := by
839-
simp [getElem?_def]
835+
theorem getElem?_eq_some_iff {xs : Vector α n} : xs[i]? = some b ↔ ∃ h : i < n, xs[i] = b :=
836+
_root_.getElem?_eq_some_iff
840837

841838
@[grind →]
842839
theorem getElem_of_getElem? {xs : Vector α n} : xs[i]? = some a → ∃ h : i < n, xs[i] = a :=
843840
getElem?_eq_some_iff.mp
844841

845-
theorem some_eq_getElem?_iff {xs : Vector α n} : some b = xs[i]? ↔ ∃ h : i < n, xs[i] = b := by
846-
rw [eq_comm, getElem?_eq_some_iff]
842+
theorem some_eq_getElem?_iff {xs : Vector α n} : some b = xs[i]? ↔ ∃ h : i < n, xs[i] = b :=
843+
_root_.some_eq_getElem?_iff
847844

848845
@[simp] theorem some_getElem_eq_getElem?_iff {xs : Vector α n} {i : Nat} (h : i < n) :
849846
(some xs[i] = xs[i]?) ↔ True := by

src/Init/GetElem.lean

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,58 @@ theorem getElem!_neg [GetElem? cont idx elem dom] [LawfulGetElem cont idx elem d
198198
simp only [getElem?_def]
199199
split <;> simp_all
200200

201+
@[simp] theorem none_eq_getElem?_iff [GetElem? cont idx elem dom] [LawfulGetElem cont idx elem dom]
202+
(c : cont) (i : idx) [Decidable (dom c i)] : none = c[i]? ↔ ¬dom c i := by
203+
simp only [getElem?_def]
204+
split <;> simp_all
205+
206+
theorem of_getElem?_eq_some [GetElem? cont idx elem dom] [LawfulGetElem cont idx elem dom]
207+
{c : cont} {i : idx} [Decidable (dom c i)] (h : c[i]? = some e) : dom c i := by
208+
simp only [getElem?_def] at h
209+
split at h <;> rename_i h'
210+
case isTrue =>
211+
exact h'
212+
case isFalse =>
213+
simp at h
214+
215+
theorem getElem?_eq_some_iff [GetElem? cont idx elem dom] [LawfulGetElem cont idx elem dom]
216+
{c : cont} {i : idx} [Decidable (dom c i)] : c[i]? = some e ↔ Exists fun h : dom c i => c[i] = e := by
217+
simp only [getElem?_def]
218+
split <;> rename_i h
219+
case isTrue =>
220+
constructor
221+
case mp =>
222+
intro w
223+
refine ⟨h, ?_⟩
224+
simpa using w
225+
case mpr =>
226+
intro ⟨h, w⟩
227+
simpa using w
228+
case isFalse =>
229+
simp only [reduceCtorEq, false_iff]
230+
intro ⟨w, w'⟩
231+
exact h w
232+
233+
theorem some_eq_getElem?_iff [GetElem? cont idx elem dom] [LawfulGetElem cont idx elem dom]
234+
{c : cont} {i : idx} [Decidable (dom c i)] : some e = c[i]? ↔ Exists fun h : dom c i => c[i] = e := by
235+
rw [eq_comm, getElem?_eq_some_iff]
236+
237+
theorem getElem_of_getElem? [GetElem? cont idx elem dom] [LawfulGetElem cont idx elem dom]
238+
{c : cont} {i : idx} [Decidable (dom c i)] (h : c[i]? = some e) : Exists fun h : dom c i => c[i] = e :=
239+
getElem?_eq_some_iff.mp h
240+
241+
grind_pattern getElem_of_getElem? => c[i]?, some e
242+
243+
@[simp] theorem some_getElem_eq_getElem?_iff [GetElem? cont idx elem dom] [LawfulGetElem cont idx elem dom]
244+
{c : cont} {i : idx} [Decidable (dom c i)] (h : dom c i):
245+
(some c[i] = c[i]?) ↔ True := by
246+
simpa [some_eq_getElem?_iff, h] using ⟨h, trivial⟩
247+
248+
@[simp] theorem getElem?_eq_some_getElem_iff [GetElem? cont idx elem dom] [LawfulGetElem cont idx elem dom]
249+
{c : cont} {i : idx} [Decidable (dom c i)] (h : dom c i):
250+
(c[i]? = some c[i]) ↔ True := by
251+
simpa [getElem?_eq_some_iff, h] using ⟨h, trivial⟩
252+
201253
@[deprecated getElem?_eq_none_iff (since := "2025-02-17")]
202254
abbrev getElem?_eq_none := @getElem?_eq_none_iff
203255

src/Std/Data/HashMap/Lemmas.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,10 @@ instance [EquivBEq α] [LawfulHashable α] : LawfulGetElem (HashMap α β) α β
823823
rw [getElem!_eq_get!_getElem?]
824824
split <;> simp_all
825825

826+
theorem getElem?_eq_some_iff [EquivBEq α] [LawfulHashable α] {k : α} {v : β} :
827+
m[k]? = some v ↔ ∃ h : k ∈ m, m[k] = v :=
828+
_root_.getElem?_eq_some_iff
829+
826830
@[simp, grind =]
827831
theorem length_keys [EquivBEq α] [LawfulHashable α] :
828832
m.keys.length = m.size :=

src/Std/Data/TreeMap/Lemmas.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,10 @@ instance [TransCmp cmp] : LawfulGetElem (TreeMap α β cmp) α β (fun m a => a
763763
rw [getElem!_eq_get!_getElem?]
764764
split <;> simp_all
765765

766+
theorem getElem?_eq_some_iff [TransCmp cmp] {k : α} {v : β} :
767+
t[k]? = some v ↔ ∃ h : k ∈ t, t[k] = v :=
768+
_root_.getElem?_eq_some_iff
769+
766770
@[simp, grind =]
767771
theorem length_keys [TransCmp cmp] :
768772
t.keys.length = t.size :=

0 commit comments

Comments
 (0)