-
Notifications
You must be signed in to change notification settings - Fork 441
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
base: master
Are you sure you want to change the base?
feat: verify insertMany method for adding lists to HashMaps #6211
Conversation
Mathlib CI status (docs):
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RawLemmas.lean
is looking pretty good now, you should be able to start adding the user-facing lemmas after addressing these final two style remarks, but please don't forget about #6211 (comment) (which GitHub unhelpfully doesn't show on the PR page...)
src/Std/Data/DHashMap/Lemmas.lean
Outdated
|
||
theorem size_ofList_le [EquivBEq α] [LawfulHashable α] | ||
{l : List (α × β)} : | ||
(ofList l).size ≤ l.length := by |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(ofList l).size ≤ l.length := by | |
(ofList l).size ≤ l.length := by |
src/Std/Data/DHashMap/Lemmas.lean
Outdated
congr | ||
|
||
theorem insertMany_cons {l : List ((a : α) × β a)} {k : α} {v : β k} : | ||
(m.insertMany (⟨k, v⟩ :: l)) = ((m.insert k v).insertMany l) := by |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(m.insertMany (⟨k, v⟩ :: l)) = ((m.insert k v).insertMany l) := by | |
m.insertMany (⟨k, v⟩ :: l) = (m.insert k v).insertMany l := by |
rw [Raw₀.insertMany_cons ⟨m.1, _⟩] | ||
rfl | ||
|
||
theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a good simp lemma to me.
(m.insertMany l).size ≤ m.size + l.length := | ||
Raw₀.size_insertMany_list_le ⟨m.1, _⟩ m.2 | ||
|
||
theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also a good simp
lemma.
src/Std/Data/DHashMap/Lemmas.lean
Outdated
apply Subtype.eq | ||
simp [insertMany] | ||
rw [Raw₀.Const.insertMany_cons ⟨m.1, _⟩] | ||
rfl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rfl | |
rfl | |
src/Std/Data/DHashMap/Lemmas.lean
Outdated
simp only [ofList] | ||
rw [get?_insertMany_list_of_contains_eq_false h] | ||
apply get?_emptyc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't love that you have multi-line proofs in DHashMap/Lemmas.lean
and DHashMap/RawLemmas.lean
, especially since the proofs are duplicated between the two files.
I think that you should prove things like
theorem size_insertMany_empty_list [EquivBEq α] [LawfulHashable α]
{l : List ((a : α) × β a)} (distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
((Raw₀.empty : Raw₀ α β).insertMany l).1.1.size = l.length := by
simp [size_insertMany_list _ Raw.WF.empty distinct]
in Internal/RawLemmas.lean
and invoke that from DHashMap/Lemmas.lean
and DHashMap/RawLemmas.lean
.
@@ -224,6 +225,21 @@ def containsKey [BEq α] (a : α) : List ((a : α) × β a) → Bool | |||
@[simp] theorem containsKey_cons [BEq α] {l : List ((a : α) × β a)} {k a : α} {v : β k} : | |||
containsKey a (⟨k, v⟩ :: l) = (k == a || containsKey a l) := rfl | |||
|
|||
theorem containsKey_eq_false_iff [BEq α][PartialEquivBEq α] {l : List ((a : α) × β a)} {a : α} : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can move this below containsKey_eq_false_if_forall_mem_keys
, then the proof is just
simp [containsKey_eq_false_iff_forall_mem_keys, keys_eq_map]
theorem DistinctKeys.def [BEq α] {l : List ((a : α) × β a)} : | ||
DistinctKeys l ↔ l.Pairwise (fun a b => (a.1 == b.1) = false) := | ||
⟨fun h => by simpa [keys_eq_map, List.pairwise_map] using h.distinct, | ||
fun h => ⟨by simpa [keys_eq_map, List.pairwise_map] using h⟩⟩ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fun h => ⟨by simpa [keys_eq_map, List.pairwise_map] using h⟩⟩ | |
fun h => ⟨by simpa [keys_eq_map, List.pairwise_map] using h⟩⟩ |
· rw [getEntry?_cons_of_true hk] | ||
· rw [getEntry?_cons_of_false, ih hl.tail hkv] | ||
exact BEq.neq_of_neq_of_beq (containsKey_eq_false_iff.1 hl.containsKey_eq_false _ hkv) hk | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .cons hd tl => insertListIfNewUnitₘ (m.insertIfNew hd ()) tl | |
| .cons hd tl => insertListIfNewUnitₘ (m.insertIfNew hd ()) tl | |
This PR verifies the
insertMany
method onHashMap
s for the special case of inserting lists.