feat: add intersection on DHashMap (#11112)
This PR adds intersection operation on `DHashMap`/`HashMap`/`HashSet` and provides several lemmas about its behaviour. --------- Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
This commit is contained in:
parent
1a4c3ca35d
commit
e35d65174c
19 changed files with 2978 additions and 51 deletions
|
|
@ -336,7 +336,18 @@ This function always merges the smaller map into the larger map, so the expected
|
|||
inner := Raw₀.union ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩
|
||||
wf := Std.DHashMap.Raw.WF.union₀ m₁.2 m₂.2
|
||||
|
||||
/--
|
||||
Computes the intersection of the given hash maps. The result will only contain entries from the first map.
|
||||
|
||||
This function always iterates through the smaller map, so the expected runtime is
|
||||
`O(min(m₁.size, m₂.size))`.
|
||||
-/
|
||||
@[inline] def inter [BEq α] [Hashable α] (m₁ m₂ : DHashMap α β) : DHashMap α β where
|
||||
inner := Raw₀.inter ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩
|
||||
wf := Std.DHashMap.Raw.WF.inter₀ m₁.2 m₂.2
|
||||
|
||||
instance [BEq α] [Hashable α] : Union (DHashMap α β) := ⟨union⟩
|
||||
instance [BEq α] [Hashable α] : Inter (DHashMap α β) := ⟨inter⟩
|
||||
|
||||
section Unverified
|
||||
|
||||
|
|
|
|||
|
|
@ -461,10 +461,25 @@ def insertMany {ρ : Type w} [ForIn Id ρ ((a : α) × β a)] [BEq α] [Hashable
|
|||
r := ⟨r.1.insertIfNew a b, fun _ h hm => h (r.2 _ h hm)⟩
|
||||
return r
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
@[inline]
|
||||
def interSmallerFn [BEq α] [Hashable α] (m sofar : Raw₀ α β) (k : α) : Raw₀ α β :=
|
||||
match m.getEntry? k with
|
||||
| some kv' => sofar.insert kv'.1 kv'.2
|
||||
| none => sofar
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
def interSmaller [BEq α] [Hashable α] (m₁ : Raw₀ α β) (m₂ : Raw α β) : Raw₀ α β :=
|
||||
(m₂.fold (fun sofar k _ => interSmallerFn m₁ sofar k) emptyWithCapacity)
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
@[inline] def union [BEq α] [Hashable α] (m₁ m₂ : Raw₀ α β) : Raw₀ α β :=
|
||||
if m₁.1.size ≤ m₂.1.size then (m₂.insertManyIfNew m₁.1).1 else (m₁.insertMany m₂.1).1
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
def inter [BEq α] [Hashable α] (m₁ m₂ : Raw₀ α β) : Raw₀ α β :=
|
||||
if m₁.1.size ≤ m₂.1.size then m₁.filter fun k _ => m₂.contains k else interSmaller m₁ m₂
|
||||
|
||||
section
|
||||
|
||||
variable {β : Type v}
|
||||
|
|
|
|||
|
|
@ -420,6 +420,12 @@ def unionₘ [BEq α] [Hashable α] (m₁ m₂ : Raw₀ α β) : Raw₀ α β :=
|
|||
else
|
||||
insertListₘ m₁ (toListModel m₂.1.buckets)
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
def interSmallerFnₘ [BEq α] [Hashable α] (m sofar : Raw₀ α β) (k : α) : Raw₀ α β :=
|
||||
match m.getEntry?ₘ k with
|
||||
| some kv' => sofar.insertₘ kv'.1 kv'.2
|
||||
| none => sofar
|
||||
|
||||
section
|
||||
|
||||
variable {β : Type v}
|
||||
|
|
@ -664,6 +670,14 @@ theorem insertManyIfNew_eq_insertListIfNewₘ [BEq α] [Hashable α] (m : Raw₀
|
|||
simp only [List.foldl_cons, insertListIfNewₘ]
|
||||
apply ih
|
||||
|
||||
theorem interSmallerFn_eq_interSmallerFnₘ [BEq α] [Hashable α] (m sofar : Raw₀ α β) (k : α) :
|
||||
interSmallerFn m sofar k = interSmallerFnₘ m sofar k := by
|
||||
rw [interSmallerFn, interSmallerFnₘ]
|
||||
rw [getEntry?_eq_getEntry?ₘ]
|
||||
congr
|
||||
ext
|
||||
rw [insert_eq_insertₘ]
|
||||
|
||||
section
|
||||
|
||||
variable {β : Type v}
|
||||
|
|
|
|||
|
|
@ -145,6 +145,10 @@ theorem union_eq [BEq α] [Hashable α] {m₁ m₂ : Raw α β} (h₁ : m₁.WF)
|
|||
m₁.union m₂ = Raw₀.union ⟨m₁, h₁.size_buckets_pos⟩ ⟨m₂, h₂.size_buckets_pos⟩ := by
|
||||
simp [Raw.union, h₁.size_buckets_pos, h₂.size_buckets_pos]
|
||||
|
||||
theorem inter_eq [BEq α] [Hashable α] {m₁ m₂ : Raw α β} (h₁ : m₁.WF) (h₂ : m₂.WF) :
|
||||
m₁.inter m₂ = Raw₀.inter ⟨m₁, h₁.size_buckets_pos⟩ ⟨m₂, h₂.size_buckets_pos⟩ := by
|
||||
simp [Raw.inter, h₁.size_buckets_pos, h₂.size_buckets_pos]
|
||||
|
||||
section
|
||||
|
||||
variable {β : Type v}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ macro_rules
|
|||
| apply Raw₀.wf_insertMany₀ | apply Raw₀.Const.wf_insertMany₀
|
||||
| apply Raw₀.Const.wf_insertManyIfNewUnit₀ | apply Raw₀.wf_union₀
|
||||
| apply Raw.WF.filter₀ | apply Raw₀.wf_map₀ | apply Raw₀.wf_filterMap₀
|
||||
| apply Raw.WF.emptyWithCapacity₀) <;> wf_trivial)
|
||||
| apply Raw.WF.emptyWithCapacity₀ | apply Raw.WF.inter₀) <;> wf_trivial)
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
scoped macro "empty" : tactic => `(tactic| { intros; simp_all [List.isEmpty_iff] } )
|
||||
|
|
@ -121,6 +121,7 @@ private meta def modifyMap : Std.DHashMap Name (fun _ => Name) :=
|
|||
⟨`insertIfNew, ``toListModel_insertIfNew⟩,
|
||||
⟨`insertMany, ``toListModel_insertMany_list⟩,
|
||||
⟨`union, ``toListModel_union⟩,
|
||||
⟨`inter, ``toListModel_inter⟩,
|
||||
⟨`Const.insertMany, ``Const.toListModel_insertMany_list⟩,
|
||||
⟨`Const.insertManyIfNewUnit, ``Const.toListModel_insertManyIfNewUnit_list⟩,
|
||||
⟨`alter, ``toListModel_alter⟩,
|
||||
|
|
@ -2708,14 +2709,14 @@ theorem get_union_of_contains_right [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ :
|
|||
revert contains_right
|
||||
simp_to_model [union, get, contains]
|
||||
intro contains_right
|
||||
apply List.getValueCast_insertList_of_contains_right
|
||||
apply getValueCast_insertList_of_contains_right
|
||||
all_goals wf_trivial
|
||||
|
||||
theorem get_union_of_contains_eq_false_left [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (contains_eq_false : m₁.contains k = false) {h'} :
|
||||
(m₁.union m₂).get k h' = m₂.get k (contains_of_contains_union_of_contains_eq_false_left h₁ h₂ h' contains_eq_false) := by
|
||||
revert contains_eq_false
|
||||
simp_to_model [union, contains, get] using List.getValueCast_insertList_of_contains_eq_false_left
|
||||
simp_to_model [union, contains, get] using getValueCast_insertList_of_contains_eq_false_left
|
||||
|
||||
theorem get_union_of_contains_eq_false_right [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (contains_eq_false : m₂.contains k = false) {h'} :
|
||||
|
|
@ -2739,7 +2740,7 @@ theorem getD_union_of_contains_eq_false_left [LawfulBEq α] (h₁ : m₁.val.WF)
|
|||
revert contains_eq_false
|
||||
simp_to_model [union, contains, getD]
|
||||
intro contains_eq_false
|
||||
apply List.getValueCastD_insertList_of_contains_eq_false_left
|
||||
apply getValueCastD_insertList_of_contains_eq_false_left
|
||||
all_goals wf_trivial
|
||||
|
||||
theorem getD_union_of_contains_eq_false_right [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
|
|
@ -2766,7 +2767,7 @@ theorem get!_union_of_contains_eq_false_left [LawfulBEq α] (h₁ : m₁.val.WF)
|
|||
revert contains_eq_false
|
||||
simp_to_model [union, contains, get!]
|
||||
intro contains_eq_false
|
||||
apply List.getValueCastD_insertList_of_contains_eq_false_left
|
||||
apply getValueCastD_insertList_of_contains_eq_false_left
|
||||
all_goals wf_trivial
|
||||
|
||||
theorem get!_union_of_contains_eq_false_right [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
|
|
@ -2816,7 +2817,7 @@ theorem getKey_union_of_contains_eq_false_left [EquivBEq α] [LawfulHashable α]
|
|||
{k : α} (contains_eq_false : m₁.contains k = false) {h'} :
|
||||
(m₁.union m₂).getKey k h' = m₂.getKey k (contains_of_contains_union_of_contains_eq_false_left h₁ h₂ h' contains_eq_false) := by
|
||||
revert contains_eq_false
|
||||
simp_to_model [union, contains, getKey] using List.getKey_insertList_of_contains_eq_false_left
|
||||
simp_to_model [union, contains, getKey] using getKey_insertList_of_contains_eq_false_left
|
||||
|
||||
theorem getKey_union_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (contains_eq_false : m₂.contains k = false) {h'} :
|
||||
|
|
@ -2841,7 +2842,7 @@ theorem getKeyD_union_of_contains_eq_false_left [EquivBEq α] [LawfulHashable α
|
|||
revert h'
|
||||
simp_to_model [contains, union, getKeyD]
|
||||
intro h'
|
||||
apply List.getKeyD_insertList_of_contains_eq_false_left
|
||||
apply getKeyD_insertList_of_contains_eq_false_left
|
||||
. wf_trivial
|
||||
. wf_trivial
|
||||
. exact h'
|
||||
|
|
@ -2852,7 +2853,7 @@ theorem getKeyD_union_of_contains_eq_false_right [EquivBEq α] [LawfulHashable
|
|||
revert h'
|
||||
simp_to_model [contains, union, getKeyD]
|
||||
intro h'
|
||||
apply List.getKeyD_insertList_of_contains_eq_false_right h'
|
||||
apply getKeyD_insertList_of_contains_eq_false_right h'
|
||||
|
||||
/- getKey! -/
|
||||
theorem getKey!_union [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
|
|
@ -2866,14 +2867,14 @@ theorem getKey!_union_of_contains_eq_false_left [Inhabited α]
|
|||
(h' : m₁.contains k = false) :
|
||||
(m₁.union m₂).getKey! k = m₂.getKey! k := by
|
||||
revert h'
|
||||
simp_to_model [getKey!, contains, union] using List.getKeyD_insertList_of_contains_eq_false_left
|
||||
simp_to_model [getKey!, contains, union] using getKeyD_insertList_of_contains_eq_false_left
|
||||
|
||||
theorem getKey!_union_of_contains_eq_false_right [Inhabited α]
|
||||
[EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF) {k : α}
|
||||
(h' : m₂.contains k = false) :
|
||||
(m₁.union m₂).getKey! k = m₁.getKey! k := by
|
||||
revert h'
|
||||
simp_to_model [contains, union, getKey!] using List.getKeyD_insertList_of_contains_eq_false_right
|
||||
simp_to_model [contains, union, getKey!] using getKeyD_insertList_of_contains_eq_false_right
|
||||
|
||||
/- size -/
|
||||
theorem size_union_of_not_mem [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF)
|
||||
|
|
@ -2899,6 +2900,7 @@ theorem size_union_le_size_add_size [EquivBEq α] [LawfulHashable α]
|
|||
theorem isEmpty_union [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF) :
|
||||
(m₁.union m₂).1.isEmpty = (m₁.1.isEmpty && m₂.1.isEmpty) := by
|
||||
simp_to_model [isEmpty, union] using List.isEmpty_insertList
|
||||
|
||||
end Union
|
||||
|
||||
namespace Const
|
||||
|
|
@ -2908,13 +2910,13 @@ variable {β : Type v} {m₁ m₂ : Raw₀ α (fun _ => β)}
|
|||
/- get? -/
|
||||
theorem get?_union [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF) {k : α} :
|
||||
Const.get? (m₁.union m₂) k = (Const.get? m₂ k).or (Const.get? m₁ k) := by
|
||||
simp_to_model [union, Const.get?] using List.getValue?_insertList
|
||||
simp_to_model [union, Const.get?] using getValue?_insertList
|
||||
|
||||
theorem get?_union_of_contains_eq_false_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (contains_eq_false : m₁.contains k = false) :
|
||||
Const.get? (m₁.union m₂) k = Const.get? m₂ k := by
|
||||
revert contains_eq_false
|
||||
simp_to_model [union, contains, Const.get?] using List.getValue?_insertList_of_contains_eq_false_left
|
||||
simp_to_model [union, contains, Const.get?] using getValue?_insertList_of_contains_eq_false_left
|
||||
|
||||
theorem get?_union_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (contains_eq_false : m₂.contains k = false) :
|
||||
|
|
@ -2922,7 +2924,7 @@ theorem get?_union_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α]
|
|||
revert contains_eq_false
|
||||
simp_to_model [union, Const.get?, contains]
|
||||
intro contains_eq_false
|
||||
apply List.getValue?_insertList_of_contains_eq_false_right contains_eq_false
|
||||
apply getValue?_insertList_of_contains_eq_false_right contains_eq_false
|
||||
|
||||
/- get -/
|
||||
theorem get_union_of_contains_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
|
|
@ -2931,14 +2933,14 @@ theorem get_union_of_contains_right [EquivBEq α] [LawfulHashable α] (h₁ : m
|
|||
revert h
|
||||
simp_to_model [union, contains, Const.get]
|
||||
intro h
|
||||
apply List.getValue_insertList_of_contains_right
|
||||
apply getValue_insertList_of_contains_right
|
||||
all_goals wf_trivial
|
||||
|
||||
theorem get_union_of_contains_eq_false_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (contains_eq_false : m₁.contains k = false) {h'} :
|
||||
Const.get (m₁.union m₂) k h' = Const.get m₂ k (contains_of_contains_union_of_contains_eq_false_left h₁ h₂ h' contains_eq_false) := by
|
||||
revert contains_eq_false
|
||||
simp_to_model [union, contains, Const.get] using List.getValue_insertList_of_contains_eq_false_left
|
||||
simp_to_model [union, contains, Const.get] using getValue_insertList_of_contains_eq_false_left
|
||||
|
||||
theorem get_union_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (contains_eq_false : m₂.contains k = false) {h'} :
|
||||
|
|
@ -2946,7 +2948,7 @@ theorem get_union_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α] (
|
|||
revert contains_eq_false
|
||||
simp_to_model [union, Const.get, contains]
|
||||
intro contains_eq_false
|
||||
apply List.getValue_insertList_of_contains_eq_false_right contains_eq_false
|
||||
apply getValue_insertList_of_contains_eq_false_right contains_eq_false
|
||||
|
||||
/- getD -/
|
||||
theorem getD_union [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF) {k : α} {fallback : β} :
|
||||
|
|
@ -2957,7 +2959,7 @@ theorem getD_union_of_contains_eq_false_left [EquivBEq α] [LawfulHashable α] (
|
|||
{k : α} {fallback : β} (contains_eq_false : m₁.contains k = false) :
|
||||
Const.getD (m₁.union m₂) k fallback = Const.getD m₂ k fallback := by
|
||||
revert contains_eq_false
|
||||
simp_to_model [union, contains, Const.getD] using List.getValueD_insertList_of_contains_eq_false_left
|
||||
simp_to_model [union, contains, Const.getD] using getValueD_insertList_of_contains_eq_false_left
|
||||
|
||||
theorem getD_union_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} {fallback : β} (contains_eq_false : m₂.contains k = false) :
|
||||
|
|
@ -2965,7 +2967,7 @@ theorem getD_union_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α]
|
|||
revert contains_eq_false
|
||||
simp_to_model [union, Const.getD, contains]
|
||||
intro contains_eq_false
|
||||
apply List.getValueD_insertList_of_contains_eq_false_right contains_eq_false
|
||||
apply getValueD_insertList_of_contains_eq_false_right contains_eq_false
|
||||
|
||||
/- get! -/
|
||||
theorem get!_union [EquivBEq α] [LawfulHashable α] [Inhabited β] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF) {k : α} :
|
||||
|
|
@ -2976,7 +2978,7 @@ theorem get!_union_of_contains_eq_false_left [EquivBEq α] [LawfulHashable α] [
|
|||
{k : α} (contains_eq_false : m₁.contains k = false) :
|
||||
Const.get! (m₁.union m₂) k = Const.get! m₂ k := by
|
||||
revert contains_eq_false
|
||||
simp_to_model [union, contains, Const.get!] using List.getValueD_insertList_of_contains_eq_false_left
|
||||
simp_to_model [union, contains, Const.get!] using getValueD_insertList_of_contains_eq_false_left
|
||||
|
||||
theorem get!_union_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α] [Inhabited β] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (contains_eq_false : m₂.contains k = false) :
|
||||
|
|
@ -2984,7 +2986,334 @@ theorem get!_union_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α]
|
|||
revert contains_eq_false
|
||||
simp_to_model [union, Const.get!, contains]
|
||||
intro contains_eq_false
|
||||
apply List.getValueD_insertList_of_contains_eq_false_right contains_eq_false
|
||||
apply getValueD_insertList_of_contains_eq_false_right contains_eq_false
|
||||
|
||||
end Const
|
||||
|
||||
section Inter
|
||||
|
||||
variable {m₁ m₂ : Raw₀ α β}
|
||||
|
||||
/- contains -/
|
||||
theorem contains_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF)
|
||||
(h₂ : m₂.val.WF) {k : α} :
|
||||
(m₁.inter m₂).contains k = (m₁.contains k && m₂.contains k) := by
|
||||
simp_to_model [contains, inter] using List.containsKey_filter_containsKey
|
||||
|
||||
theorem contains_inter_iff [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF)
|
||||
(h₂ : m₂.val.WF) {k : α} :
|
||||
(m₁.inter m₂).contains k ↔ m₁.contains k ∧ m₂.contains k := by
|
||||
simp_to_model [inter, contains] using containsKey_filter_containsKey_iff
|
||||
|
||||
theorem contains_inter_eq_false_of_contains_eq_false_left [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.val.WF) (h₂ : m₂.val.WF) {k : α}
|
||||
(h : m₁.contains k = false) :
|
||||
(m₁.inter m₂).contains k = false := by
|
||||
revert h
|
||||
simp_to_model [inter, contains] using containsKey_filter_containsKey_eq_false_of_containsKey_eq_false_left
|
||||
|
||||
theorem contains_inter_eq_false_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.val.WF) (h₂ : m₂.val.WF) {k : α}
|
||||
(h : m₂.contains k = false) :
|
||||
(m₁.inter m₂).contains k = false := by
|
||||
revert h
|
||||
simp_to_model [inter, contains] using containsKey_filter_containsKey_eq_false_of_containsKey_eq_false_right
|
||||
|
||||
/- get? -/
|
||||
theorem get?_inter [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF) {k : α} :
|
||||
(m₁.inter m₂).get? k =
|
||||
if m₂.contains k then m₁.get? k else none := by
|
||||
simp_to_model [inter, get?, contains] using getValueCast?_filter_containsKey
|
||||
|
||||
theorem get?_inter_of_contains_right [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (h : m₂.contains k) :
|
||||
(m₁.inter m₂).get? k = m₁.get? k := by
|
||||
revert h
|
||||
simp_to_model [inter, get?, contains] using getValueCast?_filter_containsKey_of_containsKey_right
|
||||
|
||||
theorem get?_inter_of_contains_eq_false_left [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (h : m₁.contains k = false) :
|
||||
(m₁.inter m₂).get? k = none := by
|
||||
revert h
|
||||
simp_to_model [inter, get?, contains] using getValueCast?_filter_containsKey_of_containsKey_eq_false_left
|
||||
|
||||
theorem get?_inter_of_contains_eq_false_right [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (h : m₂.contains k = false) :
|
||||
(m₁.inter m₂).get? k = none := by
|
||||
revert h
|
||||
simp_to_model [inter, get?, contains] using getValueCast?_filter_containsKey_of_containsKey_eq_false_right
|
||||
|
||||
/- get -/
|
||||
@[simp] theorem get_inter [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} {h_contains : (m₁.inter m₂).contains k} :
|
||||
(m₁.inter m₂).get k h_contains =
|
||||
m₁.get k ((contains_inter_iff h₁ h₂).1 h_contains).1 := by
|
||||
simp_to_model [inter, get, contains] using getValueCast_filter_containsKey
|
||||
|
||||
/- getD -/
|
||||
theorem getD_inter [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} {fallback : β k} :
|
||||
(m₁.inter m₂).getD k fallback =
|
||||
if m₂.contains k then m₁.getD k fallback else fallback := by
|
||||
simp_to_model [inter, getD, contains] using getValueCastD_filter_containsKey
|
||||
|
||||
theorem getD_inter_of_contains_right [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} {fallback : β k} (h : m₂.contains k) :
|
||||
(m₁.inter m₂).getD k fallback = m₁.getD k fallback := by
|
||||
revert h
|
||||
simp_to_model [inter, getD, contains] using getValueCastD_filter_containsKey_of_containsKey_right
|
||||
|
||||
theorem getD_inter_of_contains_eq_false_right [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} {fallback : β k} (h : m₂.contains k = false) :
|
||||
(m₁.inter m₂).getD k fallback = fallback := by
|
||||
revert h
|
||||
simp_to_model [inter, getD, contains] using getValueCastD_filter_containsKey_of_containsKey_eq_false_right
|
||||
|
||||
theorem getD_inter_of_contains_eq_false_left [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} {fallback : β k} (h : m₁.contains k = false) :
|
||||
(m₁.inter m₂).getD k fallback = fallback := by
|
||||
revert h
|
||||
simp_to_model [inter, getD, contains] using getValueCastD_filter_containsKey_of_containsKey_eq_false_left
|
||||
|
||||
/- get! -/
|
||||
theorem get!_inter [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} [Inhabited (β k)] :
|
||||
(m₁.inter m₂).get! k =
|
||||
if m₂.contains k then m₁.get! k else default := by
|
||||
simp_to_model [inter, get!, contains] using getValueCastD_filter_containsKey
|
||||
|
||||
theorem get!_inter_of_contains_right [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} [Inhabited (β k)] (h : m₂.contains k) :
|
||||
(m₁.inter m₂).get! k = m₁.get! k := by
|
||||
revert h
|
||||
simp_to_model [inter, get!, contains] using getValueCastD_filter_containsKey_of_containsKey_right
|
||||
|
||||
theorem get!_inter_of_contains_eq_false_right [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} [Inhabited (β k)] (h : m₂.contains k = false) :
|
||||
(m₁.inter m₂).get! k = default := by
|
||||
revert h
|
||||
simp_to_model [inter, get!, contains] using getValueCastD_filter_containsKey_of_containsKey_eq_false_right
|
||||
|
||||
theorem get!_inter_of_contains_eq_false_left [LawfulBEq α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} [Inhabited (β k)] (h : m₁.contains k = false) :
|
||||
(m₁.inter m₂).get! k = default := by
|
||||
revert h
|
||||
simp_to_model [inter, get!, contains] using getValueCastD_filter_containsKey_of_containsKey_eq_false_left
|
||||
|
||||
/- getKey? -/
|
||||
theorem getKey?_inter [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.val.WF) (h₂ : m₂.val.WF) {k : α} :
|
||||
(m₁.inter m₂).getKey? k =
|
||||
if m₂.contains k then m₁.getKey? k else none := by
|
||||
simp_to_model [inter, contains, getKey?] using getKey?_filter_containsKey
|
||||
|
||||
theorem getKey?_inter_of_contains_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.val.WF) (h₂ : m₂.val.WF) {k : α} (h : m₂.contains k) :
|
||||
(m₁.inter m₂).getKey? k = m₁.getKey? k := by
|
||||
revert h
|
||||
simp_to_model [contains, getKey?, inter] using getKey?_filter_containsKey_of_containsKey_right
|
||||
|
||||
theorem getKey?_inter_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.val.WF) (h₂ : m₂.val.WF) {k : α} (h : m₂.contains k = false) :
|
||||
(m₁.inter m₂).getKey? k = none := by
|
||||
revert h
|
||||
simp_to_model [contains, getKey?, inter] using getKey?_filter_containsKey_of_containsKey_eq_false_right
|
||||
|
||||
theorem getKey?_inter_of_contains_eq_false_left [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.val.WF) (h₂ : m₂.val.WF) {k : α} (h : m₁.contains k = false) :
|
||||
(m₁.inter m₂).getKey? k = none := by
|
||||
revert h
|
||||
simp_to_model [contains, getKey?, inter] using getKey?_filter_containsKey_of_containsKey_eq_false_left
|
||||
|
||||
/- getKey -/
|
||||
@[simp] theorem getKey_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} {h_contains : (m₁.inter m₂).contains k} :
|
||||
(m₁.inter m₂).getKey k h_contains =
|
||||
m₁.getKey k (by simp [contains_inter_iff h₁ h₂] at h_contains; exact h_contains.1) := by
|
||||
simp_to_model [inter, contains, getKey] using getKey_filter_containsKey
|
||||
|
||||
/- getKeyD -/
|
||||
theorem getKeyD_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF)
|
||||
(h₂ : m₂.val.WF) {k fallback : α} :
|
||||
(m₁.inter m₂).getKeyD k fallback =
|
||||
if m₂.contains k then m₁.getKeyD k fallback else fallback := by
|
||||
simp_to_model [inter, getKeyD, contains] using getKeyD_filter_containsKey
|
||||
|
||||
theorem getKeyD_inter_of_contains_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF)
|
||||
(h₂ : m₂.val.WF) {k fallback : α} (h : m₂.contains k) :
|
||||
(m₁.inter m₂).getKeyD k fallback = m₁.getKeyD k fallback := by
|
||||
revert h
|
||||
simp_to_model [inter, getKeyD, contains] using getKeyD_filter_containsKey_of_containsKey_right
|
||||
|
||||
theorem getKeyD_inter_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF)
|
||||
(h₂ : m₂.val.WF) {k fallback : α} (h : m₂.contains k = false) :
|
||||
(m₁.inter m₂).getKeyD k fallback = fallback := by
|
||||
revert h
|
||||
simp_to_model [inter, getKeyD, contains] using getKeyD_filter_containsKey_of_containsKey_eq_false_right
|
||||
|
||||
theorem getKeyD_inter_of_contains_eq_false_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF)
|
||||
(h₂ : m₂.val.WF) {k fallback : α} (h : m₁.contains k = false) :
|
||||
(m₁.inter m₂).getKeyD k fallback = fallback := by
|
||||
revert h
|
||||
simp_to_model [inter, getKeyD, contains] using getKeyD_filter_containsKey_of_containsKey_eq_false_left
|
||||
|
||||
/- getKey! -/
|
||||
theorem getKey!_inter [EquivBEq α] [LawfulHashable α] [Inhabited α] (h₁ : m₁.val.WF)
|
||||
(h₂ : m₂.val.WF) {k : α} [Inhabited α] :
|
||||
(m₁.inter m₂).getKey! k =
|
||||
if m₂.contains k then m₁.getKey! k else default := by
|
||||
simp_to_model [inter, getKey!, contains] using getKeyD_filter_containsKey
|
||||
|
||||
theorem getKey!_inter_of_contains_right [EquivBEq α] [LawfulHashable α] [Inhabited α] (h₁ : m₁.val.WF)
|
||||
(h₂ : m₂.val.WF) {k : α} (h : m₂.contains k) :
|
||||
(m₁.inter m₂).getKey! k = m₁.getKey! k := by
|
||||
revert h
|
||||
simp_to_model [inter, getKey!, contains] using getKeyD_filter_containsKey_of_containsKey_right
|
||||
|
||||
theorem getKey!_inter_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α] [Inhabited α] (h₁ : m₁.val.WF)
|
||||
(h₂ : m₂.val.WF) {k : α} (h : m₂.contains k = false) :
|
||||
(m₁.inter m₂).getKey! k = default := by
|
||||
revert h
|
||||
simp_to_model [inter, getKey!, contains] using getKeyD_filter_containsKey_of_containsKey_eq_false_right
|
||||
|
||||
theorem getKey!_inter_of_contains_eq_false_left [EquivBEq α] [LawfulHashable α] [Inhabited α] (h₁ : m₁.val.WF)
|
||||
(h₂ : m₂.val.WF) {k : α} (h : m₁.contains k = false) :
|
||||
(m₁.inter m₂).getKey! k = default := by
|
||||
revert h
|
||||
simp_to_model [inter, getKey!, contains] using getKeyD_filter_containsKey_of_containsKey_eq_false_left
|
||||
|
||||
/- size -/
|
||||
theorem size_inter_le_size_left [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.val.WF) (h₂ : m₂.val.WF) :
|
||||
(m₁.inter m₂).1.size ≤ m₁.1.size := by
|
||||
simp_to_model [inter, size] using List.length_filter_le
|
||||
|
||||
theorem size_inter_le_size_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.val.WF) (h₂ : m₂.val.WF) :
|
||||
(m₁.inter m₂).1.size ≤ m₂.1.size := by
|
||||
simp_to_model [inter, size, contains] using List.length_filter_containsKey_le
|
||||
|
||||
theorem size_inter_eq_size_left [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
(h : ∀ (a : α), m₁.contains a → m₂.contains a) :
|
||||
(m₁.inter m₂).1.size = m₁.1.size := by
|
||||
revert h
|
||||
simp_to_model [inter, size, contains] using length_filter_containsKey_eq_length_left
|
||||
|
||||
theorem size_inter_eq_size_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
(h : ∀ (a : α), m₂.contains a → m₁.contains a) :
|
||||
(m₁.inter m₂).1.size = m₂.1.size := by
|
||||
revert h
|
||||
simp_to_model [inter, size, contains] using length_filter_containsKey_of_length_right
|
||||
|
||||
theorem size_add_size_eq_size_union_add_size_inter [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.val.WF) (h₂ : m₂.val.WF) :
|
||||
m₁.1.size + m₂.1.size = (m₁.union m₂).1.size + (m₁.inter m₂).1.size := by
|
||||
simp_to_model [union, inter, size] using size_add_size_eq_size_insertList_add_size_filter_containsKey
|
||||
|
||||
/- isEmpty -/
|
||||
@[simp]
|
||||
theorem isEmpty_inter_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF) (h : m₁.1.isEmpty) :
|
||||
(m₁.inter m₂).1.isEmpty = true := by
|
||||
revert h
|
||||
simp_to_model [isEmpty, inter, contains] using List.isEmpty_filter_containsKey_left
|
||||
|
||||
/- isEmpty -/
|
||||
@[simp]
|
||||
theorem isEmpty_inter_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF) (h : m₂.1.isEmpty) :
|
||||
(m₁.inter m₂).1.isEmpty = true := by
|
||||
revert h
|
||||
simp_to_model [isEmpty, inter, contains] using List.isEmpty_filter_containsKey_right
|
||||
|
||||
theorem isEmpty_inter_iff [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF) :
|
||||
(m₁.inter m₂).1.isEmpty ↔ ∀ k, m₁.contains k → m₂.contains k = false := by
|
||||
simp_to_model [inter, contains, isEmpty] using List.isEmpty_filter_containsKey_iff
|
||||
|
||||
end Inter
|
||||
namespace Const
|
||||
|
||||
variable {β : Type v} {m₁ m₂ : Raw₀ α (fun _ => β)}
|
||||
|
||||
/- get? -/
|
||||
theorem get?_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF) {k : α} :
|
||||
Const.get? (m₁.inter m₂) k =
|
||||
if m₂.contains k then Const.get? m₁ k else none := by
|
||||
simp_to_model [inter, Const.get?, contains] using List.getValue?_filter_containsKey
|
||||
|
||||
theorem get?_inter_of_contains_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (h : m₂.contains k) :
|
||||
Const.get? (m₁.inter m₂) k = Const.get? m₁ k := by
|
||||
revert h
|
||||
simp_to_model [inter, Const.get?, contains] using List.getValue?_filter_containsKey_of_containsKey_right
|
||||
|
||||
theorem get?_inter_of_contains_eq_false_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (h : m₁.contains k = false) :
|
||||
Const.get? (m₁.inter m₂) k = none := by
|
||||
revert h
|
||||
simp_to_model [inter, Const.get?, contains] using List.getValue?_filter_containsKey_of_containsKey_eq_false_left
|
||||
|
||||
theorem get?_inter_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (h : m₂.contains k = false) :
|
||||
Const.get? (m₁.inter m₂) k = none := by
|
||||
revert h
|
||||
simp_to_model [inter, Const.get?, contains] using getValue?_filter_containsKey_of_containsKey_eq_false_right
|
||||
|
||||
@[simp] theorem get_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} {h_contains : (m₁.inter m₂).contains k} :
|
||||
Const.get (m₁.inter m₂) k h_contains =
|
||||
Const.get m₁ k ((contains_inter_iff h₁ h₂).1 h_contains).1 := by
|
||||
simp_to_model [inter, Const.get, contains] using List.getValue_filter_containsKey
|
||||
|
||||
/- getD -/
|
||||
theorem getD_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} {fallback : β} :
|
||||
Const.getD (m₁.inter m₂) k fallback =
|
||||
if m₂.contains k then Const.getD m₁ k fallback else fallback := by
|
||||
simp_to_model [inter, Const.getD, contains] using List.getValueD_filter_containsKey
|
||||
|
||||
theorem getD_inter_of_contains_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} {fallback : β} (h : m₂.contains k) :
|
||||
Const.getD (m₁.inter m₂) k fallback = Const.getD m₁ k fallback := by
|
||||
revert h
|
||||
simp_to_model [inter, Const.getD, contains] using List.getValueD_filter_containsKey_of_containsKey_right
|
||||
|
||||
theorem getD_inter_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} {fallback : β} (h : m₂.contains k = false) :
|
||||
Const.getD (m₁.inter m₂) k fallback = fallback := by
|
||||
revert h
|
||||
simp_to_model [inter, Const.getD, contains] using getValueD_filter_containsKey_of_containsKey_eq_false_right
|
||||
|
||||
theorem getD_inter_of_contains_eq_false_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} {fallback : β} (h : m₁.contains k = false) :
|
||||
Const.getD (m₁.inter m₂) k fallback = fallback := by
|
||||
revert h
|
||||
simp_to_model [inter, Const.getD, contains] using getValueD_filter_containsKey_of_containsKey_eq_false_left
|
||||
|
||||
/- get! -/
|
||||
theorem get!_inter [EquivBEq α] [LawfulHashable α] [Inhabited β] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} :
|
||||
Const.get! (m₁.inter m₂) k =
|
||||
if m₂.contains k then Const.get! m₁ k else default := by
|
||||
simp_to_model [inter, Const.get!, contains] using List.getValueD_filter_containsKey
|
||||
|
||||
theorem get!_inter_of_contains_right [EquivBEq α] [LawfulHashable α] [Inhabited β] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (h : m₂.contains k) :
|
||||
Const.get! (m₁.inter m₂) k = Const.get! m₁ k := by
|
||||
revert h
|
||||
simp_to_model [inter, Const.get!, contains] using List.getValueD_filter_containsKey_of_containsKey_right
|
||||
|
||||
theorem get!_inter_of_contains_eq_false_right [EquivBEq α] [LawfulHashable α] [Inhabited β] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (h : m₂.contains k = false) :
|
||||
Const.get! (m₁.inter m₂) k = default := by
|
||||
revert h
|
||||
simp_to_model [inter, Const.get!, contains] using getValueD_filter_containsKey_of_containsKey_eq_false_right
|
||||
|
||||
theorem get!_inter_of_contains_eq_false_left [EquivBEq α] [LawfulHashable α] [Inhabited β] (h₁ : m₁.val.WF) (h₂ : m₂.val.WF)
|
||||
{k : α} (h : m₁.contains k = false) :
|
||||
Const.get! (m₁.inter m₂) k = default := by
|
||||
revert h
|
||||
simp_to_model [inter, Const.get!, contains] using getValueD_filter_containsKey_of_containsKey_eq_false_left
|
||||
|
||||
end Const
|
||||
|
||||
|
|
|
|||
|
|
@ -167,6 +167,23 @@ theorem foldM_eq_foldlM_toListModel {δ : Type w} {m : Type w → Type w'} [Mona
|
|||
funext init'
|
||||
rw [ih]
|
||||
|
||||
theorem fold_induction {δ : Type w}
|
||||
{f : δ → (a : α) → β a → δ} {init : δ} {b : Raw α β} {P : δ → Prop}
|
||||
(base : P init) (step : ∀ acc a b , P acc → P (f acc a b)) :
|
||||
P (b.fold f init) := by
|
||||
simp [Raw.fold, Raw.foldM, ← Array.foldlM_toList]
|
||||
induction b.buckets.toList generalizing init with
|
||||
| nil => simp [base]
|
||||
| cons hd tl ih =>
|
||||
apply ih
|
||||
induction hd generalizing init with
|
||||
| nil => simp [AssocList.foldlM, pure, base]
|
||||
| cons hda hdb tl ih =>
|
||||
simp only [AssocList.foldlM, pure_bind]
|
||||
apply ih
|
||||
apply step
|
||||
exact base
|
||||
|
||||
theorem fold_eq_foldl_toListModel {l : Raw α β} {f : γ → (a : α) → β a → γ} {init : γ} :
|
||||
l.fold f init = (toListModel l.buckets).foldl (fun a b => f a b.1 b.2) init := by
|
||||
simp [Raw.fold, foldM_eq_foldlM_toListModel]
|
||||
|
|
@ -1107,7 +1124,6 @@ theorem insertMany_eq_insertListₘ_toListModel [BEq α] [Hashable α] (m m₂ :
|
|||
simp only [List.foldl_cons, insertListₘ]
|
||||
apply ih
|
||||
|
||||
|
||||
theorem insertManyIfNew_eq_insertListIfNewₘ_toListModel [BEq α] [Hashable α] (m m₂ : Raw₀ α β) :
|
||||
insertManyIfNew m m₂.1 = insertListIfNewₘ m (toListModel m₂.1.buckets) := by
|
||||
simp only [insertManyIfNew, bind_pure_comp, map_pure, bind_pure]
|
||||
|
|
@ -1142,6 +1158,20 @@ theorem toListModel_unionₘ [BEq α] [Hashable α] [EquivBEq α] [LawfulHashabl
|
|||
· exact toListModel_insertListIfNewₘ ‹_›
|
||||
· exact toListModel_insertListₘ ‹_›
|
||||
|
||||
theorem wfImp_inter [BEq α] [EquivBEq α] [Hashable α] [LawfulHashable α]
|
||||
{m₁ m₂ : Raw α β} {h₁ : 0 < m₁.buckets.size} {h₂ : 0 < m₂.buckets.size} (wh₁ : Raw.WFImp m₁) :
|
||||
Raw.WFImp (Raw₀.inter ⟨m₁, h₁⟩ ⟨m₂, h₂⟩).val := by
|
||||
rw [inter]
|
||||
split
|
||||
· apply wfImp_filter wh₁
|
||||
· rw [interSmaller]
|
||||
apply @Raw.fold_induction _ β _ (fun sofar k x => interSmallerFn ⟨m₁, h₁⟩ sofar k) emptyWithCapacity m₂ (Raw.WFImp ·.val) wfImp_emptyWithCapacity
|
||||
intro acc a b wf
|
||||
rw [interSmallerFn]
|
||||
split
|
||||
· apply wfImp_insert wf
|
||||
· apply wf
|
||||
|
||||
end Raw₀
|
||||
|
||||
namespace Raw
|
||||
|
|
@ -1163,6 +1193,7 @@ theorem WF.out [BEq α] [Hashable α] [i₁ : EquivBEq α] [i₂ : LawfulHashabl
|
|||
| constModify₀ _ h => exact Raw₀.Const.wfImp_modify (by apply h)
|
||||
| alter₀ _ h => exact Raw₀.wfImp_alter (by apply h)
|
||||
| constAlter₀ _ h => exact Raw₀.Const.wfImp_alter (by apply h)
|
||||
| inter₀ _ _ h _ => exact Raw₀.wfImp_inter (by apply h)
|
||||
|
||||
end Raw
|
||||
|
||||
|
|
@ -1312,6 +1343,7 @@ theorem wf_union₀ [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α]
|
|||
· exact wf_insertManyIfNew₀ ‹_›
|
||||
· exact wf_insertMany₀ ‹_›
|
||||
|
||||
|
||||
theorem toListModel_union [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α] {m₁ m₂ : Raw₀ α β}
|
||||
(h₁ : Raw.WFImp m₁.1) (h₂ : Raw.WFImp m₂.1) :
|
||||
Perm (toListModel (m₁.union m₂).1.buckets)
|
||||
|
|
@ -1319,6 +1351,76 @@ theorem toListModel_union [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable
|
|||
rw [union_eq_unionₘ]
|
||||
exact toListModel_unionₘ h₁ h₂
|
||||
|
||||
|
||||
/-! # `inter` -/
|
||||
|
||||
theorem wfImp_interSmallerFnₘ [BEq α] [EquivBEq α] [Hashable α] [LawfulHashable α] (m₁ : Raw₀ α β) (m₂ : Raw₀ α β)
|
||||
(hm₂ : Raw.WFImp m₂.1) (k : α) : Raw.WFImp (m₁.interSmallerFnₘ m₂ k).1 := by
|
||||
rw [interSmallerFnₘ]
|
||||
split
|
||||
· exact wfImp_insertₘ hm₂
|
||||
· exact hm₂
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
def interSmallerₘ [BEq α] [Hashable α] (m₁ : Raw₀ α β) (m₂ : Raw α β) : Raw₀ α β :=
|
||||
m₂.fold (fun sofar k _ => interSmallerFnₘ m₁ sofar k) emptyWithCapacity
|
||||
|
||||
theorem interSmaller_eq_interSmallerₘ [BEq α] [Hashable α] (m₁ : Raw₀ α β) (m₂ : Raw α β) :
|
||||
m₁.interSmaller m₂ = m₁.interSmallerₘ m₂ := by
|
||||
rw [interSmaller, interSmallerₘ]
|
||||
simp only [interSmallerFn_eq_interSmallerFnₘ]
|
||||
|
||||
theorem foldl_perm_cong [BEq α] {init₁ init₂ : List ((a : α) × β a)} {l : List ((a : α) × β a)}
|
||||
{f : List ((a : α) × β a) → ((a : α) × β a) → List ((a : α) × β a)} (h₁ : Perm init₁ init₂)
|
||||
(h₂ : ∀ h l₁ l₂, (w : DistinctKeys l₁) → Perm l₁ l₂ → Perm (f l₁ h) (f l₂ h) ∧ DistinctKeys (f l₁ h))
|
||||
(h₃ : DistinctKeys init₁)
|
||||
: Perm (List.foldl f init₁ l) (List.foldl f init₂ l) := by
|
||||
induction l generalizing init₁ init₂
|
||||
case nil =>
|
||||
simp only [foldl_nil, h₁]
|
||||
case cons h t ih =>
|
||||
simp only [foldl_cons]
|
||||
apply ih
|
||||
· exact (h₂ h init₁ init₂ h₃ h₁).1
|
||||
· exact (h₂ h init₁ init₂ h₃ h₁).2
|
||||
|
||||
theorem toListModel_interSmallerFnₘ [BEq α] [EquivBEq α] [Hashable α] [LawfulHashable α] (m sofar : Raw₀ α β)
|
||||
(l : List ((a : α) × β a))
|
||||
(hm : Raw.WFImp m.1) (hs : Raw.WFImp sofar.1) (k : α) (hml : toListModel sofar.1.buckets ~ l) :
|
||||
Perm (toListModel ((interSmallerFnₘ m sofar k).1.buckets))
|
||||
(List.interSmallerFn (toListModel m.1.buckets) l k) := by
|
||||
rw [interSmallerFnₘ, getEntry?ₘ_eq_getEntry? hm, List.interSmallerFn]
|
||||
split
|
||||
· simpa [*] using (toListModel_insertₘ hs).trans (List.insertEntry_of_perm hs.distinct hml)
|
||||
· simp [*]
|
||||
|
||||
theorem toListModel_interSmallerₘ [BEq α] [EquivBEq α] [Hashable α] [LawfulHashable α]
|
||||
(m₁ : Raw₀ α β) (m₂ : Raw α β) (hm₁ : Raw.WFImp m₁.1) :
|
||||
toListModel (m₁.interSmallerₘ m₂).1.buckets ~
|
||||
List.interSmaller (toListModel m₁.1.buckets) (toListModel m₂.buckets) := by
|
||||
rw [interSmallerₘ, Raw.fold_eq_foldl_toListModel, List.interSmaller]
|
||||
generalize toListModel m₂.buckets = l
|
||||
suffices ∀ m l', Raw.WFImp m.1 → toListModel m.1.buckets ~ l' → toListModel (foldl (fun a b => m₁.interSmallerFnₘ a b.fst) m l).val.buckets ~
|
||||
foldl (fun sofar kv => List.interSmallerFn (toListModel m₁.val.buckets) sofar kv.fst) l' l by
|
||||
simpa using this emptyWithCapacity [] wfImp_emptyWithCapacity (by simp)
|
||||
intro m l' hm hml'
|
||||
induction l generalizing m l' with
|
||||
| nil => simpa
|
||||
| cons ht tl ih =>
|
||||
rw [List.foldl_cons, List.foldl_cons]
|
||||
exact ih _ _ (wfImp_interSmallerFnₘ _ _ hm _) (toListModel_interSmallerFnₘ _ _ _ hm₁ hm _ hml')
|
||||
|
||||
theorem toListModel_inter [BEq α] [EquivBEq α] [Hashable α] [LawfulHashable α] (m₁ m₂ : Raw₀ α β) (hm₁ : Raw.WFImp m₁.1) (hm₂ : Raw.WFImp m₂.1) :
|
||||
Perm (toListModel (m₁.inter m₂).1.buckets) ((toListModel m₁.1.buckets).filter fun p => containsKey p.1 (toListModel m₂.1.buckets) ) := by
|
||||
simp [inter]
|
||||
split
|
||||
· rw [filter_eq_filterₘ]
|
||||
simp only [contains_eq_containsKey hm₂]
|
||||
exact toListModel_filterₘ
|
||||
· rw [interSmaller_eq_interSmallerₘ]
|
||||
exact Perm.trans (toListModel_interSmallerₘ _ _ hm₁)
|
||||
(interSmaller_perm_filter _ _ hm₁.distinct)
|
||||
|
||||
/-! # `Const.insertListₘ` -/
|
||||
|
||||
theorem Const.toListModel_insertListₘ {β : Type v} [BEq α] [Hashable α] [EquivBEq α]
|
||||
|
|
|
|||
|
|
@ -2146,6 +2146,324 @@ theorem get!_union_of_not_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited
|
|||
|
||||
end Const
|
||||
|
||||
section Inter
|
||||
|
||||
variable {m₁ m₂ : DHashMap α β}
|
||||
|
||||
@[simp]
|
||||
theorem inter_eq : m₁.inter m₂ = m₁ ∩ m₂ := by
|
||||
simp only [Inter.inter]
|
||||
|
||||
/- contains -/
|
||||
@[simp]
|
||||
theorem contains_inter [EquivBEq α] [LawfulHashable α] {k : α} :
|
||||
(m₁ ∩ m₂).contains k = (m₁.contains k && m₂.contains k) :=
|
||||
@Raw₀.contains_inter _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k
|
||||
|
||||
/- mem -/
|
||||
@[simp]
|
||||
theorem mem_inter_iff [EquivBEq α] [LawfulHashable α] {k : α} :
|
||||
k ∈ m₁ ∩ m₂ ↔ k ∈ m₁ ∧ k ∈ m₂ :=
|
||||
@Raw₀.contains_inter_iff _ _ _ _ ⟨m₁.1, _⟩ ⟨m₂.1, _⟩ _ _ m₁.2 m₂.2 k
|
||||
|
||||
theorem not_mem_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] {k : α}
|
||||
(not_mem : k ∉ m₁) :
|
||||
k ∉ m₁ ∩ m₂ := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem ⊢
|
||||
exact @Raw₀.contains_inter_eq_false_of_contains_eq_false_left _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k not_mem
|
||||
|
||||
theorem not_mem_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] {k : α}
|
||||
(not_mem : k ∉ m₂) :
|
||||
k ∉ m₁ ∩ m₂ := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem ⊢
|
||||
exact @Raw₀.contains_inter_eq_false_of_contains_eq_false_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k not_mem
|
||||
|
||||
/- get? -/
|
||||
theorem get?_inter [LawfulBEq α] {k : α} :
|
||||
(m₁ ∩ m₂).get? k =
|
||||
if k ∈ m₂ then m₁.get? k else none :=
|
||||
@Raw₀.get?_inter _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ m₁.2 m₂.2 k
|
||||
|
||||
theorem get?_inter_of_mem_right [LawfulBEq α]
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).get? k = m₁.get? k :=
|
||||
@Raw₀.get?_inter_of_contains_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ m₁.2 m₂.2 k mem
|
||||
|
||||
theorem get?_inter_of_not_mem_left [LawfulBEq α]
|
||||
{k : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).get? k = none := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.get?_inter_of_contains_eq_false_left _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ m₁.2 m₂.2 k not_mem
|
||||
|
||||
theorem get?_inter_of_not_mem_right [LawfulBEq α]
|
||||
{k : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).get? k = none := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.get?_inter_of_contains_eq_false_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ m₁.2 m₂.2 k not_mem
|
||||
|
||||
/- get -/
|
||||
@[simp] theorem get_inter [LawfulBEq α]
|
||||
{k : α} {h_mem : k ∈ m₁ ∩ m₂} :
|
||||
(m₁ ∩ m₂).get k h_mem =
|
||||
m₁.get k ((mem_inter_iff.1 h_mem).1) := by
|
||||
rw [mem_iff_contains] at h_mem
|
||||
exact @Raw₀.get_inter _ _ _ _ ⟨m₁.1, _⟩ ⟨m₂.1, _⟩ _ m₁.2 m₂.2 k h_mem
|
||||
|
||||
/- getD -/
|
||||
theorem getD_inter [LawfulBEq α] {k : α} {fallback : β k} :
|
||||
(m₁ ∩ m₂).getD k fallback =
|
||||
if k ∈ m₂ then m₁.getD k fallback else fallback :=
|
||||
@Raw₀.getD_inter _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ m₁.2 m₂.2 k fallback
|
||||
|
||||
theorem getD_inter_of_mem_right [LawfulBEq α]
|
||||
{k : α} {fallback : β k} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getD k fallback = m₁.getD k fallback :=
|
||||
@Raw₀.getD_inter_of_contains_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ m₁.2 m₂.2 k fallback mem
|
||||
|
||||
theorem getD_inter_of_not_mem_right [LawfulBEq α]
|
||||
{k : α} {fallback : β k} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getD k fallback = fallback := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.getD_inter_of_contains_eq_false_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ m₁.2 m₂.2 k fallback not_mem
|
||||
|
||||
theorem getD_inter_of_not_mem_left [LawfulBEq α]
|
||||
{k : α} {fallback : β k} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getD k fallback = fallback := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.getD_inter_of_contains_eq_false_left _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ m₁.2 m₂.2 k fallback not_mem
|
||||
|
||||
/- get! -/
|
||||
theorem get!_inter [LawfulBEq α] {k : α} [Inhabited (β k)] :
|
||||
(m₁ ∩ m₂).get! k =
|
||||
if k ∈ m₂ then m₁.get! k else default :=
|
||||
@Raw₀.get!_inter _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ m₁.2 m₂.2 k _
|
||||
|
||||
theorem get!_inter_of_mem_right [LawfulBEq α]
|
||||
{k : α} [Inhabited (β k)] (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).get! k = m₁.get! k :=
|
||||
@Raw₀.get!_inter_of_contains_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ m₁.2 m₂.2 k _ mem
|
||||
|
||||
theorem get!_inter_of_not_mem_right [LawfulBEq α]
|
||||
{k : α} [Inhabited (β k)] (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).get! k = default := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.get!_inter_of_contains_eq_false_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ m₁.2 m₂.2 k _ not_mem
|
||||
|
||||
theorem get!_inter_of_not_mem_left [LawfulBEq α]
|
||||
{k : α} [Inhabited (β k)] (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).get! k = default := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.get!_inter_of_contains_eq_false_left _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ m₁.2 m₂.2 k _ not_mem
|
||||
|
||||
/- getKey? -/
|
||||
theorem getKey?_inter [EquivBEq α] [LawfulHashable α] {k : α} :
|
||||
(m₁ ∩ m₂).getKey? k =
|
||||
if k ∈ m₂ then m₁.getKey? k else none :=
|
||||
@Raw₀.getKey?_inter _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k
|
||||
|
||||
theorem getKey?_inter_of_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getKey? k = m₁.getKey? k :=
|
||||
@Raw₀.getKey?_inter_of_contains_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k mem
|
||||
|
||||
theorem getKey?_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getKey? k = none := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.getKey?_inter_of_contains_eq_false_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k not_mem
|
||||
|
||||
theorem getKey?_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getKey? k = none := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.getKey?_inter_of_contains_eq_false_left _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k not_mem
|
||||
|
||||
/- getKey -/
|
||||
@[simp] theorem getKey_inter [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} {h_mem : k ∈ m₁ ∩ m₂} :
|
||||
(m₁ ∩ m₂).getKey k h_mem =
|
||||
m₁.getKey k ((mem_inter_iff.1 h_mem).1) := by
|
||||
rw [mem_iff_contains] at h_mem
|
||||
exact @Raw₀.getKey_inter _ _ _ _ ⟨m₁.1, _⟩ ⟨m₂.1, _⟩ _ _ m₁.2 m₂.2 k h_mem
|
||||
|
||||
/- getKeyD -/
|
||||
theorem getKeyD_inter [EquivBEq α] [LawfulHashable α] {k fallback : α} :
|
||||
(m₁ ∩ m₂).getKeyD k fallback =
|
||||
if k ∈ m₂ then m₁.getKeyD k fallback else fallback :=
|
||||
@Raw₀.getKeyD_inter _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k fallback
|
||||
|
||||
theorem getKeyD_inter_of_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k fallback : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getKeyD k fallback = m₁.getKeyD k fallback :=
|
||||
@Raw₀.getKeyD_inter_of_contains_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k fallback mem
|
||||
|
||||
theorem getKeyD_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k fallback : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getKeyD k fallback = fallback := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.getKeyD_inter_of_contains_eq_false_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k fallback not_mem
|
||||
|
||||
theorem getKeyD_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
{k fallback : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getKeyD k fallback = fallback := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.getKeyD_inter_of_contains_eq_false_left _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k fallback not_mem
|
||||
|
||||
/- getKey! -/
|
||||
theorem getKey!_inter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : α} :
|
||||
(m₁ ∩ m₂).getKey! k =
|
||||
if k ∈ m₂ then m₁.getKey! k else default :=
|
||||
@Raw₀.getKey!_inter _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ _ m₁.2 m₂.2 k _
|
||||
|
||||
theorem getKey!_inter_of_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getKey! k = m₁.getKey! k :=
|
||||
@Raw₀.getKey!_inter_of_contains_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ _ m₁.2 m₂.2 k mem
|
||||
|
||||
theorem getKey!_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{k : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getKey! k = default := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.getKey!_inter_of_contains_eq_false_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ _ m₁.2 m₂.2 k not_mem
|
||||
|
||||
theorem getKey!_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{k : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getKey! k = default := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.getKey!_inter_of_contains_eq_false_left _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ _ m₁.2 m₂.2 k not_mem
|
||||
|
||||
/- size -/
|
||||
theorem size_inter_le_size_left [EquivBEq α] [LawfulHashable α] :
|
||||
(m₁ ∩ m₂).size ≤ m₁.size :=
|
||||
@Raw₀.size_inter_le_size_left _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2
|
||||
|
||||
theorem size_inter_le_size_right [EquivBEq α] [LawfulHashable α] :
|
||||
(m₁ ∩ m₂).size ≤ m₂.size :=
|
||||
@Raw₀.size_inter_le_size_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2
|
||||
|
||||
theorem size_inter_eq_size_left [EquivBEq α] [LawfulHashable α]
|
||||
(h : ∀ (a : α), a ∈ m₁ → a ∈ m₂) :
|
||||
(m₁ ∩ m₂).size = m₁.size := by
|
||||
have : ∀ (a : α), m₁.contains a → m₂.contains a := by
|
||||
intro a ha
|
||||
rw [contains_iff_mem] at ha ⊢
|
||||
exact h a ha
|
||||
exact @Raw₀.size_inter_eq_size_left _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 this
|
||||
|
||||
theorem size_inter_eq_size_right [EquivBEq α] [LawfulHashable α]
|
||||
(h : ∀ (a : α), a ∈ m₂ → a ∈ m₁) :
|
||||
(m₁ ∩ m₂).size = m₂.size := by
|
||||
have : ∀ (a : α), m₂.contains a → m₁.contains a := by
|
||||
intro a ha
|
||||
rw [contains_iff_mem] at ha ⊢
|
||||
exact h a ha
|
||||
exact @Raw₀.size_inter_eq_size_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 this
|
||||
|
||||
theorem size_add_size_eq_size_union_add_size_inter [EquivBEq α] [LawfulHashable α] :
|
||||
m₁.size + m₂.size = (m₁ ∪ m₂).size + (m₁ ∩ m₂).size :=
|
||||
@Raw₀.size_add_size_eq_size_union_add_size_inter _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2
|
||||
|
||||
/- isEmpty -/
|
||||
@[simp]
|
||||
theorem isEmpty_inter_left [EquivBEq α] [LawfulHashable α] (h : m₁.isEmpty) :
|
||||
(m₁ ∩ m₂).isEmpty = true :=
|
||||
@Raw₀.isEmpty_inter_left _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 h
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_inter_right [EquivBEq α] [LawfulHashable α] (h : m₂.isEmpty) :
|
||||
(m₁ ∩ m₂).isEmpty = true :=
|
||||
@Raw₀.isEmpty_inter_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 h
|
||||
|
||||
theorem isEmpty_inter_iff [EquivBEq α] [LawfulHashable α] :
|
||||
(m₁ ∩ m₂).isEmpty ↔ ∀ k, k ∈ m₁ → k ∉ m₂ := by
|
||||
simpa only [mem_iff_contains, Bool.not_eq_true] using
|
||||
@Raw₀.isEmpty_inter_iff _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.wf m₂.wf
|
||||
|
||||
end Inter
|
||||
|
||||
namespace Const
|
||||
|
||||
variable {β : Type v} {m₁ m₂ : DHashMap α (fun _ => β)}
|
||||
|
||||
/- get? -/
|
||||
theorem get?_inter [EquivBEq α] [LawfulHashable α] {k : α} :
|
||||
Const.get? (m₁.inter m₂) k =
|
||||
if k ∈ m₂ then Const.get? m₁ k else none :=
|
||||
@Raw₀.Const.get?_inter _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k
|
||||
|
||||
theorem get?_inter_of_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
Const.get? (m₁.inter m₂) k = Const.get? m₁ k :=
|
||||
@Raw₀.Const.get?_inter_of_contains_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k mem
|
||||
|
||||
theorem get?_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (not_mem : ¬k ∈ m₁) :
|
||||
Const.get? (m₁.inter m₂) k = none := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.Const.get?_inter_of_contains_eq_false_left _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k not_mem
|
||||
|
||||
theorem get?_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (not_mem : ¬k ∈ m₂) :
|
||||
Const.get? (m₁.inter m₂) k = none := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.Const.get?_inter_of_contains_eq_false_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k not_mem
|
||||
|
||||
/- get -/
|
||||
@[simp] theorem get_inter [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} {h_mem : k ∈ m₁ ∩ m₂} :
|
||||
Const.get (m₁.inter m₂) k h_mem =
|
||||
Const.get m₁ k ((mem_inter_iff.1 h_mem).1) := by
|
||||
rw [mem_iff_contains] at h_mem
|
||||
exact @Raw₀.Const.get_inter _ _ _ _ ⟨m₁.1, _⟩ ⟨m₂.1, _⟩ _ _ m₁.2 m₂.2 k h_mem
|
||||
|
||||
/- getD -/
|
||||
theorem getD_inter [EquivBEq α] [LawfulHashable α] {k : α} {fallback : β} :
|
||||
Const.getD (m₁.inter m₂) k fallback =
|
||||
if k ∈ m₂ then Const.getD m₁ k fallback else fallback :=
|
||||
@Raw₀.Const.getD_inter _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k fallback
|
||||
|
||||
theorem getD_inter_of_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} {fallback : β} (mem : k ∈ m₂) :
|
||||
Const.getD (m₁.inter m₂) k fallback = Const.getD m₁ k fallback :=
|
||||
@Raw₀.Const.getD_inter_of_contains_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k fallback mem
|
||||
|
||||
theorem getD_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} {fallback : β} (not_mem : ¬k ∈ m₂) :
|
||||
Const.getD (m₁.inter m₂) k fallback = fallback := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.Const.getD_inter_of_contains_eq_false_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k fallback not_mem
|
||||
|
||||
theorem getD_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} {fallback : β} (not_mem : ¬k ∈ m₁) :
|
||||
Const.getD (m₁.inter m₂) k fallback = fallback := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.Const.getD_inter_of_contains_eq_false_left _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ m₁.2 m₂.2 k fallback not_mem
|
||||
|
||||
/- get! -/
|
||||
theorem get!_inter [EquivBEq α] [LawfulHashable α] [Inhabited β] {k : α} :
|
||||
Const.get! (m₁.inter m₂) k =
|
||||
if k ∈ m₂ then Const.get! m₁ k else default :=
|
||||
@Raw₀.Const.get!_inter _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ _ m₁.2 m₂.2 k
|
||||
|
||||
theorem get!_inter_of_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited β]
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
Const.get! (m₁.inter m₂) k = Const.get! m₁ k :=
|
||||
@Raw₀.Const.get!_inter_of_contains_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ _ m₁.2 m₂.2 k mem
|
||||
|
||||
theorem get!_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited β]
|
||||
{k : α} (not_mem : ¬k ∈ m₂) :
|
||||
Const.get! (m₁.inter m₂) k = default := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.Const.get!_inter_of_contains_eq_false_right _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ _ m₁.2 m₂.2 k not_mem
|
||||
|
||||
theorem get!_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] [Inhabited β]
|
||||
{k : α} (not_mem : ¬k ∈ m₁) :
|
||||
Const.get! (m₁.inter m₂) k = default := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
exact @Raw₀.Const.get!_inter_of_contains_eq_false_left _ _ _ _ ⟨m₁.1, m₁.2.size_buckets_pos⟩ ⟨m₂.1, m₂.2.size_buckets_pos⟩ _ _ _ m₁.2 m₂.2 k not_mem
|
||||
|
||||
end Const
|
||||
|
||||
namespace Const
|
||||
|
||||
variable {β : Type v} {m : DHashMap α (fun _ => β)}
|
||||
|
|
|
|||
|
|
@ -384,17 +384,6 @@ This function ensures that the value is used linearly.
|
|||
else
|
||||
∅
|
||||
|
||||
/--
|
||||
Monadically computes a value by folding the given function over the mappings in the hash
|
||||
map in some order.
|
||||
-/
|
||||
@[inline] def foldM (f : δ → (a : α) → β a → m δ) (init : δ) (b : Raw α β) : m δ :=
|
||||
b.buckets.foldlM (fun acc l => l.foldlM f acc) init
|
||||
|
||||
/-- Folds the given function over the mappings in the hash map in some order. -/
|
||||
@[inline] def fold (f : δ → (a : α) → β a → δ) (init : δ) (b : Raw α β) : δ :=
|
||||
Id.run (b.foldM (pure <| f · · ·) init)
|
||||
|
||||
namespace Internal
|
||||
|
||||
/--
|
||||
|
|
@ -516,6 +505,23 @@ This function always merges the smaller map into the larger map, so the expected
|
|||
|
||||
instance [BEq α] [Hashable α] : Union (Raw α β) := ⟨union⟩
|
||||
|
||||
/--
|
||||
Computes the intersection of the given hash maps. The result will only contain entries from the first map.
|
||||
|
||||
This function always merges the smaller map into the larger map, so the expected runtime is
|
||||
`O(min(m₁.size, m₂.size))`.
|
||||
-/
|
||||
@[inline] def inter [BEq α] [Hashable α] (m₁ m₂ : Raw α β) : Raw α β :=
|
||||
if h₁ : 0 < m₁.buckets.size then
|
||||
if h₂ : 0 < m₂.buckets.size then
|
||||
Raw₀.inter ⟨m₁, h₁⟩ ⟨m₂, h₂⟩
|
||||
else
|
||||
m₁
|
||||
else
|
||||
m₂
|
||||
|
||||
instance [BEq α] [Hashable α] : Inter (Raw α β) := ⟨inter⟩
|
||||
|
||||
|
||||
section Unverified
|
||||
|
||||
|
|
@ -664,6 +670,8 @@ inductive WF : {α : Type u} → {β : α → Type v} → [BEq α] → [Hashable
|
|||
/-- Internal implementation detail of the hash map -/
|
||||
| constAlter₀ {α} {β : Type v} [BEq α] [Hashable α] {m : Raw α (fun _ => β)} {h a}
|
||||
{f : Option β → Option β} : WF m → WF (Raw₀.Const.alter ⟨m, h⟩ a f).1
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
| inter₀ {α β} [BEq α] [Hashable α] {m₁ m₂ : Raw α β} {h₁ h₂} : WF m₁ → WF m₂ → WF (Raw₀.inter ⟨m₁, h₁⟩ ⟨m₂, h₂⟩).1
|
||||
|
||||
-- TODO: this needs to be deprecated, but there is a bootstrapping issue.
|
||||
-- @[deprecated WF.emptyWithCapacity₀ (since := "2025-03-12")]
|
||||
|
|
@ -686,6 +694,7 @@ theorem WF.size_buckets_pos [BEq α] [Hashable α] (m : Raw α β) : WF m → 0
|
|||
| constModify₀ _ => (Raw₀.Const.modify _ _ _).2
|
||||
| alter₀ _ => (Raw₀.alter _ _ _).2
|
||||
| constAlter₀ _ => (Raw₀.Const.alter _ _ _).2
|
||||
| inter₀ _ _ => (Raw₀.inter _ _).2
|
||||
|
||||
@[simp] theorem WF.emptyWithCapacity [BEq α] [Hashable α] {c : Nat} : (Raw.emptyWithCapacity c : Raw α β).WF :=
|
||||
.emptyWithCapacity₀
|
||||
|
|
@ -761,6 +770,10 @@ theorem WF.union [BEq α] [Hashable α] {m₁ m₂ : Raw α β} (h₁ : m₁.WF)
|
|||
simp [Std.DHashMap.Raw.union, h₁.size_buckets_pos, h₂.size_buckets_pos]
|
||||
exact WF.union₀ h₁ h₂
|
||||
|
||||
theorem WF.inter [BEq α] [Hashable α] {m₁ m₂ : Raw α β} (h₁ : m₁.WF) (h₂ : m₂.WF) : (m₁.inter m₂ : Raw α β).WF := by
|
||||
simp [Std.DHashMap.Raw.inter, h₁.size_buckets_pos, h₂.size_buckets_pos]
|
||||
exact WF.inter₀ h₁ h₂
|
||||
|
||||
end WF
|
||||
|
||||
end Raw
|
||||
|
|
|
|||
|
|
@ -56,6 +56,17 @@ namespace Raw
|
|||
|
||||
variable {α : Type u} {β : α → Type v} {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
/--
|
||||
Monadically computes a value by folding the given function over the mappings in the hash
|
||||
map in some order.
|
||||
-/
|
||||
@[inline] def foldM [Monad m] (f : δ → (a : α) → β a → m δ) (init : δ) (b : Raw α β) : m δ :=
|
||||
b.buckets.foldlM (fun acc l => l.foldlM f acc) init
|
||||
|
||||
/-- Folds the given function over the mappings in the hash map in some order. -/
|
||||
@[inline] def fold (f : δ → (a : α) → β a → δ) (init : δ) (b : Raw α β) : δ :=
|
||||
Id.run (b.foldM (pure <| f · · ·) init)
|
||||
|
||||
/-- Carries out a monadic action on each mapping in the hash map in some order. -/
|
||||
@[inline] def forM [Monad m] (f : (a : α) → β a → m PUnit) (b : Raw α β) : m PUnit :=
|
||||
b.buckets.forM (AssocList.forM f)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ private meta def baseNames : Array Name :=
|
|||
``getKey?_eq, ``getKey_eq, ``getKey!_eq, ``getKeyD_eq,
|
||||
``insertMany_eq, ``Const.insertMany_eq, ``Const.insertManyIfNewUnit_eq,
|
||||
``ofList_eq, ``Const.ofList_eq, ``Const.unitOfList_eq,
|
||||
``alter_eq, ``Const.alter_eq, ``modify_eq, ``Const.modify_eq, ``union_eq]
|
||||
``alter_eq, ``Const.alter_eq, ``modify_eq, ``Const.modify_eq, ``union_eq, ``inter_eq]
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
scoped syntax "simp_to_raw" ("using" term)? : tactic
|
||||
|
|
@ -2433,6 +2433,444 @@ theorem get!_union_of_not_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited
|
|||
|
||||
end Const
|
||||
|
||||
section Inter
|
||||
|
||||
variable {m₁ m₂ : Raw α β}
|
||||
|
||||
@[simp]
|
||||
theorem inter_eq : m₁.inter m₂ = m₁ ∩ m₂ := by
|
||||
simp only [Inter.inter]
|
||||
|
||||
/- contains -/
|
||||
|
||||
@[simp]
|
||||
theorem contains_inter [EquivBEq α] [LawfulHashable α] {k : α} (h₁ : m₁.WF) (h₂ : m₂.WF) :
|
||||
(m₁ ∩ m₂).contains k = (m₁.contains k && m₂.contains k) := by
|
||||
simp only [Inter.inter]
|
||||
simp_to_raw using Raw₀.contains_inter
|
||||
|
||||
/- mem -/
|
||||
|
||||
theorem mem_inter_iff [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k : α} :
|
||||
k ∈ m₁ ∩ m₂ ↔ k ∈ m₁ ∧ k ∈ m₂ := by
|
||||
simp only [Inter.inter, Membership.mem]
|
||||
simp_to_raw using Raw₀.contains_inter_iff
|
||||
|
||||
theorem not_mem_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) {k : α}
|
||||
(not_mem : k ∉ m₁) :
|
||||
k ∉ m₁ ∩ m₂ := by
|
||||
simp only [Inter.inter]
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem |-
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.contains_inter_eq_false_of_contains_eq_false_left
|
||||
|
||||
theorem not_mem_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) {k : α}
|
||||
(not_mem : k ∉ m₂) :
|
||||
k ∉ m₁ ∩ m₂ := by
|
||||
simp only [Inter.inter]
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem |-
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.contains_inter_eq_false_of_contains_eq_false_right
|
||||
|
||||
/- get? -/
|
||||
theorem get?_inter [LawfulBEq α] (h₁ : m₁.WF) (h₂ : m₂.WF) {k : α} :
|
||||
(m₁ ∩ m₂).get? k =
|
||||
if k ∈ m₂ then m₁.get? k else none := by
|
||||
simp only [Membership.mem, Inter.inter]
|
||||
simp_to_raw using Raw₀.get?_inter
|
||||
|
||||
theorem get?_inter_of_mem_right [LawfulBEq α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).get? k = m₁.get? k := by
|
||||
simp only [Membership.mem] at mem
|
||||
simp only [Inter.inter]
|
||||
revert mem
|
||||
simp_to_raw using Raw₀.get?_inter_of_contains_right
|
||||
|
||||
theorem get?_inter_of_not_mem_left [LawfulBEq α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).get? k = none := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
revert not_mem
|
||||
simp only [Inter.inter]
|
||||
simp_to_raw using Raw₀.get?_inter_of_contains_eq_false_left
|
||||
|
||||
theorem get?_inter_of_not_mem_right [LawfulBEq α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).get? k = none := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
revert not_mem
|
||||
simp only [Inter.inter]
|
||||
simp_to_raw using Raw₀.get?_inter_of_contains_eq_false_right
|
||||
|
||||
/- get -/
|
||||
@[simp] theorem get_inter [LawfulBEq α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {h_mem: k ∈ m₁ ∩ m₂} :
|
||||
(m₁ ∩ m₂).get k h_mem =
|
||||
m₁.get k ((mem_inter_iff h₁ h₂).1 h_mem).1 := by
|
||||
revert h_mem
|
||||
simp only [Membership.mem, Inter.inter]
|
||||
simp_to_raw
|
||||
intro h_mem
|
||||
apply Raw₀.get_inter
|
||||
all_goals wf_trivial
|
||||
|
||||
/- getD -/
|
||||
theorem getD_inter [LawfulBEq α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {fallback : β k} :
|
||||
(m₁ ∩ m₂).getD k fallback =
|
||||
if k ∈ m₂ then m₁.getD k fallback else fallback := by
|
||||
simp only [Inter.inter, Membership.mem]
|
||||
simp_to_raw using Raw₀.getD_inter
|
||||
|
||||
theorem getD_inter_of_mem_right [LawfulBEq α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {fallback : β k} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getD k fallback = m₁.getD k fallback := by
|
||||
revert mem
|
||||
simp only [Membership.mem, Inter.inter]
|
||||
simp_to_raw using Raw₀.getD_inter_of_contains_right
|
||||
|
||||
theorem getD_inter_of_not_mem_right [LawfulBEq α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {fallback : β k} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getD k fallback = fallback := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
simp only [Inter.inter]
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.getD_inter_of_contains_eq_false_right
|
||||
|
||||
theorem getD_inter_of_not_mem_left [LawfulBEq α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {fallback : β k} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getD k fallback = fallback := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
simp only [Inter.inter]
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.getD_inter_of_contains_eq_false_left
|
||||
|
||||
/- get! -/
|
||||
theorem get!_inter [LawfulBEq α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} [Inhabited (β k)] :
|
||||
(m₁ ∩ m₂).get! k =
|
||||
if k ∈ m₂ then m₁.get! k else default := by
|
||||
simp only [Inter.inter, Membership.mem]
|
||||
simp_to_raw using Raw₀.get!_inter
|
||||
|
||||
theorem get!_inter_of_mem_right [LawfulBEq α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} [Inhabited (β k)] (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).get! k = m₁.get! k := by
|
||||
revert mem
|
||||
simp only [Membership.mem, Inter.inter]
|
||||
simp_to_raw using Raw₀.get!_inter_of_contains_right
|
||||
|
||||
theorem get!_inter_of_not_mem_right [LawfulBEq α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} [Inhabited (β k)] (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).get! k = default := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
simp only [Inter.inter]
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.get!_inter_of_contains_eq_false_right
|
||||
|
||||
theorem get!_inter_of_not_mem_left [LawfulBEq α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} [Inhabited (β k)] (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).get! k = default := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
simp only [Inter.inter]
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.get!_inter_of_contains_eq_false_left
|
||||
|
||||
/- getKey? -/
|
||||
theorem getKey?_inter [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) {k : α} :
|
||||
(m₁ ∩ m₂).getKey? k =
|
||||
if k ∈ m₂ then m₁.getKey? k else none := by
|
||||
simp only [Membership.mem, Inter.inter]
|
||||
simp_to_raw using Raw₀.getKey?_inter
|
||||
|
||||
theorem getKey?_inter_of_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) {k : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getKey? k = m₁.getKey? k := by
|
||||
simp only [Membership.mem] at mem
|
||||
simp only [Inter.inter]
|
||||
revert mem
|
||||
simp_to_raw using Raw₀.getKey?_inter_of_contains_right
|
||||
|
||||
theorem getKey?_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) {k : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getKey? k = none := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
simp only [Inter.inter]
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.getKey?_inter_of_contains_eq_false_right
|
||||
|
||||
theorem getKey?_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) {k : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getKey? k = none := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
simp only [Inter.inter]
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.getKey?_inter_of_contains_eq_false_left
|
||||
|
||||
/- getKey -/
|
||||
@[simp] theorem getKey_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {h_mem : k ∈ m₁ ∩ m₂} :
|
||||
(m₁ ∩ m₂).getKey k h_mem =
|
||||
m₁.getKey k ((mem_inter_iff h₁ h₂).1 h_mem).1 := by
|
||||
revert h_mem
|
||||
simp only [Membership.mem, Inter.inter]
|
||||
simp_to_raw
|
||||
intro h_mem
|
||||
apply Raw₀.getKey_inter
|
||||
all_goals wf_trivial
|
||||
|
||||
/- getKeyD -/
|
||||
theorem getKeyD_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k fallback : α} :
|
||||
(m₁ ∩ m₂).getKeyD k fallback =
|
||||
if k ∈ m₂ then m₁.getKeyD k fallback else fallback := by
|
||||
simp only [Membership.mem, Inter.inter]
|
||||
simp_to_raw using Raw₀.getKeyD_inter
|
||||
|
||||
theorem getKeyD_inter_of_mem_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k fallback : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getKeyD k fallback = m₁.getKeyD k fallback := by
|
||||
simp only [Membership.mem] at mem
|
||||
simp only [Inter.inter]
|
||||
revert mem
|
||||
simp_to_raw using Raw₀.getKeyD_inter_of_contains_right
|
||||
|
||||
theorem getKeyD_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k fallback : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getKeyD k fallback = fallback := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
simp only [Inter.inter]
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.getKeyD_inter_of_contains_eq_false_right
|
||||
|
||||
theorem getKeyD_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k fallback : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getKeyD k fallback = fallback := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
simp only [Inter.inter]
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.getKeyD_inter_of_contains_eq_false_left
|
||||
|
||||
/- getKey! -/
|
||||
theorem getKey!_inter [EquivBEq α] [LawfulHashable α] [Inhabited α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k : α} :
|
||||
(m₁ ∩ m₂).getKey! k =
|
||||
if k ∈ m₂ then m₁.getKey! k else default := by
|
||||
simp only [Membership.mem, Inter.inter]
|
||||
simp_to_raw using Raw₀.getKey!_inter
|
||||
|
||||
theorem getKey!_inter_of_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getKey! k = m₁.getKey! k := by
|
||||
simp only [Membership.mem] at mem
|
||||
simp only [Inter.inter]
|
||||
revert mem
|
||||
simp_to_raw using Raw₀.getKey!_inter_of_contains_right
|
||||
|
||||
theorem getKey!_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getKey! k = default := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
simp only [Inter.inter]
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.getKey!_inter_of_contains_eq_false_right
|
||||
|
||||
theorem getKey!_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] [Inhabited α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getKey! k = default := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
simp only [Inter.inter]
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.getKey!_inter_of_contains_eq_false_left
|
||||
|
||||
/- size -/
|
||||
theorem size_inter_le_size_left [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) :
|
||||
(m₁ ∩ m₂).size ≤ m₁.size := by
|
||||
simp only [Inter.inter]
|
||||
simp_to_raw using Raw₀.size_inter_le_size_left
|
||||
|
||||
theorem size_inter_le_size_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) :
|
||||
(m₁ ∩ m₂).size ≤ m₂.size := by
|
||||
simp only [Inter.inter]
|
||||
simp_to_raw using Raw₀.size_inter_le_size_right
|
||||
|
||||
theorem size_inter_eq_size_left [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
(h : ∀ (a : α), a ∈ m₁ → a ∈ m₂) :
|
||||
(m₁ ∩ m₂).size = m₁.size := by
|
||||
have : ∀ (a : α), m₁.contains a → m₂.contains a := by
|
||||
intro a ha
|
||||
rw [contains_iff_mem] at ha ⊢
|
||||
exact h a ha
|
||||
revert this
|
||||
simp only [Inter.inter]
|
||||
simp_to_raw using Raw₀.size_inter_eq_size_left
|
||||
|
||||
theorem size_inter_eq_size_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
(h : ∀ (a : α), a ∈ m₂ → a ∈ m₁) :
|
||||
(m₁ ∩ m₂).size = m₂.size := by
|
||||
have : ∀ (a : α), m₂.contains a → m₁.contains a := by
|
||||
intro a ha
|
||||
rw [contains_iff_mem] at ha ⊢
|
||||
exact h a ha
|
||||
revert this
|
||||
simp only [Inter.inter]
|
||||
simp_to_raw using Raw₀.size_inter_eq_size_right
|
||||
|
||||
theorem size_add_size_eq_size_union_add_size_inter [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) :
|
||||
m₁.size + m₂.size = (m₁ ∪ m₂).size + (m₁ ∩ m₂).size := by
|
||||
simp only [Union.union, Inter.inter]
|
||||
simp_to_raw using @Raw₀.size_add_size_eq_size_union_add_size_inter _ _ _ _ ⟨m₁, _⟩ ⟨m₂, _⟩
|
||||
|
||||
/- isEmpty -/
|
||||
@[simp]
|
||||
theorem isEmpty_inter_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF) (h : m₁.isEmpty) :
|
||||
(m₁ ∩ m₂).isEmpty = true := by
|
||||
revert h
|
||||
simp only [Inter.inter]
|
||||
simp_to_raw using @Raw₀.isEmpty_inter_left _ _ _ _ ⟨m₁, _⟩ ⟨m₂, _⟩ _ _
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_inter_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF) (h : m₂.isEmpty) :
|
||||
(m₁ ∩ m₂).isEmpty = true := by
|
||||
revert h
|
||||
simp only [Inter.inter]
|
||||
simp_to_raw using @Raw₀.isEmpty_inter_right _ _ _ _ ⟨m₁, _⟩ ⟨m₂, _⟩ _ _
|
||||
|
||||
theorem isEmpty_inter_iff [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF) :
|
||||
(m₁ ∩ m₂).isEmpty ↔ ∀ k, k ∈ m₁ → k ∉ m₂ := by
|
||||
conv =>
|
||||
rhs
|
||||
rhs
|
||||
rhs
|
||||
rw [← contains_eq_false_iff_not_mem]
|
||||
simp only [Inter.inter, Membership.mem]
|
||||
simp_to_raw using @Raw₀.isEmpty_inter_iff _ _ _ _ ⟨m₁, _⟩ ⟨m₂, _⟩ _ _
|
||||
|
||||
end Inter
|
||||
|
||||
namespace Const
|
||||
|
||||
variable {β : Type v} {m₁ m₂ : Raw α (fun _ => β)}
|
||||
|
||||
/- get? -/
|
||||
theorem get?_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF) {k : α} :
|
||||
Const.get? (m₁ ∩ m₂) k =
|
||||
if k ∈ m₂ then Const.get? m₁ k else none := by
|
||||
simp only [Membership.mem, Inter.inter]
|
||||
simp_to_raw using Raw₀.Const.get?_inter
|
||||
|
||||
theorem get?_inter_of_mem_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
Const.get? (m₁ ∩ m₂) k = Const.get? m₁ k := by
|
||||
rw [mem_iff_contains] at mem
|
||||
revert mem
|
||||
simp only [Inter.inter]
|
||||
simp_to_raw using Raw₀.Const.get?_inter_of_contains_right
|
||||
|
||||
theorem get?_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (not_mem : ¬k ∈ m₁) :
|
||||
Const.get? (m₁ ∩ m₂) k = none := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
revert not_mem
|
||||
simp only [Inter.inter]
|
||||
simp_to_raw using Raw₀.Const.get?_inter_of_contains_eq_false_left
|
||||
|
||||
theorem get?_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (not_mem : ¬k ∈ m₂) :
|
||||
Const.get? (m₁ ∩ m₂) k = none := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
revert not_mem
|
||||
simp only [Inter.inter]
|
||||
simp_to_raw using Raw₀.Const.get?_inter_of_contains_eq_false_right
|
||||
|
||||
/- get -/
|
||||
@[simp] theorem get_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {h_mem : k ∈ m₁ ∩ m₂} :
|
||||
Const.get (m₁ ∩ m₂) k h_mem =
|
||||
Const.get m₁ k ((mem_inter_iff h₁ h₂).1 h_mem).1 := by
|
||||
revert h_mem
|
||||
simp only [Membership.mem, Inter.inter]
|
||||
simp_to_raw
|
||||
intro h_mem
|
||||
apply Raw₀.Const.get_inter
|
||||
all_goals wf_trivial
|
||||
|
||||
/- getD -/
|
||||
theorem getD_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {fallback : β} :
|
||||
Const.getD (m₁ ∩ m₂) k fallback =
|
||||
if k ∈ m₂ then Const.getD m₁ k fallback else fallback := by
|
||||
simp only [Inter.inter, Membership.mem]
|
||||
simp_to_raw using Raw₀.Const.getD_inter
|
||||
|
||||
theorem getD_inter_of_mem_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {fallback : β} (mem : k ∈ m₂) :
|
||||
Const.getD (m₁ ∩ m₂) k fallback = Const.getD m₁ k fallback := by
|
||||
rw [mem_iff_contains] at mem
|
||||
revert mem
|
||||
simp only [Inter.inter]
|
||||
simp_to_raw using Raw₀.Const.getD_inter_of_contains_right
|
||||
|
||||
theorem getD_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {fallback : β} (not_mem : ¬k ∈ m₂) :
|
||||
Const.getD (m₁ ∩ m₂) k fallback = fallback := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
simp only [Inter.inter]
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.Const.getD_inter_of_contains_eq_false_right
|
||||
|
||||
theorem getD_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {fallback : β} (not_mem : ¬k ∈ m₁) :
|
||||
Const.getD (m₁ ∩ m₂) k fallback = fallback := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
simp only [Inter.inter]
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.Const.getD_inter_of_contains_eq_false_left
|
||||
|
||||
/- get! -/
|
||||
theorem get!_inter [EquivBEq α] [LawfulHashable α] [Inhabited β] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} :
|
||||
Const.get! (m₁ ∩ m₂) k =
|
||||
if k ∈ m₂ then Const.get! m₁ k else default := by
|
||||
simp only [Inter.inter, Membership.mem]
|
||||
simp_to_raw using Raw₀.Const.get!_inter
|
||||
|
||||
theorem get!_inter_of_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited β] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
Const.get! (m₁ ∩ m₂) k = Const.get! m₁ k := by
|
||||
rw [mem_iff_contains] at mem
|
||||
revert mem
|
||||
simp only [Inter.inter]
|
||||
simp_to_raw using Raw₀.Const.get!_inter_of_contains_right
|
||||
|
||||
theorem get!_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited β] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (not_mem : ¬k ∈ m₂) :
|
||||
Const.get! (m₁ ∩ m₂) k = default := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
simp only [Inter.inter]
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.Const.get!_inter_of_contains_eq_false_right
|
||||
|
||||
theorem get!_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] [Inhabited β] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (not_mem : ¬k ∈ m₁) :
|
||||
Const.get! (m₁ ∩ m₂) k = default := by
|
||||
rw [← contains_eq_false_iff_not_mem] at not_mem
|
||||
simp only [Inter.inter]
|
||||
revert not_mem
|
||||
simp_to_raw using Raw₀.Const.get!_inter_of_contains_eq_false_left
|
||||
|
||||
end Const
|
||||
|
||||
namespace Const
|
||||
|
||||
variable {β : Type v} {m : Raw α (fun _ => β)}
|
||||
|
|
|
|||
|
|
@ -269,6 +269,11 @@ This function always merges the smaller map into the larger map, so the expected
|
|||
|
||||
instance [BEq α] [Hashable α] : Union (HashMap α β) := ⟨union⟩
|
||||
|
||||
@[inherit_doc DHashMap.inter, inline] def inter [BEq α] [Hashable α] (m₁ m₂ : HashMap α β) : HashMap α β :=
|
||||
⟨DHashMap.inter m₁.inner m₂.inner⟩
|
||||
|
||||
instance [BEq α] [Hashable α] : Inter (HashMap α β) := ⟨inter⟩
|
||||
|
||||
section Unverified
|
||||
|
||||
/-! We currently do not provide lemmas for the functions below. -/
|
||||
|
|
|
|||
|
|
@ -1557,6 +1557,218 @@ theorem isEmpty_union [EquivBEq α] [LawfulHashable α] :
|
|||
|
||||
end Union
|
||||
|
||||
section Inter
|
||||
|
||||
variable {β : Type v}
|
||||
|
||||
variable {m₁ m₂ : HashMap α β}
|
||||
|
||||
@[simp]
|
||||
theorem inter_eq : m₁.inter m₂ = m₁ ∩ m₂ := by
|
||||
simp only [Inter.inter]
|
||||
|
||||
/- contains -/
|
||||
@[simp]
|
||||
theorem contains_inter [EquivBEq α] [LawfulHashable α] {k : α} :
|
||||
(m₁ ∩ m₂).contains k = (m₁.contains k && m₂.contains k) :=
|
||||
@DHashMap.contains_inter _ _ _ _ m₁.inner m₂.inner _ _ k
|
||||
|
||||
/- mem -/
|
||||
@[simp]
|
||||
theorem mem_inter_iff [EquivBEq α] [LawfulHashable α] {k : α} :
|
||||
k ∈ m₁ ∩ m₂ ↔ k ∈ m₁ ∧ k ∈ m₂ :=
|
||||
@DHashMap.mem_inter_iff _ _ _ _ m₁.inner m₂.inner _ _ k
|
||||
|
||||
theorem not_mem_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] {k : α}
|
||||
(not_mem : k ∉ m₁) :
|
||||
k ∉ m₁ ∩ m₂ :=
|
||||
@DHashMap.not_mem_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ k not_mem
|
||||
|
||||
theorem not_mem_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] {k : α}
|
||||
(not_mem : k ∉ m₂) :
|
||||
k ∉ m₁ ∩ m₂ :=
|
||||
@DHashMap.not_mem_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ k not_mem
|
||||
|
||||
/- get? -/
|
||||
theorem get?_inter [EquivBEq α] [LawfulHashable α] {k : α} :
|
||||
(m₁ ∩ m₂).get? k =
|
||||
if k ∈ m₂ then m₁.get? k else none :=
|
||||
@DHashMap.Const.get?_inter _ _ _ _ m₁.inner m₂.inner _ _ k
|
||||
|
||||
theorem get?_inter_of_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).get? k = m₁.get? k :=
|
||||
@DHashMap.Const.get?_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ k mem
|
||||
|
||||
theorem get?_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).get? k = none :=
|
||||
@DHashMap.Const.get?_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ k not_mem
|
||||
|
||||
theorem get?_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).get? k = none :=
|
||||
@DHashMap.Const.get?_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ k not_mem
|
||||
|
||||
/- get -/
|
||||
@[simp] theorem get_inter [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} {h_mem : k ∈ m₁ ∩ m₂} :
|
||||
(m₁ ∩ m₂).get k h_mem =
|
||||
m₁.get k ((mem_inter_iff.1 h_mem).1) :=
|
||||
@DHashMap.Const.get_inter _ _ _ _ m₁.inner m₂.inner _ _ k h_mem
|
||||
|
||||
/- getD -/
|
||||
theorem getD_inter [EquivBEq α] [LawfulHashable α] {k : α} {fallback : β} :
|
||||
(m₁ ∩ m₂).getD k fallback =
|
||||
if k ∈ m₂ then m₁.getD k fallback else fallback :=
|
||||
@DHashMap.Const.getD_inter _ _ _ _ m₁.inner m₂.inner _ _ k fallback
|
||||
|
||||
theorem getD_inter_of_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} {fallback : β} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getD k fallback = m₁.getD k fallback :=
|
||||
@DHashMap.Const.getD_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ k fallback mem
|
||||
|
||||
theorem getD_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} {fallback : β} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getD k fallback = fallback :=
|
||||
@DHashMap.Const.getD_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ k fallback not_mem
|
||||
|
||||
theorem getD_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} {fallback : β} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getD k fallback = fallback :=
|
||||
@DHashMap.Const.getD_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ k fallback not_mem
|
||||
|
||||
/- get! -/
|
||||
theorem get!_inter [EquivBEq α] [LawfulHashable α] {k : α} [Inhabited β] :
|
||||
(m₁ ∩ m₂).get! k =
|
||||
if k ∈ m₂ then m₁.get! k else default :=
|
||||
@DHashMap.Const.get!_inter _ _ _ _ m₁.inner m₂.inner _ _ _ k
|
||||
|
||||
theorem get!_inter_of_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} [Inhabited β] (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).get! k = m₁.get! k :=
|
||||
@DHashMap.Const.get!_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ _ k mem
|
||||
|
||||
theorem get!_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} [Inhabited β] (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).get! k = default :=
|
||||
@DHashMap.Const.get!_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ _ k not_mem
|
||||
|
||||
theorem get!_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} [Inhabited β] (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).get! k = default :=
|
||||
@DHashMap.Const.get!_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ _ k not_mem
|
||||
|
||||
/- getKey? -/
|
||||
theorem getKey?_inter [EquivBEq α] [LawfulHashable α] {k : α} :
|
||||
(m₁ ∩ m₂).getKey? k =
|
||||
if k ∈ m₂ then m₁.getKey? k else none :=
|
||||
@DHashMap.getKey?_inter _ _ _ _ m₁.inner m₂.inner _ _ k
|
||||
|
||||
theorem getKey?_inter_of_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getKey? k = m₁.getKey? k :=
|
||||
@DHashMap.getKey?_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ k mem
|
||||
|
||||
theorem getKey?_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getKey? k = none :=
|
||||
@DHashMap.getKey?_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ k not_mem
|
||||
|
||||
theorem getKey?_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getKey? k = none :=
|
||||
@DHashMap.getKey?_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ k not_mem
|
||||
|
||||
/- getKey -/
|
||||
@[simp] theorem getKey_inter [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} {h_mem : k ∈ m₁ ∩ m₂} :
|
||||
(m₁ ∩ m₂).getKey k h_mem =
|
||||
m₁.getKey k ((mem_inter_iff.1 h_mem).1) :=
|
||||
@DHashMap.getKey_inter _ _ _ _ m₁.inner m₂.inner _ _ k h_mem
|
||||
|
||||
/- getKeyD -/
|
||||
theorem getKeyD_inter [EquivBEq α] [LawfulHashable α] {k fallback : α} :
|
||||
(m₁ ∩ m₂).getKeyD k fallback =
|
||||
if k ∈ m₂ then m₁.getKeyD k fallback else fallback :=
|
||||
@DHashMap.getKeyD_inter _ _ _ _ m₁.inner m₂.inner _ _ k fallback
|
||||
|
||||
theorem getKeyD_inter_of_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k fallback : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getKeyD k fallback = m₁.getKeyD k fallback :=
|
||||
@DHashMap.getKeyD_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ k fallback mem
|
||||
|
||||
theorem getKeyD_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k fallback : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getKeyD k fallback = fallback :=
|
||||
@DHashMap.getKeyD_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ k fallback not_mem
|
||||
|
||||
theorem getKeyD_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
{k fallback : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getKeyD k fallback = fallback :=
|
||||
@DHashMap.getKeyD_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ k fallback not_mem
|
||||
|
||||
/- getKey! -/
|
||||
theorem getKey!_inter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : α} :
|
||||
(m₁ ∩ m₂).getKey! k =
|
||||
if k ∈ m₂ then m₁.getKey! k else default :=
|
||||
@DHashMap.getKey!_inter _ _ _ _ m₁.inner m₂.inner _ _ _ k
|
||||
|
||||
theorem getKey!_inter_of_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getKey! k = m₁.getKey! k :=
|
||||
@DHashMap.getKey!_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ _ k mem
|
||||
|
||||
theorem getKey!_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{k : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getKey! k = default :=
|
||||
@DHashMap.getKey!_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ _ k not_mem
|
||||
|
||||
theorem getKey!_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{k : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getKey! k = default :=
|
||||
@DHashMap.getKey!_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ _ k not_mem
|
||||
|
||||
/- size -/
|
||||
theorem size_inter_le_size_left [EquivBEq α] [LawfulHashable α] :
|
||||
(m₁ ∩ m₂).size ≤ m₁.size :=
|
||||
@DHashMap.size_inter_le_size_left _ _ _ _ m₁.inner m₂.inner _ _
|
||||
|
||||
theorem size_inter_le_size_right [EquivBEq α] [LawfulHashable α] :
|
||||
(m₁ ∩ m₂).size ≤ m₂.size :=
|
||||
@DHashMap.size_inter_le_size_right _ _ _ _ m₁.inner m₂.inner _ _
|
||||
|
||||
theorem size_inter_eq_size_left [EquivBEq α] [LawfulHashable α]
|
||||
(h : ∀ (a : α), a ∈ m₁ → a ∈ m₂) :
|
||||
(m₁ ∩ m₂).size = m₁.size :=
|
||||
@DHashMap.size_inter_eq_size_left _ _ _ _ m₁.inner m₂.inner _ _ h
|
||||
|
||||
theorem size_inter_eq_size_right [EquivBEq α] [LawfulHashable α]
|
||||
(h : ∀ (a : α), a ∈ m₂ → a ∈ m₁) :
|
||||
(m₁ ∩ m₂).size = m₂.size :=
|
||||
@DHashMap.size_inter_eq_size_right _ _ _ _ m₁.inner m₂.inner _ _ h
|
||||
|
||||
theorem size_add_size_eq_size_union_add_size_inter [EquivBEq α] [LawfulHashable α] :
|
||||
m₁.size + m₂.size = (m₁ ∪ m₂).size + (m₁ ∩ m₂).size :=
|
||||
@DHashMap.size_add_size_eq_size_union_add_size_inter _ _ _ _ m₁.inner m₂.inner _ _
|
||||
|
||||
/- isEmpty -/
|
||||
@[simp]
|
||||
theorem isEmpty_inter_left [EquivBEq α] [LawfulHashable α] (h : m₁.isEmpty) :
|
||||
(m₁ ∩ m₂).isEmpty = true :=
|
||||
@DHashMap.isEmpty_inter_left α _ _ _ m₁.inner m₂.inner _ _ h
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_inter_right [EquivBEq α] [LawfulHashable α] (h : m₂.isEmpty) :
|
||||
(m₁ ∩ m₂).isEmpty = true :=
|
||||
@DHashMap.isEmpty_inter_right α _ _ _ m₁.inner m₂.inner _ _ h
|
||||
|
||||
theorem isEmpty_inter_iff [EquivBEq α] [LawfulHashable α] :
|
||||
(m₁ ∩ m₂).isEmpty ↔ ∀ k, k ∈ m₁ → k ∉ m₂ :=
|
||||
@DHashMap.isEmpty_inter_iff α _ _ _ m₁.inner m₂.inner _ _
|
||||
|
||||
end Inter
|
||||
|
||||
-- As `insertManyIfNewUnit` is really an implementation detail for `HashSet.insertMany`,
|
||||
-- we do not add `@[grind]` annotations to any of its lemmas.
|
||||
|
||||
|
|
|
|||
|
|
@ -234,8 +234,13 @@ instance {m : Type w → Type w'} : ForIn m (Raw α β) (α × β) where
|
|||
@[inline] def union [BEq α] [Hashable α] (m₁ m₂ : Raw α β) : Raw α β :=
|
||||
⟨DHashMap.Raw.union m₁.inner m₂.inner⟩
|
||||
|
||||
@[inherit_doc DHashMap.Raw.inter, inline] def inter [BEq α] [Hashable α] (m₁ m₂ : Raw α β) : Raw α β :=
|
||||
⟨DHashMap.Raw.inter m₁.inner m₂.inner⟩
|
||||
|
||||
instance [BEq α] [Hashable α] : Union (Raw α β) := ⟨union⟩
|
||||
|
||||
instance [BEq α] [Hashable α] : Inter (Raw α β) := ⟨inter⟩
|
||||
|
||||
section Unverified
|
||||
|
||||
@[inline, inherit_doc DHashMap.Raw.filterMap] def filterMap {γ : Type w} (f : α → β → Option γ)
|
||||
|
|
|
|||
|
|
@ -1534,6 +1534,231 @@ theorem isEmpty_union [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ :
|
|||
|
||||
end Union
|
||||
|
||||
section Inter
|
||||
|
||||
variable {β : Type v}
|
||||
|
||||
variable {m₁ m₂ : Raw α β}
|
||||
|
||||
@[simp]
|
||||
theorem inter_eq : m₁.inter m₂ = m₁ ∩ m₂ := by
|
||||
simp only [Inter.inter]
|
||||
|
||||
/- contains -/
|
||||
@[simp]
|
||||
theorem contains_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k : α} :
|
||||
(m₁ ∩ m₂).contains k = (m₁.contains k && m₂.contains k) :=
|
||||
@DHashMap.Raw.contains_inter _ _ _ _ m₁.inner m₂.inner _ _ k h₁.out h₂.out
|
||||
|
||||
/- mem -/
|
||||
@[simp]
|
||||
theorem mem_inter_iff [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k : α} :
|
||||
k ∈ m₁ ∩ m₂ ↔ k ∈ m₁ ∧ k ∈ m₂ :=
|
||||
@DHashMap.Raw.mem_inter_iff _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k
|
||||
|
||||
theorem not_mem_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) {k : α}
|
||||
(not_mem : k ∉ m₁) :
|
||||
k ∉ m₁ ∩ m₂ :=
|
||||
@DHashMap.Raw.not_mem_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
theorem not_mem_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) {k : α}
|
||||
(not_mem : k ∉ m₂) :
|
||||
k ∉ m₁ ∩ m₂ :=
|
||||
@DHashMap.Raw.not_mem_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
/- get? -/
|
||||
theorem get?_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF) {k : α} :
|
||||
get? (m₁ ∩ m₂) k =
|
||||
if k ∈ m₂ then get? m₁ k else none :=
|
||||
@DHashMap.Raw.Const.get?_inter _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k
|
||||
|
||||
theorem get?_inter_of_mem_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
get? (m₁ ∩ m₂) k = get? m₁ k :=
|
||||
@DHashMap.Raw.Const.get?_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k mem
|
||||
|
||||
theorem get?_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (not_mem : k ∉ m₁) :
|
||||
get? (m₁ ∩ m₂) k = none :=
|
||||
@DHashMap.Raw.Const.get?_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
theorem get?_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (not_mem : k ∉ m₂) :
|
||||
get? (m₁ ∩ m₂) k = none :=
|
||||
@DHashMap.Raw.Const.get?_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
/- get -/
|
||||
@[simp] theorem get_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {h_mem : k ∈ m₁ ∩ m₂} :
|
||||
get (m₁ ∩ m₂) k h_mem =
|
||||
get m₁ k ((mem_inter_iff h₁ h₂).1 h_mem).1 :=
|
||||
@DHashMap.Raw.Const.get_inter _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k h_mem
|
||||
|
||||
/- getD -/
|
||||
theorem getD_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {fallback : β} :
|
||||
getD (m₁ ∩ m₂) k fallback =
|
||||
if k ∈ m₂ then getD m₁ k fallback else fallback :=
|
||||
@DHashMap.Raw.Const.getD_inter _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k fallback
|
||||
|
||||
theorem getD_inter_of_mem_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {fallback : β} (mem : k ∈ m₂) :
|
||||
getD (m₁ ∩ m₂) k fallback = getD m₁ k fallback :=
|
||||
@DHashMap.Raw.Const.getD_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k fallback mem
|
||||
|
||||
theorem getD_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {fallback : β} (not_mem : k ∉ m₂) :
|
||||
getD (m₁ ∩ m₂) k fallback = fallback :=
|
||||
@DHashMap.Raw.Const.getD_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k fallback not_mem
|
||||
|
||||
theorem getD_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {fallback : β} (not_mem : k ∉ m₁) :
|
||||
getD (m₁ ∩ m₂) k fallback = fallback :=
|
||||
@DHashMap.Raw.Const.getD_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k fallback not_mem
|
||||
|
||||
/- get! -/
|
||||
theorem get!_inter [EquivBEq α] [LawfulHashable α] [Inhabited β] (h₁ : m₁.WF) (h₂ : m₂.WF) {k : α} :
|
||||
get! (m₁ ∩ m₂) k =
|
||||
if k ∈ m₂ then get! m₁ k else default :=
|
||||
@DHashMap.Raw.Const.get!_inter _ _ _ _ m₁.inner m₂.inner _ _ _ h₁.out h₂.out k
|
||||
|
||||
theorem get!_inter_of_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited β] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
get! (m₁ ∩ m₂) k = get! m₁ k :=
|
||||
@DHashMap.Raw.Const.get!_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ _ h₁.out h₂.out k mem
|
||||
|
||||
theorem get!_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited β] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (not_mem : k ∉ m₂) :
|
||||
get! (m₁ ∩ m₂) k = default :=
|
||||
@DHashMap.Raw.Const.get!_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
theorem get!_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] [Inhabited β] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (not_mem : k ∉ m₁) :
|
||||
get! (m₁ ∩ m₂) k = default :=
|
||||
@DHashMap.Raw.Const.get!_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
/- getKey? -/
|
||||
theorem getKey?_inter [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) {k : α} :
|
||||
(m₁ ∩ m₂).getKey? k =
|
||||
if k ∈ m₂ then m₁.getKey? k else none :=
|
||||
@DHashMap.Raw.getKey?_inter _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k
|
||||
|
||||
theorem getKey?_inter_of_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) {k : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getKey? k = m₁.getKey? k :=
|
||||
@DHashMap.Raw.getKey?_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k mem
|
||||
|
||||
theorem getKey?_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) {k : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getKey? k = none :=
|
||||
@DHashMap.Raw.getKey?_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
theorem getKey?_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) {k : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getKey? k = none :=
|
||||
@DHashMap.Raw.getKey?_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
/- getKey -/
|
||||
@[simp] theorem getKey_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {h_mem : k ∈ m₁ ∩ m₂} :
|
||||
(m₁ ∩ m₂).getKey k h_mem =
|
||||
m₁.getKey k ((mem_inter_iff h₁ h₂).1 h_mem).1 :=
|
||||
@DHashMap.Raw.getKey_inter _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k h_mem
|
||||
|
||||
/- getKeyD -/
|
||||
theorem getKeyD_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k fallback : α} :
|
||||
(m₁ ∩ m₂).getKeyD k fallback =
|
||||
if k ∈ m₂ then m₁.getKeyD k fallback else fallback :=
|
||||
@DHashMap.Raw.getKeyD_inter _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k fallback
|
||||
|
||||
theorem getKeyD_inter_of_mem_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k fallback : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getKeyD k fallback = m₁.getKeyD k fallback :=
|
||||
@DHashMap.Raw.getKeyD_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k fallback mem
|
||||
|
||||
theorem getKeyD_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k fallback : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getKeyD k fallback = fallback :=
|
||||
@DHashMap.Raw.getKeyD_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k fallback not_mem
|
||||
|
||||
theorem getKeyD_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k fallback : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getKeyD k fallback = fallback :=
|
||||
@DHashMap.Raw.getKeyD_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k fallback not_mem
|
||||
|
||||
/- getKey! -/
|
||||
theorem getKey!_inter [EquivBEq α] [LawfulHashable α] [Inhabited α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k : α} :
|
||||
(m₁ ∩ m₂).getKey! k =
|
||||
if k ∈ m₂ then m₁.getKey! k else default :=
|
||||
@DHashMap.Raw.getKey!_inter _ _ _ _ m₁.inner m₂.inner _ _ _ h₁.out h₂.out k
|
||||
|
||||
theorem getKey!_inter_of_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getKey! k = m₁.getKey! k :=
|
||||
@DHashMap.Raw.getKey!_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ _ h₁.out h₂.out k mem
|
||||
|
||||
theorem getKey!_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getKey! k = default :=
|
||||
@DHashMap.Raw.getKey!_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
theorem getKey!_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] [Inhabited α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getKey! k = default :=
|
||||
@DHashMap.Raw.getKey!_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
/- size -/
|
||||
theorem size_inter_le_size_left [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) :
|
||||
(m₁ ∩ m₂).size ≤ m₁.size :=
|
||||
@DHashMap.Raw.size_inter_le_size_left _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out
|
||||
|
||||
theorem size_inter_le_size_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) :
|
||||
(m₁ ∩ m₂).size ≤ m₂.size :=
|
||||
@DHashMap.Raw.size_inter_le_size_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out
|
||||
|
||||
theorem size_inter_eq_size_left [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
(h : ∀ (a : α), a ∈ m₁ → a ∈ m₂) :
|
||||
(m₁ ∩ m₂).size = m₁.size :=
|
||||
@DHashMap.Raw.size_inter_eq_size_left _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out h
|
||||
|
||||
theorem size_inter_eq_size_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
(h : ∀ (a : α), a ∈ m₂ → a ∈ m₁) :
|
||||
(m₁ ∩ m₂).size = m₂.size :=
|
||||
@DHashMap.Raw.size_inter_eq_size_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out h
|
||||
|
||||
theorem size_add_size_eq_size_union_add_size_inter [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) :
|
||||
m₁.size + m₂.size = (m₁ ∪ m₂).size + (m₁ ∩ m₂).size :=
|
||||
@DHashMap.Raw.size_add_size_eq_size_union_add_size_inter _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out
|
||||
|
||||
/- isEmpty -/
|
||||
@[simp]
|
||||
theorem isEmpty_inter_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF) (h : m₁.isEmpty) :
|
||||
(m₁ ∩ m₂).isEmpty = true :=
|
||||
@DHashMap.Raw.isEmpty_inter_left _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out h
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_inter_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF) (h : m₂.isEmpty) :
|
||||
(m₁ ∩ m₂).isEmpty = true :=
|
||||
@DHashMap.Raw.isEmpty_inter_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out h
|
||||
|
||||
theorem isEmpty_inter_iff [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF) :
|
||||
(m₁ ∩ m₂).isEmpty ↔ ∀ k, k ∈ m₁ → k ∉ m₂ :=
|
||||
@DHashMap.Raw.isEmpty_inter_iff _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out
|
||||
|
||||
end Inter
|
||||
|
||||
theorem getElem?_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
|
|
|
|||
|
|
@ -248,6 +248,17 @@ This function always merges the smaller set into the larger set, so the expected
|
|||
|
||||
instance [BEq α] [Hashable α] : Union (HashSet α) := ⟨union⟩
|
||||
|
||||
/--
|
||||
Computes the intersection of the given hash sets. The result will only contain entries from the first map.
|
||||
|
||||
This function always iterates through the smaller set, so the expected runtime is
|
||||
`O(min(m₁.size, m₂.size))`.
|
||||
-/
|
||||
@[inline] def inter [BEq α] [Hashable α] (m₁ m₂ : HashSet α) : HashSet α :=
|
||||
⟨HashMap.inter m₁.inner m₂.inner⟩
|
||||
|
||||
instance [BEq α] [Hashable α] : Inter (HashSet α) := ⟨inter⟩
|
||||
|
||||
section Unverified
|
||||
|
||||
/-! We currently do not provide lemmas for the functions below. -/
|
||||
|
|
|
|||
|
|
@ -922,6 +922,146 @@ theorem isEmpty_union [EquivBEq α] [LawfulHashable α] :
|
|||
|
||||
end Union
|
||||
|
||||
section Inter
|
||||
|
||||
variable {m₁ m₂ : HashSet α}
|
||||
|
||||
@[simp]
|
||||
theorem inter_eq : m₁.inter m₂ = m₁ ∩ m₂ := by
|
||||
simp only [Inter.inter]
|
||||
|
||||
/- contains -/
|
||||
@[simp]
|
||||
theorem contains_inter [EquivBEq α] [LawfulHashable α] {k : α} :
|
||||
(m₁ ∩ m₂).contains k = (m₁.contains k && m₂.contains k) :=
|
||||
@HashMap.contains_inter _ _ _ _ m₁.inner m₂.inner _ _ k
|
||||
|
||||
/- mem -/
|
||||
@[simp]
|
||||
theorem mem_inter_iff [EquivBEq α] [LawfulHashable α] {k : α} :
|
||||
(m₁ ∩ m₂).contains k ↔ m₁.contains k ∧ m₂.contains k :=
|
||||
@HashMap.mem_inter_iff _ _ _ _ m₁.inner m₂.inner _ _ k
|
||||
|
||||
theorem not_mem_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] {k : α}
|
||||
(not_mem : k ∉ m₁) :
|
||||
k ∉ m₁ ∩ m₂ :=
|
||||
@HashMap.not_mem_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ k not_mem
|
||||
|
||||
theorem not_mem_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] {k : α}
|
||||
(not_mem : k ∉ m₂) :
|
||||
k ∉ m₁ ∩ m₂ :=
|
||||
@HashMap.not_mem_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ k not_mem
|
||||
|
||||
/- get? -/
|
||||
theorem get?_inter [EquivBEq α] [LawfulHashable α] {k : α} :
|
||||
(m₁ ∩ m₂).get? k =
|
||||
if k ∈ m₂ then m₁.get? k else none :=
|
||||
@HashMap.getKey?_inter _ _ _ _ m₁.inner m₂.inner _ _ k
|
||||
|
||||
theorem get?_inter_of_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).get? k = m₁.get? k :=
|
||||
@HashMap.getKey?_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ k mem
|
||||
|
||||
theorem get?_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).get? k = none :=
|
||||
@HashMap.getKey?_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ k not_mem
|
||||
|
||||
theorem get?_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).get? k = none :=
|
||||
@HashMap.getKey?_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ k not_mem
|
||||
|
||||
/- get -/
|
||||
@[simp] theorem get_inter [EquivBEq α] [LawfulHashable α]
|
||||
{k : α} {h_mem : k ∈ m₁ ∩ m₂} :
|
||||
(m₁ ∩ m₂).get k h_mem =
|
||||
m₁.get k ((mem_inter_iff.1 h_mem).1) :=
|
||||
@HashMap.getKey_inter _ _ _ _ m₁.inner m₂.inner _ _ k h_mem
|
||||
|
||||
/- getD -/
|
||||
theorem getD_inter [EquivBEq α] [LawfulHashable α] {k fallback : α} :
|
||||
(m₁ ∩ m₂).getD k fallback =
|
||||
if k ∈ m₂ then m₁.getD k fallback else fallback :=
|
||||
@HashMap.getKeyD_inter _ _ _ _ m₁.inner m₂.inner _ _ k fallback
|
||||
|
||||
theorem getD_inter_of_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k fallback : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getD k fallback = m₁.getD k fallback :=
|
||||
@HashMap.getKeyD_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ k fallback mem
|
||||
|
||||
theorem getD_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
{k fallback : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getD k fallback = fallback :=
|
||||
@HashMap.getKeyD_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ k fallback not_mem
|
||||
|
||||
theorem getD_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
{k fallback : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getD k fallback = fallback :=
|
||||
@HashMap.getKeyD_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ k fallback not_mem
|
||||
|
||||
/- get! -/
|
||||
theorem get!_inter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : α} :
|
||||
(m₁ ∩ m₂).get! k =
|
||||
if k ∈ m₂ then m₁.get! k else default :=
|
||||
@HashMap.getKey!_inter _ _ _ _ m₁.inner m₂.inner _ _ _ k
|
||||
|
||||
theorem get!_inter_of_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).get! k = m₁.get! k :=
|
||||
@HashMap.getKey!_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ _ k mem
|
||||
|
||||
theorem get!_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{k : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).get! k = default :=
|
||||
@HashMap.getKey!_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ _ k not_mem
|
||||
|
||||
theorem get!_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{k : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).get! k = default :=
|
||||
@HashMap.getKey!_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ _ k not_mem
|
||||
|
||||
/- size -/
|
||||
theorem size_inter_le_size_left [EquivBEq α] [LawfulHashable α] :
|
||||
(m₁ ∩ m₂).size ≤ m₁.size :=
|
||||
@HashMap.size_inter_le_size_left _ _ _ _ m₁.inner m₂.inner _ _
|
||||
|
||||
theorem size_inter_le_size_right [EquivBEq α] [LawfulHashable α] :
|
||||
(m₁ ∩ m₂).size ≤ m₂.size :=
|
||||
@HashMap.size_inter_le_size_right _ _ _ _ m₁.inner m₂.inner _ _
|
||||
|
||||
theorem size_inter_eq_size_left [EquivBEq α] [LawfulHashable α]
|
||||
(h : ∀ (a : α), a ∈ m₁ → a ∈ m₂) :
|
||||
(m₁ ∩ m₂).size = m₁.size :=
|
||||
@HashMap.size_inter_eq_size_left _ _ _ _ m₁.inner m₂.inner _ _ h
|
||||
|
||||
theorem size_inter_eq_size_right [EquivBEq α] [LawfulHashable α]
|
||||
(h : ∀ (a : α), a ∈ m₂ → a ∈ m₁) :
|
||||
(m₁ ∩ m₂).size = m₂.size :=
|
||||
@HashMap.size_inter_eq_size_right _ _ _ _ m₁.inner m₂.inner _ _ h
|
||||
|
||||
theorem size_add_size_eq_size_union_add_size_inter [EquivBEq α] [LawfulHashable α] :
|
||||
m₁.size + m₂.size = (m₁ ∪ m₂).size + (m₁ ∩ m₂).size :=
|
||||
@HashMap.size_add_size_eq_size_union_add_size_inter _ _ _ _ m₁.inner m₂.inner _ _
|
||||
|
||||
/- isEmpty -/
|
||||
@[simp]
|
||||
theorem isEmpty_inter_left [EquivBEq α] [LawfulHashable α] (h : m₁.isEmpty) :
|
||||
(m₁ ∩ m₂).isEmpty = true :=
|
||||
@HashMap.isEmpty_inter_left α _ _ _ m₁.inner m₂.inner _ _ h
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_inter_right [EquivBEq α] [LawfulHashable α] (h : m₂.isEmpty) :
|
||||
(m₁ ∩ m₂).isEmpty = true :=
|
||||
@HashMap.isEmpty_inter_right α _ _ _ m₁.inner m₂.inner _ _ h
|
||||
|
||||
theorem isEmpty_inter_iff [EquivBEq α] [LawfulHashable α] :
|
||||
(m₁ ∩ m₂).isEmpty ↔ ∀ k, k ∈ m₁ → k ∉ m₂ :=
|
||||
@HashMap.isEmpty_inter_iff α _ _ _ m₁.inner m₂.inner _ _
|
||||
|
||||
end Inter
|
||||
|
||||
section
|
||||
|
||||
@[simp, grind =]
|
||||
|
|
|
|||
|
|
@ -232,14 +232,27 @@ This function always merges the smaller set into the larger set, so the expected
|
|||
|
||||
instance [BEq α] [Hashable α] : Union (Raw α) := ⟨union⟩
|
||||
|
||||
/--
|
||||
Computes the intersection of the given hash sets. The result will only contain entries from the first map.
|
||||
|
||||
This function always merges the smaller set into the larger set, so the expected runtime is
|
||||
`O(min(m₁.size, m₂.size))`.
|
||||
-/
|
||||
@[inline] def inter [BEq α] [Hashable α] (m₁ m₂ : Raw α) : Raw α :=
|
||||
⟨HashMap.Raw.inter m₁.inner m₂.inner⟩
|
||||
|
||||
instance [BEq α] [Hashable α] : Inter (Raw α) := ⟨inter⟩
|
||||
|
||||
section Unverified
|
||||
|
||||
/-! We currently do not provide lemmas for the functions below. -/
|
||||
|
||||
/-- Check if all elements satisfy the predicate, short-circuiting if a predicate fails. -/
|
||||
@[inline] def all (m : Raw α) (p : α → Bool) : Bool := m.inner.all (fun x _ => p x)
|
||||
|
||||
/-- Check if any element satisfies the predicate, short-circuiting if a predicate succeeds. -/
|
||||
@[inline] def any (m : Raw α) (p : α → Bool) : Bool := m.inner.any (fun x _ => p x)
|
||||
|
||||
section Unverified
|
||||
|
||||
/-! We currently do not provide lemmas for the functions below. -/
|
||||
|
||||
/--
|
||||
|
|
|
|||
|
|
@ -968,6 +968,167 @@ theorem isEmpty_union [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ :
|
|||
|
||||
end Union
|
||||
|
||||
section Inter
|
||||
|
||||
variable {m₁ m₂ : Raw α}
|
||||
|
||||
@[simp]
|
||||
theorem inter_eq : m₁.inter m₂ = m₁ ∩ m₂ := by
|
||||
simp only [Inter.inter]
|
||||
|
||||
/- contains -/
|
||||
@[simp]
|
||||
theorem contains_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k : α} :
|
||||
(m₁ ∩ m₂).contains k = (m₁.contains k && m₂.contains k) :=
|
||||
@HashMap.Raw.contains_inter _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k
|
||||
|
||||
/- mem -/
|
||||
@[simp]
|
||||
theorem mem_inter_iff [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k : α} :
|
||||
k ∈ m₁ ∩ m₂ ↔ k ∈ m₁ ∧ k ∈ m₂ :=
|
||||
@HashMap.Raw.mem_inter_iff _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k
|
||||
|
||||
theorem not_mem_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) {k : α}
|
||||
(not_mem : k ∉ m₁) :
|
||||
k ∉ m₁ ∩ m₂ :=
|
||||
@HashMap.Raw.not_mem_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
theorem not_mem_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) {k : α}
|
||||
(not_mem : k ∉ m₂) :
|
||||
k ∉ m₁ ∩ m₂ :=
|
||||
@HashMap.Raw.not_mem_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
/- get? -/
|
||||
theorem get?_inter [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} :
|
||||
(m₁ ∩ m₂).get? k =
|
||||
if k ∈ m₂ then m₁.get? k else none :=
|
||||
@HashMap.Raw.getKey?_inter _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k
|
||||
|
||||
theorem get?_inter_of_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).get? k = m₁.get? k :=
|
||||
@HashMap.Raw.getKey?_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k mem
|
||||
|
||||
theorem get?_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).get? k = none :=
|
||||
@HashMap.Raw.getKey?_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
theorem get?_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).get? k = none :=
|
||||
@HashMap.Raw.getKey?_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
/- get -/
|
||||
@[simp] theorem get_inter [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF)
|
||||
{k : α} {h_mem : k ∈ m₁ ∩ m₂} :
|
||||
(m₁ ∩ m₂).get k h_mem =
|
||||
m₁.get k ((mem_inter_iff h₁ h₂).1 h_mem).1 :=
|
||||
@HashMap.Raw.getKey_inter _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k h_mem
|
||||
|
||||
/- getD -/
|
||||
theorem getD_inter [EquivBEq α]
|
||||
[LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k fallback : α} :
|
||||
(m₁ ∩ m₂).getD k fallback =
|
||||
if k ∈ m₂ then m₁.getD k fallback else fallback :=
|
||||
@HashMap.Raw.getKeyD_inter _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k fallback
|
||||
|
||||
theorem getD_inter_of_mem_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k fallback : α} (mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).getD k fallback = m₁.getD k fallback :=
|
||||
@HashMap.Raw.getKeyD_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k fallback mem
|
||||
|
||||
theorem getD_inter_of_not_mem_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k fallback : α} (not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).getD k fallback = fallback :=
|
||||
@HashMap.Raw.getKeyD_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k fallback not_mem
|
||||
|
||||
theorem getD_inter_of_not_mem_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k fallback : α} (not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).getD k fallback = fallback :=
|
||||
@HashMap.Raw.getKeyD_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out k fallback not_mem
|
||||
|
||||
/- get! -/
|
||||
theorem get!_inter [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
(h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) {k : α} :
|
||||
(m₁ ∩ m₂).get! k =
|
||||
if k ∈ m₂ then m₁.get! k else default :=
|
||||
@HashMap.Raw.getKey!_inter _ _ _ _ m₁.inner m₂.inner _ _ _ h₁.out h₂.out k
|
||||
|
||||
theorem get!_inter_of_mem_right [Inhabited α]
|
||||
[EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF) {k : α}
|
||||
(mem : k ∈ m₂) :
|
||||
(m₁ ∩ m₂).get! k = m₁.get! k :=
|
||||
@HashMap.Raw.getKey!_inter_of_mem_right _ _ _ _ m₁.inner m₂.inner _ _ _ h₁.out h₂.out k mem
|
||||
|
||||
theorem get!_inter_of_not_mem_right [Inhabited α]
|
||||
[EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF) {k : α}
|
||||
(not_mem : k ∉ m₂) :
|
||||
(m₁ ∩ m₂).get! k = default :=
|
||||
@HashMap.Raw.getKey!_inter_of_not_mem_right _ _ _ _ m₁.inner m₂.inner _ _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
theorem get!_inter_of_not_mem_left [Inhabited α]
|
||||
[EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF) {k : α}
|
||||
(not_mem : k ∉ m₁) :
|
||||
(m₁ ∩ m₂).get! k = default :=
|
||||
@HashMap.Raw.getKey!_inter_of_not_mem_left _ _ _ _ m₁.inner m₂.inner _ _ _ h₁.out h₂.out k not_mem
|
||||
|
||||
/- size -/
|
||||
theorem size_inter_le_size_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) :
|
||||
(m₁ ∩ m₂).size ≤ m₁.size :=
|
||||
@HashMap.Raw.size_inter_le_size_left _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out
|
||||
|
||||
theorem size_inter_le_size_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF) :
|
||||
(m₁ ∩ m₂).size ≤ m₂.size :=
|
||||
@HashMap.Raw.size_inter_le_size_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out
|
||||
|
||||
theorem size_inter_eq_size_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF)
|
||||
(h : ∀ (a : α), a ∈ m₁ → a ∈ m₂) :
|
||||
(m₁ ∩ m₂).size = m₁.size :=
|
||||
@HashMap.Raw.size_inter_eq_size_left _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out h
|
||||
|
||||
theorem size_inter_eq_size_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF)
|
||||
(h₂ : m₂.WF)
|
||||
(h : ∀ (a : α), a ∈ m₂ → a ∈ m₁) :
|
||||
(m₁ ∩ m₂).size = m₂.size :=
|
||||
@HashMap.Raw.size_inter_eq_size_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out h
|
||||
|
||||
theorem size_add_size_eq_size_union_add_size_inter [EquivBEq α] [LawfulHashable α]
|
||||
(h₁ : m₁.WF) (h₂ : m₂.WF) :
|
||||
m₁.size + m₂.size = (m₁ ∪ m₂).size + (m₁ ∩ m₂).size :=
|
||||
@HashMap.Raw.size_add_size_eq_size_union_add_size_inter _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out
|
||||
|
||||
/- isEmpty -/
|
||||
@[simp]
|
||||
theorem isEmpty_inter_left [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF) (h : m₁.isEmpty) :
|
||||
(m₁ ∩ m₂).isEmpty = true :=
|
||||
@HashMap.Raw.isEmpty_inter_left _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out h
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_inter_right [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF) (h : m₂.isEmpty) :
|
||||
(m₁ ∩ m₂).isEmpty = true :=
|
||||
@HashMap.Raw.isEmpty_inter_right _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out h
|
||||
|
||||
theorem isEmpty_inter_iff [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h₂ : m₂.WF) :
|
||||
(m₁ ∩ m₂).isEmpty ↔ ∀ k, k ∈ m₁ → k ∉ m₂ :=
|
||||
@HashMap.Raw.isEmpty_inter_iff _ _ _ _ m₁.inner m₂.inner _ _ h₁.out h₂.out
|
||||
|
||||
end Inter
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List α) = ∅ :=
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue