Skip to content

Commit 56b1915

Browse files
committed
Use insertManyIfNew on one side
1 parent 1997048 commit 56b1915

File tree

4 files changed

+137
-8
lines changed

4 files changed

+137
-8
lines changed

src/Std/Data/DHashMap/Internal/Defs.lean

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,9 +422,19 @@ where
422422
r := ⟨r.1.insert a b, fun _ h hm => h (r.2 _ h hm)⟩
423423
return r
424424

425+
/-- Internal implementation detail of the hash map -/
426+
@[inline] def insertManyIfNew {ρ : Type w} [ForIn Id ρ ((a : α) × β a)] [BEq α] [Hashable α]
427+
(m : Raw₀ α β) (l : ρ) : { m' : Raw₀ α β // ∀ (P : Raw₀ α β → Prop),
428+
(∀ {m'' a b}, P m'' → P (m''.insertIfNew a b)) → P m → P m' } := Id.run do
429+
let mut r : { m' : Raw₀ α β // ∀ (P : Raw₀ α β → Prop),
430+
(∀ {m'' a b}, P m'' → P (m''.insertIfNew a b)) → P m → P m' } := ⟨m, fun _ _ => id⟩
431+
for ⟨a, b⟩ in l do
432+
r := ⟨r.1.insertIfNew a b, fun _ h hm => h (r.2 _ h hm)⟩
433+
return r
434+
425435
/-- Internal implementation detail of the hash map -/
426436
@[inline] def union [BEq α] [Hashable α] (m₁ m₂ : Raw₀ α β) : Raw₀ α β :=
427-
if m₁.1.size ≤ m₂.1.size then (m₂.insertMany m₁.1).1 else (m₁.insertMany m₂.1).1
437+
if m₁.1.size ≤ m₂.1.size then (m₂.insertManyIfNew m₁.1).1 else (m₁.insertMany m₂.1).1
428438

429439
section
430440

src/Std/Data/DHashMap/Internal/Model.lean

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,10 +390,16 @@ def insertListₘ [BEq α] [Hashable α] (m : Raw₀ α β) (l : List ((a : α)
390390
| .nil => m
391391
| .cons hd tl => insertListₘ (m.insert hd.1 hd.2) tl
392392

393+
/-- Internal implementation detail of the hash map -/
394+
def insertListIfNewₘ [BEq α] [Hashable α] (m : Raw₀ α β) (l : List ((a : α) × β a)) : Raw₀ α β :=
395+
match l with
396+
| .nil => m
397+
| .cons hd tl => insertListIfNewₘ (m.insertIfNew hd.1 hd.2) tl
398+
393399
/-- Internal implementation detail of the hash map -/
394400
def unionₘ [BEq α] [Hashable α] (m₁ m₂ : Raw₀ α β) : Raw₀ α β :=
395401
if m₁.1.size ≤ m₂.1.size then
396-
insertListₘ m₂ (toListModel m₁.1.buckets)
402+
insertListIfNewₘ m₂ (toListModel m₁.1.buckets)
397403
else
398404
insertListₘ m₁ (toListModel m₂.1.buckets)
399405

@@ -616,6 +622,20 @@ theorem insertMany_eq_insertListₘ [BEq α] [Hashable α] (m : Raw₀ α β) (l
616622
simp only [List.foldl_cons, insertListₘ]
617623
apply ih
618624

625+
theorem insertManyIfNew_eq_insertListIfNewₘ [BEq α] [Hashable α] (m : Raw₀ α β) (l : List ((a : α) × β a)) :
626+
insertManyIfNew m l = insertListIfNewₘ m l := by
627+
simp only [insertManyIfNew, Id.run_pure, Id.run_bind, pure_bind, List.forIn_pure_yield_eq_foldl]
628+
suffices ∀ (t : { m' // ∀ (P : Raw₀ α β → Prop),
629+
(∀ {m'' : Raw₀ α β} {a : α} {b : β a}, P m'' → P (m''.insertIfNew a b)) → P m → P m' }),
630+
(List.foldl (fun m' p => ⟨m'.val.insertIfNew p.1 p.2, fun P h₁ h₂ => h₁ (m'.2 _ h₁ h₂)⟩) t l).val =
631+
t.val.insertListIfNewₘ l from this _
632+
intro t
633+
induction l generalizing m with
634+
| nil => simp [insertListIfNewₘ]
635+
| cons hd tl ih =>
636+
simp only [List.foldl_cons, insertListIfNewₘ]
637+
apply ih
638+
619639
section
620640

621641
variable {β : Type v}

src/Std/Data/DHashMap/Internal/WF.lean

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,20 @@ theorem toListModel_insertListₘ [BEq α] [Hashable α] [EquivBEq α] [LawfulHa
995995
apply Perm.trans (ih (wfImp_insert h))
996996
apply List.insertList_perm_of_perm_first (toListModel_insert h) (wfImp_insert h).distinct
997997

998+
/-! # `insertListₘ` -/
999+
1000+
theorem toListModel_insertListIfNewₘ [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α]
1001+
{m : Raw₀ α β} {l : List ((a : α) × β a)} (h : Raw.WFImp m.1) :
1002+
Perm (toListModel (insertListIfNewₘ m l).1.buckets)
1003+
(List.insertListIfNew (toListModel m.1.buckets) l) := by
1004+
induction l generalizing m with
1005+
| nil =>
1006+
simp [insertListIfNewₘ, List.insertListIfNew]
1007+
| cons hd tl ih =>
1008+
simp only [insertListIfNewₘ, List.insertListIfNew]
1009+
apply Perm.trans (ih (wfImp_insertIfNew h))
1010+
apply List.insertListIfNew_perm_of_perm_first (toListModel_insertIfNew h) (wfImp_insertIfNew h).distinct
1011+
9981012
/-! # `unionₘ` -/
9991013

10001014
theorem insertMany_eq_insertListₘ_toListModel [BEq α] [Hashable α] (m m₂ : Raw₀ α β) :
@@ -1014,17 +1028,39 @@ theorem insertMany_eq_insertListₘ_toListModel [BEq α] [Hashable α] (m m₂ :
10141028
simp only [List.foldl_cons, insertListₘ]
10151029
apply ih
10161030

1031+
1032+
theorem insertManyIfNew_eq_insertListIfNewₘ_toListModel [BEq α] [Hashable α] (m m₂ : Raw₀ α β) :
1033+
insertManyIfNew m m₂.1 = insertListIfNewₘ m (toListModel m₂.1.buckets) := by
1034+
simp only [insertManyIfNew, bind_pure_comp, map_pure, bind_pure]
1035+
simp only [ForIn.forIn]
1036+
simp only [Raw.forIn_eq_forIn_toListModel, forIn_pure_yield_eq_foldl, Id.run_pure]
1037+
generalize toListModel m₂.val.buckets = l
1038+
suffices ∀ (t : { m' // ∀ (P : Raw₀ α β → Prop),
1039+
(∀ {m'' : Raw₀ α β} {a : α} {b : β a}, P m'' → P (m''.insertIfNew a b)) → P m → P m' }),
1040+
(List.foldl (fun m' p => ⟨m'.val.insertIfNew p.1 p.2, fun P h₁ h₂ => h₁ (m'.2 _ h₁ h₂)⟩) t l).val =
1041+
t.val.insertListIfNewₘ l from this _
1042+
intro t
1043+
induction l generalizing m with
1044+
| nil => simp [insertListIfNewₘ]
1045+
| cons hd tl ih =>
1046+
simp only [List.foldl_cons, insertListₘ]
1047+
apply ih
1048+
10171049
theorem union_eq_unionₘ [BEq α] [Hashable α] (m₁ m₂ : Raw₀ α β) :
10181050
union m₁ m₂ = unionₘ m₁ m₂ := by
10191051
rw [union, unionₘ]
1020-
split <;> rw [insertMany_eq_insertListₘ_toListModel]
1052+
split
1053+
· rw [insertManyIfNew_eq_insertListIfNewₘ_toListModel]
1054+
· rw [insertMany_eq_insertListₘ_toListModel]
10211055

10221056
theorem toListModel_unionₘ [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α]
10231057
{m₁ m₂ : Raw₀ α β} (h₁ : Raw.WFImp m₁.1) (h₂ : Raw.WFImp m₂.1) :
10241058
Perm (toListModel (unionₘ m₁ m₂).1.buckets)
10251059
(List.insertSmallerList (toListModel m₁.1.buckets) (toListModel m₂.1.buckets)) := by
10261060
rw [unionₘ, insertSmallerList, h₁.size_eq, h₂.size_eq]
1027-
split <;> exact toListModel_insertListₘ ‹_›
1061+
split
1062+
· exact toListModel_insertListIfNewₘ ‹_›
1063+
· exact toListModel_insertListₘ ‹_›
10281064

10291065
end Raw₀
10301066

@@ -1165,14 +1201,36 @@ theorem toListModel_insertMany_list [BEq α] [Hashable α] [EquivBEq α] [Lawful
11651201
apply toListModel_insertListₘ
11661202
exact h
11671203

1204+
/-! # `insertManyIfNew` -/
1205+
1206+
theorem wfImp_insertManyIfNew [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α] {ρ : Type w}
1207+
[ForIn Id ρ ((a : α) × β a)] {m : Raw₀ α β} {l : ρ} (h : Raw.WFImp m.1) :
1208+
Raw.WFImp (m.insertManyIfNew l).1.1 :=
1209+
Raw.WF.out ((m.insertManyIfNew l).2 _ Raw.WF.insertIfNew₀ (.wf m.2 h))
1210+
1211+
theorem wf_insertManyIfNew₀ [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α] {ρ : Type w}
1212+
[ForIn Id ρ ((a : α) × β a)] {m : Raw α β} {h : 0 < m.buckets.size} {l : ρ} (h' : m.WF) :
1213+
(Raw₀.insertManyIfNew ⟨m, h⟩ l).1.1.WF :=
1214+
(Raw₀.insertManyIfNew ⟨m, h⟩ l).2 _ Raw.WF.insertIfNew₀ h'
1215+
1216+
theorem toListModel_insertManyIfNew_list [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α]
1217+
{m : Raw₀ α β} {l : List ((a : α) × (β a))} (h : Raw.WFImp m.1) :
1218+
Perm (toListModel (insertManyIfNew m l).1.1.buckets)
1219+
(List.insertListIfNew (toListModel m.1.buckets) l) := by
1220+
rw [insertManyIfNew_eq_insertListIfNewₘ]
1221+
apply toListModel_insertListIfNewₘ
1222+
exact h
1223+
11681224
/-! # `union` -/
11691225

11701226
theorem wf_union₀ [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α]
11711227
{m₁ m₂ : Raw α β} {h₁ : 0 < m₁.buckets.size} {h₂ : 0 < m₂.buckets.size} (h'₁ : m₁.WF)
11721228
(h'₂ : m₂.WF) :
11731229
(Raw₀.union ⟨m₁, h₁⟩ ⟨m₂, h₂⟩).1.WF := by
11741230
rw [union]
1175-
split <;> exact wf_insertMany₀ ‹_›
1231+
split
1232+
· exact wf_insertManyIfNew₀ ‹_›
1233+
· exact wf_insertMany₀ ‹_›
11761234

11771235
theorem toListModel_union [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α] {m₁ m₂ : Raw₀ α β}
11781236
(h₁ : Raw.WFImp m₁.1) (h₂ : Raw.WFImp m₂.1) :

src/Std/Data/Internal/List/Associative.lean

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,20 +2972,61 @@ theorem isEmpty_insertList [BEq α]
29722972
rw [insertList, List.isEmpty_cons, ih, isEmpty_insertEntry]
29732973
simp
29742974

2975+
/-- Internal implementation detail of the hash map -/
2976+
def insertListIfNew [BEq α] (l : List ((a : α) × β a)) (toInsert : List ((a : α) × β a)) :
2977+
List ((a : α) × β a) :=
2978+
match toInsert with
2979+
| .nil => l
2980+
| .cons ⟨k, v⟩ tl => insertListIfNew (insertEntryIfNew k v l) tl
2981+
2982+
theorem DistinctKeys.insertListIfNew [BEq α] [PartialEquivBEq α] {l₁ l₂ : List ((a : α) × β a)}
2983+
(h : DistinctKeys l₁) :
2984+
DistinctKeys (insertListIfNew l₁ l₂) := by
2985+
induction l₂ using assoc_induction generalizing l₁
2986+
· simpa [insertListIfNew]
2987+
· rename_i k v t ih
2988+
rw [insertListIfNew.eq_def]
2989+
exact ih h.insertEntryIfNew
2990+
2991+
theorem insertListIfNew_perm_of_perm_first [BEq α] [EquivBEq α] {l1 l2 toInsert : List ((a : α) × β a)}
2992+
(h : Perm l1 l2) (distinct : DistinctKeys l1) :
2993+
Perm (insertListIfNew l1 toInsert) (insertListIfNew l2 toInsert) := by
2994+
induction toInsert generalizing l1 l2 with
2995+
| nil => simp [insertListIfNew, h]
2996+
| cons hd tl ih =>
2997+
simp only [insertListIfNew]
2998+
apply ih (insertEntryIfNew_of_perm distinct h) (DistinctKeys.insertEntryIfNew distinct)
2999+
3000+
theorem containsKey_insertListIfNew [BEq α] [PartialEquivBEq α] {l toInsert : List ((a : α) × β a)}
3001+
{k : α} : containsKey k (List.insertListIfNew l toInsert) =
3002+
(containsKey k l || (toInsert.map Sigma.fst).contains k) := by
3003+
induction toInsert generalizing l with
3004+
| nil => simp only [insertListIfNew, List.map_nil, List.elem_nil, Bool.or_false]
3005+
| cons hd tl ih =>
3006+
unfold insertListIfNew
3007+
rw [ih]
3008+
rw [containsKey_insertEntryIfNew]
3009+
simp only [Bool.or_eq_true, List.map_cons, List.contains_cons]
3010+
rw [BEq.comm]
3011+
conv => left; left; rw [Bool.or_comm]
3012+
rw [Bool.or_assoc]
3013+
29753014
/-- Internal implementation detail of the hash map -/
29763015
def insertSmallerList [BEq α] (l₁ l₂ : List ((a : α) × β a)) : List ((a : α) × β a) :=
2977-
if l₁.length ≤ l₂.length then insertList l₂ l₁ else insertList l₁ l₂
3016+
if l₁.length ≤ l₂.length then insertListIfNew l₂ l₁ else insertList l₁ l₂
29783017

29793018
theorem DistinctKeys.insertSmallerList [BEq α] [PartialEquivBEq α] {l₁ l₂ : List ((a : α) × β a)}
29803019
(h₁ : DistinctKeys l₁) (h₂ : DistinctKeys l₂) : DistinctKeys (insertSmallerList l₁ l₂) := by
29813020
rw [List.insertSmallerList]
2982-
split <;> exact DistinctKeys.insertList ‹_›
3021+
split
3022+
· exact DistinctKeys.insertListIfNew ‹_›
3023+
· exact DistinctKeys.insertList ‹_›
29833024

29843025
theorem containsKey_insertSmallerList [BEq α] [PartialEquivBEq α] {l₁ l₂ : List ((a : α) × β a)}
29853026
{k : α} : containsKey k (List.insertSmallerList l₁ l₂) = (containsKey k l₁ || containsKey k l₂) := by
29863027
rw [List.insertSmallerList]
29873028
split
2988-
· rw [containsKey_insertList, ← containsKey_eq_contains_map_fst, Bool.or_comm]
3029+
· rw [containsKey_insertListIfNew, ← containsKey_eq_contains_map_fst, Bool.or_comm]
29893030
· rw [containsKey_insertList, ← containsKey_eq_contains_map_fst]
29903031

29913032
section

0 commit comments

Comments
 (0)