diff --git a/src/Std/Data/DHashMap/Lemmas.lean b/src/Std/Data/DHashMap/Lemmas.lean index c77466d31b..fd292030f6 100644 --- a/src/Std/Data/DHashMap/Lemmas.lean +++ b/src/Std/Data/DHashMap/Lemmas.lean @@ -16,6 +16,8 @@ This file contains lemmas about `Std.DHashMap`. Most of the lemmas require is to provide an instance of `LawfulBEq α`. -/ +set_option trace.grind.ematch.pattern true + open Std.DHashMap.Internal set_option linter.missingDocs true @@ -29,11 +31,11 @@ namespace Std.DHashMap variable {m : DHashMap α β} -@[simp] +@[simp, grind =] theorem isEmpty_emptyWithCapacity {c} : (emptyWithCapacity c : DHashMap α β).isEmpty := Raw₀.isEmpty_emptyWithCapacity -@[simp] +@[simp, grind =] theorem isEmpty_empty : (∅ : DHashMap α β).isEmpty := isEmpty_emptyWithCapacity @@ -41,7 +43,7 @@ set_option linter.missingDocs false in @[deprecated isEmpty_empty (since := "2025-03-12")] abbrev isEmpty_emptyc := @isEmpty_empty -@[simp] +@[simp, grind =] theorem isEmpty_insert [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : (m.insert k v).isEmpty = false := Raw₀.isEmpty_insert _ m.2 @@ -62,14 +64,14 @@ theorem contains_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == theorem mem_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == b) : a ∈ m ↔ b ∈ m := by simp [← contains_iff_mem, contains_congr hab] -@[simp] +@[simp, grind =] theorem contains_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : DHashMap α β).contains a = false := Raw₀.contains_emptyWithCapacity -@[simp] theorem not_mem_emptyWithCapacity {a : α} {c} : ¬a ∈ (emptyWithCapacity c : DHashMap α β) := by +@[simp, grind] theorem not_mem_emptyWithCapacity {a : α} {c} : ¬a ∈ (emptyWithCapacity c : DHashMap α β) := by simp [mem_iff_contains] -@[simp] theorem contains_empty {a : α} : (∅ : DHashMap α β).contains a = false := +@[simp, grind =] theorem contains_empty {a : α} : (∅ : DHashMap α β).contains a = false := contains_emptyWithCapacity set_option linter.missingDocs false in @@ -113,12 +115,12 @@ theorem isEmpty_iff_forall_not_mem [EquivBEq α] [LawfulHashable α] : Singleton.singleton p = (∅ : DHashMap α β).insert p.1 p.2 := rfl -@[simp] +@[simp, grind =] theorem contains_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} : (m.insert k v).contains a = (k == a || m.contains a) := Raw₀.contains_insert ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem mem_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} : a ∈ m.insert k v ↔ k == a ∨ a ∈ m := by simp [← contains_iff_mem, contains_insert] @@ -137,11 +139,11 @@ theorem contains_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β theorem mem_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : k ∈ m.insert k v := by simp -@[simp] +@[simp, grind =] theorem size_emptyWithCapacity {c} : (emptyWithCapacity c : DHashMap α β).size = 0 := Raw₀.size_emptyWithCapacity -@[simp] +@[simp, grind =] theorem size_empty : (∅ : DHashMap α β).size = 0 := size_emptyWithCapacity @@ -151,7 +153,7 @@ abbrev size_emptyc := @size_empty theorem isEmpty_eq_size_eq_zero : m.isEmpty = (m.size == 0) := rfl -theorem size_insert [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : +@[grind =] theorem size_insert [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : (m.insert k v).size = if k ∈ m then m.size else m.size + 1 := Raw₀.size_insert ⟨m.1, _⟩ m.2 @@ -163,11 +165,11 @@ theorem size_insert_le [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : (m.insert k v).size ≤ m.size + 1 := Raw₀.size_insert_le ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem erase_emptyWithCapacity {k : α} {c : Nat} : (emptyWithCapacity c : DHashMap α β).erase k = emptyWithCapacity c := Subtype.eq (congrArg Subtype.val (Raw₀.erase_emptyWithCapacity (k := k)) :) -@[simp] +@[simp, grind =] theorem erase_empty {k : α} : (∅ : DHashMap α β).erase k = ∅ := erase_emptyWithCapacity @@ -175,17 +177,17 @@ set_option linter.missingDocs false in @[deprecated erase_empty (since := "2025-03-12")] abbrev erase_emptyc := @erase_empty -@[simp] +@[simp, grind =] theorem isEmpty_erase [EquivBEq α] [LawfulHashable α] {k : α} : (m.erase k).isEmpty = (m.isEmpty || (m.size == 1 && m.contains k)) := Raw₀.isEmpty_erase _ m.2 -@[simp] +@[simp, grind =] theorem contains_erase [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k).contains a = (!(k == a) && m.contains a) := Raw₀.contains_erase ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem mem_erase [EquivBEq α] [LawfulHashable α] {k a : α} : a ∈ m.erase k ↔ (k == a) = false ∧ a ∈ m := by simp [← contains_iff_mem, contains_erase] @@ -197,7 +199,7 @@ theorem contains_of_contains_erase [EquivBEq α] [LawfulHashable α] {k a : α} theorem mem_of_mem_erase [EquivBEq α] [LawfulHashable α] {k a : α} : a ∈ m.erase k → a ∈ m := by simp -theorem size_erase [EquivBEq α] [LawfulHashable α] {k : α} : +@[grind =] theorem size_erase [EquivBEq α] [LawfulHashable α] {k : α} : (m.erase k).size = if k ∈ m then m.size - 1 else m.size := Raw₀.size_erase _ m.2 @@ -208,29 +210,29 @@ theorem size_le_size_erase [EquivBEq α] [LawfulHashable α] {k : α} : m.size ≤ (m.erase k).size + 1 := Raw₀.size_le_size_erase ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem containsThenInsert_fst {k : α} {v : β k} : (m.containsThenInsert k v).1 = m.contains k := Raw₀.containsThenInsert_fst _ -@[simp] +@[simp, grind =] theorem containsThenInsert_snd {k : α} {v : β k} : (m.containsThenInsert k v).2 = m.insert k v := Subtype.eq <| (congrArg Subtype.val (Raw₀.containsThenInsert_snd _ (k := k)) :) -@[simp] +@[simp, grind =] theorem containsThenInsertIfNew_fst {k : α} {v : β k} : (m.containsThenInsertIfNew k v).1 = m.contains k := Raw₀.containsThenInsertIfNew_fst _ -@[simp] +@[simp, grind =] theorem containsThenInsertIfNew_snd {k : α} {v : β k} : (m.containsThenInsertIfNew k v).2 = m.insertIfNew k v := Subtype.eq <| (congrArg Subtype.val (Raw₀.containsThenInsertIfNew_snd _ (k := k)) :) -@[simp] +@[simp, grind =] theorem get?_emptyWithCapacity [LawfulBEq α] {a : α} {c} : (emptyWithCapacity c : DHashMap α β).get? a = none := Raw₀.get?_emptyWithCapacity -@[simp] +@[simp, grind =] theorem get?_empty [LawfulBEq α] {a : α} : (∅ : DHashMap α β).get? a = none := get?_emptyWithCapacity @@ -241,7 +243,7 @@ abbrev get?_emptyc := @get?_empty theorem get?_of_isEmpty [LawfulBEq α] {a : α} : m.isEmpty = true → m.get? a = none := Raw₀.get?_of_isEmpty ⟨m.1, _⟩ m.2 -theorem get?_insert [LawfulBEq α] {a k : α} {v : β k} : (m.insert k v).get? a = +@[grind =] theorem get?_insert [LawfulBEq α] {a k : α} {v : β k} : (m.insert k v).get? a = if h : k == a then some (cast (congrArg β (eq_of_beq h)) v) else m.get? a := Raw₀.get?_insert ⟨m.1, _⟩ m.2 @@ -270,7 +272,7 @@ theorem get?_eq_none_of_contains_eq_false [LawfulBEq α] {a : α} : theorem get?_eq_none [LawfulBEq α] {a : α} : ¬a ∈ m → m.get? a = none := by simpa [← contains_iff_mem] using get?_eq_none_of_contains_eq_false -theorem get?_erase [LawfulBEq α] {k a : α} : +@[grind =] theorem get?_erase [LawfulBEq α] {k a : α} : (m.erase k).get? a = if k == a then none else m.get? a := Raw₀.get?_erase ⟨m.1, _⟩ m.2 @@ -282,11 +284,11 @@ namespace Const variable {β : Type v} {m : DHashMap α (fun _ => β)} -@[simp] +@[simp, grind =] theorem get?_emptyWithCapacity {a : α} {c} : get? (emptyWithCapacity c : DHashMap α (fun _ => β)) a = none := Raw₀.Const.get?_emptyWithCapacity -@[simp] +@[simp, grind =] theorem get?_empty {a : α} : get? (∅ : DHashMap α (fun _ => β)) a = none := get?_emptyWithCapacity @@ -298,7 +300,7 @@ theorem get?_of_isEmpty [EquivBEq α] [LawfulHashable α] {a : α} : m.isEmpty = true → get? m a = none := Raw₀.Const.get?_of_isEmpty ⟨m.1, _⟩ m.2 -theorem get?_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : +@[grind =] theorem get?_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : get? (m.insert k v) a = if k == a then some v else get? m a := Raw₀.Const.get?_insert ⟨m.1, _⟩ m.2 @@ -330,7 +332,7 @@ theorem get?_eq_none_of_contains_eq_false [EquivBEq α] [LawfulHashable α] {a : theorem get?_eq_none [EquivBEq α] [LawfulHashable α] {a : α} : ¬a ∈ m → get? m a = none := by simpa [← contains_iff_mem] using get?_eq_none_of_contains_eq_false -theorem get?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : +@[grind =] theorem get?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : Const.get? (m.erase k) a = if k == a then none else get? m a := Raw₀.Const.get?_erase ⟨m.1, _⟩ m.2 @@ -346,7 +348,7 @@ theorem get?_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == b) : end Const -theorem get_insert [LawfulBEq α] {k a : α} {v : β k} {h₁} : +@[grind =] theorem get_insert [LawfulBEq α] {k a : α} {v : β k} {h₁} : (m.insert k v).get a h₁ = if h₂ : k == a then cast (congrArg β (eq_of_beq h₂)) v @@ -359,7 +361,7 @@ theorem get_insert_self [LawfulBEq α] {k : α} {v : β k} : (m.insert k v).get k mem_insert_self = v := Raw₀.get_insert_self ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem get_erase [LawfulBEq α] {k a : α} {h'} : (m.erase k).get a h' = m.get a (mem_of_mem_erase h') := Raw₀.get_erase ⟨m.1, _⟩ m.2 @@ -371,7 +373,7 @@ theorem get_eq_get_get? [LawfulBEq α] {a : α} {h} : m.get a h = (m.get? a).get (mem_iff_isSome_get?.mp h) := by simp only [get?_eq_some_get h, Option.get_some] -theorem get_get? [LawfulBEq α] {a : α} {h} : +@[grind =] theorem get_get? [LawfulBEq α] {a : α} {h} : (m.get? a).get h = m.get a (mem_iff_isSome_get?.mpr h) := get_eq_get_get?.symm @@ -379,7 +381,7 @@ namespace Const variable {β : Type v} {m : DHashMap α (fun _ => β)} -theorem get_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : +@[grind =] theorem get_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : get (m.insert k v) a h₁ = if h₂ : k == a then v else get m a (mem_of_mem_insert h₁ (Bool.eq_false_iff.2 h₂)) := Raw₀.Const.get_insert ⟨m.1, _⟩ m.2 @@ -389,7 +391,7 @@ theorem get_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : get (m.insert k v) k mem_insert_self = v := Raw₀.Const.get_insert_self ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem get_erase [EquivBEq α] [LawfulHashable α] {k a : α} {h'} : get (m.erase k) a h' = get m a (mem_of_mem_erase h') := Raw₀.Const.get_erase ⟨m.1, _⟩ m.2 @@ -402,7 +404,7 @@ theorem get_eq_get_get? [EquivBEq α] [LawfulHashable α] {a : α} {h} : get m a h = (get? m a).get (mem_iff_isSome_get?.mp h) := by simp only [get?_eq_some_get h, Option.get_some] -theorem get_get? [EquivBEq α] [LawfulHashable α] {a : α} {h} : +@[grind =] theorem get_get? [EquivBEq α] [LawfulHashable α] {a : α} {h} : (get? m a).get h = get m a (mem_iff_isSome_get?.mpr h) := get_eq_get_get?.symm @@ -415,12 +417,12 @@ theorem get_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == b) {h end Const -@[simp] +@[simp, grind =] theorem get!_emptyWithCapacity [LawfulBEq α] {a : α} [Inhabited (β a)] {c} : (emptyWithCapacity c : DHashMap α β).get! a = default := Raw₀.get!_emptyWithCapacity -@[simp] +@[simp, grind =] theorem get!_empty [LawfulBEq α] {a : α} [Inhabited (β a)] : (∅ : DHashMap α β).get! a = default := get!_emptyWithCapacity @@ -433,7 +435,7 @@ theorem get!_of_isEmpty [LawfulBEq α] {a : α} [Inhabited (β a)] : m.isEmpty = true → m.get! a = default := Raw₀.get!_of_isEmpty ⟨m.1, _⟩ m.2 -theorem get!_insert [LawfulBEq α] {k a : α} [Inhabited (β a)] {v : β k} : +@[grind =] theorem get!_insert [LawfulBEq α] {k a : α} [Inhabited (β a)] {v : β k} : (m.insert k v).get! a = if h : k == a then cast (congrArg β (eq_of_beq h)) v else m.get! a := Raw₀.get!_insert ⟨m.1, _⟩ m.2 @@ -451,7 +453,7 @@ theorem get!_eq_default [LawfulBEq α] {a : α} [Inhabited (β a)] : ¬a ∈ m → m.get! a = default := by simpa [← contains_iff_mem] using get!_eq_default_of_contains_eq_false -theorem get!_erase [LawfulBEq α] {k a : α} [Inhabited (β a)] : +@[grind =] theorem get!_erase [LawfulBEq α] {k a : α} [Inhabited (β a)] : (m.erase k).get! a = if k == a then default else m.get! a := Raw₀.get!_erase ⟨m.1, _⟩ m.2 @@ -480,12 +482,12 @@ namespace Const variable {β : Type v} {m : DHashMap α (fun _ => β)} -@[simp] +@[simp, grind =] theorem get!_emptyWithCapacity [Inhabited β] {a : α} {c} : get! (emptyWithCapacity c : DHashMap α (fun _ => β)) a = default := Raw₀.Const.get!_emptyWithCapacity -@[simp] +@[simp, grind =] theorem get!_empty [Inhabited β] {a : α} : get! (∅ : DHashMap α (fun _ => β)) a = default := get!_emptyWithCapacity @@ -497,7 +499,7 @@ theorem get!_of_isEmpty [EquivBEq α] [LawfulHashable α] [Inhabited β] {a : α m.isEmpty = true → get! m a = default := Raw₀.Const.get!_of_isEmpty ⟨m.1, _⟩ m.2 -theorem get!_insert [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : +@[grind =] theorem get!_insert [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : get! (m.insert k v) a = if k == a then v else get! m a := Raw₀.Const.get!_insert ⟨m.1, _⟩ m.2 @@ -514,7 +516,7 @@ theorem get!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited β] {a : α ¬a ∈ m → get! m a = default := by simpa [← contains_iff_mem] using get!_eq_default_of_contains_eq_false -theorem get!_erase [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} : +@[grind =] theorem get!_erase [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} : get! (m.erase k) a = if k == a then default else get! m a := Raw₀.Const.get!_erase ⟨m.1, _⟩ m.2 @@ -549,12 +551,12 @@ theorem get!_congr [EquivBEq α] [LawfulHashable α] [Inhabited β] {a b : α} ( end Const -@[simp] +@[simp, grind =] theorem getD_emptyWithCapacity [LawfulBEq α] {a : α} {fallback : β a} {c} : (emptyWithCapacity c : DHashMap α β).getD a fallback = fallback := Raw₀.getD_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getD_empty [LawfulBEq α] {a : α} {fallback : β a} : (∅ : DHashMap α β).getD a fallback = fallback := getD_emptyWithCapacity @@ -567,7 +569,7 @@ theorem getD_of_isEmpty [LawfulBEq α] {a : α} {fallback : β a} : m.isEmpty = true → m.getD a fallback = fallback := Raw₀.getD_of_isEmpty ⟨m.1, _⟩ m.2 -theorem getD_insert [LawfulBEq α] {k a : α} {fallback : β a} {v : β k} : +@[grind =] theorem getD_insert [LawfulBEq α] {k a : α} {fallback : β a} {v : β k} : (m.insert k v).getD a fallback = if h : k == a then cast (congrArg β (eq_of_beq h)) v else m.getD a fallback := Raw₀.getD_insert ⟨m.1, _⟩ m.2 @@ -585,7 +587,7 @@ theorem getD_eq_fallback [LawfulBEq α] {a : α} {fallback : β a} : ¬a ∈ m → m.getD a fallback = fallback := by simpa [← contains_iff_mem] using getD_eq_fallback_of_contains_eq_false -theorem getD_erase [LawfulBEq α] {k a : α} {fallback : β a} : +@[grind =] theorem getD_erase [LawfulBEq α] {k a : α} {fallback : β a} : (m.erase k).getD a fallback = if k == a then fallback else m.getD a fallback := Raw₀.getD_erase ⟨m.1, _⟩ m.2 @@ -618,12 +620,12 @@ namespace Const variable {β : Type v} {m : DHashMap α (fun _ => β)} -@[simp] +@[simp, grind =] theorem getD_emptyWithCapacity {a : α} {fallback : β} {c} : getD (emptyWithCapacity c : DHashMap α (fun _ => β)) a fallback = fallback := Raw₀.Const.getD_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getD_empty {a : α} {fallback : β} : getD (∅ : DHashMap α (fun _ => β)) a fallback = fallback := getD_emptyWithCapacity @@ -636,7 +638,7 @@ theorem getD_of_isEmpty [EquivBEq α] [LawfulHashable α] {a : α} {fallback : m.isEmpty = true → getD m a fallback = fallback := Raw₀.Const.getD_of_isEmpty ⟨m.1, _⟩ m.2 -theorem getD_insert [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : +@[grind =] theorem getD_insert [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : getD (m.insert k v) a fallback = if k == a then v else getD m a fallback := Raw₀.Const.getD_insert ⟨m.1, _⟩ m.2 @@ -653,7 +655,7 @@ theorem getD_eq_fallback [EquivBEq α] [LawfulHashable α] {a : α} {fallback : ¬a ∈ m → getD m a fallback = fallback := by simpa [← contains_iff_mem] using getD_eq_fallback_of_contains_eq_false -theorem getD_erase [EquivBEq α] [LawfulHashable α] {k a : α} {fallback : β} : +@[grind =] theorem getD_erase [EquivBEq α] [LawfulHashable α] {k a : α} {fallback : β} : getD (m.erase k) a fallback = if k == a then fallback else getD m a fallback := Raw₀.Const.getD_erase ⟨m.1, _⟩ m.2 @@ -692,11 +694,11 @@ theorem getD_congr [EquivBEq α] [LawfulHashable α] {a b : α} {fallback : β} end Const -@[simp] +@[simp, grind =] theorem getKey?_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : DHashMap α β).getKey? a = none := Raw₀.getKey?_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getKey?_empty {a : α} : (∅ : DHashMap α β).getKey? a = none := getKey?_emptyWithCapacity @@ -708,7 +710,7 @@ theorem getKey?_of_isEmpty [EquivBEq α] [LawfulHashable α] {a : α} : m.isEmpty = true → m.getKey? a = none := Raw₀.getKey?_of_isEmpty ⟨m.1, _⟩ m.2 -theorem getKey?_insert [EquivBEq α] [LawfulHashable α] {a k : α} {v : β k} : +@[grind =] theorem getKey?_insert [EquivBEq α] [LawfulHashable α] {a k : α} {v : β k} : (m.insert k v).getKey? a = if k == a then some k else m.getKey? a := Raw₀.getKey?_insert ⟨m.1, _⟩ m.2 @@ -746,7 +748,7 @@ theorem getKey?_eq_none_of_contains_eq_false [EquivBEq α] [LawfulHashable α] { theorem getKey?_eq_none [EquivBEq α] [LawfulHashable α] {a : α} : ¬a ∈ m → m.getKey? a = none := by simpa [← contains_iff_mem] using getKey?_eq_none_of_contains_eq_false -theorem getKey?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : +@[grind =] theorem getKey?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k).getKey? a = if k == a then none else m.getKey? a := Raw₀.getKey?_erase ⟨m.1, _⟩ m.2 @@ -769,7 +771,7 @@ theorem getKey?_eq_some_of_contains [LawfulBEq α] {k : α} (h : m.contains k) : theorem getKey?_eq_some [LawfulBEq α] {k : α} (h : k ∈ m) : m.getKey? k = some k := by simpa only [mem_iff_contains] using getKey?_eq_some_of_contains h -theorem getKey_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} {h₁} : +@[grind =] theorem getKey_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} {h₁} : (m.insert k v).getKey a h₁ = if h₂ : k == a then k @@ -782,7 +784,7 @@ theorem getKey_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} (m.insert k v).getKey k mem_insert_self = k := Raw₀.getKey_insert_self ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem getKey_erase [EquivBEq α] [LawfulHashable α] {k a : α} {h'} : (m.erase k).getKey a h' = m.getKey a (mem_of_mem_erase h') := Raw₀.getKey_erase ⟨m.1, _⟩ m.2 @@ -795,7 +797,7 @@ theorem getKey_eq_get_getKey? [EquivBEq α] [LawfulHashable α] {a : α} {h} : m.getKey a h = (m.getKey? a).get (mem_iff_isSome_getKey?.mp h) := by simp only [getKey?_eq_some_getKey h, Option.get_some] -@[simp] +@[simp, grind =] theorem get_getKey? [EquivBEq α] [LawfulHashable α] {a : α} {h} : (m.getKey? a).get h = m.getKey a (mem_iff_isSome_getKey?.mpr h) := getKey_eq_get_getKey?.symm @@ -807,16 +809,16 @@ theorem getKey_congr [EquivBEq α] [LawfulHashable α] {k₁ k₂ : α} (h : k (h₁ : k₁ ∈ m) : m.getKey k₁ h₁ = m.getKey k₂ ((mem_congr h).mp h₁) := Raw₀.getKey_congr ⟨m.1, _⟩ m.2 h h₁ -@[simp] +@[simp, grind =] theorem getKey_eq [LawfulBEq α] {k : α} (h : k ∈ m) : m.getKey k h = k := Raw₀.getKey_eq ⟨m.1, _⟩ m.2 h -@[simp] +@[simp, grind =] theorem getKey!_emptyWithCapacity [Inhabited α] {a : α} {c} : (emptyWithCapacity c : DHashMap α β).getKey! a = default := Raw₀.getKey!_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getKey!_empty [Inhabited α] {a : α} : (∅ : DHashMap α β).getKey! a = default := getKey!_emptyWithCapacity @@ -829,7 +831,7 @@ theorem getKey!_of_isEmpty [EquivBEq α] [LawfulHashable α] [Inhabited α] {a : m.isEmpty = true → m.getKey! a = default := Raw₀.getKey!_of_isEmpty ⟨m.1, _⟩ m.2 -theorem getKey!_insert [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β k} : +@[grind =] theorem getKey!_insert [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β k} : (m.insert k v).getKey! a = if k == a then k else m.getKey! a := Raw₀.getKey!_insert ⟨m.1, _⟩ m.2 @@ -848,7 +850,7 @@ theorem getKey!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited α] {a : ¬a ∈ m → m.getKey! a = default := by simpa [← contains_iff_mem] using getKey!_eq_default_of_contains_eq_false -theorem getKey!_erase [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} : +@[grind =] theorem getKey!_erase [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} : (m.erase k).getKey! a = if k == a then default else m.getKey! a := Raw₀.getKey!_erase ⟨m.1, _⟩ m.2 @@ -884,12 +886,12 @@ theorem getKey!_eq_of_contains [LawfulBEq α] [Inhabited α] {k : α} (h : m.con theorem getKey!_eq_of_mem [LawfulBEq α] [Inhabited α] {k : α} (h : k ∈ m) : m.getKey! k = k := getKey!_eq_of_contains h -@[simp] +@[simp, grind =] theorem getKeyD_emptyWithCapacity {a fallback : α} {c} : (emptyWithCapacity c : DHashMap α β).getKeyD a fallback = fallback := Raw₀.getKeyD_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getKeyD_empty {a fallback : α} : (∅ : DHashMap α β).getKeyD a fallback = fallback := getKeyD_emptyWithCapacity @@ -902,7 +904,7 @@ theorem getKeyD_of_isEmpty [EquivBEq α] [LawfulHashable α] {a fallback : α} : m.isEmpty = true → m.getKeyD a fallback = fallback := Raw₀.getKeyD_of_isEmpty ⟨m.1, _⟩ m.2 -theorem getKeyD_insert [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β k} : +@[grind =] theorem getKeyD_insert [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β k} : (m.insert k v).getKeyD a fallback = if k == a then k else m.getKeyD a fallback := Raw₀.getKeyD_insert ⟨m.1, _⟩ m.2 @@ -921,7 +923,7 @@ theorem getKeyD_eq_fallback [EquivBEq α] [LawfulHashable α] {a fallback : α} ¬a ∈ m → m.getKeyD a fallback = fallback := by simpa [← contains_iff_mem] using getKeyD_eq_fallback_of_contains_eq_false -theorem getKeyD_erase [EquivBEq α] [LawfulHashable α] {k a fallback : α} : +@[grind =] theorem getKeyD_erase [EquivBEq α] [LawfulHashable α] {k a fallback : α} : (m.erase k).getKeyD a fallback = if k == a then fallback else m.getKeyD a fallback := Raw₀.getKeyD_erase ⟨m.1, _⟩ m.2 @@ -962,17 +964,17 @@ theorem getKeyD_eq_of_mem [LawfulBEq α] {k fallback : α} (h : k ∈ m) : m.getKeyD k fallback = k := getKeyD_eq_of_contains h -@[simp] +@[simp, grind =] theorem isEmpty_insertIfNew [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : (m.insertIfNew k v).isEmpty = false := Raw₀.isEmpty_insertIfNew ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem contains_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} : (m.insertIfNew k v).contains a = (k == a || m.contains a) := Raw₀.contains_insertIfNew ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem mem_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} : a ∈ m.insertIfNew k v ↔ k == a ∨ a ∈ m := by simp [← contains_iff_mem, contains_insertIfNew] @@ -1005,6 +1007,7 @@ theorem mem_of_mem_insertIfNew' [EquivBEq α] [LawfulHashable α] {k a : α} {v a ∈ m.insertIfNew k v → ¬((k == a) ∧ ¬k ∈ m) → a ∈ m := by simpa [← contains_iff_mem, -contains_insertIfNew] using contains_of_contains_insertIfNew' +@[grind =] theorem size_insertIfNew [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : (m.insertIfNew k v).size = if k ∈ m then m.size else m.size + 1 := Raw₀.size_insertIfNew ⟨m.1, _⟩ m.2 @@ -1017,23 +1020,27 @@ theorem size_insertIfNew_le [EquivBEq α] [LawfulHashable α] {k : α} {v : β k (m.insertIfNew k v).size ≤ m.size + 1 := Raw₀.size_insertIfNew_le _ m.2 +@[grind =] theorem get?_insertIfNew [LawfulBEq α] {k a : α} {v : β k} : (m.insertIfNew k v).get? a = if h : k == a ∧ ¬k ∈ m then some (cast (congrArg β (eq_of_beq h.1)) v) else m.get? a := by simp only [mem_iff_contains, Bool.not_eq_true] exact Raw₀.get?_insertIfNew ⟨m.1, _⟩ m.2 +@[grind =] theorem get_insertIfNew [LawfulBEq α] {k a : α} {v : β k} {h₁} : (m.insertIfNew k v).get a h₁ = if h₂ : k == a ∧ ¬k ∈ m then cast (congrArg β (eq_of_beq h₂.1)) v else m.get a (mem_of_mem_insertIfNew' h₁ h₂) := by simp only [mem_iff_contains, Bool.not_eq_true] exact Raw₀.get_insertIfNew ⟨m.1, _⟩ m.2 +@[grind =] theorem get!_insertIfNew [LawfulBEq α] {k a : α} [Inhabited (β a)] {v : β k} : (m.insertIfNew k v).get! a = if h : k == a ∧ ¬k ∈ m then cast (congrArg β (eq_of_beq h.1)) v else m.get! a := by simp only [mem_iff_contains, Bool.not_eq_true] exact Raw₀.get!_insertIfNew ⟨m.1, _⟩ m.2 +@[grind =] theorem getD_insertIfNew [LawfulBEq α] {k a : α} {fallback : β a} {v : β k} : (m.insertIfNew k v).getD a fallback = if h : k == a ∧ ¬k ∈ m then cast (congrArg β (eq_of_beq h.1)) v @@ -1045,22 +1052,26 @@ namespace Const variable {β : Type v} {m : DHashMap α (fun _ => β)} +@[grind =] theorem get?_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : get? (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then some v else get? m a := by simp only [mem_iff_contains, Bool.not_eq_true] exact Raw₀.Const.get?_insertIfNew ⟨m.1, _⟩ m.2 +@[grind =] theorem get_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : get (m.insertIfNew k v) a h₁ = if h₂ : k == a ∧ ¬k ∈ m then v else get m a (mem_of_mem_insertIfNew' h₁ h₂) := by simp only [mem_iff_contains, Bool.not_eq_true] exact Raw₀.Const.get_insertIfNew ⟨m.1, _⟩ m.2 +@[grind =] theorem get!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : get! (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then v else get! m a := by simp only [mem_iff_contains, Bool.not_eq_true] exact Raw₀.Const.get!_insertIfNew ⟨m.1, _⟩ m.2 +@[grind =] theorem getD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : getD (m.insertIfNew k v) a fallback = if k == a ∧ ¬k ∈ m then v else getD m a fallback := by @@ -1069,34 +1080,38 @@ theorem getD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {fallback end Const +@[grind =] theorem getKey?_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} : getKey? (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then some k else getKey? m a := by simp [← contains_iff_mem, contains_insertIfNew] exact Raw₀.getKey?_insertIfNew ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} {h₁} : getKey (m.insertIfNew k v) a h₁ = if h₂ : k == a ∧ ¬k ∈ m then k else getKey m a (mem_of_mem_insertIfNew' h₁ h₂) := by simp [← contains_iff_mem, contains_insertIfNew] exact Raw₀.getKey_insertIfNew ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β k} : getKey! (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then k else getKey! m a := by simp [← contains_iff_mem, contains_insertIfNew] exact Raw₀.getKey!_insertIfNew ⟨m.1, _⟩ m.2 +@[grind =] theorem getKeyD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β k} : getKeyD (m.insertIfNew k v) a fallback = if k == a ∧ ¬k ∈ m then k else getKeyD m a fallback := by simp [← contains_iff_mem, contains_insertIfNew] exact Raw₀.getKeyD_insertIfNew ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_fst [LawfulBEq α] {k : α} {v : β k} : (m.getThenInsertIfNew? k v).1 = m.get? k := Raw₀.getThenInsertIfNew?_fst _ -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_snd [LawfulBEq α] {k : α} {v : β k} : (m.getThenInsertIfNew? k v).2 = m.insertIfNew k v := Subtype.eq <| (congrArg Subtype.val (Raw₀.getThenInsertIfNew?_snd _ (k := k)) :) @@ -1105,33 +1120,33 @@ namespace Const variable {β : Type v} {m : DHashMap α (fun _ => β)} -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_fst {k : α} {v : β} : (getThenInsertIfNew? m k v).1 = get? m k := Raw₀.Const.getThenInsertIfNew?_fst _ -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_snd {k : α} {v : β} : (getThenInsertIfNew? m k v).2 = m.insertIfNew k v := Subtype.eq <| (congrArg Subtype.val (Raw₀.Const.getThenInsertIfNew?_snd _ (k := k)) :) end Const -@[simp] +@[simp, grind =] theorem length_keys [EquivBEq α] [LawfulHashable α] : m.keys.length = m.size := Raw₀.length_keys ⟨m.1, m.2.size_buckets_pos⟩ m.2 -@[simp] +@[simp, grind =] theorem isEmpty_keys [EquivBEq α] [LawfulHashable α]: m.keys.isEmpty = m.isEmpty := Raw₀.isEmpty_keys ⟨m.1, m.2.size_buckets_pos⟩ m.2 -@[simp] +@[simp, grind =] theorem contains_keys [EquivBEq α] [LawfulHashable α] {k : α} : m.keys.contains k = m.contains k := Raw₀.contains_keys ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem mem_keys [LawfulBEq α] {k : α} : k ∈ m.keys ↔ k ∈ m := by rw [mem_iff_contains] @@ -1145,7 +1160,7 @@ theorem distinct_keys [EquivBEq α] [LawfulHashable α] : m.keys.Pairwise (fun a b => (a == b) = false) := Raw₀.distinct_keys ⟨m.1, m.2.size_buckets_pos⟩ m.2 -@[simp] +@[simp, grind =] theorem map_fst_toList_eq_keys [EquivBEq α] [LawfulHashable α] : m.toList.map Sigma.fst = m.keys := Raw₀.map_fst_toList_eq_keys ⟨m.1, m.2.size_buckets_pos⟩ @@ -1155,17 +1170,17 @@ theorem map_sigma_fst_toList_eq_keys [EquivBEq α] [LawfulHashable α] : m.toList.map Sigma.fst = m.keys := Raw₀.map_fst_toList_eq_keys ⟨m.1, m.2.size_buckets_pos⟩ -@[simp] +@[simp, grind =] theorem length_toList [EquivBEq α] [LawfulHashable α] : m.toList.length = m.size := Raw₀.length_toList ⟨m.1, m.2.size_buckets_pos⟩ m.2 -@[simp] +@[simp, grind =] theorem isEmpty_toList [EquivBEq α] [LawfulHashable α] : m.toList.isEmpty = m.isEmpty := Raw₀.isEmpty_toList ⟨m.1, m.2.size_buckets_pos⟩ m.2 -@[simp] +@[simp, grind =] theorem mem_toList_iff_get?_eq_some [LawfulBEq α] {k : α} {v : β k} : ⟨k, v⟩ ∈ m.toList ↔ m.get? k = some v := @@ -1196,7 +1211,7 @@ namespace Const variable {β : Type v} {m : DHashMap α (fun _ => β)} -@[simp] +@[simp, grind =] theorem map_fst_toList_eq_keys [EquivBEq α] [LawfulHashable α] : (toList m).map Prod.fst = m.keys := Raw₀.Const.map_fst_toList_eq_keys ⟨m.1, m.2.size_buckets_pos⟩ @@ -1206,17 +1221,17 @@ theorem map_prod_fst_toList_eq_keys [EquivBEq α] [LawfulHashable α] : (toList m).map Prod.fst = m.keys := Raw₀.Const.map_fst_toList_eq_keys ⟨m.1, m.2.size_buckets_pos⟩ -@[simp] +@[simp, grind =] theorem length_toList [EquivBEq α] [LawfulHashable α] : (toList m).length = m.size := Raw₀.Const.length_toList ⟨m.1, m.2.size_buckets_pos⟩ m.2 -@[simp] +@[simp, grind =] theorem isEmpty_toList [EquivBEq α] [LawfulHashable α] : (toList m).isEmpty = m.isEmpty := Raw₀.Const.isEmpty_toList ⟨m.1, m.2.size_buckets_pos⟩ m.2 -@[simp] +@[simp, grind =] theorem mem_toList_iff_get?_eq_some [LawfulBEq α] {k : α} {v : β} : (k, v) ∈ toList m ↔ get? m k = some v := @@ -1271,7 +1286,7 @@ theorem fold_eq_foldl_toList {f : δ → (a : α) → β a → δ} {init : δ} : m.fold f init = m.toList.foldl (fun a b => f a b.1 b.2) init := Raw₀.fold_eq_foldl_toList ⟨m.1, m.2.size_buckets_pos⟩ -@[simp] +@[simp, grind =] theorem forM_eq_forM [Monad m'] [LawfulMonad m'] {f : (a : α) → β a → m' PUnit} : DHashMap.forM f m = ForM.forM m (fun a => f a.1 a.2) := rfl @@ -1279,7 +1294,7 @@ theorem forM_eq_forM_toList [Monad m'] [LawfulMonad m'] {f : (a : α) × β a ForM.forM m f = ForM.forM m.toList f := Raw₀.forM_eq_forM_toList ⟨m.1, m.2.size_buckets_pos⟩ -@[simp] +@[simp, grind =] theorem forIn_eq_forIn [Monad m'] [LawfulMonad m'] {f : (a : α) → β a → δ → m' (ForInStep δ)} {init : δ} : DHashMap.forIn f init m = ForIn.forIn m init (fun a b => f a.1 a.2 b) := rfl @@ -1382,20 +1397,21 @@ end monadic variable {ρ : Type w} [ForIn Id ρ ((a : α) × β a)] -@[simp] +@[simp, grind =] theorem insertMany_nil : m.insertMany [] = m := Subtype.eq (congrArg Subtype.val (Raw₀.insertMany_nil ⟨m.1, m.2.size_buckets_pos⟩) :) -@[simp] +@[simp, grind =] theorem insertMany_list_singleton {k : α} {v : β k} : m.insertMany [⟨k, v⟩] = m.insert k v := Subtype.eq (congrArg Subtype.val (Raw₀.insertMany_list_singleton ⟨m.1, m.2.size_buckets_pos⟩) :) -theorem insertMany_cons {l : List ((a : α) × β a)} {k : α} {v : β k} : +@[grind _=_] theorem insertMany_cons {l : List ((a : α) × β a)} {k : α} {v : β k} : m.insertMany (⟨k, v⟩ :: l) = (m.insert k v).insertMany l := Subtype.eq (congrArg Subtype.val (Raw₀.insertMany_cons ⟨m.1, m.2.size_buckets_pos⟩) :) +@[grind _=_] theorem insertMany_append {l₁ l₂ : List ((a : α) × β a)} : m.insertMany (l₁ ++ l₂) = (m.insertMany l₁).insertMany l₂ := by induction l₁ generalizing m with @@ -1411,13 +1427,13 @@ theorem insertMany_ind {motive : DHashMap α β → Prop} (m : DHashMap α β) ( (fun m a b ⟨h, h'⟩ => ⟨h.insert₀, insert ⟨m, h⟩ a b h'⟩) : ∃ h, motive ⟨(Raw₀.insertMany _ l).1, h⟩).2 -@[simp] +@[simp, grind =] theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} {k : α} : (m.insertMany l).contains k = (m.contains k || (l.map Sigma.fst).contains k) := Raw₀.contains_insertMany_list ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} {k : α} : k ∈ m.insertMany l ↔ k ∈ m ∨ (l.map Sigma.fst).contains k := by @@ -1562,12 +1578,16 @@ theorem size_le_size_insertMany [EquivBEq α] [LawfulHashable α] {l : ρ} : m.size ≤ (m.insertMany l).size := Raw₀.size_le_size_insertMany ⟨m.1, _⟩ m.2 +grind_pattern size_le_size_insertMany => (insertMany m l).size + theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} : (m.insertMany l).size ≤ m.size + l.length := Raw₀.size_insertMany_list_le ⟨m.1, _⟩ m.2 -@[simp] +grind_pattern size_insertMany_list_le => (insertMany m l).size + +@[simp, grind =] theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} : (m.insertMany l).isEmpty = (m.isEmpty && l.isEmpty) := @@ -1582,21 +1602,22 @@ namespace Const variable {β : Type v} {m : DHashMap α (fun _ => β)} variable {ρ : Type w} [ForIn Id ρ (α × β)] -@[simp] +@[simp, grind =] theorem insertMany_nil : insertMany m [] = m := Subtype.eq (congrArg Subtype.val (Raw₀.Const.insertMany_nil ⟨m.1, m.2.size_buckets_pos⟩) :) -@[simp] +@[simp, grind =] theorem insertMany_list_singleton {k : α} {v : β} : insertMany m [⟨k, v⟩] = m.insert k v := Subtype.eq (congrArg Subtype.val (Raw₀.Const.insertMany_list_singleton ⟨m.1, m.2.size_buckets_pos⟩) :) -theorem insertMany_cons {l : List (α × β)} {k : α} {v : β} : +@[grind _=_] theorem insertMany_cons {l : List (α × β)} {k : α} {v : β} : insertMany m (⟨k, v⟩ :: l) = insertMany (m.insert k v) l := Subtype.eq (congrArg Subtype.val (Raw₀.Const.insertMany_cons ⟨m.1, m.2.size_buckets_pos⟩) :) +@[grind _=_] theorem insertMany_append {l₁ l₂ : List (α × β)} : insertMany m (l₁ ++ l₂) = insertMany (insertMany m l₁) l₂ := by induction l₁ generalizing m with @@ -1612,13 +1633,13 @@ theorem insertMany_ind {motive : DHashMap α (fun _ => β) → Prop} (m : DHashM (fun m a b ⟨h, h'⟩ => ⟨h.insert₀, insert ⟨m, h⟩ a b h'⟩) : ∃ h, motive ⟨(Raw₀.Const.insertMany _ l).1, h⟩).2 -@[simp] +@[simp, grind =] theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : (Const.insertMany m l).contains k = (m.contains k || (l.map Prod.fst).contains k) := Raw₀.Const.contains_insertMany_list ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : k ∈ insertMany m l ↔ k ∈ m ∨ (l.map Prod.fst).contains k := by @@ -1709,12 +1730,16 @@ theorem size_le_size_insertMany [EquivBEq α] [LawfulHashable α] {l : ρ} : m.size ≤ (insertMany m l).size := Raw₀.Const.size_le_size_insertMany ⟨m.1, _⟩ m.2 +grind_pattern size_le_size_insertMany => (insertMany m l).size + theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] {l : List (α × β)} : (insertMany m l).size ≤ m.size + l.length := Raw₀.Const.size_insertMany_list_le ⟨m.1, _⟩ m.2 -@[simp] +grind_pattern size_insertMany_list_le => (insertMany m l).size + +@[simp, grind =] theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List (α × β)} : (insertMany m l).isEmpty = (m.isEmpty && l.isEmpty) := @@ -1736,6 +1761,7 @@ theorem get?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] get? (insertMany m l) k' = some v := Raw₀.Const.get?_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem +@[grind =] theorem get?_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : get? (insertMany m l) k = @@ -1974,30 +2000,30 @@ end DHashMap namespace DHashMap -@[simp] +@[simp, grind =] theorem ofList_nil : ofList ([] : List ((a : α) × (β a))) = ∅ := Subtype.eq (congrArg Subtype.val (Raw₀.insertMany_emptyWithCapacity_list_nil (α := α)) :) -@[simp] +@[simp, grind =] theorem ofList_singleton {k : α} {v : β k} : ofList [⟨k, v⟩] = (∅: DHashMap α β).insert k v := Subtype.eq (congrArg Subtype.val (Raw₀.insertMany_emptyWithCapacity_list_singleton (α := α)) :) -theorem ofList_cons {k : α} {v : β k} {tl : List ((a : α) × (β a))} : +@[grind _=_] theorem ofList_cons {k : α} {v : β k} {tl : List ((a : α) × (β a))} : ofList (⟨k, v⟩ :: tl) = ((∅ : DHashMap α β).insert k v).insertMany tl := Subtype.eq (congrArg Subtype.val (Raw₀.insertMany_emptyWithCapacity_list_cons (α := α)) :) theorem ofList_eq_insertMany_empty {l : List ((a : α) × β a)} : ofList l = insertMany (∅ : DHashMap α β) l := rfl -@[simp] +@[simp, grind =] theorem contains_ofList [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} {k : α} : (ofList l).contains k = (l.map Sigma.fst).contains k := Raw₀.contains_insertMany_emptyWithCapacity_list -@[simp] +@[simp, grind =] theorem mem_ofList [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} {k : α} : k ∈ ofList l ↔ (l.map Sigma.fst).contains k := by @@ -2111,7 +2137,9 @@ theorem size_ofList_le [EquivBEq α] [LawfulHashable α] (ofList l).size ≤ l.length := Raw₀.size_insertMany_emptyWithCapacity_list_le -@[simp] +grind_pattern size_ofList_le => (ofList l).size + +@[simp, grind =] theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} : (ofList l).isEmpty = l.isEmpty := @@ -2121,30 +2149,30 @@ namespace Const variable {β : Type v} -@[simp] +@[simp, grind =] theorem ofList_nil : ofList ([] : List (α × β)) = ∅ := Subtype.eq (congrArg Subtype.val (Raw₀.Const.insertMany_emptyWithCapacity_list_nil (α:= α)) :) -@[simp] +@[simp, grind =] theorem ofList_singleton {k : α} {v : β} : ofList [⟨k, v⟩] = (∅ : DHashMap α (fun _ => β)).insert k v := Subtype.eq (congrArg Subtype.val (Raw₀.Const.insertMany_emptyWithCapacity_list_singleton (α:= α)) :) -theorem ofList_cons {k : α} {v : β} {tl : List (α × β)} : +@[grind _=_] theorem ofList_cons {k : α} {v : β} {tl : List (α × β)} : ofList (⟨k, v⟩ :: tl) = insertMany ((∅ : DHashMap α (fun _ => β)).insert k v) tl := Subtype.eq (congrArg Subtype.val (Raw₀.Const.insertMany_emptyWithCapacity_list_cons (α:= α)) :) theorem ofList_eq_insertMany_empty {l : List (α × β)} : ofList l = insertMany (∅ : DHashMap α (fun _ => β)) l := rfl -@[simp] +@[simp, grind =] theorem contains_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : (ofList l).contains k = (l.map Prod.fst).contains k := Raw₀.Const.contains_insertMany_emptyWithCapacity_list -@[simp] +@[simp, grind =] theorem mem_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : k ∈ ofList l ↔ (l.map Prod.fst).contains k := by @@ -2258,7 +2286,9 @@ theorem size_ofList_le [EquivBEq α] [LawfulHashable α] (ofList l).size ≤ l.length := Raw₀.Const.size_insertMany_emptyWithCapacity_list_le -@[simp] +grind_pattern size_ofList_le => (ofList l).size + +@[simp, grind =] theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} : (ofList l).isEmpty = l.isEmpty := @@ -2388,15 +2418,17 @@ theorem isEmpty_alter_eq_isEmpty_erase [LawfulBEq α] {k : α} {f : Option (β k (m.alter k f).isEmpty = ((m.erase k).isEmpty && (f (m.get? k)).isNone) := Raw₀.isEmpty_alter_eq_isEmpty_erase _ m.2 -@[simp] +@[simp, grind =] theorem isEmpty_alter [LawfulBEq α] {k : α} {f : Option (β k) → Option (β k)} : (alter m k f).isEmpty = ((m.isEmpty || (m.size == 1 && m.contains k)) && (f (get? m k)).isNone) := Raw₀.isEmpty_alter _ m.2 +@[grind =] theorem contains_alter [LawfulBEq α] {k k': α} {f : Option (β k) → Option (β k)} : (m.alter k f).contains k' = if k == k' then (f (m.get? k)).isSome else m.contains k' := Raw₀.contains_alter ⟨_, _⟩ m.2 +@[grind =] theorem mem_alter [LawfulBEq α] {k k': α} {f : Option (β k) → Option (β k)} : k' ∈ m.alter k f ↔ if k == k' then (f (m.get? k)).isSome = true else k' ∈ m := by simp only [mem_iff_contains, contains_alter, beq_iff_eq, Bool.ite_eq_true_distrib] @@ -2423,6 +2455,7 @@ theorem mem_alter_of_beq_eq_false [LawfulBEq α] {k k' : α} {f : Option (β k) (h : (k == k') = false) : k' ∈ m.alter k f ↔ k' ∈ m := by simp only [mem_iff_contains, contains_alter_of_beq_eq_false, h] +@[grind =] theorem size_alter [LawfulBEq α] {k : α} {f : Option (β k) → Option (β k)} : (m.alter k f).size = if k ∈ m ∧ (f (m.get? k)).isNone then @@ -2461,6 +2494,7 @@ theorem size_le_size_alter [LawfulBEq α] {k : α} {f : Option (β k) → Option m.size - 1 ≤ (m.alter k f).size := Raw₀.size_le_size_alter ⟨m.1, _⟩ m.2 +@[grind =] theorem get?_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} : (m.alter k f).get? k' = if h : k == k' then @@ -2474,6 +2508,7 @@ theorem get?_alter_self [LawfulBEq α] {k : α} {f : Option (β k) → Option ( (m.alter k f).get? k = f (m.get? k) := by simp only [get?_alter, beq_self_eq_true, reduceDIte, Function.comp_apply, cast_eq] +@[grind =] theorem get_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} {h : k' ∈ m.alter k f} : (m.alter k f).get k' h = @@ -2492,6 +2527,7 @@ theorem get_alter_self [LawfulBEq α] {k : α} {f : Option (β k) → Option (β (m.alter k f).get k h = (f (m.get? k)).get h' := Raw₀.get_alter_self ⟨m.1, _⟩ m.2 +@[grind =] theorem get!_alter [LawfulBEq α] {k k' : α} [hi : Inhabited (β k')] {f : Option (β k) → Option (β k)} : (m.alter k f).get! k' = if heq : k == k' then @@ -2509,6 +2545,7 @@ theorem get!_alter_self [LawfulBEq α] {k : α} [Inhabited (β k)] {f : Option ( (m.alter k f).get! k = (f (m.get? k)).get! := by simp only [get!_alter, beq_self_eq_true, reduceDIte, cast_eq, Option.map_cast_apply] +@[grind =] theorem getD_alter [LawfulBEq α] {k k' : α} {fallback : β k'} {f : Option (β k) → Option (β k)} : (m.alter k f).getD k' fallback = if heq : k == k' then @@ -2522,6 +2559,7 @@ theorem getD_alter_self [LawfulBEq α] {k : α} {fallback : β k} {f : Option ( (m.alter k f).getD k fallback = (f (m.get? k)).getD fallback := Raw₀.getD_alter_self ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey?_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} : (m.alter k f).getKey? k' = if k == k' then @@ -2534,6 +2572,7 @@ theorem getKey?_alter_self [LawfulBEq α] {k : α} {f : Option (β k) → Option (m.alter k f).getKey? k = if (f (m.get? k)).isSome then some k else none := by simp only [getKey?_alter, beq_self_eq_true, ↓reduceIte] +@[grind =] theorem getKey!_alter [LawfulBEq α] [Inhabited α] {k k' : α} {f : Option (β k) → Option (β k)} : (m.alter k f).getKey! k' = if k == k' then @@ -2566,6 +2605,7 @@ theorem getKey_alter_self [LawfulBEq α] [Inhabited α] {k : α} {f : Option (β {h : k ∈ m.alter k f} : (m.alter k f).getKey k h = k := by simp +@[grind =] theorem getKeyD_alter [LawfulBEq α] {k k' fallback : α} {f : Option (β k) → Option (β k)} : (m.alter k f).getKeyD k' fallback = if k == k' then @@ -2589,17 +2629,19 @@ theorem isEmpty_alter_eq_isEmpty_erase [EquivBEq α] [LawfulHashable α] {k : α (Const.alter m k f).isEmpty = ((m.erase k).isEmpty && (f (Const.get? m k)).isNone) := Raw₀.Const.isEmpty_alter_eq_isEmpty_erase _ m.2 -@[simp] +@[simp, grind =] theorem isEmpty_alter [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β → Option β} : (Const.alter m k f).isEmpty = ((m.isEmpty || (m.size == 1 && m.contains k)) && (f (Const.get? m k)).isNone) := Raw₀.Const.isEmpty_alter _ m.2 +@[grind =] theorem contains_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} : (Const.alter m k f).contains k' = if k == k' then (f (Const.get? m k)).isSome else m.contains k' := Raw₀.Const.contains_alter ⟨m.1, _⟩ m.2 +@[grind =] theorem mem_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} : k' ∈ Const.alter m k f ↔ if k == k' then (f (Const.get? m k)).isSome = true else k' ∈ m := by simp only [mem_iff_contains, contains_alter, Bool.ite_eq_true_distrib] @@ -2627,6 +2669,7 @@ theorem mem_alter_of_beq_eq_false [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} (h : (k == k') = false) : k' ∈ Const.alter m k f ↔ k' ∈ m := by simp only [mem_iff_contains, contains_alter_of_beq_eq_false, h] +@[grind =] theorem size_alter [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β → Option β} : (Const.alter m k f).size = if k ∈ m ∧ (f (Const.get? m k)).isNone then @@ -2665,6 +2708,7 @@ theorem size_le_size_alter [EquivBEq α] [LawfulHashable α] {k : α} {f : Optio m.size - 1 ≤ (Const.alter m k f).size := Raw₀.Const.size_le_size_alter ⟨m.1, _⟩ m.2 +@[grind =] theorem get?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} : Const.get? (Const.alter m k f) k' = if k == k' then @@ -2678,6 +2722,7 @@ theorem get?_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Option Const.get? (Const.alter m k f) k = f (Const.get? m k) := by simp [get?_alter] +@[grind =] theorem get_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} {h : k' ∈ Const.alter m k f} : Const.get (Const.alter m k f) k' h = @@ -2696,6 +2741,7 @@ theorem get_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β Const.get (Const.alter m k f) k h = (f (Const.get? m k)).get h' := by simp [get_alter] +@[grind =] theorem get!_alter [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] {f : Option β → Option β} : Const.get! (Const.alter m k f) k' = if k == k' then @@ -2709,6 +2755,7 @@ theorem get!_alter_self [EquivBEq α] [LawfulHashable α] {k : α} [Inhabited β {f : Option β → Option β} : Const.get! (Const.alter m k f) k = (f (Const.get? m k)).get! := by simp [get!_alter] +@[grind =] theorem getD_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} {f : Option β → Option β} : Const.getD (Const.alter m k f) k' fallback = @@ -2724,6 +2771,7 @@ theorem getD_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {fallback : Const.getD (Const.alter m k f) k fallback = (f (Const.get? m k)).getD fallback := by simp [getD_alter] +@[grind =] theorem getKey?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} : (Const.alter m k f).getKey? k' = if k == k' then @@ -2736,6 +2784,7 @@ theorem getKey?_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Optio (Const.alter m k f).getKey? k = if (f (Const.get? m k)).isSome then some k else none := by simp [getKey?_alter] +@[grind =] theorem getKey!_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : Option β → Option β} : (Const.alter m k f).getKey! k' = if k == k' then @@ -2749,6 +2798,7 @@ theorem getKey!_alter_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : (Const.alter m k f).getKey! k = if (f (Const.get? m k)).isSome then k else default := by simp [getKey!_alter] +@[grind =] theorem getKey_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : Option β → Option β} {h : k' ∈ Const.alter m k f} : (Const.alter m k f).getKey k' h = @@ -2765,6 +2815,7 @@ theorem getKey_alter_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : (Const.alter m k f).getKey k h = k := by simp [getKey_alter] +@[grind =] theorem getKeyD_alter [EquivBEq α] [LawfulHashable α] {k k' fallback : α} {f : Option β → Option β} : (Const.alter m k f).getKeyD k' fallback = if k == k' then @@ -2785,24 +2836,25 @@ end Alter section Modify -@[simp] +@[simp, grind =] theorem isEmpty_modify [LawfulBEq α] {k : α} {f : β k → β k} : (m.modify k f).isEmpty = m.isEmpty := Raw₀.isEmpty_modify _ m.2 -@[simp] +@[simp, grind =] theorem contains_modify [LawfulBEq α] {k k': α} {f : β k → β k} : (m.modify k f).contains k' = m.contains k' := Raw₀.contains_modify ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem mem_modify [LawfulBEq α] {k k': α} {f : β k → β k} : k' ∈ m.modify k f ↔ k' ∈ m := by simp only [mem_iff_contains, contains_modify] -@[simp] +@[simp, grind =] theorem size_modify [LawfulBEq α] {k : α} {f : β k → β k} : (m.modify k f).size = m.size := Raw₀.size_modify ⟨m.1, _⟩ m.2 +@[grind =] theorem get?_modify [LawfulBEq α] {k k' : α} {f : β k → β k} : (m.modify k f).get? k' = if h : k == k' then (cast (congrArg (Option ∘ β) (eq_of_beq h)) ((m.get? k).map f)) @@ -2815,6 +2867,7 @@ theorem get?_modify_self [LawfulBEq α] {k : α} {f : β k → β k} : (m.modify k f).get? k = (m.get? k).map f := Raw₀.get?_modify_self ⟨m.1, _⟩ m.2 +@[grind =] theorem get_modify [LawfulBEq α] {k k' : α} {f : β k → β k} (h : k' ∈ m.modify k f) : (m.modify k f).get k' h = @@ -2832,6 +2885,7 @@ theorem get_modify_self [LawfulBEq α] {k : α} {f : β k → β k} {h : k ∈ m (m.modify k f).get k h = f (m.get k h') := Raw₀.get_modify_self ⟨m.1, _⟩ m.2 +@[grind =] theorem get!_modify [LawfulBEq α] {k k' : α} [hi : Inhabited (β k')] {f : β k → β k} : (m.modify k f).get! k' = if heq : k == k' then @@ -2845,6 +2899,7 @@ theorem get!_modify_self [LawfulBEq α] {k : α} [Inhabited (β k)] {f : β k (m.modify k f).get! k = ((m.get? k).map f).get! := Raw₀.get!_modify_self ⟨m.1, _⟩ m.2 +@[grind =] theorem getD_modify [LawfulBEq α] {k k' : α} {fallback : β k'} {f : β k → β k} : (m.modify k f).getD k' fallback = if heq : k == k' then @@ -2858,6 +2913,7 @@ theorem getD_modify_self [LawfulBEq α] {k : α} {fallback : β k} {f : β k → (m.modify k f).getD k fallback = ((m.get? k).map f).getD fallback := Raw₀.getD_modify_self ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey?_modify [LawfulBEq α] {k k' : α} {f : β k → β k} : (m.modify k f).getKey? k' = if k == k' then @@ -2870,6 +2926,7 @@ theorem getKey?_modify_self [LawfulBEq α] {k : α} {f : β k → β k} : (m.modify k f).getKey? k = if k ∈ m then some k else none := Raw₀.getKey?_modify_self ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey!_modify [LawfulBEq α] [Inhabited α] {k k' : α} {f : β k → β k} : (m.modify k f).getKey! k' = if k == k' then @@ -2898,6 +2955,7 @@ theorem getKey_modify_self [LawfulBEq α] [Inhabited α] {k : α} {f : β k → {h : k ∈ m.modify k f} : (m.modify k f).getKey k h = k := Raw₀.getKey_modify_self ⟨m.1, _⟩ m.2 h +@[grind =] theorem getKeyD_modify [LawfulBEq α] {k k' fallback : α} {f : β k → β k} : (m.modify k f).getKeyD k' fallback = if k == k' then @@ -2914,26 +2972,27 @@ namespace Const variable {β : Type v} {m : DHashMap α (fun _ => β)} -@[simp] +@[simp, grind =] theorem isEmpty_modify [EquivBEq α] [LawfulHashable α] {k : α} {f : β → β} : (Const.modify m k f).isEmpty = m.isEmpty := Raw₀.Const.isEmpty_modify _ m.2 -@[simp] +@[simp, grind =] theorem contains_modify [EquivBEq α] [LawfulHashable α] {k k': α} {f : β → β} : (Const.modify m k f).contains k' = m.contains k' := Raw₀.Const.contains_modify ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem mem_modify [EquivBEq α] [LawfulHashable α] {k k': α} {f : β → β} : k' ∈ Const.modify m k f ↔ k' ∈ m := by simp only [mem_iff_contains, contains_modify] -@[simp] +@[simp, grind =] theorem size_modify [EquivBEq α] [LawfulHashable α] {k : α} {f : β → β} : (Const.modify m k f).size = m.size := Raw₀.Const.size_modify ⟨m.1, _⟩ m.2 +@[grind =] theorem get?_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} : Const.get? (Const.modify m k f) k' = if k == k' then Const.get? m k |>.map f @@ -2946,6 +3005,7 @@ theorem get?_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β → Const.get? (Const.modify m k f) k = (Const.get? m k).map f := Raw₀.Const.get?_modify_self ⟨m.1, _⟩ m.2 +@[grind =] theorem get_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} {h : k' ∈ Const.modify m k f} : Const.get (Const.modify m k f) k' h = @@ -2964,6 +3024,7 @@ theorem get_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β → Const.get (Const.modify m k f) k h = f (Const.get m k h') := Raw₀.Const.get_modify_self ⟨m.1, _⟩ m.2 +@[grind =] theorem get!_modify [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] {f : β → β} : Const.get! (Const.modify m k f) k' = if k == k' then @@ -2977,6 +3038,7 @@ theorem get!_modify_self [EquivBEq α] [LawfulHashable α] {k : α} [Inhabited Const.get! (Const.modify m k f) k = ((Const.get? m k).map f).get! := Raw₀.Const.get!_modify_self ⟨m.1, _⟩ m.2 +@[grind =] theorem getD_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} {f : β → β} : Const.getD (Const.modify m k f) k' fallback = if k == k' then @@ -2990,6 +3052,7 @@ theorem getD_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {fallback : Const.getD (Const.modify m k f) k fallback = ((Const.get? m k).map f).getD fallback := Raw₀.Const.getD_modify_self ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey?_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} : (Const.modify m k f).getKey? k' = if k == k' then @@ -3002,6 +3065,7 @@ theorem getKey?_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β (Const.modify m k f).getKey? k = if k ∈ m then some k else none := Raw₀.Const.getKey?_modify_self ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey!_modify [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : β → β} : (Const.modify m k f).getKey! k' = if k == k' then @@ -3014,6 +3078,7 @@ theorem getKey!_modify_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k (Const.modify m k f).getKey! k = if k ∈ m then k else default := Raw₀.Const.getKey!_modify_self ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey_modify [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : β → β} {h : k' ∈ Const.modify m k f} : (Const.modify m k f).getKey k' h = @@ -3029,6 +3094,7 @@ theorem getKey_modify_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : {h : k ∈ Const.modify m k f} : (Const.modify m k f).getKey k h = k := Raw₀.Const.getKey_modify_self ⟨m.1, _⟩ m.2 h +@[grind =] theorem getKeyD_modify [EquivBEq α] [LawfulHashable α] {k k' fallback : α} {f : β → β} : (Const.modify m k f).getKeyD k' fallback = if k == k' then @@ -3298,6 +3364,7 @@ theorem toList_filterMap {f : (a : α) → β a → Option (γ a)} : (m.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩))) := Raw₀.toList_filterMap ⟨m.1, m.2.size_buckets_pos⟩ +@[grind =] theorem isEmpty_filterMap_iff [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} : (m.filterMap f).isEmpty = true ↔ @@ -3310,11 +3377,13 @@ theorem isEmpty_filterMap_eq_false_iff [LawfulBEq α] ∃ (k : α) (h : k ∈ m), (f k (m.get k h)).isSome := Raw₀.isEmpty_filterMap_eq_false_iff ⟨m.1, _⟩ m.2 +@[grind =] theorem contains_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} : (m.filterMap f).contains k = (m.get? k).any (f k · |>.isSome) := Raw₀.contains_filterMap ⟨m.1, _⟩ m.2 +@[grind =] theorem mem_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} : k ∈ m.filterMap f ↔ ∃ h, (f k (m.get k h)).isSome := by @@ -3336,12 +3405,14 @@ theorem size_filterMap_le_size [EquivBEq α] [LawfulHashable α] (m.filterMap f).size ≤ m.size := Raw₀.size_filterMap_le_size ⟨m.1, m.2.size_buckets_pos⟩ m.2 +grind_pattern size_filterMap_le_size => (m.filterMap f).size + theorem size_filterMap_eq_size_iff [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} : (m.filterMap f).size = m.size ↔ ∀ (a : α) (h : a ∈ m), (f a (m.get a h)).isSome := Raw₀.size_filterMap_eq_size_iff ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem get?_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} : (m.filterMap f).get? k = (m.get? k).bind (f k) := @@ -3353,7 +3424,7 @@ theorem isSome_apply_of_mem_filterMap [LawfulBEq α] (f k (m.get k (mem_of_mem_filterMap h'))).isSome := Raw₀.isSome_apply_of_contains_filterMap ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem get_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} {h'} : (m.filterMap f).get k h' = @@ -3361,16 +3432,19 @@ theorem get_filterMap [LawfulBEq α] (isSome_apply_of_mem_filterMap h') := Raw₀.get_filterMap ⟨m.1, _⟩ m.2 +@[grind =] theorem get!_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} [Inhabited (γ k)] : (m.filterMap f).get! k = ((m.get? k).bind (f k)).get! := Raw₀.get!_filterMap ⟨m.1, _⟩ m.2 +@[grind =] theorem getD_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} {fallback : γ k} : (m.filterMap f).getD k fallback = ((m.get? k).bind (f k)).getD fallback := Raw₀.getD_filterMap ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey?_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} : (m.filterMap f).getKey? k = @@ -3378,12 +3452,13 @@ theorem getKey?_filterMap [LawfulBEq α] (f x (m.get x (mem_of_getKey?_eq_some h'))).isSome) := Raw₀.getKey?_filterMap ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem getKey_filterMap [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → Option (γ a)} {k : α} {h'} : (m.filterMap f).getKey k h' = m.getKey k (mem_of_mem_filterMap h') := Raw₀.getKey_filterMap ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey!_filterMap [LawfulBEq α] [Inhabited α] {f : (a : α) → β a → Option (γ a)} {k : α} : (m.filterMap f).getKey! k = @@ -3391,6 +3466,7 @@ theorem getKey!_filterMap [LawfulBEq α] [Inhabited α] (f x (m.get x (mem_of_getKey?_eq_some h'))).isSome)).get! := Raw₀.getKey!_filterMap ⟨m.1, _⟩ m.2 +@[grind =] theorem getKeyD_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k fallback : α} : (m.filterMap f).getKeyD k fallback = @@ -3402,6 +3478,7 @@ namespace Const variable {β : Type v} {γ : Type w} {m : DHashMap α (fun _ => β)} +@[grind =] theorem isEmpty_filterMap_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} : (m.filterMap f).isEmpty ↔ ∀ k h, f (m.getKey k h) (get m k h) = none := @@ -3412,16 +3489,22 @@ theorem isEmpty_filterMap_eq_false_iff [EquivBEq α] [LawfulHashable α] (m.filterMap f).isEmpty = false ↔ ∃ k h, (f (m.getKey k h) (get m k h)).isSome := Raw₀.Const.isEmpty_filterMap_eq_false_iff ⟨m.1, _⟩ m.2 +-- TODO: `contains_filterMap` is missing + +@[grind =] theorem mem_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} : k ∈ m.filterMap f ↔ ∃ h, (f (m.getKey k h) (Const.get m k h)).isSome := Raw₀.Const.contains_filterMap_iff ⟨m.1, _⟩ m.2 +-- TODO: `size_filterMap_le_size` is missing + theorem size_filterMap_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} : (m.filterMap f).size = m.size ↔ ∀ k h, (f (m.getKey k h) (Const.get m k h)).isSome := Raw₀.Const.size_filterMap_eq_size_iff ⟨m.1, _⟩ m.2 +@[grind =] theorem get?_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} : Const.get? (m.filterMap f) k = (Const.get? m k).pbind (fun x h' => @@ -3440,7 +3523,7 @@ theorem isSome_apply_of_mem_filterMap [EquivBEq α] [LawfulHashable α] (Const.get m k (mem_of_mem_filterMap h))).isSome := Raw₀.Const.isSome_apply_of_contains_filterMap ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem get_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} {h} : Const.get (m.filterMap f) k h = @@ -3449,6 +3532,7 @@ theorem get_filterMap [EquivBEq α] [LawfulHashable α] (isSome_apply_of_mem_filterMap h) := Raw₀.Const.get_filterMap ⟨m.1, _⟩ m.2 +@[grind =] theorem get!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited γ] {f : α → β → Option γ} {k : α} : Const.get! (m.filterMap f) k = @@ -3461,6 +3545,7 @@ theorem get!_filterMap_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inh Const.get! (m.filterMap f) k = ((Const.get? m k).bind (f k')).get! := Raw₀.Const.get!_filterMap_of_getKey?_eq_some ⟨m.1, _⟩ m.2 h +@[grind =] theorem getD_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} {fallback : γ} : Const.getD (m.filterMap f) k fallback = @@ -3479,6 +3564,7 @@ theorem toList_filterMap ((Const.toList m).filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x)))) := Raw₀.Const.toList_filterMap ⟨m.1, m.2.size_buckets_pos⟩ +@[grind =] theorem getKey?_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} : (m.filterMap f).getKey? k = @@ -3486,6 +3572,7 @@ theorem getKey?_filterMap [EquivBEq α] [LawfulHashable α] (f x (Const.get m x (mem_of_getKey?_eq_some h'))).isSome) := Raw₀.Const.getKey?_filterMap ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → Option γ} {k : α} : (m.filterMap f).getKey! k = @@ -3493,6 +3580,7 @@ theorem getKey!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited α] (f x (Const.get m x (mem_of_getKey?_eq_some h'))).isSome)).get! := Raw₀.Const.getKey!_filterMap ⟨m.1, _⟩ m.2 +@[grind =] theorem getKeyD_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k fallback : α} : (m.filterMap f).getKeyD k fallback = @@ -3518,6 +3606,7 @@ theorem keys_filter_key {f : α → Bool} : (m.filter fun k _ => f k).keys.Perm (m.keys.filter f) := Raw₀.keys_filter_key ⟨m.1, m.2.size_buckets_pos⟩ +@[grind =] theorem isEmpty_filter_iff [LawfulBEq α] {f : (a : α) → β a → Bool} : (m.filter f).isEmpty = true ↔ @@ -3542,11 +3631,13 @@ theorem isEmpty_filter_key_eq_false_iff [EquivBEq α] [LawfulHashable α] ∃ (k : α) (h : k ∈ m), f (m.getKey k h) := Raw₀.isEmpty_filter_key_eq_false_iff ⟨m.1, _⟩ m.2 +@[grind =] theorem contains_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} : (m.filter f).contains k = (m.get? k).any (f k) := Raw₀.contains_filter ⟨m.1, _⟩ m.2 +@[grind =] theorem mem_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} : k ∈ m.filter f ↔ ∃ h, f k (m.get k h) := by @@ -3573,6 +3664,8 @@ theorem size_filter_le_size [EquivBEq α] [LawfulHashable α] (m.filter f).size ≤ m.size := Raw₀.size_filter_le_size ⟨m.1, m.2.size_buckets_pos⟩ m.2 +grind_pattern size_filter_le_size => (m.filter f).size + theorem size_filter_eq_size_iff [LawfulBEq α] {f : (a : α) → β a → Bool} : (m.filter f).size = m.size ↔ ∀ k h, f k (m.get k h) := @@ -3595,23 +3688,25 @@ theorem size_filter_key_eq_size_iff [EquivBEq α] [LawfulHashable α] (m.filter fun k _ => f k).size = m.size ↔ ∀ (k : α) (h : k ∈ m), f (m.getKey k h) := Raw₀.size_filter_key_eq_size_iff ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem get?_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} : (m.filter f).get? k = (m.get? k).filter (f k) := Raw₀.get?_filter ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem get_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} {h'} : (m.filter f).get k h' = m.get k (mem_of_mem_filter h') := Raw₀.get_filter ⟨m.1, _⟩ m.2 +@[grind =] theorem get!_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} [Inhabited (β k)] : (m.filter f).get! k = ((m.get? k).filter (f k)).get! := Raw₀.get!_filter ⟨m.1, _⟩ m.2 +@[grind =] theorem getD_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} {fallback : β k} : (m.filter f).getD k fallback = ((m.get? k).filter (f k)).getD fallback := @@ -3622,6 +3717,7 @@ theorem keys_filter [LawfulBEq α] {f : (a : α) → β a → Bool} : (m.keys.attach.filter (fun ⟨x, h'⟩ => f x (m.get x (mem_of_mem_keys h')))).unattach := Raw₀.keys_filter ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey?_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} : (m.filter f).getKey? k = @@ -3634,12 +3730,13 @@ theorem getKey?_filter_key [EquivBEq α] [LawfulHashable α] (m.filter fun k _ => f k).getKey? k = (m.getKey? k).filter f := Raw₀.getKey?_filter_key ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem getKey_filter [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → Bool} {k : α} {h'} : (m.filter f).getKey k h' = m.getKey k (mem_of_mem_filter h') := Raw₀.getKey_filter ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey!_filter [LawfulBEq α] [Inhabited α] {f : (a : α) → β a → Bool} {k : α} : (m.filter f).getKey! k = @@ -3652,6 +3749,7 @@ theorem getKey!_filter_key [EquivBEq α] [LawfulHashable α] [Inhabited α] (m.filter fun k _ => f k).getKey! k = ((m.getKey? k).filter f).get! := Raw₀.getKey!_filter_key ⟨m.1, _⟩ m.2 +@[grind =] theorem getKeyD_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k fallback : α} : (m.filter f).getKeyD k fallback = @@ -3668,6 +3766,7 @@ namespace Const variable {β : Type v} {γ : Type w} {m : DHashMap α (fun _ => β)} +@[grind =] theorem isEmpty_filter_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} : (m.filter f).isEmpty = true ↔ @@ -3680,6 +3779,9 @@ theorem isEmpty_filter_eq_false_iff [EquivBEq α] [LawfulHashable α] ∃ (k : α) (h : k ∈ m), (f (m.getKey k h) (Const.get m k h)) = true := Raw₀.Const.isEmpty_filter_eq_false_iff ⟨m.1, _⟩ m.2 +-- TODO: `contains_filter` is missing + +@[grind =] theorem mem_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} : k ∈ m.filter f ↔ ∃ (h' : k ∈ m), @@ -3691,6 +3793,8 @@ theorem size_filter_le_size [EquivBEq α] [LawfulHashable α] (m.filter f).size ≤ m.size := Raw₀.Const.size_filter_le_size ⟨m.1, m.2.size_buckets_pos⟩ m.2 +grind_pattern size_filter_le_size => (m.filter f).size + theorem size_filter_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} : (m.filter f).size = m.size ↔ ∀ (a : α) (h : a ∈ m), @@ -3703,6 +3807,7 @@ theorem filter_equiv_self_iff [EquivBEq α] [LawfulHashable α] ⟨fun h => (Raw₀.Const.filter_equiv_self_iff ⟨m.1, _⟩ m.2).mp h.1, fun h => ⟨(Raw₀.Const.filter_equiv_self_iff ⟨m.1, _⟩ m.2).mpr h⟩ ⟩ +@[grind =] theorem get?_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} : Const.get? (m.filter f) k = (Const.get? m k).pfilter (fun x h' => @@ -3715,12 +3820,13 @@ theorem get?_filter_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] Const.get? (m.filter f) k = (Const.get? m k).filter (fun x => f k' x) := Raw₀.Const.get?_filter_of_getKey?_eq_some ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem get_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} {h'} : Const.get (m.filter f) k h' = Const.get m k (mem_of_mem_filter h') := Raw₀.Const.get_filter ⟨m.1, _⟩ m.2 +@[grind =] theorem get!_filter [EquivBEq α] [LawfulHashable α] [Inhabited β] {f : α → β → Bool} {k : α} : Const.get! (m.filter f) k = @@ -3734,6 +3840,7 @@ theorem get!_filter_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhabi Const.get! (m.filter f) k = ((Const.get? m k).filter (fun x => f k' x)).get! := Raw₀.Const.get!_filter_of_getKey?_eq_some ⟨m.1, _⟩ m.2 +@[grind =] theorem getD_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} {fallback : β} : Const.getD (m.filter f) k fallback = ((Const.get? m k).pfilter (fun x h' => @@ -3757,6 +3864,7 @@ theorem keys_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} : (m.keys.attach.filter (fun ⟨x, h'⟩ => f x (get m x (mem_of_mem_keys h')))).unattach := Raw₀.Const.keys_filter ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey?_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} : (m.filter f).getKey? k = @@ -3764,6 +3872,7 @@ theorem getKey?_filter [EquivBEq α] [LawfulHashable α] (f x (Const.get m x (mem_of_getKey?_eq_some h')))) := Raw₀.Const.getKey?_filter ⟨m.1, _⟩ m.2 +@[grind =] theorem getKey!_filter [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → Bool} {k : α} : (m.filter f).getKey! k = @@ -3771,6 +3880,7 @@ theorem getKey!_filter [EquivBEq α] [LawfulHashable α] [Inhabited α] (f x (Const.get m x (mem_of_getKey?_eq_some h'))))).get! := Raw₀.Const.getKey!_filter ⟨m.1, _⟩ m.2 +@[grind =] theorem getKeyD_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k fallback : α} : (m.filter f).getKeyD k fallback = @@ -3805,12 +3915,13 @@ theorem filterMap_equiv_map [EquivBEq α] [LawfulHashable α] (m.filterMap (fun k v => some (f k v))) ~m m.map f := ⟨Raw₀.filterMap_equiv_map ⟨m.1, m.2.size_buckets_pos⟩ m.2⟩ -@[simp] +@[simp, grind =] theorem isEmpty_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} : (m.map f).isEmpty = m.isEmpty := Raw₀.isEmpty_map ⟨m.1, m.2.size_buckets_pos⟩ m.2 +@[grind =] theorem contains_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k : α} : (m.map f).contains k = m.contains k := @@ -3821,7 +3932,7 @@ theorem contains_of_contains_map [EquivBEq α] [LawfulHashable α] (m.map f).contains k = true → m.contains k = true := Raw₀.contains_of_contains_map ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem mem_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k : α} : k ∈ m.map f ↔ k ∈ m := by @@ -3832,53 +3943,55 @@ theorem mem_of_mem_map [EquivBEq α] [LawfulHashable α] k ∈ m.map f → k ∈ m := Raw₀.contains_of_contains_map ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem size_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} : (m.map f).size = m.size := Raw₀.size_map ⟨m.1, m.2.size_buckets_pos⟩ m.2 -@[simp] +@[simp, grind =] theorem get?_map [LawfulBEq α] {f : (a : α) → β a → γ a} {k : α} : (m.map f).get? k = (m.get? k).map (f k) := Raw₀.get?_map ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem get_map [LawfulBEq α] {f : (a : α) → β a → γ a} {k : α} {h'} : (m.map f).get k h' = f k (m.get k (mem_of_mem_map h')) := Raw₀.get_map ⟨m.1, _⟩ m.2 +@[grind =] theorem get!_map [LawfulBEq α] {f : (a : α) → β a → γ a} {k : α} [Inhabited (γ k)] : (m.map f).get! k = ((m.get? k).map (f k)).get! := Raw₀.get!_map ⟨m.1, _⟩ m.2 +@[grind =] theorem getD_map [LawfulBEq α] {f : (a : α) → β a → γ a} {k : α} {fallback : γ k} : (m.map f).getD k fallback = ((m.get? k).map (f k)).getD fallback := Raw₀.getD_map ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem getKey?_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k : α} : (m.map f).getKey? k = m.getKey? k := Raw₀.getKey?_map ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem getKey_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k : α} {h'} : (m.map f).getKey k h' = m.getKey k (mem_of_mem_map h') := Raw₀.getKey_map ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem getKey!_map [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : (a : α) → β a → γ a} {k : α} : (m.map f).getKey! k = m.getKey! k := Raw₀.getKey!_map ⟨m.1, _⟩ m.2 -@[simp] +@[simp, grind =] theorem getKeyD_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k fallback : α} : (m.map f).getKeyD k fallback = m.getKeyD k fallback := @@ -3888,7 +4001,7 @@ namespace Const variable {β : Type v} {γ : Type w} {m : DHashMap α fun _ => β} -@[simp] +@[simp, grind =] theorem get?_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} : Const.get? (m.map f) k = (Const.get? m k).map (f k) := @@ -3907,7 +4020,7 @@ theorem get?_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] Const.get? (m.map f) k = (Const.get? m k).map (f k') := Raw₀.Const.get?_map_of_getKey?_eq_some ⟨m.1, _⟩ m.2 h -@[simp] +@[simp, grind =] theorem get_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} {h'} : Const.get (m.map f) k h' = f k (Const.get m k (mem_of_mem_map h')) := @@ -3921,6 +4034,7 @@ theorem get_map' [EquivBEq α] [LawfulHashable α] f (m.getKey k (mem_of_mem_map h')) (Const.get m k (mem_of_mem_map h')) := Raw₀.Const.get_map' ⟨m.1, _⟩ m.2 +@[grind =] theorem get!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ] {f : α → β → γ} {k : α} : Const.get! (m.map f) k = ((Const.get? m k).map (f k)).get! := @@ -3939,6 +4053,7 @@ theorem get!_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhabited Const.get! (m.map f) k = ((Const.get? m k).map (f k')).get! := Raw₀.Const.get!_map_of_getKey?_eq_some ⟨m.1, _⟩ m.2 h +@[grind =] theorem getD_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} {fallback : γ} : Const.getD (m.map f) k fallback = ((Const.get? m k).map (f k)).getD fallback := diff --git a/src/Std/Data/DHashMap/RawLemmas.lean b/src/Std/Data/DHashMap/RawLemmas.lean index cb29135508..8c465e2aa5 100644 --- a/src/Std/Data/DHashMap/RawLemmas.lean +++ b/src/Std/Data/DHashMap/RawLemmas.lean @@ -15,6 +15,8 @@ This file contains lemmas about `Std.Data.DHashMap.Raw`. Most of the lemmas requ is to provide an instance of `LawfulBEq α`. -/ +set_option trace.grind.ematch.pattern true + open Std.DHashMap.Internal set_option linter.missingDocs true @@ -65,11 +67,11 @@ open Internal.Raw₀ Internal.Raw variable {m : Raw α β} -@[simp] +@[simp, grind =] theorem size_emptyWithCapacity {c} : (emptyWithCapacity c : Raw α β).size = 0 := by simp_to_raw using Raw₀.size_emptyWithCapacity -@[simp] +@[simp, grind =] theorem size_empty : (∅ : Raw α β).size = 0 := size_emptyWithCapacity @@ -82,11 +84,11 @@ theorem isEmpty_eq_size_eq_zero : m.isEmpty = (m.size == 0) := by variable [BEq α] [Hashable α] -@[simp] +@[simp, grind =] theorem isEmpty_emptyWithCapacity {c} : (emptyWithCapacity c : Raw α β).isEmpty := by simp_to_raw using Raw₀.isEmpty_emptyWithCapacity -@[simp] +@[simp, grind =] theorem isEmpty_empty : (∅ : Raw α β).isEmpty := isEmpty_emptyWithCapacity @@ -94,7 +96,7 @@ set_option linter.missingDocs false in @[deprecated isEmpty_empty (since := "2025-03-11")] abbrev isEmpty_emptyc := @isEmpty_empty -@[simp] +@[simp, grind =] theorem isEmpty_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v : β k} : (m.insert k v).isEmpty = false := by simp_to_raw using Raw₀.isEmpty_insert @@ -114,13 +116,13 @@ theorem mem_congr [EquivBEq α] [LawfulHashable α] (h : m.WF) {a b : α} (hab : a ∈ m ↔ b ∈ m := by simp [← contains_iff_mem, contains_congr h hab] -@[simp] theorem contains_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : Raw α β).contains a = false := by +@[simp, grind =] theorem contains_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : Raw α β).contains a = false := by simp_to_raw using Raw₀.contains_emptyWithCapacity -@[simp] theorem not_mem_emptyWithCapacity {a : α} {c} : ¬a ∈ (emptyWithCapacity c : Raw α β) := by +@[simp, grind] theorem not_mem_emptyWithCapacity {a : α} {c} : ¬a ∈ (emptyWithCapacity c : Raw α β) := by simp [mem_iff_contains] -@[simp] theorem contains_empty {a : α} : (∅ : Raw α β).contains a = false := +@[simp, grind =] theorem contains_empty {a : α} : (∅ : Raw α β).contains a = false := contains_emptyWithCapacity set_option linter.missingDocs false in @@ -164,12 +166,12 @@ theorem isEmpty_iff_forall_not_mem [EquivBEq α] [LawfulHashable α] (h : m.WF) Singleton.singleton p = (∅ : Raw α β).insert p.1 p.2 := rfl -@[simp] +@[simp, grind =] theorem contains_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {a k : α} {v : β k} : (m.insert k v).contains a = (k == a || m.contains a) := by simp_to_raw using Raw₀.contains_insert -@[simp] +@[simp, grind =] theorem mem_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β k} : a ∈ m.insert k v ↔ k == a ∨ a ∈ m := by simp [← contains_iff_mem, contains_insert h] @@ -192,7 +194,7 @@ theorem mem_insert_self [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v k ∈ m.insert k v := by simp [mem_iff_contains, contains_insert_self h] -theorem size_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v : β k} : +@[grind =] theorem size_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v : β k} : (m.insert k v).size = if k ∈ m then m.size else m.size + 1 := by simp only [mem_iff_contains] simp_to_raw using Raw₀.size_insert @@ -205,12 +207,12 @@ theorem size_insert_le [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v (m.insert k v).size ≤ m.size + 1 := by simp_to_raw using Raw₀.size_insert_le ⟨m, _⟩ h -@[simp] +@[simp, grind =] theorem erase_emptyWithCapacity {k : α} {c : Nat} : (emptyWithCapacity c : Raw α β).erase k = emptyWithCapacity c := by rw [erase_eq (by wf_trivial)] exact congrArg Subtype.val Raw₀.erase_emptyWithCapacity -@[simp] +@[simp, grind =] theorem erase_empty {k : α} : (∅ : Raw α β).erase k = ∅ := erase_emptyWithCapacity @@ -218,17 +220,17 @@ set_option linter.missingDocs false in @[deprecated erase_empty (since := "2025-03-11")] abbrev erase_emptyc := @erase_empty -@[simp] +@[simp, grind =] theorem isEmpty_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} : (m.erase k).isEmpty = (m.isEmpty || (m.size == 1 && m.contains k)) := by simp_to_raw using Raw₀.isEmpty_erase -@[simp] +@[simp, grind =] theorem contains_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : (m.erase k).contains a = (!(k == a) && m.contains a) := by simp_to_raw using Raw₀.contains_erase -@[simp] +@[simp, grind =] theorem mem_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : a ∈ m.erase k ↔ (k == a) = false ∧ a ∈ m := by simp [← contains_iff_mem, contains_erase h] @@ -241,7 +243,7 @@ theorem mem_of_mem_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} a ∈ m.erase k → a ∈ m := by simpa [← contains_iff_mem] using contains_of_contains_erase h -theorem size_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} : +@[grind =] theorem size_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} : (m.erase k).size = if k ∈ m then m.size - 1 else m.size := by simp only [mem_iff_contains] simp_to_raw using Raw₀.size_erase @@ -254,31 +256,31 @@ theorem size_le_size_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} m.size ≤ (m.erase k).size + 1 := by simp_to_raw using Raw₀.size_le_size_erase ⟨m, _⟩ -@[simp] +@[simp, grind =] theorem containsThenInsert_fst (h : m.WF) {k : α} {v : β k} : (m.containsThenInsert k v).1 = m.contains k := by simp_to_raw using Raw₀.containsThenInsert_fst -@[simp] +@[simp, grind =] theorem containsThenInsert_snd (h : m.WF) {k : α} {v : β k} : (m.containsThenInsert k v).2 = m.insert k v := by simp_to_raw using congrArg Subtype.val (Raw₀.containsThenInsert_snd _) -@[simp] +@[simp, grind =] theorem containsThenInsertIfNew_fst (h : m.WF) {k : α} {v : β k} : (m.containsThenInsertIfNew k v).1 = m.contains k := by simp_to_raw using Raw₀.containsThenInsertIfNew_fst -@[simp] +@[simp, grind =] theorem containsThenInsertIfNew_snd (h : m.WF) {k : α} {v : β k} : (m.containsThenInsertIfNew k v).2 = m.insertIfNew k v := by simp_to_raw using congrArg Subtype.val (Raw₀.containsThenInsertIfNew_snd _) -@[simp] +@[simp, grind =] theorem get?_emptyWithCapacity [LawfulBEq α] {a : α} {c} : (emptyWithCapacity c : Raw α β).get? a = none := by simp_to_raw using Raw₀.get?_emptyWithCapacity -@[simp] +@[simp, grind =] theorem get?_empty [LawfulBEq α] {a : α} : (∅ : Raw α β).get? a = none := get?_emptyWithCapacity @@ -289,7 +291,7 @@ abbrev get?_emptyc := @get?_empty theorem get?_of_isEmpty [LawfulBEq α] (h : m.WF) {a : α} : m.isEmpty = true → m.get? a = none := by simp_to_raw using Raw₀.get?_of_isEmpty ⟨m, _⟩ -theorem get?_insert [LawfulBEq α] (h : m.WF) {a k : α} {v : β k} : (m.insert k v).get? a = +@[grind =] theorem get?_insert [LawfulBEq α] (h : m.WF) {a k : α} {v : β k} : (m.insert k v).get? a = if h : k == a then some (cast (congrArg β (eq_of_beq h)) v) else m.get? a := by simp_to_raw using Raw₀.get?_insert @@ -323,7 +325,7 @@ theorem get?_eq_none_of_contains_eq_false [LawfulBEq α] (h : m.WF) {a : α} : theorem get?_eq_none [LawfulBEq α] (h : m.WF) {a : α} : ¬a ∈ m → m.get? a = none := by simpa [← contains_iff_mem] using get?_eq_none_of_contains_eq_false h -theorem get?_erase [LawfulBEq α] (h : m.WF) {k a : α} : +@[grind =] theorem get?_erase [LawfulBEq α] (h : m.WF) {k a : α} : (m.erase k).get? a = if k == a then none else m.get? a := by simp_to_raw using Raw₀.get?_erase @@ -335,11 +337,11 @@ namespace Const variable {β : Type v} {m : DHashMap.Raw α (fun _ => β)} (h : m.WF) -@[simp] +@[simp, grind =] theorem get?_emptyWithCapacity {a : α} {c} : get? (emptyWithCapacity c : Raw α (fun _ => β)) a = none := by simp_to_raw using Raw₀.Const.get?_emptyWithCapacity -@[simp] +@[simp, grind =] theorem get?_empty {a : α} : get? (∅ : Raw α (fun _ => β)) a = none := get?_emptyWithCapacity @@ -351,7 +353,7 @@ theorem get?_of_isEmpty [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} : m.isEmpty = true → get? m a = none := by simp_to_raw using Raw₀.Const.get?_of_isEmpty ⟨m, _⟩ -theorem get?_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : +@[grind =] theorem get?_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : get? (m.insert k v) a = if k == a then some v else get? m a := by simp_to_raw using Raw₀.Const.get?_insert @@ -387,7 +389,7 @@ theorem get?_eq_none [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} : ¬a ∈ m → get? m a = none := by simpa [← contains_iff_mem] using get?_eq_none_of_contains_eq_false h -theorem get?_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : +@[grind =] theorem get?_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : Const.get? (m.erase k) a = if k == a then none else get? m a := by simp_to_raw using Raw₀.Const.get?_erase @@ -405,7 +407,7 @@ theorem get?_congr [EquivBEq α] [LawfulHashable α] (h : m.WF) {a b : α} (hab end Const -theorem get_insert [LawfulBEq α] (h : m.WF) {k a : α} {v : β k} {h₁} : +@[grind =] theorem get_insert [LawfulBEq α] (h : m.WF) {k a : α} {v : β k} {h₁} : (m.insert k v).get a h₁ = if h₂ : k == a then cast (congrArg β (eq_of_beq h₂)) v @@ -418,7 +420,7 @@ theorem get_insert_self [LawfulBEq α] (h : m.WF) {k : α} {v : β k} : (m.insert k v).get k (mem_insert_self h) = v := by simp_to_raw using Raw₀.get_insert_self ⟨m, _⟩ -@[simp] +@[simp, grind =] theorem get_erase [LawfulBEq α] (h : m.WF) {k a : α} {h'} : (m.erase a).get k h' = m.get k (mem_of_mem_erase h h') := by simp_to_raw using Raw₀.get_erase ⟨m, _⟩ @@ -430,7 +432,7 @@ theorem get_eq_get_get? [LawfulBEq α] (h : m.WF) {a : α} {h'} : m.get a h' = (m.get? a).get ((mem_iff_isSome_get? h).mp h') := by simp only [get?_eq_some_get h h', Option.get_some] -theorem get_get? [LawfulBEq α] (h : m.WF) {a : α} {h'} : +@[grind =] theorem get_get? [LawfulBEq α] (h : m.WF) {a : α} {h'} : (m.get? a).get h' = m.get a ((mem_iff_isSome_get? h).mpr h') := (get_eq_get_get? h).symm @@ -438,7 +440,7 @@ namespace Const variable {β : Type v} {m : DHashMap.Raw α (fun _ => β)} (h : m.WF) -theorem get_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} {h₁} : +@[grind =] theorem get_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} {h₁} : get (m.insert k v) a h₁ = if h₂ : k == a then v else get m a (mem_of_mem_insert h h₁ (Bool.eq_false_iff.2 h₂)) := by simp_to_raw using Raw₀.Const.get_insert ⟨m, _⟩ @@ -448,7 +450,7 @@ theorem get_insert_self [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v get (m.insert k v) k (mem_insert_self h) = v := by simp_to_raw using Raw₀.Const.get_insert_self ⟨m, _⟩ -@[simp] +@[simp, grind =] theorem get_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {h'} : get (m.erase k) a h' = get m a (mem_of_mem_erase h h') := by simp_to_raw using Raw₀.Const.get_erase ⟨m, _⟩ @@ -461,7 +463,7 @@ theorem get_eq_get_get? [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} {h get m a h' = (get? m a).get ((mem_iff_isSome_get? h).mp h') := by simp only [get?_eq_some_get h h', Option.get_some] -theorem get_get? [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} {h'} : +@[grind =] theorem get_get? [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} {h'} : (get? m a).get h' = get m a ((mem_iff_isSome_get? h).mpr h') := (get_eq_get_get? h).symm @@ -474,12 +476,12 @@ theorem get_congr [EquivBEq α] [LawfulHashable α] (h : m.WF) {a b : α} (hab : end Const -@[simp] +@[simp, grind =] theorem get!_emptyWithCapacity [LawfulBEq α] {a : α} [Inhabited (β a)] {c} : (emptyWithCapacity c : Raw α β).get! a = default := by simp_to_raw using Raw₀.get!_emptyWithCapacity -@[simp] +@[simp, grind =] theorem get!_empty [LawfulBEq α] {a : α} [Inhabited (β a)] : (∅ : Raw α β).get! a = default := get!_emptyWithCapacity @@ -492,7 +494,7 @@ theorem get!_of_isEmpty [LawfulBEq α] (h : m.WF) {a : α} [Inhabited (β a)] : m.isEmpty = true → m.get! a = default := by simp_to_raw using Raw₀.get!_of_isEmpty ⟨m, _⟩ -theorem get!_insert [LawfulBEq α] (h : m.WF) {k a : α} [Inhabited (β a)] {v : β k} : +@[grind =] theorem get!_insert [LawfulBEq α] (h : m.WF) {k a : α} [Inhabited (β a)] {v : β k} : (m.insert k v).get! a = if h : k == a then cast (congrArg β (eq_of_beq h)) v else m.get! a := by simp_to_raw using Raw₀.get!_insert @@ -509,7 +511,7 @@ theorem get!_eq_default [LawfulBEq α] (h : m.WF) {a : α} [Inhabited (β a)] : ¬a ∈ m → m.get! a = default := by simpa [← contains_iff_mem] using get!_eq_default_of_contains_eq_false h -theorem get!_erase [LawfulBEq α] (h : m.WF) {k a : α} [Inhabited (β a)] : +@[grind =] theorem get!_erase [LawfulBEq α] (h : m.WF) {k a : α} [Inhabited (β a)] : (m.erase k).get! a = if k == a then default else m.get! a := by simp_to_raw using Raw₀.get!_erase @@ -538,11 +540,11 @@ namespace Const variable {β : Type v} {m : DHashMap.Raw α (fun _ => β)} (h : m.WF) -@[simp] +@[simp, grind =] theorem get!_emptyWithCapacity [Inhabited β] {a : α} {c} : get! (emptyWithCapacity c : Raw α (fun _ => β)) a = default := by simp_to_raw using Raw₀.Const.get!_emptyWithCapacity -@[simp] +@[simp, grind =] theorem get!_empty [Inhabited β] {a : α} : get! (∅ : Raw α (fun _ => β)) a = default := get!_emptyWithCapacity @@ -554,7 +556,7 @@ theorem get!_of_isEmpty [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m. m.isEmpty = true → get! m a = default := by simp_to_raw using Raw₀.Const.get!_of_isEmpty ⟨m, _⟩ -theorem get!_insert [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.WF) {k a : α} {v : β} : +@[grind =] theorem get!_insert [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.WF) {k a : α} {v : β} : get! (m.insert k v) a = if k == a then v else get! m a := by simp_to_raw using Raw₀.Const.get!_insert @@ -572,7 +574,7 @@ theorem get!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m. ¬a ∈ m → get! m a = default := by simpa [← contains_iff_mem] using get!_eq_default_of_contains_eq_false h -theorem get!_erase [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.WF) {k a : α} : +@[grind =] theorem get!_erase [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.WF) {k a : α} : get! (m.erase k) a = if k == a then default else get! m a := by simp_to_raw using Raw₀.Const.get!_erase @@ -607,12 +609,12 @@ theorem get!_congr [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.WF) { end Const -@[simp] +@[simp, grind =] theorem getD_emptyWithCapacity [LawfulBEq α] {a : α} {fallback : β a} {c} : (emptyWithCapacity c : Raw α β).getD a fallback = fallback := by simp_to_raw using Raw₀.getD_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getD_empty [LawfulBEq α] {a : α} {fallback : β a} : (∅ : Raw α β).getD a fallback = fallback := getD_emptyWithCapacity @@ -625,7 +627,7 @@ theorem getD_of_isEmpty [LawfulBEq α] (h : m.WF) {a : α} {fallback : β a} : m.isEmpty = true → m.getD a fallback = fallback := by simp_to_raw using Raw₀.getD_of_isEmpty ⟨m, _⟩ -theorem getD_insert [LawfulBEq α] (h : m.WF) {k a : α} {fallback : β a} {v : β k} : +@[grind =] theorem getD_insert [LawfulBEq α] (h : m.WF) {k a : α} {fallback : β a} {v : β k} : (m.insert k v).getD a fallback = if h : k == a then cast (congrArg β (eq_of_beq h)) v else m.getD a fallback := by simp_to_raw using Raw₀.getD_insert @@ -643,7 +645,7 @@ theorem getD_eq_fallback [LawfulBEq α] (h : m.WF) {a : α} {fallback : β a} : ¬a ∈ m → m.getD a fallback = fallback := by simpa [← contains_iff_mem] using getD_eq_fallback_of_contains_eq_false h -theorem getD_erase [LawfulBEq α] (h : m.WF) {k a : α} {fallback : β a} : +@[grind =] theorem getD_erase [LawfulBEq α] (h : m.WF) {k a : α} {fallback : β a} : (m.erase k).getD a fallback = if k == a then fallback else m.getD a fallback := by simp_to_raw using Raw₀.getD_erase @@ -676,12 +678,12 @@ namespace Const variable {β : Type v} {m : DHashMap.Raw α (fun _ => β)} (h : m.WF) -@[simp] +@[simp, grind =] theorem getD_emptyWithCapacity {a : α} {fallback : β} {c} : getD (emptyWithCapacity c : Raw α (fun _ => β)) a fallback = fallback := by simp_to_raw using Raw₀.Const.getD_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getD_empty {a : α} {fallback : β} : getD (∅ : Raw α (fun _ => β)) a fallback = fallback := getD_emptyWithCapacity @@ -693,7 +695,7 @@ theorem getD_of_isEmpty [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} {f m.isEmpty = true → getD m a fallback = fallback := by simp_to_raw using Raw₀.Const.getD_of_isEmpty ⟨m, _⟩ -theorem getD_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {fallback v : β} : +@[grind =] theorem getD_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {fallback v : β} : getD (m.insert k v) a fallback = if k == a then v else getD m a fallback := by simp_to_raw using Raw₀.Const.getD_insert @@ -710,7 +712,7 @@ theorem getD_eq_fallback [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} { ¬a ∈ m → getD m a fallback = fallback := by simpa [← contains_iff_mem] using getD_eq_fallback_of_contains_eq_false h -theorem getD_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {fallback : β} : +@[grind =] theorem getD_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {fallback : β} : getD (m.erase k) a fallback = if k == a then fallback else getD m a fallback := by simp_to_raw using Raw₀.Const.getD_erase @@ -749,12 +751,12 @@ theorem getD_congr [EquivBEq α] [LawfulHashable α] (h : m.WF) {a b : α} {fall end Const -@[simp] +@[simp, grind =] theorem getKey?_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : Raw α β).getKey? a = none := by simp_to_raw using Raw₀.getKey?_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getKey?_empty {a : α} : (∅ : Raw α β).getKey? a = none := getKey?_emptyWithCapacity @@ -766,7 +768,7 @@ theorem getKey?_of_isEmpty [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} m.isEmpty = true → m.getKey? a = none := by simp_to_raw using Raw₀.getKey?_of_isEmpty ⟨m, _⟩ -theorem getKey?_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {a k : α} {v : β k} : +@[grind =] theorem getKey?_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {a k : α} {v : β k} : (m.insert k v).getKey? a = if k == a then some k else m.getKey? a := by simp_to_raw using Raw₀.getKey?_insert @@ -808,7 +810,7 @@ theorem getKey?_eq_none [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} : ¬a ∈ m → m.getKey? a = none := by simpa [← contains_iff_mem] using getKey?_eq_none_of_contains_eq_false h -theorem getKey?_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : +@[grind =] theorem getKey?_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : (m.erase k).getKey? a = if k == a then none else m.getKey? a := by simp_to_raw using Raw₀.getKey?_erase @@ -833,7 +835,7 @@ theorem getKey?_eq_some [LawfulBEq α] (h : m.WF) {k : α} : k ∈ m → m.getKey? k = some k := by simpa only [mem_iff_contains] using getKey?_eq_some_of_contains h -theorem getKey_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β k} {h₁} : +@[grind =] theorem getKey_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β k} {h₁} : (m.insert k v).getKey a h₁ = if h₂ : k == a then k @@ -846,7 +848,7 @@ theorem getKey_insert_self [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} (m.insert k v).getKey k (mem_insert_self h) = k := by simp_to_raw using Raw₀.getKey_insert_self ⟨m, _⟩ -@[simp] +@[simp, grind =] theorem getKey_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {h'} : (m.erase a).getKey k h' = m.getKey k (mem_of_mem_erase h h') := by simp_to_raw using Raw₀.getKey_erase ⟨m, _⟩ @@ -859,7 +861,7 @@ theorem getKey_eq_get_getKey? [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : m.getKey a h' = (m.getKey? a).get ((mem_iff_isSome_getKey? h).mp h') := by simp only [getKey?_eq_some_getKey h h', Option.get_some] -@[simp] +@[simp, grind =] theorem get_getKey? [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} {h'} : (m.getKey? a).get h' = m.getKey a ((mem_iff_isSome_getKey? h).mpr h') := (getKey_eq_get_getKey? h).symm @@ -873,17 +875,17 @@ theorem getKey_congr [EquivBEq α] [LawfulHashable α] (h : m.WF) {k₁ k₂ : m.getKey k₁ h₁ = m.getKey k₂ (((mem_congr h h').mp h₁)) := by simp_to_raw using Raw₀.getKey_congr -@[simp] +@[simp, grind =] theorem getKey_eq [LawfulBEq α] (h : m.WF) {k : α} (h') : m.getKey k h' = k := by simp_to_raw using Raw₀.getKey_eq -@[simp] +@[simp, grind =] theorem getKey!_emptyWithCapacity [Inhabited α] {a : α} {c} : (emptyWithCapacity c : Raw α β).getKey! a = default := by simp_to_raw using Raw₀.getKey!_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getKey!_empty [Inhabited α] {a : α} : (∅ : Raw α β).getKey! a = default := getKey!_emptyWithCapacity @@ -896,7 +898,7 @@ theorem getKey!_of_isEmpty [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.isEmpty = true → m.getKey! a = default := by simp_to_raw using Raw₀.getKey!_of_isEmpty ⟨m, _⟩ -theorem getKey!_insert [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {k a : α} {v : β k} : +@[grind =] theorem getKey!_insert [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {k a : α} {v : β k} : (m.insert k v).getKey! a = if k == a then k else m.getKey! a := by simp_to_raw using Raw₀.getKey!_insert @@ -915,7 +917,7 @@ theorem getKey!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : ¬a ∈ m → m.getKey! a = default := by simpa [← contains_iff_mem] using getKey!_eq_default_of_contains_eq_false h -theorem getKey!_erase [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {k a : α} : +@[grind =] theorem getKey!_erase [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {k a : α} : (m.erase k).getKey! a = if k == a then default else m.getKey! a := by simp_to_raw using Raw₀.getKey!_erase @@ -953,12 +955,12 @@ theorem getKey!_eq_of_mem [LawfulBEq α] [Inhabited α] (h : m.WF) {k : α} : k ∈ m → m.getKey! k = k := by simpa only [mem_iff_contains] using getKey!_eq_of_contains h -@[simp] +@[simp, grind =] theorem getKeyD_emptyWithCapacity {a fallback : α} {c} : (emptyWithCapacity c : Raw α β).getKeyD a fallback = fallback := by simp_to_raw using Raw₀.getKeyD_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getKeyD_empty {a fallback : α} : (∅ : Raw α β).getKeyD a fallback = fallback := getKeyD_emptyWithCapacity @@ -971,7 +973,7 @@ theorem getKeyD_of_isEmpty [EquivBEq α] [LawfulHashable α] (h : m.WF) {a fallb m.isEmpty = true → m.getKeyD a fallback = fallback := by simp_to_raw using Raw₀.getKeyD_of_isEmpty ⟨m, _⟩ -theorem getKeyD_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} {v : β k} : +@[grind =] theorem getKeyD_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} {v : β k} : (m.insert k v).getKeyD a fallback = if k == a then k else m.getKeyD a fallback := by simp_to_raw using Raw₀.getKeyD_insert @@ -990,7 +992,7 @@ theorem getKeyD_eq_fallback [EquivBEq α] [LawfulHashable α] (h : m.WF) {a fall ¬a ∈ m → m.getKeyD a fallback = fallback := by simpa [← contains_iff_mem] using getKeyD_eq_fallback_of_contains_eq_false h -theorem getKeyD_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} : +@[grind =] theorem getKeyD_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} : (m.erase k).getKeyD a fallback = if k == a then fallback else m.getKeyD a fallback := by simp_to_raw using Raw₀.getKeyD_erase @@ -1033,17 +1035,17 @@ theorem getKeyD_eq_of_mem [LawfulBEq α] (h : m.WF) {k fallback : α} : k ∈ m → m.getKeyD k fallback = k := by simpa only [mem_iff_contains] using getKeyD_eq_of_contains h -@[simp] +@[simp, grind =] theorem isEmpty_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v : β k} : (m.insertIfNew k v).isEmpty = false := by simp_to_raw using Raw₀.isEmpty_insertIfNew -@[simp] +@[simp, grind =] theorem contains_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β k} : (m.insertIfNew k v).contains a = (k == a || m.contains a) := by simp_to_raw using Raw₀.contains_insertIfNew -@[simp] +@[simp, grind =] theorem mem_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β k} : a ∈ m.insertIfNew k v ↔ k == a ∨ a ∈ m := by simp [← contains_iff_mem, contains_insertIfNew h] @@ -1077,7 +1079,7 @@ theorem mem_of_mem_insertIfNew' [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a ∈ m.insertIfNew k v → ¬((k == a) ∧ ¬k ∈ m) → a ∈ m := by simpa [← contains_iff_mem] using contains_of_contains_insertIfNew' h -theorem size_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v : β k} : +@[grind =] theorem size_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v : β k} : (m.insertIfNew k v).size = if k ∈ m then m.size else m.size + 1 := by simp only [mem_iff_contains] simp_to_raw using Raw₀.size_insertIfNew @@ -1090,27 +1092,27 @@ theorem size_insertIfNew_le [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α (m.insertIfNew k v).size ≤ m.size + 1 := by simp_to_raw using Raw₀.size_insertIfNew_le -theorem get?_insertIfNew [LawfulBEq α] (h : m.WF) {k a : α} {v : β k} : +@[grind =] theorem get?_insertIfNew [LawfulBEq α] (h : m.WF) {k a : α} {v : β k} : (m.insertIfNew k v).get? a = if h : k == a ∧ ¬k ∈ m then some (cast (congrArg β (eq_of_beq h.1)) v) else m.get? a := by simp only [mem_iff_contains, Bool.not_eq_true] simp_to_raw using Raw₀.get?_insertIfNew ⟨m, _⟩ -theorem get_insertIfNew [LawfulBEq α] (h : m.WF) {k a : α} {v : β k} {h₁} : +@[grind =] theorem get_insertIfNew [LawfulBEq α] (h : m.WF) {k a : α} {v : β k} {h₁} : (m.insertIfNew k v).get a h₁ = if h₂ : k == a ∧ ¬k ∈ m then cast (congrArg β (eq_of_beq h₂.1)) v else m.get a (mem_of_mem_insertIfNew' h h₁ h₂) := by simp only [mem_iff_contains, Bool.not_eq_true] simp_to_raw using Raw₀.get_insertIfNew ⟨m, _⟩ -theorem get!_insertIfNew [LawfulBEq α] (h : m.WF) {k a : α} [Inhabited (β a)] {v : β k} : +@[grind =] theorem get!_insertIfNew [LawfulBEq α] (h : m.WF) {k a : α} [Inhabited (β a)] {v : β k} : (m.insertIfNew k v).get! a = if h : k == a ∧ ¬k ∈ m then cast (congrArg β (eq_of_beq h.1)) v else m.get! a := by simp only [mem_iff_contains, Bool.not_eq_true] simp_to_raw using Raw₀.get!_insertIfNew ⟨m, _⟩ -theorem getD_insertIfNew [LawfulBEq α] (h : m.WF) {k a : α} {fallback : β a} {v : β k} : +@[grind =] theorem getD_insertIfNew [LawfulBEq α] (h : m.WF) {k a : α} {fallback : β a} {v : β k} : (m.insertIfNew k v).getD a fallback = if h : k == a ∧ ¬k ∈ m then cast (congrArg β (eq_of_beq h.1)) v else m.getD a fallback := by @@ -1121,24 +1123,24 @@ namespace Const variable {β : Type v} {m : DHashMap.Raw α (fun _ => β)} (h : m.WF) -theorem get?_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : +@[grind =] theorem get?_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : get? (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then some v else get? m a := by simp only [mem_iff_contains, Bool.not_eq_true] simp_to_raw using Raw₀.Const.get?_insertIfNew -theorem get_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} {h₁} : +@[grind =] theorem get_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} {h₁} : get (m.insertIfNew k v) a h₁ = if h₂ : k == a ∧ ¬k ∈ m then v else get m a (mem_of_mem_insertIfNew' h h₁ h₂) := by simp only [mem_iff_contains, Bool.not_eq_true] simp_to_raw using Raw₀.Const.get_insertIfNew ⟨m, _⟩ -theorem get!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.WF) {k a : α} +@[grind =] theorem get!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.WF) {k a : α} {v : β} : get! (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then v else get! m a := by simp only [mem_iff_contains, Bool.not_eq_true] simp_to_raw using Raw₀.Const.get!_insertIfNew -theorem getD_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {fallback v : β} : +@[grind =] theorem getD_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {fallback v : β} : getD (m.insertIfNew k v) a fallback = if k == a ∧ ¬k ∈ m then v else getD m a fallback := by simp only [mem_iff_contains, Bool.not_eq_true] @@ -1146,36 +1148,36 @@ theorem getD_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} end Const -theorem getKey?_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β k} : +@[grind =] theorem getKey?_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β k} : getKey? (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then some k else getKey? m a := by simp only [mem_iff_contains, Bool.not_eq_true] simp_to_raw using Raw₀.getKey?_insertIfNew -theorem getKey_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β k} {h₁} : +@[grind =] theorem getKey_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β k} {h₁} : getKey (m.insertIfNew k v) a h₁ = if h₂ : k == a ∧ ¬k ∈ m then k else getKey m a (mem_of_mem_insertIfNew' h h₁ h₂) := by simp only [mem_iff_contains, Bool.not_eq_true] simp_to_raw using Raw₀.getKey_insertIfNew ⟨m, _⟩ -theorem getKey!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {k a : α} +@[grind =] theorem getKey!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {k a : α} {v : β k} : getKey! (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then k else getKey! m a := by simp only [mem_iff_contains, Bool.not_eq_true] simp_to_raw using Raw₀.getKey!_insertIfNew -theorem getKeyD_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} +@[grind =] theorem getKeyD_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} {v : β k} : getKeyD (m.insertIfNew k v) a fallback = if k == a ∧ ¬k ∈ m then k else getKeyD m a fallback := by simp only [mem_iff_contains, Bool.not_eq_true] simp_to_raw using Raw₀.getKeyD_insertIfNew -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_fst [LawfulBEq α] (h : m.WF) {k : α} {v : β k} : (m.getThenInsertIfNew? k v).1 = m.get? k := by simp_to_raw using Raw₀.getThenInsertIfNew?_fst -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_snd [LawfulBEq α] (h : m.WF) {k : α} {v : β k} : (m.getThenInsertIfNew? k v).2 = m.insertIfNew k v := by simp_to_raw using congrArg Subtype.val (Raw₀.getThenInsertIfNew?_snd _) @@ -1184,34 +1186,34 @@ namespace Const variable {β : Type v} {m : DHashMap.Raw α (fun _ => β)} (h : m.WF) -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_fst (h : m.WF) {k : α} {v : β} : (getThenInsertIfNew? m k v).1 = get? m k := by simp_to_raw using Raw₀.Const.getThenInsertIfNew?_fst -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_snd (h : m.WF) {k : α} {v : β} : (getThenInsertIfNew? m k v).2 = m.insertIfNew k v := by simp_to_raw using congrArg Subtype.val (Raw₀.Const.getThenInsertIfNew?_snd _) end Const -@[simp] +@[simp, grind =] theorem length_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.keys.length = m.size := by simp_to_raw using Raw₀.length_keys ⟨m, h.size_buckets_pos⟩ h -@[simp] +@[simp, grind =] theorem isEmpty_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.keys.isEmpty = m.isEmpty := by simp_to_raw using Raw₀.isEmpty_keys ⟨m, h.size_buckets_pos⟩ -@[simp] +@[simp, grind =] theorem contains_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} : m.keys.contains k = m.contains k := by simp_to_raw using Raw₀.contains_keys ⟨m, _⟩ h -@[simp] +@[simp, grind =] theorem mem_keys [LawfulBEq α] [LawfulHashable α] (h : m.WF) {k : α} : k ∈ m.keys ↔ k ∈ m := by rw [mem_iff_contains] @@ -1226,7 +1228,7 @@ theorem distinct_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.keys.Pairwise (fun a b => (a == b) = false) := by simp_to_raw using Raw₀.distinct_keys ⟨m, h.size_buckets_pos⟩ h -@[simp] +@[simp, grind =] theorem map_fst_toList_eq_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.toList.map Sigma.fst = m.keys := by apply Raw₀.map_fst_toList_eq_keys ⟨m, h.size_buckets_pos⟩ @@ -1236,17 +1238,17 @@ theorem map_sigma_fst_toList_eq_keys [EquivBEq α] [LawfulHashable α] (h : m.WF m.toList.map Sigma.fst = m.keys := by apply Raw₀.map_fst_toList_eq_keys ⟨m, h.size_buckets_pos⟩ -@[simp] +@[simp, grind =] theorem length_toList [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.toList.length = m.size := by apply Raw₀.length_toList ⟨m, h.size_buckets_pos⟩ h -@[simp] +@[simp, grind =] theorem isEmpty_toList [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.toList.isEmpty = m.isEmpty := by apply Raw₀.isEmpty_toList ⟨m, h.size_buckets_pos⟩ h -@[simp] +@[simp, grind =] theorem mem_toList_iff_get?_eq_some [LawfulBEq α] (h : m.WF) {k : α} {v : β k} : ⟨k, v⟩ ∈ m.toList ↔ m.get? k = some v := by @@ -1277,7 +1279,7 @@ namespace Const variable {β : Type v} {m : Raw α (fun _ => β)} -@[simp] +@[simp, grind =] theorem map_fst_toList_eq_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) : (Raw.Const.toList m).map Prod.fst = m.keys := by apply Raw₀.Const.map_fst_toList_eq_keys ⟨m, h.size_buckets_pos⟩ @@ -1287,17 +1289,17 @@ theorem map_prod_fst_toList_eq_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) (Raw.Const.toList m).map Prod.fst = m.keys := by apply Raw₀.Const.map_fst_toList_eq_keys ⟨m, h.size_buckets_pos⟩ -@[simp] +@[simp, grind =] theorem length_toList [EquivBEq α] [LawfulHashable α] (h : m.WF) : (Raw.Const.toList m).length = m.size := by apply Raw₀.Const.length_toList ⟨m, h.size_buckets_pos⟩ h -@[simp] +@[simp, grind =] theorem isEmpty_toList [EquivBEq α] [LawfulHashable α] (h : m.WF) : (Raw.Const.toList m).isEmpty = m.isEmpty := by apply Raw₀.Const.isEmpty_toList ⟨m, h.size_buckets_pos⟩ h -@[simp] +@[simp, grind =] theorem mem_toList_iff_get?_eq_some [LawfulBEq α] (h : m.WF) {k : α} {v : β} : (k, v) ∈ Raw.Const.toList m ↔ get? m k = some v := by @@ -1356,7 +1358,7 @@ theorem fold_eq_foldl_toList (h : m.WF) {f : δ → (a : α) → β a → δ} {i Raw₀.fold_eq_foldl_toList ⟨m, h.size_buckets_pos⟩ omit [BEq α] [Hashable α] in -@[simp] +@[simp, grind =] theorem forM_eq_forM [Monad m'] [LawfulMonad m'] {f : (a : α) → β a → m' PUnit} : Raw.forM f m = ForM.forM m (fun a => f a.1 a.2) := rfl @@ -1366,7 +1368,7 @@ theorem forM_eq_forM_toList [Monad m'] [LawfulMonad m'] (h : m.WF) {f : (a : α) Raw₀.forM_eq_forM_toList ⟨m, h.size_buckets_pos⟩ omit [BEq α] [Hashable α] in -@[simp] +@[simp, grind =] theorem forIn_eq_forIn [Monad m'] [LawfulMonad m'] {f : (a : α) → β a → δ → m' (ForInStep δ)} {init : δ} : Raw.forIn f init m = ForIn.forIn m init (fun a b => f a.1 a.2 b) := rfl @@ -1477,24 +1479,25 @@ section insertMany variable {ρ : Type w} [ForIn Id ρ ((a : α) × β a)] -@[simp] +@[simp, grind =] theorem insertMany_nil [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.insertMany [] = m := by simp_to_raw rw [Raw₀.insertMany_nil] -@[simp] +@[simp, grind =] theorem insertMany_list_singleton {k : α} {v : β k} [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.insertMany [⟨k, v⟩] = m.insert k v := by simp_to_raw rw [Raw₀.insertMany_list_singleton] -theorem insertMany_cons {l : List ((a : α) × β a)} {k : α} {v : β k} [EquivBEq α] [LawfulHashable α] +@[grind _=_] theorem insertMany_cons {l : List ((a : α) × β a)} {k : α} {v : β k} [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.insertMany (⟨k, v⟩ :: l) = (m.insert k v).insertMany l := by simp_to_raw rw [Raw₀.insertMany_cons] +@[grind _=_] theorem insertMany_append [EquivBEq α] [LawfulHashable α] (h : m.WF) {l₁ l₂ : List ((a : α) × β a)} : insertMany m (l₁ ++ l₂) = insertMany (insertMany m l₁) l₂ := by induction l₁ generalizing m with @@ -1513,13 +1516,13 @@ theorem insertMany_ind {motive : Raw α β → Prop} (m : Raw α β) (l : ρ) simpa only [Raw.insert, m.2, ↓reduceDIte] using insert m.1 a b h · exact init -@[simp] +@[simp, grind =] theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List ((a : α) × β a)} {k : α} : (m.insertMany l).contains k = (m.contains k || (l.map Sigma.fst).contains k) := by simp_to_raw using Raw₀.contains_insertMany_list -@[simp] +@[simp, grind =] theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List ((a : α) × β a)} {k : α} : k ∈ (m.insertMany l) ↔ k ∈ m ∨ (l.map Sigma.fst).contains k := by @@ -1666,12 +1669,16 @@ theorem size_le_size_insertMany [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : ρ} : m.size ≤ (m.insertMany l).size := by simp_to_raw using Raw₀.size_le_size_insertMany ⟨m, _⟩ +grind_pattern size_le_size_insertMany => (insertMany m l).size + theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List ((a : α) × β a)} : (m.insertMany l).size ≤ m.size + l.length := by simp_to_raw using Raw₀.size_insertMany_list_le -@[simp] +grind_pattern size_insertMany_list_le => (insertMany m l).size + +@[simp, grind =] theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List ((a : α) × β a)} : (m.insertMany l).isEmpty = (m.isEmpty && l.isEmpty) := by @@ -1686,25 +1693,26 @@ namespace Const variable {β : Type v} {m : Raw α (fun _ => β)} variable {ρ : Type w} [ForIn Id ρ (α × β)] -@[simp] +@[simp, grind =] theorem insertMany_nil (h : m.WF) : insertMany m [] = m := by simp_to_raw rw [Raw₀.Const.insertMany_nil] -@[simp] +@[simp, grind =] theorem insertMany_list_singleton (h : m.WF) {k : α} {v : β} : insertMany m [⟨k, v⟩] = m.insert k v := by simp_to_raw rw [Raw₀.Const.insertMany_list_singleton] -theorem insertMany_cons (h : m.WF) {l : List (α × β)} +@[grind _=_] theorem insertMany_cons (h : m.WF) {l : List (α × β)} {k : α} {v : β} : insertMany m (⟨k, v⟩ :: l) = insertMany (m.insert k v) l := by simp_to_raw rw [Raw₀.Const.insertMany_cons] +@[grind _=_] theorem insertMany_append (h : m.WF) {l₁ l₂ : List (α × β)} : insertMany m (l₁ ++ l₂) = insertMany (insertMany m l₁) l₂ := by induction l₁ generalizing m with @@ -1723,13 +1731,13 @@ theorem insertMany_ind {motive : Raw α (fun _ => β) → Prop} (m : Raw α fun simpa only [Raw.insert, m.2, ↓reduceDIte] using insert m.1 a b h · exact init -@[simp] +@[simp, grind =] theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List (α × β)} {k : α} : (insertMany m l).contains k = (m.contains k || (l.map Prod.fst).contains k) := by simp_to_raw using Raw₀.Const.contains_insertMany_list -@[simp] +@[simp, grind =] theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List (α × β)} {k : α} : k ∈ insertMany m l ↔ k ∈ m ∨ (l.map Prod.fst).contains k := by @@ -1822,12 +1830,16 @@ theorem size_le_size_insertMany [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : ρ} : m.size ≤ (insertMany m l).size := by simp_to_raw using Raw₀.Const.size_le_size_insertMany ⟨m, _⟩ +grind_pattern size_le_size_insertMany => (insertMany m l).size + theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List (α × β)} : (insertMany m l).size ≤ m.size + l.length := by simp_to_raw using Raw₀.Const.size_insertMany_list_le -@[simp] +grind_pattern size_insertMany_list_le => (insertMany m l).size + +@[simp, grind =] theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List (α × β)} : (insertMany m l).isEmpty = (m.isEmpty && l.isEmpty) := by @@ -1849,7 +1861,7 @@ theorem get?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.WF) get? (insertMany m l) k' = some v := by simp_to_raw using Raw₀.Const.get?_insertMany_list_of_mem -theorem get?_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List (α × β)} {k : α} : +@[grind _=_] theorem get?_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List (α × β)} {k : α} : get? (insertMany m l) k = (l.findSomeRev? (fun ⟨a, b⟩ => if a == k then some b else none)).or (get? m k) := by induction l generalizing m with @@ -2098,19 +2110,19 @@ variable [BEq α] [Hashable α] open Internal.Raw Internal.Raw₀ -@[simp] +@[simp, grind =] theorem ofList_nil : ofList ([] : List ((a : α) × (β a))) = ∅ := by simp_to_raw rw [Raw₀.insertMany_emptyWithCapacity_list_nil] -@[simp] +@[simp, grind =] theorem ofList_singleton {k : α} {v : β k} : ofList [⟨k, v⟩] = (∅ : Raw α β).insert k v := by simp_to_raw rw [Raw₀.insertMany_emptyWithCapacity_list_singleton] -theorem ofList_cons [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} {tl : List ((a : α) × (β a))} : +@[grind _=_] theorem ofList_cons [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} {tl : List ((a : α) × (β a))} : ofList (⟨k, v⟩ :: tl) = ((∅ : Raw α β).insert k v).insertMany tl := by simp_to_raw rw [Raw₀.insertMany_emptyWithCapacity_list_cons] @@ -2118,13 +2130,13 @@ theorem ofList_cons [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} {tl : theorem ofList_eq_insertMany_empty {l : List ((a : α) × (β a))} : ofList l = insertMany (∅ : Raw α β) l := rfl -@[simp] +@[simp, grind =] theorem contains_ofList [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} {k : α} : (ofList l).contains k = (l.map Sigma.fst).contains k := by simp_to_raw using Raw₀.contains_insertMany_emptyWithCapacity_list -@[simp] +@[simp, grind =] theorem mem_ofList [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} {k : α} : k ∈ ofList l ↔ (l.map Sigma.fst).contains k := by @@ -2238,7 +2250,9 @@ theorem size_ofList_le [EquivBEq α] [LawfulHashable α] (ofList l).size ≤ l.length := by simp_to_raw using Raw₀.size_insertMany_emptyWithCapacity_list_le -@[simp] +grind_pattern size_ofList_le => (ofList l).size + +@[simp, grind =] theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} : (ofList l).isEmpty = l.isEmpty := by @@ -2248,19 +2262,19 @@ namespace Const variable {β : Type v} -@[simp] +@[simp, grind =] theorem ofList_nil : ofList ([] : List (α × β)) = ∅ := by simp_to_raw simp -@[simp] +@[simp, grind =] theorem ofList_singleton {k : α} {v : β} : ofList [⟨k, v⟩] = (∅ : Raw α (fun _ => β)).insert k v := by simp_to_raw simp -theorem ofList_cons {k : α} {v : β} {tl : List (α × β)} : +@[grind _=_] theorem ofList_cons {k : α} {v : β} {tl : List (α × β)} : ofList (⟨k, v⟩ :: tl) = insertMany ((∅ : Raw α (fun _ => β)).insert k v) tl := by simp_to_raw rw [Raw₀.Const.insertMany_emptyWithCapacity_list_cons] @@ -2268,13 +2282,13 @@ theorem ofList_cons {k : α} {v : β} {tl : List (α × β)} : theorem ofList_eq_insertMany_empty {l : List (α × β)} : ofList l = insertMany (∅ : Raw α (fun _ => β)) l := rfl -@[simp] +@[simp, grind =] theorem contains_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : (ofList l).contains k = (l.map Prod.fst).contains k := by simp_to_raw using Raw₀.Const.contains_insertMany_emptyWithCapacity_list -@[simp] +@[simp, grind =] theorem mem_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : k ∈ (ofList l) ↔ (l.map Prod.fst).contains k := by @@ -2388,7 +2402,9 @@ theorem size_ofList_le [EquivBEq α] [LawfulHashable α] (ofList l).size ≤ l.length := by simp_to_raw using Raw₀.Const.size_insertMany_emptyWithCapacity_list_le -@[simp] +grind_pattern size_ofList_le => (ofList l).size + +@[simp, grind =] theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} : (ofList l).isEmpty = l.isEmpty := by @@ -2524,15 +2540,17 @@ theorem isEmpty_alter_eq_isEmpty_erase [LawfulBEq α] {k : α} {f : Option (β k (h : m.WF) : (m.alter k f).isEmpty = ((m.erase k).isEmpty && (f (m.get? k)).isNone) := by simp_to_raw using Raw₀.isEmpty_alter_eq_isEmpty_erase -@[simp] +@[simp, grind =] theorem isEmpty_alter [LawfulBEq α] {k : α} {f : Option (β k) → Option (β k)} (h : m.WF) : (m.alter k f).isEmpty = ((m.isEmpty || (m.size == 1 && m.contains k)) && (f (m.get? k)).isNone) := by simp_to_raw using Raw₀.isEmpty_alter +@[grind =] theorem contains_alter [LawfulBEq α] {k k': α} {f : Option (β k) → Option (β k)} (h : m.WF) : (m.alter k f).contains k' = if k == k' then (f (m.get? k)).isSome else m.contains k' := by simp_to_raw using Raw₀.contains_alter +@[grind =] theorem mem_alter [LawfulBEq α] {k k': α} {f : Option (β k) → Option (β k)} (h : m.WF) : k' ∈ m.alter k f ↔ if k == k' then (f (m.get? k)).isSome = true else k' ∈ m := by simp [← contains_iff_mem, contains_alter h] @@ -2559,6 +2577,7 @@ theorem mem_alter_of_beq_eq_false [LawfulBEq α] {k k' : α} {f : Option (β k) (h : m.WF) (he : (k == k') = false) : k' ∈ m.alter k f ↔ k' ∈ m := by simp only [mem_iff_contains, contains_alter_of_beq_eq_false h, he] +@[grind =] theorem size_alter [LawfulBEq α] {k : α} {f : Option (β k) → Option (β k)} (h : m.WF) : (m.alter k f).size = if k ∈ m ∧ (f (m.get? k)).isNone then @@ -2606,6 +2625,7 @@ theorem size_le_size_alter [LawfulBEq α] {k : α} {f : Option (β k) → Option m.size - 1 ≤ (m.alter k f).size := by simp_to_raw using Raw₀.size_le_size_alter ⟨m, h.size_buckets_pos⟩ +@[grind =] theorem get?_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} (h : m.WF) : (m.alter k f).get? k' = if h : k == k' then (cast (congrArg (Option ∘ β) (eq_of_beq h)) (f (m.get? k))) @@ -2617,6 +2637,7 @@ theorem get?_alter_self [LawfulBEq α] {k : α} {f : Option (β k) → Option ( (m.alter k f).get? k = f (m.get? k) := by simp [get?_alter h] +@[grind =] theorem get_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} (h : m.WF) {hc : k' ∈ m.alter k f} : (m.alter k f).get k' hc = @@ -2639,6 +2660,7 @@ theorem get_alter_self [LawfulBEq α] {k : α} {f : Option (β k) → Option (β revert hc simp_to_raw using Raw₀.get_alter_self +@[grind =] theorem get!_alter [LawfulBEq α] {k k' : α} [hi : Inhabited (β k')] {f : Option (β k) → Option (β k)} (h : m.WF) : (m.alter k f).get! k' = if heq : k == k' then @@ -2656,6 +2678,7 @@ theorem get!_alter_self [LawfulBEq α] {k : α} [Inhabited (β k)] {f : Option ( (h : m.WF) : (m.alter k f).get! k = (f (m.get? k)).get! := by simp [get!_alter h, Option.map_cast_apply] +@[grind =] theorem getD_alter [LawfulBEq α] {k k' : α} {fallback : β k'} {f : Option (β k) → Option (β k)} (h : m.WF) : (m.alter k f).getD k' fallback = if heq : k == k' then @@ -2669,6 +2692,7 @@ theorem getD_alter_self [LawfulBEq α] {k : α} {fallback : β k} {f : Option ( (h : m.WF) : (m.alter k f).getD k fallback = (f (m.get? k)).getD fallback := by simp_to_raw using Raw₀.getD_alter_self +@[grind =] theorem getKey?_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} (h : m.WF) : (m.alter k f).getKey? k' = if k == k' then @@ -2681,6 +2705,7 @@ theorem getKey?_alter_self [LawfulBEq α] {k : α} {f : Option (β k) → Option (m.alter k f).getKey? k = if (f (m.get? k)).isSome then some k else none := by simp [getKey?_alter h] +@[grind =] theorem getKey!_alter [LawfulBEq α] [Inhabited α] {k k' : α} {f : Option (β k) → Option (β k)} (h : m.WF) : (m.alter k f).getKey! k' = if k == k' then @@ -2694,6 +2719,7 @@ theorem getKey!_alter_self [LawfulBEq α] [Inhabited α] {k : α} {f : Option ( simp [getKey!_alter h] -- Note that in many use cases `getKey_eq` gives a simpler right hand side. +@[grind =] theorem getKey_alter [LawfulBEq α] [Inhabited α] {k k' : α} {f : Option (β k) → Option (β k)} (h : m.WF) {hc : k' ∈ m.alter k f} : (m.alter k f).getKey k' hc = @@ -2711,6 +2737,7 @@ theorem getKey_alter_self [LawfulBEq α] [Inhabited α] {k : α} {f : Option (β (h : m.WF) {hc : k ∈ m.alter k f} : (m.alter k f).getKey k hc = k := by simp [getKey_alter h] +@[grind =] theorem getKeyD_alter [LawfulBEq α] {k k' fallback : α} {f : Option (β k) → Option (β k)} (h : m.WF) : (m.alter k f).getKeyD k' fallback = if k == k' then @@ -2734,17 +2761,19 @@ theorem isEmpty_alter_eq_isEmpty_erase [EquivBEq α] [LawfulHashable α] {k : α (Const.alter m k f).isEmpty = ((m.erase k).isEmpty && (f (Const.get? m k)).isNone) := by simp_to_raw using Raw₀.Const.isEmpty_alter_eq_isEmpty_erase -@[simp] +@[simp, grind =] theorem isEmpty_alter [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β → Option β} (h : m.WF) : (Const.alter m k f).isEmpty = ((m.isEmpty || (m.size == 1 && m.contains k)) && (f (get? m k)).isNone) := by simp_to_raw using Raw₀.Const.isEmpty_alter +@[grind =] theorem contains_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} (h : m.WF) : (Const.alter m k f).contains k' = if k == k' then (f (Const.get? m k)).isSome else m.contains k' := by simp_to_raw using Raw₀.Const.contains_alter +@[grind =] theorem mem_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} (h : m.WF) : k' ∈ Const.alter m k f ↔ if k == k' then (f (Const.get? m k)).isSome = true else k' ∈ m := by simp only [mem_iff_contains, contains_alter h, Bool.ite_eq_true_distrib] @@ -2773,6 +2802,7 @@ theorem mem_alter_of_beq_eq_false [EquivBEq α] [LawfulHashable α] {k k' : α} k' ∈ Const.alter m k f ↔ k' ∈ m := by simp only [mem_iff_contains, contains_alter_of_beq_eq_false h, he] +@[grind =] theorem size_alter [LawfulBEq α] {k : α} {f : Option β → Option β} (h : m.WF) : (Const.alter m k f).size = if k ∈ m ∧ (f (Const.get? m k)).isNone then @@ -2820,6 +2850,7 @@ theorem size_le_size_alter [LawfulBEq α] {k : α} {f : Option β → Option β} m.size - 1 ≤ (Const.alter m k f).size := by simp_to_raw using Raw₀.Const.size_le_size_alter ⟨m, h.size_buckets_pos⟩ +@[grind =] theorem get?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} (h : m.WF) : Const.get? (Const.alter m k f) k' = if k == k' then @@ -2833,6 +2864,7 @@ theorem get?_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Option (h : m.WF) : Const.get? (Const.alter m k f) k = f (Const.get? m k) := by simp [get?_alter h] +@[grind =] theorem get_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} (h : m.WF) {hc : k' ∈ Const.alter m k f} : Const.get (Const.alter m k f) k' hc = @@ -2855,6 +2887,7 @@ theorem get_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β revert hc simp [get_alter h] +@[grind =] theorem get!_alter [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] {f : Option β → Option β} (h : m.WF) : Const.get! (Const.alter m k f) k' = if k == k' then @@ -2869,6 +2902,7 @@ theorem get!_alter_self [EquivBEq α] [LawfulHashable α] {k : α} [Inhabited β Const.get! (Const.alter m k f) k = (f (Const.get? m k)).get! := by simp [get!_alter h] +@[grind =] theorem getD_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} {f : Option β → Option β} (h : m.WF) : Const.getD (Const.alter m k f) k' fallback = if k == k' then @@ -2883,6 +2917,7 @@ theorem getD_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {fallback : Const.getD (Const.alter m k f) k fallback = (f (Const.get? m k)).getD fallback := by simp [getD_alter h] +@[grind =] theorem getKey?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} (h : m.WF) : (Const.alter m k f).getKey? k' = if k == k' then @@ -2896,6 +2931,7 @@ theorem getKey?_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Optio (Const.alter m k f).getKey? k = if (f (Const.get? m k)).isSome then some k else none := by simp [getKey?_alter h] +@[grind =] theorem getKey!_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : Option β → Option β} (h : m.WF) : (Const.alter m k f).getKey! k' = if k == k' then @@ -2909,6 +2945,7 @@ theorem getKey!_alter_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : (Const.alter m k f).getKey! k = if (f (Const.get? m k)).isSome then k else default := by simp [getKey!_alter h] +@[grind =] theorem getKey_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : Option β → Option β} (h : m.WF) {hc : k' ∈ Const.alter m k f} : (Const.alter m k f).getKey k' hc = @@ -2927,6 +2964,7 @@ theorem getKey_alter_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : (Const.alter m k f).getKey k hc = k := by simp [getKey_alter h] +@[grind =] theorem getKeyD_alter [EquivBEq α] [LawfulHashable α] {k k' fallback : α} {f : Option β → Option β} (h : m.WF) : (Const.alter m k f).getKeyD k' fallback = if k == k' then @@ -2946,26 +2984,27 @@ end Alter section Modify -@[simp] +@[simp, grind =] theorem isEmpty_modify [LawfulBEq α] {k : α} {f : β k → β k} (h : m.WF) : (m.modify k f).isEmpty = m.isEmpty := by simp_to_raw using Raw₀.isEmpty_modify -@[simp] +@[simp, grind =] theorem contains_modify [LawfulBEq α] {k k': α} {f : β k → β k} (h : m.WF) : (m.modify k f).contains k' = m.contains k' := by simp_to_raw using Raw₀.contains_modify -@[simp] +@[simp, grind =] theorem mem_modify [LawfulBEq α] {k k': α} {f : β k → β k} (h : m.WF) : k' ∈ m.modify k f ↔ k' ∈ m := by simp only [mem_iff_contains, contains_modify h] -@[simp] +@[simp, grind =] theorem size_modify [LawfulBEq α] {k : α} {f : β k → β k} (h : m.WF) : (m.modify k f).size = m.size := by simp_to_raw using Raw₀.size_modify +@[grind =] theorem get?_modify [LawfulBEq α] {k k' : α} {f : β k → β k} (h : m.WF) : (m.modify k f).get? k' = if h : k == k' then @@ -2979,6 +3018,7 @@ theorem get?_modify_self [LawfulBEq α] {k : α} {f : β k → β k} (h : m.WF) (m.modify k f).get? k = (m.get? k).map f := by simp_to_raw using Raw₀.get?_modify_self +@[grind =] theorem get_modify [LawfulBEq α] {k k' : α} {f : β k → β k} (h : m.WF) {hc : k' ∈ m.modify k f} : (m.modify k f).get k' hc = @@ -3000,6 +3040,7 @@ theorem get_modify_self [LawfulBEq α] {k : α} {f : β k → β k} (h : m.WF) { revert hc simp_to_raw using Raw₀.get_modify_self +@[grind =] theorem get!_modify [LawfulBEq α] {k k' : α} [hi : Inhabited (β k')] {f : β k → β k} (h : m.WF) : (m.modify k f).get! k' = if heq : k == k' then @@ -3013,6 +3054,7 @@ theorem get!_modify_self [LawfulBEq α] {k : α} [Inhabited (β k)] {f : β k (m.modify k f).get! k = ((m.get? k).map f).get! := by simp_to_raw using Raw₀.get!_modify_self +@[grind =] theorem getD_modify [LawfulBEq α] {k k' : α} {fallback : β k'} {f : β k → β k} (h : m.WF) : (m.modify k f).getD k' fallback = if heq : k == k' then @@ -3026,6 +3068,7 @@ theorem getD_modify_self [LawfulBEq α] {k : α} {fallback : β k} {f : β k → (m.modify k f).getD k fallback = ((m.get? k).map f).getD fallback := by simp_to_raw using Raw₀.getD_modify_self +@[grind =] theorem getKey?_modify [LawfulBEq α] {k k' : α} {f : β k → β k} (h : m.WF) : (m.modify k f).getKey? k' = if k == k' then @@ -3040,6 +3083,7 @@ theorem getKey?_modify_self [LawfulBEq α] {k : α} {f : β k → β k} (h : m.W simp only [mem_iff_contains] simp_to_raw using Raw₀.getKey?_modify_self +@[grind =] theorem getKey!_modify [LawfulBEq α] [Inhabited α] {k k' : α} {f : β k → β k} (h : m.WF) : (m.modify k f).getKey! k' = if k == k' then @@ -3073,6 +3117,7 @@ theorem getKey_modify_self [LawfulBEq α] [Inhabited α] {k : α} {f : β k → revert hc simp_to_raw using Raw₀.getKey_modify_self +@[grind =] theorem getKeyD_modify [LawfulBEq α] {k k' fallback : α} {f : β k → β k} (h : m.WF) : (m.modify k f).getKeyD k' fallback = if k == k' then @@ -3091,26 +3136,27 @@ namespace Const variable {β : Type v} {m : Raw α (fun _ => β)} -@[simp] +@[simp, grind =] theorem isEmpty_modify [EquivBEq α] [LawfulHashable α] {k : α} {f : β → β} (h : m.WF) : (Const.modify m k f).isEmpty = m.isEmpty := by simp_to_raw using Raw₀.Const.isEmpty_modify -@[simp] +@[simp, grind =] theorem contains_modify [EquivBEq α] [LawfulHashable α] {k k': α} {f : β → β} (h : m.WF) : (Const.modify m k f).contains k' = m.contains k' := by simp_to_raw using Raw₀.Const.contains_modify -@[simp] +@[simp, grind =] theorem mem_modify [EquivBEq α] [LawfulHashable α] {k k': α} {f : β → β} (h : m.WF) : k' ∈ Const.modify m k f ↔ k' ∈ m := by simp only [mem_iff_contains, contains_modify h] -@[simp] +@[simp, grind =] theorem size_modify [EquivBEq α] [LawfulHashable α] {k : α} {f : β → β} (h : m.WF) : (Const.modify m k f).size = m.size := by simp_to_raw using Raw₀.Const.size_modify +@[grind =] theorem get?_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} (h : m.WF) : Const.get? (Const.modify m k f) k' = if k == k' then @@ -3124,6 +3170,7 @@ theorem get?_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β → Const.get? (Const.modify m k f) k = (Const.get? m k).map f := by simp_to_raw using Raw₀.Const.get?_modify_self +@[grind =] theorem get_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} (h : m.WF) {hc : k' ∈ Const.modify m k f} : Const.get (Const.modify m k f) k' hc = @@ -3146,6 +3193,7 @@ theorem get_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β → revert hc simp_to_raw using Raw₀.Const.get_modify_self +@[grind =] theorem get!_modify [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] {f : β → β} (h : m.WF) : Const.get! (Const.modify m k f) k' = if k == k' then @@ -3159,6 +3207,7 @@ theorem get!_modify_self [EquivBEq α] [LawfulHashable α] {k : α} [Inhabited (h : m.WF) : Const.get! (Const.modify m k f) k = ((Const.get? m k).map f).get! := by simp_to_raw using Raw₀.Const.get!_modify_self +@[grind =] theorem getD_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} {f : β → β} (h : m.WF) : Const.getD (Const.modify m k f) k' fallback = if k == k' then @@ -3172,6 +3221,7 @@ theorem getD_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {fallback : Const.getD (Const.modify m k f) k fallback = ((Const.get? m k).map f).getD fallback := by simp_to_raw using Raw₀.Const.getD_modify_self +@[grind =] theorem getKey?_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} (h : m.WF) : (Const.modify m k f).getKey? k' = if k == k' then @@ -3186,6 +3236,7 @@ theorem getKey?_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β simp only [mem_iff_contains] simp_to_raw using Raw₀.Const.getKey?_modify_self +@[grind =] theorem getKey!_modify [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : β → β} (h : m.WF) : (Const.modify m k f).getKey! k' = if k == k' then @@ -3200,6 +3251,7 @@ theorem getKey!_modify_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k simp only [mem_iff_contains] simp_to_raw using Raw₀.Const.getKey!_modify_self +@[grind =] theorem getKey_modify [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : β → β} (h : m.WF) : {hc : k' ∈ Const.modify m k f} → (Const.modify m k f).getKey k' hc = @@ -3218,6 +3270,7 @@ theorem getKey_modify_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : revert hc simp_to_raw using Raw₀.Const.getKey_modify_self +@[grind =] theorem getKeyD_modify [EquivBEq α] [LawfulHashable α] {k k' fallback : α} {f : β → β} (h : m.WF) : (Const.modify m k f).getKeyD k' fallback = if k == k' then @@ -3500,6 +3553,7 @@ theorem toList_filterMap {f : (a : α) → β a → Option (γ a)} (h : m.WF) : (m.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩))) := by simp_to_raw using Raw₀.toList_filterMap +@[grind =] theorem isEmpty_filterMap_iff [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} (h : m.WF) : (m.filterMap f).isEmpty = true ↔ @@ -3514,11 +3568,13 @@ theorem isEmpty_filterMap_eq_false_iff [LawfulBEq α] simp only [mem_iff_contains] simp_to_raw using Raw₀.isEmpty_filterMap_eq_false_iff +@[grind =] theorem contains_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} (h : m.WF) : (m.filterMap f).contains k = (m.get? k).any (f k · |>.isSome) := by simp_to_raw using Raw₀.contains_filterMap +@[grind =] theorem mem_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} (h : m.WF) : k ∈ m.filterMap f ↔ ∃ h, (f k (m.get k h)).isSome := by @@ -3541,13 +3597,15 @@ theorem size_filterMap_le_size [EquivBEq α] [LawfulHashable α] (m.filterMap f).size ≤ m.size := by simp_to_raw using Raw₀.size_filterMap_le_size +grind_pattern size_filterMap_le_size => (m.filterMap f).size + theorem size_filterMap_eq_size_iff [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} (h : m.WF) : (m.filterMap f).size = m.size ↔ ∀ (a : α) (h : a ∈ m), (f a (m.get a h)).isSome := by simp only [mem_iff_contains] simp_to_raw using Raw₀.size_filterMap_eq_size_iff -@[simp] +@[simp, grind =] theorem get?_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} (h : m.WF) : (m.filterMap f).get? k = (m.get? k).bind (f k) := by @@ -3560,7 +3618,7 @@ theorem isSome_apply_of_mem_filterMap [LawfulBEq α] simp only [mem_iff_contains] simp_to_raw using Raw₀.isSome_apply_of_contains_filterMap -@[simp] +@[simp, grind =] theorem get_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} {h'} (h : m.WF) : (m.filterMap f).get k h' = @@ -3568,16 +3626,19 @@ theorem get_filterMap [LawfulBEq α] (isSome_apply_of_mem_filterMap h h') := by simp_to_raw using Raw₀.get_filterMap +@[grind =] theorem get!_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} [Inhabited (γ k)] (h : m.WF) : (m.filterMap f).get! k = ((m.get? k).bind (f k)).get! := by simp_to_raw using Raw₀.get!_filterMap +@[grind =] theorem getD_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} {fallback : γ k} (h : m.WF) : (m.filterMap f).getD k fallback = ((m.get? k).bind (f k)).getD fallback := by simp_to_raw using Raw₀.getD_filterMap +@[grind =] theorem getKey?_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} (h : m.WF) : (m.filterMap f).getKey? k = @@ -3585,12 +3646,13 @@ theorem getKey?_filterMap [LawfulBEq α] (f x (m.get x (mem_of_getKey?_eq_some h h'))).isSome) := by simp_to_raw using Raw₀.getKey?_filterMap -@[simp] +@[simp, grind =] theorem getKey_filterMap [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → Option (γ a)} {k : α} {h'} (h : m.WF) : (m.filterMap f).getKey k h' = m.getKey k (mem_of_mem_filterMap h h') := by simp_to_raw using Raw₀.getKey_filterMap +@[grind =] theorem getKey!_filterMap [LawfulBEq α] [Inhabited α] {f : (a : α) → β a → Option (γ a)} {k : α} (h : m.WF) : (m.filterMap f).getKey! k = @@ -3598,6 +3660,7 @@ theorem getKey!_filterMap [LawfulBEq α] [Inhabited α] (f x (m.get x (mem_of_getKey?_eq_some h h'))).isSome)).get! := by simp_to_raw using Raw₀.getKey!_filterMap +@[grind =] theorem getKeyD_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k fallback : α} (h : m.WF) : (m.filterMap f).getKeyD k fallback = @@ -3609,6 +3672,7 @@ namespace Const variable {β : Type v} {γ : Type w} {m : Raw α (fun _ => β)} +@[grind =] theorem isEmpty_filterMap_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} (h : m.WF) : (m.filterMap f).isEmpty = true ↔ @@ -3623,6 +3687,9 @@ theorem isEmpty_filterMap_eq_false_iff [EquivBEq α] [LawfulHashable α] simp only [mem_iff_contains] simp_to_raw using Raw₀.Const.isEmpty_filterMap_eq_false_iff +-- TODO: `contains_filterMap` is missing + +@[grind =] theorem mem_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} (h : m.WF) : k ∈ m.filterMap f ↔ ∃ h, (f (m.getKey k h) (Const.get m k h)).isSome := by @@ -3635,6 +3702,9 @@ theorem size_filterMap_eq_size_iff [EquivBEq α] [LawfulHashable α] simp only [mem_iff_contains] simp_to_raw using Raw₀.Const.size_filterMap_eq_size_iff +-- TODO: `size_filterMap_le_size` is missing + +@[grind =] theorem get?_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} (h : m.WF) : Const.get? (m.filterMap f) k = (Const.get? m k).pbind (fun x h' => @@ -3654,7 +3724,7 @@ theorem isSome_apply_of_mem_filterMap [EquivBEq α] [LawfulHashable α] simp [← contains_iff_mem] simp_to_raw using Raw₀.Const.isSome_apply_of_contains_filterMap -@[simp] +@[simp, grind =] theorem get_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} {h'} (h : m.WF) : Const.get (m.filterMap f) k h' = @@ -3663,6 +3733,7 @@ theorem get_filterMap [EquivBEq α] [LawfulHashable α] (isSome_apply_of_mem_filterMap h h') := by simp_to_raw using Raw₀.Const.get_filterMap +@[grind =] theorem get!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited γ] {f : α → β → Option γ} {k : α} (h : m.WF) : Const.get! (m.filterMap f) k = @@ -3677,6 +3748,7 @@ theorem get!_filterMap_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inh fun x => f k' x).get! := by simp_to_raw using Raw₀.Const.get!_filterMap_of_getKey?_eq_some +@[grind =] theorem getD_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} {fallback : γ} (h : m.WF) : Const.getD (m.filterMap f) k fallback = @@ -3696,6 +3768,7 @@ theorem toList_filterMap ((Const.toList m).filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x)))) := by simp_to_raw using Raw₀.Const.toList_filterMap +@[grind =] theorem getKey?_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} (h : m.WF) : (m.filterMap f).getKey? k = @@ -3703,12 +3776,13 @@ theorem getKey?_filterMap [EquivBEq α] [LawfulHashable α] (f x (Const.get m x (mem_of_getKey?_eq_some h h'))).isSome) := by simp_to_raw using Raw₀.Const.getKey?_filterMap -@[simp] +@[simp, grind =] theorem getKey_filterMap [EquivBEq α] [LawfulHashable α] {f : (a : α) → β → Option γ} {k : α} {h'} (h : m.WF) : (m.filterMap f).getKey k h' = m.getKey k (mem_of_mem_filterMap h h') := by simp_to_raw using Raw₀.getKey_filterMap +@[grind =] theorem getKey!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → Option γ} {k : α} (h : m.WF) : (m.filterMap f).getKey! k = @@ -3716,6 +3790,7 @@ theorem getKey!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited α] (f x (Const.get m x (mem_of_getKey?_eq_some h h'))).isSome)).get! := by simp_to_raw using Raw₀.Const.getKey!_filterMap +@[grind =] theorem getKeyD_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k fallback : α} (h : m.WF) : (m.filterMap f).getKeyD k fallback = @@ -3741,6 +3816,7 @@ theorem keys_filter_key {f : α → Bool} (h : m.WF) : (m.filter fun k _ => f k).keys.Perm (m.keys.filter f) := by simp_to_raw using Raw₀.keys_filter_key +@[grind =] theorem isEmpty_filter_iff [LawfulBEq α] {f : (a : α) → β a → Bool} (h : m.WF) : (m.filter f).isEmpty = true ↔ @@ -3769,11 +3845,13 @@ theorem isEmpty_filter_key_eq_false_iff [EquivBEq α] [LawfulHashable α] simp only [mem_iff_contains] simp_to_raw using Raw₀.isEmpty_filter_key_eq_false_iff +@[grind =] theorem contains_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} (h : m.WF) : (m.filter f).contains k = (m.get? k).any (f k) := by simp_to_raw using Raw₀.contains_filter +@[grind =] theorem mem_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} (h : m.WF) : k ∈ m.filter f ↔ (m.get? k).any (f k) := by @@ -3802,6 +3880,8 @@ theorem size_filter_le_size [EquivBEq α] [LawfulHashable α] (m.filter f).size ≤ m.size := by simp_to_raw using Raw₀.size_filter_le_size +grind_pattern size_filter_le_size => (m.filter f).size + theorem size_filter_eq_size_iff [LawfulBEq α] {f : (a : α) → β a → Bool} (h : m.WF) : (m.filter f).size = m.size ↔ ∀ k h, f k (m.get k h) = true := by @@ -3826,23 +3906,25 @@ theorem size_filter_key_eq_size_iff [EquivBEq α] [LawfulHashable α] simp only [mem_iff_contains] simp_to_raw using Raw₀.size_filter_key_eq_size_iff -@[simp] +@[simp, grind =] theorem get?_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} (h : m.WF) : (m.filter f).get? k = (m.get? k).filter (f k) := by simp_to_raw using Raw₀.get?_filter -@[simp] +@[simp, grind =] theorem get_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} {h'} (h : m.WF) : (m.filter f).get k h' = m.get k (mem_of_mem_filter h h') := by simp_to_raw using Raw₀.get_filter +@[grind =] theorem get!_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} [Inhabited (β k)] (h : m.WF) : (m.filter f).get! k = ((m.get? k).filter (f k)).get! := by simp_to_raw using Raw₀.get!_filter +@[grind =] theorem getD_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} {fallback : β k} (h : m.WF) : (m.filter f).getD k fallback = ((m.get? k).filter (f k)).getD fallback := by @@ -3853,6 +3935,7 @@ theorem keys_filter [LawfulBEq α] {f : (a : α) → β a → Bool} (h : m.WF) : (m.keys.attach.filter (fun ⟨x, h'⟩ => f x (m.get x (mem_of_mem_keys h h')))).unattach := by simp_to_raw using Raw₀.keys_filter +@[grind =] theorem getKey?_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} (h : m.WF) : (m.filter f).getKey? k = @@ -3865,12 +3948,13 @@ theorem getKey?_filter_key [EquivBEq α] [LawfulHashable α] (m.filter fun k _ => f k).getKey? k = (m.getKey? k).filter f := by simp_to_raw using Raw₀.getKey?_filter_key -@[simp] +@[simp, grind =] theorem getKey_filter [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → Bool} {k : α} {h'} (h : m.WF) : (m.filter f).getKey k h' = m.getKey k (mem_of_mem_filter h h') := by simp_to_raw using Raw₀.getKey_filter +@[grind =] theorem getKey!_filter [LawfulBEq α] [Inhabited α] {f : (a : α) → β a → Bool} {k : α} (h : m.WF) : (m.filter f).getKey! k = @@ -3883,6 +3967,7 @@ theorem getKey!_filter_key [EquivBEq α] [LawfulHashable α] [Inhabited α] (m.filter fun k _ => f k).getKey! k = ((m.getKey? k).filter f).get! := by simp_to_raw using Raw₀.getKey!_filter_key +@[grind =] theorem getKeyD_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k fallback : α} (h : m.WF) : (m.filter f).getKeyD k fallback = @@ -3899,6 +3984,7 @@ namespace Const variable {β : Type v} {γ : Type w} {m : Raw α (fun _ => β)} +@[grind =] theorem isEmpty_filter_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} (h : m.WF) : (m.filter f).isEmpty = true ↔ @@ -3913,6 +3999,9 @@ theorem isEmpty_filter_eq_false_iff [EquivBEq α] [LawfulHashable α] simp only [mem_iff_contains] simp_to_raw using Raw₀.Const.isEmpty_filter_eq_false_iff +-- TODO: `contains_filter` is missing + +@[grind =] theorem mem_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} (h : m.WF) : k ∈ m.filter f ↔ ∃ (h' : k ∈ m), @@ -3925,6 +4014,8 @@ theorem size_filter_le_size [EquivBEq α] [LawfulHashable α] (m.filter f).size ≤ m.size := by simp_to_raw using Raw₀.Const.size_filter_le_size +grind_pattern size_filter_le_size => (m.filter f).size + theorem size_filter_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} (h : m.WF) : (m.filter f).size = m.size ↔ ∀ (a : α) (h : a ∈ m), @@ -3939,6 +4030,7 @@ theorem filter_equiv_self_iff [EquivBEq α] [LawfulHashable α] simp [← contains_iff_mem] simp_to_raw using Raw₀.Const.filter_equiv_self_iff +@[grind =] theorem get?_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} (h : m.WF) : Const.get? (m.filter f) k = (Const.get? m k).pfilter (fun x h' => @@ -3951,12 +4043,13 @@ theorem get?_filter_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] Const.get? (m.filter f) k = (Const.get? m k).filter (fun x => f k' x) := by simp_to_raw using Raw₀.Const.get?_filter_of_getKey?_eq_some -@[simp] +@[simp, grind =] theorem get_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} {h'} (h : m.WF) : Const.get (m.filter f) k h' = Const.get m k (mem_of_mem_filter h h') := by simp_to_raw using Raw₀.Const.get_filter +@[grind =] theorem get!_filter [EquivBEq α] [LawfulHashable α] [Inhabited β] {f : α → β → Bool} {k : α} (h : m.WF) : Const.get! (m.filter f) k = @@ -3970,6 +4063,7 @@ theorem get!_filter_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhabi Const.get! (m.filter f) k = ((Const.get? m k).filter (fun x => f k' x)).get! := by simp_to_raw using Raw₀.Const.get!_filter_of_getKey?_eq_some +@[grind =] theorem getD_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} {fallback : β} (h : m.WF) : Const.getD (m.filter f) k fallback = ((Const.get? m k).pfilter (fun x h' => @@ -3993,6 +4087,7 @@ theorem keys_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} ( (m.keys.attach.filter (fun ⟨x, h'⟩ => f x (get m x (mem_of_mem_keys h h')))).unattach := by simp_to_raw using Raw₀.Const.keys_filter +@[grind =] theorem getKey?_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} (h : m.WF) : (m.filter f).getKey? k = @@ -4000,6 +4095,7 @@ theorem getKey?_filter [EquivBEq α] [LawfulHashable α] (f x (Const.get m x (mem_of_getKey?_eq_some h h')))) := by simp_to_raw using Raw₀.Const.getKey?_filter +@[grind =] theorem getKey!_filter [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → Bool} {k : α} (h : m.WF) : (m.filter f).getKey! k = @@ -4007,6 +4103,7 @@ theorem getKey!_filter [EquivBEq α] [LawfulHashable α] [Inhabited α] (f x (Const.get m x (mem_of_getKey?_eq_some h h'))))).get! := by simp_to_raw using Raw₀.Const.getKey!_filter +@[grind =] theorem getKeyD_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k fallback : α} (h : m.WF) : (m.filter f).getKeyD k fallback = @@ -4041,12 +4138,13 @@ theorem filterMap_equiv_map [EquivBEq α] [LawfulHashable α] (m.filterMap (fun k v => some (f k v))) ~m m.map f := by simp_to_raw using Raw₀.filterMap_equiv_map -@[simp] +@[simp, grind =] theorem isEmpty_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} (h : m.WF) : (m.map f).isEmpty = m.isEmpty := by simp_to_raw using Raw₀.isEmpty_map +@[grind =] theorem contains_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k : α} (h : m.WF) : (m.map f).contains k = m.contains k := by @@ -4057,7 +4155,7 @@ theorem contains_of_contains_map [EquivBEq α] [LawfulHashable α] (m.map f).contains k = true → m.contains k = true := by simp_to_raw using Raw₀.contains_of_contains_map -@[simp] +@[simp, grind =] theorem mem_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k : α} (h : m.WF) : k ∈ (m.map f) ↔ k ∈ m := by @@ -4070,53 +4168,55 @@ theorem mem_of_mem_map [EquivBEq α] [LawfulHashable α] simp only [mem_iff_contains] simp_to_raw using Raw₀.contains_of_contains_map -@[simp] +@[simp, grind =] theorem size_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} (h : m.WF) : (m.map f).size = m.size := by simp_to_raw using Raw₀.size_map -@[simp] +@[simp, grind =] theorem get?_map [LawfulBEq α] {f : (a : α) → β a → γ a} {k : α} (h : m.WF) : (m.map f).get? k = (m.get? k).map (f k) := by simp_to_raw using Raw₀.get?_map -@[simp] +@[simp, grind =] theorem get_map [LawfulBEq α] {f : (a : α) → β a → γ a} {k : α} {h'} (h : m.WF) : (m.map f).get k h' = f k (m.get k (mem_of_mem_map h h')) := by simp_to_raw using Raw₀.get_map +@[grind =] theorem get!_map [LawfulBEq α] {f : (a : α) → β a → γ a} {k : α} [Inhabited (γ k)] (h : m.WF) : (m.map f).get! k = ((m.get? k).map (f k)).get! := by simp_to_raw using Raw₀.get!_map +@[grind =] theorem getD_map [LawfulBEq α] {f : (a : α) → β a → γ a} {k : α} {fallback : γ k} (h : m.WF) : (m.map f).getD k fallback = ((m.get? k).map (f k)).getD fallback := by simp_to_raw using Raw₀.getD_map -@[simp] +@[simp, grind =] theorem getKey?_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k : α} (h : m.WF) : (m.map f).getKey? k = m.getKey? k := by simp_to_raw using Raw₀.getKey?_map -@[simp] +@[simp, grind =] theorem getKey_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k : α} {h'} (h : m.WF) : (m.map f).getKey k h' = m.getKey k (mem_of_mem_map h h') := by simp_to_raw using Raw₀.getKey_map -@[simp] +@[simp, grind =] theorem getKey!_map [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : (a : α) → β a → γ a} {k : α} (h : m.WF) : (m.map f).getKey! k = m.getKey! k := by simp_to_raw using Raw₀.getKey!_map -@[simp] +@[simp, grind =] theorem getKeyD_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k fallback : α} (h : m.WF) : (m.map f).getKeyD k fallback = m.getKeyD k fallback := by @@ -4135,7 +4235,7 @@ theorem get?_map' [EquivBEq α] [LawfulHashable α] simp only [mem_iff_contains] simp_to_raw using Raw₀.Const.get?_map' -@[simp] +@[simp, grind =] theorem get?_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} (h : m.WF) : Const.get? (m.map f) k = (Const.get? m k).map (f k) := by @@ -4155,7 +4255,7 @@ theorem get_map' [EquivBEq α] [LawfulHashable α] (Const.get m k (mem_of_mem_map h h'))) := by simp_to_raw using Raw₀.Const.get_map' -@[simp] +@[simp, grind =] theorem get_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} (h : m.WF) {h'} : Const.get (m.map f) k h' = f k (Const.get m k (mem_of_mem_map h h')) := by @@ -4170,6 +4270,7 @@ theorem get!_map' [EquivBEq α] [LawfulHashable α] [Inhabited γ] simp only [mem_iff_contains] simp_to_raw using Raw₀.Const.get!_map' +@[grind =] theorem get!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ] {f : α → β → γ} {k : α} (h : m.WF) : Const.get! (m.map f) k = ((Const.get? m k).map (f k)).get! := by @@ -4189,6 +4290,7 @@ theorem getD_map' [EquivBEq α] [LawfulHashable α] simp only [mem_iff_contains] simp_to_raw using Raw₀.Const.getD_map' +@[grind =] theorem getD_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} {fallback : γ} (h : m.WF) : Const.getD (m.map f) k fallback = ((Const.get? m k).map (f k)).getD fallback := by diff --git a/src/Std/Data/DTreeMap/Lemmas.lean b/src/Std/Data/DTreeMap/Lemmas.lean index b08cc67493..a49cf07a20 100644 --- a/src/Std/Data/DTreeMap/Lemmas.lean +++ b/src/Std/Data/DTreeMap/Lemmas.lean @@ -1289,6 +1289,7 @@ theorem insertMany_cons {l : List ((a : α) × β a)} {k : α} {v : β k} : t.insertMany (⟨k, v⟩ :: l) = (t.insert k v).insertMany l := ext <| Impl.insertMany_cons t.wf +@[grind _=_] theorem insertMany_append {l₁ l₂ : List ((a : α) × β a)} : insertMany t (l₁ ++ l₂) = insertMany (insertMany t l₁) l₂ := by induction l₁ generalizing t with @@ -1469,6 +1470,7 @@ theorem insertMany_cons {l : List (α × β)} {k : α} {v : β} : Const.insertMany t ((k, v) :: l) = Const.insertMany (t.insert k v) l := ext <| Impl.Const.insertMany_cons t.wf +@[grind _=_] theorem insertMany_append {l₁ l₂ : List (α × β)} : insertMany t (l₁ ++ l₂) = insertMany (insertMany t l₁) l₂ := by induction l₁ generalizing t with diff --git a/src/Std/Data/DTreeMap/Raw/Lemmas.lean b/src/Std/Data/DTreeMap/Raw/Lemmas.lean index 9c43d819e6..1e0e1157b4 100644 --- a/src/Std/Data/DTreeMap/Raw/Lemmas.lean +++ b/src/Std/Data/DTreeMap/Raw/Lemmas.lean @@ -1296,6 +1296,7 @@ theorem insertMany_cons {l : List ((a : α) × β a)} {k : α} {v : β k} : t.insertMany (⟨k, v⟩ :: l) = (t.insert k v).insertMany l := ext <| Impl.insertMany!_cons +@[grind _=_] theorem insertMany_append {l₁ l₂ : List ((a : α) × β a)} : insertMany t (l₁ ++ l₂) = insertMany (insertMany t l₁) l₂ := by induction l₁ generalizing t with @@ -1476,6 +1477,7 @@ theorem insertMany_cons {l : List (α × β)} {k : α} {v : β} : Const.insertMany t ((k, v) :: l) = Const.insertMany (t.insert k v) l := ext <| Impl.Const.insertMany!_cons +@[grind _=_] theorem insertMany_append {l₁ l₂ : List (α × β)} : insertMany t (l₁ ++ l₂) = insertMany (insertMany t l₁) l₂ := by induction l₁ generalizing t with diff --git a/src/Std/Data/ExtDHashMap/Lemmas.lean b/src/Std/Data/ExtDHashMap/Lemmas.lean index 4af9801dc8..01f73f67fd 100644 --- a/src/Std/Data/ExtDHashMap/Lemmas.lean +++ b/src/Std/Data/ExtDHashMap/Lemmas.lean @@ -12,6 +12,8 @@ import Std.Data.ExtDHashMap.Basic This file contains lemmas about `Std.ExtDHashMap`. -/ +set_option trace.grind.ematch.pattern true + set_option linter.missingDocs true set_option autoImplicit false @@ -26,7 +28,7 @@ namespace Std.ExtDHashMap variable {m : ExtDHashMap α β} -@[simp] +@[simp, grind =] theorem isEmpty_iff [EquivBEq α] [LawfulHashable α] : m.isEmpty ↔ m = ∅ := by rcases m with ⟨m⟩ refine m.equiv_empty_iff_isEmpty.symm.trans ?_ @@ -39,7 +41,7 @@ theorem isEmpty_eq_false_iff [EquivBEq α] [LawfulHashable α] : m.isEmpty = fal @[simp] theorem empty_eq : ∅ = m ↔ m = ∅ := eq_comm -@[simp] +@[simp, grind =] theorem emptyWithCapacity_eq [EquivBEq α] [LawfulHashable α] {c} : (emptyWithCapacity c : ExtDHashMap α β) = ∅ := isEmpty_iff.mp DHashMap.isEmpty_emptyWithCapacity @@ -61,7 +63,7 @@ theorem contains_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == theorem mem_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == b) : a ∈ m ↔ b ∈ m := m.inductionOn fun _ => DHashMap.mem_congr hab -@[simp] +@[simp, grind =] theorem contains_empty [EquivBEq α] [LawfulHashable α] {a : α} : (∅ : DHashMap α β).contains a = false := DHashMap.contains_empty @@ -85,12 +87,12 @@ theorem singleton_eq_insert [EquivBEq α] [LawfulHashable α] {p : (a : α) × Singleton.singleton p = (∅ : DHashMap α β).insert p.1 p.2 := rfl -@[simp] +@[simp, grind =] theorem contains_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} : (m.insert k v).contains a = (k == a || m.contains a) := m.inductionOn fun _ => DHashMap.contains_insert -@[simp] +@[simp, grind =] theorem mem_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} : a ∈ m.insert k v ↔ k == a ∨ a ∈ m := m.inductionOn fun _ => DHashMap.mem_insert @@ -105,14 +107,14 @@ theorem contains_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β theorem mem_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : k ∈ m.insert k v := by simp -@[simp] +@[simp, grind =] theorem size_empty [EquivBEq α] [LawfulHashable α] : (∅ : ExtDHashMap α β).size = 0 := rfl theorem eq_empty_iff_size_eq_zero [EquivBEq α] [LawfulHashable α] : m = ∅ ↔ m.size = 0 := isEmpty_iff.symm.trans <| m.inductionOn fun _ => (Bool.eq_iff_iff.mp DHashMap.isEmpty_eq_size_eq_zero).trans beq_iff_eq -theorem size_insert [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : +@[grind =] theorem size_insert [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : (m.insert k v).size = if k ∈ m then m.size else m.size + 1 := m.inductionOn fun _ => DHashMap.size_insert @@ -122,7 +124,7 @@ theorem size_le_size_insert [EquivBEq α] [LawfulHashable α] {k : α} {v : β k theorem size_insert_le [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : (m.insert k v).size ≤ m.size + 1 := m.inductionOn fun _ => DHashMap.size_insert_le -@[simp] +@[simp, grind =] theorem erase_empty [EquivBEq α] [LawfulHashable α] {k : α} : (∅ : ExtDHashMap α β).erase k = ∅ := congrArg Quotient.mk' DHashMap.erase_empty @@ -136,12 +138,12 @@ theorem erase_eq_empty_iff [EquivBEq α] [LawfulHashable α] {k : α} : simp only [DHashMap.isEmpty_erase, Bool.or_eq_true, Bool.and_eq_true, beq_iff_eq] rfl -@[simp] +@[simp, grind =] theorem contains_erase [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k).contains a = (!(k == a) && m.contains a) := m.inductionOn fun _ => DHashMap.contains_erase -@[simp] +@[simp, grind =] theorem mem_erase [EquivBEq α] [LawfulHashable α] {k a : α} : a ∈ m.erase k ↔ (k == a) = false ∧ a ∈ m := by simp [← contains_iff_mem, contains_erase] @@ -153,7 +155,7 @@ theorem contains_of_contains_erase [EquivBEq α] [LawfulHashable α] {k a : α} theorem mem_of_mem_erase [EquivBEq α] [LawfulHashable α] {k a : α} : a ∈ m.erase k → a ∈ m := by simp -theorem size_erase [EquivBEq α] [LawfulHashable α] {k : α} : +@[grind =] theorem size_erase [EquivBEq α] [LawfulHashable α] {k : α} : (m.erase k).size = if k ∈ m then m.size - 1 else m.size := m.inductionOn fun _ => DHashMap.size_erase @@ -164,29 +166,29 @@ theorem size_le_size_erase [EquivBEq α] [LawfulHashable α] {k : α} : m.size ≤ (m.erase k).size + 1 := m.inductionOn fun _ => DHashMap.size_le_size_erase -@[simp] +@[simp, grind =] theorem containsThenInsert_fst [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : (m.containsThenInsert k v).1 = m.contains k := m.inductionOn fun _ => DHashMap.containsThenInsert_fst -@[simp] +@[simp, grind =] theorem containsThenInsert_snd [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : (m.containsThenInsert k v).2 = m.insert k v := m.inductionOn fun _ => congrArg Quotient.mk' DHashMap.containsThenInsert_snd -@[simp] +@[simp, grind =] theorem containsThenInsertIfNew_fst [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : (m.containsThenInsertIfNew k v).1 = m.contains k := m.inductionOn fun _ => DHashMap.containsThenInsertIfNew_fst -@[simp] +@[simp, grind =] theorem containsThenInsertIfNew_snd [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : (m.containsThenInsertIfNew k v).2 = m.insertIfNew k v := m.inductionOn fun _ => congrArg Quotient.mk' DHashMap.containsThenInsertIfNew_snd -@[simp] +@[simp, grind =] theorem get?_empty [LawfulBEq α] {a : α} : (∅ : ExtDHashMap α β).get? a = none := DHashMap.get?_empty -theorem get?_insert [LawfulBEq α] {a k : α} {v : β k} : (m.insert k v).get? a = +@[grind =] theorem get?_insert [LawfulBEq α] {a k : α} {v : β k} : (m.insert k v).get? a = if h : k == a then some (cast (congrArg β (eq_of_beq h)) v) else m.get? a := m.inductionOn fun _ => DHashMap.get?_insert @@ -215,7 +217,7 @@ theorem get?_eq_none_of_contains_eq_false [LawfulBEq α] {a : α} : theorem get?_eq_none [LawfulBEq α] {a : α} : ¬a ∈ m → m.get? a = none := by simpa [← contains_iff_mem] using get?_eq_none_of_contains_eq_false -theorem get?_erase [LawfulBEq α] {k a : α} : +@[grind =] theorem get?_erase [LawfulBEq α] {k a : α} : (m.erase k).get? a = if k == a then none else m.get? a := m.inductionOn fun _ => DHashMap.get?_erase @@ -227,11 +229,11 @@ namespace Const variable {β : Type v} {m : ExtDHashMap α (fun _ => β)} -@[simp] +@[simp, grind =] theorem get?_empty [EquivBEq α] [LawfulHashable α] {a : α} : get? (∅ : ExtDHashMap α (fun _ => β)) a = none := DHashMap.Const.get?_empty -theorem get?_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : +@[grind =] theorem get?_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : get? (m.insert k v) a = if k == a then some v else get? m a := m.inductionOn fun _ => DHashMap.Const.get?_insert @@ -264,7 +266,7 @@ theorem get?_eq_none_of_contains_eq_false [EquivBEq α] [LawfulHashable α] {a : theorem get?_eq_none [EquivBEq α] [LawfulHashable α] {a : α} : ¬a ∈ m → get? m a = none := by simpa [← contains_iff_mem] using get?_eq_none_of_contains_eq_false -theorem get?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : +@[grind =] theorem get?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : Const.get? (m.erase k) a = if k == a then none else get? m a := m.inductionOn fun _ => DHashMap.Const.get?_erase @@ -280,7 +282,7 @@ theorem get?_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == b) : end Const -theorem get_insert [LawfulBEq α] {k a : α} {v : β k} {h₁} : +@[grind =] theorem get_insert [LawfulBEq α] {k a : α} {v : β k} {h₁} : (m.insert k v).get a h₁ = if h₂ : k == a then cast (congrArg β (eq_of_beq h₂)) v @@ -293,7 +295,7 @@ theorem get_insert_self [LawfulBEq α] {k : α} {v : β k} : (m.insert k v).get k mem_insert_self = v := m.inductionOn fun _ => DHashMap.get_insert_self -@[simp] +@[simp, grind =] theorem get_erase [LawfulBEq α] {k a : α} {h'} : (m.erase k).get a h' = m.get a (mem_of_mem_erase h') := m.inductionOn (fun _ _ => DHashMap.get_erase) h' @@ -305,7 +307,7 @@ theorem get_eq_get_get? [LawfulBEq α] {a : α} {h} : m.get a h = (m.get? a).get (mem_iff_isSome_get?.mp h) := m.inductionOn (fun _ _ => DHashMap.get_eq_get_get?) h -theorem get_get? [LawfulBEq α] {a : α} {h} : +@[grind =]theorem get_get? [LawfulBEq α] {a : α} {h} : (m.get? a).get h = m.get a (mem_iff_isSome_get?.mpr h) := m.inductionOn (fun _ _ => DHashMap.get_get?) h @@ -313,7 +315,7 @@ namespace Const variable {β : Type v} {m : ExtDHashMap α (fun _ => β)} -theorem get_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : +@[grind =] theorem get_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : get (m.insert k v) a h₁ = if h₂ : k == a then v else get m a (mem_of_mem_insert h₁ (Bool.eq_false_iff.2 h₂)) := m.inductionOn (fun _ _ => DHashMap.Const.get_insert) h₁ @@ -323,7 +325,7 @@ theorem get_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : get (m.insert k v) k mem_insert_self = v := m.inductionOn fun _ => DHashMap.Const.get_insert_self -@[simp] +@[simp, grind =] theorem get_erase [EquivBEq α] [LawfulHashable α] {k a : α} {h'} : get (m.erase k) a h' = get m a (mem_of_mem_erase h') := m.inductionOn (fun _ _ => DHashMap.Const.get_erase) h' @@ -336,7 +338,7 @@ theorem get_eq_get_get? [EquivBEq α] [LawfulHashable α] {a : α} {h} : get m a h = (get? m a).get (mem_iff_isSome_get?.mp h) := m.inductionOn (fun _ _ => DHashMap.Const.get_eq_get_get?) h -theorem get_get? [EquivBEq α] [LawfulHashable α] {a : α} {h} : +@[grind =] theorem get_get? [EquivBEq α] [LawfulHashable α] {a : α} {h} : (get? m a).get h = get m a (mem_iff_isSome_get?.mpr h) := m.inductionOn (fun _ _ => DHashMap.Const.get_get?) h @@ -349,12 +351,12 @@ theorem get_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == b) {h end Const -@[simp] +@[simp, grind =] theorem get!_empty [LawfulBEq α] {a : α} [Inhabited (β a)] : (∅ : ExtDHashMap α β).get! a = default := DHashMap.get!_empty -theorem get!_insert [LawfulBEq α] {k a : α} [Inhabited (β a)] {v : β k} : +@[grind =] theorem get!_insert [LawfulBEq α] {k a : α} [Inhabited (β a)] {v : β k} : (m.insert k v).get! a = if h : k == a then cast (congrArg β (eq_of_beq h)) v else m.get! a := m.inductionOn fun _ => DHashMap.get!_insert @@ -372,7 +374,7 @@ theorem get!_eq_default [LawfulBEq α] {a : α} [Inhabited (β a)] : ¬a ∈ m → m.get! a = default := m.inductionOn fun _ => DHashMap.get!_eq_default -theorem get!_erase [LawfulBEq α] {k a : α} [Inhabited (β a)] : +@[grind =] theorem get!_erase [LawfulBEq α] {k a : α} [Inhabited (β a)] : (m.erase k).get! a = if k == a then default else m.get! a := m.inductionOn fun _ => DHashMap.get!_erase @@ -401,11 +403,11 @@ namespace Const variable {β : Type v} {m : ExtDHashMap α (fun _ => β)} -@[simp] +@[simp, grind =] theorem get!_empty [EquivBEq α] [LawfulHashable α] [Inhabited β] {a : α} : get! (∅ : ExtDHashMap α (fun _ => β)) a = default := DHashMap.Const.get!_empty -theorem get!_insert [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : +@[grind =]theorem get!_insert [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : get! (m.insert k v) a = if k == a then v else get! m a := m.inductionOn fun _ => DHashMap.Const.get!_insert @@ -422,7 +424,7 @@ theorem get!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited β] {a : α ¬a ∈ m → get! m a = default := m.inductionOn fun _ => DHashMap.Const.get!_eq_default -theorem get!_erase [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} : +@[grind =] theorem get!_erase [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} : get! (m.erase k) a = if k == a then default else get! m a := m.inductionOn fun _ => DHashMap.Const.get!_erase @@ -457,12 +459,12 @@ theorem get!_congr [EquivBEq α] [LawfulHashable α] [Inhabited β] {a b : α} ( end Const -@[simp] +@[simp, grind =] theorem getD_empty [LawfulBEq α] {a : α} {fallback : β a} : (∅ : ExtDHashMap α β).getD a fallback = fallback := DHashMap.getD_empty -theorem getD_insert [LawfulBEq α] {k a : α} {fallback : β a} {v : β k} : +@[grind =]theorem getD_insert [LawfulBEq α] {k a : α} {fallback : β a} {v : β k} : (m.insert k v).getD a fallback = if h : k == a then cast (congrArg β (eq_of_beq h)) v else m.getD a fallback := m.inductionOn fun _ => DHashMap.getD_insert @@ -480,7 +482,7 @@ theorem getD_eq_fallback [LawfulBEq α] {a : α} {fallback : β a} : ¬a ∈ m → m.getD a fallback = fallback := m.inductionOn fun _ => DHashMap.getD_eq_fallback -theorem getD_erase [LawfulBEq α] {k a : α} {fallback : β a} : +@[grind =] theorem getD_erase [LawfulBEq α] {k a : α} {fallback : β a} : (m.erase k).getD a fallback = if k == a then fallback else m.getD a fallback := m.inductionOn fun _ => DHashMap.getD_erase @@ -513,12 +515,12 @@ namespace Const variable {β : Type v} {m : ExtDHashMap α (fun _ => β)} -@[simp] +@[simp, grind =] theorem getD_empty [EquivBEq α] [LawfulHashable α] {a : α} {fallback : β} : getD (∅ : ExtDHashMap α (fun _ => β)) a fallback = fallback := DHashMap.Const.getD_empty -theorem getD_insert [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : +@[grind =] theorem getD_insert [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : getD (m.insert k v) a fallback = if k == a then v else getD m a fallback := m.inductionOn fun _ => DHashMap.Const.getD_insert @@ -535,7 +537,7 @@ theorem getD_eq_fallback [EquivBEq α] [LawfulHashable α] {a : α} {fallback : ¬a ∈ m → getD m a fallback = fallback := m.inductionOn fun _ => DHashMap.Const.getD_eq_fallback -theorem getD_erase [EquivBEq α] [LawfulHashable α] {k a : α} {fallback : β} : +@[grind =] theorem getD_erase [EquivBEq α] [LawfulHashable α] {k a : α} {fallback : β} : getD (m.erase k) a fallback = if k == a then fallback else getD m a fallback := m.inductionOn fun _ => DHashMap.Const.getD_erase @@ -574,11 +576,11 @@ theorem getD_congr [EquivBEq α] [LawfulHashable α] {a b : α} {fallback : β} end Const -@[simp] +@[simp, grind =] theorem getKey?_empty [EquivBEq α] [LawfulHashable α] {a : α} : (∅ : ExtDHashMap α β).getKey? a = none := DHashMap.getKey?_empty -theorem getKey?_insert [EquivBEq α] [LawfulHashable α] {a k : α} {v : β k} : +@[grind =] theorem getKey?_insert [EquivBEq α] [LawfulHashable α] {a k : α} {v : β k} : (m.insert k v).getKey? a = if k == a then some k else m.getKey? a := m.inductionOn fun _ => DHashMap.getKey?_insert @@ -616,7 +618,7 @@ theorem getKey?_eq_none_of_contains_eq_false [EquivBEq α] [LawfulHashable α] { theorem getKey?_eq_none [EquivBEq α] [LawfulHashable α] {a : α} : ¬a ∈ m → m.getKey? a = none := m.inductionOn fun _ => DHashMap.getKey?_eq_none -theorem getKey?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : +@[grind =] theorem getKey?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k).getKey? a = if k == a then none else m.getKey? a := m.inductionOn fun _ => DHashMap.getKey?_erase @@ -639,7 +641,7 @@ theorem getKey?_eq_some_of_contains [LawfulBEq α] {k : α} (h : m.contains k) : theorem getKey?_eq_some [LawfulBEq α] {k : α} (h : k ∈ m) : m.getKey? k = some k := m.inductionOn (fun _ h => DHashMap.getKey?_eq_some h) h -theorem getKey_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} {h₁} : +@[grind =] theorem getKey_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} {h₁} : (m.insert k v).getKey a h₁ = if h₂ : k == a then k @@ -652,7 +654,7 @@ theorem getKey_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} (m.insert k v).getKey k mem_insert_self = k := m.inductionOn fun _ => DHashMap.getKey_insert_self -@[simp] +@[simp, grind =] theorem getKey_erase [EquivBEq α] [LawfulHashable α] {k a : α} {h'} : (m.erase k).getKey a h' = m.getKey a (mem_of_mem_erase h') := m.inductionOn (fun _ _ => DHashMap.getKey_erase) h' @@ -665,7 +667,7 @@ theorem getKey_eq_get_getKey? [EquivBEq α] [LawfulHashable α] {a : α} {h} : m.getKey a h = (m.getKey? a).get (mem_iff_isSome_getKey?.mp h) := m.inductionOn (fun _ _ => DHashMap.getKey_eq_get_getKey?) h -@[simp] +@[simp, grind =] theorem get_getKey? [EquivBEq α] [LawfulHashable α] {a : α} {h} : (m.getKey? a).get h = m.getKey a (mem_iff_isSome_getKey?.mpr h) := m.inductionOn (fun _ _ => DHashMap.get_getKey?) h @@ -677,16 +679,16 @@ theorem getKey_congr [EquivBEq α] [LawfulHashable α] {k₁ k₂ : α} (h : k (h₁ : k₁ ∈ m) : m.getKey k₁ h₁ = m.getKey k₂ ((mem_congr h).mp h₁) := m.inductionOn (fun _ h h₁ => DHashMap.getKey_congr h h₁) h h₁ -@[simp] +@[simp, grind =] theorem getKey_eq [LawfulBEq α] {k : α} (h : k ∈ m) : m.getKey k h = k := m.inductionOn (fun _ h => DHashMap.getKey_eq h) h -@[simp] +@[simp, grind =] theorem getKey!_empty [EquivBEq α] [LawfulHashable α] [Inhabited α] {a : α} : (∅ : ExtDHashMap α β).getKey! a = default := DHashMap.getKey!_empty -theorem getKey!_insert [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β k} : +@[grind =] theorem getKey!_insert [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β k} : (m.insert k v).getKey! a = if k == a then k else m.getKey! a := m.inductionOn fun _ => DHashMap.getKey!_insert @@ -705,7 +707,7 @@ theorem getKey!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited α] {a : ¬a ∈ m → m.getKey! a = default := m.inductionOn fun _ => DHashMap.getKey!_eq_default -theorem getKey!_erase [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} : +@[grind =] theorem getKey!_erase [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} : (m.erase k).getKey! a = if k == a then default else m.getKey! a := m.inductionOn fun _ => DHashMap.getKey!_erase @@ -741,12 +743,12 @@ theorem getKey!_eq_of_contains [LawfulBEq α] [Inhabited α] {k : α} (h : m.con theorem getKey!_eq_of_mem [LawfulBEq α] [Inhabited α] {k : α} (h : k ∈ m) : m.getKey! k = k := m.inductionOn (fun _ h => DHashMap.getKey!_eq_of_mem h) h -@[simp] +@[simp, grind =] theorem getKeyD_empty [EquivBEq α] [LawfulHashable α] {a fallback : α} : (∅ : ExtDHashMap α β).getKeyD a fallback = fallback := DHashMap.getKeyD_empty -theorem getKeyD_insert [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β k} : +@[grind =] theorem getKeyD_insert [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β k} : (m.insert k v).getKeyD a fallback = if k == a then k else m.getKeyD a fallback := m.inductionOn fun _ => DHashMap.getKeyD_insert @@ -765,7 +767,7 @@ theorem getKeyD_eq_fallback [EquivBEq α] [LawfulHashable α] {a fallback : α} ¬a ∈ m → m.getKeyD a fallback = fallback := m.inductionOn fun _ => DHashMap.getKeyD_eq_fallback -theorem getKeyD_erase [EquivBEq α] [LawfulHashable α] {k a fallback : α} : +@[grind =] theorem getKeyD_erase [EquivBEq α] [LawfulHashable α] {k a fallback : α} : (m.erase k).getKeyD a fallback = if k == a then fallback else m.getKeyD a fallback := m.inductionOn fun _ => DHashMap.getKeyD_erase @@ -811,12 +813,12 @@ theorem not_insertIfNew_eq_empty [EquivBEq α] [LawfulHashable α] {k : α} {v : ¬m.insertIfNew k v = ∅ := isEmpty_eq_false_iff.mp <| m.inductionOn fun _ => DHashMap.isEmpty_insertIfNew -@[simp] +@[simp, grind =] theorem contains_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} : (m.insertIfNew k v).contains a = (k == a || m.contains a) := m.inductionOn fun _ => DHashMap.contains_insertIfNew -@[simp] +@[simp, grind =] theorem mem_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} : a ∈ m.insertIfNew k v ↔ k == a ∨ a ∈ m := m.inductionOn fun _ => DHashMap.mem_insertIfNew @@ -849,7 +851,7 @@ theorem mem_of_mem_insertIfNew' [EquivBEq α] [LawfulHashable α] {k a : α} {v a ∈ m.insertIfNew k v → ¬((k == a) ∧ ¬k ∈ m) → a ∈ m := m.inductionOn fun _ => DHashMap.mem_of_mem_insertIfNew' -theorem size_insertIfNew [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : +@[grind =] theorem size_insertIfNew [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : (m.insertIfNew k v).size = if k ∈ m then m.size else m.size + 1 := m.inductionOn fun _ => DHashMap.size_insertIfNew @@ -861,21 +863,21 @@ theorem size_insertIfNew_le [EquivBEq α] [LawfulHashable α] {k : α} {v : β k (m.insertIfNew k v).size ≤ m.size + 1 := m.inductionOn fun _ => DHashMap.size_insertIfNew_le -theorem get?_insertIfNew [LawfulBEq α] {k a : α} {v : β k} : (m.insertIfNew k v).get? a = +@[grind =] theorem get?_insertIfNew [LawfulBEq α] {k a : α} {v : β k} : (m.insertIfNew k v).get? a = if h : k == a ∧ ¬k ∈ m then some (cast (congrArg β (eq_of_beq h.1)) v) else m.get? a := m.inductionOn fun _ => DHashMap.get?_insertIfNew -theorem get_insertIfNew [LawfulBEq α] {k a : α} {v : β k} {h₁} : (m.insertIfNew k v).get a h₁ = +@[grind =] theorem get_insertIfNew [LawfulBEq α] {k a : α} {v : β k} {h₁} : (m.insertIfNew k v).get a h₁ = if h₂ : k == a ∧ ¬k ∈ m then cast (congrArg β (eq_of_beq h₂.1)) v else m.get a (mem_of_mem_insertIfNew' h₁ h₂) := m.inductionOn (fun _ _ => DHashMap.get_insertIfNew) h₁ -theorem get!_insertIfNew [LawfulBEq α] {k a : α} [Inhabited (β a)] {v : β k} : +@[grind =] theorem get!_insertIfNew [LawfulBEq α] {k a : α} [Inhabited (β a)] {v : β k} : (m.insertIfNew k v).get! a = if h : k == a ∧ ¬k ∈ m then cast (congrArg β (eq_of_beq h.1)) v else m.get! a := m.inductionOn fun _ => DHashMap.get!_insertIfNew -theorem getD_insertIfNew [LawfulBEq α] {k a : α} {fallback : β a} {v : β k} : +@[grind =] theorem getD_insertIfNew [LawfulBEq α] {k a : α} {fallback : β a} {v : β k} : (m.insertIfNew k v).getD a fallback = if h : k == a ∧ ¬k ∈ m then cast (congrArg β (eq_of_beq h.1)) v else m.getD a fallback := @@ -885,50 +887,50 @@ namespace Const variable {β : Type v} {m : ExtDHashMap α (fun _ => β)} -theorem get?_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : +@[grind =] theorem get?_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : get? (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then some v else get? m a := m.inductionOn fun _ => DHashMap.Const.get?_insertIfNew -theorem get_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : +@[grind =] theorem get_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : get (m.insertIfNew k v) a h₁ = if h₂ : k == a ∧ ¬k ∈ m then v else get m a (mem_of_mem_insertIfNew' h₁ h₂) := m.inductionOn (fun _ _ => DHashMap.Const.get_insertIfNew) h₁ -theorem get!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : +@[grind =] theorem get!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : get! (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then v else get! m a := m.inductionOn fun _ => DHashMap.Const.get!_insertIfNew -theorem getD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : +@[grind =] theorem getD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : getD (m.insertIfNew k v) a fallback = if k == a ∧ ¬k ∈ m then v else getD m a fallback := m.inductionOn fun _ => DHashMap.Const.getD_insertIfNew end Const -theorem getKey?_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} : +@[grind =] theorem getKey?_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} : getKey? (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then some k else getKey? m a := m.inductionOn fun _ => DHashMap.getKey?_insertIfNew -theorem getKey_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} {h₁} : +@[grind =] theorem getKey_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β k} {h₁} : getKey (m.insertIfNew k v) a h₁ = if h₂ : k == a ∧ ¬k ∈ m then k else getKey m a (mem_of_mem_insertIfNew' h₁ h₂) := m.inductionOn (fun _ _ => DHashMap.getKey_insertIfNew) h₁ -theorem getKey!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β k} : +@[grind =] theorem getKey!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β k} : getKey! (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then k else getKey! m a := m.inductionOn fun _ => DHashMap.getKey!_insertIfNew -theorem getKeyD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β k} : +@[grind =] theorem getKeyD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β k} : getKeyD (m.insertIfNew k v) a fallback = if k == a ∧ ¬k ∈ m then k else getKeyD m a fallback := m.inductionOn fun _ => DHashMap.getKeyD_insertIfNew -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_fst [LawfulBEq α] {k : α} {v : β k} : (m.getThenInsertIfNew? k v).1 = m.get? k := m.inductionOn fun _ => DHashMap.getThenInsertIfNew?_fst -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_snd [LawfulBEq α] {k : α} {v : β k} : (m.getThenInsertIfNew? k v).2 = m.insertIfNew k v := m.inductionOn fun _ => congrArg Quotient.mk' DHashMap.getThenInsertIfNew?_snd @@ -937,11 +939,11 @@ namespace Const variable {β : Type v} {m : ExtDHashMap α (fun _ => β)} -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_fst [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (getThenInsertIfNew? m k v).1 = get? m k := m.inductionOn fun _ => DHashMap.Const.getThenInsertIfNew?_fst -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_snd [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (getThenInsertIfNew? m k v).2 = m.insertIfNew k v := m.inductionOn fun _ => congrArg Quotient.mk' DHashMap.Const.getThenInsertIfNew?_snd @@ -952,13 +954,14 @@ section insertMany variable {ρ : Type w} [ForIn Id ρ ((a : α) × β a)] -@[simp] +@[simp, grind =] theorem insertMany_nil [EquivBEq α] [LawfulHashable α] : m.insertMany [] = m := rfl -@[simp] +@[simp, grind =] theorem insertMany_list_singleton [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : m.insertMany [⟨k, v⟩] = m.insert k v := rfl +@[grind _=_] theorem insertMany_cons [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} {p : (a : α) × β a} : m.insertMany (p :: l) = (m.insert p.1 p.2).insertMany l := by @@ -969,6 +972,7 @@ theorem insertMany_cons [EquivBEq α] [LawfulHashable α] exact (List.foldl_hom (f := Subtype.val) fun x y => rfl).symm exact (List.foldl_hom (f := Subtype.val) fun x y => rfl).symm +@[grind _=_] theorem insertMany_append [EquivBEq α] [LawfulHashable α] {l₁ l₂ : List ((a : α) × β a)} : insertMany m (l₁ ++ l₂) = insertMany (insertMany m l₁) l₂ := by induction l₁ generalizing m with @@ -994,7 +998,7 @@ theorem insertMany_ind [EquivBEq α] [LawfulHashable α] {motive : ExtDHashMap change motive (Subtype.val ?my_mvar) exact Subtype.property ?my_mvar motive init (insert _ _ _) -@[simp] +@[simp, grind =] theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} {k : α} : (m.insertMany l).contains k = (m.contains k || (l.map Sigma.fst).contains k) := by @@ -1002,7 +1006,7 @@ theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] simp only [insertMany_list_mk] exact DHashMap.contains_insertMany_list -@[simp] +@[simp, grind =] theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} {k : α} : k ∈ m.insertMany l ↔ k ∈ m ∨ (l.map Sigma.fst).contains k := by @@ -1185,6 +1189,8 @@ theorem size_le_size_insertMany_list [EquivBEq α] [LawfulHashable α] theorem size_le_size_insertMany [EquivBEq α] [LawfulHashable α] {l : ρ} : m.size ≤ (m.insertMany l).size := insertMany_ind m l (Nat.le_refl _) fun _ _ _ h => Nat.le_trans h size_le_size_insert +grind_pattern size_le_size_insertMany_list => (m.insertMany l).size + theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} : (m.insertMany l).size ≤ m.size + l.length := by @@ -1192,6 +1198,8 @@ theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] simp only [insertMany_list_mk] exact DHashMap.size_insertMany_list_le +grind_pattern size_insertMany_list_le => (m.insertMany l).size + @[simp] theorem insertMany_list_eq_empty_iff [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} : m.insertMany l = ∅ ↔ m = ∅ ∧ l = [] := by @@ -1209,14 +1217,15 @@ namespace Const variable {β : Type v} {m : ExtDHashMap α (fun _ => β)} variable {ρ : Type w} [ForIn Id ρ (α × β)] -@[simp] +@[simp, grind =] theorem insertMany_nil [EquivBEq α] [LawfulHashable α] : insertMany m [] = m := rfl -@[simp] +@[simp, grind =] theorem insertMany_list_singleton [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : insertMany m [⟨k, v⟩] = m.insert k v := rfl +@[grind _=_] theorem insertMany_cons [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {p : α × β} : insertMany m (p :: l) = insertMany (m.insert p.1 p.2) l := by rcases p with ⟨k, v⟩ @@ -1226,6 +1235,7 @@ theorem insertMany_cons [EquivBEq α] [LawfulHashable α] {l : List (α × β)} exact (List.foldl_hom (f := Subtype.val) fun x y => rfl).symm exact (List.foldl_hom (f := Subtype.val) fun x y => rfl).symm +@[grind _=_] theorem insertMany_append [EquivBEq α] [LawfulHashable α] {l₁ l₂ : List (α × β)} : insertMany m (l₁ ++ l₂) = insertMany (insertMany m l₁) l₂ := by induction l₁ generalizing m with @@ -1253,7 +1263,7 @@ theorem insertMany_ind [EquivBEq α] [LawfulHashable α] {motive : ExtDHashMap change motive (Subtype.val ?my_mvar) exact Subtype.property ?my_mvar motive init (insert _ _ _) -@[simp] +@[simp, grind =] theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : (Const.insertMany m l).contains k = (m.contains k || (l.map Prod.fst).contains k) := by @@ -1261,7 +1271,7 @@ theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] simp only [insertMany_list_mk] exact DHashMap.Const.contains_insertMany_list -@[simp] +@[simp, grind =] theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : k ∈ insertMany m l ↔ k ∈ m ∨ (l.map Prod.fst).contains k := by @@ -1374,6 +1384,8 @@ theorem size_le_size_insertMany_list [EquivBEq α] [LawfulHashable α] theorem size_le_size_insertMany [EquivBEq α] [LawfulHashable α] {l : ρ} : m.size ≤ (insertMany m l).size := insertMany_ind m l (Nat.le_refl _) fun _ _ _ h => Nat.le_trans h size_le_size_insert +grind_pattern size_le_size_insertMany => (insertMany m l).size + theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] {l : List (α × β)} : (insertMany m l).size ≤ m.size + l.length := by @@ -1381,6 +1393,8 @@ theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] simp only [insertMany_list_mk] exact DHashMap.Const.size_insertMany_list_le +grind_pattern size_insertMany_list_le => (insertMany m l).size + @[simp] theorem insertMany_list_eq_empty_iff [EquivBEq α] [LawfulHashable α] {l : List (α × β)} : insertMany m l = ∅ ↔ m = ∅ ∧ l = [] := by @@ -1408,7 +1422,7 @@ theorem get?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] simp only [insertMany_list_mk] exact DHashMap.Const.get?_insertMany_list_of_mem k_beq distinct mem -theorem get?_insertMany_list [EquivBEq α] [LawfulHashable α] +@[grind =] theorem get?_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : get? (insertMany m l) k = (l.findSomeRev? (fun ⟨a, b⟩ => if a == k then some b else none)).or (get? m k) := by @@ -1690,14 +1704,15 @@ end ExtDHashMap namespace ExtDHashMap -@[simp] +@[simp, grind =] theorem ofList_nil [EquivBEq α] [LawfulHashable α] : ofList ([] : List ((a : α) × β a)) = ∅ := rfl -@[simp] +@[simp, grind =] theorem ofList_singleton [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} : ofList [⟨k, v⟩] = (∅ : ExtDHashMap α β).insert k v := rfl +@[grind _=_] theorem ofList_cons [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} {tl : List ((a : α) × β a)} : ofList (⟨k, v⟩ :: tl) = ((∅ : ExtDHashMap α β).insert k v).insertMany tl := by conv => rhs; apply insertMany_list_mk @@ -1708,13 +1723,13 @@ theorem ofList_eq_insertMany_empty [EquivBEq α] [LawfulHashable α] {l : List ( conv => rhs; apply insertMany_list_mk exact congrArg Quotient.mk' DHashMap.ofList_eq_insertMany_empty -@[simp] +@[simp, grind =] theorem contains_ofList [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} {k : α} : (ofList l).contains k = (l.map Sigma.fst).contains k := DHashMap.contains_ofList -@[simp] +@[simp, grind =] theorem mem_ofList [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} {k : α} : k ∈ ofList l ↔ (l.map Sigma.fst).contains k := @@ -1828,6 +1843,8 @@ theorem size_ofList_le [EquivBEq α] [LawfulHashable α] (ofList l).size ≤ l.length := DHashMap.size_ofList_le +grind_pattern size_ofList_le => (ofList l).size + @[simp] theorem ofList_eq_empty_iff [EquivBEq α] [LawfulHashable α] {l : List ((a : α) × β a)} : ofList l = ∅ ↔ l = [] := by @@ -1838,16 +1855,17 @@ namespace Const variable {β : Type v} -@[simp] +@[simp, grind =] theorem ofList_nil [EquivBEq α] [LawfulHashable α] : ofList ([] : List (α × β)) = ∅ := rfl -@[simp] +@[simp, grind =] theorem ofList_singleton [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : ofList [⟨k, v⟩] = (∅ : ExtDHashMap α (fun _ => β)).insert k v := rfl +@[grind _=_] theorem ofList_cons [EquivBEq α] [LawfulHashable α] {k : α} {v : β} {tl : List (α × β)} : ofList (⟨k, v⟩ :: tl) = insertMany ((∅ : ExtDHashMap α (fun _ => β)).insert k v) tl := by conv => rhs; apply insertMany_list_mk @@ -1858,13 +1876,13 @@ theorem ofList_eq_insertMany_empty [EquivBEq α] [LawfulHashable α] {l : List ( conv => rhs; apply insertMany_list_mk exact congrArg Quotient.mk' DHashMap.Const.ofList_eq_insertMany_empty -@[simp] +@[simp, grind =] theorem contains_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : (ofList l).contains k = (l.map Prod.fst).contains k := DHashMap.Const.contains_ofList -@[simp] +@[simp, grind =] theorem mem_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : k ∈ ofList l ↔ (l.map Prod.fst).contains k := @@ -1978,6 +1996,8 @@ theorem size_ofList_le [EquivBEq α] [LawfulHashable α] (ofList l).size ≤ l.length := DHashMap.Const.size_ofList_le +grind_pattern size_ofList_le => (ofList l).size + @[simp] theorem ofList_eq_empty_iff [EquivBEq α] [LawfulHashable α] {l : List (α × β)} : ofList l = ∅ ↔ l = [] := by @@ -2118,11 +2138,11 @@ theorem alter_eq_empty_iff [LawfulBEq α] {k : α} {f : Option (β k) → Option alter m k f = ∅ ↔ (m = ∅ ∨ (m.size = 1 ∧ k ∈ m)) ∧ f (get? m k) = none := by simp only [alter_eq_empty_iff_erase_eq_empty, erase_eq_empty_iff] -theorem contains_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} : +@[grind =] theorem contains_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} : (m.alter k f).contains k' = if k == k' then (f (m.get? k)).isSome else m.contains k' := m.inductionOn fun _ => DHashMap.contains_alter -theorem mem_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} : +@[grind =] theorem mem_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} : k' ∈ m.alter k f ↔ if k == k' then (f (m.get? k)).isSome = true else k' ∈ m := m.inductionOn fun _ => DHashMap.mem_alter @@ -2148,7 +2168,7 @@ theorem mem_alter_of_beq_eq_false [LawfulBEq α] {k k' : α} {f : Option (β k) (h : (k == k') = false) : k' ∈ m.alter k f ↔ k' ∈ m := m.inductionOn (fun _ h => DHashMap.mem_alter_of_beq_eq_false h) h -theorem size_alter [LawfulBEq α] {k : α} {f : Option (β k) → Option (β k)} : +@[grind =] theorem size_alter [LawfulBEq α] {k : α} {f : Option (β k) → Option (β k)} : (m.alter k f).size = if k ∈ m ∧ (f (m.get? k)).isNone then m.size - 1 @@ -2184,7 +2204,7 @@ theorem size_le_size_alter [LawfulBEq α] {k : α} {f : Option (β k) → Option m.size - 1 ≤ (m.alter k f).size := m.inductionOn fun _ => DHashMap.size_le_size_alter -theorem get?_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} : +@[grind =] theorem get?_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} : (m.alter k f).get? k' = if h : k == k' then (cast (congrArg (Option ∘ β) (eq_of_beq h)) (f (m.get? k))) @@ -2197,7 +2217,7 @@ theorem get?_alter_self [LawfulBEq α] {k : α} {f : Option (β k) → Option ( (m.alter k f).get? k = f (m.get? k) := m.inductionOn fun _ => DHashMap.get?_alter_self -theorem get_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} +@[grind =] theorem get_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} {h : k' ∈ m.alter k f} : (m.alter k f).get k' h = if heq : k == k' then @@ -2215,7 +2235,7 @@ theorem get_alter_self [LawfulBEq α] {k : α} {f : Option (β k) → Option (β (m.alter k f).get k h = (f (m.get? k)).get h' := m.inductionOn (fun _ _ => DHashMap.get_alter_self) h -theorem get!_alter [LawfulBEq α] {k k' : α} [hi : Inhabited (β k')] +@[grind =] theorem get!_alter [LawfulBEq α] {k k' : α} [hi : Inhabited (β k')] {f : Option (β k) → Option (β k)} : (m.alter k f).get! k' = if heq : k == k' then (f (m.get? k)).map (cast (congrArg β (eq_of_beq heq))) |>.get! @@ -2228,7 +2248,7 @@ theorem get!_alter_self [LawfulBEq α] {k : α} [Inhabited (β k)] {f : Option ( (m.alter k f).get! k = (f (m.get? k)).get! := m.inductionOn fun _ => DHashMap.get!_alter_self -theorem getD_alter [LawfulBEq α] {k k' : α} {fallback : β k'} {f : Option (β k) → Option (β k)} : +@[grind =] theorem getD_alter [LawfulBEq α] {k k' : α} {fallback : β k'} {f : Option (β k) → Option (β k)} : (m.alter k f).getD k' fallback = if heq : k == k' then f (m.get? k) |>.map (cast (congrArg β <| eq_of_beq heq)) |>.getD fallback @@ -2241,7 +2261,7 @@ theorem getD_alter_self [LawfulBEq α] {k : α} {fallback : β k} {f : Option ( (m.alter k f).getD k fallback = (f (m.get? k)).getD fallback := m.inductionOn fun _ => DHashMap.getD_alter_self -theorem getKey?_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} : +@[grind =] theorem getKey?_alter [LawfulBEq α] {k k' : α} {f : Option (β k) → Option (β k)} : (m.alter k f).getKey? k' = if k == k' then if (f (m.get? k)).isSome then some k else none @@ -2253,7 +2273,7 @@ theorem getKey?_alter_self [LawfulBEq α] {k : α} {f : Option (β k) → Option (m.alter k f).getKey? k = if (f (m.get? k)).isSome then some k else none := m.inductionOn fun _ => DHashMap.getKey?_alter_self -theorem getKey!_alter [LawfulBEq α] [Inhabited α] {k k' : α} {f : Option (β k) → Option (β k)} : +@[grind =] theorem getKey!_alter [LawfulBEq α] [Inhabited α] {k k' : α} {f : Option (β k) → Option (β k)} : (m.alter k f).getKey! k' = if k == k' then if (f (m.get? k)).isSome then k else default @@ -2281,7 +2301,7 @@ theorem getKey_alter_self [LawfulBEq α] [Inhabited α] {k : α} {f : Option (β {h : k ∈ m.alter k f} : (m.alter k f).getKey k h = k := m.inductionOn (fun _ _ => DHashMap.getKey_alter_self) h -theorem getKeyD_alter [LawfulBEq α] {k k' fallback : α} {f : Option (β k) → Option (β k)} : +@[grind =] theorem getKeyD_alter [LawfulBEq α] {k k' fallback : α} {f : Option (β k) → Option (β k)} : (m.alter k f).getKeyD k' fallback = if k == k' then if (f (m.get? k)).isSome then k else fallback @@ -2313,12 +2333,12 @@ theorem alter_eq_empty_iff [EquivBEq α] [LawfulHashable α] {k : α} {f : Optio alter m k f = ∅ ↔ (m = ∅ ∨ (m.size = 1 ∧ k ∈ m)) ∧ f (get? m k) = none := by simp only [alter_eq_empty_iff_erase_eq_empty, erase_eq_empty_iff] -theorem contains_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} : +@[grind =] theorem contains_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} : (Const.alter m k f).contains k' = if k == k' then (f (Const.get? m k)).isSome else m.contains k' := m.inductionOn fun _ => DHashMap.Const.contains_alter -theorem mem_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} : +@[grind =] theorem mem_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} : k' ∈ Const.alter m k f ↔ if k == k' then (f (Const.get? m k)).isSome = true else k' ∈ m := m.inductionOn fun _ => DHashMap.Const.mem_alter @@ -2345,7 +2365,7 @@ theorem mem_alter_of_beq_eq_false [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} (h : (k == k') = false) : k' ∈ Const.alter m k f ↔ k' ∈ m := m.inductionOn (fun _ h => DHashMap.Const.mem_alter_of_beq_eq_false h) h -theorem size_alter [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β → Option β} : +@[grind =] theorem size_alter [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β → Option β} : (Const.alter m k f).size = if k ∈ m ∧ (f (Const.get? m k)).isNone then m.size - 1 @@ -2381,7 +2401,7 @@ theorem size_le_size_alter [EquivBEq α] [LawfulHashable α] {k : α} {f : Optio m.size - 1 ≤ (Const.alter m k f).size := m.inductionOn fun _ => DHashMap.Const.size_le_size_alter -theorem get?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} : +@[grind =] theorem get?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} : Const.get? (Const.alter m k f) k' = if k == k' then f (Const.get? m k) @@ -2394,7 +2414,7 @@ theorem get?_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Option Const.get? (Const.alter m k f) k = f (Const.get? m k) := m.inductionOn fun _ => DHashMap.Const.get?_alter_self -theorem get_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} +@[grind =] theorem get_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} {h : k' ∈ Const.alter m k f} : Const.get (Const.alter m k f) k' h = if heq : k == k' then @@ -2412,7 +2432,7 @@ theorem get_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β Const.get (Const.alter m k f) k h = (f (Const.get? m k)).get h' := m.inductionOn (fun _ _ => DHashMap.Const.get_alter_self) h -theorem get!_alter [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] +@[grind =] theorem get!_alter [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] {f : Option β → Option β} : Const.get! (Const.alter m k f) k' = if k == k' then f (Const.get? m k) |>.get! @@ -2425,7 +2445,7 @@ theorem get!_alter_self [EquivBEq α] [LawfulHashable α] {k : α} [Inhabited β {f : Option β → Option β} : Const.get! (Const.alter m k f) k = (f (Const.get? m k)).get! := m.inductionOn fun _ => DHashMap.Const.get!_alter_self -theorem getD_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} +@[grind =] theorem getD_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} {f : Option β → Option β} : Const.getD (Const.alter m k f) k' fallback = if k == k' then @@ -2440,7 +2460,7 @@ theorem getD_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {fallback : Const.getD (Const.alter m k f) k fallback = (f (Const.get? m k)).getD fallback := m.inductionOn fun _ => DHashMap.Const.getD_alter_self -theorem getKey?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} : +@[grind =] theorem getKey?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} : (Const.alter m k f).getKey? k' = if k == k' then if (f (Const.get? m k)).isSome then some k else none @@ -2452,7 +2472,7 @@ theorem getKey?_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Optio (Const.alter m k f).getKey? k = if (f (Const.get? m k)).isSome then some k else none := m.inductionOn fun _ => DHashMap.Const.getKey?_alter_self -theorem getKey!_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} +@[grind =] theorem getKey!_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : Option β → Option β} : (Const.alter m k f).getKey! k' = if k == k' then if (f (Const.get? m k)).isSome then k else default @@ -2465,7 +2485,7 @@ theorem getKey!_alter_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : (Const.alter m k f).getKey! k = if (f (Const.get? m k)).isSome then k else default := m.inductionOn fun _ => DHashMap.Const.getKey!_alter_self -theorem getKey_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} +@[grind =] theorem getKey_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : Option β → Option β} {h : k' ∈ Const.alter m k f} : (Const.alter m k f).getKey k' h = if heq : k == k' then @@ -2481,7 +2501,8 @@ theorem getKey_alter_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : (Const.alter m k f).getKey k h = k := m.inductionOn (fun _ _ => DHashMap.Const.getKey_alter_self) h -theorem getKeyD_alter [EquivBEq α] [LawfulHashable α] {k k' fallback : α} {f : Option β → Option β} : +@[grind =] theorem getKeyD_alter [EquivBEq α] [LawfulHashable α] {k k' fallback : α} + {f : Option β → Option β} : (Const.alter m k f).getKeyD k' fallback = if k == k' then if (f (Const.get? m k)).isSome then k else fallback @@ -2507,19 +2528,20 @@ theorem modify_eq_empty_iff [LawfulBEq α] {k : α} {f : β k → β k} : simp only [← isEmpty_iff, Bool.coe_iff_coe] exact m.inductionOn fun _ => DHashMap.isEmpty_modify -@[simp] +@[simp, grind =] theorem contains_modify [LawfulBEq α] {k k': α} {f : β k → β k} : (m.modify k f).contains k' = m.contains k' := m.inductionOn fun _ => DHashMap.contains_modify -@[simp] +@[simp, grind =] theorem mem_modify [LawfulBEq α] {k k': α} {f : β k → β k} : k' ∈ m.modify k f ↔ k' ∈ m := m.inductionOn fun _ => DHashMap.mem_modify -@[simp] +@[simp, grind =] theorem size_modify [LawfulBEq α] {k : α} {f : β k → β k} : (m.modify k f).size = m.size := m.inductionOn fun _ => DHashMap.size_modify +@[grind =] theorem get?_modify [LawfulBEq α] {k k' : α} {f : β k → β k} : (m.modify k f).get? k' = if h : k == k' then (cast (congrArg (Option ∘ β) (eq_of_beq h)) ((m.get? k).map f)) @@ -2532,6 +2554,7 @@ theorem get?_modify_self [LawfulBEq α] {k : α} {f : β k → β k} : (m.modify k f).get? k = (m.get? k).map f := m.inductionOn fun _ => DHashMap.get?_modify_self +@[grind =] theorem get_modify [LawfulBEq α] {k k' : α} {f : β k → β k} (h : k' ∈ m.modify k f) : (m.modify k f).get k' h = @@ -2549,6 +2572,7 @@ theorem get_modify_self [LawfulBEq α] {k : α} {f : β k → β k} {h : k ∈ m (m.modify k f).get k h = f (m.get k h') := m.inductionOn (fun _ _ => DHashMap.get_modify_self) h +@[grind =] theorem get!_modify [LawfulBEq α] {k k' : α} [hi : Inhabited (β k')] {f : β k → β k} : (m.modify k f).get! k' = if heq : k == k' then @@ -2562,6 +2586,7 @@ theorem get!_modify_self [LawfulBEq α] {k : α} [Inhabited (β k)] {f : β k (m.modify k f).get! k = ((m.get? k).map f).get! := m.inductionOn fun _ => DHashMap.get!_modify_self +@[grind =] theorem getD_modify [LawfulBEq α] {k k' : α} {fallback : β k'} {f : β k → β k} : (m.modify k f).getD k' fallback = if heq : k == k' then @@ -2575,6 +2600,7 @@ theorem getD_modify_self [LawfulBEq α] {k : α} {fallback : β k} {f : β k → (m.modify k f).getD k fallback = ((m.get? k).map f).getD fallback := m.inductionOn fun _ => DHashMap.getD_modify_self +@[grind =] theorem getKey?_modify [LawfulBEq α] {k k' : α} {f : β k → β k} : (m.modify k f).getKey? k' = if k == k' then @@ -2587,6 +2613,7 @@ theorem getKey?_modify_self [LawfulBEq α] {k : α} {f : β k → β k} : (m.modify k f).getKey? k = if k ∈ m then some k else none := m.inductionOn fun _ => DHashMap.getKey?_modify_self +@[grind =] theorem getKey!_modify [LawfulBEq α] [Inhabited α] {k k' : α} {f : β k → β k} : (m.modify k f).getKey! k' = if k == k' then @@ -2615,6 +2642,7 @@ theorem getKey_modify_self [LawfulBEq α] [Inhabited α] {k : α} {f : β k → {h : k ∈ m.modify k f} : (m.modify k f).getKey k h = k := m.inductionOn (fun _ _ => DHashMap.getKey_modify_self) h +@[grind =] theorem getKeyD_modify [LawfulBEq α] {k k' fallback : α} {f : β k → β k} : (m.modify k f).getKeyD k' fallback = if k == k' then @@ -2637,21 +2665,22 @@ theorem modify_eq_empty_iff [EquivBEq α] [LawfulHashable α] {k : α} {f : β simp only [← isEmpty_iff, Bool.coe_iff_coe] exact m.inductionOn fun _ => DHashMap.Const.isEmpty_modify -@[simp] +@[simp, grind =] theorem contains_modify [EquivBEq α] [LawfulHashable α] {k k': α} {f : β → β} : (Const.modify m k f).contains k' = m.contains k' := m.inductionOn fun _ => DHashMap.Const.contains_modify -@[simp] +@[simp, grind =] theorem mem_modify [EquivBEq α] [LawfulHashable α] {k k': α} {f : β → β} : k' ∈ Const.modify m k f ↔ k' ∈ m := m.inductionOn fun _ => DHashMap.Const.mem_modify -@[simp] +@[simp, grind =] theorem size_modify [EquivBEq α] [LawfulHashable α] {k : α} {f : β → β} : (Const.modify m k f).size = m.size := m.inductionOn fun _ => DHashMap.Const.size_modify +@[grind =] theorem get?_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} : Const.get? (Const.modify m k f) k' = if k == k' then Const.get? m k |>.map f @@ -2664,6 +2693,7 @@ theorem get?_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β → Const.get? (Const.modify m k f) k = (Const.get? m k).map f := m.inductionOn fun _ => DHashMap.Const.get?_modify_self +@[grind =] theorem get_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} {h : k' ∈ Const.modify m k f} : Const.get (Const.modify m k f) k' h = @@ -2682,6 +2712,7 @@ theorem get_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β → Const.get (Const.modify m k f) k h = f (Const.get m k h') := m.inductionOn (fun _ _ => DHashMap.Const.get_modify_self) h +@[grind =] theorem get!_modify [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] {f : β → β} : Const.get! (Const.modify m k f) k' = if k == k' then @@ -2695,6 +2726,7 @@ theorem get!_modify_self [EquivBEq α] [LawfulHashable α] {k : α} [Inhabited Const.get! (Const.modify m k f) k = ((Const.get? m k).map f).get! := m.inductionOn fun _ => DHashMap.Const.get!_modify_self +@[grind =] theorem getD_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} {f : β → β} : Const.getD (Const.modify m k f) k' fallback = if k == k' then @@ -2708,6 +2740,7 @@ theorem getD_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {fallback : Const.getD (Const.modify m k f) k fallback = ((Const.get? m k).map f).getD fallback := m.inductionOn fun _ => DHashMap.Const.getD_modify_self +@[grind =] theorem getKey?_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} : (Const.modify m k f).getKey? k' = if k == k' then @@ -2720,6 +2753,7 @@ theorem getKey?_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β (Const.modify m k f).getKey? k = if k ∈ m then some k else none := m.inductionOn fun _ => DHashMap.Const.getKey?_modify_self +@[grind =] theorem getKey!_modify [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : β → β} : (Const.modify m k f).getKey! k' = if k == k' then @@ -2732,6 +2766,7 @@ theorem getKey!_modify_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k (Const.modify m k f).getKey! k = if k ∈ m then k else default := m.inductionOn fun _ => DHashMap.Const.getKey!_modify_self +@[grind =] theorem getKey_modify [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : β → β} {h : k' ∈ Const.modify m k f} : (Const.modify m k f).getKey k' h = @@ -2747,6 +2782,7 @@ theorem getKey_modify_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : {h : k ∈ Const.modify m k f} : (Const.modify m k f).getKey k h = k := m.inductionOn (fun _ _ => DHashMap.Const.getKey_modify_self) h +@[grind =] theorem getKeyD_modify [EquivBEq α] [LawfulHashable α] {k k' fallback : α} {f : β → β} : (Const.modify m k f).getKeyD k' fallback = if k == k' then @@ -2809,11 +2845,13 @@ theorem filterMap_eq_empty_iff [LawfulBEq α] m.filterMap f = ∅ ↔ ∀ k h, f k (m.get k h) = none := isEmpty_iff.symm.trans <| m.inductionOn fun _ => DHashMap.isEmpty_filterMap_iff +@[grind =] theorem contains_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} : (m.filterMap f).contains k = (m.get? k).any (f k · |>.isSome) := m.inductionOn fun _ => DHashMap.contains_filterMap +@[grind =] theorem mem_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} : k ∈ m.filterMap f ↔ ∃ h, (f k (m.get k h)).isSome := @@ -2834,12 +2872,14 @@ theorem size_filterMap_le_size [EquivBEq α] [LawfulHashable α] (m.filterMap f).size ≤ m.size := m.inductionOn fun _ => DHashMap.size_filterMap_le_size +grind_pattern size_filterMap_le_size => (m.filterMap f).size + theorem size_filterMap_eq_size_iff [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} : (m.filterMap f).size = m.size ↔ ∀ (a : α) (h : a ∈ m), (f a (m.get a h)).isSome := m.inductionOn fun _ => DHashMap.size_filterMap_eq_size_iff -@[simp] +@[simp, grind =] theorem get?_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} : (m.filterMap f).get? k = (m.get? k).bind (f k) := @@ -2851,7 +2891,7 @@ theorem isSome_apply_of_mem_filterMap [LawfulBEq α] (f k (m.get k (mem_of_mem_filterMap h'))).isSome := m.inductionOn fun _ => DHashMap.isSome_apply_of_mem_filterMap -@[simp] +@[simp, grind =] theorem get_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} {h'} : (m.filterMap f).get k h' = @@ -2859,16 +2899,19 @@ theorem get_filterMap [LawfulBEq α] (isSome_apply_of_mem_filterMap h') := m.inductionOn (fun _ _ => DHashMap.get_filterMap) h' +@[grind =] theorem get!_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} [Inhabited (γ k)] : (m.filterMap f).get! k = ((m.get? k).bind (f k)).get! := m.inductionOn fun _ => DHashMap.get!_filterMap +@[grind =] theorem getD_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} {fallback : γ k} : (m.filterMap f).getD k fallback = ((m.get? k).bind (f k)).getD fallback := m.inductionOn fun _ => DHashMap.getD_filterMap +@[grind =] theorem getKey?_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k : α} : (m.filterMap f).getKey? k = @@ -2876,12 +2919,13 @@ theorem getKey?_filterMap [LawfulBEq α] (f x (m.get x (mem_of_getKey?_eq_some h'))).isSome) := m.inductionOn fun _ => DHashMap.getKey?_filterMap -@[simp] +@[simp, grind =] theorem getKey_filterMap [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → Option (γ a)} {k : α} {h'} : (m.filterMap f).getKey k h' = m.getKey k (mem_of_mem_filterMap h') := m.inductionOn (fun _ _ => DHashMap.getKey_filterMap) h' +@[grind =] theorem getKey!_filterMap [LawfulBEq α] [Inhabited α] {f : (a : α) → β a → Option (γ a)} {k : α} : (m.filterMap f).getKey! k = @@ -2889,6 +2933,7 @@ theorem getKey!_filterMap [LawfulBEq α] [Inhabited α] (f x (m.get x (mem_of_getKey?_eq_some h'))).isSome)).get! := m.inductionOn fun _ => DHashMap.getKey!_filterMap +@[grind =] theorem getKeyD_filterMap [LawfulBEq α] {f : (a : α) → β a → Option (γ a)} {k fallback : α} : (m.filterMap f).getKeyD k fallback = @@ -2904,16 +2949,25 @@ theorem filterMap_eq_empty_iff [EquivBEq α] [LawfulHashable α] {f : α → β m.filterMap f = ∅ ↔ ∀ k h, f (m.getKey k h) (get m k h) = none := isEmpty_iff.symm.trans <| m.inductionOn fun _ => DHashMap.Const.isEmpty_filterMap_iff +@[grind =] theorem mem_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} : k ∈ m.filterMap f ↔ ∃ h, (f (m.getKey k h) (Const.get m k h)).isSome := m.inductionOn fun _ => DHashMap.Const.mem_filterMap +theorem size_filterMap_le_size [EquivBEq α] [LawfulHashable α] + {f : (a : α) → β → Option γ} : + (m.filterMap f).size ≤ m.size := + m.inductionOn fun _ => DHashMap.size_filterMap_le_size + +grind_pattern size_filterMap_le_size => (m.filterMap f).size + theorem size_filterMap_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} : (m.filterMap f).size = m.size ↔ ∀ k h, (f (m.getKey k h) (Const.get m k h)).isSome := m.inductionOn fun _ => DHashMap.Const.size_filterMap_eq_size_iff +@[grind =] theorem get?_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} : Const.get? (m.filterMap f) k = (Const.get? m k).pbind (fun x h' => @@ -2932,7 +2986,7 @@ theorem isSome_apply_of_mem_filterMap [EquivBEq α] [LawfulHashable α] (Const.get m k (mem_of_mem_filterMap h))).isSome := m.inductionOn fun _ => DHashMap.Const.isSome_apply_of_mem_filterMap -@[simp] +@[simp, grind =] theorem get_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} {h} : Const.get (m.filterMap f) k h = @@ -2941,6 +2995,7 @@ theorem get_filterMap [EquivBEq α] [LawfulHashable α] (isSome_apply_of_mem_filterMap h) := m.inductionOn (fun _ _ => DHashMap.Const.get_filterMap) h +@[grind =] theorem get!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited γ] {f : α → β → Option γ} {k : α} : Const.get! (m.filterMap f) k = @@ -2953,6 +3008,7 @@ theorem get!_filterMap_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inh Const.get! (m.filterMap f) k = ((Const.get? m k).bind (f k')).get! := m.inductionOn (fun _ h => DHashMap.Const.get!_filterMap_of_getKey?_eq_some h) h +@[grind =] theorem getD_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} {fallback : γ} : Const.getD (m.filterMap f) k fallback = @@ -2965,6 +3021,7 @@ theorem getD_filterMap_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] Const.getD (m.filterMap f) k fallback = ((Const.get? m k).bind (f k')).getD fallback := m.inductionOn (fun _ h => DHashMap.Const.getD_filterMap_of_getKey?_eq_some h) h +@[grind =] theorem getKey?_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} : (m.filterMap f).getKey? k = @@ -2972,6 +3029,7 @@ theorem getKey?_filterMap [EquivBEq α] [LawfulHashable α] (f x (Const.get m x (mem_of_getKey?_eq_some h'))).isSome) := m.inductionOn fun _ => DHashMap.Const.getKey?_filterMap +@[grind =] theorem getKey!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → Option γ} {k : α} : (m.filterMap f).getKey! k = @@ -2979,6 +3037,7 @@ theorem getKey!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited α] (f x (Const.get m x (mem_of_getKey?_eq_some h'))).isSome)).get! := m.inductionOn fun _ => DHashMap.Const.getKey!_filterMap +@[grind =] theorem getKeyD_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k fallback : α} : (m.filterMap f).getKeyD k fallback = @@ -3006,11 +3065,11 @@ theorem filter_key_eq_empty_iff [EquivBEq α] [LawfulHashable α] {f : α → Bo m.filter (fun a _ => f a) = ∅ ↔ ∀ k h, f (m.getKey k h) = false := isEmpty_iff.symm.trans <| m.inductionOn fun _ => DHashMap.isEmpty_filter_key_iff -theorem contains_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} : +@[grind =] theorem contains_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} : (m.filter f).contains k = (m.get? k).any (f k) := m.inductionOn fun _ => DHashMap.contains_filter -theorem mem_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} : +@[grind =] theorem mem_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} : k ∈ m.filter f ↔ ∃ h, f k (m.get k h) := m.inductionOn fun _ => DHashMap.mem_filter @@ -3030,6 +3089,8 @@ theorem size_filter_le_size [EquivBEq α] [LawfulHashable α] {f : (a : α) → (m.filter f).size ≤ m.size := m.inductionOn fun _ => DHashMap.size_filter_le_size +grind_pattern size_filter_le_size => (m.filter f).size + theorem size_filter_eq_size_iff [LawfulBEq α] {f : (a : α) → β a → Bool} : (m.filter f).size = m.size ↔ ∀ k h, f k (m.get k h) := m.inductionOn fun _ => DHashMap.size_filter_eq_size_iff @@ -3046,28 +3107,31 @@ theorem size_filter_key_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α (m.filter fun k _ => f k).size = m.size ↔ ∀ k h, f (m.getKey k h) := m.inductionOn fun _ => DHashMap.size_filter_key_eq_size_iff -@[simp] +@[simp, grind =] theorem get?_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} : (m.filter f).get? k = (m.get? k).filter (f k) := m.inductionOn fun _ => DHashMap.get?_filter -@[simp] +@[simp, grind =] theorem get_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} {h'} : (m.filter f).get k h' = m.get k (mem_of_mem_filter h') := m.inductionOn (fun _ _ => DHashMap.get_filter) h' +@[grind =] theorem get!_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} [Inhabited (β k)] : (m.filter f).get! k = ((m.get? k).filter (f k)).get! := m.inductionOn fun _ => DHashMap.get!_filter +@[grind =] theorem getD_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} {fallback : β k} : (m.filter f).getD k fallback = ((m.get? k).filter (f k)).getD fallback := m.inductionOn fun _ => DHashMap.getD_filter +@[grind =] theorem getKey?_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k : α} : (m.filter f).getKey? k = @@ -3080,12 +3144,13 @@ theorem getKey?_filter_key [EquivBEq α] [LawfulHashable α] (m.filter fun k _ => f k).getKey? k = (m.getKey? k).filter f := m.inductionOn fun _ => DHashMap.getKey?_filter_key -@[simp] +@[simp, grind =] theorem getKey_filter [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → Bool} {k : α} {h'} : (m.filter f).getKey k h' = m.getKey k (mem_of_mem_filter h') := m.inductionOn (fun _ _ => DHashMap.getKey_filter) h' +@[grind =] theorem getKey!_filter [LawfulBEq α] [Inhabited α] {f : (a : α) → β a → Bool} {k : α} : (m.filter f).getKey! k = @@ -3098,6 +3163,7 @@ theorem getKey!_filter_key [EquivBEq α] [LawfulHashable α] [Inhabited α] (m.filter fun k _ => f k).getKey! k = ((m.getKey? k).filter f).get! := m.inductionOn fun _ => DHashMap.getKey!_filter_key +@[grind =] theorem getKeyD_filter [LawfulBEq α] {f : (a : α) → β a → Bool} {k fallback : α} : (m.filter f).getKeyD k fallback = @@ -3118,7 +3184,7 @@ theorem filter_eq_empty_iff [EquivBEq α] [LawfulHashable α] {f : α → β → m.filter f = ∅ ↔ ∀ k h, f (m.getKey k h) (Const.get m k h) = false := isEmpty_iff.symm.trans <| m.inductionOn fun _ => DHashMap.Const.isEmpty_filter_iff -theorem mem_filter [EquivBEq α] [LawfulHashable α] +@[grind =] theorem mem_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} : k ∈ m.filter f ↔ ∃ (h' : k ∈ m), f (m.getKey k h') (Const.get m k h') := @@ -3129,6 +3195,8 @@ theorem size_filter_le_size [EquivBEq α] [LawfulHashable α] (m.filter f).size ≤ m.size := m.inductionOn fun _ => DHashMap.Const.size_filter_le_size +grind_pattern size_filter_le_size => (m.filter f).size + theorem size_filter_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} : (m.filter f).size = m.size ↔ ∀ (a : α) (h : a ∈ m), @@ -3139,7 +3207,7 @@ theorem filter_eq_self_iff [EquivBEq α] [LawfulHashable α] {f : α → β → m.filter f = m ↔ ∀ k h, f (m.getKey k h) (Const.get m k h) := m.inductionOn fun _ => Iff.trans ⟨Quotient.exact, Quotient.sound⟩ DHashMap.Const.filter_equiv_self_iff -theorem get?_filter [EquivBEq α] [LawfulHashable α] +@[grind =] theorem get?_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} : Const.get? (m.filter f) k = (Const.get? m k).pfilter (fun x h' => f (m.getKey k (mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))) x) := @@ -3151,13 +3219,13 @@ theorem get?_filter_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] Const.get? (m.filter f) k = (Const.get? m k).filter (fun x => f k' x) := m.inductionOn fun _ => DHashMap.Const.get?_filter_of_getKey?_eq_some -@[simp] +@[simp, grind =] theorem get_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} {h'} : Const.get (m.filter f) k h' = Const.get m k (mem_of_mem_filter h') := m.inductionOn (fun _ _ => DHashMap.Const.get_filter) h' -theorem get!_filter [EquivBEq α] [LawfulHashable α] [Inhabited β] +@[grind =] theorem get!_filter [EquivBEq α] [LawfulHashable α] [Inhabited β] {f : α → β → Bool} {k : α} : Const.get! (m.filter f) k = ((Const.get? m k).pfilter (fun x h' => @@ -3170,7 +3238,7 @@ theorem get!_filter_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhabi Const.get! (m.filter f) k = ((Const.get? m k).filter (fun x => f k' x)).get! := m.inductionOn fun _ => DHashMap.Const.get!_filter_of_getKey?_eq_some -theorem getD_filter [EquivBEq α] [LawfulHashable α] +@[grind =] theorem getD_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} {fallback : β} : Const.getD (m.filter f) k fallback = ((Const.get? m k).pfilter (fun x h' => f (m.getKey k (mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))) x)).getD fallback := @@ -3183,21 +3251,21 @@ theorem getD_filter_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] ((Const.get? m k).filter (fun x => f k' x)).getD fallback := m.inductionOn fun _ => DHashMap.Const.getD_filter_of_getKey?_eq_some -theorem getKey?_filter [EquivBEq α] [LawfulHashable α] +@[grind =] theorem getKey?_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} : (m.filter f).getKey? k = (m.getKey? k).pfilter (fun x h' => (f x (Const.get m x (mem_of_getKey?_eq_some h')))) := m.inductionOn fun _ => DHashMap.Const.getKey?_filter -theorem getKey!_filter [EquivBEq α] [LawfulHashable α] [Inhabited α] +@[grind =] theorem getKey!_filter [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → Bool} {k : α} : (m.filter f).getKey! k = ((m.getKey? k).pfilter (fun x h' => (f x (Const.get m x (mem_of_getKey?_eq_some h'))))).get! := m.inductionOn fun _ => DHashMap.Const.getKey!_filter -theorem getKeyD_filter [EquivBEq α] [LawfulHashable α] +@[grind =] theorem getKeyD_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k fallback : α} : (m.filter f).getKeyD k fallback = ((m.getKey? k).pfilter (fun x h' => @@ -3231,7 +3299,7 @@ theorem map_eq_empty_iff [EquivBEq α] [LawfulHashable α] {f : (a : α) → β simp only [← isEmpty_iff, Bool.coe_iff_coe] exact m.inductionOn fun _ => DHashMap.isEmpty_map -theorem contains_map [EquivBEq α] [LawfulHashable α] +@[grind =] theorem contains_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k : α} : (m.map f).contains k = m.contains k := m.inductionOn fun _ => DHashMap.contains_map @@ -3241,7 +3309,7 @@ theorem contains_of_contains_map [EquivBEq α] [LawfulHashable α] (m.map f).contains k = true → m.contains k = true := m.inductionOn fun _ => DHashMap.contains_of_contains_map -@[simp] +@[simp, grind =] theorem mem_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k : α} : k ∈ m.map f ↔ k ∈ m := @@ -3252,53 +3320,55 @@ theorem mem_of_mem_map [EquivBEq α] [LawfulHashable α] k ∈ m.map f → k ∈ m := m.inductionOn fun _ => DHashMap.mem_of_mem_map -@[simp] +@[simp, grind =] theorem size_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} : (m.map f).size = m.size := m.inductionOn fun _ => DHashMap.size_map -@[simp] +@[simp, grind =] theorem get?_map [LawfulBEq α] {f : (a : α) → β a → γ a} {k : α} : (m.map f).get? k = (m.get? k).map (f k) := m.inductionOn fun _ => DHashMap.get?_map -@[simp] +@[simp, grind =] theorem get_map [LawfulBEq α] {f : (a : α) → β a → γ a} {k : α} {h'} : (m.map f).get k h' = f k (m.get k (mem_of_mem_map h')) := m.inductionOn (fun _ _ => DHashMap.get_map) h' +@[grind =] theorem get!_map [LawfulBEq α] {f : (a : α) → β a → γ a} {k : α} [Inhabited (γ k)] : (m.map f).get! k = ((m.get? k).map (f k)).get! := m.inductionOn fun _ => DHashMap.get!_map +@[grind =] theorem getD_map [LawfulBEq α] {f : (a : α) → β a → γ a} {k : α} {fallback : γ k} : (m.map f).getD k fallback = ((m.get? k).map (f k)).getD fallback := m.inductionOn fun _ => DHashMap.getD_map -@[simp] +@[simp, grind =] theorem getKey?_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k : α} : (m.map f).getKey? k = m.getKey? k := m.inductionOn fun _ => DHashMap.getKey?_map -@[simp] +@[simp, grind =] theorem getKey_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k : α} {h'} : (m.map f).getKey k h' = m.getKey k (mem_of_mem_map h') := m.inductionOn (fun _ _ => DHashMap.getKey_map) h' -@[simp] +@[simp, grind =] theorem getKey!_map [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : (a : α) → β a → γ a} {k : α} : (m.map f).getKey! k = m.getKey! k := m.inductionOn fun _ => DHashMap.getKey!_map -@[simp] +@[simp, grind =] theorem getKeyD_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β a → γ a} {k fallback : α} : (m.map f).getKeyD k fallback = m.getKeyD k fallback := @@ -3308,7 +3378,7 @@ namespace Const variable {β : Type v} {γ : Type w} {m : ExtDHashMap α fun _ => β} -@[simp] +@[simp, grind =] theorem get?_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} : Const.get? (m.map f) k = (Const.get? m k).map (f k) := @@ -3327,7 +3397,7 @@ theorem get?_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] Const.get? (m.map f) k = (Const.get? m k).map (f k') := m.inductionOn (fun _ h => DHashMap.Const.get?_map_of_getKey?_eq_some h) h -@[simp] +@[simp, grind =] theorem get_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} {h'} : Const.get (m.map f) k h' = f k (Const.get m k (mem_of_mem_map h')) := @@ -3341,7 +3411,7 @@ theorem get_map' [EquivBEq α] [LawfulHashable α] f (m.getKey k (mem_of_mem_map h')) (Const.get m k (mem_of_mem_map h')) := m.inductionOn (fun _ _ => DHashMap.Const.get_map') h' -theorem get!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ] +@[grind =] theorem get!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ] {f : α → β → γ} {k : α} : Const.get! (m.map f) k = ((Const.get? m k).map (f k)).get! := m.inductionOn fun _ => DHashMap.Const.get!_map @@ -3359,7 +3429,7 @@ theorem get!_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhabited Const.get! (m.map f) k = ((Const.get? m k).map (f k')).get! := m.inductionOn (fun _ h => DHashMap.Const.get!_map_of_getKey?_eq_some h) h -theorem getD_map [LawfulBEq α] [LawfulHashable α] +@[grind =] theorem getD_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} {fallback : γ} : Const.getD (m.map f) k fallback = ((Const.get? m k).map (f k)).getD fallback := m.inductionOn fun _ => DHashMap.Const.getD_map diff --git a/src/Std/Data/ExtHashMap/Lemmas.lean b/src/Std/Data/ExtHashMap/Lemmas.lean index e4141eeeb1..3e651b5fb7 100644 --- a/src/Std/Data/ExtHashMap/Lemmas.lean +++ b/src/Std/Data/ExtHashMap/Lemmas.lean @@ -13,6 +13,8 @@ import Std.Data.ExtDHashMap.Lemmas This module contains lemmas about `Std.ExtHashMap`. -/ +set_option trace.grind.ematch.pattern true + set_option linter.missingDocs true set_option autoImplicit false @@ -32,7 +34,7 @@ private theorem ext {m m' : ExtHashMap α β} : m.inner = m'.inner → m = m' := private theorem ext_iff {m m' : ExtHashMap α β} : m = m' ↔ m.inner = m'.inner := ⟨fun h => h ▸ rfl, ext⟩ -@[simp] +@[simp, grind =] theorem isEmpty_iff [EquivBEq α] [LawfulHashable α] : m.isEmpty ↔ m = ∅ := ExtDHashMap.isEmpty_iff.trans ext_iff.symm @@ -43,7 +45,7 @@ theorem isEmpty_eq_false_iff [EquivBEq α] [LawfulHashable α] : m.isEmpty = fal @[simp] theorem empty_eq : ∅ = m ↔ m = ∅ := eq_comm -@[simp] +@[simp, grind =] theorem emptyWithCapacity_eq [EquivBEq α] [LawfulHashable α] {c} : (emptyWithCapacity c : ExtHashMap α β) = ∅ := ext ExtDHashMap.emptyWithCapacity_eq @@ -67,7 +69,7 @@ theorem mem_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == b) : a ∈ m ↔ b ∈ m := ExtDHashMap.mem_congr hab -@[simp] theorem contains_empty [EquivBEq α] [LawfulHashable α] {a : α} : (∅ : ExtHashMap α β).contains a = false := +@[simp, grind =] theorem contains_empty [EquivBEq α] [LawfulHashable α] {a : α} : (∅ : ExtHashMap α β).contains a = false := ExtDHashMap.contains_empty @[simp] theorem not_mem_empty [EquivBEq α] [LawfulHashable α] {a : α} : ¬a ∈ (∅ : ExtHashMap α β) := @@ -87,12 +89,12 @@ theorem eq_empty_iff_forall_not_mem [EquivBEq α] [LawfulHashable α] : m = ∅ Singleton.singleton p = (∅ : ExtHashMap α β).insert p.1 p.2 := rfl -@[simp] +@[simp, grind =] theorem contains_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : (m.insert k v).contains a = (k == a || m.contains a) := ExtDHashMap.contains_insert -@[simp] +@[simp, grind =] theorem mem_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : a ∈ m.insert k v ↔ k == a ∨ a ∈ m := ExtDHashMap.mem_insert @@ -111,13 +113,14 @@ theorem contains_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β} theorem mem_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : k ∈ m.insert k v := by simp -@[simp] +@[simp, grind =] theorem size_empty [EquivBEq α] [LawfulHashable α] : (∅ : ExtHashMap α β).size = 0 := ExtDHashMap.size_empty theorem eq_empty_iff_size_eq_zero [EquivBEq α] [LawfulHashable α] : m = ∅ ↔ m.size = 0 := ext_iff.trans ExtDHashMap.eq_empty_iff_size_eq_zero +@[grind =] theorem size_insert [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (m.insert k v).size = if k ∈ m then m.size else m.size + 1 := ExtDHashMap.size_insert @@ -130,7 +133,7 @@ theorem size_insert_le [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (m.insert k v).size ≤ m.size + 1 := ExtDHashMap.size_insert_le -@[simp] +@[simp, grind =] theorem erase_empty [EquivBEq α] [LawfulHashable α] {a : α} : (∅ : ExtHashMap α β).erase a = ∅ := ext ExtDHashMap.erase_empty @@ -139,12 +142,12 @@ theorem erase_eq_empty_iff [EquivBEq α] [LawfulHashable α] {k : α} : m.erase k = ∅ ↔ m = ∅ ∨ m.size = 1 ∧ k ∈ m := by simpa only [ext_iff] using ExtDHashMap.erase_eq_empty_iff -@[simp] +@[simp, grind =] theorem contains_erase [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k).contains a = (!(k == a) && m.contains a) := ExtDHashMap.contains_erase -@[simp] +@[simp, grind =] theorem mem_erase [EquivBEq α] [LawfulHashable α] {k a : α} : a ∈ m.erase k ↔ (k == a) = false ∧ a ∈ m := ExtDHashMap.mem_erase @@ -156,7 +159,7 @@ theorem contains_of_contains_erase [EquivBEq α] [LawfulHashable α] {k a : α} theorem mem_of_mem_erase [EquivBEq α] [LawfulHashable α] {k a : α} : a ∈ m.erase k → a ∈ m := ExtDHashMap.mem_of_mem_erase -theorem size_erase [EquivBEq α] [LawfulHashable α] {k : α} : +@[grind =] theorem size_erase [EquivBEq α] [LawfulHashable α] {k : α} : (m.erase k).size = if k ∈ m then m.size - 1 else m.size := ExtDHashMap.size_erase @@ -167,34 +170,35 @@ theorem size_le_size_erase [EquivBEq α] [LawfulHashable α] {k : α} : m.size ≤ (m.erase k).size + 1 := ExtDHashMap.size_le_size_erase -@[simp] +@[simp, grind =] theorem containsThenInsert_fst [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (m.containsThenInsert k v).1 = m.contains k := ExtDHashMap.containsThenInsert_fst -@[simp] +@[simp, grind =] theorem containsThenInsert_snd [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (m.containsThenInsert k v).2 = m.insert k v := ext (ExtDHashMap.containsThenInsert_snd) -@[simp] +@[simp, grind =] theorem containsThenInsertIfNew_fst [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (m.containsThenInsertIfNew k v).1 = m.contains k := ExtDHashMap.containsThenInsertIfNew_fst -@[simp] +@[simp, grind =] theorem containsThenInsertIfNew_snd [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (m.containsThenInsertIfNew k v).2 = m.insertIfNew k v := ext ExtDHashMap.containsThenInsertIfNew_snd -@[simp] theorem get_eq_getElem [EquivBEq α] [LawfulHashable α] {a : α} {h} : get m a h = m[a]'h := rfl -@[simp] theorem get?_eq_getElem? [EquivBEq α] [LawfulHashable α] {a : α} : get? m a = m[a]? := rfl -@[simp] theorem get!_eq_getElem! [EquivBEq α] [LawfulHashable α] [Inhabited β] {a : α} : get! m a = m[a]! := rfl +@[simp, grind =] theorem get_eq_getElem [EquivBEq α] [LawfulHashable α] {a : α} {h} : get m a h = m[a]'h := rfl +@[simp, grind =] theorem get?_eq_getElem? [EquivBEq α] [LawfulHashable α] {a : α} : get? m a = m[a]? := rfl +@[simp, grind =] theorem get!_eq_getElem! [EquivBEq α] [LawfulHashable α] [Inhabited β] {a : α} : get! m a = m[a]! := rfl -@[simp] +@[simp, grind =] theorem getElem?_empty [EquivBEq α] [LawfulHashable α] {a : α} : (∅ : ExtHashMap α β)[a]? = none := ExtDHashMap.Const.get?_empty +@[grind =] theorem getElem?_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : (m.insert k v)[a]? = if k == a then some v else m[a]? := ExtDHashMap.Const.get?_insert @@ -229,7 +233,7 @@ theorem getElem?_eq_none_of_contains_eq_false [EquivBEq α] [LawfulHashable α] theorem getElem?_eq_none [EquivBEq α] [LawfulHashable α] {a : α} : ¬a ∈ m → m[a]? = none := ExtDHashMap.Const.get?_eq_none -theorem getElem?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : +@[grind =] theorem getElem?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k)[a]? = if k == a then none else m[a]? := ExtDHashMap.Const.get?_erase @@ -240,7 +244,7 @@ theorem getElem?_erase_self [EquivBEq α] [LawfulHashable α] {k : α} : (m.eras theorem getElem?_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == b) : m[a]? = m[b]? := ExtDHashMap.Const.get?_congr hab -theorem getElem_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : +@[grind =] theorem getElem_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : (m.insert k v)[a]'h₁ = if h₂ : k == a then v else m[a]'(mem_of_mem_insert h₁ (Bool.eq_false_iff.2 h₂)) := ExtDHashMap.Const.get_insert (h₁ := h₁) @@ -250,7 +254,7 @@ theorem getElem_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β} (m.insert k v)[k]'mem_insert_self = v := ExtDHashMap.Const.get_insert_self -@[simp] +@[simp, grind =] theorem getElem_erase [EquivBEq α] [LawfulHashable α] {k a : α} {h'} : (m.erase k)[a]'h' = m[a]'(mem_of_mem_erase h') := ExtDHashMap.Const.get_erase (h' := h') @@ -263,7 +267,7 @@ theorem getElem_eq_get_getElem? [EquivBEq α] [LawfulHashable α] {a : α} {h} : m[a]'h = m[a]?.get (mem_iff_isSome_getElem?.mp h) := ExtDHashMap.Const.get_eq_get_get? (h := h) -theorem get_getElem? [EquivBEq α] [LawfulHashable α] {a : α} {h} : +@[grind =] theorem get_getElem? [EquivBEq α] [LawfulHashable α] {a : α} {h} : m[a]?.get h = m[a]'(mem_iff_isSome_getElem?.mpr h) := ExtDHashMap.Const.get_get? @@ -271,12 +275,12 @@ theorem getElem_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == b m[a]'h' = m[b]'((mem_congr hab).1 h') := ExtDHashMap.Const.get_congr hab (h' := h') -@[simp] +@[simp, grind =] theorem getElem!_empty [EquivBEq α] [LawfulHashable α] [Inhabited β] {a : α} : (∅ : ExtHashMap α β)[a]! = default := ExtDHashMap.Const.get!_empty -theorem getElem!_insert [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : +@[grind =] theorem getElem!_insert [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : (m.insert k v)[a]! = if k == a then v else m[a]! := ExtDHashMap.Const.get!_insert @@ -293,7 +297,7 @@ theorem getElem!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited β] {a ¬a ∈ m → m[a]! = default := ExtDHashMap.Const.get!_eq_default -theorem getElem!_erase [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} : +@[grind =] theorem getElem!_erase [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} : (m.erase k)[a]! = if k == a then default else m[a]! := ExtDHashMap.Const.get!_erase @@ -322,12 +326,12 @@ theorem getElem!_congr [EquivBEq α] [LawfulHashable α] [Inhabited β] {a b : m[a]! = m[b]! := ExtDHashMap.Const.get!_congr hab -@[simp] +@[simp, grind =] theorem getD_empty [EquivBEq α] [LawfulHashable α] {a : α} {fallback : β} : (∅ : ExtHashMap α β).getD a fallback = fallback := ExtDHashMap.Const.getD_empty -theorem getD_insert [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : +@[grind =] theorem getD_insert [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : (m.insert k v).getD a fallback = if k == a then v else m.getD a fallback := ExtDHashMap.Const.getD_insert @@ -344,7 +348,7 @@ theorem getD_eq_fallback [EquivBEq α] [LawfulHashable α] {a : α} {fallback : ¬a ∈ m → m.getD a fallback = fallback := ExtDHashMap.Const.getD_eq_fallback -theorem getD_erase [EquivBEq α] [LawfulHashable α] {k a : α} {fallback : β} : +@[grind =] theorem getD_erase [EquivBEq α] [LawfulHashable α] {k a : α} {fallback : β} : (m.erase k).getD a fallback = if k == a then fallback else m.getD a fallback := ExtDHashMap.Const.getD_erase @@ -377,12 +381,12 @@ theorem getD_congr [EquivBEq α] [LawfulHashable α] {a b : α} {fallback : β} m.getD a fallback = m.getD b fallback := ExtDHashMap.Const.getD_congr hab -@[simp] +@[simp, grind =] theorem getKey?_empty [EquivBEq α] [LawfulHashable α] {a : α} : (∅ : ExtHashMap α β).getKey? a = none := ExtDHashMap.getKey?_empty -theorem getKey?_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : +@[grind =] theorem getKey?_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : (m.insert k v).getKey? a = if k == a then some k else m.getKey? a := ExtDHashMap.getKey?_insert @@ -420,7 +424,7 @@ theorem getKey?_eq_none_of_contains_eq_false [EquivBEq α] [LawfulHashable α] { theorem getKey?_eq_none [EquivBEq α] [LawfulHashable α] {a : α} : ¬a ∈ m → m.getKey? a = none := ExtDHashMap.getKey?_eq_none -theorem getKey?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : +@[grind =] theorem getKey?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k).getKey? a = if k == a then none else m.getKey? a := ExtDHashMap.getKey?_erase @@ -442,7 +446,7 @@ theorem getKey?_eq_some_of_contains [LawfulBEq α] {k : α} (h : m.contains k) : theorem getKey?_eq_some [LawfulBEq α] {k : α} (h : k ∈ m) : m.getKey? k = some k := by simpa only [mem_iff_contains] using getKey?_eq_some_of_contains h -theorem getKey_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : +@[grind =] theorem getKey_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : (m.insert k v).getKey a h₁ = if h₂ : k == a then k else m.getKey a ((mem_of_mem_insert h₁ (by simpa using h₂))) := ExtDHashMap.getKey_insert (h₁ := h₁) @@ -452,7 +456,7 @@ theorem getKey_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (m.insert k v).getKey k mem_insert_self = k := ExtDHashMap.getKey_insert_self -@[simp] +@[simp, grind =] theorem getKey_erase [EquivBEq α] [LawfulHashable α] {k a : α} {h'} : (m.erase k).getKey a h' = m.getKey a (mem_of_mem_erase h') := ExtDHashMap.getKey_erase (h' := h') @@ -465,7 +469,7 @@ theorem getKey_eq_get_getKey? [EquivBEq α] [LawfulHashable α] {a : α} {h} : m.getKey a h = (m.getKey? a).get (mem_iff_isSome_getKey?.mp h) := ExtDHashMap.getKey_eq_get_getKey? -@[simp] +@[simp, grind =] theorem get_getKey? [EquivBEq α] [LawfulHashable α] {a : α} {h} : (m.getKey? a).get h = m.getKey a (mem_iff_isSome_getKey?.mpr h) := ExtDHashMap.get_getKey? @@ -477,16 +481,16 @@ theorem getKey_congr [EquivBEq α] [LawfulHashable α] {k₁ k₂ : α} (h : k (h₁ : k₁ ∈ m) : m.getKey k₁ h₁ = m.getKey k₂ ((mem_congr h).mp h₁) := ExtDHashMap.getKey_congr h h₁ -@[simp] +@[simp, grind =] theorem getKey_eq [LawfulBEq α] {k : α} (h : k ∈ m) : m.getKey k h = k := ExtDHashMap.getKey_eq h -@[simp] +@[simp, grind =] theorem getKey!_empty [EquivBEq α] [LawfulHashable α] [Inhabited α] {a : α} : (∅ : ExtHashMap α β).getKey! a = default := ExtDHashMap.getKey!_empty -theorem getKey!_insert [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β} : +@[grind =] theorem getKey!_insert [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β} : (m.insert k v).getKey! a = if k == a then k else m.getKey! a := ExtDHashMap.getKey!_insert @@ -503,7 +507,7 @@ theorem getKey!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited α] {a : ¬a ∈ m → m.getKey! a = default := ExtDHashMap.getKey!_eq_default -theorem getKey!_erase [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} : +@[grind =] theorem getKey!_erase [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} : (m.erase k).getKey! a = if k == a then default else m.getKey! a := ExtDHashMap.getKey!_erase @@ -539,12 +543,12 @@ theorem getKey!_eq_of_contains [LawfulBEq α] [Inhabited α] {k : α} (h : m.con theorem getKey!_eq_of_mem [LawfulBEq α] [Inhabited α] {k : α} (h : k ∈ m) : m.getKey! k = k := ExtDHashMap.getKey!_eq_of_mem h -@[simp] +@[simp, grind =] theorem getKeyD_empty [EquivBEq α] [LawfulHashable α] {a : α} {fallback : α} : (∅ : ExtHashMap α β).getKeyD a fallback = fallback := ExtDHashMap.getKeyD_empty -theorem getKeyD_insert [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β} : +@[grind =] theorem getKeyD_insert [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β} : (m.insert k v).getKeyD a fallback = if k == a then k else m.getKeyD a fallback := ExtDHashMap.getKeyD_insert @@ -561,7 +565,7 @@ theorem getKeyD_eq_fallback [EquivBEq α] [LawfulHashable α] {a : α} {fallback ¬a ∈ m → m.getKeyD a fallback = fallback := ExtDHashMap.getKeyD_eq_fallback -theorem getKeyD_erase [EquivBEq α] [LawfulHashable α] {k a : α} {fallback : α} : +@[grind =] theorem getKeyD_erase [EquivBEq α] [LawfulHashable α] {k a : α} {fallback : α} : (m.erase k).getKeyD a fallback = if k == a then fallback else m.getKeyD a fallback := ExtDHashMap.getKeyD_erase @@ -607,12 +611,12 @@ theorem not_insertIfNew_eq_empty [EquivBEq α] [LawfulHashable α] {k : α} {v : ¬m.insertIfNew k v = ∅ := (not_congr ext_iff).mpr ExtDHashMap.not_insertIfNew_eq_empty -@[simp] +@[simp, grind =] theorem contains_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : (m.insertIfNew k v).contains a = (k == a || m.contains a) := ExtDHashMap.contains_insertIfNew -@[simp] +@[simp, grind =] theorem mem_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : a ∈ m.insertIfNew k v ↔ k == a ∨ a ∈ m := ExtDHashMap.mem_insertIfNew @@ -645,7 +649,7 @@ theorem mem_of_mem_insertIfNew' [EquivBEq α] [LawfulHashable α] {k a : α} {v a ∈ m.insertIfNew k v → ¬((k == a) ∧ ¬k ∈ m) → a ∈ m := ExtDHashMap.mem_of_mem_insertIfNew' -theorem size_insertIfNew [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : +@[grind =] theorem size_insertIfNew [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (m.insertIfNew k v).size = if k ∈ m then m.size else m.size + 1 := ExtDHashMap.size_insertIfNew @@ -657,47 +661,47 @@ theorem size_insertIfNew_le [EquivBEq α] [LawfulHashable α] {k : α} {v : β} (m.insertIfNew k v).size ≤ m.size + 1 := ExtDHashMap.size_insertIfNew_le -theorem getElem?_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : +@[grind =] theorem getElem?_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : (m.insertIfNew k v)[a]? = if k == a ∧ ¬k ∈ m then some v else m[a]? := ExtDHashMap.Const.get?_insertIfNew -theorem getElem_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : +@[grind =] theorem getElem_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : (m.insertIfNew k v)[a]'h₁ = if h₂ : k == a ∧ ¬k ∈ m then v else m[a]'(mem_of_mem_insertIfNew' h₁ h₂) := ExtDHashMap.Const.get_insertIfNew (h₁ := h₁) -theorem getElem!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : +@[grind =] theorem getElem!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : (m.insertIfNew k v)[a]! = if k == a ∧ ¬k ∈ m then v else m[a]! := ExtDHashMap.Const.get!_insertIfNew -theorem getD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : +@[grind =] theorem getD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : (m.insertIfNew k v).getD a fallback = if k == a ∧ ¬k ∈ m then v else m.getD a fallback := ExtDHashMap.Const.getD_insertIfNew -theorem getKey?_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : +@[grind =] theorem getKey?_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : getKey? (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then some k else getKey? m a := ExtDHashMap.getKey?_insertIfNew -theorem getKey_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : +@[grind =] theorem getKey_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : getKey (m.insertIfNew k v) a h₁ = if h₂ : k == a ∧ ¬k ∈ m then k else getKey m a (mem_of_mem_insertIfNew' h₁ h₂) := ExtDHashMap.getKey_insertIfNew -theorem getKey!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β} : +@[grind =] theorem getKey!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β} : getKey! (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then k else getKey! m a := ExtDHashMap.getKey!_insertIfNew -theorem getKeyD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β} : +@[grind =] theorem getKeyD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β} : getKeyD (m.insertIfNew k v) a fallback = if k == a ∧ ¬k ∈ m then k else getKeyD m a fallback := ExtDHashMap.getKeyD_insertIfNew -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_fst [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (getThenInsertIfNew? m k v).1 = get? m k := ExtDHashMap.Const.getThenInsertIfNew?_fst -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_snd [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (getThenInsertIfNew? m k v).2 = m.insertIfNew k v := ext (ExtDHashMap.Const.getThenInsertIfNew?_snd) @@ -713,20 +717,22 @@ instance [EquivBEq α] [LawfulHashable α] : LawfulGetElem (ExtHashMap α β) α variable {ρ : Type w} [ForIn Id ρ (α × β)] -@[simp] +@[simp, grind =] theorem insertMany_nil [EquivBEq α] [LawfulHashable α] : insertMany m [] = m := ext ExtDHashMap.Const.insertMany_nil -@[simp] +@[simp, grind =] theorem insertMany_list_singleton [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : insertMany m [⟨k, v⟩] = m.insert k v := ext ExtDHashMap.Const.insertMany_list_singleton +@[grind =] theorem insertMany_cons [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} {v : β} : insertMany m (⟨k, v⟩ :: l) = insertMany (m.insert k v) l := ext ExtDHashMap.Const.insertMany_cons +@[grind _=_] theorem insertMany_append [EquivBEq α] [LawfulHashable α] {l₁ l₂ : List (α × β)} : insertMany m (l₁ ++ l₂) = insertMany (insertMany m l₁) l₂ := by induction l₁ generalizing m with @@ -742,13 +748,13 @@ theorem insertMany_ind [EquivBEq α] [LawfulHashable α] show motive ⟨ExtDHashMap.Const.insertMany m.1 l⟩ from ExtDHashMap.Const.insertMany_ind m.inner l init fun m => insert ⟨m⟩ -@[simp] +@[simp, grind =] theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : (insertMany m l).contains k = (m.contains k || (l.map Prod.fst).contains k) := ExtDHashMap.Const.contains_insertMany_list -@[simp] +@[simp, grind =] theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : k ∈ insertMany m l ↔ k ∈ m ∨ (l.map Prod.fst).contains k := @@ -776,7 +782,7 @@ theorem getElem?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (insertMany m l)[k']? = some v := ExtDHashMap.Const.get?_insertMany_list_of_mem k_beq distinct mem -theorem getElem?_insertMany_list [EquivBEq α] [LawfulHashable α] +@[grind =] theorem getElem?_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : (insertMany m l)[k]? = (l.findSomeRev? (fun ⟨a, b⟩ => if a == k then some b else none)).or m[k]? := ExtDHashMap.Const.get?_insertMany_list @@ -893,11 +899,15 @@ theorem size_le_size_insertMany [EquivBEq α] [LawfulHashable α] {l : ρ} : m.size ≤ (insertMany m l).size := ExtDHashMap.Const.size_le_size_insertMany +grind_pattern size_le_size_insertMany => (insertMany m l).size + theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] {l : List (α × β)} : (insertMany m l).size ≤ m.size + l.length := ExtDHashMap.Const.size_insertMany_list_le +grind_pattern size_insertMany_list_le => (insertMany m l).size + @[simp] theorem insertMany_list_eq_empty_iff [EquivBEq α] [LawfulHashable α] {l : List (α × β)} : m.insertMany l = ∅ ↔ m = ∅ ∧ l = [] := by @@ -1079,16 +1089,17 @@ end section -@[simp] +@[simp, grind =] theorem ofList_nil [EquivBEq α] [LawfulHashable α] : ofList ([] : List (α × β)) = ∅ := ext ExtDHashMap.Const.ofList_nil -@[simp] +@[simp, grind =] theorem ofList_singleton [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : ofList [⟨k, v⟩] = (∅ : ExtHashMap α β).insert k v := ext ExtDHashMap.Const.ofList_singleton +@[grind _=_] theorem ofList_cons [EquivBEq α] [LawfulHashable α] {k : α} {v : β} {tl : List (α × β)} : ofList (⟨k, v⟩ :: tl) = insertMany ((∅ : ExtHashMap α β).insert k v) tl := ext ExtDHashMap.Const.ofList_cons @@ -1097,13 +1108,13 @@ theorem ofList_eq_insertMany_empty [EquivBEq α] [LawfulHashable α] {l : List ( ofList l = insertMany (∅ : ExtHashMap α β) l := ext ExtDHashMap.Const.ofList_eq_insertMany_empty -@[simp] +@[simp, grind =] theorem contains_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : (ofList l).contains k = (l.map Prod.fst).contains k := ExtDHashMap.Const.contains_ofList -@[simp] +@[simp, grind =] theorem mem_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : k ∈ ofList l ↔ (l.map Prod.fst).contains k := @@ -1217,6 +1228,8 @@ theorem size_ofList_le [EquivBEq α] [LawfulHashable α] (ofList l).size ≤ l.length := ExtDHashMap.Const.size_ofList_le +grind_pattern size_ofList => (ofList l).size + @[simp] theorem ofList_eq_empty_iff [EquivBEq α] [LawfulHashable α] {l : List (α × β)} : ofList l = ∅ ↔ l = [] := @@ -1350,11 +1363,11 @@ theorem alter_eq_empty_iff [EquivBEq α] [LawfulHashable α] {k : α} {f : Optio alter m k f = ∅ ↔ (m = ∅ ∨ (m.size = 1 ∧ k ∈ m)) ∧ f m[k]? = none := by simpa only [ext_iff] using ExtDHashMap.Const.alter_eq_empty_iff -theorem contains_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} : +@[grind =] theorem contains_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} : (alter m k f).contains k' = if k == k' then (f m[k]?).isSome else m.contains k' := ExtDHashMap.Const.contains_alter -theorem mem_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} : +@[grind =] theorem mem_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} : k' ∈ alter m k f ↔ if k == k' then (f m[k]?).isSome = true else k' ∈ m := ExtDHashMap.Const.mem_alter @@ -1381,7 +1394,7 @@ theorem mem_alter_of_beq_eq_false [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} (h : (k == k') = false) : k' ∈ alter m k f ↔ k' ∈ m := ExtDHashMap.Const.mem_alter_of_beq_eq_false h -theorem size_alter [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β → Option β} : +@[grind =] theorem size_alter [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β → Option β} : (m.alter k f).size = if k ∈ m ∧ (f m[k]?).isNone then m.size - 1 @@ -1419,7 +1432,7 @@ theorem size_le_size_alter [EquivBEq α] [LawfulHashable α] {k : α} {f : Optio m.size - 1 ≤ (alter m k f).size := ExtDHashMap.Const.size_le_size_alter -theorem getElem?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} : +@[grind =] theorem getElem?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} : (alter m k f)[k']? = if k == k' then f m[k]? @@ -1446,7 +1459,7 @@ theorem get?_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Option get? (alter m k f) k = f (get? m k) := ExtDHashMap.Const.get?_alter_self -theorem getElem_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} +@[grind =] theorem getElem_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} {h : k' ∈ alter m k f} : (alter m k f)[k'] = if heq : k == k' then @@ -1483,7 +1496,7 @@ theorem get_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β get (alter m k f) k h = (f (get? m k)).get h' := ExtDHashMap.Const.get_alter_self -theorem getElem!_alter [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] +@[grind =] theorem getElem!_alter [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] {f : Option β → Option β} : (alter m k f)[k']! = if k == k' then f m[k]? |>.get! @@ -1510,7 +1523,7 @@ theorem get!_alter_self [EquivBEq α] [LawfulHashable α] {k : α} [Inhabited β {f : Option β → Option β} : get! (alter m k f) k = (f (get? m k)).get! := ExtDHashMap.Const.get!_alter_self -theorem getD_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} +@[grind =] theorem getD_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} {f : Option β → Option β} : getD (alter m k f) k' fallback = if k == k' then @@ -1525,7 +1538,7 @@ theorem getD_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {fallback : getD (alter m k f) k fallback = (f m[k]?).getD fallback := ExtDHashMap.Const.getD_alter_self -theorem getKey?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} : +@[grind =] theorem getKey?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} : (alter m k f).getKey? k' = if k == k' then if (f m[k]?).isSome then some k else none @@ -1537,7 +1550,7 @@ theorem getKey?_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Optio (alter m k f).getKey? k = if (f m[k]?).isSome then some k else none := ExtDHashMap.Const.getKey?_alter_self -theorem getKey!_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} +@[grind =] theorem getKey!_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : Option β → Option β} : (alter m k f).getKey! k' = if k == k' then if (f m[k]?).isSome then k else default @@ -1550,7 +1563,7 @@ theorem getKey!_alter_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : (alter m k f).getKey! k = if (f m[k]?).isSome then k else default := ExtDHashMap.Const.getKey!_alter_self -theorem getKey_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} +@[grind =] theorem getKey_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : Option β → Option β} {h : k' ∈ alter m k f} : (alter m k f).getKey k' h = if heq : k == k' then @@ -1566,7 +1579,7 @@ theorem getKey_alter_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : (alter m k f).getKey k h = k := ExtDHashMap.Const.getKey_alter_self -theorem getKeyD_alter [EquivBEq α] [LawfulHashable α] {k k' fallback : α} +@[grind =] theorem getKeyD_alter [EquivBEq α] [LawfulHashable α] {k k' fallback : α} {f : Option β → Option β} : (alter m k f).getKeyD k' fallback = if k == k' then @@ -1591,22 +1604,22 @@ theorem modify_eq_empty_iff [EquivBEq α] [LawfulHashable α] {k : α} {f : β modify m k f = ∅ ↔ m = ∅ := by simpa only [ext_iff] using ExtDHashMap.Const.modify_eq_empty_iff -@[simp] +@[simp, grind =] theorem contains_modify [EquivBEq α] [LawfulHashable α] {k k': α} {f : β → β} : (modify m k f).contains k' = m.contains k' := ExtDHashMap.Const.contains_modify -@[simp] +@[simp, grind =] theorem mem_modify [EquivBEq α] [LawfulHashable α] {k k': α} {f : β → β} : k' ∈ modify m k f ↔ k' ∈ m := ExtDHashMap.Const.mem_modify -@[simp] +@[simp, grind =] theorem size_modify [EquivBEq α] [LawfulHashable α] {k : α} {f : β → β} : (modify m k f).size = m.size := ExtDHashMap.Const.size_modify -theorem getElem?_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} : +@[grind =] theorem getElem?_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} : (modify m k f)[k']? = if k == k' then m[k]?.map f @@ -1633,7 +1646,7 @@ theorem get?_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β → get? (modify m k f) k = (get? m k).map f := ExtDHashMap.Const.get?_modify_self -theorem getElem_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} +@[grind =] theorem getElem_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} {h : k' ∈ modify m k f} : (modify m k f)[k'] = if heq : k == k' then @@ -1670,7 +1683,7 @@ theorem get_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β → get (modify m k f) k h = f (get m k h') := ExtDHashMap.Const.get_modify_self -theorem getElem!_modify [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] {f : β → β} : +@[grind =] theorem getElem!_modify [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] {f : β → β} : (modify m k f)[k']! = if k == k' then m[k]?.map f |>.get! @@ -1697,7 +1710,7 @@ theorem get!_modify_self [EquivBEq α] [LawfulHashable α] {k : α} [Inhabited get! (modify m k f) k = ((get? m k).map f).get! := ExtDHashMap.Const.get!_modify_self -theorem getD_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} {f : β → β} : +@[grind =] theorem getD_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} {f : β → β} : getD (modify m k f) k' fallback = if k == k' then m[k]?.map f |>.getD fallback @@ -1710,7 +1723,7 @@ theorem getD_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {fallback : getD (modify m k f) k fallback = (m[k]?.map f).getD fallback := ExtDHashMap.Const.getD_modify_self -theorem getKey?_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} : +@[grind =] theorem getKey?_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} : (modify m k f).getKey? k' = if k == k' then if k ∈ m then some k else none @@ -1722,7 +1735,7 @@ theorem getKey?_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β (modify m k f).getKey? k = if k ∈ m then some k else none := ExtDHashMap.Const.getKey?_modify_self -theorem getKey!_modify [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : β → β} : +@[grind =] theorem getKey!_modify [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : β → β} : (modify m k f).getKey! k' = if k == k' then if k ∈ m then k else default @@ -1734,7 +1747,7 @@ theorem getKey!_modify_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k (modify m k f).getKey! k = if k ∈ m then k else default := ExtDHashMap.Const.getKey!_modify_self -theorem getKey_modify [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : β → β} +@[grind =] theorem getKey_modify [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : β → β} {h : k' ∈ modify m k f} : (modify m k f).getKey k' h = if k == k' then @@ -1749,7 +1762,7 @@ theorem getKey_modify_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : {h : k ∈ modify m k f} : (modify m k f).getKey k h = k := ExtDHashMap.Const.getKey_modify_self -theorem getKeyD_modify [EquivBEq α] [LawfulHashable α] {k k' fallback : α} {f : β → β} : +@[grind =] theorem getKeyD_modify [EquivBEq α] [LawfulHashable α] {k k' fallback : α} {f : β → β} : (modify m k f).getKeyD k' fallback = if k == k' then if k ∈ m then k else fallback @@ -1801,7 +1814,7 @@ theorem filterMap_eq_empty_iff [EquivBEq α] [LawfulHashable α] {f : α → β m.filterMap f = ∅ ↔ ∀ k h, f (m.getKey k h) (m[k]'h) = none := ext_iff.trans ExtDHashMap.Const.filterMap_eq_empty_iff -theorem mem_filterMap [EquivBEq α] [LawfulHashable α] +@[grind =] theorem mem_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} : k ∈ m.filterMap f ↔ ∃ h, (f (m.getKey k h) m[k]).isSome := ExtDHashMap.Const.mem_filterMap @@ -1821,12 +1834,14 @@ theorem size_filterMap_le_size [EquivBEq α] [LawfulHashable α] (m.filterMap f).size ≤ m.size := ExtDHashMap.size_filterMap_le_size +grind_pattern size_filterMap_le_size => (m.filterMap f).size + theorem size_filterMap_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} : (m.filterMap f).size = m.size ↔ ∀ k h, (f (m.getKey k h) m[k]).isSome := ExtDHashMap.Const.size_filterMap_eq_size_iff -theorem getElem?_filterMap [EquivBEq α] [LawfulHashable α] +@[grind =] theorem getElem?_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} : (m.filterMap f)[k]? = m[k]?.pbind (fun x h' => f (m.getKey k (mem_iff_isSome_getElem?.mpr (Option.isSome_of_eq_some h'))) x) := @@ -1844,8 +1859,7 @@ theorem isSome_apply_of_mem_filterMap [EquivBEq α] [LawfulHashable α] (m[k]'(mem_of_mem_filterMap h))).isSome := ExtDHashMap.Const.isSome_apply_of_mem_filterMap -@[simp] -theorem getElem_filterMap [EquivBEq α] [LawfulHashable α] +@[simp, grind =] theorem getElem_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} {h} : (m.filterMap f)[k]'h = (f (m.getKey k (mem_of_mem_filterMap h)) @@ -1853,7 +1867,7 @@ theorem getElem_filterMap [EquivBEq α] [LawfulHashable α] (isSome_apply_of_mem_filterMap h) := ExtDHashMap.Const.get_filterMap (h := h) -theorem getElem!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited γ] +@[grind =] theorem getElem!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited γ] {f : α → β → Option γ} {k : α} : (m.filterMap f)[k]! = (m[k]?.pbind (fun x h' => @@ -1865,7 +1879,7 @@ theorem getElem!_filterMap_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] (m.filterMap f)[k]! = (m[k]?.bind (f k')).get! := ExtDHashMap.Const.get!_filterMap_of_getKey?_eq_some h -theorem getD_filterMap [EquivBEq α] [LawfulHashable α] +@[grind =] theorem getD_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} {fallback : γ} : (m.filterMap f).getD k fallback = (m[k]?.pbind (fun x h' => @@ -1877,27 +1891,27 @@ theorem getD_filterMap_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] (m.filterMap f).getD k fallback = (m[k]?.bind (f k')).getD fallback := ExtDHashMap.Const.getD_filterMap_of_getKey?_eq_some h -theorem getKey?_filterMap [EquivBEq α] [LawfulHashable α] +@[grind =] theorem getKey?_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} : (m.filterMap f).getKey? k = (m.getKey? k).pfilter (fun x h' => (f x (m[x]'(mem_of_getKey?_eq_some h'))).isSome) := ExtDHashMap.Const.getKey?_filterMap -@[simp] +@[simp, grind =] theorem getKey_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} {h'} : (m.filterMap f).getKey k h' = m.getKey k (mem_of_mem_filterMap h') := ExtDHashMap.getKey_filterMap -theorem getKey!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited α] +@[grind =] theorem getKey!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → Option γ} {k : α} : (m.filterMap f).getKey! k = ((m.getKey? k).pfilter (fun x h' => (f x (m[x]'(mem_of_getKey?_eq_some h'))).isSome)).get! := ExtDHashMap.Const.getKey!_filterMap -theorem getKeyD_filterMap [EquivBEq α] [LawfulHashable α] +@[grind =] theorem getKeyD_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k fallback : α} : (m.filterMap f).getKeyD k fallback = ((m.getKey? k).pfilter (fun x h' => @@ -1918,7 +1932,7 @@ theorem filter_eq_empty_iff [EquivBEq α] [LawfulHashable α] {f : α → β → m.filter f = ∅ ↔ ∀ k h, f (m.getKey k h) (m[k]'h) = false := ext_iff.trans ExtDHashMap.Const.filter_eq_empty_iff -theorem mem_filter [EquivBEq α] [LawfulHashable α] +@[grind =] theorem mem_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} : k ∈ m.filter f ↔ ∃ (h' : k ∈ m), f (m.getKey k h') m[k] := ExtDHashMap.Const.mem_filter @@ -1938,6 +1952,8 @@ theorem size_filter_le_size [EquivBEq α] [LawfulHashable α] (m.filter f).size ≤ m.size := ExtDHashMap.size_filter_le_size +grind_pattern size_filter_le_size => (m.filter f).size + theorem size_filter_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} : (m.filter f).size = m.size ↔ ∀ k h, f (m.getKey k h) (m.get k h) := @@ -1948,7 +1964,7 @@ theorem filter_eq_self_iff [EquivBEq α] [LawfulHashable α] m.filter f = m ↔ ∀ k h, f (m.getKey k h) (m.get k h) := ext_iff.trans ExtDHashMap.Const.filter_eq_self_iff -theorem getElem?_filter [EquivBEq α] [LawfulHashable α] +@[grind =] theorem getElem?_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} : (m.filter f)[k]? = m[k]?.pfilter (fun x h' => f (m.getKey k (mem_iff_isSome_getElem?.mpr (Option.isSome_of_eq_some h'))) x) := @@ -1960,13 +1976,12 @@ theorem getElem?_filter_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] (m.filter f)[k]? = m[k]?.filter (fun x => f k' x) := ExtDHashMap.Const.get?_filter_of_getKey?_eq_some -@[simp] -theorem getElem_filter [EquivBEq α] [LawfulHashable α] +@[simp, grind =] theorem getElem_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} {h'} : (m.filter f)[k]'(h') = m[k]'(mem_of_mem_filter h') := ExtDHashMap.Const.get_filter (h' := h') -theorem getElem!_filter [EquivBEq α] [LawfulHashable α] [Inhabited β] +@[grind =] theorem getElem!_filter [EquivBEq α] [LawfulHashable α] [Inhabited β] {f : α → β → Bool} {k : α} : (m.filter f)[k]! = (m[k]?.pfilter (fun x h' => @@ -1979,7 +1994,7 @@ theorem getElem!_filter_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [In (m.filter f)[k]! = (m[k]?.filter (f k')).get! := ExtDHashMap.Const.get!_filter_of_getKey?_eq_some -theorem getD_filter [EquivBEq α] [LawfulHashable α] +@[grind =] theorem getD_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} {fallback : β} : (m.filter f).getD k fallback = (m[k]?.pfilter (fun x h' => f (m.getKey k (mem_iff_isSome_getElem?.mpr (Option.isSome_of_eq_some h'))) x)).getD fallback := @@ -1992,7 +2007,7 @@ theorem getD_filter_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] (m[k]?.filter (fun x => f k' x)).getD fallback := ExtDHashMap.Const.getD_filter_of_getKey?_eq_some -theorem getKey?_filter [EquivBEq α] [LawfulHashable α] +@[grind =] theorem getKey?_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} : (m.filter f).getKey? k = (m.getKey? k).pfilter (fun x h' => @@ -2004,13 +2019,13 @@ theorem getKey?_filter_key [EquivBEq α] [LawfulHashable α] (m.filter fun k _ => f k).getKey? k = (m.getKey? k).filter f := ExtDHashMap.getKey?_filter_key -@[simp] +@[simp, grind =] theorem getKey_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} {h'} : (m.filter f).getKey k h' = m.getKey k (mem_of_mem_filter h') := ExtDHashMap.getKey_filter -theorem getKey!_filter [EquivBEq α] [LawfulHashable α] [Inhabited α] +@[grind =] theorem getKey!_filter [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → Bool} {k : α} : (m.filter f).getKey! k = ((m.getKey? k).pfilter (fun x h' => @@ -2022,7 +2037,7 @@ theorem getKey!_filter_key [EquivBEq α] [LawfulHashable α] [Inhabited α] (m.filter fun k _ => f k).getKey! k = ((m.getKey? k).filter f).get! := ExtDHashMap.getKey!_filter_key -theorem getKeyD_filter [EquivBEq α] [LawfulHashable α] +@[grind =] theorem getKeyD_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k fallback : α} : (m.filter f).getKeyD k fallback = ((m.getKey? k).pfilter (fun x h' => @@ -2059,7 +2074,7 @@ theorem map_eq_empty_iff [EquivBEq α] [LawfulHashable α] {f : α → β → γ m.map f = ∅ ↔ m = ∅ := by simpa only [ext_iff] using ExtDHashMap.map_eq_empty_iff -@[simp] +@[simp, grind =] theorem contains_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} : (m.map f).contains k = m.contains k := @@ -2070,7 +2085,7 @@ theorem contains_of_contains_map [EquivBEq α] [LawfulHashable α] (m.map f).contains k = true → m.contains k = true := ExtDHashMap.contains_of_contains_map -@[simp] +@[simp, grind =] theorem mem_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} : k ∈ m.map f ↔ k ∈ m := by @@ -2081,13 +2096,13 @@ theorem mem_of_mem_map [EquivBEq α] [LawfulHashable α] k ∈ m.map f → k ∈ m := ExtDHashMap.contains_of_contains_map -@[simp] +@[simp, grind =] theorem size_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} : (m.map f).size = m.size := ExtDHashMap.size_map -@[simp] +@[simp, grind =] theorem getElem?_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} : (m.map f)[k]? = m[k]?.map (f k) := @@ -2106,7 +2121,7 @@ theorem getElem?_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] (m.map f)[k]? = m[k]?.map (f k') := ExtDHashMap.Const.get?_map_of_getKey?_eq_some h -@[simp] +@[simp, grind =] theorem getElem_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} {h'} : (m.map f)[k]' h' = @@ -2121,7 +2136,7 @@ theorem getElem_map' [EquivBEq α] [LawfulHashable α] f (m.getKey k (mem_of_mem_map h')) (m[k]'(mem_of_mem_map h')) := ExtDHashMap.Const.get_map' (h' := h') -theorem getElem!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ] +@[grind =] theorem getElem!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ] {f : α → β → γ} {k : α} : (m.map f)[k]! = (m[k]?.map (f k)).get! := @@ -2140,7 +2155,7 @@ theorem getElem!_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhab (m.map f)[k]! = (m[k]?.map (f k')).get! := ExtDHashMap.Const.get!_map_of_getKey?_eq_some h -theorem getD_map [LawfulBEq α] [LawfulHashable α] +@[grind =] theorem getD_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} {fallback : γ} : (m.map f).getD k fallback = (m[k]?.map (f k)).getD fallback := @@ -2159,25 +2174,25 @@ theorem getD_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhabited (m.map f).getD k fallback = (m[k]?.map (f k')).getD fallback := ExtDHashMap.Const.getD_map_of_getKey?_eq_some h -@[simp] +@[simp, grind =] theorem getKey?_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} : (m.map f).getKey? k = m.getKey? k := ExtDHashMap.getKey?_map -@[simp] +@[simp, grind =] theorem getKey_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} {h'} : (m.map f).getKey k h' = m.getKey k (mem_of_mem_map h') := ExtDHashMap.getKey_map -@[simp] +@[simp, grind =] theorem getKey!_map [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → γ} {k : α} : (m.map f).getKey! k = m.getKey! k := ExtDHashMap.getKey!_map -@[simp] +@[simp, grind =] theorem getKeyD_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} {k fallback : α} : (m.map f).getKeyD k fallback = m.getKeyD k fallback := diff --git a/src/Std/Data/ExtHashSet/Lemmas.lean b/src/Std/Data/ExtHashSet/Lemmas.lean index 2db7ec9071..26e3b4ca97 100644 --- a/src/Std/Data/ExtHashSet/Lemmas.lean +++ b/src/Std/Data/ExtHashSet/Lemmas.lean @@ -13,6 +13,8 @@ import Std.Data.ExtHashSet.Basic This module contains lemmas about `Std.ExtHashSet`. -/ +set_option trace.grind.ematch.pattern true + set_option linter.missingDocs true set_option autoImplicit false @@ -32,7 +34,7 @@ private theorem ext {m m' : ExtHashSet α} : m.inner = m'.inner → m = m' := by private theorem ext_iff {m m' : ExtHashSet α} : m = m' ↔ m.inner = m'.inner := ⟨fun h => h ▸ rfl, ext⟩ -@[simp] +@[simp, grind =] theorem isEmpty_iff [EquivBEq α] [LawfulHashable α] : m.isEmpty ↔ m = ∅ := ExtHashMap.isEmpty_iff.trans ext_iff.symm @@ -43,7 +45,7 @@ theorem isEmpty_eq_false_iff [EquivBEq α] [LawfulHashable α] : m.isEmpty = fal @[simp] theorem empty_eq : ∅ = m ↔ m = ∅ := eq_comm -@[simp] +@[simp, grind =] theorem emptyWithCapacity_eq [EquivBEq α] [LawfulHashable α] {c} : (emptyWithCapacity c : ExtHashSet α) = ∅ := ext ExtHashMap.emptyWithCapacity_eq @@ -66,7 +68,7 @@ theorem contains_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == theorem mem_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == b) : a ∈ m ↔ b ∈ m := ExtHashMap.mem_congr hab -@[simp] theorem contains_empty [EquivBEq α] [LawfulHashable α] {a : α} : +@[simp, grind =] theorem contains_empty [EquivBEq α] [LawfulHashable α] {a : α} : (∅ : ExtHashSet α).contains a = false := ExtHashMap.contains_empty @@ -87,12 +89,12 @@ theorem eq_empty_iff_forall_not_mem [EquivBEq α] [LawfulHashable α] : m = ∅ Singleton.singleton a = (∅ : ExtHashSet α).insert a := rfl -@[simp] +@[simp, grind =] theorem contains_insert [EquivBEq α] [LawfulHashable α] {k a : α} : (m.insert k).contains a = (k == a || m.contains a) := ExtHashMap.contains_insertIfNew -@[simp] +@[simp, grind =] theorem mem_insert [EquivBEq α] [LawfulHashable α] {k a : α} : a ∈ m.insert k ↔ k == a ∨ a ∈ m := ExtHashMap.mem_insertIfNew @@ -121,13 +123,14 @@ theorem contains_insert_self [EquivBEq α] [LawfulHashable α] {k : α} : (m.ins theorem mem_insert_self [EquivBEq α] [LawfulHashable α] {k : α} : k ∈ m.insert k := by simp -@[simp] +@[simp, grind =] theorem size_empty [EquivBEq α] [LawfulHashable α] : (∅ : ExtHashSet α).size = 0 := ExtHashMap.size_empty theorem eq_empty_iff_size_eq_zero [EquivBEq α] [LawfulHashable α] : m = ∅ ↔ m.size = 0 := ext_iff.trans ExtHashMap.eq_empty_iff_size_eq_zero +@[grind =] theorem size_insert [EquivBEq α] [LawfulHashable α] {k : α} : (m.insert k).size = if k ∈ m then m.size else m.size + 1 := ExtHashMap.size_insertIfNew @@ -139,7 +142,7 @@ theorem size_insert_le [EquivBEq α] [LawfulHashable α] {k : α} : (m.insert k).size ≤ m.size + 1 := ExtHashMap.size_insertIfNew_le -@[simp] +@[simp, grind =] theorem erase_empty [EquivBEq α] [LawfulHashable α] {a : α} : (∅ : ExtHashSet α).erase a = ∅ := ext ExtHashMap.erase_empty @@ -148,12 +151,12 @@ theorem erase_eq_empty_iff [EquivBEq α] [LawfulHashable α] {k : α} : m.erase k = ∅ ↔ m = ∅ ∨ m.size = 1 ∧ k ∈ m := by simpa only [ext_iff] using ExtHashMap.erase_eq_empty_iff -@[simp] +@[simp, grind =] theorem contains_erase [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k).contains a = (!(k == a) && m.contains a) := ExtHashMap.contains_erase -@[simp] +@[simp, grind =] theorem mem_erase [EquivBEq α] [LawfulHashable α] {k a : α} : a ∈ m.erase k ↔ (k == a) = false ∧ a ∈ m := ExtHashMap.mem_erase @@ -165,6 +168,7 @@ theorem contains_of_contains_erase [EquivBEq α] [LawfulHashable α] {k a : α} theorem mem_of_mem_erase [EquivBEq α] [LawfulHashable α] {k a : α} : a ∈ m.erase k → a ∈ m := ExtHashMap.mem_of_mem_erase +@[grind =] theorem size_erase [EquivBEq α] [LawfulHashable α] {k : α} : (m.erase k).size = if k ∈ m then m.size - 1 else m.size := ExtHashMap.size_erase @@ -176,10 +180,11 @@ theorem size_le_size_erase [EquivBEq α] [LawfulHashable α] {k : α} : m.size ≤ (m.erase k).size + 1 := ExtHashMap.size_le_size_erase -@[simp] +@[simp, grind =] theorem get?_empty [EquivBEq α] [LawfulHashable α] {a : α} : (∅ : ExtHashSet α).get? a = none := ExtHashMap.getKey?_empty +@[grind =] theorem get?_insert [EquivBEq α] [LawfulHashable α] {k a : α} : (m.insert k).get? a = if k == a ∧ ¬k ∈ m then some k else m.get? a := ExtHashMap.getKey?_insertIfNew @@ -209,6 +214,7 @@ theorem get?_eq_none_of_contains_eq_false [EquivBEq α] [LawfulHashable α] {a : theorem get?_eq_none [EquivBEq α] [LawfulHashable α] {a : α} : ¬a ∈ m → m.get? a = none := ExtHashMap.getKey?_eq_none +@[grind =] theorem get?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k).get? a = if k == a then none else m.get? a := ExtHashMap.getKey?_erase @@ -230,12 +236,13 @@ theorem get?_eq_some_of_contains [LawfulBEq α] {k : α} (h : m.contains k) : m. theorem get?_eq_some [LawfulBEq α] {k : α} (h : k ∈ m) : m.get? k = some k := ExtHashMap.getKey?_eq_some h +@[grind =] theorem get_insert [EquivBEq α] [LawfulHashable α] {k a : α} {h₁} : (m.insert k).get a h₁ = if h₂ : k == a ∧ ¬k ∈ m then k else m.get a (mem_of_mem_insert' h₁ h₂) := ExtHashMap.getKey_insertIfNew (h₁ := h₁) -@[simp] +@[simp, grind =] theorem get_erase [EquivBEq α] [LawfulHashable α] {k a : α} {h'} : (m.erase k).get a h' = m.get a (mem_of_mem_erase h') := ExtHashMap.getKey_erase (h' := h') @@ -248,7 +255,7 @@ theorem get_eq_get_get? [EquivBEq α] [LawfulHashable α] {k : α} {h} : m.get k h = (m.get? k).get (mem_iff_isSome_get?.mp h) := ExtHashMap.getKey_eq_get_getKey? -theorem get_get? [EquivBEq α] [LawfulHashable α] {k : α} {h} : +@[grind =] theorem get_get? [EquivBEq α] [LawfulHashable α] {k : α} {h} : (m.get? k).get h = m.get k (mem_iff_isSome_get?.mpr h) := ExtHashMap.get_getKey? @@ -259,15 +266,16 @@ theorem get_congr [EquivBEq α] [LawfulHashable α] {k₁ k₂ : α} (h : k₁ = (h₁ : k₁ ∈ m) : m.get k₁ h₁ = m.get k₂ ((mem_congr h).mp h₁) := ExtHashMap.getKey_congr h h₁ -@[simp] +@[simp, grind =] theorem get_eq [LawfulBEq α] {k : α} (h : k ∈ m) : m.get k h = k := ExtHashMap.getKey_eq h -@[simp] +@[simp, grind =] theorem get!_empty [EquivBEq α] [LawfulHashable α] [Inhabited α] {a : α} : (∅ : ExtHashSet α).get! a = default := ExtHashMap.getKey!_empty +@[grind =] theorem get!_insert [Inhabited α] [EquivBEq α] [LawfulHashable α] {k a : α} : (m.insert k).get! a = if k == a ∧ ¬k ∈ m then k else m.get! a := ExtHashMap.getKey!_insertIfNew @@ -280,6 +288,7 @@ theorem get!_eq_default [Inhabited α] [EquivBEq α] [LawfulHashable α] {a : α ¬a ∈ m → m.get! a = default := ExtHashMap.getKey!_eq_default +@[grind =] theorem get!_erase [Inhabited α] [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k).get! a = if k == a then default else m.get! a := ExtHashMap.getKey!_erase @@ -315,12 +324,12 @@ theorem get!_eq_of_contains [LawfulBEq α] [Inhabited α] {k : α} (h : m.contai theorem get!_eq_of_mem [LawfulBEq α] [Inhabited α] {k : α} (h : k ∈ m) : m.get! k = k := ExtHashMap.getKey!_eq_of_mem h -@[simp] +@[simp, grind =] theorem getD_empty [EquivBEq α] [LawfulHashable α] {a fallback : α} : (∅ : ExtHashSet α).getD a fallback = fallback := ExtHashMap.getKeyD_empty -theorem getD_insert [EquivBEq α] [LawfulHashable α] {k a fallback : α} : +@[grind] theorem getD_insert [EquivBEq α] [LawfulHashable α] {k a fallback : α} : (m.insert k).getD a fallback = if k == a ∧ ¬k ∈ m then k else m.getD a fallback := ExtHashMap.getKeyD_insertIfNew @@ -333,7 +342,7 @@ theorem getD_eq_fallback [EquivBEq α] [LawfulHashable α] {a fallback : α} : ¬a ∈ m → m.getD a fallback = fallback := ExtHashMap.getKeyD_eq_fallback -theorem getD_erase [EquivBEq α] [LawfulHashable α] {k a fallback : α} : +@[grind =] theorem getD_erase [EquivBEq α] [LawfulHashable α] {k a fallback : α} : (m.erase k).getD a fallback = if k == a then fallback else m.getD a fallback := ExtHashMap.getKeyD_erase @@ -373,32 +382,34 @@ theorem getD_eq_of_contains [LawfulBEq α] {k fallback : α} (h : m.contains k) theorem getD_eq_of_mem [LawfulBEq α] {k fallback : α} (h : k ∈ m) : m.getD k fallback = k := ExtHashMap.getKeyD_eq_of_mem h -@[simp] +@[simp, grind =] theorem containsThenInsert_fst [EquivBEq α] [LawfulHashable α] {k : α} : (m.containsThenInsert k).1 = m.contains k := ExtHashMap.containsThenInsertIfNew_fst -@[simp] +@[simp, grind =] theorem containsThenInsert_snd [EquivBEq α] [LawfulHashable α] {k : α} : (m.containsThenInsert k).2 = m.insert k := ext ExtHashMap.containsThenInsertIfNew_snd variable {ρ : Type v} [ForIn Id ρ α] -@[simp] +@[simp, grind =] theorem insertMany_nil [EquivBEq α] [LawfulHashable α] : insertMany m [] = m := ext ExtHashMap.insertManyIfNewUnit_nil -@[simp] +@[simp, grind =] theorem insertMany_list_singleton [EquivBEq α] [LawfulHashable α] {k : α} : insertMany m [k] = m.insert k := ext ExtHashMap.insertManyIfNewUnit_list_singleton +@[grind _=_] theorem insertMany_cons [EquivBEq α] [LawfulHashable α] {l : List α} {k : α} : insertMany m (k :: l) = insertMany (m.insert k) l := ext ExtHashMap.insertManyIfNewUnit_cons +@[grind _=_] theorem insertMany_append [EquivBEq α] [LawfulHashable α] {l₁ l₂ : List α} : insertMany m (l₁ ++ l₂) = insertMany (insertMany m l₁) l₂ := by induction l₁ generalizing m with @@ -414,13 +425,13 @@ theorem insertMany_ind [EquivBEq α] [LawfulHashable α] show motive ⟨m.1.insertManyIfNewUnit l⟩ from ExtHashMap.insertManyIfNewUnit_ind m.inner l init fun m => insert ⟨m⟩ -@[simp] +@[simp, grind =] theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List α} {k : α} : (insertMany m l).contains k = (m.contains k || l.contains k) := ExtHashMap.contains_insertManyIfNewUnit_list -@[simp] +@[simp, grind =] theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List α} {k : α} : k ∈ insertMany m l ↔ k ∈ m ∨ l.contains k := @@ -525,11 +536,15 @@ theorem size_le_size_insertMany [EquivBEq α] [LawfulHashable α] {l : ρ} : m.size ≤ (insertMany m l).size := ExtHashMap.size_le_size_insertManyIfNewUnit +grind_pattern size_le_size_insertMany => (insertMany m l).size + theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] {l : List α} : (insertMany m l).size ≤ m.size + l.length := ExtHashMap.size_insertManyIfNewUnit_list_le +grind_pattern size_insertMany_list_le => (insertMany m l).size + @[simp] theorem insertMany_list_eq_empty_iff [EquivBEq α] [LawfulHashable α] {l : List α} : m.insertMany l = ∅ ↔ m = ∅ ∧ l = [] := by @@ -543,16 +558,17 @@ end section -@[simp] +@[simp, grind =] theorem ofList_nil [EquivBEq α] [LawfulHashable α] : ofList ([] : List α) = ∅ := ext ExtHashMap.unitOfList_nil -@[simp] +@[simp, grind =] theorem ofList_singleton [EquivBEq α] [LawfulHashable α] {k : α} : ofList [k] = (∅ : ExtHashSet α).insert k := ext ExtHashMap.unitOfList_singleton +@[grind _=_] theorem ofList_cons [EquivBEq α] [LawfulHashable α] {hd : α} {tl : List α} : ofList (hd :: tl) = insertMany ((∅ : ExtHashSet α).insert hd) tl := @@ -564,13 +580,13 @@ theorem ofList_eq_insertMany_empty [EquivBEq α] [LawfulHashable α] {l : List | [] => by simp | hd :: tl => by simp [ofList_cons, insertMany_cons] -@[simp] +@[simp, grind =] theorem contains_ofList [EquivBEq α] [LawfulHashable α] {l : List α} {k : α} : (ofList l).contains k = l.contains k := ExtHashMap.contains_unitOfList -@[simp] +@[simp, grind =] theorem mem_ofList [EquivBEq α] [LawfulHashable α] {l : List α} {k : α} : k ∈ ofList l ↔ l.contains k := @@ -632,6 +648,8 @@ theorem size_ofList_le [EquivBEq α] [LawfulHashable α] (ofList l).size ≤ l.length := ExtHashMap.size_unitOfList_le +grind_pattern size_ofList_le => (ofList l).size + @[simp] theorem ofList_eq_empty_iff [EquivBEq α] [LawfulHashable α] {l : List α} : ofList l = ∅ ↔ l = [] := @@ -664,7 +682,7 @@ theorem filter_eq_empty_iff [EquivBEq α] [LawfulHashable α] {f : α → Bool} m.filter f = ∅ ↔ ∀ k h, f (m.get k h) = false := ext_iff.trans ExtHashMap.filter_eq_empty_iff -@[simp] +@[simp, grind =] theorem mem_filter [EquivBEq α] [LawfulHashable α] {f : α → Bool} {k : α} : k ∈ m.filter f ↔ ∃ h, f (m.get k h) := @@ -685,6 +703,8 @@ theorem size_filter_le_size [EquivBEq α] [LawfulHashable α] (m.filter f).size ≤ m.size := ExtHashMap.size_filter_le_size +grind_pattern size_filter_le_size => (m.filter f).size + theorem size_filter_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α → Bool} : (m.filter f).size = m.size ↔ ∀ k h, f (m.get k h) := @@ -695,23 +715,25 @@ theorem filter_eq_self_iff [EquivBEq α] [LawfulHashable α] m.filter f = m ↔ ∀ k h, f (m.get k h) := ext_iff.trans ExtHashMap.filter_eq_self_iff -@[simp] +@[simp, grind =] theorem get?_filter [EquivBEq α] [LawfulHashable α] {f : α → Bool} {k : α} : (m.filter f).get? k = (m.get? k).filter f := ExtHashMap.getKey?_filter_key -@[simp] +@[simp, grind =] theorem get_filter [EquivBEq α] [LawfulHashable α] {f : α → Bool} {k : α} {h} : (m.filter f).get k h = m.get k (mem_of_mem_filter h) := ExtHashMap.getKey_filter +@[grind =] theorem get!_filter [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → Bool} {k : α} : (m.filter f).get! k = ((m.get? k).filter f).get! := ExtHashMap.getKey!_filter_key +@[grind =] theorem getD_filter [EquivBEq α] [LawfulHashable α] {f : α → Bool} {k fallback : α} : (m.filter f).getD k fallback = ((m.get? k).filter f).getD fallback := diff --git a/src/Std/Data/HashMap/Lemmas.lean b/src/Std/Data/HashMap/Lemmas.lean index b2298b0af3..2ae59a7cd2 100644 --- a/src/Std/Data/HashMap/Lemmas.lean +++ b/src/Std/Data/HashMap/Lemmas.lean @@ -16,6 +16,8 @@ This module contains lemmas about `Std.Data.HashMap`. Most of the lemmas require is to provide an instance of `LawfulBEq α`. -/ +set_option trace.grind.ematch.pattern true + set_option linter.missingDocs true set_option autoImplicit false @@ -32,11 +34,11 @@ variable {m : HashMap α β} private theorem ext {m m' : HashMap α β} : m.inner = m'.inner → m = m' := by cases m; cases m'; rintro rfl; rfl -@[simp] +@[simp, grind =] theorem isEmpty_emptyWithCapacity {c} : (emptyWithCapacity c : HashMap α β).isEmpty := DHashMap.isEmpty_emptyWithCapacity -@[simp] +@[simp, grind =] theorem isEmpty_empty : (∅ : HashMap α β).isEmpty := DHashMap.isEmpty_empty @@ -44,7 +46,7 @@ set_option linter.missingDocs false in @[deprecated isEmpty_empty (since := "2025-03-12")] abbrev isEmpty_emptyc := @isEmpty_empty -@[simp] +@[simp, grind =] theorem isEmpty_insert [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (m.insert k v).isEmpty = false := DHashMap.isEmpty_insert @@ -64,20 +66,21 @@ theorem mem_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == b) : a ∈ m ↔ b ∈ m := DHashMap.mem_congr hab -@[simp] +@[simp, grind =] theorem contains_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : HashMap α β).contains a = false := DHashMap.contains_emptyWithCapacity -@[simp] theorem not_mem_emptyWithCapacity {a : α} {c} : ¬a ∈ (emptyWithCapacity c : HashMap α β) := +@[simp, grind] theorem not_mem_emptyWithCapacity {a : α} {c} : ¬a ∈ (emptyWithCapacity c : HashMap α β) := DHashMap.not_mem_emptyWithCapacity -@[simp] theorem contains_empty {a : α} : (∅ : HashMap α β).contains a = false := +@[simp, grind =] theorem contains_empty {a : α} : (∅ : HashMap α β).contains a = false := DHashMap.contains_empty set_option linter.missingDocs false in @[deprecated contains_empty (since := "2025-03-12")] abbrev contains_emptyc := @contains_empty +-- `grind` can't use this lemma, unfortunately, because it can't work out `β` @[simp] theorem not_mem_empty {a : α} : ¬a ∈ (∅ : HashMap α β) := DHashMap.not_mem_empty @@ -115,12 +118,12 @@ theorem isEmpty_iff_forall_not_mem [EquivBEq α] [LawfulHashable α] : Singleton.singleton p = (∅ : HashMap α β).insert p.1 p.2 := rfl -@[simp] +@[simp, grind =] theorem contains_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : (m.insert k v).contains a = (k == a || m.contains a) := DHashMap.contains_insert -@[simp] +@[simp, grind =] theorem mem_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : a ∈ m.insert k v ↔ k == a ∨ a ∈ m := DHashMap.mem_insert @@ -139,11 +142,11 @@ theorem contains_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β} theorem mem_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : k ∈ m.insert k v := by simp -@[simp] +@[simp, grind =] theorem size_emptyWithCapacity {c} : (emptyWithCapacity c : HashMap α β).size = 0 := DHashMap.size_emptyWithCapacity -@[simp] +@[simp, grind =] theorem size_empty : (∅ : HashMap α β).size = 0 := DHashMap.size_empty @@ -154,7 +157,7 @@ abbrev size_emptyc := @size_empty theorem isEmpty_eq_size_eq_zero : m.isEmpty = (m.size == 0) := DHashMap.isEmpty_eq_size_eq_zero -theorem size_insert [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : +@[grind =] theorem size_insert [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (m.insert k v).size = if k ∈ m then m.size else m.size + 1 := DHashMap.size_insert @@ -166,11 +169,11 @@ theorem size_insert_le [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (m.insert k v).size ≤ m.size + 1 := DHashMap.size_insert_le -@[simp] +@[simp, grind =] theorem erase_emptyWithCapacity {a : α} {c : Nat} : (emptyWithCapacity c : HashMap α β).erase a = emptyWithCapacity c := ext DHashMap.erase_emptyWithCapacity -@[simp] +@[simp, grind =] theorem erase_empty {a : α} : (∅ : HashMap α β).erase a = ∅ := ext DHashMap.erase_empty @@ -178,17 +181,17 @@ set_option linter.missingDocs false in @[deprecated erase_empty (since := "2025-03-12")] abbrev erase_emptyc := @erase_empty -@[simp] +@[simp, grind =] theorem isEmpty_erase [EquivBEq α] [LawfulHashable α] {k : α} : (m.erase k).isEmpty = (m.isEmpty || (m.size == 1 && m.contains k)) := DHashMap.isEmpty_erase -@[simp] +@[simp, grind =] theorem contains_erase [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k).contains a = (!(k == a) && m.contains a) := DHashMap.contains_erase -@[simp] +@[simp, grind =] theorem mem_erase [EquivBEq α] [LawfulHashable α] {k a : α} : a ∈ m.erase k ↔ (k == a) = false ∧ a ∈ m := DHashMap.mem_erase @@ -200,7 +203,7 @@ theorem contains_of_contains_erase [EquivBEq α] [LawfulHashable α] {k a : α} theorem mem_of_mem_erase [EquivBEq α] [LawfulHashable α] {k a : α} : a ∈ m.erase k → a ∈ m := DHashMap.mem_of_mem_erase -theorem size_erase [EquivBEq α] [LawfulHashable α] {k : α} : +@[grind =] theorem size_erase [EquivBEq α] [LawfulHashable α] {k : α} : (m.erase k).size = if k ∈ m then m.size - 1 else m.size := DHashMap.size_erase @@ -211,32 +214,33 @@ theorem size_le_size_erase [EquivBEq α] [LawfulHashable α] {k : α} : m.size ≤ (m.erase k).size + 1 := DHashMap.size_le_size_erase -@[simp] +@[simp, grind =] theorem containsThenInsert_fst {k : α} {v : β} : (m.containsThenInsert k v).1 = m.contains k := DHashMap.containsThenInsert_fst -@[simp] +@[simp, grind =] theorem containsThenInsert_snd {k : α} {v : β} : (m.containsThenInsert k v).2 = m.insert k v := ext (DHashMap.containsThenInsert_snd) -@[simp] +@[simp, grind =] theorem containsThenInsertIfNew_fst {k : α} {v : β} : (m.containsThenInsertIfNew k v).1 = m.contains k := DHashMap.containsThenInsertIfNew_fst -@[simp] +@[simp, grind =] theorem containsThenInsertIfNew_snd {k : α} {v : β} : (m.containsThenInsertIfNew k v).2 = m.insertIfNew k v := ext DHashMap.containsThenInsertIfNew_snd -@[simp] theorem get_eq_getElem {a : α} {h} : get m a h = m[a]'h := rfl -@[simp] theorem get?_eq_getElem? {a : α} : get? m a = m[a]? := rfl -@[simp] theorem get!_eq_getElem! [Inhabited β] {a : α} : get! m a = m[a]! := rfl +@[simp, grind =] theorem get_eq_getElem {a : α} {h} : get m a h = m[a]'h := rfl +@[simp, grind =] theorem get?_eq_getElem? {a : α} : get? m a = m[a]? := rfl +@[simp, grind =] theorem get!_eq_getElem! [Inhabited β] {a : α} : get! m a = m[a]! := rfl -@[simp] +@[simp, grind =] theorem getElem?_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : HashMap α β)[a]? = none := DHashMap.Const.get?_emptyWithCapacity +-- `grind` can not find a usable pattern here @[simp] theorem getElem?_empty {a : α} : (∅ : HashMap α β)[a]? = none := DHashMap.Const.get?_empty @@ -249,7 +253,7 @@ theorem getElem?_of_isEmpty [EquivBEq α] [LawfulHashable α] {a : α} : m.isEmpty = true → m[a]? = none := DHashMap.Const.get?_of_isEmpty -theorem getElem?_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : +@[grind =] theorem getElem?_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : (m.insert k v)[a]? = if k == a then some v else m[a]? := DHashMap.Const.get?_insert @@ -258,6 +262,7 @@ theorem getElem?_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β} (m.insert k v)[k]? = some v := DHashMap.Const.get?_insert_self +-- TODO: request this is reversed, and made `@[simp, grind]` theorem contains_eq_isSome_getElem? [EquivBEq α] [LawfulHashable α] {a : α} : m.contains a = m[a]?.isSome := DHashMap.Const.contains_eq_isSome_get? @@ -283,7 +288,7 @@ theorem getElem?_eq_none_of_contains_eq_false [EquivBEq α] [LawfulHashable α] theorem getElem?_eq_none [EquivBEq α] [LawfulHashable α] {a : α} : ¬a ∈ m → m[a]? = none := DHashMap.Const.get?_eq_none -theorem getElem?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : +@[grind =] theorem getElem?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k)[a]? = if k == a then none else m[a]? := DHashMap.Const.get?_erase @@ -294,7 +299,7 @@ theorem getElem?_erase_self [EquivBEq α] [LawfulHashable α] {k : α} : (m.eras theorem getElem?_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == b) : m[a]? = m[b]? := DHashMap.Const.get?_congr hab -theorem getElem_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : +@[grind =] theorem getElem_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : (m.insert k v)[a]'h₁ = if h₂ : k == a then v else m[a]'(mem_of_mem_insert h₁ (Bool.eq_false_iff.2 h₂)) := DHashMap.Const.get_insert (h₁ := h₁) @@ -304,7 +309,7 @@ theorem getElem_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β} (m.insert k v)[k]'mem_insert_self = v := DHashMap.Const.get_insert_self -@[simp] +@[simp, grind =] theorem getElem_erase [EquivBEq α] [LawfulHashable α] {k a : α} {h'} : (m.erase k)[a]'h' = m[a]'(mem_of_mem_erase h') := DHashMap.Const.get_erase (h' := h') @@ -317,7 +322,7 @@ theorem getElem_eq_get_getElem? [EquivBEq α] [LawfulHashable α] {a : α} {h} : m[a]'h = m[a]?.get (mem_iff_isSome_getElem?.mp h) := DHashMap.Const.get_eq_get_get? -theorem get_getElem? [EquivBEq α] [LawfulHashable α] {a : α} {h} : +@[grind =] theorem get_getElem? [EquivBEq α] [LawfulHashable α] {a : α} {h} : m[a]?.get h = m[a]'(mem_iff_isSome_getElem?.mpr h) := DHashMap.Const.get_get? @@ -325,11 +330,11 @@ theorem getElem_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == b m[a]'h' = m[b]'((mem_congr hab).1 h') := DHashMap.Const.get_congr hab (h' := h') -@[simp] +@[simp, grind =] theorem getElem!_emptyWithCapacity [Inhabited β] {a : α} {c} : (emptyWithCapacity c : HashMap α β)[a]! = default := DHashMap.Const.get!_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getElem!_empty [Inhabited β] {a : α} : (∅ : HashMap α β)[a]! = default := DHashMap.Const.get!_empty @@ -341,7 +346,7 @@ theorem getElem!_of_isEmpty [EquivBEq α] [LawfulHashable α] [Inhabited β] {a m.isEmpty = true → m[a]! = default := DHashMap.Const.get!_of_isEmpty -theorem getElem!_insert [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : +@[grind =] theorem getElem!_insert [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : (m.insert k v)[a]! = if k == a then v else m[a]! := DHashMap.Const.get!_insert @@ -358,7 +363,7 @@ theorem getElem!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited β] {a ¬a ∈ m → m[a]! = default := DHashMap.Const.get!_eq_default -theorem getElem!_erase [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} : +@[grind =] theorem getElem!_erase [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} : (m.erase k)[a]! = if k == a then default else m[a]! := DHashMap.Const.get!_erase @@ -387,12 +392,12 @@ theorem getElem!_congr [EquivBEq α] [LawfulHashable α] [Inhabited β] {a b : m[a]! = m[b]! := DHashMap.Const.get!_congr hab -@[simp] +@[simp, grind =] theorem getD_emptyWithCapacity {a : α} {fallback : β} {c} : (emptyWithCapacity c : HashMap α β).getD a fallback = fallback := DHashMap.Const.getD_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getD_empty {a : α} {fallback : β} : (∅ : HashMap α β).getD a fallback = fallback := DHashMap.Const.getD_empty @@ -404,7 +409,7 @@ theorem getD_of_isEmpty [EquivBEq α] [LawfulHashable α] {a : α} {fallback : m.isEmpty = true → m.getD a fallback = fallback := DHashMap.Const.getD_of_isEmpty -theorem getD_insert [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : +@[grind =] theorem getD_insert [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : (m.insert k v).getD a fallback = if k == a then v else m.getD a fallback := DHashMap.Const.getD_insert @@ -421,7 +426,7 @@ theorem getD_eq_fallback [EquivBEq α] [LawfulHashable α] {a : α} {fallback : ¬a ∈ m → m.getD a fallback = fallback := DHashMap.Const.getD_eq_fallback -theorem getD_erase [EquivBEq α] [LawfulHashable α] {k a : α} {fallback : β} : +@[grind =] theorem getD_erase [EquivBEq α] [LawfulHashable α] {k a : α} {fallback : β} : (m.erase k).getD a fallback = if k == a then fallback else m.getD a fallback := DHashMap.Const.getD_erase @@ -454,11 +459,11 @@ theorem getD_congr [EquivBEq α] [LawfulHashable α] {a b : α} {fallback : β} m.getD a fallback = m.getD b fallback := DHashMap.Const.getD_congr hab -@[simp] +@[simp, grind =] theorem getKey?_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : HashMap α β).getKey? a = none := DHashMap.getKey?_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getKey?_empty {a : α} : (∅ : HashMap α β).getKey? a = none := DHashMap.getKey?_empty @@ -470,7 +475,7 @@ theorem getKey?_of_isEmpty [EquivBEq α] [LawfulHashable α] {a : α} : m.isEmpty = true → m.getKey? a = none := DHashMap.getKey?_of_isEmpty -theorem getKey?_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : +@[grind =] theorem getKey?_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : (m.insert k v).getKey? a = if k == a then some k else m.getKey? a := DHashMap.getKey?_insert @@ -508,7 +513,7 @@ theorem getKey?_eq_none_of_contains_eq_false [EquivBEq α] [LawfulHashable α] { theorem getKey?_eq_none [EquivBEq α] [LawfulHashable α] {a : α} : ¬a ∈ m → m.getKey? a = none := DHashMap.getKey?_eq_none -theorem getKey?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : +@[grind =] theorem getKey?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k).getKey? a = if k == a then none else m.getKey? a := DHashMap.getKey?_erase @@ -530,7 +535,7 @@ theorem getKey?_eq_some_of_contains [LawfulBEq α] {k : α} (h : m.contains k) : theorem getKey?_eq_some [LawfulBEq α] {k : α} (h : k ∈ m) : m.getKey? k = some k := by simpa only [mem_iff_contains] using getKey?_eq_some_of_contains h -theorem getKey_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : +@[grind =] theorem getKey_insert [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : (m.insert k v).getKey a h₁ = if h₂ : k == a then k else m.getKey a (mem_of_mem_insert h₁ (by simpa using h₂)) := DHashMap.getKey_insert (h₁ := h₁) @@ -540,7 +545,7 @@ theorem getKey_insert_self [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (m.insert k v).getKey k mem_insert_self = k := DHashMap.getKey_insert_self -@[simp] +@[simp, grind =] theorem getKey_erase [EquivBEq α] [LawfulHashable α] {k a : α} {h'} : (m.erase k).getKey a h' = m.getKey a (mem_of_mem_erase h') := DHashMap.getKey_erase (h' := h') @@ -553,7 +558,7 @@ theorem getKey_eq_get_getKey? [EquivBEq α] [LawfulHashable α] {a : α} {h} : m.getKey a h = (m.getKey? a).get (mem_iff_isSome_getKey?.mp h) := DHashMap.getKey_eq_get_getKey? -@[simp] +@[simp, grind =] theorem get_getKey? [EquivBEq α] [LawfulHashable α] {a : α} {h} : (m.getKey? a).get h = m.getKey a (mem_iff_isSome_getKey?.mpr h) := DHashMap.get_getKey? @@ -565,15 +570,14 @@ theorem getKey_congr [EquivBEq α] [LawfulHashable α] {k₁ k₂ : α} (h : k (h₁ : k₁ ∈ m) : m.getKey k₁ h₁ = m.getKey k₂ ((mem_congr h).mp h₁) := DHashMap.getKey_congr h h₁ -@[simp] -theorem getKey_eq [LawfulBEq α] {k : α} (h : k ∈ m) : m.getKey k h = k := +@[simp, grind =] theorem getKey_eq [LawfulBEq α] {k : α} (h : k ∈ m) : m.getKey k h = k := DHashMap.getKey_eq h -@[simp] +@[simp, grind =] theorem getKey!_emptyWithCapacity [Inhabited α] {a : α} {c} : (emptyWithCapacity c : HashMap α β).getKey! a = default := DHashMap.getKey!_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getKey!_empty [Inhabited α] {a : α} : (∅ : HashMap α β).getKey! a = default := DHashMap.getKey!_empty @@ -585,7 +589,7 @@ theorem getKey!_of_isEmpty [EquivBEq α] [LawfulHashable α] [Inhabited α] {a : m.isEmpty = true → m.getKey! a = default := DHashMap.getKey!_of_isEmpty -theorem getKey!_insert [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β} : +@[grind =] theorem getKey!_insert [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β} : (m.insert k v).getKey! a = if k == a then k else m.getKey! a := DHashMap.getKey!_insert @@ -602,7 +606,7 @@ theorem getKey!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited α] {a : ¬a ∈ m → m.getKey! a = default := DHashMap.getKey!_eq_default -theorem getKey!_erase [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} : +@[grind =] theorem getKey!_erase [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} : (m.erase k).getKey! a = if k == a then default else m.getKey! a := DHashMap.getKey!_erase @@ -638,12 +642,12 @@ theorem getKey!_eq_of_contains [LawfulBEq α] [Inhabited α] {k : α} (h : m.con theorem getKey!_eq_of_mem [LawfulBEq α] [Inhabited α] {k : α} (h : k ∈ m) : m.getKey! k = k := DHashMap.getKey!_eq_of_mem h -@[simp] +@[simp, grind =] theorem getKeyD_emptyWithCapacity {a : α} {fallback : α} {c} : (emptyWithCapacity c : HashMap α β).getKeyD a fallback = fallback := DHashMap.getKeyD_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getKeyD_empty {a : α} {fallback : α} : (∅ : HashMap α β).getKeyD a fallback = fallback := DHashMap.getKeyD_empty @@ -655,7 +659,7 @@ theorem getKeyD_of_isEmpty [EquivBEq α] [LawfulHashable α] {a : α} {fallback m.isEmpty = true → m.getKeyD a fallback = fallback := DHashMap.getKeyD_of_isEmpty -theorem getKeyD_insert [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β} : +@[grind =] theorem getKeyD_insert [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β} : (m.insert k v).getKeyD a fallback = if k == a then k else m.getKeyD a fallback := DHashMap.getKeyD_insert @@ -672,7 +676,7 @@ theorem getKeyD_eq_fallback [EquivBEq α] [LawfulHashable α] {a : α} {fallback ¬a ∈ m → m.getKeyD a fallback = fallback := DHashMap.getKeyD_eq_fallback -theorem getKeyD_erase [EquivBEq α] [LawfulHashable α] {k a : α} {fallback : α} : +@[grind =] theorem getKeyD_erase [EquivBEq α] [LawfulHashable α] {k a : α} {fallback : α} : (m.erase k).getKeyD a fallback = if k == a then fallback else m.getKeyD a fallback := DHashMap.getKeyD_erase @@ -713,17 +717,17 @@ theorem getKeyD_eq_of_mem [LawfulBEq α] {k fallback : α} (h : k ∈ m) : m.getKeyD k fallback = k := DHashMap.getKeyD_eq_of_mem h -@[simp] +@[simp, grind =] theorem isEmpty_insertIfNew [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (m.insertIfNew k v).isEmpty = false := DHashMap.isEmpty_insertIfNew -@[simp] +@[simp, grind =] theorem contains_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : (m.insertIfNew k v).contains a = (k == a || m.contains a) := DHashMap.contains_insertIfNew -@[simp] +@[simp, grind =] theorem mem_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : a ∈ m.insertIfNew k v ↔ k == a ∨ a ∈ m := DHashMap.mem_insertIfNew @@ -756,7 +760,7 @@ theorem mem_of_mem_insertIfNew' [EquivBEq α] [LawfulHashable α] {k a : α} {v a ∈ m.insertIfNew k v → ¬((k == a) ∧ ¬k ∈ m) → a ∈ m := DHashMap.mem_of_mem_insertIfNew' -theorem size_insertIfNew [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : +@[grind =] theorem size_insertIfNew [EquivBEq α] [LawfulHashable α] {k : α} {v : β} : (m.insertIfNew k v).size = if k ∈ m then m.size else m.size + 1 := DHashMap.size_insertIfNew @@ -768,46 +772,46 @@ theorem size_insertIfNew_le [EquivBEq α] [LawfulHashable α] {k : α} {v : β} (m.insertIfNew k v).size ≤ m.size + 1 := DHashMap.size_insertIfNew_le -theorem getElem?_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : +@[grind =] theorem getElem?_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : (m.insertIfNew k v)[a]? = if k == a ∧ ¬k ∈ m then some v else m[a]? := DHashMap.Const.get?_insertIfNew -theorem getElem_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : +@[grind =] theorem getElem_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : (m.insertIfNew k v)[a]'h₁ = if h₂ : k == a ∧ ¬k ∈ m then v else m[a]'(mem_of_mem_insertIfNew' h₁ h₂) := DHashMap.Const.get_insertIfNew (h₁ := h₁) -theorem getElem!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : +@[grind =] theorem getElem!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited β] {k a : α} {v : β} : (m.insertIfNew k v)[a]! = if k == a ∧ ¬k ∈ m then v else m[a]! := DHashMap.Const.get!_insertIfNew -theorem getD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : +@[grind =] theorem getD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {fallback v : β} : (m.insertIfNew k v).getD a fallback = if k == a ∧ ¬k ∈ m then v else m.getD a fallback := DHashMap.Const.getD_insertIfNew -theorem getKey?_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : +@[grind =] theorem getKey?_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} : getKey? (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then some k else getKey? m a := DHashMap.getKey?_insertIfNew -theorem getKey_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : +@[grind =] theorem getKey_insertIfNew [EquivBEq α] [LawfulHashable α] {k a : α} {v : β} {h₁} : getKey (m.insertIfNew k v) a h₁ = if h₂ : k == a ∧ ¬k ∈ m then k else getKey m a (mem_of_mem_insertIfNew' h₁ h₂) := DHashMap.getKey_insertIfNew -theorem getKey!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β} : +@[grind =] theorem getKey!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited α] {k a : α} {v : β} : getKey! (m.insertIfNew k v) a = if k == a ∧ ¬k ∈ m then k else getKey! m a := DHashMap.getKey!_insertIfNew -theorem getKeyD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β} : +@[grind =] theorem getKeyD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a fallback : α} {v : β} : getKeyD (m.insertIfNew k v) a fallback = if k == a ∧ ¬k ∈ m then k else getKeyD m a fallback := DHashMap.getKeyD_insertIfNew -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_fst {k : α} {v : β} : (getThenInsertIfNew? m k v).1 = get? m k := DHashMap.Const.getThenInsertIfNew?_fst -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_snd {k : α} {v : β} : (getThenInsertIfNew? m k v).2 = m.insertIfNew k v := ext (DHashMap.Const.getThenInsertIfNew?_snd) @@ -821,22 +825,22 @@ instance [EquivBEq α] [LawfulHashable α] : LawfulGetElem (HashMap α β) α β rw [getElem!_eq_get!_getElem?] split <;> simp_all -@[simp] +@[simp, grind =] theorem length_keys [EquivBEq α] [LawfulHashable α] : m.keys.length = m.size := DHashMap.length_keys -@[simp] +@[simp, grind =] theorem isEmpty_keys [EquivBEq α] [LawfulHashable α]: m.keys.isEmpty = m.isEmpty := DHashMap.isEmpty_keys -@[simp] +@[simp, grind =] theorem contains_keys [EquivBEq α] [LawfulHashable α] {k : α} : m.keys.contains k = m.contains k := DHashMap.contains_keys -@[simp] +@[simp, grind =] theorem mem_keys [LawfulBEq α] [LawfulHashable α] {k : α} : k ∈ m.keys ↔ k ∈ m := DHashMap.mem_keys @@ -848,7 +852,7 @@ theorem distinct_keys [EquivBEq α] [LawfulHashable α] : m.keys.Pairwise (fun a b => (a == b) = false) := DHashMap.distinct_keys -@[simp] +@[simp, grind =] theorem map_fst_toList_eq_keys [EquivBEq α] [LawfulHashable α] : m.toList.map Prod.fst = m.keys := DHashMap.Const.map_fst_toList_eq_keys @@ -858,17 +862,17 @@ theorem map_prod_fst_toList_eq_keys [EquivBEq α] [LawfulHashable α] : m.toList.map Prod.fst = m.keys := DHashMap.Const.map_fst_toList_eq_keys -@[simp] +@[simp, grind =] theorem length_toList [EquivBEq α] [LawfulHashable α] : m.toList.length = m.size := DHashMap.Const.length_toList -@[simp] +@[simp, grind =] theorem isEmpty_toList [EquivBEq α] [LawfulHashable α] : m.toList.isEmpty = m.isEmpty := DHashMap.Const.isEmpty_toList -@[simp] +@[simp, grind =] theorem mem_toList_iff_getElem?_eq_some [LawfulBEq α] {k : α} {v : β} : (k, v) ∈ m.toList ↔ m[k]? = some v := @@ -923,7 +927,7 @@ theorem fold_eq_foldl_toList {f : δ → (a : α) → β → δ} {init : δ} : m.fold f init = m.toList.foldl (fun a b => f a b.1 b.2) init := DHashMap.Const.fold_eq_foldl_toList -@[simp] +@[simp, grind =] theorem forM_eq_forM [Monad m'] [LawfulMonad m'] {f : (a : α) → β → m' PUnit} : m.forM f = ForM.forM m (fun a => f a.1 a.2) := rfl @@ -931,7 +935,7 @@ theorem forM_eq_forM_toList [Monad m'] [LawfulMonad m'] {f : α × β → m' PUn ForM.forM m f = ForM.forM m.toList f := DHashMap.Const.forMUncurried_eq_forM_toList -@[simp] +@[simp, grind =] theorem forIn_eq_forIn [Monad m'] [LawfulMonad m'] {f : (a : α) → β → δ → m' (ForInStep δ)} {init : δ} : m.forIn f init = ForIn.forIn m init (fun a d => f a.1 a.2 d) := rfl @@ -963,20 +967,22 @@ end monadic variable {ρ : Type w} [ForIn Id ρ (α × β)] -@[simp] +@[simp, grind =] theorem insertMany_nil : insertMany m [] = m := ext DHashMap.Const.insertMany_nil -@[simp] +@[simp, grind =] theorem insertMany_list_singleton {k : α} {v : β} : insertMany m [⟨k, v⟩] = m.insert k v := ext DHashMap.Const.insertMany_list_singleton +@[grind _=_] theorem insertMany_cons {l : List (α × β)} {k : α} {v : β} : insertMany m (⟨k, v⟩ :: l) = insertMany (m.insert k v) l := ext DHashMap.Const.insertMany_cons +@[grind _=_] theorem insertMany_append {l₁ l₂ : List (α × β)} : insertMany m (l₁ ++ l₂) = insertMany (insertMany m l₁) l₂ := by induction l₁ generalizing m with @@ -991,13 +997,13 @@ theorem insertMany_ind {motive : HashMap α β → Prop} (m : HashMap α β) {l show motive ⟨DHashMap.Const.insertMany m.1 l⟩ from DHashMap.Const.insertMany_ind m.inner l init fun m => insert ⟨m⟩ -@[simp] +@[simp, grind =] theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : (insertMany m l).contains k = (m.contains k || (l.map Prod.fst).contains k) := DHashMap.Const.contains_insertMany_list -@[simp] +@[simp, grind =] theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : k ∈ insertMany m l ↔ k ∈ m ∨ (l.map Prod.fst).contains k := @@ -1025,6 +1031,7 @@ theorem getElem?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (insertMany m l)[k']? = some v := DHashMap.Const.get?_insertMany_list_of_mem k_beq distinct mem +@[grind =] theorem getElem?_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : (insertMany m l)[k]? = (l.findSomeRev? (fun ⟨a, b⟩ => if a == k then some b else none)).or m[k]? := @@ -1142,12 +1149,16 @@ theorem size_le_size_insertMany [EquivBEq α] [LawfulHashable α] {l : ρ} : m.size ≤ (insertMany m l).size := DHashMap.Const.size_le_size_insertMany +grind_pattern size_le_size_insertMany => (insertMany m l).size + theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] {l : List (α × β)} : (insertMany m l).size ≤ m.size + l.length := DHashMap.Const.size_insertMany_list_le -@[simp] +grind_pattern size_insertMany_list_le => (insertMany m l).size + +@[simp, grind =] theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List (α × β)} : (insertMany m l).isEmpty = (m.isEmpty && l.isEmpty) := @@ -1157,6 +1168,9 @@ theorem isEmpty_of_isEmpty_insertMany [EquivBEq α] [LawfulHashable α] {l : ρ} : (insertMany m l).isEmpty → m.isEmpty := DHashMap.Const.isEmpty_of_isEmpty_insertMany +-- As `insertManyIfNewUnit` is really an implementation detail for `HashSet.insertMany`, +-- we do not add `@[grind]` annotations to any of its lemmas. + variable {m : HashMap α Unit} variable {ρ : Type w} [ForIn Id ρ α] @@ -1329,17 +1343,17 @@ end section -@[simp] +@[simp, grind =] theorem ofList_nil : ofList ([] : List (α × β)) = ∅ := ext DHashMap.Const.ofList_nil -@[simp] +@[simp, grind =] theorem ofList_singleton {k : α} {v : β} : ofList [⟨k, v⟩] = (∅ : HashMap α β).insert k v := ext DHashMap.Const.ofList_singleton -theorem ofList_cons {k : α} {v : β} {tl : List (α × β)} : +@[grind _=_] theorem ofList_cons {k : α} {v : β} {tl : List (α × β)} : ofList (⟨k, v⟩ :: tl) = insertMany ((∅ : HashMap α β).insert k v) tl := ext DHashMap.Const.ofList_cons @@ -1347,13 +1361,13 @@ theorem ofList_eq_insertMany_empty {l : List (α × β)} : ofList l = insertMany (∅ : HashMap α β) l := ext DHashMap.Const.ofList_eq_insertMany_empty -@[simp] +@[simp, grind =] theorem contains_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : (ofList l).contains k = (l.map Prod.fst).contains k := DHashMap.Const.contains_ofList -@[simp] +@[simp, grind =] theorem mem_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : k ∈ ofList l ↔ (l.map Prod.fst).contains k := @@ -1467,12 +1481,17 @@ theorem size_ofList_le [EquivBEq α] [LawfulHashable α] (ofList l).size ≤ l.length := DHashMap.Const.size_ofList_le -@[simp] +grind_pattern size_ofList_le => (ofList l).size + +@[simp, grind =] theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} : (ofList l).isEmpty = l.isEmpty := DHashMap.Const.isEmpty_ofList +-- As `unitOfList` is an implementation detail for `HashSet.ofList`, +-- we don't add `@[grind]` annotations. + @[simp] theorem unitOfList_nil : unitOfList ([] : List α) = ∅ := @@ -1598,15 +1617,17 @@ theorem isEmpty_alter_eq_isEmpty_erase [EquivBEq α] [LawfulHashable α] {k : α (alter m k f).isEmpty = ((m.erase k).isEmpty && (f m[k]?).isNone) := DHashMap.Const.isEmpty_alter_eq_isEmpty_erase -@[simp] +@[simp, grind =] theorem isEmpty_alter [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β → Option β} : (alter m k f).isEmpty = ((m.isEmpty || (m.size == 1 && m.contains k)) && (f m[k]?).isNone) := DHashMap.Const.isEmpty_alter +@[grind =] theorem contains_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} : (alter m k f).contains k' = if k == k' then (f m[k]?).isSome else m.contains k' := DHashMap.Const.contains_alter +@[grind =] theorem mem_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} : k' ∈ alter m k f ↔ if k == k' then (f m[k]?).isSome = true else k' ∈ m := DHashMap.Const.mem_alter @@ -1634,6 +1655,7 @@ theorem mem_alter_of_beq_eq_false [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} (h : (k == k') = false) : k' ∈ alter m k f ↔ k' ∈ m := DHashMap.Const.mem_alter_of_beq_eq_false h +@[grind =] theorem size_alter [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β → Option β} : (m.alter k f).size = if k ∈ m ∧ (f m[k]?).isNone then @@ -1672,6 +1694,7 @@ theorem size_le_size_alter [EquivBEq α] [LawfulHashable α] {k : α} {f : Optio m.size - 1 ≤ (alter m k f).size := DHashMap.Const.size_le_size_alter +@[grind =] theorem getElem?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} : (alter m k f)[k']? = if k == k' then @@ -1699,6 +1722,7 @@ theorem get?_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Option get? (alter m k f) k = f (get? m k) := DHashMap.Const.get?_alter_self +@[grind =] theorem getElem_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} {h : k' ∈ alter m k f} : (alter m k f)[k'] = @@ -1736,6 +1760,7 @@ theorem get_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β get (alter m k f) k h = (f (get? m k)).get h' := DHashMap.Const.get_alter_self +@[grind =] theorem getElem!_alter [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] {f : Option β → Option β} : (alter m k f)[k']! = if k == k' then @@ -1763,6 +1788,7 @@ theorem get!_alter_self [EquivBEq α] [LawfulHashable α] {k : α} [Inhabited β {f : Option β → Option β} : get! (alter m k f) k = (f (get? m k)).get! := DHashMap.Const.get!_alter_self +@[grind =] theorem getD_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} {f : Option β → Option β} : getD (alter m k f) k' fallback = @@ -1778,6 +1804,7 @@ theorem getD_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {fallback : getD (alter m k f) k fallback = (f m[k]?).getD fallback := DHashMap.Const.getD_alter_self +@[grind =] theorem getKey?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} : (alter m k f).getKey? k' = if k == k' then @@ -1790,6 +1817,7 @@ theorem getKey?_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Optio (alter m k f).getKey? k = if (f m[k]?).isSome then some k else none := DHashMap.Const.getKey?_alter_self +@[grind =] theorem getKey!_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : Option β → Option β} : (alter m k f).getKey! k' = if k == k' then @@ -1803,6 +1831,7 @@ theorem getKey!_alter_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : (alter m k f).getKey! k = if (f m[k]?).isSome then k else default := DHashMap.Const.getKey!_alter_self +@[grind =] theorem getKey_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : Option β → Option β} {h : k' ∈ alter m k f} : (alter m k f).getKey k' h = @@ -1819,6 +1848,7 @@ theorem getKey_alter_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : (alter m k f).getKey k h = k := DHashMap.Const.getKey_alter_self +@[grind =] theorem getKeyD_alter [EquivBEq α] [LawfulHashable α] {k k' fallback : α} {f : Option β → Option β} : (alter m k f).getKeyD k' fallback = @@ -1839,26 +1869,27 @@ section Modify variable {m : HashMap α β} -@[simp] +@[simp, grind =] theorem isEmpty_modify [EquivBEq α] [LawfulHashable α] {k : α} {f : β → β} : (modify m k f).isEmpty = m.isEmpty := DHashMap.Const.isEmpty_modify -@[simp] +@[simp, grind =] theorem contains_modify [EquivBEq α] [LawfulHashable α] {k k': α} {f : β → β} : (modify m k f).contains k' = m.contains k' := DHashMap.Const.contains_modify -@[simp] +@[simp, grind =] theorem mem_modify [EquivBEq α] [LawfulHashable α] {k k': α} {f : β → β} : k' ∈ modify m k f ↔ k' ∈ m := DHashMap.Const.mem_modify -@[simp] +@[simp, grind =] theorem size_modify [EquivBEq α] [LawfulHashable α] {k : α} {f : β → β} : (modify m k f).size = m.size := DHashMap.Const.size_modify +@[grind =] theorem getElem?_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} : (modify m k f)[k']? = if k == k' then @@ -1886,6 +1917,7 @@ theorem get?_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β → get? (modify m k f) k = (get? m k).map f := DHashMap.Const.get?_modify_self +@[grind =] theorem getElem_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} {h : k' ∈ modify m k f} : (modify m k f)[k'] = @@ -1923,6 +1955,7 @@ theorem get_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β → get (modify m k f) k h = f (get m k h') := DHashMap.Const.get_modify_self +@[grind =] theorem getElem!_modify [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] {f : β → β} : (modify m k f)[k']! = if k == k' then @@ -1950,6 +1983,7 @@ theorem get!_modify_self [EquivBEq α] [LawfulHashable α] {k : α} [Inhabited get! (modify m k f) k = ((get? m k).map f).get! := DHashMap.Const.get!_modify_self +@[grind =] theorem getD_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} {f : β → β} : getD (modify m k f) k' fallback = if k == k' then @@ -1963,6 +1997,7 @@ theorem getD_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {fallback : getD (modify m k f) k fallback = (m[k]?.map f).getD fallback := DHashMap.Const.getD_modify_self +@[grind =] theorem getKey?_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} : (modify m k f).getKey? k' = if k == k' then @@ -1975,6 +2010,7 @@ theorem getKey?_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β (modify m k f).getKey? k = if k ∈ m then some k else none := DHashMap.Const.getKey?_modify_self +@[grind =] theorem getKey!_modify [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : β → β} : (modify m k f).getKey! k' = if k == k' then @@ -1987,6 +2023,7 @@ theorem getKey!_modify_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k (modify m k f).getKey! k = if k ∈ m then k else default := DHashMap.Const.getKey!_modify_self +@[grind =] theorem getKey_modify [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : β → β} {h : k' ∈ modify m k f} : (modify m k f).getKey k' h = @@ -2002,6 +2039,7 @@ theorem getKey_modify_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : {h : k ∈ modify m k f} : (modify m k f).getKey k h = k := DHashMap.Const.getKey_modify_self +@[grind =] theorem getKeyD_modify [EquivBEq α] [LawfulHashable α] {k k' fallback : α} {f : β → β} : (modify m k f).getKeyD k' fallback = if k == k' then @@ -2208,6 +2246,7 @@ theorem toList_filterMap {f : (a : α) → β → Option γ} : (m.toList.filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x)))) := DHashMap.Const.toList_filterMap +@[grind =] theorem isEmpty_filterMap_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} : (m.filterMap f).isEmpty ↔ ∀ k h, f (m.getKey k h) m[k] = none := @@ -2218,6 +2257,9 @@ theorem isEmpty_filterMap_eq_false_iff [EquivBEq α] [LawfulHashable α] (m.filterMap f).isEmpty = false ↔ ∃ k h, (f (m.getKey k h) m[k]).isSome := DHashMap.Const.isEmpty_filterMap_eq_false_iff +-- TODO: `contains_filterMap` is missing + +@[grind =] theorem mem_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} : k ∈ m.filterMap f ↔ ∃ h, (f (m.getKey k h) m[k]).isSome := @@ -2238,11 +2280,14 @@ theorem size_filterMap_le_size [EquivBEq α] [LawfulHashable α] (m.filterMap f).size ≤ m.size := DHashMap.size_filterMap_le_size +grind_pattern size_filterMap_le_size => (m.filterMap f).size + theorem size_filterMap_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} : (m.filterMap f).size = m.size ↔ ∀ k h, (f (m.getKey k h) m[k]).isSome := DHashMap.Const.size_filterMap_eq_size_iff +@[grind =] theorem getElem?_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} : (m.filterMap f)[k]? = m[k]?.pbind (fun x h' => @@ -2261,7 +2306,7 @@ theorem isSome_apply_of_mem_filterMap [EquivBEq α] [LawfulHashable α] (m[k]'(mem_of_mem_filterMap h))).isSome := DHashMap.Const.isSome_apply_of_mem_filterMap -@[simp] +@[simp, grind =] theorem getElem_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} {h} : (m.filterMap f)[k]'h = @@ -2270,6 +2315,7 @@ theorem getElem_filterMap [EquivBEq α] [LawfulHashable α] (isSome_apply_of_mem_filterMap h) := DHashMap.Const.get_filterMap +@[grind =] theorem getElem!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited γ] {f : α → β → Option γ} {k : α} : (m.filterMap f)[k]! = @@ -2282,6 +2328,7 @@ theorem getElem!_filterMap_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] (m.filterMap f)[k]! = (m[k]?.bind (f k')).get! := DHashMap.Const.get!_filterMap_of_getKey?_eq_some h +@[grind =] theorem getD_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} {fallback : γ} : (m.filterMap f).getD k fallback = @@ -2294,6 +2341,7 @@ theorem getD_filterMap_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] (m.filterMap f).getD k fallback = (m[k]?.bind (f k')).getD fallback := DHashMap.Const.getD_filterMap_of_getKey?_eq_some h +@[grind =] theorem getKey?_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} : (m.filterMap f).getKey? k = @@ -2301,12 +2349,13 @@ theorem getKey?_filterMap [EquivBEq α] [LawfulHashable α] (f x (m[x]'(mem_of_getKey?_eq_some h'))).isSome) := DHashMap.Const.getKey?_filterMap -@[simp] +@[simp, grind =] theorem getKey_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} {h'} : (m.filterMap f).getKey k h' = m.getKey k (mem_of_mem_filterMap h') := DHashMap.getKey_filterMap +@[grind =] theorem getKey!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → Option γ} {k : α} : (m.filterMap f).getKey! k = @@ -2314,6 +2363,7 @@ theorem getKey!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited α] (f x (m[x]'(mem_of_getKey?_eq_some h'))).isSome)).get! := DHashMap.Const.getKey!_filterMap +@[grind =] theorem getKeyD_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k fallback : α} : (m.filterMap f).getKeyD k fallback = @@ -2339,6 +2389,7 @@ theorem keys_filter_key {f : α → Bool} : (m.filter fun k _ => f k).keys.Perm (m.keys.filter f) := DHashMap.keys_filter_key +@[grind =] theorem isEmpty_filter_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} : (m.filter f).isEmpty = true ↔ @@ -2351,6 +2402,9 @@ theorem isEmpty_filter_eq_false_iff [EquivBEq α] [LawfulHashable α] ∃ (k : α) (h : k ∈ m), f (m.getKey k h) m[k] = true := DHashMap.Const.isEmpty_filter_eq_false_iff +-- TODO: `contains_filter` is missing + +@[grind =] theorem mem_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} : k ∈ m.filter f ↔ ∃ (h' : k ∈ m), f (m.getKey k h') m[k] := @@ -2371,6 +2425,8 @@ theorem size_filter_le_size [EquivBEq α] [LawfulHashable α] (m.filter f).size ≤ m.size := DHashMap.size_filter_le_size +grind_pattern size_filter_le_size => (m.filter f).size + theorem size_filter_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} : (m.filter f).size = m.size ↔ ∀ k h, f (m.getKey k h) (m.get k h) := @@ -2382,6 +2438,7 @@ theorem filter_equiv_self_iff [EquivBEq α] [LawfulHashable α] ⟨fun h => DHashMap.Const.filter_equiv_self_iff.mp h.1, fun h => ⟨DHashMap.Const.filter_equiv_self_iff.mpr h⟩⟩ +@[grind =] theorem getElem?_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} : (m.filter f)[k]? = m[k]?.pfilter (fun x h' => @@ -2394,12 +2451,13 @@ theorem getElem?_filter_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] (m.filter f)[k]? = m[k]?.filter (fun x => f k' x) := DHashMap.Const.get?_filter_of_getKey?_eq_some -@[simp] +@[simp, grind =] theorem getElem_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} {h'} : (m.filter f)[k]'(h') = m[k]'(mem_of_mem_filter h') := DHashMap.Const.get_filter +@[grind =] theorem getElem!_filter [EquivBEq α] [LawfulHashable α] [Inhabited β] {f : α → β → Bool} {k : α} : (m.filter f)[k]! = @@ -2413,6 +2471,7 @@ theorem getElem!_filter_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [In (m.filter f)[k]! = (m[k]?.filter (f k')).get! := DHashMap.Const.get!_filter_of_getKey?_eq_some +@[grind =] theorem getD_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} {fallback : β} : (m.filter f).getD k fallback = (m[k]?.pfilter (fun x h' => @@ -2431,6 +2490,7 @@ theorem keys_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} : (m.keys.attach.filter (fun ⟨x, h'⟩ => f x (get m x (mem_of_mem_keys h')))).unattach := DHashMap.Const.keys_filter +@[grind =] theorem getKey?_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} : (m.filter f).getKey? k = @@ -2443,12 +2503,13 @@ theorem getKey?_filter_key [EquivBEq α] [LawfulHashable α] (m.filter fun k _ => f k).getKey? k = (m.getKey? k).filter f := DHashMap.getKey?_filter_key -@[simp] +@[simp, grind =] theorem getKey_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} {h'} : (m.filter f).getKey k h' = m.getKey k (mem_of_mem_filter h') := DHashMap.getKey_filter +@[grind =] theorem getKey!_filter [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → Bool} {k : α} : (m.filter f).getKey! k = @@ -2461,6 +2522,7 @@ theorem getKey!_filter_key [EquivBEq α] [LawfulHashable α] [Inhabited α] (m.filter fun k _ => f k).getKey! k = ((m.getKey? k).filter f).get! := DHashMap.getKey!_filter_key +@[grind =] theorem getKeyD_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k fallback : α} : (m.filter f).getKeyD k fallback = @@ -2498,13 +2560,13 @@ theorem filterMap_equiv_map [EquivBEq α] [LawfulHashable α] (m.filterMap (fun k v => some (f k v))) ~m m.map f := ⟨DHashMap.filterMap_equiv_map⟩ -@[simp] +@[simp, grind =] theorem isEmpty_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} : (m.map f).isEmpty = m.isEmpty := DHashMap.isEmpty_map -@[simp] +@[simp, grind =] theorem contains_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} : (m.map f).contains k = m.contains k := @@ -2515,7 +2577,7 @@ theorem contains_of_contains_map [EquivBEq α] [LawfulHashable α] (m.map f).contains k = true → m.contains k = true := DHashMap.contains_of_contains_map -@[simp] +@[simp, grind =] theorem mem_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} : k ∈ m.map f ↔ k ∈ m := by @@ -2526,13 +2588,13 @@ theorem mem_of_mem_map [EquivBEq α] [LawfulHashable α] k ∈ m.map f → k ∈ m := DHashMap.contains_of_contains_map -@[simp] +@[simp, grind =] theorem size_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} : (m.map f).size = m.size := DHashMap.size_map -@[simp] +@[simp, grind =] theorem getElem?_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} : (m.map f)[k]? = m[k]?.map (f k) := @@ -2551,7 +2613,7 @@ theorem getElem?_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] (m.map f)[k]? = m[k]?.map (f k') := DHashMap.Const.get?_map_of_getKey?_eq_some h -@[simp] +@[simp, grind =] theorem getElem_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} {h'} : (m.map f)[k]'(h') = @@ -2566,6 +2628,7 @@ theorem getElem_map' [EquivBEq α] [LawfulHashable α] f (m.getKey k (mem_of_mem_map h')) (m[k]'(mem_of_mem_map h')) := DHashMap.Const.get_map' +@[grind =] theorem getElem!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ] {f : α → β → γ} {k : α} : (m.map f)[k]! = @@ -2585,6 +2648,7 @@ theorem getElem!_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhab (m.map f)[k]! = (m[k]?.map (f k')).get! := DHashMap.Const.get!_map_of_getKey?_eq_some h +@[grind =] theorem getD_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} {fallback : γ} : (m.map f).getD k fallback = @@ -2604,25 +2668,25 @@ theorem getD_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhabited (m.map f).getD k fallback = (m[k]?.map (f k')).getD fallback := DHashMap.Const.getD_map_of_getKey?_eq_some h -@[simp] +@[simp, grind =] theorem getKey?_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} : (m.map f).getKey? k = m.getKey? k := DHashMap.getKey?_map -@[simp] +@[simp, grind =] theorem getKey_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} {h'} : (m.map f).getKey k h' = m.getKey k (mem_of_mem_map h') := DHashMap.getKey_map -@[simp] +@[simp, grind =] theorem getKey!_map [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → γ} {k : α} : (m.map f).getKey! k = m.getKey! k := DHashMap.getKey!_map -@[simp] +@[simp, grind =] theorem getKeyD_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} {k fallback : α} : (m.map f).getKeyD k fallback = m.getKeyD k fallback := diff --git a/src/Std/Data/HashMap/RawLemmas.lean b/src/Std/Data/HashMap/RawLemmas.lean index 13ba53cc20..7f98e8ca25 100644 --- a/src/Std/Data/HashMap/RawLemmas.lean +++ b/src/Std/Data/HashMap/RawLemmas.lean @@ -15,6 +15,8 @@ This module contains lemmas about `Std.Data.HashMap.Raw`. Most of the lemmas req is to provide an instance of `LawfulBEq α`. -/ +set_option trace.grind.ematch.pattern true + set_option linter.missingDocs true set_option autoImplicit false @@ -28,11 +30,11 @@ namespace Raw variable {m : Raw α β} -@[simp] +@[simp, grind =] theorem size_emptyWithCapacity {c} : (emptyWithCapacity c : Raw α β).size = 0 := DHashMap.Raw.size_emptyWithCapacity -@[simp] +@[simp, grind =] theorem size_empty : (∅ : Raw α β).size = 0 := DHashMap.Raw.size_empty @@ -48,11 +50,11 @@ private theorem ext {m m' : Raw α β} : m.inner = m'.inner → m = m' := by variable [BEq α] [Hashable α] -@[simp] +@[simp, grind =] theorem isEmpty_emptyWithCapacity {c} : (emptyWithCapacity c : Raw α β).isEmpty := DHashMap.Raw.isEmpty_emptyWithCapacity -@[simp] +@[simp, grind =] theorem isEmpty_empty : (∅ : Raw α β).isEmpty := DHashMap.Raw.isEmpty_empty @@ -60,7 +62,7 @@ set_option linter.missingDocs false in @[deprecated isEmpty_empty (since := "2025-03-12")] abbrev isEmpty_emptyc := @isEmpty_empty -@[simp] +@[simp, grind =] theorem isEmpty_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v : β} : (m.insert k v).isEmpty = false := DHashMap.Raw.isEmpty_insert h.out @@ -80,13 +82,14 @@ theorem mem_congr [EquivBEq α] [LawfulHashable α] (h : m.WF) {a b : α} (hab : a ∈ m ↔ b ∈ m := DHashMap.Raw.mem_congr h.out hab -@[simp] theorem contains_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : Raw α β).contains a = false := +@[simp, grind =] +theorem contains_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : Raw α β).contains a = false := DHashMap.Raw.contains_emptyWithCapacity -@[simp] theorem not_mem_emptyWithCapacity {a : α} {c} : ¬a ∈ (emptyWithCapacity c : Raw α β) := +@[simp, grind] theorem not_mem_emptyWithCapacity {a : α} {c} : ¬a ∈ (emptyWithCapacity c : Raw α β) := DHashMap.Raw.not_mem_emptyWithCapacity -@[simp] theorem contains_empty {a : α} : (∅ : Raw α β).contains a = false := +@[simp, grind =] theorem contains_empty {a : α} : (∅ : Raw α β).contains a = false := DHashMap.Raw.contains_empty set_option linter.missingDocs false in @@ -130,12 +133,12 @@ theorem isEmpty_iff_forall_not_mem [EquivBEq α] [LawfulHashable α] (h : m.WF) Singleton.singleton p = (∅ : Raw α β).insert p.1 p.2 := rfl -@[simp] +@[simp, grind =] theorem contains_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : (m.insert k v).contains a = (k == a || m.contains a) := DHashMap.Raw.contains_insert h.out -@[simp] +@[simp, grind =] theorem mem_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : a ∈ m.insert k v ↔ k == a ∨ a ∈ m := DHashMap.Raw.mem_insert h.out @@ -158,7 +161,7 @@ theorem mem_insert_self [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v k ∈ m.insert k v := DHashMap.Raw.mem_insert_self h.out -theorem size_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v : β} : +@[grind =] theorem size_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v : β} : (m.insert k v).size = if k ∈ m then m.size else m.size + 1 := DHashMap.Raw.size_insert h.out @@ -170,11 +173,11 @@ theorem size_insert_le [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v (m.insert k v).size ≤ m.size + 1 := DHashMap.Raw.size_insert_le h.out -@[simp] +@[simp, grind =] theorem erase_emptyWithCapacity {k : α} {c : Nat} : (emptyWithCapacity c : Raw α β).erase k = emptyWithCapacity c := ext DHashMap.Raw.erase_emptyWithCapacity -@[simp] +@[simp, grind =] theorem erase_empty {k : α} : (∅ : Raw α β).erase k = ∅ := ext DHashMap.Raw.erase_empty @@ -182,17 +185,17 @@ set_option linter.missingDocs false in @[deprecated erase_empty (since := "2025-03-12")] abbrev erase_emptyc := @erase_empty -@[simp] +@[simp, grind =] theorem isEmpty_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} : (m.erase k).isEmpty = (m.isEmpty || (m.size == 1 && m.contains k)) := DHashMap.Raw.isEmpty_erase h.out -@[simp] +@[simp, grind =] theorem contains_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : (m.erase k).contains a = (!(k == a) && m.contains a) := DHashMap.Raw.contains_erase h.out -@[simp] +@[simp, grind =] theorem mem_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : a ∈ m.erase k ↔ (k == a) = false ∧ a ∈ m := DHashMap.Raw.mem_erase h.out @@ -205,7 +208,7 @@ theorem mem_of_mem_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} a ∈ m.erase k → a ∈ m := DHashMap.Raw.mem_of_mem_erase h.out -theorem size_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} : +@[grind =] theorem size_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} : (m.erase k).size = if k ∈ m then m.size - 1 else m.size := DHashMap.Raw.size_erase h.out @@ -217,31 +220,31 @@ theorem size_le_size_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} m.size ≤ (m.erase k).size + 1 := DHashMap.Raw.size_le_size_erase h.out -@[simp] +@[simp, grind =] theorem containsThenInsert_fst (h : m.WF) {k : α} {v : β} : (m.containsThenInsert k v).1 = m.contains k := DHashMap.Raw.containsThenInsert_fst h.out -@[simp] +@[simp, grind =] theorem containsThenInsert_snd (h : m.WF) {k : α} {v : β} : (m.containsThenInsert k v).2 = m.insert k v := ext (DHashMap.Raw.containsThenInsert_snd h.out) -@[simp] +@[simp, grind =] theorem containsThenInsertIfNew_fst (h : m.WF) {k : α} {v : β} : (m.containsThenInsertIfNew k v).1 = m.contains k := DHashMap.Raw.containsThenInsertIfNew_fst h.out -@[simp] +@[simp, grind =] theorem containsThenInsertIfNew_snd (h : m.WF) {k : α} {v : β} : (m.containsThenInsertIfNew k v).2 = m.insertIfNew k v := ext (DHashMap.Raw.containsThenInsertIfNew_snd h.out) -@[simp] theorem get_eq_getElem {a : α} {h} : get m a h = m[a]'h := rfl -@[simp] theorem get?_eq_getElem? {a : α} : get? m a = m[a]? := rfl -@[simp] theorem get!_eq_getElem! [Inhabited β] {a : α} : get! m a = m[a]! := rfl +@[simp, grind =] theorem get_eq_getElem {a : α} {h} : get m a h = m[a]'h := rfl +@[simp, grind =] theorem get?_eq_getElem? {a : α} : get? m a = m[a]? := rfl +@[simp, grind =] theorem get!_eq_getElem! [Inhabited β] {a : α} : get! m a = m[a]! := rfl -@[simp] +@[simp, grind =] theorem getElem?_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : Raw α β)[a]? = none := DHashMap.Raw.Const.get?_emptyWithCapacity @@ -265,7 +268,7 @@ theorem getElem?_of_isEmpty [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α m.isEmpty = true → m[a]? = none := DHashMap.Raw.Const.get?_of_isEmpty h.out -theorem getElem?_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : +@[grind =] theorem getElem?_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : (m.insert k v)[a]? = if k == a then some v else m[a]? := DHashMap.Raw.Const.get?_insert h.out @@ -300,7 +303,7 @@ theorem getElem?_eq_none [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} : ¬a ∈ m → m[a]? = none := DHashMap.Raw.Const.get?_eq_none h.out -theorem getElem?_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : +@[grind =] theorem getElem?_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : (m.erase k)[a]? = if k == a then none else m[a]? := DHashMap.Raw.Const.get?_erase h.out @@ -313,7 +316,7 @@ theorem getElem?_congr [EquivBEq α] [LawfulHashable α] (h : m.WF) {a b : α} ( m[a]? = m[b]? := DHashMap.Raw.Const.get?_congr h.out hab -theorem getElem_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} {h₁} : +@[grind =] theorem getElem_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} {h₁} : (m.insert k v)[a]'h₁ = if h₂ : k == a then v else m[a]'(mem_of_mem_insert h h₁ (Bool.eq_false_iff.2 h₂)) := DHashMap.Raw.Const.get_insert (h₁ := h₁) h.out @@ -323,7 +326,7 @@ theorem getElem_insert_self [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α (m.insert k v)[k]'(mem_insert_self h) = v := DHashMap.Raw.Const.get_insert_self h.out -@[simp] +@[simp, grind =] theorem getElem_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {h'} : (m.erase k)[a]'h' = m[a]'(mem_of_mem_erase h h') := DHashMap.Raw.Const.get_erase (h' := h') h.out @@ -336,7 +339,7 @@ theorem getElem_eq_get_getElem? [EquivBEq α] [LawfulHashable α] (h : m.WF) {a m[a]'(h') = m[a]?.get ((mem_iff_isSome_getElem? h).mp h') := DHashMap.Raw.Const.get_eq_get_get? h.out (h' := h') -theorem get_getElem? [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} {h'} : +@[grind =] theorem get_getElem? [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} {h'} : m[a]?.get h' = m[a]'((mem_iff_isSome_getElem? h).mpr h') := DHashMap.Raw.Const.get_get? h.out @@ -344,11 +347,11 @@ theorem getElem_congr [EquivBEq α] [LawfulHashable α] (h : m.WF) {a b : α} (h m[a]'h' = m[b]'((mem_congr h hab).1 h') := DHashMap.Raw.Const.get_congr h.out hab (h' := h') -@[simp] +@[simp, grind =] theorem getElem!_emptyWithCapacity [Inhabited β] {a : α} {c} : (emptyWithCapacity c : Raw α β)[a]! = default := DHashMap.Raw.Const.get!_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getElem!_empty [Inhabited β] {a : α} : (∅ : Raw α β)[a]! = default := DHashMap.Raw.Const.get!_empty @@ -360,7 +363,7 @@ theorem getElem!_of_isEmpty [EquivBEq α] [LawfulHashable α] [Inhabited β] (h m.isEmpty = true → m[a]! = default := DHashMap.Raw.Const.get!_of_isEmpty h.out -theorem getElem!_insert [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.WF) {k a : α} {v : β} : +@[grind =] theorem getElem!_insert [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.WF) {k a : α} {v : β} : (m.insert k v)[a]! = if k == a then v else m[a]! := DHashMap.Raw.Const.get!_insert h.out @@ -377,7 +380,7 @@ theorem getElem!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited β] (h ¬a ∈ m → m[a]! = default := DHashMap.Raw.Const.get!_eq_default h.out -theorem getElem!_erase [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.WF) {k a : α} : +@[grind =] theorem getElem!_erase [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.WF) {k a : α} : (m.erase k)[a]! = if k == a then default else m[a]! := DHashMap.Raw.Const.get!_erase h.out @@ -406,11 +409,11 @@ theorem getElem!_congr [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.W (hab : a == b) : m[a]! = m[b]! := DHashMap.Raw.Const.get!_congr h.out hab -@[simp] +@[simp, grind =] theorem getD_emptyWithCapacity {a : α} {fallback : β} {c} : (emptyWithCapacity c : Raw α β).getD a fallback = fallback := DHashMap.Raw.Const.getD_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getD_empty {a : α} {fallback : β} : (∅ : Raw α β).getD a fallback = fallback := DHashMap.Raw.Const.getD_empty @@ -422,7 +425,7 @@ theorem getD_of_isEmpty [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} {f m.isEmpty = true → m.getD a fallback = fallback := DHashMap.Raw.Const.getD_of_isEmpty h.out -theorem getD_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {fallback v : β} : +@[grind =] theorem getD_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {fallback v : β} : (m.insert k v).getD a fallback = if k == a then v else m.getD a fallback := DHashMap.Raw.Const.getD_insert h.out @@ -439,7 +442,7 @@ theorem getD_eq_fallback [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} { ¬a ∈ m → m.getD a fallback = fallback := DHashMap.Raw.Const.getD_eq_fallback h.out -theorem getD_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {fallback : β} : +@[grind =] theorem getD_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {fallback : β} : (m.erase k).getD a fallback = if k == a then fallback else m.getD a fallback := DHashMap.Raw.Const.getD_erase h.out @@ -472,11 +475,11 @@ theorem getD_congr [EquivBEq α] [LawfulHashable α] (h : m.WF) {a b : α} {fall (hab : a == b) : m.getD a fallback = m.getD b fallback := DHashMap.Raw.Const.getD_congr h.out hab -@[simp] +@[simp, grind =] theorem getKey?_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : Raw α β).getKey? a = none := DHashMap.Raw.getKey?_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getKey?_empty {a : α} : (∅ : Raw α β).getKey? a = none := DHashMap.Raw.getKey?_empty @@ -488,7 +491,7 @@ theorem getKey?_of_isEmpty [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} m.isEmpty = true → m.getKey? a = none := DHashMap.Raw.getKey?_of_isEmpty h.out -theorem getKey?_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : +@[grind =] theorem getKey?_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : (m.insert k v).getKey? a = if k == a then some k else m.getKey? a := DHashMap.Raw.getKey?_insert h.out @@ -514,7 +517,7 @@ theorem getKey?_eq_none [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} : ¬a ∈ m → m.getKey? a = none := DHashMap.Raw.getKey?_eq_none h.out -theorem getKey?_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : +@[grind =] theorem getKey?_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : (m.erase k).getKey? a = if k == a then none else m.getKey? a := DHashMap.Raw.getKey?_erase h.out @@ -538,7 +541,7 @@ theorem getKey?_eq_some_of_contains [LawfulBEq α] (h : m.WF) {k : α} (h' : m.c theorem getKey?_eq_some [LawfulBEq α] (h : m.WF) {k : α} (h' : k ∈ m) : m.getKey? k = some k := DHashMap.Raw.getKey?_eq_some h.out h' -theorem getKey_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} {h₁} : +@[grind =] theorem getKey_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} {h₁} : (m.insert k v).getKey a h₁ = if h₂ : k == a then k else m.getKey a (mem_of_mem_insert h h₁ (Bool.eq_false_iff.2 h₂)) := DHashMap.Raw.getKey_insert (h₁ := h₁) h.out @@ -562,7 +565,7 @@ theorem mem_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] m.getKey? a = some a' → a' ∈ m := DHashMap.Raw.mem_of_getKey?_eq_some h.out -@[simp] +@[simp, grind =] theorem getKey_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {h'} : (m.erase k).getKey a h' = m.getKey a (mem_of_mem_erase h h') := DHashMap.Raw.getKey_erase (h' := h') h.out @@ -575,7 +578,7 @@ theorem getKey_eq_get_getKey? [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : m.getKey a h' = (m.getKey? a).get ((mem_iff_isSome_getKey? h).mp h') := DHashMap.Raw.getKey_eq_get_getKey? h.out -@[simp] +@[simp, grind =] theorem get_getKey? [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} {h'} : (m.getKey? a).get h' = m.getKey a ((mem_iff_isSome_getKey? h).mpr h') := DHashMap.Raw.get_getKey? h.out @@ -589,16 +592,16 @@ theorem getKey_congr [EquivBEq α] [LawfulHashable α] (h : m.WF) {k₁ k₂ : m.getKey k₁ h₁ = m.getKey k₂ ((mem_congr h h').mp h₁) := DHashMap.Raw.getKey_congr h.out h' h₁ -@[simp] +@[simp, grind =] theorem getKey_eq [LawfulBEq α] (h : m.WF) {k : α} (h' : k ∈ m) : m.getKey k h' = k := DHashMap.Raw.getKey_eq h.out h' -@[simp] +@[simp, grind =] theorem getKey!_emptyWithCapacity [Inhabited α] {a : α} {c} : (emptyWithCapacity c : Raw α β).getKey! a = default := DHashMap.Raw.getKey!_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getKey!_empty [Inhabited α] {a : α} : (∅ : Raw α β).getKey! a = default := DHashMap.Raw.getKey!_empty @@ -610,7 +613,7 @@ theorem getKey!_of_isEmpty [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.isEmpty = true → m.getKey! a = default := DHashMap.Raw.getKey!_of_isEmpty h.out -theorem getKey!_insert [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {k a : α} {v : β} : +@[grind =] theorem getKey!_insert [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {k a : α} {v : β} : (m.insert k v).getKey! a = if k == a then k else m.getKey! a := DHashMap.Raw.getKey!_insert h.out @@ -627,7 +630,7 @@ theorem getKey!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : ¬a ∈ m → m.getKey! a = default := DHashMap.Raw.getKey!_eq_default h.out -theorem getKey!_erase [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {k a : α} : +@[grind =] theorem getKey!_erase [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {k a : α} : (m.erase k).getKey! a = if k == a then default else m.getKey! a := DHashMap.Raw.getKey!_erase h.out @@ -664,12 +667,12 @@ theorem getKey!_eq_of_mem [LawfulBEq α] [Inhabited α] (h : m.WF) {k : α} (h' m.getKey! k = k := DHashMap.Raw.getKey!_eq_of_mem h.out h' -@[simp] +@[simp, grind =] theorem getKeyD_emptyWithCapacity {a fallback : α} {c} : (emptyWithCapacity c : Raw α β).getKeyD a fallback = fallback := DHashMap.Raw.getKeyD_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getKeyD_empty {a fallback : α} : (∅ : Raw α β).getKeyD a fallback = fallback := DHashMap.Raw.getKeyD_empty @@ -681,7 +684,7 @@ theorem getKeyD_of_isEmpty [EquivBEq α] [LawfulHashable α] (h : m.WF) {a fallb m.isEmpty = true → m.getKeyD a fallback = fallback := DHashMap.Raw.getKeyD_of_isEmpty h.out -theorem getKeyD_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} {v : β} : +@[grind =] theorem getKeyD_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} {v : β} : (m.insert k v).getKeyD a fallback = if k == a then k else m.getKeyD a fallback := DHashMap.Raw.getKeyD_insert h.out @@ -698,7 +701,7 @@ theorem getKeyD_eq_fallback [EquivBEq α] [LawfulHashable α] (h : m.WF) {a fall ¬a ∈ m → m.getKeyD a fallback = fallback := DHashMap.Raw.getKeyD_eq_fallback h.out -theorem getKeyD_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} : +@[grind =] theorem getKeyD_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} : (m.erase k).getKeyD a fallback = if k == a then fallback else m.getKeyD a fallback := DHashMap.Raw.getKeyD_erase h.out @@ -740,17 +743,17 @@ theorem getKeyD_eq_of_mem [LawfulBEq α] (h : m.WF) {k fallback : α} (h' : k m.getKeyD k fallback = k := DHashMap.Raw.getKeyD_eq_of_mem h.out h' -@[simp] +@[simp, grind =] theorem isEmpty_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v : β} : (m.insertIfNew k v).isEmpty = false := DHashMap.Raw.isEmpty_insertIfNew h.out -@[simp] +@[simp, grind =] theorem contains_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : (m.insertIfNew k v).contains a = (k == a || m.contains a) := DHashMap.Raw.contains_insertIfNew h.out -@[simp] +@[simp, grind =] theorem mem_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : a ∈ m.insertIfNew k v ↔ k == a ∨ a ∈ m := DHashMap.Raw.mem_insertIfNew h.out @@ -783,7 +786,7 @@ theorem mem_of_mem_insertIfNew' [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a ∈ m.insertIfNew k v → ¬((k == a) ∧ ¬k ∈ m) → a ∈ m := DHashMap.Raw.mem_of_mem_insertIfNew' h.out -theorem size_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v : β} : +@[grind =] theorem size_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {v : β} : (m.insertIfNew k v).size = if k ∈ m then m.size else m.size + 1 := DHashMap.Raw.size_insertIfNew h.out @@ -795,67 +798,67 @@ theorem size_insertIfNew_le [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α (m.insertIfNew k v).size ≤ m.size + 1 := DHashMap.Raw.size_insertIfNew_le h.out -theorem getElem?_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : +@[grind =] theorem getElem?_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : (m.insertIfNew k v)[a]? = if k == a ∧ ¬k ∈ m then some v else m[a]? := DHashMap.Raw.Const.get?_insertIfNew h.out -theorem getElem_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} {h₁} : +@[grind =] theorem getElem_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} {h₁} : (m.insertIfNew k v)[a]'h₁ = if h₂ : k == a ∧ ¬k ∈ m then v else m[a]'(mem_of_mem_insertIfNew' h h₁ h₂) := DHashMap.Raw.Const.get_insertIfNew h.out (h₁ := h₁) -theorem getElem!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.WF) {k a : α} +@[grind =] theorem getElem!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.WF) {k a : α} {v : β} : (m.insertIfNew k v)[a]! = if k == a ∧ ¬k ∈ m then v else m[a]! := DHashMap.Raw.Const.get!_insertIfNew h.out -theorem getD_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {fallback v : β} : +@[grind =] theorem getD_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {fallback v : β} : (m.insertIfNew k v).getD a fallback = if k == a ∧ ¬k ∈ m then v else m.getD a fallback := DHashMap.Raw.Const.getD_insertIfNew h.out -theorem getKey?_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : +@[grind =] theorem getKey?_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} : (m.insertIfNew k v).getKey? a = if k == a ∧ ¬k ∈ m then some k else m.getKey? a := DHashMap.Raw.getKey?_insertIfNew h.out -theorem getKey_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} {h₁} : +@[grind =] theorem getKey_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {v : β} {h₁} : (m.insertIfNew k v).getKey a h₁ = if h₂ : k == a ∧ ¬k ∈ m then k else m.getKey a (mem_of_mem_insertIfNew' h h₁ h₂) := DHashMap.Raw.getKey_insertIfNew h.out -theorem getKey!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {k a : α} {v : β} : +@[grind =] theorem getKey!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {k a : α} {v : β} : (m.insertIfNew k v).getKey! a = if k == a ∧ ¬k ∈ m then k else m.getKey! a := DHashMap.Raw.getKey!_insertIfNew h.out -theorem getKeyD_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} {v : β} : +@[grind =] theorem getKeyD_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} {v : β} : (m.insertIfNew k v).getKeyD a fallback = if k == a ∧ ¬k ∈ m then k else m.getKeyD a fallback := DHashMap.Raw.getKeyD_insertIfNew h.out -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_fst (h : m.WF) {k : α} {v : β} : (getThenInsertIfNew? m k v).1 = get? m k := DHashMap.Raw.Const.getThenInsertIfNew?_fst h.out -@[simp] +@[simp, grind =] theorem getThenInsertIfNew?_snd (h : m.WF) {k : α} {v : β} : (getThenInsertIfNew? m k v).2 = m.insertIfNew k v := ext (DHashMap.Raw.Const.getThenInsertIfNew?_snd h.out) -@[simp] +@[simp, grind =] theorem length_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.keys.length = m.size := DHashMap.Raw.length_keys h.out -@[simp] +@[simp, grind =] theorem isEmpty_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.keys.isEmpty = m.isEmpty := DHashMap.Raw.isEmpty_keys h.out -@[simp] +@[simp, grind =] theorem contains_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} : m.keys.contains k = m.contains k := DHashMap.Raw.contains_keys h.out -@[simp] +@[simp, grind =] theorem mem_keys [LawfulBEq α] (h : m.WF) {k : α} : k ∈ m.keys ↔ k ∈ m := DHashMap.Raw.mem_keys h.out @@ -868,7 +871,7 @@ theorem distinct_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.keys.Pairwise (fun a b => (a == b) = false) := DHashMap.Raw.distinct_keys h.out -@[simp] +@[simp, grind =] theorem map_fst_toList_eq_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.toList.map Prod.fst = m.keys := DHashMap.Raw.Const.map_fst_toList_eq_keys h.out @@ -878,17 +881,17 @@ theorem map_prod_fst_toList_eq_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) m.toList.map Prod.fst = m.keys := DHashMap.Raw.Const.map_fst_toList_eq_keys h.out -@[simp] +@[simp, grind =] theorem length_toList [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.toList.length = m.size := DHashMap.Raw.Const.length_toList h.out -@[simp] +@[simp, grind =] theorem isEmpty_toList [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.toList.isEmpty = m.isEmpty := DHashMap.Raw.Const.isEmpty_toList h.out -@[simp] +@[simp, grind =] theorem mem_toList_iff_getElem?_eq_some [LawfulBEq α] (h : m.WF) {k : α} {v : β} : (k, v) ∈ m.toList ↔ m[k]? = some v := @@ -945,7 +948,7 @@ theorem fold_eq_foldl_toList (h : m.WF) {f : δ → (a : α) → β → δ} {ini DHashMap.Raw.Const.fold_eq_foldl_toList h.out omit [BEq α] [Hashable α] in -@[simp] +@[simp, grind =] theorem forM_eq_forM [Monad m'] [LawfulMonad m'] {f : (a : α) → β → m' PUnit} : m.forM f = ForM.forM m (fun a => f a.1 a.2) := rfl @@ -954,7 +957,7 @@ theorem forM_eq_forM_toList [Monad m'] [LawfulMonad m'] (h : m.WF) {f : α × β DHashMap.Raw.Const.forMUncurried_eq_forM_toList h.out omit [BEq α] [Hashable α] in -@[simp] +@[simp, grind =] theorem forIn_eq_forIn [Monad m'] [LawfulMonad m'] {f : (a : α) → β → δ → m' (ForInStep δ)} {init : δ} : m.forIn f init = ForIn.forIn m init (fun a d => f a.1 a.2 d) := rfl @@ -986,22 +989,24 @@ end monadic variable {ρ : Type w} [ForIn Id ρ (α × β)] -@[simp] +@[simp, grind =] theorem insertMany_nil (h : m.WF) : insertMany m [] = m := ext (DHashMap.Raw.Const.insertMany_nil h.out) -@[simp] +@[simp, grind =] theorem insertMany_list_singleton (h : m.WF) {k : α} {v : β} : insertMany m [⟨k, v⟩] = m.insert k v := ext (DHashMap.Raw.Const.insertMany_list_singleton h.out) +@[grind _=_] theorem insertMany_cons (h : m.WF) {l : List (α × β)} {k : α} {v : β} : insertMany m (⟨k, v⟩ :: l) = insertMany (m.insert k v) l := ext (DHashMap.Raw.Const.insertMany_cons h.out) +@[grind _=_] theorem insertMany_append (h : m.WF) {l₁ l₂ : List (α × β)} : insertMany m (l₁ ++ l₂) = insertMany (insertMany m l₁) l₂ := by induction l₁ generalizing m with @@ -1016,13 +1021,13 @@ theorem insertMany_ind {motive : Raw α β → Prop} (m : Raw α β) {l : ρ} show motive ⟨DHashMap.Raw.Const.insertMany m.1 l⟩ from DHashMap.Raw.Const.insertMany_ind m.inner l init fun m => insert ⟨m⟩ -@[simp] +@[simp, grind =] theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List (α × β)} {k : α} : (insertMany m l).contains k = (m.contains k || (l.map Prod.fst).contains k) := DHashMap.Raw.Const.contains_insertMany_list h.out -@[simp] +@[simp, grind =] theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List (α × β)} {k : α} : k ∈ insertMany m l ↔ k ∈ m ∨ (l.map Prod.fst).contains k := @@ -1112,12 +1117,16 @@ theorem size_le_size_insertMany [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : ρ} : m.size ≤ (insertMany m l).size := DHashMap.Raw.Const.size_le_size_insertMany h.out +grind_pattern size_le_size_insertMany => (insertMany m l).size + theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List (α × β)} : (insertMany m l).size ≤ m.size + l.length := DHashMap.Raw.Const.size_insertMany_list_le h.out -@[simp] +grind_pattern size_insertMany_list_le => (insertMany m l).size + +@[simp, grind =] theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List (α × β)} : (insertMany m l).isEmpty = (m.isEmpty && l.isEmpty) := @@ -1139,6 +1148,7 @@ theorem getElem?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (insertMany m l)[k']? = some v := DHashMap.Raw.Const.get?_insertMany_list_of_mem h.out k_beq distinct mem +@[grind =] theorem getElem?_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List (α × β)} {k : α} : (insertMany m l)[k]? = (l.findSomeRev? (fun ⟨a, b⟩ => if a == k then some b else none)).or m[k]? := @@ -1363,16 +1373,17 @@ namespace Raw variable [BEq α] [Hashable α] -@[simp] +@[simp, grind =] theorem ofList_nil : ofList ([] : List (α × β)) = ∅ := ext DHashMap.Raw.Const.ofList_nil -@[simp] +@[simp, grind =] theorem ofList_singleton {k : α} {v : β} : ofList [⟨k, v⟩] = (∅ : Raw α β).insert k v := ext DHashMap.Raw.Const.ofList_singleton +@[grind _=_] theorem ofList_cons {k : α} {v : β} {tl : List (α × β)} : ofList (⟨k, v⟩ :: tl) = insertMany ((∅ : Raw α β).insert k v) tl := ext DHashMap.Raw.Const.ofList_cons @@ -1381,13 +1392,13 @@ theorem ofList_eq_insertMany_empty {l : List (α × β)} : ofList l = insertMany (∅ : Raw α β) l := ext DHashMap.Raw.Const.ofList_eq_insertMany_empty -@[simp] +@[simp, grind =] theorem contains_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : (ofList l).contains k = (l.map Prod.fst).contains k := DHashMap.Raw.Const.contains_ofList -@[simp] +@[simp, grind =] theorem mem_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} {k : α} : k ∈ (ofList l) ↔ (l.map Prod.fst).contains k := @@ -1501,7 +1512,9 @@ theorem size_ofList_le [EquivBEq α] [LawfulHashable α] (ofList l).size ≤ l.length := DHashMap.Raw.Const.size_ofList_le -@[simp] +grind_pattern size_ofList_le => (ofList l).size + +@[simp, grind =] theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α] {l : List (α × β)} : (ofList l).isEmpty = l.isEmpty := @@ -1633,16 +1646,18 @@ theorem isEmpty_alter_eq_isEmpty_erase [EquivBEq α] [LawfulHashable α] {k : α (alter m k f).isEmpty = ((m.erase k).isEmpty && (f m[k]?).isNone) := DHashMap.Raw.Const.isEmpty_alter_eq_isEmpty_erase h.out -@[simp] +@[simp, grind =] theorem isEmpty_alter [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β → Option β} (h : m.WF) : (alter m k f).isEmpty = ((m.isEmpty || (m.size == 1 && m.contains k)) && (f m[k]?).isNone) := DHashMap.Raw.Const.isEmpty_alter h.out +@[grind =] theorem contains_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} (h : m.WF) : (alter m k f).contains k' = if k == k' then (f m[k]?).isSome else m.contains k' := DHashMap.Raw.Const.contains_alter h.out +@[grind =] theorem mem_alter [EquivBEq α] [LawfulHashable α] {k k': α} {f : Option β → Option β} (h : m.WF) : k' ∈ alter m k f ↔ if k == k' then (f m[k]?).isSome = true else k' ∈ m := DHashMap.Raw.Const.mem_alter h.out @@ -1670,6 +1685,7 @@ theorem mem_alter_of_beq_eq_false [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} (h : m.WF) (he : (k == k') = false) : k' ∈ alter m k f ↔ k' ∈ m := DHashMap.Raw.Const.mem_alter_of_beq_eq_false h.out he +@[grind =] theorem size_alter [LawfulBEq α] {k : α} {f : Option β → Option β} (h : m.WF) : (alter m k f).size = if k ∈ m ∧ (f m[k]?).isNone then @@ -1706,6 +1722,7 @@ theorem size_le_size_alter [LawfulBEq α] {k : α} {f : Option β → Option β} m.size - 1 ≤ (alter m k f).size := DHashMap.Raw.Const.size_le_size_alter h.out +@[grind =] theorem getElem?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} (h : m.WF) : (alter m k f)[k']? = if k == k' then @@ -1733,6 +1750,7 @@ theorem get?_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Option (h : m.WF) : get? (alter m k f) k = f (get? m k) := DHashMap.Raw.Const.get?_alter_self h.out +@[grind =] theorem getElem_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} (h : m.WF) {hc : k' ∈ alter m k f} : (alter m k f)[k'] = @@ -1770,6 +1788,7 @@ theorem get_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Option β get (alter m k f) k hc = (f (get? m k)).get h' := DHashMap.Raw.Const.get_alter_self h.out +@[grind =] theorem getElem!_alter [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] {f : Option β → Option β} (h : m.WF) : (alter m k f)[k']! = if k == k' then @@ -1797,6 +1816,7 @@ theorem get!_alter_self [EquivBEq α] [LawfulHashable α] {k : α} [Inhabited β {f : Option β → Option β} (h : m.WF) : get! (alter m k f) k = (f (get? m k)).get! := DHashMap.Raw.Const.get!_alter_self h.out +@[grind =] theorem getD_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} {f : Option β → Option β} (h : m.WF) : getD (alter m k f) k' fallback = if k == k' then @@ -1811,6 +1831,7 @@ theorem getD_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {fallback : getD (alter m k f) k fallback = (f m[k]?).getD fallback := DHashMap.Raw.Const.getD_alter_self h.out +@[grind =] theorem getKey?_alter [EquivBEq α] [LawfulHashable α] {k k' : α} {f : Option β → Option β} (h : m.WF) : (alter m k f).getKey? k' = if k == k' then @@ -1823,6 +1844,7 @@ theorem getKey?_alter_self [EquivBEq α] [LawfulHashable α] {k : α} {f : Optio (h : m.WF) : (alter m k f).getKey? k = if (f m[k]?).isSome then some k else none := DHashMap.Raw.Const.getKey?_alter_self h.out +@[grind =] theorem getKey!_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : Option β → Option β} (h : m.WF) : (alter m k f).getKey! k' = if k == k' then @@ -1836,6 +1858,7 @@ theorem getKey!_alter_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : (alter m k f).getKey! k = if (f m[k]?).isSome then k else default := DHashMap.Raw.Const.getKey!_alter_self h.out +@[grind =] theorem getKey_alter [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : Option β → Option β} (h : m.WF) {hc : k' ∈ alter m k f} : (alter m k f).getKey k' hc = @@ -1852,6 +1875,7 @@ theorem getKey_alter_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : (alter m k f).getKey k hc = k := DHashMap.Raw.Const.getKey_alter_self h.out +@[grind =] theorem getKeyD_alter [EquivBEq α] [LawfulHashable α] {k k' fallback : α} {f : Option β → Option β} (h : m.WF) : (alter m k f).getKeyD k' fallback = if k == k' then @@ -1869,26 +1893,27 @@ end Alter section Modify -@[simp] +@[simp, grind =] theorem isEmpty_modify [EquivBEq α] [LawfulHashable α] {k : α} {f : β → β} (h : m.WF) : (modify m k f).isEmpty = m.isEmpty := DHashMap.Raw.Const.isEmpty_modify h.out -@[simp] +@[simp, grind =] theorem contains_modify [EquivBEq α] [LawfulHashable α] {k k': α} {f : β → β} (h : m.WF) : (modify m k f).contains k' = m.contains k' := DHashMap.Raw.Const.contains_modify h.out -@[simp] +@[simp, grind =] theorem mem_modify [EquivBEq α] [LawfulHashable α] {k k': α} {f : β → β} (h : m.WF) : k' ∈ modify m k f ↔ k' ∈ m := DHashMap.Raw.Const.mem_modify h.out -@[simp] +@[simp, grind =] theorem size_modify [EquivBEq α] [LawfulHashable α] {k : α} {f : β → β} (h : m.WF) : (modify m k f).size = m.size := DHashMap.Raw.Const.size_modify h.out +@[grind =] theorem getElem?_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} (h : m.WF) : (modify m k f)[k']? = if k == k' then @@ -1916,6 +1941,7 @@ theorem get?_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β → get? (modify m k f) k = (get? m k).map f := DHashMap.Raw.Const.get?_modify_self h.out +@[grind =] theorem getElem_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} (h : m.WF) {hc : k' ∈ modify m k f} : (modify m k f)[k']'hc = @@ -1953,6 +1979,7 @@ theorem get_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β → get (modify m k f) k hc = f (get m k h') := DHashMap.Raw.Const.get_modify_self h.out +@[grind =] theorem getElem!_modify [EquivBEq α] [LawfulHashable α] {k k' : α} [Inhabited β] {f : β → β} (h : m.WF) : (modify m k f)[k']! = if k == k' then @@ -1980,6 +2007,7 @@ theorem get!_modify_self [EquivBEq α] [LawfulHashable α] {k : α} [Inhabited (h : m.WF) : get! (modify m k f) k = ((get? m k).map f).get! := DHashMap.Raw.Const.get!_modify_self h.out +@[grind =] theorem getD_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {fallback : β} {f : β → β} (h : m.WF) : getD (modify m k f) k' fallback = if k == k' then @@ -1993,6 +2021,7 @@ theorem getD_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {fallback : getD (modify m k f) k fallback = (m[k]?.map f).getD fallback := DHashMap.Raw.Const.getD_modify_self h.out +@[grind =] theorem getKey?_modify [EquivBEq α] [LawfulHashable α] {k k' : α} {f : β → β} (h : m.WF) : (modify m k f).getKey? k' = if k == k' then @@ -2005,6 +2034,7 @@ theorem getKey?_modify_self [EquivBEq α] [LawfulHashable α] {k : α} {f : β (modify m k f).getKey? k = if k ∈ m then some k else none := DHashMap.Raw.Const.getKey?_modify_self h.out +@[grind =] theorem getKey!_modify [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : β → β} (h : m.WF) : (modify m k f).getKey! k' = if k == k' then @@ -2017,6 +2047,7 @@ theorem getKey!_modify_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k (h : m.WF) : (modify m k f).getKey! k = if k ∈ m then k else default := DHashMap.Raw.Const.getKey!_modify_self h.out +@[grind =] theorem getKey_modify [EquivBEq α] [LawfulHashable α] [Inhabited α] {k k' : α} {f : β → β} (h : m.WF) {hc : k' ∈ modify m k f} : (modify m k f).getKey k' hc = @@ -2032,6 +2063,7 @@ theorem getKey_modify_self [EquivBEq α] [LawfulHashable α] [Inhabited α] {k : (h : m.WF) {hc : k ∈ modify m k f} : (modify m k f).getKey k hc = k := DHashMap.Raw.Const.getKey_modify_self h.out +@[grind =] theorem getKeyD_modify [EquivBEq α] [LawfulHashable α] {k k' fallback : α} {f : β → β} (h : m.WF) : (modify m k f).getKeyD k' fallback = if k == k' then @@ -2241,6 +2273,7 @@ theorem toList_filterMap {f : α → β → Option γ} (h : m.WF) : (m.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩))) := DHashMap.Raw.Const.toList_filterMap h.out +@[grind =] theorem isEmpty_filterMap_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} (h : m.WF) : (m.filterMap f).isEmpty = true ↔ @@ -2253,6 +2286,9 @@ theorem isEmpty_filterMap_eq_false_iff [EquivBEq α] [LawfulHashable α] ∃ (k : α) (h : k ∈ m), (f (m.getKey k h) (m[k]'h)).isSome := DHashMap.Raw.Const.isEmpty_filterMap_eq_false_iff h.out +-- TODO: `contains_filterMap` is missing + +@[grind =] theorem mem_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} (h : m.WF) : k ∈ (m.filterMap f) ↔ ∃ (g : k ∈ m), @@ -2269,12 +2305,14 @@ theorem size_filterMap_le_size [EquivBEq α] [LawfulHashable α] (m.filterMap f).size ≤ m.size := DHashMap.Raw.size_filterMap_le_size h.out +grind_pattern size_filterMap_le_size => (m.filterMap f).size theorem size_filterMap_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} (h : m.WF) : (m.filterMap f).size = m.size ↔ ∀ (a : α) (h : a ∈ m), (f (m.getKey a h) (m[a]'h)).isSome := DHashMap.Raw.Const.size_filterMap_eq_size_iff h.out +@[grind =] theorem getElem?_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} (h : m.WF) : (m.filterMap f)[k]? = m[k]?.pbind (fun x h' => @@ -2294,6 +2332,7 @@ theorem isSome_apply_of_mem_filterMap [EquivBEq α] [LawfulHashable α] (m[k]'(mem_of_mem_filterMap h h'))).isSome := DHashMap.Raw.Const.isSome_apply_of_mem_filterMap h.out +@[grind =] theorem getElem_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} {g} (h : m.WF) : (m.filterMap f)[k]'g = @@ -2302,6 +2341,7 @@ theorem getElem_filterMap [EquivBEq α] [LawfulHashable α] (isSome_apply_of_mem_filterMap h g) := DHashMap.Raw.Const.get_filterMap h.out (h':= g) +@[grind =] theorem getElem!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited γ] {f : α → β → Option γ} {k : α} (h : m.WF) : (m.filterMap f)[k]! = @@ -2316,6 +2356,7 @@ theorem getElem!_filterMap_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] fun x => f k' x).get! := DHashMap.Raw.Const.get!_filterMap_of_getKey?_eq_some h.out +@[grind =] theorem getD_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} {fallback : γ} (h : m.WF) : getD (m.filterMap f) k fallback = @@ -2329,6 +2370,7 @@ theorem getD_filterMap_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] fun x => f k' x).getD fallback := DHashMap.Raw.Const.getD_filterMap_of_getKey?_eq_some h.out +@[grind =] theorem getKey?_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k : α} (h : m.WF) : (m.filterMap f).getKey? k = @@ -2342,6 +2384,7 @@ theorem getKey_filterMap [EquivBEq α] [LawfulHashable α] (m.filterMap f).getKey k h' = m.getKey k (mem_of_mem_filterMap h h') := DHashMap.Raw.getKey_filterMap h.out +@[grind =] theorem getKey!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → Option γ} {k : α} (h : m.WF) : (m.filterMap f).getKey! k = @@ -2349,6 +2392,7 @@ theorem getKey!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited α] (f x (m[x]'(mem_of_getKey?_eq_some h h'))).isSome)).get! := DHashMap.Raw.Const.getKey!_filterMap h.out +@[grind =] theorem getKeyD_filterMap [EquivBEq α] [LawfulHashable α] {f : α → β → Option γ} {k fallback : α} (h : m.WF) : (m.filterMap f).getKeyD k fallback = @@ -2373,6 +2417,7 @@ theorem keys_filter_key {f : α → Bool} (h : m.WF) : (m.filter fun k _ => f k).keys.Perm (m.keys.filter f) := DHashMap.Raw.keys_filter_key h.out +@[grind =] theorem isEmpty_filter_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} (h : m.WF) : (m.filter f).isEmpty = true ↔ @@ -2385,6 +2430,9 @@ theorem isEmpty_filter_eq_false_iff [EquivBEq α] [LawfulHashable α] ∃ (k : α) (h : k ∈ m), f (m.getKey k h) (m[k]'h) := DHashMap.Raw.Const.isEmpty_filter_eq_false_iff h.out +-- TODO: `contains_filter` is missing + +@[grind =] theorem mem_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} (h : m.WF) : k ∈ m.filter f ↔ ∃ (h' : k ∈ m), @@ -2401,6 +2449,8 @@ theorem size_filter_le_size [EquivBEq α] [LawfulHashable α] (m.filter f).size ≤ m.size := DHashMap.Raw.size_filter_le_size h.out +grind_pattern size_filter_le_size => (m.filter f).size + theorem size_filter_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} (h : m.WF) : (m.filter f).size = m.size ↔ ∀ (a : α) (h : a ∈ m), @@ -2414,6 +2464,7 @@ theorem filter_equiv_self_iff [EquivBEq α] [LawfulHashable α] ⟨fun h' => (DHashMap.Raw.Const.filter_equiv_self_iff h.out).mp h'.1, fun h' => ⟨(DHashMap.Raw.Const.filter_equiv_self_iff h.out).mpr h'⟩⟩ +@[grind =] theorem getElem?_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} (h : m.WF) : (m.filter f)[k]? = m[k]?.pfilter (fun x h' => @@ -2426,12 +2477,13 @@ theorem getElem?_filter_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] (m.filter f)[k]? = m[k]?.filter (f k') := DHashMap.Raw.Const.get?_filter_of_getKey?_eq_some h.out -@[simp] +@[simp, grind =] theorem getElem_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} {h'} (h : m.WF) : (m.filter f)[k]' h' = m[k]' (mem_of_mem_filter h h') := DHashMap.Raw.Const.get_filter h.out (h' := h') +@[grind =] theorem getElem!_filter [EquivBEq α] [LawfulHashable α] [Inhabited β] {f : α → β → Bool} {k : α} (h : m.WF) : (m.filter f)[k]! = @@ -2445,6 +2497,7 @@ theorem getElem!_filter_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [In (m.filter f)[k]! = (m[k]?.filter (fun x => f k' x)).get! := DHashMap.Raw.Const.get!_filter_of_getKey?_eq_some h.out +@[grind =] theorem getD_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} {fallback : β} (h : m.WF) : getD (m.filter f) k fallback = (m[k]?.pfilter (fun x h' => @@ -2463,6 +2516,7 @@ theorem keys_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} ( (m.keys.attach.filter (fun ⟨x, h'⟩ => f x (m[x]' (mem_of_mem_keys h h')))).unattach := DHashMap.Raw.Const.keys_filter h.out +@[grind =] theorem getKey?_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} (h : m.WF) : (m.filter f).getKey? k = @@ -2475,12 +2529,13 @@ theorem getKey?_filter_key [EquivBEq α] [LawfulHashable α] (m.filter fun k _ => f k).getKey? k = (m.getKey? k).filter f := DHashMap.Raw.getKey?_filter_key h.out -@[simp] +@[simp, grind =] theorem getKey_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k : α} (h : m.WF) {h'} : (m.filter f).getKey k h' = m.getKey k (mem_of_mem_filter h h') := DHashMap.Raw.getKey_filter h.out +@[grind =] theorem getKey!_filter [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → Bool} {k : α} (h : m.WF) : (m.filter f).getKey! k = @@ -2493,6 +2548,7 @@ theorem getKey!_filter_key [EquivBEq α] [LawfulHashable α] [Inhabited α] (m.filter fun k _ => f k).getKey! k = ((m.getKey? k).filter f).get! := DHashMap.Raw.getKey!_filter_key h.out +@[grind =] theorem getKeyD_filter [EquivBEq α] [LawfulHashable α] {f : α → β → Bool} {k fallback : α} (h : m.WF) : (m.filter f).getKeyD k fallback = @@ -2528,13 +2584,13 @@ theorem filterMap_equiv_map [EquivBEq α] [LawfulHashable α] (m.filterMap (fun k v => Option.some (f k v))) ~m (m.map f) := ⟨DHashMap.Raw.filterMap_equiv_map h.out⟩ -@[simp] +@[simp, grind =] theorem isEmpty_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} (h : m.WF) : (m.map f).isEmpty = m.isEmpty := DHashMap.Raw.isEmpty_map h.out -@[simp] +@[simp, grind =] theorem contains_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} (h : m.WF) : (m.map f).contains k = m.contains k := @@ -2545,7 +2601,7 @@ theorem contains_of_contains_map [EquivBEq α] [LawfulHashable α] (m.map f).contains k = true → m.contains k = true := DHashMap.Raw.contains_of_contains_map h.out -@[simp] +@[simp, grind =] theorem mem_map [EquivBEq α] [LawfulHashable α] {f : (a : α) → β → γ} {k : α} (h : m.WF) : k ∈ (m.map f) ↔ k ∈ m := @@ -2556,37 +2612,37 @@ theorem mem_of_mem_map [EquivBEq α] [LawfulHashable α] k ∈ (m.map f) → k ∈ m := DHashMap.Raw.mem_of_mem_map h.out -@[simp] +@[simp, grind =] theorem size_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} (h : m.WF) : (m.map f).size = m.size := DHashMap.Raw.size_map h.out -@[simp] +@[simp, grind =] theorem getKey?_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} (h : m.WF) : (m.map f).getKey? k = m.getKey? k := DHashMap.Raw.getKey?_map h.out -@[simp] +@[simp, grind =] theorem getKey_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} {h'} (h : m.WF) : (m.map f).getKey k h' = m.getKey k (mem_of_mem_map h h') := DHashMap.Raw.getKey_map h.out -@[simp] +@[simp, grind =] theorem getKey!_map [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → β → γ} {k : α} (h : m.WF) : (m.map f).getKey! k = m.getKey! k := DHashMap.Raw.getKey!_map h.out -@[simp] +@[simp, grind =] theorem getKeyD_map [EquivBEq α] [LawfulHashable α] {f : α → β → γ} {k fallback : α} (h : m.WF) : (m.map f).getKeyD k fallback = m.getKeyD k fallback := DHashMap.Raw.getKeyD_map h.out -@[simp] +@[simp, grind =] theorem getElem?_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} (h : m.WF) : (m.map f)[k]? = m[k]?.map (f k) := @@ -2605,7 +2661,7 @@ theorem getElem?_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] (m.map f)[k]? = m[k]?.map (f k') := DHashMap.Raw.Const.get?_map_of_getKey?_eq_some h.out h' -@[simp] +@[simp, grind =] theorem getElem_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} {h'} (h : m.WF) : (m.map f)[k]' h' = @@ -2621,6 +2677,7 @@ theorem getElem_map' [EquivBEq α] [LawfulHashable α] (m[k]' (mem_of_mem_map h h'))) := DHashMap.Raw.Const.get_map' h.out (h':= h') +@[grind =] theorem getElem!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ] {f : α → β → γ} {k : α} (h : m.WF) : (m.map f)[k]! = @@ -2640,6 +2697,7 @@ theorem getElem!_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhab (m.map f)[k]! = (m[k]?.map (f k')).get! := DHashMap.Raw.Const.get!_map_of_getKey?_eq_some h.out h' +@[grind =] theorem getD_map [LawfulBEq α] [LawfulHashable α] {f : α → β → γ} {k : α} {fallback : γ} (h : m.WF) : (m.map f).getD k fallback = diff --git a/src/Std/Data/HashSet/Lemmas.lean b/src/Std/Data/HashSet/Lemmas.lean index 2456b6db46..c50add160a 100644 --- a/src/Std/Data/HashSet/Lemmas.lean +++ b/src/Std/Data/HashSet/Lemmas.lean @@ -15,6 +15,8 @@ This module contains lemmas about `Std.Data.HashSet`. Most of the lemmas require is to provide an instance of `LawfulBEq α`. -/ +set_option trace.grind.ematch.pattern true + set_option linter.missingDocs true set_option autoImplicit false @@ -31,11 +33,11 @@ variable {m : HashSet α} private theorem ext {m m' : HashSet α} : m.inner = m'.inner → m = m' := by cases m; cases m'; rintro rfl; rfl -@[simp] +@[simp, grind =] theorem isEmpty_emptyWithCapacity {c} : (emptyWithCapacity c : HashSet α).isEmpty := HashMap.isEmpty_emptyWithCapacity -@[simp] +@[simp, grind =] theorem isEmpty_empty : (∅ : HashSet α).isEmpty := HashMap.isEmpty_empty @@ -43,7 +45,7 @@ set_option linter.missingDocs false in @[deprecated isEmpty_empty (since := "2025-03-12")] abbrev isEmpty_emptyc := @isEmpty_empty -@[simp] +@[simp, grind =] theorem isEmpty_insert [EquivBEq α] [LawfulHashable α] {a : α} : (m.insert a).isEmpty = false := HashMap.isEmpty_insertIfNew @@ -61,14 +63,14 @@ theorem contains_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == theorem mem_congr [EquivBEq α] [LawfulHashable α] {a b : α} (hab : a == b) : a ∈ m ↔ b ∈ m := HashMap.mem_congr hab -@[simp] +@[simp, grind =] theorem contains_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : HashSet α).contains a = false := HashMap.contains_emptyWithCapacity -@[simp] theorem not_mem_emptyWithCapacity {a : α} {c} : ¬a ∈ (emptyWithCapacity c : HashSet α) := +@[simp, grind] theorem not_mem_emptyWithCapacity {a : α} {c} : ¬a ∈ (emptyWithCapacity c : HashSet α) := HashMap.not_mem_emptyWithCapacity -@[simp] theorem contains_empty {a : α} : (∅ : HashSet α).contains a = false := +@[simp, grind =] theorem contains_empty {a : α} : (∅ : HashSet α).contains a = false := HashMap.contains_empty set_option linter.missingDocs false in @@ -110,12 +112,12 @@ theorem isEmpty_iff_forall_not_mem [EquivBEq α] [LawfulHashable α] : @[simp] theorem singleton_eq_insert {a : α} : Singleton.singleton a = (∅ : HashSet α).insert a := rfl -@[simp] +@[simp, grind =] theorem contains_insert [EquivBEq α] [LawfulHashable α] {k a : α} : (m.insert k).contains a = (k == a || m.contains a) := HashMap.contains_insertIfNew -@[simp] +@[simp, grind =] theorem mem_insert [EquivBEq α] [LawfulHashable α] {k a : α} : a ∈ m.insert k ↔ k == a ∨ a ∈ m := HashMap.mem_insertIfNew @@ -144,11 +146,11 @@ theorem contains_insert_self [EquivBEq α] [LawfulHashable α] {k : α} : (m.ins theorem mem_insert_self [EquivBEq α] [LawfulHashable α] {k : α} : k ∈ m.insert k := by simp -@[simp] +@[simp, grind =] theorem size_emptyWithCapacity {c} : (emptyWithCapacity c : HashSet α).size = 0 := HashMap.size_emptyWithCapacity -@[simp] +@[simp, grind =] theorem size_empty : (∅ : HashSet α).size = 0 := HashMap.size_empty @@ -159,7 +161,7 @@ abbrev size_emptyc := @size_empty theorem isEmpty_eq_size_eq_zero : m.isEmpty = (m.size == 0) := HashMap.isEmpty_eq_size_eq_zero -theorem size_insert [EquivBEq α] [LawfulHashable α] {k : α} : +@[grind =] theorem size_insert [EquivBEq α] [LawfulHashable α] {k : α} : (m.insert k).size = if k ∈ m then m.size else m.size + 1 := HashMap.size_insertIfNew @@ -170,11 +172,11 @@ theorem size_insert_le [EquivBEq α] [LawfulHashable α] {k : α} : (m.insert k).size ≤ m.size + 1 := HashMap.size_insertIfNew_le -@[simp] +@[simp, grind =] theorem erase_emptyWithCapacity {a : α} {c : Nat} : (emptyWithCapacity c : HashSet α).erase a = emptyWithCapacity c := ext HashMap.erase_emptyWithCapacity -@[simp] +@[simp, grind =] theorem erase_empty {a : α} : (∅ : HashSet α).erase a = ∅ := ext HashMap.erase_empty @@ -182,17 +184,17 @@ set_option linter.missingDocs false in @[deprecated erase_empty (since := "2025-03-12")] abbrev erase_emptyc := @erase_empty -@[simp] +@[simp, grind =] theorem isEmpty_erase [EquivBEq α] [LawfulHashable α] {k : α} : (m.erase k).isEmpty = (m.isEmpty || (m.size == 1 && m.contains k)) := HashMap.isEmpty_erase -@[simp] +@[simp, grind =] theorem contains_erase [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k).contains a = (!(k == a) && m.contains a) := HashMap.contains_erase -@[simp] +@[simp, grind =] theorem mem_erase [EquivBEq α] [LawfulHashable α] {k a : α} : a ∈ m.erase k ↔ (k == a) = false ∧ a ∈ m := HashMap.mem_erase @@ -204,7 +206,7 @@ theorem contains_of_contains_erase [EquivBEq α] [LawfulHashable α] {k a : α} theorem mem_of_mem_erase [EquivBEq α] [LawfulHashable α] {k a : α} : a ∈ m.erase k → a ∈ m := HashMap.mem_of_mem_erase -theorem size_erase [EquivBEq α] [LawfulHashable α] {k : α} : +@[grind =] theorem size_erase [EquivBEq α] [LawfulHashable α] {k : α} : (m.erase k).size = if k ∈ m then m.size - 1 else m.size := HashMap.size_erase @@ -215,11 +217,11 @@ theorem size_le_size_erase [EquivBEq α] [LawfulHashable α] {k : α} : m.size ≤ (m.erase k).size + 1 := HashMap.size_le_size_erase -@[simp] +@[simp, grind =] theorem get?_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : HashSet α).get? a = none := HashMap.getKey?_emptyWithCapacity -@[simp] +@[simp, grind =] theorem get?_empty {a : α} : (∅ : HashSet α).get? a = none := HashMap.getKey?_empty @@ -231,7 +233,7 @@ theorem get?_of_isEmpty [EquivBEq α] [LawfulHashable α] {a : α} : m.isEmpty = true → m.get? a = none := HashMap.getKey?_of_isEmpty -theorem get?_insert [EquivBEq α] [LawfulHashable α] {k a : α} : +@[grind =] theorem get?_insert [EquivBEq α] [LawfulHashable α] {k a : α} : (m.insert k).get? a = if k == a ∧ ¬k ∈ m then some k else m.get? a := HashMap.getKey?_insertIfNew @@ -260,7 +262,7 @@ theorem get?_eq_none_of_contains_eq_false [EquivBEq α] [LawfulHashable α] {a : theorem get?_eq_none [EquivBEq α] [LawfulHashable α] {a : α} : ¬a ∈ m → m.get? a = none := HashMap.getKey?_eq_none -theorem get?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : +@[grind =] theorem get?_erase [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k).get? a = if k == a then none else m.get? a := HashMap.getKey?_erase @@ -281,12 +283,12 @@ theorem get?_eq_some_of_contains [LawfulBEq α] {k : α} (h : m.contains k) : m. theorem get?_eq_some [LawfulBEq α] {k : α} (h : k ∈ m) : m.get? k = some k := HashMap.getKey?_eq_some h -theorem get_insert [EquivBEq α] [LawfulHashable α] {k a : α} {h₁} : +@[grind =] theorem get_insert [EquivBEq α] [LawfulHashable α] {k a : α} {h₁} : (m.insert k).get a h₁ = if h₂ : k == a ∧ ¬k ∈ m then k else m.get a (mem_of_mem_insert' h₁ h₂) := HashMap.getKey_insertIfNew (h₁ := h₁) -@[simp] +@[simp, grind =] theorem get_erase [EquivBEq α] [LawfulHashable α] {k a : α} {h'} : (m.erase k).get a h' = m.get a (mem_of_mem_erase h') := HashMap.getKey_erase (h' := h') @@ -299,7 +301,7 @@ theorem get_eq_get_get? [EquivBEq α] [LawfulHashable α] {k : α} {h} : m.get k h = (m.get? k).get (mem_iff_isSome_get?.mp h) := HashMap.getKey_eq_get_getKey? -theorem get_get? [EquivBEq α] [LawfulHashable α] {k : α} {h} : +@[grind =] theorem get_get? [EquivBEq α] [LawfulHashable α] {k : α} {h} : (m.get? k).get h = m.get k (mem_iff_isSome_get?.mpr h) := HashMap.get_getKey? @@ -310,15 +312,15 @@ theorem get_congr [EquivBEq α] [LawfulHashable α] {k₁ k₂ : α} (h : k₁ = (h₁ : k₁ ∈ m) : m.get k₁ h₁ = m.get k₂ ((mem_congr h).mp h₁) := HashMap.getKey_congr h h₁ -@[simp] +@[simp, grind =] theorem get_eq [LawfulBEq α] {k : α} (h : k ∈ m) : m.get k h = k := HashMap.getKey_eq h -@[simp] +@[simp, grind =] theorem get!_emptyWithCapacity [Inhabited α] {a : α} {c} : (emptyWithCapacity c : HashSet α).get! a = default := HashMap.getKey!_emptyWithCapacity -@[simp] +@[simp, grind =] theorem get!_empty [Inhabited α] {a : α} : (∅ : HashSet α).get! a = default := HashMap.getKey!_empty @@ -330,7 +332,7 @@ theorem get!_of_isEmpty [Inhabited α] [EquivBEq α] [LawfulHashable α] {a : α m.isEmpty = true → m.get! a = default := HashMap.getKey!_of_isEmpty -theorem get!_insert [Inhabited α] [EquivBEq α] [LawfulHashable α] {k a : α} : +@[grind =] theorem get!_insert [Inhabited α] [EquivBEq α] [LawfulHashable α] {k a : α} : (m.insert k).get! a = if k == a ∧ ¬k ∈ m then k else m.get! a := HashMap.getKey!_insertIfNew @@ -342,7 +344,7 @@ theorem get!_eq_default [Inhabited α] [EquivBEq α] [LawfulHashable α] {a : α ¬a ∈ m → m.get! a = default := HashMap.getKey!_eq_default -theorem get!_erase [Inhabited α] [EquivBEq α] [LawfulHashable α] {k a : α} : +@[grind =] theorem get!_erase [Inhabited α] [EquivBEq α] [LawfulHashable α] {k a : α} : (m.erase k).get! a = if k == a then default else m.get! a := HashMap.getKey!_erase @@ -377,11 +379,11 @@ theorem get!_eq_of_contains [LawfulBEq α] [Inhabited α] {k : α} (h : m.contai theorem get!_eq_of_mem [LawfulBEq α] [Inhabited α] {k : α} (h : k ∈ m) : m.get! k = k := HashMap.getKey!_eq_of_mem h -@[simp] +@[simp, grind =] theorem getD_emptyWithCapacity {a fallback : α} {c} : (emptyWithCapacity c : HashSet α).getD a fallback = fallback := HashMap.getKeyD_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getD_empty {a fallback : α} : (∅ : HashSet α).getD a fallback = fallback := HashMap.getKeyD_empty @@ -393,7 +395,7 @@ theorem getD_of_isEmpty [EquivBEq α] [LawfulHashable α] {a fallback : α} : m.isEmpty = true → m.getD a fallback = fallback := HashMap.getKeyD_of_isEmpty -theorem getD_insert [EquivBEq α] [LawfulHashable α] {k a fallback : α} : +@[grind =] theorem getD_insert [EquivBEq α] [LawfulHashable α] {k a fallback : α} : (m.insert k).getD a fallback = if k == a ∧ ¬k ∈ m then k else m.getD a fallback := HashMap.getKeyD_insertIfNew @@ -406,7 +408,7 @@ theorem getD_eq_fallback [EquivBEq α] [LawfulHashable α] {a fallback : α} : ¬a ∈ m → m.getD a fallback = fallback := HashMap.getKeyD_eq_fallback -theorem getD_erase [EquivBEq α] [LawfulHashable α] {k a fallback : α} : +@[grind =] theorem getD_erase [EquivBEq α] [LawfulHashable α] {k a fallback : α} : (m.erase k).getD a fallback = if k == a then fallback else m.getD a fallback := HashMap.getKeyD_erase @@ -446,30 +448,30 @@ theorem getD_eq_of_contains [LawfulBEq α] {k fallback : α} (h : m.contains k) theorem getD_eq_of_mem [LawfulBEq α] {k fallback : α} (h : k ∈ m) : m.getD k fallback = k := HashMap.getKeyD_eq_of_mem h -@[simp] +@[simp, grind =] theorem containsThenInsert_fst {k : α} : (m.containsThenInsert k).1 = m.contains k := HashMap.containsThenInsertIfNew_fst -@[simp] +@[simp, grind =] theorem containsThenInsert_snd {k : α} : (m.containsThenInsert k).2 = m.insert k := ext HashMap.containsThenInsertIfNew_snd -@[simp] +@[simp, grind =] theorem length_toList [EquivBEq α] [LawfulHashable α] : m.toList.length = m.size := HashMap.length_keys -@[simp] +@[simp, grind =] theorem isEmpty_toList [EquivBEq α] [LawfulHashable α] : m.toList.isEmpty = m.isEmpty := HashMap.isEmpty_keys -@[simp] +@[simp, grind =] theorem contains_toList [EquivBEq α] [LawfulHashable α] {k : α} : m.toList.contains k = m.contains k := HashMap.contains_keys -@[simp] +@[simp, grind =] theorem mem_toList [LawfulBEq α] [LawfulHashable α] {k : α} : k ∈ m.toList ↔ k ∈ m := HashMap.mem_keys @@ -491,7 +493,7 @@ theorem fold_eq_foldl_toList {f : δ → α → δ} {init : δ} : m.fold f init = m.toList.foldl f init := HashMap.fold_eq_foldl_keys -@[simp] +@[simp, grind =] theorem forM_eq_forM [Monad m'] [LawfulMonad m'] {f : α → m' PUnit} : m.forM f = ForM.forM m f := rfl @@ -499,7 +501,7 @@ theorem forM_eq_forM_toList [Monad m'] [LawfulMonad m'] {f : α → m' PUnit} : ForM.forM m f = ForM.forM m.toList f := HashMap.forM_eq_forM_keys -@[simp] +@[simp, grind =] theorem forIn_eq_forIn [Monad m'] [LawfulMonad m'] {f : α → δ → m' (ForInStep δ)} {init : δ} : ForIn.forIn m init f = ForIn.forIn m init f := rfl @@ -513,20 +515,21 @@ end monadic variable {ρ : Type v} [ForIn Id ρ α] -@[simp] +@[simp, grind =] theorem insertMany_nil : insertMany m [] = m := ext HashMap.insertManyIfNewUnit_nil -@[simp] +@[simp, grind =] theorem insertMany_list_singleton {k : α} : insertMany m [k] = m.insert k := ext HashMap.insertManyIfNewUnit_list_singleton -theorem insertMany_cons {l : List α} {k : α} : +@[grind _=_] theorem insertMany_cons {l : List α} {k : α} : insertMany m (k :: l) = insertMany (m.insert k) l := ext HashMap.insertManyIfNewUnit_cons +@[grind _=_] theorem insertMany_append {l₁ l₂ : List α} : insertMany m (l₁ ++ l₂) = insertMany (insertMany m l₁) l₂ := by induction l₁ generalizing m with @@ -541,13 +544,13 @@ theorem insertMany_ind {motive : HashSet α → Prop} (m : HashSet α) {l : ρ} show motive ⟨m.1.insertManyIfNewUnit l⟩ from HashMap.insertManyIfNewUnit_ind m.inner l init fun m => insert ⟨m⟩ -@[simp] +@[simp, grind =] theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List α} {k : α} : (insertMany m l).contains k = (m.contains k || l.contains k) := HashMap.contains_insertManyIfNewUnit_list -@[simp] +@[simp, grind =] theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List α} {k : α} : k ∈ insertMany m l ↔ k ∈ m ∨ l.contains k := @@ -652,12 +655,16 @@ theorem size_le_size_insertMany [EquivBEq α] [LawfulHashable α] {l : ρ} : m.size ≤ (insertMany m l).size := HashMap.size_le_size_insertManyIfNewUnit +grind_pattern size_le_size_insertMany => (insertMany m l).size + theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] {l : List α} : (insertMany m l).size ≤ m.size + l.length := HashMap.size_insertManyIfNewUnit_list_le -@[simp] +grind_pattern size_insertMany_list_le => (insertMany m l).size + +@[simp, grind =] theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α] {l : List α} : (insertMany m l).isEmpty = (m.isEmpty && l.isEmpty) := @@ -671,17 +678,17 @@ end section -@[simp] +@[simp, grind =] theorem ofList_nil : ofList ([] : List α) = ∅ := ext HashMap.unitOfList_nil -@[simp] +@[simp, grind =] theorem ofList_singleton {k : α} : ofList [k] = (∅ : HashSet α).insert k := ext HashMap.unitOfList_singleton -theorem ofList_cons {hd : α} {tl : List α} : +@[grind _=_] theorem ofList_cons {hd : α} {tl : List α} : ofList (hd :: tl) = insertMany ((∅ : HashSet α).insert hd) tl := ext HashMap.unitOfList_cons @@ -692,13 +699,13 @@ theorem ofList_eq_insertMany_empty {l : List α} : | [] => by simp | hd :: tl => by simp [ofList_cons, insertMany_cons] -@[simp] +@[simp, grind =] theorem contains_ofList [EquivBEq α] [LawfulHashable α] {l : List α} {k : α} : (ofList l).contains k = l.contains k := HashMap.contains_unitOfList -@[simp] +@[simp, grind =] theorem mem_ofList [EquivBEq α] [LawfulHashable α] {l : List α} {k : α} : k ∈ ofList l ↔ l.contains k := @@ -760,7 +767,9 @@ theorem size_ofList_le [EquivBEq α] [LawfulHashable α] (ofList l).size ≤ l.length := HashMap.size_unitOfList_le -@[simp] +grind_pattern size_ofList_le => (ofList l).size + +@[simp, grind =] theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α] {l : List α} : (ofList l).isEmpty = l.isEmpty := @@ -893,7 +902,7 @@ theorem toList_filter {f : α → Bool} : (m.filter f).toList.Perm (m.toList.filter f) := HashMap.keys_filter_key -theorem isEmpty_filter_iff [EquivBEq α] [LawfulHashable α] +@[grind =] theorem isEmpty_filter_iff [EquivBEq α] [LawfulHashable α] {f : α → Bool} : (m.filter f).isEmpty ↔ ∀ k h, f (m.get k h) = false := HashMap.isEmpty_filter_iff @@ -903,7 +912,9 @@ theorem isEmpty_filter_eq_false_iff [EquivBEq α] [LawfulHashable α] (m.filter f).isEmpty = false ↔ ∃ k h, f (m.get k h) := HashMap.isEmpty_filter_eq_false_iff -@[simp] +-- TODO: `contains_filter` is missing. + +@[simp, grind =] theorem mem_filter [EquivBEq α] [LawfulHashable α] {f : α → Bool} {k : α} : k ∈ m.filter f ↔ ∃ h, f (m.get k h) := @@ -924,6 +935,8 @@ theorem size_filter_le_size [EquivBEq α] [LawfulHashable α] (m.filter f).size ≤ m.size := HashMap.size_filter_le_size +grind_pattern size_filter_le_size => (m.filter f).size + theorem size_filter_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α → Bool} : (m.filter f).size = m.size ↔ ∀ k h, f (m.get k h) := @@ -935,23 +948,25 @@ theorem filter_equiv_self_iff [EquivBEq α] [LawfulHashable α] ⟨fun h => HashMap.filter_equiv_self_iff.mp h.1, fun h => ⟨HashMap.filter_equiv_self_iff.mpr h⟩⟩ -@[simp] +@[simp, grind =] theorem get?_filter [EquivBEq α] [LawfulHashable α] {f : α → Bool} {k : α} : (m.filter f).get? k = (m.get? k).filter f := HashMap.getKey?_filter_key -@[simp] +@[simp, grind =] theorem get_filter [EquivBEq α] [LawfulHashable α] {f : α → Bool} {k : α} {h} : (m.filter f).get k h = m.get k (mem_of_mem_filter h) := HashMap.getKey_filter +@[grind =] theorem get!_filter [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → Bool} {k : α} : (m.filter f).get! k = ((m.get? k).filter f).get! := HashMap.getKey!_filter_key +@[grind =] theorem getD_filter [EquivBEq α] [LawfulHashable α] {f : α → Bool} {k fallback : α} : (m.filter f).getD k fallback = ((m.get? k).filter f).getD fallback := diff --git a/src/Std/Data/HashSet/RawLemmas.lean b/src/Std/Data/HashSet/RawLemmas.lean index 2e4d7fa606..f205343ab7 100644 --- a/src/Std/Data/HashSet/RawLemmas.lean +++ b/src/Std/Data/HashSet/RawLemmas.lean @@ -15,6 +15,8 @@ This module contains lemmas about `Std.Data.HashSet.Raw`. Most of the lemmas req is to provide an instance of `LawfulBEq α`. -/ +set_option trace.grind.ematch.pattern true + set_option linter.missingDocs true set_option autoImplicit false @@ -31,11 +33,11 @@ variable {m : Raw α} private theorem ext {m m' : Raw α} : m.inner = m'.inner → m = m' := by cases m; cases m'; rintro rfl; rfl -@[simp] +@[simp, grind =] theorem size_emptyWithCapacity {c} : (emptyWithCapacity c : Raw α).size = 0 := HashMap.Raw.size_emptyWithCapacity -@[simp] +@[simp, grind =] theorem size_empty : (∅ : Raw α).size = 0 := HashMap.Raw.size_empty @@ -48,11 +50,11 @@ theorem isEmpty_eq_size_eq_zero : m.isEmpty = (m.size == 0) := variable [BEq α] [Hashable α] -@[simp] +@[simp, grind =] theorem isEmpty_emptyWithCapacity {c} : (emptyWithCapacity c : Raw α).isEmpty := HashMap.Raw.isEmpty_emptyWithCapacity -@[simp] +@[simp, grind =] theorem isEmpty_empty : (∅ : Raw α).isEmpty := HashMap.Raw.isEmpty_empty @@ -60,7 +62,7 @@ set_option linter.missingDocs false in @[deprecated isEmpty_empty (since := "2025-03-12")] abbrev isEmpty_emptyc := @isEmpty_empty -@[simp] +@[simp, grind =] theorem isEmpty_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} : (m.insert a).isEmpty = false := HashMap.Raw.isEmpty_insertIfNew h.out @@ -80,13 +82,13 @@ theorem mem_congr [EquivBEq α] [LawfulHashable α] (h : m.WF) {a b : α} (hab : a ∈ m ↔ b ∈ m := HashMap.Raw.mem_congr h.out hab -@[simp] theorem contains_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : Raw α).contains a = false := +@[simp, grind =] theorem contains_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : Raw α).contains a = false := HashMap.Raw.contains_emptyWithCapacity -@[simp] theorem not_mem_emptyWithCapacity {a : α} {c} : ¬a ∈ (emptyWithCapacity c : Raw α) := +@[simp, grind] theorem not_mem_emptyWithCapacity {a : α} {c} : ¬a ∈ (emptyWithCapacity c : Raw α) := HashMap.Raw.not_mem_emptyWithCapacity -@[simp] theorem contains_empty {a : α} : (∅ : Raw α).contains a = false := +@[simp, grind =] theorem contains_empty {a : α} : (∅ : Raw α).contains a = false := HashMap.Raw.contains_empty set_option linter.missingDocs false in @@ -128,12 +130,12 @@ theorem isEmpty_iff_forall_not_mem [EquivBEq α] [LawfulHashable α] (h : m.WF) @[simp] theorem singleton_eq_insert {a : α} : Singleton.singleton a = (∅ : Raw α).insert a := rfl -@[simp] +@[simp, grind =] theorem contains_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : (m.insert k).contains a = (k == a || m.contains a) := HashMap.Raw.contains_insertIfNew h.out -@[simp] +@[simp, grind =] theorem mem_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : a ∈ m.insert k ↔ k == a ∨ a ∈ m := HashMap.Raw.mem_insertIfNew h.out @@ -167,7 +169,7 @@ theorem contains_insert_self [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : theorem mem_insert_self [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} : k ∈ m.insert k := HashMap.Raw.mem_insertIfNew_self h.out -theorem size_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} : +@[grind =]theorem size_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} : (m.insert k).size = if k ∈ m then m.size else m.size + 1 := HashMap.Raw.size_insertIfNew h.out @@ -179,11 +181,11 @@ theorem size_insert_le [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} : (m.insert k).size ≤ m.size + 1 := HashMap.Raw.size_insertIfNew_le h.out -@[simp] +@[simp, grind =] theorem erase_emptyWithCapacity {k : α} {c : Nat} : (emptyWithCapacity c : Raw α).erase k = emptyWithCapacity c := ext HashMap.Raw.erase_emptyWithCapacity -@[simp] +@[simp, grind =] theorem erase_empty {k : α} : (∅ : Raw α).erase k = ∅ := ext HashMap.Raw.erase_empty @@ -191,17 +193,17 @@ set_option linter.missingDocs false in @[deprecated erase_empty (since := "2025-03-12")] abbrev erase_emptyc := @erase_empty -@[simp] +@[simp, grind =] theorem isEmpty_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} : (m.erase k).isEmpty = (m.isEmpty || (m.size == 1 && m.contains k)) := HashMap.Raw.isEmpty_erase h.out -@[simp] +@[simp, grind =] theorem contains_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : (m.erase k).contains a = (!(k == a) && m.contains a) := HashMap.Raw.contains_erase h.out -@[simp] +@[simp, grind =] theorem mem_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : a ∈ m.erase k ↔ (k == a) = false ∧ a ∈ m := HashMap.Raw.mem_erase h.out @@ -214,6 +216,7 @@ theorem mem_of_mem_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} a ∈ m.erase k → a ∈ m := HashMap.Raw.mem_of_mem_erase h.out +@[grind =] theorem size_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} : (m.erase k).size = if k ∈ m then m.size - 1 else m.size := HashMap.Raw.size_erase h.out @@ -226,11 +229,11 @@ theorem size_le_size_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} m.size ≤ (m.erase k).size + 1 := HashMap.Raw.size_le_size_erase h.out -@[simp] +@[simp, grind =] theorem get?_emptyWithCapacity {a : α} {c} : (emptyWithCapacity c : Raw α).get? a = none := HashMap.Raw.getKey?_emptyWithCapacity -@[simp] +@[simp, grind =] theorem get?_empty {a : α} : (∅ : Raw α).get? a = none := HashMap.Raw.getKey?_empty @@ -242,7 +245,7 @@ theorem get?_of_isEmpty [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} : m.isEmpty = true → m.get? a = none := HashMap.Raw.getKey?_of_isEmpty h.out -theorem get?_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : +@[grind =] theorem get?_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : (m.insert k).get? a = if k == a ∧ ¬k ∈ m then some k else m.get? a := HashMap.Raw.getKey?_insertIfNew h.out @@ -272,7 +275,7 @@ theorem get?_eq_none [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} : ¬a ∈ m → m.get? a = none := HashMap.Raw.getKey?_eq_none h.out -theorem get?_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : +@[grind =] theorem get?_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : (m.erase k).get? a = if k == a then none else m.get? a := HashMap.Raw.getKey?_erase h.out @@ -292,12 +295,12 @@ theorem get?_eq_some [LawfulBEq α] (h : m.WF) {k : α} (h' : k ∈ m) : m.get? k = some k := HashMap.Raw.getKey?_eq_some h.out h' -theorem get_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {h₁} : +@[grind =] theorem get_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {h₁} : (m.insert k).get a h₁ = if h₂ : k == a ∧ ¬k ∈ m then k else m.get a (mem_of_mem_insert' h h₁ h₂) := HashMap.Raw.getKey_insertIfNew (h₁ := h₁) h.out -@[simp] +@[simp, grind =] theorem get_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} {h'} : (m.erase k).get a h' = m.get a (mem_of_mem_erase h h') := HashMap.Raw.getKey_erase (h' := h') h.out @@ -310,7 +313,7 @@ theorem get_eq_get_get? [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {h m.get k h' = (m.get? k).get ((mem_iff_isSome_get? h).mp h') := HashMap.Raw.getKey_eq_get_getKey? h.out -theorem get_get? [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {h'} : +@[grind =] theorem get_get? [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} {h'} : (m.get? k).get h' = m.get k ((mem_iff_isSome_get? h).mpr h') := HashMap.Raw.get_getKey? h.out @@ -328,16 +331,16 @@ theorem get_congr [EquivBEq α] [LawfulHashable α] (h : m.WF) {k₁ k₂ : α} m.get k₁ h₁ = m.get k₂ (((mem_congr h h').mp h₁)) := HashMap.Raw.getKey_congr h.out h' h₁ -@[simp] +@[simp, grind =] theorem get_eq [LawfulBEq α] (h : m.WF) {k : α} (h' : m.contains k) : m.get k h' = k := HashMap.Raw.getKey_eq h.out h' -@[simp] +@[simp, grind =] theorem get!_emptyWithCapacity [Inhabited α] {a : α} {c} : (emptyWithCapacity c : Raw α).get! a = default := HashMap.Raw.getKey!_emptyWithCapacity -@[simp] +@[simp, grind =] theorem get!_empty [Inhabited α] {a : α} : (∅ : Raw α).get! a = default := HashMap.Raw.getKey!_empty @@ -349,7 +352,7 @@ theorem get!_of_isEmpty [Inhabited α] [EquivBEq α] [LawfulHashable α] (h : m. m.isEmpty = true → m.get! a = default := HashMap.Raw.getKey!_of_isEmpty h.out -theorem get!_insert [Inhabited α] [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : +@[grind =] theorem get!_insert [Inhabited α] [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : (m.insert k).get! a = if k == a ∧ ¬k ∈ m then k else m.get! a := HashMap.Raw.getKey!_insertIfNew h.out @@ -362,7 +365,7 @@ theorem get!_eq_default [Inhabited α] [EquivBEq α] [LawfulHashable α] (h : m. ¬a ∈ m → m.get! a = default := HashMap.Raw.getKey!_eq_default h.out -theorem get!_erase [Inhabited α] [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : +@[grind =] theorem get!_erase [Inhabited α] [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a : α} : (m.erase k).get! a = if k == a then default else m.get! a := HashMap.Raw.getKey!_erase h.out @@ -398,11 +401,11 @@ theorem get!_eq_of_contains [LawfulBEq α] [Inhabited α] (h : m.WF) {k : α} (h theorem get!_eq_of_mem [LawfulBEq α] [Inhabited α] (h : m.WF) {k : α} (h' : k ∈ m) : m.get! k = k := HashMap.Raw.getKey!_eq_of_mem h.out h' -@[simp] +@[simp, grind =] theorem getD_emptyWithCapacity {a fallback : α} {c} : (emptyWithCapacity c : Raw α).getD a fallback = fallback := HashMap.Raw.getKeyD_emptyWithCapacity -@[simp] +@[simp, grind =] theorem getD_empty {a fallback : α} : (∅ : Raw α).getD a fallback = fallback := HashMap.Raw.getKeyD_empty @@ -414,7 +417,7 @@ theorem getD_of_isEmpty [EquivBEq α] [LawfulHashable α] (h : m.WF) {a fallback m.isEmpty = true → m.getD a fallback = fallback := HashMap.Raw.getKeyD_of_isEmpty h.out -theorem getD_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} : +@[grind =] theorem getD_insert [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} : (m.insert k).getD a fallback = if k == a ∧ ¬k ∈ m then k else m.getD a fallback := HashMap.Raw.getKeyD_insertIfNew h.out @@ -427,7 +430,7 @@ theorem getD_eq_fallback [EquivBEq α] [LawfulHashable α] (h : m.WF) {a fallbac ¬a ∈ m → m.getD a fallback = fallback := HashMap.Raw.getKeyD_eq_fallback h.out -theorem getD_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} : +@[grind =] theorem getD_erase [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fallback : α} : (m.erase k).getD a fallback = if k == a then fallback else m.getD a fallback := HashMap.Raw.getKeyD_erase h.out @@ -469,30 +472,30 @@ theorem getD_eq_of_mem [LawfulBEq α] (h : m.WF) {k fallback : α} (h' : k ∈ m m.getD k fallback = k := HashMap.Raw.getKeyD_eq_of_mem h.out h' -@[simp] +@[simp, grind =] theorem containsThenInsert_fst (h : m.WF) {k : α} : (m.containsThenInsert k).1 = m.contains k := HashMap.Raw.containsThenInsertIfNew_fst h.out -@[simp] +@[simp, grind =] theorem containsThenInsert_snd (h : m.WF) {k : α} : (m.containsThenInsert k).2 = m.insert k := ext (HashMap.Raw.containsThenInsertIfNew_snd h.out) -@[simp] +@[simp, grind =] theorem length_toList [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.toList.length = m.size := HashMap.Raw.length_keys h.1 -@[simp] +@[simp, grind =] theorem isEmpty_toList [EquivBEq α] [LawfulHashable α] (h : m.WF) : m.toList.isEmpty = m.isEmpty := HashMap.Raw.isEmpty_keys h.1 -@[simp] +@[simp, grind =] theorem contains_toList [EquivBEq α] [LawfulHashable α] {k : α} (h : m.WF) : m.toList.contains k = m.contains k := HashMap.Raw.contains_keys h.1 -@[simp] +@[simp, grind =] theorem mem_toList [LawfulBEq α] [LawfulHashable α] (h : m.WF) {k : α} : k ∈ m.toList ↔ k ∈ m := HashMap.Raw.mem_keys h.1 @@ -515,7 +518,7 @@ theorem fold_eq_foldl_toList (h : m.WF) {f : δ → α → δ} {init : δ} : HashMap.Raw.fold_eq_foldl_keys h.out omit [BEq α] [Hashable α] in -@[simp] +@[simp, grind =] theorem forM_eq_forM [Monad m'] [LawfulMonad m'] {f : α → m' PUnit} : m.forM f = ForM.forM m f := rfl @@ -524,7 +527,7 @@ theorem forM_eq_forM_toList [Monad m'] [LawfulMonad m'] (h : m.WF) {f : α → m HashMap.Raw.forM_eq_forM_keys h.out omit [BEq α] [Hashable α] in -@[simp] +@[simp, grind =] theorem forIn_eq_forIn [Monad m'] [LawfulMonad m'] {f : α → δ → m' (ForInStep δ)} {init : δ} : m.forIn f init = ForIn.forIn m init f := rfl @@ -538,20 +541,22 @@ end monadic variable {ρ : Type v} [ForIn Id ρ α] -@[simp] +@[simp, grind =] theorem insertMany_nil (h : m.WF) : insertMany m [] = m := ext (HashMap.Raw.insertManyIfNewUnit_nil h.1) -@[simp] +@[simp, grind =] theorem insertMany_list_singleton (h : m.WF) {k : α} : insertMany m [k] = m.insert k := ext (HashMap.Raw.insertManyIfNewUnit_list_singleton h.1) +@[grind _=_] theorem insertMany_cons (h : m.WF) {l : List α} {k : α} : insertMany m (k :: l) = insertMany (m.insert k) l := ext (HashMap.Raw.insertManyIfNewUnit_cons h.1) +@[grind _=_] theorem insertMany_append (h : m.WF) {l₁ l₂ : List α} : insertMany m (l₁ ++ l₂) = insertMany (insertMany m l₁) l₂ := by induction l₁ generalizing m with @@ -566,13 +571,13 @@ theorem insertMany_ind {motive : Raw α → Prop} (m : Raw α) (l : ρ) show motive ⟨m.1.insertManyIfNewUnit l⟩ from HashMap.Raw.insertManyIfNewUnit_ind m.inner l init fun m => insert ⟨m⟩ -@[simp] +@[simp, grind =] theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List α} {k : α} : (insertMany m l).contains k = (m.contains k || l.contains k) := HashMap.Raw.contains_insertManyIfNewUnit_list h.1 -@[simp] +@[simp, grind =] theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List α} {k : α} : k ∈ insertMany m l ↔ k ∈ m ∨ l.contains k := @@ -677,12 +682,16 @@ theorem size_le_size_insertMany [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : ρ} : m.size ≤ (insertMany m l).size := HashMap.Raw.size_le_size_insertManyIfNewUnit h.out +grind_pattern size_le_size_insertMany => (insertMany m l).size + theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List α} : (insertMany m l).size ≤ m.size + l.length := HashMap.Raw.size_insertManyIfNewUnit_list_le h.1 -@[simp] +grind_pattern size_insertMany_list_le => (insertMany m l).size + +@[simp, grind =] theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List α} : (insertMany m l).isEmpty = (m.isEmpty && l.isEmpty) := @@ -692,27 +701,28 @@ theorem isEmpty_of_isEmpty_insertMany [EquivBEq α] [LawfulHashable α] (h : m.W {l : ρ} : (insertMany m l).isEmpty → m.isEmpty := HashMap.Raw.isEmpty_of_isEmpty_insertManyIfNewUnit h.out -@[simp] +@[simp, grind =] theorem ofList_nil : ofList ([] : List α) = ∅ := ext HashMap.Raw.unitOfList_nil -@[simp] +@[simp, grind =] theorem ofList_singleton {k : α} : ofList [k] = (∅ : Raw α).insert k := ext HashMap.Raw.unitOfList_singleton +@[grind _=_] theorem ofList_cons {hd : α} {tl : List α} : ofList (hd :: tl) = insertMany ((∅ : Raw α).insert hd) tl := ext HashMap.Raw.unitOfList_cons -@[simp] +@[simp, grind =] theorem contains_ofList [EquivBEq α] [LawfulHashable α] {l : List α} {k : α} : (ofList l).contains k = l.contains k := HashMap.Raw.contains_unitOfList -@[simp] +@[simp, grind =] theorem mem_ofList [EquivBEq α] [LawfulHashable α] {l : List α} {k : α} : k ∈ ofList l ↔ l.contains k := @@ -774,7 +784,9 @@ theorem size_ofList_le [EquivBEq α] [LawfulHashable α] (ofList l).size ≤ l.length := HashMap.Raw.size_unitOfList_le -@[simp] +grind_pattern size_ofList_le => (ofList l).size + +@[simp, grind =] theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α] {l : List α} : (ofList l).isEmpty = l.isEmpty := @@ -896,7 +908,7 @@ theorem toList_filter {f : α → Bool} (h : m.WF) : (m.filter f).toList.Perm (m.toList.filter f) := HashMap.Raw.keys_filter_key h.1 -theorem isEmpty_filter_iff [EquivBEq α] [LawfulHashable α] +@[grind =] theorem isEmpty_filter_iff [EquivBEq α] [LawfulHashable α] {f : α → Bool} (h : m.WF) : (m.filter f).isEmpty ↔ ∀ (k : α) (h : k ∈ m), f (m.get k h) = false := @@ -908,7 +920,9 @@ theorem isEmpty_filter_eq_false_iff [EquivBEq α] [LawfulHashable α] ∃ (k : α) (h : k ∈ m), f (m.get k h) := HashMap.Raw.isEmpty_filter_eq_false_iff h.out -@[simp] +-- TODO: `contains_filter` is missing. + +@[simp, grind =] theorem mem_filter [EquivBEq α] [LawfulHashable α] {f : α → Bool} {k : α} (h : m.WF) : (k ∈ m.filter f) ↔ ∃ (h' : k ∈ m), f (m.get k h') := @@ -924,6 +938,8 @@ theorem size_filter_le_size [EquivBEq α] [LawfulHashable α] (m.filter f).size ≤ m.size := HashMap.Raw.size_filter_le_size h.out +grind_pattern size_filter_le_size => (m.filter f).size + theorem size_filter_eq_size_iff [EquivBEq α] [LawfulHashable α] {f : α → Bool} (h : m.WF) : (m.filter f).size = m.size ↔ ∀ (k : α) (h : k ∈ m), f (m.get k h) := @@ -935,24 +951,24 @@ theorem filter_equiv_self_iff [EquivBEq α] [LawfulHashable α] ⟨fun h' => (HashMap.Raw.filter_equiv_self_iff h.out).mp h'.1, fun h' => ⟨(HashMap.Raw.filter_equiv_self_iff h.out).mpr h'⟩⟩ -@[simp] +@[simp, grind =] theorem get?_filter [EquivBEq α] [LawfulHashable α] {f : α → Bool} {k : α} (h : m.WF) : (m.filter f).get? k = (m.get? k).filter f := HashMap.Raw.getKey?_filter_key h.out -@[simp] +@[simp, grind =] theorem get_filter [EquivBEq α] [LawfulHashable α] {f : α → Bool} {k : α} {h'} (h : m.WF) : (m.filter f).get k h' = (m.get k (mem_of_mem_filter h h')) := HashMap.Raw.getKey_filter h.out -theorem get!_filter [EquivBEq α] [LawfulHashable α] [Inhabited α] +@[grind =] theorem get!_filter [EquivBEq α] [LawfulHashable α] [Inhabited α] {f : α → Bool} {k : α} (h : m.WF) : (m.filter f).get! k = ((m.get? k).filter f).get! := HashMap.Raw.getKey!_filter_key h.out -theorem getD_filter [EquivBEq α] [LawfulHashable α] +@[grind =] theorem getD_filter [EquivBEq α] [LawfulHashable α] {f : α → Bool} {k fallback : α} (h : m.WF) : (m.filter f).getD k fallback = ((m.get? k).filter f).getD fallback := HashMap.Raw.getKeyD_filter_key h.out diff --git a/src/Std/Data/TreeMap/Raw/Lemmas.lean b/src/Std/Data/TreeMap/Raw/Lemmas.lean index 639cc30c1e..44ac4c2407 100644 --- a/src/Std/Data/TreeMap/Raw/Lemmas.lean +++ b/src/Std/Data/TreeMap/Raw/Lemmas.lean @@ -920,6 +920,7 @@ theorem insertMany_cons {l : List (α × β)} {k : α} {v : β} : t.insertMany (⟨k, v⟩ :: l) = (t.insert k v).insertMany l := ext <| DTreeMap.Raw.Const.insertMany_cons +@[grind _=_] theorem insertMany_append {l₁ l₂ : List (α × β)} : insertMany t (l₁ ++ l₂) = insertMany (insertMany t l₁) l₂ := by induction l₁ generalizing t with diff --git a/src/Std/Data/TreeSet/Lemmas.lean b/src/Std/Data/TreeSet/Lemmas.lean index ce8a21e861..7b0c5a6fa7 100644 --- a/src/Std/Data/TreeSet/Lemmas.lean +++ b/src/Std/Data/TreeSet/Lemmas.lean @@ -490,6 +490,7 @@ theorem insertMany_cons {l : List α} {k : α} : t.insertMany (k :: l) = (t.insert k).insertMany l := ext TreeMap.insertManyIfNewUnit_cons +@[grind _=_] theorem insertMany_append {l₁ l₂ : List α} : insertMany t (l₁ ++ l₂) = insertMany (insertMany t l₁) l₂ := by induction l₁ generalizing t with diff --git a/src/Std/Data/TreeSet/Raw/Lemmas.lean b/src/Std/Data/TreeSet/Raw/Lemmas.lean index dceafef89f..a6cb25a956 100644 --- a/src/Std/Data/TreeSet/Raw/Lemmas.lean +++ b/src/Std/Data/TreeSet/Raw/Lemmas.lean @@ -488,6 +488,7 @@ theorem insertMany_cons {l : List α} {k : α} : t.insertMany (k :: l) = (t.insert k).insertMany l := ext TreeMap.Raw.insertManyIfNewUnit_cons +@[grind _=_] theorem insertMany_append {l₁ l₂ : List α} : insertMany t (l₁ ++ l₂) = insertMany (insertMany t l₁) l₂ := by induction l₁ generalizing t with diff --git a/tests/lean/grind/experiments/map.lean b/tests/lean/grind/experiments/map.lean new file mode 100644 index 0000000000..1480ea3865 --- /dev/null +++ b/tests/lean/grind/experiments/map.lean @@ -0,0 +1,26 @@ +import Std.Data.HashMap +import Std.Data.DHashMap +import Std.Data.ExtHashMap +set_option grind.warning false + +open Std + +-- Do we want this? +example (m : HashMap Nat Nat) (h : m.isEmpty) : m[3]? = none := by grind [HashMap.getElem?_of_isEmpty] + +-- Don't just use `@[grind]`, instead add two patterns! +-- Do this for List etc? +-- attribute [grind] HashMap.getElem?_eq_some_getElem -- Do we do this for list? +grind_pattern HashMap.getElem?_eq_some_getElem => a ∈ m, m[a]? + +example (m : HashMap Nat Nat) : ((m.alter 5 id).erase 7).size ≥ m.size - 1 := by grind + +example (m : ExtHashMap Nat Nat) : + (m.insert 1 2).filter (fun k v => k > 1000) = (m.insert 1 3).filter fun k v => k > 1000 := by + ext1 k + grind + +example (m : ExtHashMap Nat Nat) : + (((m.insert 1 2).insert 3 4).insert 5 6).filter (fun k v => k > 6) = m.filter fun k v => k > 6 := by + ext1 k + grind diff --git a/tests/lean/run/grind_map.lean b/tests/lean/run/grind_map.lean new file mode 100644 index 0000000000..4233c88851 --- /dev/null +++ b/tests/lean/run/grind_map.lean @@ -0,0 +1,34 @@ +import Std.Data.HashMap +import Std.Data.DHashMap +import Std.Data.ExtHashMap +import Std.Data.HashSet +set_option grind.warning false + +open Std + +section + +variable [BEq α] [LawfulBEq α] [Hashable α] [LawfulHashable α ] + +example : (∅ : DHashMap α β).isEmpty := by grind +example (m : DHashMap α β) (h : m = ∅) : m.isEmpty := by grind + +example : (((∅ : HashMap Nat Nat).insert 3 6).insert 4 7).contains 3 := by grind + +example : (((∅ : HashMap Nat Nat).insert 3 6).insert 4 7).contains 9 == false := by grind + +example (m : HashMap Nat Nat) (h : m.contains 3) : (m.erase 2).contains 3 := by grind +example (m : HashMap Nat Nat) (h : (m.erase 2).contains 3) : m.contains 3 := by grind +example (m : HashMap Nat Nat) : (m.erase 3).contains 3 = false := by grind +example (m : HashMap Nat Nat) (h : m.contains 3 = false) : (m.erase 2).contains 3 = false := by grind + +-- Insert twice +example (m : HashMap Nat Nat) : m.size ≤ ((m.insert 1 2).insert 3 4).size := by grind +example (m : HashMap Nat Nat) : ((m.insert 1 2).insert 3 4).size ≤ m.size + 2 := by grind +-- Insert the same key twice +example (m : HashMap Nat Nat) : m.size ≤ ((m.insert 1 2).insert 1 4).size := by grind +example (m : HashMap Nat Nat) : ((m.insert 1 2).insert 1 4).size ≤ m.size + 1 := by grind + +example : (((∅ : HashMap Nat Nat).insert 3 6).erase 4)[3]? = some 6 := by grind + +end diff --git a/tests/lean/run/grind_map_uniform.lean b/tests/lean/run/grind_map_uniform.lean new file mode 100644 index 0000000000..59863ee1a7 --- /dev/null +++ b/tests/lean/run/grind_map_uniform.lean @@ -0,0 +1,12 @@ +import Lean.Meta.Tactic.Grind +import Std.Data.DHashMap +import Std.Data.HashMap +import Std.Data.HashSet +import Std.Data.TreeMap +import Std.Data.TreeSet + +#eval Lean.Meta.Grind.isEMatchTheorem `Std.DHashMap.isEmpty_emptyWithCapacity +#eval Lean.Meta.Grind.isEMatchTheorem `Std.HashMap.isEmpty_emptyWithCapacity +#eval Lean.Meta.Grind.isEMatchTheorem `Std.HashSet.isEmpty_emptyWithCapacity +#eval Lean.Meta.Grind.isEMatchTheorem `Std.TreeMap.isEmpty_emptyWithCapacity +#eval Lean.Meta.Grind.isEMatchTheorem `Std.TreeSet.isEmpty_emptyWithCapacity