Skip to content
Merged
Show file tree
Hide file tree
Changes from 104 commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
f59fa7d
Initial `getEntry` work
wkrozowski Oct 31, 2025
5911740
end of day push
wkrozowski Oct 31, 2025
e44545c
push intermediate changes
wkrozowski Nov 3, 2025
cb7ac1d
end of day push
wkrozowski Nov 3, 2025
b54f683
chore: push lemma about `getEntry`
wkrozowski Nov 4, 2025
037c5b8
foldl model
wkrozowski Nov 4, 2025
cd12c0a
chore: intermediate work
wkrozowski Nov 4, 2025
2239c23
Massive lemma is done
wkrozowski Nov 5, 2025
8b8f3bb
refactor
wkrozowski Nov 5, 2025
02226fc
WF lemma is now working
wkrozowski Nov 5, 2025
69669c6
chore : the wf variant works
wkrozowski Nov 5, 2025
439e242
chore add lemmas
wkrozowski Nov 5, 2025
a7c71fa
more lemmas
wkrozowski Nov 5, 2025
725689c
all get lemmas are done
wkrozowski Nov 6, 2025
64a7891
getKey? lemmas are done
wkrozowski Nov 6, 2025
9298608
Add const lemmas
wkrozowski Nov 6, 2025
c7d1e13
Remove sorried proof
wkrozowski Nov 6, 2025
3bf6ad4
push unfinished work
wkrozowski Nov 6, 2025
20bd320
Prove length lemma
wkrozowski Nov 7, 2025
8bf7034
push changes
wkrozowski Nov 7, 2025
db949a8
Finish sublemma
wkrozowski Nov 7, 2025
8c035db
add wf predicate
wkrozowski Nov 7, 2025
ad46950
Add getEntry?/getEntry lemmas
wkrozowski Nov 7, 2025
247fb58
Add getEntry! and getEntryD
wkrozowski Nov 10, 2025
5b6274d
fix naming
wkrozowski Nov 10, 2025
8a80729
push what i have
wkrozowski Nov 11, 2025
804fba0
Cleanup old fold
wkrozowski Nov 11, 2025
5411489
Add isEmpty lemma
wkrozowski Nov 12, 2025
86f2b74
add size lemma
wkrozowski Nov 12, 2025
bae20a2
fix simp_to_model
wkrozowski Nov 12, 2025
be0de57
cleanup
wkrozowski Nov 12, 2025
0228303
Further cleanup
wkrozowski Nov 12, 2025
d6253e8
add getEntry to publicly exposed DHashMap
wkrozowski Nov 12, 2025
3f011be
Merge branch 'wojciech/hashmap_getEntry' into wojciech/hashmap_inters…
wkrozowski Nov 12, 2025
fb2e980
Fix WF issues
wkrozowski Nov 12, 2025
05e9752
Fix comments
wkrozowski Nov 12, 2025
4d7e70e
Merge branch 'wojciech/hashmap_getEntry' into wojciech/hashmap_inters…
wkrozowski Nov 12, 2025
cfd6372
cleanup by applying Markus' suggestion
wkrozowski Nov 12, 2025
3b74c67
fix deleted code
wkrozowski Nov 12, 2025
8693512
renaming
wkrozowski Nov 12, 2025
dbfe831
rename size lemma
wkrozowski Nov 12, 2025
a6c2a75
Add Raw DHashMap inter lemmas
wkrozowski Nov 12, 2025
95fab3b
Add DHashMap lemmas
wkrozowski Nov 13, 2025
81efbee
Add basic support for HashMap raw
wkrozowski Nov 13, 2025
3bf6d39
reorganise things in the files
wkrozowski Nov 13, 2025
a6fcc76
Add const lemmas
wkrozowski Nov 13, 2025
2c2a986
Add inter lemmas
wkrozowski Nov 13, 2025
b5a421b
Add hashSet lemmas
wkrozowski Nov 13, 2025
8be273f
Slight reorganisation
wkrozowski Nov 13, 2025
8b7cfa1
Add `eraseMany` and `wf_eraseMany`
wkrozowski Nov 13, 2025
3766be5
Add Raw.erase
wkrozowski Nov 13, 2025
a9c0b35
Add further sublemmas
wkrozowski Nov 13, 2025
922beb5
add new correspondence lemma
wkrozowski Nov 14, 2025
b652b7b
add to list model
wkrozowski Nov 14, 2025
ed7b23a
add lemmas
wkrozowski Nov 14, 2025
7f45903
chore: add sublemmas
wkrozowski Nov 14, 2025
b1435c1
further progress on lemmas
wkrozowski Nov 14, 2025
002545f
push intermediate work
wkrozowski Nov 14, 2025
0b840ad
push
wkrozowski Nov 14, 2025
d33bb5f
Update src/Std/Data/Internal/List/Associative.lean
wkrozowski Nov 14, 2025
ae0385b
Update src/Std/Data/DHashMap/Basic.lean
wkrozowski Nov 14, 2025
7aa501b
Update src/Std/Data/DHashMap/Lemmas.lean
wkrozowski Nov 14, 2025
d3cb462
Fix WF
wkrozowski Nov 14, 2025
3bde3f9
Fix docstrings
wkrozowski Nov 14, 2025
66304f9
Fix simp attributes
wkrozowski Nov 14, 2025
75885a4
Remove unnecessary List prefix
wkrozowski Nov 14, 2025
6a0ddf9
resolve merge issues
wkrozowski Nov 15, 2025
dac309f
fixes
wkrozowski Nov 15, 2025
b56b1bb
fix compilation
wkrozowski Nov 15, 2025
6303bdc
chore: remove untrue lemma
wkrozowski Nov 15, 2025
fa51969
More set difference lemmas
wkrozowski Nov 17, 2025
07b32d6
Finish remaining intersection lemma
wkrozowski Nov 17, 2025
173a923
Merge branch 'master' into wojciech/hashmap_intersection4
wkrozowski Nov 17, 2025
3e6ed8d
Rename sublemmas
wkrozowski Nov 17, 2025
5e30864
Merge branch 'wojciech/hashmap_intersection4' into wojciech/hashmap_d…
wkrozowski Nov 17, 2025
1d45840
Rename `eraseMany` to `eraseManyEntries`
wkrozowski Nov 17, 2025
ff2445c
Merge branch 'master' into wojciech/hashmap_diff2
wkrozowski Nov 18, 2025
6b5dba1
Apply Markus' suggestion
wkrozowski Nov 18, 2025
ac3049f
Untrack files added by accident
wkrozowski Nov 18, 2025
c19e2b7
Add lemmas
wkrozowski Nov 18, 2025
150f3cb
Add all lemmas
wkrozowski Nov 18, 2025
8bd0307
Fix notation for WF lemmas
wkrozowski Nov 19, 2025
1689034
save what I have so far
wkrozowski Nov 20, 2025
496f2c4
Merge branch 'master' into wojciech/hashmap_diff2
wkrozowski Nov 21, 2025
0e2c1d8
refactor progress
wkrozowski Nov 21, 2025
bf29a9b
further progress
wkrozowski Nov 21, 2025
54fb119
Further progress
wkrozowski Nov 21, 2025
c3ce644
Refactor progress
wkrozowski Nov 21, 2025
12e76c7
Lemmas pass
wkrozowski Nov 21, 2025
005b5e7
Clean up `Associative.lean`
wkrozowski Nov 21, 2025
318b54f
Fix typo
wkrozowski Nov 21, 2025
eb88d10
finish renaming
wkrozowski Nov 27, 2025
824946f
Merge branch 'master' into wojciech/hashmap_diff2
wkrozowski Nov 27, 2025
8f760c2
add congr lemmas
wkrozowski Nov 27, 2025
2a84bba
push changes
wkrozowski Nov 27, 2025
842461e
Fix toModel
wkrozowski Nov 27, 2025
8752a33
Get the internal lemmas working
wkrozowski Nov 27, 2025
3eb1945
Non-Raw lemmas are working
wkrozowski Nov 27, 2025
f3c432f
DTreeMap.Raw lemmas
wkrozowski Nov 27, 2025
28b4424
Add TreeMap lemmas
wkrozowski Nov 27, 2025
294f4fd
Add the remaining TreeSet lemmas
wkrozowski Nov 27, 2025
9bab334
add wf lemmas to raw variants
wkrozowski Nov 27, 2025
5516ccd
Add Raw TreeSet lemmas
wkrozowski Nov 27, 2025
4beb885
Merge branch 'master' into wojciech/treemap_diff2
wkrozowski Nov 27, 2025
e2bd487
rename lemmas
wkrozowski Dec 1, 2025
a4a9515
Merge branch 'master' into wojciech/treemap_diff2
wkrozowski Dec 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/Std/Data/DTreeMap/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -1053,14 +1053,23 @@ def inter (t₁ t₂ : DTreeMap α β cmp) : DTreeMap α β cmp :=
letI : Ord α := ⟨cmp⟩; ⟨t₁.inner.inter t₂.inner t₁.wf.balanced, @Impl.WF.inter _ _ _ _ t₂.inner t₁.wf.balanced t₁.wf⟩

instance : Inter (DTreeMap α β cmp) := ⟨inter⟩

/--
Computes the difference of the given tree maps.
This function always iterates through the smaller map.
-/
def diff (t₁ t₂ : DTreeMap α β cmp) : DTreeMap α β cmp :=
letI : Ord α := ⟨cmp⟩; ⟨t₁.inner.diff t₂.inner t₁.wf.balanced, @Impl.WF.diff α β _ t₁.inner t₁.wf t₂.inner⟩

instance : SDiff (DTreeMap α β cmp) := ⟨diff⟩

/--
Erases multiple mappings from the tree map by iterating over the given collection and calling
`erase`.
-/
@[inline]
def eraseMany {ρ} [ForIn Id ρ α] (t : DTreeMap α β cmp) (l : ρ) : DTreeMap α β cmp :=
letI : Ord α := ⟨cmp⟩; ⟨t.inner.eraseMany l t.wf.balanced, t.wf.eraseMany⟩

namespace Const

variable {β : Type v}
Expand Down
728 changes: 727 additions & 1 deletion src/Std/Data/DTreeMap/Internal/Lemmas.lean

Large diffs are not rendered by default.

44 changes: 44 additions & 0 deletions src/Std/Data/DTreeMap/Internal/Operations.lean
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,36 @@ def eraseMany! [Ord α] {ρ : Type w} [ForIn Id ρ α] (t : Impl α β) (l : ρ)
r := ⟨r.val.erase! a, fun h₀ h₁ => h₁ _ _ (r.2 h₀ h₁)⟩
return r

/-- A tree map obtained by erasing elements from `t`, bundled with an inductive principle. -/
abbrev IteratedEntryErasureFrom [Ord α] (t) :=
{ t' // ∀ {P : Impl α β → Prop}, P t → (∀ t'' a h, P t'' → P (t''.erase a h).impl) → P t' }

/-- Iterate over `l` and erase all of its elements from `t`. -/
@[inline]
def eraseManyEntries [Ord α] {ρ : Type w} [ForIn Id ρ ((a : α) × β a)] (t : Impl α β) (l : ρ) (h : t.Balanced) :
IteratedEntryErasureFrom t := Id.run do
let mut r := ⟨t, fun h _ => h⟩
for ⟨a, _⟩ in l do
let hr := r.2 h (fun t'' a h _ => (t''.erase a h).balanced_impl)
r := ⟨r.val.erase a hr |>.impl, fun h₀ h₁ => h₁ _ _ _ (r.2 h₀ h₁)⟩
return r

/-- A tree map obtained by erasing elements from `t`, bundled with an inductive principle. -/
abbrev IteratedSlowEntryErasureFrom [Ord α] (t) :=
{ t' // ∀ {P : Impl α β → Prop}, P t → (∀ t'' a, P t'' → P (t''.erase! a)) → P t' }

/--
Slower version of `eraseManyEntries` which can be used in absence of balance information but still
assumes the preconditions of `eraseManyEntries`, otherwise might panic.
-/
@[inline]
def eraseManyEntries! [Ord α] {ρ : Type w} [ForIn Id ρ ((a : α) × β a)] (t : Impl α β) (l : ρ) :
IteratedSlowErasureFrom t := Id.run do
let mut r := ⟨t, fun h _ => h⟩
for ⟨a, _⟩ in l do
r := ⟨r.val.erase! a, fun h₀ h₁ => h₁ _ _ (r.2 h₀ h₁)⟩
return r

/-- A tree map obtained by inserting elements into `t`, bundled with an inductive principle. -/
abbrev IteratedInsertionInto [Ord α] (t) :=
{ t' // ∀ {P : Impl α β → Prop}, P t → (∀ t'' a b h, P t'' → P (t''.insert a b h).impl) → P t' }
Expand Down Expand Up @@ -792,6 +822,20 @@ information but still assumes the preconditions of `filter`, otherwise might pan
def inter! [Ord α] (m₁ m₂ : Impl α β): Impl α β :=
if m₁.size ≤ m₂.size then m₁.filter! (fun k _ => m₂.contains k) else interSmaller m₁ m₂

/--
Computes the difference of the given tree maps.
This function always iterates through the smaller map.
-/
def diff [Ord α] (t₁ t₂ : Impl α β) (h₁ : t₁.Balanced) : Impl α β :=
if t₁.size ≤ t₂.size then (t₁.filter (fun p _ => !t₂.contains p) h₁).impl else (t₁.eraseManyEntries t₂ h₁)

/--
Slower version of `diff` which can be used in the absence of balance
information but still assumes the preconditions of `diff`, otherwise might panic.
-/
def diff! [Ord α] (t₁ t₂ : Impl α β) : Impl α β :=
if t₁.size ≤ t₂.size then t₁.filter! (fun p _ => !t₂.contains p) else t₁.eraseManyEntries! t₂

/--
Changes the mapping of the key `k` by applying the function `f` to the current mapped value
(if any). This function can be used to insert a new mapping, modify an existing one or delete it.
Expand Down
11 changes: 11 additions & 0 deletions src/Std/Data/DTreeMap/Internal/WF/Defs.lean
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ theorem WF.balanced [Ord α] {t : Impl α β} (h : WF t) : t.Balanced := by
case constModify ih => exact Const.balanced_modify ih
case inter ih => exact balanced_inter ih

theorem WF.eraseManyEntries [Ord α] {ρ} [ForIn Id ρ ((a : α) × β a)] {t : Impl α β} {l : ρ} {h} (hwf : WF t) :
WF (t.eraseManyEntries l h).val :=
(t.eraseManyEntries l h).2 hwf fun _ _ _ hwf' => hwf'.erase

theorem WF.eraseMany [Ord α] {ρ} [ForIn Id ρ α] {t : Impl α β} {l : ρ} {h} (hwf : WF t) :
WF (t.eraseMany l h).val :=
(t.eraseMany l h).2 hwf fun _ _ _ hwf' => hwf'.erase
Expand Down Expand Up @@ -110,6 +114,13 @@ theorem WF.union [Ord α] {t₁ : Impl α β} {h₁ : t₁.WF} {t₂ : Impl α
. apply WF.insertManyIfNew h₂
. apply WF.insertMany h₁

theorem WF.diff [Ord α] {t₁ : Impl α β} {h₁ : t₁.WF} {t₂ : Impl α β} :
(t₁.diff t₂ h₁.balanced).WF := by
simp [Impl.diff]
split
· apply WF.filter h₁
· apply WF.eraseManyEntries h₁

section Const

variable {β : Type v}
Expand Down
103 changes: 103 additions & 0 deletions src/Std/Data/DTreeMap/Internal/WF/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -1661,6 +1661,75 @@ theorem WF.eraseMany! {_ : Ord α} [TransOrd α] {ρ} [ForIn Id ρ α] {l : ρ}
{t : Impl α β} (h : t.WF) : (t.eraseMany! l).1.WF :=
(t.eraseMany! l).2 h (fun _ _ h' => h'.erase!)

/-!
### `eraseManyEntries`
-/

theorem eraseManyEntries!_eq_foldl {_ : Ord α} {l : List ((a : α) × β a)} {t : Impl α β} :
(t.eraseManyEntries! l).val = l.foldl (init := t) fun acc ⟨k, _⟩ => acc.erase! k := by
simp [eraseManyEntries!, ← List.foldl_hom Subtype.val, List.forIn_pure_yield_eq_foldl]

theorem eraseManyEntries_eq_foldl {_ : Ord α} {l : List ((a : α) × β a)} {t : Impl α β} (h : t.Balanced) :
(t.eraseManyEntries l h).val = l.foldl (init := t) fun acc ⟨k, _⟩ => acc.erase! k := by
simp [eraseManyEntries, erase_eq_erase!, ← List.foldl_hom Subtype.val, List.forIn_pure_yield_eq_foldl]

theorem eraseManyEntries_eq_foldl_impl {_ : Ord α} {t₁ : Impl α β} (h₁ : t₁.Balanced) {t₂ : Impl α β} :
(t₁.eraseManyEntries t₂ h₁).val = t₂.foldl (init := t₁) fun acc k _ => acc.erase! k := by
simp [foldl_eq_foldl]
rw [← eraseManyEntries_eq_foldl]
rotate_left
· exact h₁
· simp only [eraseManyEntries, pure, ForIn.forIn, Id.run_bind]
rw [forIn_eq_forIn_toListModel]
congr

theorem eraseManyEntries!_eq_foldl_impl {_ : Ord α} {t₁ : Impl α β} {t₂ : Impl α β} :
(t₁.eraseManyEntries! t₂).val = t₂.foldl (init := t₁) fun acc k _ => acc.erase! k := by
simp [foldl_eq_foldl]
rw [← eraseManyEntries!_eq_foldl]
simp only [eraseManyEntries!, pure, ForIn.forIn, Id.run_bind]
rw [forIn_eq_forIn_toListModel]
congr

theorem eraseManyEntries_eq_eraseManyEntries!_impl {_ : Ord α}
{t₁ t₂ : Impl α β} (h : t₁.Balanced) :
(t₁.eraseManyEntries t₂ h).val = (t₁.eraseManyEntries! t₂).val := by
simp only [eraseManyEntries_eq_foldl_impl, eraseManyEntries!_eq_foldl_impl]

theorem eraseManyEntries_impl_perm_eraseList {_ : Ord α} [BEq α] [LawfulBEqOrd α] [TransOrd α]
{t₁ : Impl α β} (h₁ : t₁.WF) {t₂ : Impl α β} :
List.Perm (t₁.eraseManyEntries t₂ h₁.balanced).val.toListModel (t₁.toListModel.eraseList (t₂.toListModel.map (·.1))) := by
rw [eraseManyEntries_eq_foldl_impl]
rw [foldl_eq_foldl]
induction t₂.toListModel generalizing t₁ with
| nil => rfl
| cons e es ih =>
simp only [List.foldl_cons]
apply List.Perm.trans (@ih (t₁.erase! e.1) (h₁.erase!))
apply eraseList_perm_of_perm_first
· apply toListModel_erase!
· exact h₁.balanced
· exact h₁.ordered
· apply h₁.erase!.ordered.distinctKeys

theorem toListModel_eraseManyEntries_impl {_ : Ord α} [BEq α] [LawfulBEqOrd α] [TransOrd α]
{t₁ : Impl α β} (h₁ : t₁.WF) {t₂ : Impl α β} :
List.Perm (t₁.eraseManyEntries t₂ h₁.balanced).val.toListModel (t₁.toListModel.filter (fun p => !List.contains (t₂.toListModel.map Sigma.fst) p.fst )) := by
apply List.Perm.trans
· apply eraseManyEntries_impl_perm_eraseList h₁
· apply eraseList_perm_filter_not_contains
· apply h₁.ordered.distinctKeys

theorem toListModel_eraseManyEntries!_impl {_ : Ord α} [BEq α] [LawfulBEqOrd α] [TransOrd α]
{t₁ : Impl α β} (h₁ : t₁.WF) {t₂ : Impl α β} :
List.Perm (t₁.eraseManyEntries! t₂).val.toListModel (t₁.toListModel.filter (fun p => !List.contains (t₂.toListModel.map Sigma.fst) p.fst)) := by
rw [← eraseManyEntries_eq_eraseManyEntries!_impl h₁.balanced]
apply toListModel_eraseManyEntries_impl h₁

theorem WF.eraseManyEntries! {_ : Ord α} [TransOrd α] {ρ} [ForIn Id ρ ((a : α) × β a)] {l : ρ}
{t : Impl α β} (h : t.WF) : (t.eraseManyEntries! l).1.WF :=
(t.eraseManyEntries! l).2 h (fun _ _ h' => h'.erase!)

/-!
### `insertMany`
-/
Expand Down Expand Up @@ -2048,6 +2117,40 @@ theorem toListModel_interSmallerFn {_ : Ord α} [TransOrd α] [BEq α] [LawfulBE
simp only [heq, hml]
exact h₁.ordered

/-!
### diff
-/

theorem toListModel_diff {_ : Ord α} [BEq α] [LawfulBEqOrd α] [TransOrd α]
{t₁ t₂ : Impl α β} (h₁ : t₁.WF) (h₂ : t₂.WF) :
List.Perm (t₁.diff t₂ h₁.balanced).toListModel (t₁.toListModel.filter (fun p => !List.contains (t₂.toListModel.map Sigma.fst) p.fst)) := by
rw [diff]
split
· simp only [toListModel_filter]
conv =>
lhs
lhs
ext e
congr
rw [contains_eq_containsKey h₂.ordered]
rw [containsKey_eq_contains_map_fst]
· apply toListModel_eraseManyEntries_impl h₁

theorem diff_eq_diff! [Ord α]
{t₁ t₂ : Impl α β} (h₁ : t₁.WF) :
(t₁.diff t₂ h₁.balanced) = t₁.diff! t₂ := by
simp only [diff, diff!]
split
· rw [filter_eq_filter!]
. rw [eraseManyEntries_eq_eraseManyEntries!_impl h₁.balanced]

theorem WF.diff! {_ : Ord α} [TransOrd α]
{t₁ : Impl α β} (h₁ : t₁.WF) {t₂ : Impl α β} : (t₁.diff! t₂).WF := by
simp only [Impl.diff!]
split
. exact WF.filter! h₁
. exact WF.eraseManyEntries! h₁

/-!
### interSmaller
-/
Expand Down
Loading
Loading