Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: verify insertMany method for adding lists to HashMaps #6211

Merged
merged 86 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
05b86d2
Model function for insertManyList
jt0202 Nov 10, 2024
ea17bbb
Verified insertManyList_contains for Raw0
jt0202 Nov 10, 2024
ed56c5e
verified InsertList together with insert/size
jt0202 Nov 10, 2024
db8a642
Renamed List.insertMany to List.insertList and added Perm result for …
jt0202 Nov 10, 2024
2aecd5a
Use simp_to_model for insertList_contains
monsterkrampe Nov 11, 2024
3845a2e
Add get_insertList result to internal hashmap
monsterkrampe Nov 13, 2024
42d72e3
Try to show insertMany_eq_insertList
monsterkrampe Nov 15, 2024
a1d965d
Add remarks from meeting
monsterkrampe Nov 15, 2024
83b4e10
Added equality proof between insertMany & insertList by @TwoFX
jt0202 Nov 16, 2024
ed9f63a
Simplified size_insertList
jt0202 Nov 16, 2024
ceb23c9
Added results for isEmpty
jt0202 Nov 17, 2024
a9b4847
Start get? verification
jt0202 Nov 17, 2024
da76a1d
WIP: verification getValueCast?
jt0202 Nov 18, 2024
9013992
Finished DistinctKeys for get?
jt0202 Nov 19, 2024
1d18281
Finish get verification
jt0202 Nov 21, 2024
f023e7f
Some formatting
jt0202 Nov 21, 2024
fdd6bab
Pull insertList up to DHashMap
jt0202 Nov 21, 2024
273a0d0
Add results for getKey?_insertList
monsterkrampe Nov 18, 2024
be70b67
Add results for variants of getKey_insertList
monsterkrampe Nov 19, 2024
a5f7e12
Multiple small changes
jt0202 Nov 26, 2024
77bc339
Replace insertList with insertMany in lemmas
jt0202 Nov 26, 2024
cea3723
Hotfix for build after rebase
monsterkrampe Nov 27, 2024
6f01fd3
Split getKey? result into two cases
monsterkrampe Nov 27, 2024
c85b156
Adjust remaining getKey results
monsterkrampe Nov 28, 2024
3a4c796
Remove obsolete auxiliary result
monsterkrampe Nov 28, 2024
0cb4f2a
Use getKey?_of_perm for getKey?_insertList
monsterkrampe Nov 29, 2024
a2d70af
Rework getValueCast? according to suggestion
monsterkrampe Nov 29, 2024
4fd84f3
Remove obsolete aux results; Fix colon spacing
monsterkrampe Nov 29, 2024
8f3eaa2
constant get for insertMany
jt0202 Nov 30, 2024
446e801
Verify Const.insertMany
jt0202 Nov 30, 2024
49e4a9d
Verify insertManyIfNewUnit
jt0202 Dec 1, 2024
8340caf
get results for insertManyIfNewUnit
jt0202 Dec 2, 2024
45e3bc0
Style fixes
jt0202 Dec 2, 2024
7f4bc44
Merge branch 'leanprover:master' into hashMap-insertList
jt0202 Dec 2, 2024
bddf6fb
Adjust simp spacing
monsterkrampe Dec 3, 2024
ae25818
Incorporate smaller remarks from PR
monsterkrampe Dec 3, 2024
9bb3511
Shorten List.pairwise statements
monsterkrampe Dec 3, 2024
3266d6c
Fix two more small spacing issues
monsterkrampe Dec 3, 2024
422ed96
Unify getValue? proofs with getValueCast?
monsterkrampe Dec 4, 2024
5ce3a53
Simplify insertListConst
monsterkrampe Dec 4, 2024
be3fc59
Remove and simplify according to some PR comments
monsterkrampe Dec 5, 2024
6572813
Break some long lines
monsterkrampe Dec 5, 2024
be75a4c
Rename theorems to resolve Const namespace issue
monsterkrampe Dec 5, 2024
3689bd6
Convert negated ands into simp normal form
monsterkrampe Dec 5, 2024
b8d325d
Try getEntry?_insertList approach
monsterkrampe Dec 10, 2024
14a1da0
Use getEntry?_insertList approach where applicable
monsterkrampe Dec 11, 2024
cdc6b59
Simplify isEmpty results; Fix formatting
monsterkrampe Dec 11, 2024
0617166
Fix formatting
monsterkrampe Dec 11, 2024
0f7fd51
Remove one theorem variant for Const
monsterkrampe Dec 11, 2024
fe60013
Style fix for Internal list
jt0202 Dec 12, 2024
4b79e10
Added size_insertMany_list_le & further style fixes
jt0202 Dec 12, 2024
b233bc5
Moved results up to Raw
jt0202 Dec 12, 2024
41acb69
ofList lemmas introduced
jt0202 Dec 12, 2024
cd58f46
Small name correction
jt0202 Dec 12, 2024
e1234aa
Added cons for ofList
jt0202 Dec 15, 2024
62f5a53
Small style fixes
jt0202 Dec 28, 2024
ee522d3
Further small fixes
jt0202 Dec 28, 2024
57f188c
Experimental: Pulled results up to DHashMap
jt0202 Dec 28, 2024
2b5d6bf
Merge branch 'master' into hashMap-insertList
jt0202 Dec 28, 2024
340ac3a
Small style fixes
jt0202 Jan 5, 2025
7624c21
Added predecessors for ofList into Raw0
jt0202 Jan 5, 2025
37fd60f
Rework of DHashMap lemmas for ofList
jt0202 Jan 5, 2025
5f9dd86
Style fixes
jt0202 Jan 5, 2025
d07c76e
Rewrite of DHashMap.RawLemmas
jt0202 Jan 6, 2025
78c35f1
Small style fix
jt0202 Jan 6, 2025
eee4646
Style fix
jt0202 Jan 8, 2025
b54f7be
Removed colons from two model functions
jt0202 Jan 8, 2025
b51500d
Style fixes
jt0202 Jan 8, 2025
62e03c3
Style fixes
jt0202 Jan 8, 2025
fffcc8f
Style fixes
jt0202 Jan 8, 2025
e5ac649
Style fixes
jt0202 Jan 9, 2025
447c8e4
Results for HashMaps
jt0202 Jan 9, 2025
564ce90
Replace symbols for get
jt0202 Jan 9, 2025
26c9ec7
Result for HashSets
jt0202 Jan 9, 2025
d4edd97
Fix names
jt0202 Jan 9, 2025
d36c5fd
Style fixes
jt0202 Jan 10, 2025
1360be3
Golf associative
jt0202 Jan 10, 2025
83d7b4a
Rewrote getKey functions for insertManyIfNewUnit_list
jt0202 Jan 10, 2025
281c080
Fix typo in HashMap/RawLemmas
monsterkrampe Jan 13, 2025
4a24852
Move ofList out of unverified
jt0202 Jan 13, 2025
42ee903
Style fixes
jt0202 Jan 14, 2025
317b351
Merge branch 'master' into hashMap-insertList
jt0202 Jan 14, 2025
b521a65
Added docstring that went missing during merge
jt0202 Jan 14, 2025
97f9854
Add HashMap size_le_size_insertMany_list theorems
monsterkrampe Jan 14, 2025
aea42fb
Replace 'm.contains k = false' by '¬ k ∈ m' in statements for insertI…
jt0202 Jan 14, 2025
b43dfca
Style fixes & simplified equality lemmas
jt0202 Jan 15, 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
24 changes: 12 additions & 12 deletions src/Std/Data/DHashMap/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -290,24 +290,12 @@ This function ensures that the value is used linearly.
⟨(Raw₀.Const.insertManyIfNewUnit ⟨m.1, m.2.size_buckets_pos⟩ l).1,
(Raw₀.Const.insertManyIfNewUnit ⟨m.1, m.2.size_buckets_pos⟩ l).2 _ Raw.WF.insertIfNew₀ m.2⟩

@[inline, inherit_doc Raw.ofList] def ofList [BEq α] [Hashable α] (l : List ((a : α) × β a)) :
DHashMap α β :=
insertMany ∅ l

/-- Computes the union of the given hash maps, by traversing `m₂` and inserting its elements into `m₁`. -/
@[inline] def union [BEq α] [Hashable α] (m₁ m₂ : DHashMap α β) : DHashMap α β :=
m₂.fold (init := m₁) fun acc x => acc.insert x

instance [BEq α] [Hashable α] : Union (DHashMap α β) := ⟨union⟩

@[inline, inherit_doc Raw.Const.ofList] def Const.ofList {β : Type v} [BEq α] [Hashable α]
(l : List (α × β)) : DHashMap α (fun _ => β) :=
Const.insertMany ∅ l

@[inline, inherit_doc Raw.Const.unitOfList] def Const.unitOfList [BEq α] [Hashable α] (l : List α) :
DHashMap α (fun _ => Unit) :=
Const.insertManyIfNewUnit ∅ l

@[inline, inherit_doc Raw.Const.unitOfArray] def Const.unitOfArray [BEq α] [Hashable α] (l : Array α) :
DHashMap α (fun _ => Unit) :=
Const.insertManyIfNewUnit ∅ l
Expand All @@ -321,4 +309,16 @@ instance [BEq α] [Hashable α] [Repr α] [(a : α) → Repr (β a)] : Repr (DHa

end Unverified

@[inline, inherit_doc Raw.ofList] def ofList [BEq α] [Hashable α] (l : List ((a : α) × β a)) :
TwoFX marked this conversation as resolved.
Show resolved Hide resolved
DHashMap α β :=
insertMany ∅ l

@[inline, inherit_doc Raw.Const.ofList] def Const.ofList {β : Type v} [BEq α] [Hashable α]
(l : List (α × β)) : DHashMap α (fun _ => β) :=
Const.insertMany ∅ l

@[inline, inherit_doc Raw.Const.unitOfList] def Const.unitOfList [BEq α] [Hashable α] (l : List α) :
DHashMap α (fun _ => Unit) :=
Const.insertManyIfNewUnit ∅ l

end Std.DHashMap
875 changes: 873 additions & 2 deletions src/Std/Data/DHashMap/Internal/List/Associative.lean

Large diffs are not rendered by default.

65 changes: 64 additions & 1 deletion src/Std/Data/DHashMap/Internal/Model.lean
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ theorem toListModel_updateAllBuckets {m : Raw₀ α β} {f : AssocList α β →
omega
rw [updateAllBuckets, toListModel, Array.toList_map, List.flatMap_eq_foldl, List.foldl_map,
toListModel, List.flatMap_eq_foldl]
suffices ∀ (l : List (AssocList α β)) (l' : List ((a: α) × δ a)) (l'' : List ((a : α) × β a)),
suffices ∀ (l : List (AssocList α β)) (l' : List ((a : α) × δ a)) (l'' : List ((a : α) × β a)),
Perm (g l'') l' →
Perm (l.foldl (fun acc a => acc ++ (f a).toList) l')
(g (l.foldl (fun acc a => acc ++ a.toList) l'')) by
Expand Down Expand Up @@ -378,6 +378,12 @@ def mapₘ (m : Raw₀ α β) (f : (a : α) → β a → δ a) : Raw₀ α δ :=
def filterₘ (m : Raw₀ α β) (f : (a : α) → β a → Bool) : Raw₀ α β :=
⟨withComputedSize (updateAllBuckets m.1.buckets fun l => l.filter f), by simpa using m.2⟩

/-- Internal implementation detail of the hash map -/
def insertListₘ [BEq α] [Hashable α] (m : Raw₀ α β) (l : List ((a : α) × β a)) : Raw₀ α β :=
match l with
| .nil => m
| .cons hd tl => insertListₘ (m.insert hd.1 hd.2) tl

section

variable {β : Type v}
Expand All @@ -398,6 +404,20 @@ def Const.getDₘ [BEq α] [Hashable α] (m : Raw₀ α (fun _ => β)) (a : α)
def Const.get!ₘ [BEq α] [Hashable α] [Inhabited β] (m : Raw₀ α (fun _ => β)) (a : α) : β :=
(Const.get?ₘ m a).get!

/-- Internal implementation detail of the hash map -/
def Const.insertListₘ [BEq α] [Hashable α] (m : Raw₀ α (fun _ => β)) (l: List (α × β)) :
Raw₀ α (fun _ => β) :=
match l with
| .nil => m
| .cons hd tl => insertListₘ (m.insert hd.1 hd.2) tl

/-- Internal implementation detail of the hash map -/
def Const.insertListIfNewUnitₘ [BEq α] [Hashable α] (m : Raw₀ α (fun _ => Unit)) (l: List α) :
Raw₀ α (fun _ => Unit) :=
match l with
| .nil => m
| .cons hd tl => insertListIfNewUnitₘ (m.insertIfNew hd ()) tl
TwoFX marked this conversation as resolved.
Show resolved Hide resolved

end

/-! # Equivalence between model functions and real implementations -/
Expand Down Expand Up @@ -569,6 +589,19 @@ theorem map_eq_mapₘ (m : Raw₀ α β) (f : (a : α) → β a → δ a) :
theorem filter_eq_filterₘ (m : Raw₀ α β) (f : (a : α) → β a → Bool) :
m.filter f = m.filterₘ f := rfl

theorem insertMany_eq_insertListₘ [BEq α] [Hashable α](m : Raw₀ α β) (l : List ((a : α) × β a)) : insertMany m l = insertListₘ m l := by
simp only [insertMany, Id.run, Id.pure_eq, Id.bind_eq, List.forIn_yield_eq_foldl]
suffices ∀ (t : { m' // ∀ (P : Raw₀ α β → Prop),
(∀ {m'' : Raw₀ α β} {a : α} {b : β a}, P m'' → P (m''.insert a b)) → P m → P m' }),
(List.foldl (fun m' p => ⟨m'.val.insert p.1 p.2, fun P h₁ h₂ => h₁ (m'.2 _ h₁ h₂)⟩) t l).val =
t.val.insertListₘ l from this _
intro t
induction l generalizing m with
| nil => simp [insertListₘ]
| cons hd tl ih =>
simp only [List.foldl_cons, insertListₘ]
apply ih

section

variable {β : Type v}
Expand Down Expand Up @@ -599,6 +632,36 @@ theorem Const.getThenInsertIfNew?_eq_get?ₘ [BEq α] [Hashable α] (m : Raw₀
dsimp only [Array.ugetElem_eq_getElem, Array.uset]
split <;> simp_all [-getValue?_eq_none]

theorem Const.insertMany_eq_insertListₘ [BEq α] [Hashable α] (m : Raw₀ α (fun _ => β))
(l: List (α × β)):
(Const.insertMany m l).1 = Const.insertListₘ m l := by
simp only [insertMany, Id.run, Id.pure_eq, Id.bind_eq, List.forIn_yield_eq_foldl]
suffices ∀ (t : { m' // ∀ (P : Raw₀ α (fun _ => β) → Prop),
(∀ {m'' : Raw₀ α (fun _ => β)} {a : α} {b : β}, P m'' → P (m''.insert a b)) → P m → P m' }),
(List.foldl (fun m' p => ⟨m'.val.insert p.1 p.2, fun P h₁ h₂ => h₁ (m'.2 _ h₁ h₂)⟩) t l).val =
Const.insertListₘ t.val l from this _
intro t
induction l generalizing m with
| nil => simp [insertListₘ]
| cons hd tl ih =>
simp only [List.foldl_cons, insertListₘ]
apply ih

theorem Const.insertManyIfNewUnit_eq_insertListIfNewUnitₘ [BEq α] [Hashable α]
(m : Raw₀ α (fun _ => Unit)) (l: List α):
(Const.insertManyIfNewUnit m l).1 = Const.insertListIfNewUnitₘ m l := by
simp only [insertManyIfNewUnit, Id.run, Id.pure_eq, Id.bind_eq, List.forIn_yield_eq_foldl]
suffices ∀ (t : { m' // ∀ (P : Raw₀ α (fun _ => Unit) → Prop),
(∀ {m'' a b}, P m'' → P (m''.insertIfNew a b)) → P m → P m'}),
(List.foldl (fun m' p => ⟨m'.val.insertIfNew p (), fun P h₁ h₂ => h₁ (m'.2 _ h₁ h₂)⟩) t l).val =
Const.insertListIfNewUnitₘ t.val l from this _
intro t
induction l generalizing m with
| nil => simp [insertListIfNewUnitₘ]
| cons hd tl ih =>
simp only [List.foldl_cons, insertListIfNewUnitₘ]
apply ih
monsterkrampe marked this conversation as resolved.
Show resolved Hide resolved

end

end Raw₀
Expand Down
42 changes: 42 additions & 0 deletions src/Std/Data/DHashMap/Internal/Raw.lean
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,52 @@ theorem filter_val [BEq α] [Hashable α] {m : Raw₀ α β} {f : (a : α) →
m.val.filter f = m.filter f := by
simp [Raw.filter, m.2]

theorem insertMany_eq [BEq α] [Hashable α] {m : Raw α β} (h : m.WF) {ρ : Type w} [ForIn Id ρ ((a : α) × β a)] {l : ρ} :
m.insertMany l = Raw₀.insertMany ⟨m, h.size_buckets_pos⟩ l := by
simp [Raw.insertMany, h.size_buckets_pos]

theorem insertMany_val [BEq α][Hashable α] {m : Raw₀ α β} {ρ : Type w} [ForIn Id ρ ((a : α) × β a)] {l : ρ} :
m.val.insertMany l = m.insertMany l := by
simp [Raw.insertMany, m.2]

theorem ofList_eq [BEq α] [Hashable α] {l : List ((a : α) × β a)} :
Raw.ofList l = Raw₀.insertMany Raw₀.empty l := by
simp only [Raw.ofList, Raw.insertMany, (Raw.WF.empty).size_buckets_pos ∅, ↓reduceDIte]
congr

section

variable {β : Type v}

theorem Const.insertMany_eq [BEq α] [Hashable α] {m : Raw α (fun _ => β)} (h : m.WF) {ρ : Type w} [ForIn Id ρ (α × β)] {l : ρ} :
Raw.Const.insertMany m l = Raw₀.Const.insertMany ⟨m, h.size_buckets_pos⟩ l := by
simp [Raw.Const.insertMany, h.size_buckets_pos]

theorem Const.insertMany_val [BEq α][Hashable α] {m : Raw₀ α (fun _ => β)} {ρ : Type w} [ForIn Id ρ (α × β)] {l : ρ} :
Raw.Const.insertMany m.val l = Raw₀.Const.insertMany m l := by
simp [Raw.Const.insertMany, m.2]

theorem Const.ofList_eq [BEq α] [Hashable α] {l : List (α × β)} :
Raw.Const.ofList l = Raw₀.Const.insertMany Raw₀.empty l := by
simp only [Raw.Const.ofList, Raw.Const.insertMany, (Raw.WF.empty).size_buckets_pos ∅, ↓reduceDIte]
congr

theorem Const.insertManyIfNewUnit_eq {ρ : Type w} [ForIn Id ρ α] [BEq α] [Hashable α]
{m : Raw α (fun _ => Unit)} {l : ρ} (h : m.WF):
Raw.Const.insertManyIfNewUnit m l = Raw₀.Const.insertManyIfNewUnit ⟨m, h.size_buckets_pos⟩ l := by
simp [Raw.Const.insertManyIfNewUnit, h.size_buckets_pos]

theorem Const.insertManyIfNewUnit_val {ρ : Type w} [ForIn Id ρ α] [BEq α] [Hashable α]
{m : Raw₀ α (fun _ => Unit)} {l : ρ} :
Raw.Const.insertManyIfNewUnit m.val l = Raw₀.Const.insertManyIfNewUnit m l := by
simp [Raw.Const.insertManyIfNewUnit, m.2]

theorem Const.unitOfList_eq [BEq α] [Hashable α] {l : List α} :
Raw.Const.unitOfList l = Raw₀.Const.insertManyIfNewUnit Raw₀.empty l := by
simp only [Raw.Const.unitOfList, Raw.Const.insertManyIfNewUnit, (Raw.WF.empty).size_buckets_pos ∅,
↓reduceDIte]
congr

theorem Const.get?_eq [BEq α] [Hashable α] {m : Raw α (fun _ => β)} (h : m.WF) {a : α} :
Raw.Const.get? m a = Raw₀.Const.get? ⟨m, h.size_buckets_pos⟩ a := by
simp [Raw.Const.get?, h.size_buckets_pos]
Expand Down
Loading
Loading