feat: add ofArray to DHashMap/HashMap/HashSet (#11243)
This PR adds `ofArray` to `DHashMap`/`HashMap`/`HashSet` and proves a simp lemma allowing to rewrite `ofArray` to `ofList`. --------- Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
This commit is contained in:
parent
70b4943506
commit
fea55533d9
12 changed files with 142 additions and 2 deletions
|
|
@ -387,10 +387,18 @@ end Unverified
|
|||
DHashMap α β :=
|
||||
insertMany ∅ l
|
||||
|
||||
@[inline, inherit_doc Raw.ofArray] def ofArray [BEq α] [Hashable α] (l : Array ((a : α) × β a)) :
|
||||
DHashMap α β :=
|
||||
insertMany ∅ l
|
||||
|
||||
@[inline, inherit_doc Raw.Const.ofList] def Const.ofList {β : Type v} [BEq α] [Hashable α]
|
||||
(l : List (α × β)) : DHashMap α (fun _ => β) :=
|
||||
Const.insertMany ∅ l
|
||||
|
||||
@[inline, inherit_doc Raw.Const.ofArray] def Const.ofArray {β : Type v} [BEq α] [Hashable α]
|
||||
(l : Array (α × β)) : DHashMap α (fun _ => β) :=
|
||||
Const.insertMany ∅ l
|
||||
|
||||
@[inline, inherit_doc Raw.Const.unitOfList] def Const.unitOfList [BEq α] [Hashable α] (l : List α) :
|
||||
DHashMap α (fun _ => Unit) :=
|
||||
Const.insertManyIfNewUnit ∅ l
|
||||
|
|
|
|||
|
|
@ -133,6 +133,11 @@ theorem ofList_eq [BEq α] [Hashable α] {l : List ((a : α) × β a)} :
|
|||
simp only [Raw.ofList, Raw.insertMany, (Raw.WF.empty).size_buckets_pos ∅, ↓reduceDIte]
|
||||
congr
|
||||
|
||||
theorem ofArray_eq [BEq α] [Hashable α] {a : Array ((a : α) × β a)} :
|
||||
Raw.ofArray a = Raw₀.insertMany Raw₀.emptyWithCapacity a := by
|
||||
simp only [Raw.ofArray, Raw.insertMany, (Raw.WF.empty).size_buckets_pos ∅, ↓reduceDIte]
|
||||
congr
|
||||
|
||||
theorem alter_eq [BEq α] [LawfulBEq α] [Hashable α] {m : Raw α β} (h : m.WF) {k : α} {f : Option (β k) → Option (β k)} :
|
||||
m.alter k f = Raw₀.alter ⟨m, h.size_buckets_pos⟩ k f := by
|
||||
simp [Raw.alter, h.size_buckets_pos]
|
||||
|
|
@ -162,6 +167,11 @@ theorem Const.ofList_eq [BEq α] [Hashable α] {l : List (α × β)} :
|
|||
simp only [Raw.Const.ofList, Raw.Const.insertMany, (Raw.WF.empty).size_buckets_pos ∅, ↓reduceDIte]
|
||||
congr
|
||||
|
||||
theorem Const.ofArray_eq [BEq α] [Hashable α] {a : Array (α × β)} :
|
||||
Raw.Const.ofArray a = Raw₀.Const.insertMany Raw₀.emptyWithCapacity a := by
|
||||
simp only [Raw.Const.ofArray, Raw.Const.insertMany, (Raw.WF.empty).size_buckets_pos ∅, ↓reduceDIte]
|
||||
congr
|
||||
|
||||
theorem Const.insertManyIfNewUnit_eq {ρ : Type w} [ForIn Id ρ α] [BEq α] [Hashable α]
|
||||
{m : Raw α (fun _ => Unit)} {l : ρ} (h : m.WF):
|
||||
Raw.Const.insertManyIfNewUnit m l = Raw₀.Const.insertManyIfNewUnit ⟨m, h.size_buckets_pos⟩ l := by
|
||||
|
|
@ -173,6 +183,12 @@ theorem Const.unitOfList_eq [BEq α] [Hashable α] {l : List α} :
|
|||
↓reduceDIte]
|
||||
congr
|
||||
|
||||
theorem Const.unitOfArray_eq [BEq α] [Hashable α] {a : Array α} :
|
||||
Raw.Const.unitOfArray a = Raw₀.Const.insertManyIfNewUnit Raw₀.emptyWithCapacity a := by
|
||||
simp only [Raw.Const.unitOfArray, Raw.Const.insertManyIfNewUnit, (Raw.WF.empty).size_buckets_pos ∅,
|
||||
↓reduceDIte]
|
||||
congr
|
||||
|
||||
theorem Const.get?_eq [BEq α] [Hashable α] {m : Raw α (fun _ => β)} (h : m.WF) {a : α} :
|
||||
Raw.Const.get? m a = Raw₀.Const.get? ⟨m, h.size_buckets_pos⟩ a := by
|
||||
simp [Raw.Const.get?, h.size_buckets_pos]
|
||||
|
|
|
|||
|
|
@ -1124,6 +1124,18 @@ theorem insertMany_eq_insertListₘ_toListModel [BEq α] [Hashable α] (m m₂ :
|
|||
simp only [List.foldl_cons, insertListₘ]
|
||||
apply ih
|
||||
|
||||
theorem insertMany_array_eq_insertMany_toList [BEq α] [Hashable α] (m : Raw₀ α β) (a : Array ((k : α) × (β k))) :
|
||||
insertMany m a = insertMany m a.toList := by
|
||||
simp only [insertMany, bind_pure_comp, map_pure, bind_pure, ← Array.forIn_toList, forIn_pure_yield_eq_foldl, Array.foldl_toList, Id.run_pure]
|
||||
|
||||
theorem Const.insertMany_array_eq_insertMany_toList [BEq α] [Hashable α] {β : Type v} (m : Raw₀ α fun _ => β) (a : Array (α × β)) :
|
||||
Const.insertMany m a = Const.insertMany m a.toList := by
|
||||
simp only [insertMany, bind_pure_comp, map_pure, bind_pure, ← Array.forIn_toList, forIn_pure_yield_eq_foldl, Array.foldl_toList, Id.run_pure]
|
||||
|
||||
theorem Const.insertManyIfNewUnit_array_eq_insertManyIfNewUnit_toList [BEq α] [Hashable α] (m : Raw₀ α fun _ => Unit) (a : Array α) :
|
||||
Const.insertManyIfNewUnit m a = Const.insertManyIfNewUnit m a.toList := by
|
||||
simp only [insertManyIfNewUnit, bind_pure_comp, map_pure, bind_pure, ← Array.forIn_toList, forIn_pure_yield_eq_foldl, Array.foldl_toList, Id.run_pure]
|
||||
|
||||
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]
|
||||
|
|
|
|||
|
|
@ -2888,6 +2888,11 @@ end DHashMap
|
|||
|
||||
namespace DHashMap
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofArray_eq_ofList (a : Array ((a : α) × (β a))) :
|
||||
ofArray a = ofList a.toList :=
|
||||
ext <| congrArg Subtype.val <| congrArg Subtype.val (Raw₀.insertMany_array_eq_insertMany_toList (α := α) _ a)
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List ((a : α) × (β a))) = ∅ :=
|
||||
|
|
@ -3037,6 +3042,11 @@ namespace Const
|
|||
|
||||
variable {β : Type v}
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofArray_eq_ofList (a : Array (α × β)) :
|
||||
ofArray a = ofList a.toList :=
|
||||
ext <| congrArg Subtype.val <| congrArg Subtype.val (Raw₀.Const.insertMany_array_eq_insertMany_toList (α := α) _ a)
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List (α × β)) = ∅ :=
|
||||
|
|
@ -3182,6 +3192,11 @@ theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α]
|
|||
(ofList l).isEmpty = l.isEmpty :=
|
||||
Raw₀.Const.isEmpty_insertMany_emptyWithCapacity_list
|
||||
|
||||
@[simp, grind =]
|
||||
theorem unitOfArray_eq_unitOfList (a : Array α) :
|
||||
unitOfArray a = unitOfList a.toList :=
|
||||
ext <| congrArg Subtype.val <| congrArg Subtype.val (Raw₀.Const.insertManyIfNewUnit_array_eq_insertManyIfNewUnit_toList (α := α) _ a)
|
||||
|
||||
@[simp]
|
||||
theorem unitOfList_nil :
|
||||
unitOfList ([] : List α) = ∅ :=
|
||||
|
|
|
|||
|
|
@ -607,10 +607,19 @@ occurrence takes precedence. -/
|
|||
@[inline] def ofList [BEq α] [Hashable α] (l : List ((a : α) × β a)) : Raw α β :=
|
||||
insertMany ∅ l
|
||||
|
||||
/-- Creates a hash map from an array of mappings. If the same key appears multiple times, the last
|
||||
occurrence takes precedence. -/
|
||||
@[inline] def ofArray [BEq α] [Hashable α] (l : Array ((a : α) × β a)) : Raw α β :=
|
||||
insertMany ∅ l
|
||||
|
||||
@[inline, inherit_doc Raw.ofList] def Const.ofList {β : Type v} [BEq α] [Hashable α]
|
||||
(l : List (α × β)) : Raw α (fun _ => β) :=
|
||||
Const.insertMany ∅ l
|
||||
|
||||
@[inline, inherit_doc Raw.ofArray] def Const.ofArray {β : Type v} [BEq α] [Hashable α]
|
||||
(l : Array (α × β)) : Raw α (fun _ => β) :=
|
||||
Const.insertMany ∅ l
|
||||
|
||||
/-- Creates a hash map from a list of keys, associating the value `()` with each key.
|
||||
|
||||
This is mainly useful to implement `HashSet.ofList`, so if you are considering using this,
|
||||
|
|
@ -760,6 +769,18 @@ theorem WF.Const.unitOfList [BEq α] [Hashable α] {l : List α} :
|
|||
(Const.unitOfList l : Raw α (fun _ => Unit)).WF :=
|
||||
Const.insertManyIfNewUnit WF.empty
|
||||
|
||||
theorem WF.ofArray [BEq α] [Hashable α] {a : Array ((a : α) × β a)} :
|
||||
(ofArray a : Raw α β).WF :=
|
||||
.insertMany WF.empty
|
||||
|
||||
theorem WF.Const.ofArray {β : Type v} [BEq α] [Hashable α] {a : Array (α × β)} :
|
||||
(Const.ofArray a : Raw α (fun _ => β)).WF :=
|
||||
Const.insertMany WF.empty
|
||||
|
||||
theorem WF.Const.unitOfArray [BEq α] [Hashable α] {a : Array α} :
|
||||
(Const.unitOfArray a : Raw α (fun _ => Unit)).WF :=
|
||||
Const.insertManyIfNewUnit WF.empty
|
||||
|
||||
theorem WF.union₀ [BEq α] [Hashable α] {m₁ m₂ : Raw α β} (h₁ : m₁.WF) (h₂ : m₂.WF) : (Raw₀.union ⟨m₁, h₁.size_buckets_pos⟩ ⟨m₂, h₂.size_buckets_pos⟩).val.WF := by
|
||||
simp only [Raw₀.union]
|
||||
split
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ private meta def baseNames : Array Name :=
|
|||
``get?_eq, ``get_eq, ``get!_eq, ``getD_eq,
|
||||
``Const.get?_eq, ``Const.get_eq, ``Const.getD_eq, ``Const.get!_eq,
|
||||
``getKey?_eq, ``getKey_eq, ``getKey!_eq, ``getKeyD_eq,
|
||||
``insertMany_eq, ``Const.insertMany_eq, ``Const.insertManyIfNewUnit_eq,
|
||||
``ofList_eq, ``Const.ofList_eq, ``Const.unitOfList_eq,
|
||||
``insertMany_eq, ``Const.insertMany_eq, ``Const.insertManyIfNewUnit_eq, ``ofArray_eq, ``Const.ofArray_eq,
|
||||
``ofList_eq, ``Const.ofList_eq, ``Const.unitOfList_eq, ``Const.unitOfArray_eq,
|
||||
``alter_eq, ``Const.alter_eq, ``modify_eq, ``Const.modify_eq, ``union_eq, ``inter_eq]
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
|
|
@ -3340,6 +3340,12 @@ variable [BEq α] [Hashable α]
|
|||
|
||||
open Internal.Raw Internal.Raw₀
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofArray_eq_ofList (a : Array ((a : α) × (β a))) :
|
||||
ofArray a = ofList a.toList := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.insertMany_array_eq_insertMany_toList]
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List ((a : α) × (β a))) = ∅ := by
|
||||
|
|
@ -3492,6 +3498,12 @@ namespace Const
|
|||
|
||||
variable {β : Type v}
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofArray_eq_ofList (a : Array (α × β)) :
|
||||
ofArray a = ofList a.toList := by
|
||||
simp_to_raw
|
||||
rw [Const.insertMany_array_eq_insertMany_toList]
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List (α × β)) = ∅ := by
|
||||
|
|
@ -3640,6 +3652,12 @@ theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α]
|
|||
(ofList l).isEmpty = l.isEmpty := by
|
||||
simp_to_raw using Raw₀.Const.isEmpty_insertMany_emptyWithCapacity_list
|
||||
|
||||
@[simp, grind =]
|
||||
theorem unitOfArray_eq_unitOfList (a : Array α) :
|
||||
unitOfArray a = unitOfList a.toList := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.Const.insertManyIfNewUnit_array_eq_insertManyIfNewUnit_toList]
|
||||
|
||||
@[simp]
|
||||
theorem unitOfList_nil :
|
||||
unitOfList ([] : List α) = ∅ := by
|
||||
|
|
|
|||
|
|
@ -198,6 +198,10 @@ instance [BEq α] [Hashable α] : GetElem? (HashMap α β) α β (fun m a => a
|
|||
HashMap α Unit :=
|
||||
⟨DHashMap.Const.unitOfList l⟩
|
||||
|
||||
@[inline, inherit_doc DHashMap.Const.ofArray] def ofArray [BEq α] [Hashable α] (a : Array (α × β)) :
|
||||
HashMap α β :=
|
||||
⟨DHashMap.Const.ofArray a⟩
|
||||
|
||||
@[inline, inherit_doc DHashMap.Const.toList] def toList (m : HashMap α β) :
|
||||
List (α × β) :=
|
||||
DHashMap.Const.toList m.inner
|
||||
|
|
|
|||
|
|
@ -2105,6 +2105,12 @@ theorem size_ofList_le [EquivBEq α] [LawfulHashable α]
|
|||
|
||||
grind_pattern size_ofList_le => (ofList l).size
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofArray_eq_ofList (a : Array (α × β)) :
|
||||
ofArray a = ofList a.toList := by
|
||||
apply ext
|
||||
apply DHashMap.Const.ofArray_eq_ofList
|
||||
|
||||
@[simp, grind =]
|
||||
theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
|
|
@ -2222,6 +2228,12 @@ theorem size_unitOfList_le [EquivBEq α] [LawfulHashable α]
|
|||
(unitOfList l).size ≤ l.length :=
|
||||
DHashMap.Const.size_unitOfList_le
|
||||
|
||||
@[simp, grind =]
|
||||
theorem unitOfArray_eq_unitOfList (a : Array α) :
|
||||
unitOfArray a = unitOfList a.toList := by
|
||||
apply ext
|
||||
apply DHashMap.Const.unitOfArray_eq_unitOfList
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
|
|
|
|||
|
|
@ -192,6 +192,10 @@ instance [BEq α] [Hashable α] : GetElem? (Raw α β) α β (fun m a => a ∈ m
|
|||
(l : List α) : Raw α Unit :=
|
||||
⟨DHashMap.Raw.Const.unitOfList l⟩
|
||||
|
||||
@[inline, inherit_doc DHashMap.Raw.Const.ofList] def ofArray [BEq α] [Hashable α]
|
||||
(a : Array (α × β)) : Raw α β :=
|
||||
⟨DHashMap.Raw.Const.ofArray a⟩
|
||||
|
||||
@[inline, inherit_doc DHashMap.Raw.Const.alter] def alter [BEq α] [EquivBEq α] [Hashable α]
|
||||
(m : Raw α β) (a : α) (f : Option β → Option β) : Raw α β :=
|
||||
⟨DHashMap.Raw.Const.alter m.inner a f⟩
|
||||
|
|
@ -342,9 +346,15 @@ theorem WF.insertManyIfNewUnit [BEq α] [Hashable α] {ρ : Type w} [ForIn Id ρ
|
|||
theorem WF.ofList [BEq α] [Hashable α] {l : List (α × β)} : (ofList l).WF :=
|
||||
⟨DHashMap.Raw.WF.Const.ofList⟩
|
||||
|
||||
theorem WF.ofArray [BEq α] [Hashable α] {a : Array (α × β)} : (ofArray a).WF :=
|
||||
⟨DHashMap.Raw.WF.Const.ofArray⟩
|
||||
|
||||
theorem WF.unitOfList [BEq α] [Hashable α] {l : List α} : (unitOfList l).WF :=
|
||||
⟨DHashMap.Raw.WF.Const.unitOfList⟩
|
||||
|
||||
theorem WF.unitOfArray [BEq α] [Hashable α] {a : Array α} : (unitOfArray a).WF :=
|
||||
⟨DHashMap.Raw.WF.Const.unitOfArray⟩
|
||||
|
||||
theorem WF.union [BEq α] [Hashable α] {m₁ m₂ : Raw α β} (h₁ : m₁.WF) (h₂ : m₂.WF) : (m₁ ∪ m₂).WF :=
|
||||
⟨DHashMap.Raw.WF.union h₁.out h₂.out⟩
|
||||
|
||||
|
|
|
|||
|
|
@ -2156,6 +2156,12 @@ theorem size_ofList_le [EquivBEq α] [LawfulHashable α]
|
|||
|
||||
grind_pattern size_ofList_le => (ofList l).size
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofArray_eq_ofList (a : Array (α × β)) :
|
||||
ofArray a = ofList a.toList := by
|
||||
apply ext
|
||||
apply DHashMap.Raw.Const.ofArray_eq_ofList
|
||||
|
||||
@[simp, grind =]
|
||||
theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
|
|
@ -2244,6 +2250,12 @@ theorem size_unitOfList_le [EquivBEq α] [LawfulHashable α]
|
|||
(unitOfList l).size ≤ l.length :=
|
||||
DHashMap.Raw.Const.size_unitOfList_le
|
||||
|
||||
@[simp, grind =]
|
||||
theorem unitOfArray_eq_unitOfList (a : Array α) :
|
||||
unitOfArray a = unitOfList a.toList := by
|
||||
apply ext
|
||||
apply DHashMap.Raw.Const.unitOfArray_eq_unitOfList
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
|
|
|
|||
|
|
@ -1086,6 +1086,12 @@ end Inter
|
|||
|
||||
section
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofArray_eq_ofList (a : Array α) :
|
||||
ofArray a = ofList a.toList := by
|
||||
apply ext
|
||||
apply HashMap.unitOfArray_eq_unitOfList
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List α) = ∅ :=
|
||||
|
|
|
|||
|
|
@ -1150,6 +1150,12 @@ theorem isEmpty_inter_iff [EquivBEq α] [LawfulHashable α] (h₁ : m₁.WF) (h
|
|||
|
||||
end Inter
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofArray_eq_ofList (a : Array α) :
|
||||
ofArray a = ofList a.toList := by
|
||||
apply ext
|
||||
apply HashMap.Raw.unitOfArray_eq_unitOfList
|
||||
|
||||
@[simp, grind =]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List α) = ∅ :=
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue