lean4-htt/src/Std/Data/TreeMap/Lemmas.lean
Wojciech Różowski 361bfdbc5c
refactor: HashMap/TreeMap and their extensional variants to use getElem instance (#11578)
This PR refactors the usage of `get` operation on
`HashMap`/`TreeMap`/`ExtHashMap`/`ExtTreeMap` to `getElem` instace.
2025-12-10 17:52:34 +00:00

4838 lines
178 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel, Paul Reichert
-/
module
prelude
import Std.Data.DTreeMap.Lemmas
public import Std.Data.TreeMap.AdditionalOperations
@[expose] public section
/-!
# Tree map lemmas
This file contains lemmas about `Std.TreeMap`. Most of the lemmas require
`TransCmp cmp` for the comparison function `cmp`.
-/
set_option linter.missingDocs true
set_option autoImplicit false
universe u v w w'
namespace Std.TreeMap
variable {α : Type u} {β : Type v} {γ : Type w} {δ : Type w} {cmp : αα → Ordering} {t : TreeMap α β cmp}
private theorem ext {t t' : TreeMap α β cmp} : t.inner = t'.inner → t = t' := by
cases t; cases t'; rintro rfl; rfl
@[simp, grind =]
theorem isEmpty_emptyc : (∅ : TreeMap α β cmp).isEmpty :=
DTreeMap.isEmpty_emptyc
@[simp, grind =]
theorem isEmpty_insert [TransCmp cmp] {k : α} {v : β} :
(t.insert k v).isEmpty = false :=
DTreeMap.isEmpty_insert
theorem mem_iff_contains {k : α} : k ∈ t ↔ t.contains k :=
DTreeMap.mem_iff_contains
@[simp, grind _=_]
theorem contains_iff_mem {k : α} : t.contains k ↔ k ∈ t :=
DTreeMap.contains_iff_mem
theorem contains_congr [TransCmp cmp] {k k' : α} (hab : cmp k k' = .eq) :
t.contains k = t.contains k' :=
DTreeMap.contains_congr hab
theorem mem_congr [TransCmp cmp] {k k' : α} (hab : cmp k k' = .eq) : k ∈ t ↔ k' ∈ t :=
DTreeMap.mem_congr hab
@[simp, grind =]
theorem contains_emptyc {k : α} : (∅ : TreeMap α β cmp).contains k = false :=
DTreeMap.contains_emptyc
@[simp]
theorem not_mem_emptyc {k : α} : k ∉ (∅ : TreeMap α β cmp) :=
DTreeMap.not_mem_emptyc
theorem contains_of_isEmpty [TransCmp cmp] {a : α} :
t.isEmpty → t.contains a = false :=
DTreeMap.contains_of_isEmpty
theorem not_mem_of_isEmpty [TransCmp cmp] {a : α} :
t.isEmpty → a ∉ t :=
DTreeMap.not_mem_of_isEmpty
theorem isEmpty_eq_false_iff_exists_contains_eq_true [TransCmp cmp] :
t.isEmpty = false ↔ ∃ a, t.contains a = true :=
DTreeMap.isEmpty_eq_false_iff_exists_contains_eq_true
theorem isEmpty_eq_false_iff_exists_mem [TransCmp cmp] :
t.isEmpty = false ↔ ∃ a, a ∈ t :=
DTreeMap.isEmpty_eq_false_iff_exists_mem
theorem isEmpty_eq_false_of_contains [TransCmp cmp] {a : α} (hc : t.contains a = true) :
t.isEmpty = false :=
DTreeMap.isEmpty_eq_false_of_contains hc
theorem isEmpty_iff_forall_contains [TransCmp cmp] :
t.isEmpty = true ↔ ∀ a, t.contains a = false :=
DTreeMap.isEmpty_iff_forall_contains
theorem isEmpty_iff_forall_not_mem [TransCmp cmp] :
t.isEmpty = true ↔ ∀ a, ¬a ∈ t :=
DTreeMap.isEmpty_iff_forall_not_mem
@[simp]
theorem insert_eq_insert {p : α × β} : Insert.insert p t = t.insert p.1 p.2 :=
rfl
@[simp]
theorem singleton_eq_insert {p : α × β} :
Singleton.singleton p = (∅ : TreeMap α β cmp).insert p.1 p.2 :=
rfl
@[simp, grind =]
theorem contains_insert [h : TransCmp cmp] {k a : α} {v : β} :
(t.insert k v).contains a = (cmp k a == .eq || t.contains a) :=
DTreeMap.contains_insert
@[simp, grind =]
theorem mem_insert [TransCmp cmp] {k a : α} {v : β} :
a ∈ t.insert k v ↔ cmp k a = .eq a ∈ t :=
DTreeMap.mem_insert
theorem contains_insert_self [TransCmp cmp] {k : α} {v : β} :
(t.insert k v).contains k :=
DTreeMap.contains_insert_self
theorem mem_insert_self [TransCmp cmp] {k : α} {v : β} :
k ∈ t.insert k v :=
DTreeMap.mem_insert_self
theorem contains_of_contains_insert [TransCmp cmp] {k a : α} {v : β} :
(t.insert k v).contains a → cmp k a ≠ .eq → t.contains a :=
DTreeMap.contains_of_contains_insert
theorem mem_of_mem_insert [TransCmp cmp] {k a : α} {v : β} :
a ∈ t.insert k v → cmp k a ≠ .eq → a ∈ t :=
DTreeMap.mem_of_mem_insert
@[simp, grind =]
theorem size_emptyc : (∅ : TreeMap α β cmp).size = 0 :=
DTreeMap.size_emptyc
theorem isEmpty_eq_size_eq_zero :
t.isEmpty = (t.size == 0) :=
DTreeMap.isEmpty_eq_size_eq_zero
@[grind =] theorem size_insert [TransCmp cmp] {k : α} {v : β} :
(t.insert k v).size = if t.contains k then t.size else t.size + 1 :=
DTreeMap.size_insert
theorem size_le_size_insert [TransCmp cmp] {k : α} {v : β} :
t.size ≤ (t.insert k v).size :=
DTreeMap.size_le_size_insert
theorem size_insert_le [TransCmp cmp] {k : α} {v : β} :
(t.insert k v).size ≤ t.size + 1 :=
DTreeMap.size_insert_le
@[simp, grind =]
theorem erase_emptyc {k : α} :
(∅ : TreeMap α β cmp).erase k = ∅ :=
ext <| DTreeMap.erase_emptyc
@[simp, grind =]
theorem isEmpty_erase [TransCmp cmp] {k : α} :
(t.erase k).isEmpty = (t.isEmpty || (t.size == 1 && t.contains k)) :=
DTreeMap.isEmpty_erase
theorem isEmpty_eq_isEmpty_erase_and_not_contains [TransCmp cmp] (k : α) :
t.isEmpty = ((t.erase k).isEmpty && !(t.contains k)) :=
DTreeMap.isEmpty_eq_isEmpty_erase_and_not_contains k
theorem isEmpty_eq_false_of_isEmpty_erase_eq_false [TransCmp cmp] {k : α}
(he : (t.erase k).isEmpty = false) :
t.isEmpty = false :=
DTreeMap.isEmpty_eq_false_of_isEmpty_erase_eq_false he
@[simp, grind =]
theorem contains_erase [TransCmp cmp] {k a : α} :
(t.erase k).contains a = (cmp k a != .eq && t.contains a) :=
DTreeMap.contains_erase
@[simp, grind =]
theorem mem_erase [TransCmp cmp] {k a : α} :
a ∈ t.erase k ↔ cmp k a ≠ .eq ∧ a ∈ t :=
DTreeMap.mem_erase
theorem contains_of_contains_erase [TransCmp cmp] {k a : α} :
(t.erase k).contains a → t.contains a :=
DTreeMap.contains_of_contains_erase
theorem mem_of_mem_erase [TransCmp cmp] {k a : α} :
a ∈ t.erase k → a ∈ t :=
DTreeMap.mem_of_mem_erase
@[grind =] theorem size_erase [TransCmp cmp] {k : α} :
(t.erase k).size = if t.contains k then t.size - 1 else t.size :=
DTreeMap.size_erase
theorem size_erase_le [TransCmp cmp] {k : α} :
(t.erase k).size ≤ t.size :=
DTreeMap.size_erase_le
theorem size_le_size_erase [TransCmp cmp] {k : α} :
t.size ≤ (t.erase k).size + 1 :=
DTreeMap.size_le_size_erase
@[simp, grind =]
theorem containsThenInsert_fst [TransCmp cmp] {k : α} {v : β} :
(t.containsThenInsert k v).1 = t.contains k :=
DTreeMap.containsThenInsert_fst
@[simp, grind =]
theorem containsThenInsert_snd [TransCmp cmp] {k : α} {v : β} :
(t.containsThenInsert k v).2 = t.insert k v :=
ext <| DTreeMap.containsThenInsert_snd
@[simp, grind =]
theorem containsThenInsertIfNew_fst [TransCmp cmp] {k : α} {v : β} :
(t.containsThenInsertIfNew k v).1 = t.contains k :=
DTreeMap.containsThenInsertIfNew_fst
@[simp, grind =]
theorem containsThenInsertIfNew_snd [TransCmp cmp] {k : α} {v : β} :
(t.containsThenInsertIfNew k v).2 = t.insertIfNew k v :=
ext <| DTreeMap.containsThenInsertIfNew_snd
@[simp, grind =] theorem get_eq_getElem {a : α} {h} : get t a h = t[a]'h := rfl
@[simp, grind =] theorem get?_eq_getElem? {a : α} : get? t a = t[a]? := rfl
@[simp, grind =] theorem get!_eq_getElem! [Inhabited β] {a : α} : get! t a = t[a]! := rfl
@[simp, grind =]
theorem getElem?_emptyc [TransCmp cmp] {a : α} :
(∅ : TreeMap α β cmp)[a]? = none :=
DTreeMap.Const.get?_emptyc (cmp := cmp) (a := a)
theorem getElem?_of_isEmpty [TransCmp cmp] {a : α} :
t.isEmpty = true → t[a]? = none :=
DTreeMap.Const.get?_of_isEmpty
@[grind =]
theorem getElem?_insert [TransCmp cmp] {a k : α} {v : β} :
(t.insert k v)[a]? = if cmp k a = .eq then some v else t[a]? :=
DTreeMap.Const.get?_insert
@[simp]
theorem getElem?_insert_self [TransCmp cmp] {k : α} {v : β} :
(t.insert k v)[k]? = some v :=
DTreeMap.Const.get?_insert_self
theorem contains_eq_isSome_getElem? [TransCmp cmp] {a : α} :
t.contains a = t[a]?.isSome :=
DTreeMap.Const.contains_eq_isSome_get?
@[simp]
theorem isSome_getElem?_eq_contains [TransCmp cmp] {a : α} :
t[a]?.isSome = t.contains a :=
contains_eq_isSome_getElem?.symm
theorem mem_iff_isSome_getElem? [TransCmp cmp] {a : α} :
a ∈ t ↔ t[a]?.isSome :=
DTreeMap.Const.mem_iff_isSome_get?
@[simp]
theorem isSome_getElem?_iff_mem [TransCmp cmp] {a : α} :
t[a]?.isSome ↔ a ∈ t :=
mem_iff_isSome_getElem?.symm
theorem getElem?_eq_some_iff [TransCmp cmp] {k : α} {v : β} :
t[k]? = some v ↔ ∃ h, t[k] = v :=
DTreeMap.Const.get?_eq_some_iff
theorem mem_of_getKey?_eq_some [TransCmp cmp] {k k' : α}
(h : t.getKey? k = some k') : k' ∈ t :=
DTreeMap.mem_of_getKey?_eq_some h
theorem getKey?_eq_some_iff [TransCmp cmp] {k k' : α} :
getKey? t k = some k' ↔ ∃ h, getKey t k h = k' :=
DTreeMap.getKey?_eq_some_iff
theorem getElem?_eq_none_of_contains_eq_false [TransCmp cmp] {a : α} :
t.contains a = false → t[a]? = none :=
DTreeMap.Const.get?_eq_none_of_contains_eq_false
theorem getElem?_eq_none [TransCmp cmp] {a : α} :
¬ a ∈ t → t[a]? = none :=
DTreeMap.Const.get?_eq_none
@[grind =] theorem getElem?_erase [TransCmp cmp] {k a : α} :
(t.erase k)[a]? = if cmp k a = .eq then none else t[a]? :=
DTreeMap.Const.get?_erase
@[simp]
theorem getElem?_erase_self [TransCmp cmp] {k : α} :
(t.erase k)[k]? = none :=
DTreeMap.Const.get?_erase_self
theorem getElem?_congr [TransCmp cmp] {a b : α} (hab : cmp a b = .eq) :
t[a]? = t[b]? :=
DTreeMap.Const.get?_congr hab
@[grind =] theorem getElem_insert [TransCmp cmp] {k a : α} {v : β} {h₁} :
(t.insert k v)[a]'h₁ =
if h₂ : cmp k a = .eq then v
else t[a]'(mem_of_mem_insert h₁ h₂) :=
DTreeMap.Const.get_insert
theorem toList_insert_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} {v : β} :
(t.insert k v).toList.Perm (⟨k, v⟩ :: t.toList.filter (¬k == ·.1)) := DTreeMap.Const.toList_insert_perm
theorem keys_insertIfNew_perm {t : TreeMap α Unit cmp} [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} :
(t.insertIfNew k ()).keys.Perm (if k ∈ t then t.keys else k :: t.keys) :=
DTreeMap.keys_insertIfNew_perm
@[simp]
theorem getElem_insert_self [TransCmp cmp] {k : α} {v : β} :
(t.insert k v)[k]'mem_insert_self = v :=
DTreeMap.Const.get_insert_self
@[simp, grind =]
theorem getElem_erase [TransCmp cmp] {k a : α} {h'} :
(t.erase k)[a]'h' = t[a]'(mem_of_mem_erase h') :=
DTreeMap.Const.get_erase
theorem getElem?_eq_some_getElem [TransCmp cmp] {a : α} (h) :
t[a]? = some (t[a]'h) :=
DTreeMap.Const.get?_eq_some_get h
theorem getElem_eq_get_getElem? [TransCmp cmp] {a : α} {h} :
t[a] = t[a]?.get (mem_iff_isSome_getElem?.mp h) :=
DTreeMap.Const.get_eq_get_get?
@[grind =] theorem get_getElem? [TransCmp cmp] {a : α} {h} :
t[a]?.get h = t[a]'(mem_iff_isSome_getElem?.mpr h) :=
DTreeMap.Const.get_get?
theorem getElem_congr [TransCmp cmp] {a b : α} (hab : cmp a b = .eq) {h'} :
t[a]'h' = t[b]'((mem_congr hab).mp h') :=
DTreeMap.Const.get_congr hab
@[simp, grind =]
theorem getElem!_emptyc [TransCmp cmp] [Inhabited β] {a : α} :
(∅ : TreeMap α β cmp)[a]! = default :=
DTreeMap.Const.get!_emptyc (cmp := cmp) (a := a)
theorem getElem!_of_isEmpty [TransCmp cmp] [Inhabited β] {a : α} :
t.isEmpty = true → t[a]! = default :=
DTreeMap.Const.get!_of_isEmpty
@[grind =] theorem getElem!_insert [TransCmp cmp] [Inhabited β] {k a : α} {v : β} :
(t.insert k v)[a]! = if cmp k a = .eq then v else t[a]! :=
DTreeMap.Const.get!_insert
@[simp]
theorem getElem!_insert_self [TransCmp cmp] [Inhabited β] {k : α}
{v : β} : (t.insert k v)[k]! = v :=
DTreeMap.Const.get!_insert_self
theorem getElem!_eq_default_of_contains_eq_false [TransCmp cmp] [Inhabited β] {a : α} :
t.contains a = false → t[a]! = default :=
DTreeMap.Const.get!_eq_default_of_contains_eq_false
theorem getElem!_eq_default [TransCmp cmp] [Inhabited β] {a : α} :
¬ a ∈ t → t[a]! = default :=
DTreeMap.Const.get!_eq_default
@[grind =] theorem getElem!_erase [TransCmp cmp] [Inhabited β] {k a : α} :
(t.erase k)[a]! = if cmp k a = .eq then default else t[a]! :=
DTreeMap.Const.get!_erase
@[simp]
theorem getElem!_erase_self [TransCmp cmp] [Inhabited β] {k : α} :
(t.erase k)[k]! = default :=
DTreeMap.Const.get!_erase_self
theorem getElem?_eq_some_getElem!_of_contains [TransCmp cmp] [Inhabited β] {a : α} :
t.contains a = true → t[a]? = some t[a]! :=
DTreeMap.Const.get?_eq_some_get!
theorem getElem?_eq_some_getElem! [TransCmp cmp] [Inhabited β] {a : α} :
a ∈ t → t[a]? = some t[a]! :=
DTreeMap.Const.get?_eq_some_get!
theorem getElem!_eq_get!_getElem? [TransCmp cmp] [Inhabited β] {a : α} :
t[a]! = t[a]?.get! :=
DTreeMap.Const.get!_eq_get!_get?
theorem getElem_eq_getElem! [TransCmp cmp] [Inhabited β] {a : α} {h} :
t[a]'h = t[a]! :=
DTreeMap.Const.get_eq_get!
theorem getElem!_congr [TransCmp cmp] [Inhabited β] {a b : α}
(hab : cmp a b = .eq) : t[a]! = t[b]! :=
DTreeMap.Const.get!_congr hab
@[simp, grind =]
theorem getD_emptyc [TransCmp cmp] {a : α} {fallback : β} :
getD (∅ : TreeMap α β cmp) a fallback = fallback :=
DTreeMap.Const.getD_emptyc
theorem getD_of_isEmpty [TransCmp cmp] {a : α} {fallback : β} :
t.isEmpty = true → getD t a fallback = fallback :=
DTreeMap.Const.getD_of_isEmpty
@[grind =] theorem getD_insert [TransCmp cmp] {k a : α} {fallback v : β} :
getD (t.insert k v) a fallback = if cmp k a = .eq then v else getD t a fallback :=
DTreeMap.Const.getD_insert
@[simp]
theorem getD_insert_self [TransCmp cmp] {k : α} {fallback v : β} :
getD (t.insert k v) k fallback = v :=
DTreeMap.Const.getD_insert_self
theorem getD_eq_fallback_of_contains_eq_false [TransCmp cmp] {a : α} {fallback : β} :
t.contains a = false → getD t a fallback = fallback :=
DTreeMap.Const.getD_eq_fallback_of_contains_eq_false
theorem getD_eq_fallback [TransCmp cmp] {a : α} {fallback : β} :
¬ a ∈ t → getD t a fallback = fallback :=
DTreeMap.Const.getD_eq_fallback
@[grind =] theorem getD_erase [TransCmp cmp] {k a : α} {fallback : β} :
getD (t.erase k) a fallback = if cmp k a = .eq then
fallback
else
getD t a fallback :=
DTreeMap.Const.getD_erase
@[simp]
theorem getD_erase_self [TransCmp cmp] {k : α} {fallback : β} :
getD (t.erase k) k fallback = fallback :=
DTreeMap.Const.getD_erase_self
theorem getElem?_eq_some_getD_of_contains [TransCmp cmp] {a : α} {fallback : β} :
t.contains a = true → t[a]? = some (getD t a fallback) :=
DTreeMap.Const.get?_eq_some_getD_of_contains
theorem getElem?_eq_some_getD [TransCmp cmp] {a : α} {fallback : β} :
a ∈ t → t[a]? = some (getD t a fallback) :=
DTreeMap.Const.get?_eq_some_getD
theorem getD_eq_getD_getElem? [TransCmp cmp] {a : α} {fallback : β} :
getD t a fallback = t[a]?.getD fallback :=
DTreeMap.Const.getD_eq_getD_get?
theorem getElem_eq_getD [TransCmp cmp] {a : α} {fallback : β} {h} :
t[a]'h = getD t a fallback :=
DTreeMap.Const.get_eq_getD
theorem getElem!_eq_getD_default [TransCmp cmp] [Inhabited β] {a : α} :
t[a]! = getD t a default :=
DTreeMap.Const.get!_eq_getD_default
theorem getD_congr [TransCmp cmp] {a b : α} {fallback : β}
(hab : cmp a b = .eq) : getD t a fallback = getD t b fallback :=
DTreeMap.Const.getD_congr hab
@[simp, grind =]
theorem getKey?_emptyc {a : α} : (∅ : TreeMap α β cmp).getKey? a = none :=
DTreeMap.getKey?_emptyc
theorem getKey?_of_isEmpty [TransCmp cmp] {a : α} :
t.isEmpty = true → t.getKey? a = none :=
DTreeMap.getKey?_of_isEmpty
@[grind =] theorem getKey?_insert [TransCmp cmp] {a k : α} {v : β} :
(t.insert k v).getKey? a = if cmp k a = .eq then some k else t.getKey? a :=
DTreeMap.getKey?_insert
@[simp]
theorem getKey?_insert_self [TransCmp cmp] {k : α} {v : β} :
(t.insert k v).getKey? k = some k :=
DTreeMap.getKey?_insert_self
theorem contains_eq_isSome_getKey? [TransCmp cmp] {a : α} :
t.contains a = (t.getKey? a).isSome :=
DTreeMap.contains_eq_isSome_getKey?
@[simp, grind =]
theorem isSome_getKey?_eq_contains [TransCmp cmp] {a : α} :
(t.getKey? a).isSome = t.contains a :=
contains_eq_isSome_getKey?.symm
theorem mem_iff_isSome_getKey? [TransCmp cmp] {a : α} :
a ∈ t ↔ (t.getKey? a).isSome :=
DTreeMap.mem_iff_isSome_getKey?
@[simp]
theorem isSome_getKey?_iff_mem [TransCmp cmp] {a : α} :
(t.getKey? a).isSome ↔ a ∈ t :=
mem_iff_isSome_getKey?.symm
theorem getKey?_eq_none_of_contains_eq_false [TransCmp cmp] {a : α} :
t.contains a = false → t.getKey? a = none :=
DTreeMap.getKey?_eq_none_of_contains_eq_false
theorem getKey?_eq_none [TransCmp cmp] {a : α} :
¬ a ∈ t → t.getKey? a = none :=
DTreeMap.getKey?_eq_none
@[grind =] theorem getKey?_erase [TransCmp cmp] {k a : α} :
(t.erase k).getKey? a = if cmp k a = .eq then none else t.getKey? a :=
DTreeMap.getKey?_erase
@[simp]
theorem getKey?_erase_self [TransCmp cmp] {k : α} :
(t.erase k).getKey? k = none :=
DTreeMap.getKey?_erase_self
theorem compare_getKey?_self [TransCmp cmp] {k : α} :
(t.getKey? k).all (cmp · k = .eq) :=
DTreeMap.compare_getKey?_self
theorem getKey?_congr [TransCmp cmp] {k k' : α} (h' : cmp k k' = .eq) :
t.getKey? k = t.getKey? k' :=
DTreeMap.getKey?_congr h'
theorem getKey?_eq_some_of_contains [TransCmp cmp] [LawfulEqCmp cmp]
{k : α} (h' : t.contains k) :
t.getKey? k = some k :=
DTreeMap.getKey?_eq_some_of_contains h'
theorem getKey?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} (h' : k ∈ t) :
t.getKey? k = some k :=
DTreeMap.getKey?_eq_some_of_contains h'
@[grind =] theorem getKey_insert [TransCmp cmp] {k a : α} {v : β} {h₁} :
(t.insert k v).getKey a h₁ =
if h₂ : cmp k a = .eq then k else t.getKey a (mem_of_mem_insert h₁ h₂) :=
DTreeMap.getKey_insert
@[simp]
theorem getKey_insert_self [TransCmp cmp] {k : α} {v : β} :
(t.insert k v).getKey k mem_insert_self = k :=
DTreeMap.getKey_insert_self
@[simp, grind =]
theorem getKey_erase [TransCmp cmp] {k a : α} {h'} :
(t.erase k).getKey a h' = t.getKey a (mem_of_mem_erase h') :=
DTreeMap.getKey_erase
theorem getKey?_eq_some_getKey [TransCmp cmp] {a : α} (h') :
t.getKey? a = some (t.getKey a h') :=
DTreeMap.getKey?_eq_some_getKey h'
theorem getKey_eq_get_getKey? [TransCmp cmp] {a : α} {h} :
t.getKey a h = (t.getKey? a).get (mem_iff_isSome_getKey?.mp h) :=
DTreeMap.getKey_eq_get_getKey?
@[simp, grind =]
theorem get_getKey? [TransCmp cmp] {a : α} {h} :
(t.getKey? a).get h = t.getKey a (mem_iff_isSome_getKey?.mpr h) :=
DTreeMap.get_getKey?
theorem compare_getKey_self [TransCmp cmp] {k : α} (h' : k ∈ t) :
cmp (t.getKey k h') k = .eq :=
DTreeMap.compare_getKey_self h'
theorem getKey_congr [TransCmp cmp] {k₁ k₂ : α} (h' : cmp k₁ k₂ = .eq)
(h₁ : k₁ ∈ t) : t.getKey k₁ h₁ = t.getKey k₂ ((mem_congr h').mp h₁) :=
DTreeMap.getKey_congr h' h₁
@[simp, grind =]
theorem getKey_eq [TransCmp cmp] [LawfulEqCmp cmp] {k : α} (h' : k ∈ t) :
t.getKey k h' = k :=
DTreeMap.getKey_eq h'
@[simp, grind =]
theorem getKey!_emptyc {a : α} [Inhabited α] :
(∅ : TreeMap α β cmp).getKey! a = default :=
DTreeMap.getKey!_emptyc
theorem getKey!_of_isEmpty [TransCmp cmp] [Inhabited α] {a : α} :
t.isEmpty = true → t.getKey! a = default :=
DTreeMap.getKey!_of_isEmpty
@[grind =] theorem getKey!_insert [TransCmp cmp] [Inhabited α] {k a : α}
{v : β} : (t.insert k v).getKey! a = if cmp k a = .eq then k else t.getKey! a :=
DTreeMap.getKey!_insert
@[simp]
theorem getKey!_insert_self [TransCmp cmp] [Inhabited α] {a : α}
{b : β} : (t.insert a b).getKey! a = a :=
DTreeMap.getKey!_insert_self
theorem getKey!_eq_default_of_contains_eq_false [TransCmp cmp] [Inhabited α] {a : α} :
t.contains a = false → t.getKey! a = default :=
DTreeMap.getKey!_eq_default_of_contains_eq_false
theorem getKey!_eq_default [TransCmp cmp] [Inhabited α] {a : α} :
¬ a ∈ t → t.getKey! a = default :=
DTreeMap.getKey!_eq_default
@[grind =] theorem getKey!_erase [TransCmp cmp] [Inhabited α] {k a : α} :
(t.erase k).getKey! a = if cmp k a = .eq then default else t.getKey! a :=
DTreeMap.getKey!_erase
@[simp]
theorem getKey!_erase_self [TransCmp cmp] [Inhabited α] {k : α} :
(t.erase k).getKey! k = default :=
DTreeMap.getKey!_erase_self
theorem getKey?_eq_some_getKey!_of_contains [TransCmp cmp] [Inhabited α] {a : α} :
t.contains a = true → t.getKey? a = some (t.getKey! a) :=
DTreeMap.getKey?_eq_some_getKey!_of_contains
theorem getKey?_eq_some_getKey! [TransCmp cmp] [Inhabited α] {a : α} :
a ∈ t → t.getKey? a = some (t.getKey! a) :=
DTreeMap.getKey?_eq_some_getKey!
theorem getKey!_eq_get!_getKey? [TransCmp cmp] [Inhabited α] {a : α} :
t.getKey! a = (t.getKey? a).get! :=
DTreeMap.getKey!_eq_get!_getKey?
theorem getKey_eq_getKey! [TransCmp cmp] [Inhabited α] {a : α} {h} :
t.getKey a h = t.getKey! a :=
DTreeMap.getKey_eq_getKey!
theorem getKey!_congr [TransCmp cmp] [Inhabited α] {k k' : α} (h' : cmp k k' = .eq) :
t.getKey! k = t.getKey! k' :=
DTreeMap.getKey!_congr h'
theorem getKey!_eq_of_contains [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] {k : α}
(h' : t.contains k) :
t.getKey! k = k :=
DTreeMap.getKey!_eq_of_contains h'
theorem getKey!_eq_of_mem [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] {k : α} (h' : k ∈ t) :
t.getKey! k = k :=
DTreeMap.getKey!_eq_of_mem h'
@[simp, grind =]
theorem getKeyD_emptyc {a : α} {fallback : α} :
(∅ : TreeMap α β cmp).getKeyD a fallback = fallback :=
DTreeMap.getKeyD_emptyc
theorem getKeyD_of_isEmpty [TransCmp cmp] {a fallback : α} :
t.isEmpty = true → t.getKeyD a fallback = fallback :=
DTreeMap.getKeyD_of_isEmpty
@[grind =] theorem getKeyD_insert [TransCmp cmp] {k a fallback : α} {v : β} :
(t.insert k v).getKeyD a fallback = if cmp k a = .eq then k else t.getKeyD a fallback :=
DTreeMap.getKeyD_insert
@[simp]
theorem getKeyD_insert_self [TransCmp cmp] {a fallback : α} {b : β} :
(t.insert a b).getKeyD a fallback = a :=
DTreeMap.getKeyD_insert_self
theorem getKeyD_eq_fallback_of_contains_eq_false [TransCmp cmp] {a fallback : α} :
t.contains a = false → t.getKeyD a fallback = fallback :=
DTreeMap.getKeyD_eq_fallback_of_contains_eq_false
theorem getKeyD_eq_fallback [TransCmp cmp] {a fallback : α} :
¬ a ∈ t → t.getKeyD a fallback = fallback :=
DTreeMap.getKeyD_eq_fallback
@[grind =] theorem getKeyD_erase [TransCmp cmp] {k a fallback : α} :
(t.erase k).getKeyD a fallback =
if cmp k a = .eq then fallback else t.getKeyD a fallback :=
DTreeMap.getKeyD_erase
@[simp]
theorem getKeyD_erase_self [TransCmp cmp] {k fallback : α} :
(t.erase k).getKeyD k fallback = fallback :=
DTreeMap.getKeyD_erase_self
theorem getKey?_eq_some_getKeyD_of_contains [TransCmp cmp] {a fallback : α} :
t.contains a = true → t.getKey? a = some (t.getKeyD a fallback) :=
DTreeMap.getKey?_eq_some_getKeyD_of_contains
theorem getKey?_eq_some_getKeyD [TransCmp cmp] {a fallback : α} :
a ∈ t → t.getKey? a = some (t.getKeyD a fallback) :=
DTreeMap.getKey?_eq_some_getKeyD
theorem getKeyD_eq_getD_getKey? [TransCmp cmp] {a fallback : α} :
t.getKeyD a fallback = (t.getKey? a).getD fallback :=
DTreeMap.getKeyD_eq_getD_getKey?
theorem getKey_eq_getKeyD [TransCmp cmp] {a fallback : α} {h} :
t.getKey a h = t.getKeyD a fallback :=
DTreeMap.getKey_eq_getKeyD
theorem getKey!_eq_getKeyD_default [TransCmp cmp] [Inhabited α] {a : α} :
t.getKey! a = t.getKeyD a default :=
DTreeMap.getKey!_eq_getKeyD_default
theorem getKeyD_congr [TransCmp cmp] {k k' fallback : α} (h' : cmp k k' = .eq) :
t.getKeyD k fallback = t.getKeyD k' fallback :=
DTreeMap.getKeyD_congr h'
theorem getKeyD_eq_of_contains [TransCmp cmp] [LawfulEqCmp cmp] {k fallback : α}
(h' : t.contains k) :
t.getKeyD k fallback = k :=
DTreeMap.getKeyD_eq_of_contains h'
theorem getKeyD_eq_of_mem [TransCmp cmp] [LawfulEqCmp cmp] {k fallback : α} (h' : k ∈ t) :
t.getKeyD k fallback = k :=
DTreeMap.getKeyD_eq_of_contains h'
@[simp, grind =]
theorem isEmpty_insertIfNew [TransCmp cmp] {k : α} {v : β} :
(t.insertIfNew k v).isEmpty = false :=
DTreeMap.isEmpty_insertIfNew
@[simp, grind =]
theorem contains_insertIfNew [TransCmp cmp] {k a : α} {v : β} :
(t.insertIfNew k v).contains a = (cmp k a == .eq || t.contains a) :=
DTreeMap.contains_insertIfNew
@[simp, grind =]
theorem mem_insertIfNew [TransCmp cmp] {k a : α} {v : β} :
a ∈ t.insertIfNew k v ↔ cmp k a = .eq a ∈ t :=
DTreeMap.mem_insertIfNew
@[simp]
theorem contains_insertIfNew_self [TransCmp cmp] {k : α} {v : β} :
(t.insertIfNew k v).contains k :=
DTreeMap.contains_insertIfNew_self
@[simp]
theorem mem_insertIfNew_self [TransCmp cmp] {k : α} {v : β} :
k ∈ t.insertIfNew k v :=
DTreeMap.mem_insertIfNew_self
theorem contains_of_contains_insertIfNew [TransCmp cmp] {k a : α} {v : β} :
(t.insertIfNew k v).contains a → cmp k a ≠ .eq → t.contains a :=
DTreeMap.contains_of_contains_insertIfNew
theorem mem_of_mem_insertIfNew [TransCmp cmp] {k a : α} {v : β} :
a ∈ t.insertIfNew k v → cmp k a ≠ .eq → a ∈ t :=
DTreeMap.contains_of_contains_insertIfNew
/-- This is a restatement of `mem_of_mem_insertIfNew` that is written to exactly match the
proof obligation in the statement of `get_insertIfNew`. -/
theorem mem_of_mem_insertIfNew' [TransCmp cmp] {k a : α} {v : β} :
a ∈ (t.insertIfNew k v) → ¬ (cmp k a = .eq ∧ ¬ k ∈ t) → a ∈ t :=
DTreeMap.mem_of_mem_insertIfNew'
@[grind =] theorem size_insertIfNew [TransCmp cmp] {k : α} {v : β} :
(t.insertIfNew k v).size = if k ∈ t then t.size else t.size + 1 :=
DTreeMap.size_insertIfNew
theorem size_le_size_insertIfNew [TransCmp cmp] {k : α} {v : β} :
t.size ≤ (t.insertIfNew k v).size :=
DTreeMap.size_le_size_insertIfNew
theorem size_insertIfNew_le [TransCmp cmp] {k : α} {v : β} :
(t.insertIfNew k v).size ≤ t.size + 1 :=
DTreeMap.size_insertIfNew_le
@[grind =] theorem getElem?_insertIfNew [TransCmp cmp] {k a : α} {v : β} :
(t.insertIfNew k v)[a]? =
if cmp k a = .eq ∧ ¬ k ∈ t then some v else t[a]? :=
DTreeMap.Const.get?_insertIfNew
@[grind =] theorem getElem_insertIfNew [TransCmp cmp] {k a : α} {v : β} {h₁} :
(t.insertIfNew k v)[a]'h₁ =
if h₂ : cmp k a = .eq ∧ ¬ k ∈ t then v else t[a]'(mem_of_mem_insertIfNew' h₁ h₂) :=
DTreeMap.Const.get_insertIfNew
@[grind =] theorem getElem!_insertIfNew [TransCmp cmp] [Inhabited β] {k a : α} {v : β} :
(t.insertIfNew k v)[a]! = if cmp k a = .eq ∧ ¬ k ∈ t then v else t[a]! :=
DTreeMap.Const.get!_insertIfNew
@[grind =] theorem getD_insertIfNew [TransCmp cmp] {k a : α} {fallback v : β} :
getD (t.insertIfNew k v) a fallback =
if cmp k a = .eq ∧ ¬ k ∈ t then v else getD t a fallback :=
DTreeMap.Const.getD_insertIfNew
@[grind =] theorem getKey?_insertIfNew [TransCmp cmp] {k a : α} {v : β} :
(t.insertIfNew k v).getKey? a =
if cmp k a = .eq ∧ ¬ k ∈ t then some k else t.getKey? a :=
DTreeMap.getKey?_insertIfNew
@[grind =] theorem getKey_insertIfNew [TransCmp cmp] {k a : α} {v : β} {h₁} :
(t.insertIfNew k v).getKey a h₁ =
if h₂ : cmp k a = .eq ∧ ¬ k ∈ t then k
else t.getKey a (mem_of_mem_insertIfNew' h₁ h₂) :=
DTreeMap.getKey_insertIfNew
@[grind =] theorem getKey!_insertIfNew [TransCmp cmp] [Inhabited α] {k a : α}
{v : β} :
(t.insertIfNew k v).getKey! a =
if cmp k a = .eq ∧ ¬ k ∈ t then k else t.getKey! a :=
DTreeMap.getKey!_insertIfNew
@[grind =] theorem getKeyD_insertIfNew [TransCmp cmp] {k a fallback : α}
{v : β} :
(t.insertIfNew k v).getKeyD a fallback =
if cmp k a = .eq ∧ ¬ k ∈ t then k else t.getKeyD a fallback :=
DTreeMap.getKeyD_insertIfNew
@[simp, grind =]
theorem getThenInsertIfNew?_fst [TransCmp cmp] {k : α} {v : β} :
(getThenInsertIfNew? t k v).1 = t[k]? :=
DTreeMap.Const.getThenInsertIfNew?_fst
@[simp, grind =]
theorem getThenInsertIfNew?_snd [TransCmp cmp] {k : α} {v : β} :
(getThenInsertIfNew? t k v).2 = t.insertIfNew k v :=
ext <| DTreeMap.Const.getThenInsertIfNew?_snd
instance [TransCmp cmp] : LawfulGetElem (TreeMap α β cmp) α β (fun m a => a ∈ m) where
getElem?_def m a _ := by
split
· exact getElem?_eq_some_getElem _
· exact getElem?_eq_none _
getElem!_def m a := by
rw [getElem!_eq_get!_getElem?]
split <;> simp_all
@[simp, grind =]
theorem length_keys [TransCmp cmp] :
t.keys.length = t.size :=
DTreeMap.length_keys
@[simp, grind =]
theorem isEmpty_keys :
t.keys.isEmpty = t.isEmpty :=
DTreeMap.isEmpty_keys
@[simp, grind =]
theorem contains_keys [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] {k : α} :
t.keys.contains k = t.contains k :=
DTreeMap.contains_keys
@[simp, grind =]
theorem mem_keys [LawfulEqCmp cmp] [TransCmp cmp] {k : α} :
k ∈ t.keys ↔ k ∈ t :=
DTreeMap.mem_keys
theorem mem_of_mem_keys [TransCmp cmp] {k : α} (h : k ∈ t.keys) : k ∈ t :=
DTreeMap.mem_of_mem_keys h
theorem distinct_keys [TransCmp cmp] :
t.keys.Pairwise (fun a b => ¬ cmp a b = .eq) :=
DTreeMap.distinct_keys
theorem nodup_keys [TransCmp cmp] :
t.keys.Nodup :=
t.distinct_keys.imp Std.ReflCmp.ne_of_cmp_ne_eq
theorem ordered_keys [TransCmp cmp] :
t.keys.Pairwise (fun a b => cmp a b = .lt) :=
DTreeMap.ordered_keys
@[simp, grind _=_]
theorem map_fst_toList_eq_keys :
(toList t).map Prod.fst = t.keys :=
DTreeMap.Const.map_fst_toList_eq_keys
@[simp, grind =]
theorem length_toList :
(toList t).length = t.size :=
DTreeMap.Const.length_toList
@[simp, grind =]
theorem isEmpty_toList :
(toList t).isEmpty = t.isEmpty :=
DTreeMap.Const.isEmpty_toList
@[simp, grind =]
theorem mem_toList_iff_getElem?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β} :
(k, v) ∈ toList t ↔ t[k]? = some v :=
DTreeMap.Const.mem_toList_iff_get?_eq_some
@[simp]
theorem mem_toList_iff_getKey?_eq_some_and_getElem?_eq_some [TransCmp cmp] {k : α} {v : β} :
(k, v) ∈ toList t ↔ t.getKey? k = some k ∧ t[k]? = some v :=
DTreeMap.Const.mem_toList_iff_getKey?_eq_some_and_get?_eq_some
theorem getElem?_eq_some_iff_exists_compare_eq_eq_and_mem_toList [TransCmp cmp] {k : α} {v : β} :
t[k]? = some v ↔ ∃ (k' : α), cmp k k' = .eq ∧ (k', v) ∈ toList t :=
DTreeMap.Const.get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList
theorem find?_toList_eq_some_iff_getKey?_eq_some_and_getElem?_eq_some [TransCmp cmp] {k k' : α}
{v : β} :
t.toList.find? (cmp ·.1 k == .eq) = some ⟨k', v⟩ ↔
t.getKey? k = some k' ∧ t[k]? = some v :=
DTreeMap.Const.find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some
theorem find?_toList_eq_none_iff_contains_eq_false [TransCmp cmp] {k : α} :
(toList t).find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false :=
DTreeMap.Const.find?_toList_eq_none_iff_contains_eq_false
@[simp]
theorem find?_toList_eq_none_iff_not_mem [TransCmp cmp] {k : α} :
(toList t).find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t :=
DTreeMap.Const.find?_toList_eq_none_iff_not_mem
theorem distinct_keys_toList [TransCmp cmp] :
(toList t).Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq) :=
DTreeMap.Const.distinct_keys_toList
theorem ordered_keys_toList [TransCmp cmp] :
(toList t).Pairwise (fun a b => cmp a.1 b.1 = .lt) :=
DTreeMap.Const.ordered_keys_toList
section monadic
variable {δ : Type w} {m : Type w → Type w'}
theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m] {f : δ → α → β → m δ} {init : δ} :
t.foldlM f init = t.toList.foldlM (fun a b => f a b.1 b.2) init :=
DTreeMap.Const.foldlM_eq_foldlM_toList
theorem foldl_eq_foldl_toList {f : δ → α → β → δ} {init : δ} :
t.foldl f init = t.toList.foldl (fun a b => f a b.1 b.2) init :=
DTreeMap.Const.foldl_eq_foldl_toList
theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] {f : α → β → δ → m δ} {init : δ} :
t.foldrM f init = t.toList.foldrM (fun a b => f a.1 a.2 b) init :=
DTreeMap.Const.foldrM_eq_foldrM_toList
theorem foldr_eq_foldr_toList {f : α → β → δ → δ} {init : δ} :
t.foldr f init = t.toList.foldr (fun a b => f a.1 a.2 b) init :=
DTreeMap.Const.foldr_eq_foldr_toList
@[simp, grind =]
theorem forM_eq_forM [Monad m] [LawfulMonad m] {f : α → β → m PUnit} :
t.forM f = ForM.forM t (fun a => f a.1 a.2) := rfl
theorem forM_eq_forM_toList [Monad m] [LawfulMonad m] {f : α × β → m PUnit} :
ForM.forM t f = ForM.forM t.toList f :=
DTreeMap.Const.forMUncurried_eq_forM_toList (f := f)
@[simp, grind =]
theorem forIn_eq_forIn [Monad m] [LawfulMonad m]
{f : α → β → δ → m (ForInStep δ)} {init : δ} :
t.forIn f init = ForIn.forIn t init (fun a d => f a.1 a.2 d) := rfl
theorem forIn_eq_forIn_toList [Monad m] [LawfulMonad m]
{f : α × β → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init f = ForIn.forIn t.toList init f :=
DTreeMap.Const.forInUncurried_eq_forIn_toList
theorem foldlM_eq_foldlM_keys [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} :
t.foldlM (fun d a _ => f d a) init = t.keys.foldlM f init :=
DTreeMap.foldlM_eq_foldlM_keys
theorem foldl_eq_foldl_keys {f : δ → α → δ} {init : δ} :
t.foldl (fun d a _ => f d a) init = t.keys.foldl f init :=
DTreeMap.foldl_eq_foldl_keys
theorem foldrM_eq_foldrM_keys [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} :
t.foldrM (fun a _ d => f a d) init = t.keys.foldrM f init :=
DTreeMap.foldrM_eq_foldrM_keys
theorem foldr_eq_foldr_keys {f : α → δ → δ} {init : δ} :
t.foldr (fun a _ d => f a d) init = t.keys.foldr f init :=
DTreeMap.foldr_eq_foldr_keys
theorem forM_eq_forM_keys [Monad m] [LawfulMonad m] {f : α → m PUnit} :
ForM.forM t (fun a => f a.1) = t.keys.forM f :=
DTreeMap.forM_eq_forM_keys
theorem forIn_eq_forIn_keys [Monad m] [LawfulMonad m] {f : α → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init (fun a d => f a.1 d) = ForIn.forIn t.keys init f :=
DTreeMap.forIn_eq_forIn_keys
end monadic
@[simp, grind =]
theorem insertMany_nil :
t.insertMany [] = t :=
rfl
@[simp, grind =]
theorem insertMany_list_singleton {k : α} {v : β} :
t.insertMany [⟨k, v⟩] = t.insert k v :=
rfl
@[grind _=_] theorem insertMany_cons {l : List (α × β)} {k : α} {v : β} :
t.insertMany (⟨k, v⟩ :: l) = (t.insert k v).insertMany l :=
ext <| DTreeMap.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
| nil => simp
| cons hd tl ih =>
rw [List.cons_append, insertMany_cons, insertMany_cons, ih]
@[simp, grind =]
theorem contains_insertMany_list [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k : α} :
(t.insertMany l).contains k = (t.contains k || (l.map Prod.fst).contains k) :=
DTreeMap.Const.contains_insertMany_list
@[simp, grind =]
theorem mem_insertMany_list [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k : α} :
k ∈ t.insertMany l ↔ k ∈ t (l.map Prod.fst).contains k :=
DTreeMap.Const.mem_insertMany_list
theorem mem_of_mem_insertMany_list [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k : α} :
k ∈ t.insertMany l → (l.map Prod.fst).contains k = false → k ∈ t :=
DTreeMap.Const.mem_of_mem_insertMany_list
theorem getKey?_insertMany_list_of_contains_eq_false [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k : α}
(contains_eq_false : (l.map Prod.fst).contains k = false) :
(t.insertMany l).getKey? k = t.getKey? k :=
DTreeMap.Const.getKey?_insertMany_list_of_contains_eq_false contains_eq_false
theorem getKey?_insertMany_list_of_mem [TransCmp cmp]
{l : List (α × β)}
{k k' : α} (k_eq : cmp k k' = .eq)
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : k ∈ l.map Prod.fst) :
(t.insertMany l).getKey? k' = some k :=
DTreeMap.Const.getKey?_insertMany_list_of_mem k_eq distinct mem
theorem getKey_insertMany_list_of_contains_eq_false [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k : α}
(contains_eq_false : (l.map Prod.fst).contains k = false)
{h'} :
(t.insertMany l).getKey k h' =
t.getKey k (mem_of_mem_insertMany_list h' contains_eq_false) :=
DTreeMap.Const.getKey_insertMany_list_of_contains_eq_false contains_eq_false
theorem getKey_insertMany_list_of_mem [TransCmp cmp]
{l : List (α × β)}
{k k' : α} (k_eq : cmp k k' = .eq)
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : k ∈ l.map Prod.fst)
{h'} :
(t.insertMany l).getKey k' h' = k :=
DTreeMap.Const.getKey_insertMany_list_of_mem k_eq distinct mem
theorem getKey!_insertMany_list_of_contains_eq_false [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
[Inhabited α] {l : List (α × β)} {k : α}
(contains_eq_false : (l.map Prod.fst).contains k = false) :
(t.insertMany l).getKey! k = t.getKey! k :=
DTreeMap.Const.getKey!_insertMany_list_of_contains_eq_false contains_eq_false
theorem getKey!_insertMany_list_of_mem [TransCmp cmp] [Inhabited α]
{l : List (α × β)}
{k k' : α} (k_eq : cmp k k' = .eq)
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : k ∈ l.map Prod.fst) :
(t.insertMany l).getKey! k' = k :=
DTreeMap.Const.getKey!_insertMany_list_of_mem k_eq distinct mem
theorem getKeyD_insertMany_list_of_contains_eq_false [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k fallback : α}
(contains_eq_false : (l.map Prod.fst).contains k = false) :
(t.insertMany l).getKeyD k fallback = t.getKeyD k fallback :=
DTreeMap.Const.getKeyD_insertMany_list_of_contains_eq_false contains_eq_false
theorem getKeyD_insertMany_list_of_mem [TransCmp cmp]
{l : List (α × β)}
{k k' fallback : α} (k_eq : cmp k k' = .eq)
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : k ∈ l.map Prod.fst) :
(t.insertMany l).getKeyD k' fallback = k :=
DTreeMap.Const.getKeyD_insertMany_list_of_mem k_eq distinct mem
theorem size_insertMany_list [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} (distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq)) :
(∀ (a : α), a ∈ t → (l.map Prod.fst).contains a = false) →
(t.insertMany l).size = t.size + l.length :=
DTreeMap.Const.size_insertMany_list distinct
theorem size_le_size_insertMany_list [TransCmp cmp]
{l : List (α × β)} :
t.size ≤ (t.insertMany l).size :=
DTreeMap.Const.size_le_size_insertMany_list
grind_pattern size_le_size_insertMany_list => (t.insertMany l).size
theorem size_insertMany_list_le [TransCmp cmp]
{l : List (α × β)} :
(t.insertMany l).size ≤ t.size + l.length :=
DTreeMap.Const.size_insertMany_list_le
grind_pattern size_insertMany_list_le => (t.insertMany l).size
@[simp, grind =]
theorem isEmpty_insertMany_list [TransCmp cmp]
{l : List (α × β)} :
(t.insertMany l).isEmpty = (t.isEmpty && l.isEmpty) :=
DTreeMap.Const.isEmpty_insertMany_list
theorem getElem?_insertMany_list_of_contains_eq_false [TransCmp cmp] [BEq α]
[LawfulBEqCmp cmp] {l : List (α × β)} {k : α}
(contains_eq_false : (l.map Prod.fst).contains k = false) :
(t.insertMany l)[k]? = t[k]? :=
DTreeMap.Const.get?_insertMany_list_of_contains_eq_false contains_eq_false
theorem getElem?_insertMany_list_of_mem [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k k' : α} (k_eq : cmp k k' = .eq) {v : β}
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq)) (mem : ⟨k, v⟩ ∈ l) :
(t.insertMany l)[k']? = some v :=
DTreeMap.Const.get?_insertMany_list_of_mem k_eq distinct mem
@[grind =] theorem getElem?_insertMany_list [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k : α} :
(t.insertMany l)[k]? =
(l.findSomeRev? (fun ⟨a, b⟩ => if cmp a k = .eq then some b else none)).or (t[k]?) :=
DTreeMap.Const.get?_insertMany_list
theorem getElem_insertMany_list_of_contains_eq_false [TransCmp cmp] [BEq α]
[LawfulBEqCmp cmp]
{l : List (α × β)} {k : α}
(contains : (l.map Prod.fst).contains k = false)
{h'} :
(t.insertMany l)[k]'h' =
t[k]'(mem_of_mem_insertMany_list h' contains) :=
DTreeMap.Const.get_insertMany_list_of_contains_eq_false contains
theorem getElem_insertMany_list_of_mem [TransCmp cmp]
{l : List (α × β)} {k k' : α} (k_eq : cmp k k' = .eq) {v : β}
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : ⟨k, v⟩ ∈ l)
{h'} :
(t.insertMany l)[k']'h' = v :=
DTreeMap.Const.get_insertMany_list_of_mem k_eq distinct mem
theorem getElem!_insertMany_list_of_contains_eq_false [TransCmp cmp]
[BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k : α} [Inhabited β]
(contains_eq_false : (l.map Prod.fst).contains k = false) :
(t.insertMany l)[k]! = t[k]! :=
DTreeMap.Const.get!_insertMany_list_of_contains_eq_false contains_eq_false
theorem getElem!_insertMany_list_of_mem [TransCmp cmp]
{l : List (α × β)} {k k' : α} (k_eq : cmp k k' = .eq) {v : β} [Inhabited β]
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : ⟨k, v⟩ ∈ l) :
(t.insertMany l)[k']! = v :=
DTreeMap.Const.get!_insertMany_list_of_mem k_eq distinct mem
theorem getD_insertMany_list_of_contains_eq_false [TransCmp cmp]
[BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k : α} {fallback : β}
(contains_eq_false : (l.map Prod.fst).contains k = false) :
(t.insertMany l).getD k fallback = t.getD k fallback :=
DTreeMap.Const.getD_insertMany_list_of_contains_eq_false contains_eq_false
theorem getD_insertMany_list_of_mem [TransCmp cmp]
{l : List (α × β)} {k k' : α} (k_eq : cmp k k' = .eq) {v : β} {fallback : β}
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : ⟨k, v⟩ ∈ l) :
(t.insertMany l).getD k' fallback = v :=
DTreeMap.Const.getD_insertMany_list_of_mem k_eq distinct mem
section Unit
variable {t : TreeMap α Unit cmp}
@[simp]
theorem insertManyIfNewUnit_nil :
insertManyIfNewUnit t [] = t :=
rfl
@[simp]
theorem insertManyIfNewUnit_list_singleton {k : α} :
insertManyIfNewUnit t [k] = t.insertIfNew k () :=
rfl
theorem insertManyIfNewUnit_cons {l : List α} {k : α} :
insertManyIfNewUnit t (k :: l) = insertManyIfNewUnit (t.insertIfNew k ()) l :=
ext <| DTreeMap.Const.insertManyIfNewUnit_cons
@[simp]
theorem contains_insertManyIfNewUnit_list [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List α} {k : α} :
(insertManyIfNewUnit t l).contains k = (t.contains k || l.contains k) :=
DTreeMap.Const.contains_insertManyIfNewUnit_list
@[simp]
theorem mem_insertManyIfNewUnit_list [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List α} {k : α} :
k ∈ insertManyIfNewUnit t l ↔ k ∈ t l.contains k :=
DTreeMap.Const.mem_insertManyIfNewUnit_list
theorem mem_of_mem_insertManyIfNewUnit_list [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List α} {k : α} (contains_eq_false : l.contains k = false) :
k ∈ insertManyIfNewUnit t l → k ∈ t :=
DTreeMap.Const.mem_of_mem_insertManyIfNewUnit_list contains_eq_false
theorem getKey?_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
[TransCmp cmp] [BEq α] [LawfulBEqCmp cmp] {l : List α} {k : α}
(not_mem : ¬ k ∈ t) (contains_eq_false : l.contains k = false) :
getKey? (insertManyIfNewUnit t l) k = none :=
DTreeMap.Const.getKey?_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
not_mem contains_eq_false
theorem getKey?_insertManyIfNewUnit_list_of_not_mem_of_mem [TransCmp cmp]
{l : List α} {k k' : α} (k_eq : cmp k k' = .eq)
(not_mem : ¬ k ∈ t) (distinct : l.Pairwise (fun a b => ¬ cmp a b = .eq)) (mem : k ∈ l) :
getKey? (insertManyIfNewUnit t l) k' = some k :=
DTreeMap.Const.getKey?_insertManyIfNewUnit_list_of_not_mem_of_mem k_eq not_mem distinct mem
theorem getKey?_insertManyIfNewUnit_list_of_mem [TransCmp cmp]
{l : List α} {k : α} (mem : k ∈ t) :
getKey? (insertManyIfNewUnit t l) k = getKey? t k :=
DTreeMap.Const.getKey?_insertManyIfNewUnit_list_of_mem mem
theorem getKey_insertManyIfNewUnit_list_of_mem [TransCmp cmp]
{l : List α} {k : α} {h'} (contains : k ∈ t) :
getKey (insertManyIfNewUnit t l) k h' = getKey t k contains :=
DTreeMap.Const.getKey_insertManyIfNewUnit_list_of_mem contains
theorem getKey_insertManyIfNewUnit_list_of_not_mem_of_mem [TransCmp cmp]
{l : List α}
{k k' : α} (k_eq : cmp k k' = .eq) {h'} (not_mem : ¬ k ∈ t)
(distinct : l.Pairwise (fun a b => ¬ cmp a b = .eq)) (mem : k ∈ l) :
getKey (insertManyIfNewUnit t l) k' h' = k :=
DTreeMap.Const.getKey_insertManyIfNewUnit_list_of_not_mem_of_mem k_eq not_mem distinct mem
theorem getKey!_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
[TransCmp cmp] [BEq α] [LawfulBEqCmp cmp] [Inhabited α] {l : List α} {k : α}
(not_mem : ¬ k ∈ t) (contains_eq_false : l.contains k = false) :
getKey! (insertManyIfNewUnit t l) k = default :=
DTreeMap.Const.getKey!_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
not_mem contains_eq_false
theorem getKey!_insertManyIfNewUnit_list_of_not_mem_of_mem [TransCmp cmp]
[Inhabited α] {l : List α} {k k' : α} (k_eq : cmp k k' = .eq)
(not_mem : ¬ k ∈ t) (distinct : l.Pairwise (fun a b => ¬ cmp a b = .eq)) (mem : k ∈ l) :
getKey! (insertManyIfNewUnit t l) k' = k :=
DTreeMap.Const.getKey!_insertManyIfNewUnit_list_of_not_mem_of_mem k_eq not_mem distinct mem
theorem getKey!_insertManyIfNewUnit_list_of_mem [TransCmp cmp]
[Inhabited α] {l : List α} {k : α} (mem : k ∈ t) :
getKey! (insertManyIfNewUnit t l) k = getKey! t k :=
DTreeMap.Const.getKey!_insertManyIfNewUnit_list_of_mem mem
theorem getKeyD_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
[TransCmp cmp] [BEq α] [LawfulBEqCmp cmp] {l : List α} {k fallback : α}
(not_mem : ¬ k ∈ t) (contains_eq_false : l.contains k = false) :
getKeyD (insertManyIfNewUnit t l) k fallback = fallback :=
DTreeMap.Const.getKeyD_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
not_mem contains_eq_false
theorem getKeyD_insertManyIfNewUnit_list_of_not_mem_of_mem [TransCmp cmp]
{l : List α} {k k' fallback : α} (k_eq : cmp k k' = .eq)
(not_mem : ¬ k ∈ t) (distinct : l.Pairwise (fun a b => ¬ cmp a b = .eq)) (mem : k ∈ l) :
getKeyD (insertManyIfNewUnit t l) k' fallback = k :=
DTreeMap.Const.getKeyD_insertManyIfNewUnit_list_of_not_mem_of_mem k_eq not_mem distinct mem
theorem getKeyD_insertManyIfNewUnit_list_of_mem [TransCmp cmp]
{l : List α} {k fallback : α} (mem : k ∈ t) :
getKeyD (insertManyIfNewUnit t l) k fallback = getKeyD t k fallback :=
DTreeMap.Const.getKeyD_insertManyIfNewUnit_list_of_mem mem
theorem size_insertManyIfNewUnit_list [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List α}
(distinct : l.Pairwise (fun a b => ¬ cmp a b = .eq)) :
(∀ (a : α), a ∈ t → l.contains a = false) →
(insertManyIfNewUnit t l).size = t.size + l.length :=
DTreeMap.Const.size_insertManyIfNewUnit_list distinct
theorem size_le_size_insertManyIfNewUnit_list [TransCmp cmp]
{l : List α} :
t.size ≤ (insertManyIfNewUnit t l).size :=
DTreeMap.Const.size_le_size_insertManyIfNewUnit_list
theorem size_insertManyIfNewUnit_list_le [TransCmp cmp]
{l : List α} :
(insertManyIfNewUnit t l).size ≤ t.size + l.length :=
DTreeMap.Const.size_insertManyIfNewUnit_list_le
@[simp]
theorem isEmpty_insertManyIfNewUnit_list [TransCmp cmp] {l : List α} :
(insertManyIfNewUnit t l).isEmpty = (t.isEmpty && l.isEmpty) :=
DTreeMap.Const.isEmpty_insertManyIfNewUnit_list
@[simp]
theorem getElem?_insertManyIfNewUnit_list [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List α} {k : α} :
(insertManyIfNewUnit t l)[k]? = if k ∈ t l.contains k then some () else none :=
DTreeMap.Const.get?_insertManyIfNewUnit_list
@[simp]
theorem getElem_insertManyIfNewUnit_list {l : List α} {k : α} {h'} :
(insertManyIfNewUnit t l)[k]'h' = () :=
rfl
@[simp]
theorem getElem!_insertManyIfNewUnit_list {l : List α} {k : α} :
(insertManyIfNewUnit t l)[k]! = () :=
rfl
@[simp]
theorem getD_insertManyIfNewUnit_list
{l : List α} {k : α} {fallback : Unit} :
getD (insertManyIfNewUnit t l) k fallback = () :=
rfl
end Unit
@[simp, grind =]
theorem ofList_nil :
ofList ([] : List (α × β)) cmp = ∅ := by
rfl
@[simp, grind =]
theorem ofList_singleton {k : α} {v : β} :
ofList [⟨k, v⟩] cmp = (∅ : TreeMap α β cmp).insert k v := by
rfl
@[grind _=_] theorem ofList_cons {k : α} {v : β} {tl : List (α × β)} :
ofList (⟨k, v⟩ :: tl) cmp = insertMany ((∅ : TreeMap α β cmp).insert k v) tl :=
ext DTreeMap.Const.ofList_cons
theorem ofList_eq_insertMany_empty {l : List (α × β)} :
ofList l cmp = insertMany (∅ : TreeMap α β cmp) l := rfl
@[simp, grind =]
theorem contains_ofList [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp] {l : List (α × β)} {k : α} :
(ofList l cmp).contains k = (l.map Prod.fst).contains k :=
DTreeMap.Const.contains_ofList
@[simp, grind =]
theorem mem_ofList [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp] {l : List (α × β)} {k : α} :
k ∈ ofList l cmp ↔ (l.map Prod.fst).contains k :=
DTreeMap.Const.mem_ofList
theorem getElem?_ofList_of_contains_eq_false [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k : α}
(contains_eq_false : (l.map Prod.fst).contains k = false) :
(ofList l cmp)[k]? = none :=
DTreeMap.Const.get?_ofList_of_contains_eq_false contains_eq_false
theorem getElem?_ofList_of_mem [TransCmp cmp]
{l : List (α × β)} {k k' : α} (k_eq : cmp k k' = .eq) {v : β}
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : ⟨k, v⟩ ∈ l) :
(ofList l cmp)[k']? = some v :=
DTreeMap.Const.get?_ofList_of_mem k_eq distinct mem
theorem getElem_ofList_of_mem [TransCmp cmp]
{l : List (α × β)} {k k' : α} (k_eq : cmp k k' = .eq) {v : β}
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : ⟨k, v⟩ ∈ l)
{h} :
(ofList l cmp)[k']'h = v :=
DTreeMap.Const.get_ofList_of_mem k_eq distinct mem
theorem getElem!_ofList_of_contains_eq_false [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k : α} [Inhabited β]
(contains_eq_false : (l.map Prod.fst).contains k = false) :
(ofList l cmp)[k]! = default :=
DTreeMap.Const.get!_ofList_of_contains_eq_false contains_eq_false
theorem getElem!_ofList_of_mem [TransCmp cmp]
{l : List (α × β)} {k k' : α} (k_eq : cmp k k' = .eq) {v : β} [Inhabited β]
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : ⟨k, v⟩ ∈ l) :
(ofList l cmp)[k']! = v :=
DTreeMap.Const.get!_ofList_of_mem k_eq distinct mem
theorem getD_ofList_of_contains_eq_false [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k : α} {fallback : β}
(contains_eq_false : (l.map Prod.fst).contains k = false) :
getD (ofList l cmp) k fallback = fallback :=
DTreeMap.Const.getD_ofList_of_contains_eq_false contains_eq_false
theorem getD_ofList_of_mem [TransCmp cmp]
{l : List (α × β)} {k k' : α} (k_eq : cmp k k' = .eq) {v : β} {fallback : β}
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : ⟨k, v⟩ ∈ l) :
getD (ofList l cmp) k' fallback = v :=
DTreeMap.Const.getD_ofList_of_mem k_eq distinct mem
theorem getKey?_ofList_of_contains_eq_false [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k : α}
(contains_eq_false : (l.map Prod.fst).contains k = false) :
(ofList l cmp).getKey? k = none :=
DTreeMap.Const.getKey?_ofList_of_contains_eq_false contains_eq_false
theorem getKey?_ofList_of_mem [TransCmp cmp]
{l : List (α × β)}
{k k' : α} (k_eq : cmp k k' = .eq)
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : k ∈ l.map Prod.fst) :
(ofList l cmp).getKey? k' = some k :=
DTreeMap.Const.getKey?_ofList_of_mem k_eq distinct mem
theorem getKey_ofList_of_mem [TransCmp cmp]
{l : List (α × β)}
{k k' : α} (k_eq : cmp k k' = .eq)
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : k ∈ l.map Prod.fst)
{h'} :
(ofList l cmp).getKey k' h' = k :=
DTreeMap.Const.getKey_ofList_of_mem k_eq distinct mem
theorem getKey!_ofList_of_contains_eq_false [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
[Inhabited α] {l : List (α × β)} {k : α}
(contains_eq_false : (l.map Prod.fst).contains k = false) :
(ofList l cmp).getKey! k = default :=
DTreeMap.Const.getKey!_ofList_of_contains_eq_false contains_eq_false
theorem getKey!_ofList_of_mem [TransCmp cmp] [Inhabited α]
{l : List (α × β)}
{k k' : α} (k_eq : cmp k k' = .eq)
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : k ∈ l.map Prod.fst) :
(ofList l cmp).getKey! k' = k :=
DTreeMap.Const.getKey!_ofList_of_mem k_eq distinct mem
theorem getKeyD_ofList_of_contains_eq_false [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List (α × β)} {k fallback : α}
(contains_eq_false : (l.map Prod.fst).contains k = false) :
(ofList l cmp).getKeyD k fallback = fallback :=
DTreeMap.Const.getKeyD_ofList_of_contains_eq_false contains_eq_false
theorem getKeyD_ofList_of_mem [TransCmp cmp]
{l : List (α × β)}
{k k' fallback : α} (k_eq : cmp k k' = .eq)
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq))
(mem : k ∈ l.map Prod.fst) :
(ofList l cmp).getKeyD k' fallback = k :=
DTreeMap.Const.getKeyD_ofList_of_mem k_eq distinct mem
theorem size_ofList [TransCmp cmp] {l : List (α × β)}
(distinct : l.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq)) :
(ofList l cmp).size = l.length :=
DTreeMap.Const.size_ofList distinct
theorem size_ofList_le [TransCmp cmp] {l : List (α × β)} :
(ofList l cmp).size ≤ l.length :=
DTreeMap.Const.size_ofList_le
grind_pattern size_ofList_le => (ofList l cmp).size
@[simp, grind =]
theorem isEmpty_ofList [TransCmp cmp] {l : List (α × β)} :
(ofList l cmp).isEmpty = l.isEmpty :=
DTreeMap.Const.isEmpty_ofList
@[simp]
theorem unitOfList_nil :
unitOfList ([] : List α) cmp =
(∅ : TreeMap α Unit cmp) :=
rfl
@[simp]
theorem unitOfList_singleton {k : α} :
unitOfList [k] cmp = (∅ : TreeMap α Unit cmp).insertIfNew k () :=
rfl
theorem unitOfList_cons {hd : α} {tl : List α} :
unitOfList (hd :: tl) cmp =
insertManyIfNewUnit ((∅ : TreeMap α Unit cmp).insertIfNew hd ()) tl :=
ext DTreeMap.Const.unitOfList_cons
@[simp]
theorem contains_unitOfList [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp] {l : List α} {k : α} :
(unitOfList l cmp).contains k = l.contains k :=
DTreeMap.Const.contains_unitOfList
@[simp]
theorem mem_unitOfList [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp] {l : List α} {k : α} :
k ∈ unitOfList l cmp ↔ l.contains k := by
simp [← contains_iff_mem]
theorem getKey?_unitOfList_of_contains_eq_false [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp]
{l : List α} {k : α}
(contains_eq_false : l.contains k = false) :
getKey? (unitOfList l cmp) k = none :=
DTreeMap.Const.getKey?_unitOfList_of_contains_eq_false contains_eq_false
theorem getKey?_unitOfList_of_mem [TransCmp cmp]
{l : List α} {k k' : α} (k_eq : cmp k k' = .eq)
(distinct : l.Pairwise (fun a b => ¬ cmp a b = .eq)) (mem : k ∈ l) :
getKey? (unitOfList l cmp) k' = some k :=
DTreeMap.Const.getKey?_unitOfList_of_mem k_eq distinct mem
theorem getKey_unitOfList_of_mem [TransCmp cmp]
{l : List α}
{k k' : α} (k_eq : cmp k k' = .eq)
(distinct : l.Pairwise (fun a b => ¬ cmp a b = .eq))
(mem : k ∈ l) {h'} :
getKey (unitOfList l cmp) k' h' = k :=
DTreeMap.Const.getKey_unitOfList_of_mem k_eq distinct mem
theorem getKey!_unitOfList_of_contains_eq_false [TransCmp cmp] [BEq α]
[LawfulBEqCmp cmp] [Inhabited α] {l : List α} {k : α}
(contains_eq_false : l.contains k = false) :
getKey! (unitOfList l cmp) k = default :=
DTreeMap.Const.getKey!_unitOfList_of_contains_eq_false contains_eq_false
theorem getKey!_unitOfList_of_mem [TransCmp cmp]
[Inhabited α] {l : List α} {k k' : α} (k_eq : cmp k k' = .eq)
(distinct : l.Pairwise (fun a b => ¬ cmp a b = .eq))
(mem : k ∈ l) :
getKey! (unitOfList l cmp) k' = k :=
DTreeMap.Const.getKey!_unitOfList_of_mem k_eq distinct mem
theorem getKeyD_unitOfList_of_contains_eq_false [TransCmp cmp] [BEq α]
[LawfulBEqCmp cmp] {l : List α} {k fallback : α}
(contains_eq_false : l.contains k = false) :
getKeyD (unitOfList l cmp) k fallback = fallback :=
DTreeMap.Const.getKeyD_unitOfList_of_contains_eq_false contains_eq_false
theorem getKeyD_unitOfList_of_mem [TransCmp cmp]
{l : List α} {k k' fallback : α} (k_eq : cmp k k' = .eq)
(distinct : l.Pairwise (fun a b => ¬ cmp a b = .eq))
(mem : k ∈ l) :
getKeyD (unitOfList l cmp) k' fallback = k :=
DTreeMap.Const.getKeyD_unitOfList_of_mem k_eq distinct mem
theorem size_unitOfList [TransCmp cmp] {l : List α}
(distinct : l.Pairwise (fun a b => ¬ cmp a b = .eq)) :
(unitOfList l cmp).size = l.length :=
DTreeMap.Const.size_unitOfList distinct
theorem size_unitOfList_le [TransCmp cmp] {l : List α} :
(unitOfList l cmp).size ≤ l.length :=
DTreeMap.Const.size_unitOfList_le
@[simp]
theorem isEmpty_unitOfList [TransCmp cmp] {l : List α} :
(unitOfList l cmp).isEmpty = l.isEmpty :=
DTreeMap.Const.isEmpty_unitOfList
@[simp]
theorem getElem?_unitOfList [TransCmp cmp] [BEq α] [LawfulBEqCmp cmp] {l : List α} {k : α} :
(unitOfList l cmp)[k]? = if l.contains k then some () else none :=
DTreeMap.Const.get?_unitOfList
@[simp]
theorem getElem_unitOfList {l : List α} {k : α} {h} :
(unitOfList l cmp)[k]'h = () :=
DTreeMap.Const.get_unitOfList
@[simp]
theorem getElem!_unitOfList {l : List α} {k : α} :
(unitOfList l cmp)[k]! = () :=
DTreeMap.Const.get!_unitOfList
@[simp]
theorem getD_unitOfList {l : List α} {k : α} {fallback : Unit} :
getD (unitOfList l cmp) k fallback = () :=
DTreeMap.Const.getD_unitOfList
section Union
variable (t₁ t₂ : TreeMap α β cmp)
variable {t₁ t₂}
@[simp]
theorem union_eq : t₁.union t₂ = t₁ t₂ := by
simp only [Union.union]
/- contains -/
@[simp]
theorem contains_union [TransCmp cmp] {k : α} :
(t₁ t₂).contains k = (t₁.contains k || t₂.contains k) :=
DTreeMap.contains_union
/- mem -/
theorem mem_union_of_left [TransCmp cmp] {k : α} :
k ∈ t₁ → k ∈ t₁ t₂ :=
DTreeMap.mem_union_of_left
theorem mem_union_of_right [TransCmp cmp] {k : α} :
k ∈ t₂ → k ∈ t₁ t₂ :=
DTreeMap.mem_union_of_right
@[simp]
theorem mem_union_iff [TransCmp cmp] {k : α} :
k ∈ t₁ t₂ ↔ k ∈ t₁ k ∈ t₂ :=
DTreeMap.mem_union_iff
theorem mem_of_mem_union_of_not_mem_right [TransCmp cmp] {k : α} :
k ∈ t₁ t₂ → ¬k ∈ t₂ → k ∈ t₁ :=
DTreeMap.mem_of_mem_union_of_not_mem_right
theorem mem_of_mem_union_of_not_mem_left [TransCmp cmp]
{k : α} :
k ∈ t₁ t₂ → ¬k ∈ t₁ → k ∈ t₂ :=
DTreeMap.mem_of_mem_union_of_not_mem_left
/- Equiv -/
theorem Equiv.union_left {t₃ : TreeMap α β cmp} [TransCmp cmp] (equiv : t₁.Equiv t₂) :
(t₁ t₃).Equiv (t₂ t₃) :=
⟨DTreeMap.Equiv.union_left equiv.1⟩
theorem Equiv.union_right {t₃ : TreeMap α β cmp} [TransCmp cmp] (equiv : t₂.Equiv t₃) :
(t₁ t₂).Equiv (t₁ t₃) :=
⟨DTreeMap.Equiv.union_right equiv.1⟩
theorem Equiv.union_congr {t₃ t₄ : TreeMap α β cmp} [TransCmp cmp]
(equiv₁ : t₁.Equiv t₃) (equiv₂ : t₂.Equiv t₄) :
(t₁ t₂).Equiv (t₃ t₄) :=
⟨DTreeMap.Equiv.union_congr equiv₁.1 equiv₂.1⟩
theorem union_insert_right_equiv_insert_union [TransCmp cmp] {p : (_ : α) × β} :
(t₁ (t₂.insert p.fst p.snd)).Equiv ((t₁ t₂).insert p.fst p.snd) :=
⟨DTreeMap.union_insert_right_equiv_insert_union⟩
/- getElem? -/
theorem getElem?_union [TransCmp cmp]
{k : α} :
(t₁ t₂)[k]? = (t₂[k]?).or (t₁[k]?) :=
DTreeMap.Const.get?_union
theorem getElem?_union_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : ¬k ∈ t₁) :
(t₁ t₂)[k]? = t₂[k]? :=
DTreeMap.Const.get?_union_of_not_mem_left not_mem
theorem getElem?_union_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : ¬k ∈ t₂) :
(t₁ t₂)[k]? = t₁[k]? :=
DTreeMap.Const.get?_union_of_not_mem_right not_mem
/- get? -/
@[deprecated getElem?_union (since := "2025-12-10")]
theorem get?_union [TransCmp cmp]
{k : α} :
(t₁ t₂).get? k = (t₂.get? k).or (t₁.get? k) :=
DTreeMap.Const.get?_union
@[deprecated getElem?_union_of_not_mem_left (since := "2025-12-10")]
theorem get?_union_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : ¬k ∈ t₁) :
(t₁ t₂).get? k = t₂.get? k :=
DTreeMap.Const.get?_union_of_not_mem_left not_mem
@[deprecated getElem?_union_of_not_mem_right (since := "2025-12-10")]
theorem get?_union_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : ¬k ∈ t₂) :
(t₁ t₂).get? k = t₁.get? k :=
DTreeMap.Const.get?_union_of_not_mem_right not_mem
/- getElem -/
theorem getElem_union_of_mem_right [TransCmp cmp]
{k : α} (mem : k ∈ t₂) :
(t₁ t₂)[k]'(mem_union_of_right mem) = t₂[k]'mem :=
DTreeMap.Const.get_union_of_mem_right mem
theorem getElem_union_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : ¬k ∈ t₁) {h'} :
(t₁ t₂)[k]'h' = t₂[k]'(mem_of_mem_union_of_not_mem_left h' not_mem) :=
DTreeMap.Const.get_union_of_not_mem_left not_mem
theorem getElem_union_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : ¬k ∈ t₂) {h'} :
(t₁ t₂)[k]'h' = t₁[k]'(mem_of_mem_union_of_not_mem_right h' not_mem) :=
DTreeMap.Const.get_union_of_not_mem_right not_mem
/- get -/
@[deprecated getElem_union_of_mem_right (since := "2025-12-10")]
theorem get_union_of_mem_right [TransCmp cmp]
{k : α} (mem : k ∈ t₂) :
(t₁ t₂).get k (mem_union_of_right mem) = t₂.get k mem :=
DTreeMap.Const.get_union_of_mem_right mem
@[deprecated getElem_union_of_not_mem_left (since := "2025-12-10")]
theorem get_union_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : ¬k ∈ t₁) {h'} :
(t₁ t₂).get k h' = t₂.get k (mem_of_mem_union_of_not_mem_left h' not_mem) :=
DTreeMap.Const.get_union_of_not_mem_left not_mem
@[deprecated getElem_union_of_not_mem_right (since := "2025-12-10")]
theorem get_union_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : ¬k ∈ t₂) {h'} :
(t₁ t₂).get k h' = t₁.get k (mem_of_mem_union_of_not_mem_right h' not_mem) :=
DTreeMap.Const.get_union_of_not_mem_right not_mem
/- getD -/
theorem getD_union [TransCmp cmp]
{k : α} {fallback : β} :
(t₁ t₂).getD k fallback = t₂.getD k (t₁.getD k fallback) :=
DTreeMap.Const.getD_union
theorem getD_union_of_not_mem_left [TransCmp cmp]
{k : α} {fallback : β} (not_mem : ¬k ∈ t₁) :
(t₁ t₂).getD k fallback = t₂.getD k fallback :=
DTreeMap.Const.getD_union_of_not_mem_left not_mem
theorem getD_union_of_not_mem_right [TransCmp cmp]
{k : α} {fallback : β} (not_mem : ¬k ∈ t₂) :
(t₁ t₂).getD k fallback = t₁.getD k fallback :=
DTreeMap.Const.getD_union_of_not_mem_right not_mem
/- getElem! -/
theorem getElem!_union [TransCmp cmp]
{k : α} [Inhabited β] :
(t₁ t₂)[k]! = t₂.getD k (t₁[k]!) :=
DTreeMap.Const.get!_union
theorem getElem!_union_of_not_mem_left [TransCmp cmp]
{k : α} [Inhabited β] (not_mem : ¬k ∈ t₁) :
(t₁ t₂)[k]! = t₂[k]! :=
DTreeMap.Const.get!_union_of_not_mem_left not_mem
theorem getElem!_union_of_not_mem_right [TransCmp cmp]
{k : α} [Inhabited β] (not_mem : ¬k ∈ t₂) :
(t₁ t₂)[k]! = t₁[k]! :=
DTreeMap.Const.get!_union_of_not_mem_right not_mem
/- get! -/
@[deprecated getElem!_union (since := "2025-12-10")]
theorem get!_union [TransCmp cmp]
{k : α} [Inhabited β] :
(t₁ t₂).get! k = t₂.getD k (t₁.get! k) :=
DTreeMap.Const.get!_union
@[deprecated getElem!_union_of_not_mem_left (since := "2025-12-10")]
theorem get!_union_of_not_mem_left [TransCmp cmp]
{k : α} [Inhabited β] (not_mem : ¬k ∈ t₁) :
(t₁ t₂).get! k = t₂.get! k :=
DTreeMap.Const.get!_union_of_not_mem_left not_mem
@[deprecated getElem!_union_of_not_mem_right (since := "2025-12-10")]
theorem get!_union_of_not_mem_right [TransCmp cmp]
{k : α} [Inhabited β] (not_mem : ¬k ∈ t₂) :
(t₁ t₂).get! k = t₁.get! k :=
DTreeMap.Const.get!_union_of_not_mem_right not_mem
/- getKey? -/
theorem getKey?_union [TransCmp cmp]
{k : α} :
(t₁ t₂).getKey? k = (t₂.getKey? k).or (t₁.getKey? k) :=
DTreeMap.getKey?_union
theorem getKey?_union_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : ¬k ∈ t₁) :
(t₁ t₂).getKey? k = t₂.getKey? k :=
DTreeMap.getKey?_union_of_not_mem_left not_mem
theorem getKey?_union_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : ¬k ∈ t₂) :
(t₁ t₂).getKey? k = t₁.getKey? k :=
DTreeMap.getKey?_union_of_not_mem_right not_mem
/- getKey -/
theorem getKey_union_of_mem_right [TransCmp cmp]
{k : α} (mem : k ∈ t₂) :
(t₁ t₂).getKey k (mem_union_of_right mem) = t₂.getKey k mem :=
DTreeMap.getKey_union_of_mem_right mem
theorem getKey_union_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : ¬k ∈ t₁) {h'} :
(t₁ t₂).getKey k h' = t₂.getKey k (mem_of_mem_union_of_not_mem_left h' not_mem) :=
DTreeMap.getKey_union_of_not_mem_left not_mem
theorem getKey_union_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : ¬k ∈ t₂) {h'} :
(t₁ t₂).getKey k h' = t₁.getKey k (mem_of_mem_union_of_not_mem_right h' not_mem) :=
DTreeMap.getKey_union_of_not_mem_right not_mem
/- getKeyD -/
theorem getKeyD_union [TransCmp cmp] {k fallback : α} :
(t₁ t₂).getKeyD k fallback = t₂.getKeyD k (t₁.getKeyD k fallback) :=
DTreeMap.getKeyD_union
theorem getKeyD_union_of_not_mem_left [TransCmp cmp] {k fallback : α} (mem : ¬k ∈ t₁) :
(t₁ t₂).getKeyD k fallback = t₂.getKeyD k fallback :=
DTreeMap.getKeyD_union_of_not_mem_left mem
theorem getKeyD_union_of_not_mem_right [TransCmp cmp] {k fallback : α} (mem : ¬k ∈ t₂) :
(t₁ t₂).getKeyD k fallback = t₁.getKeyD k fallback :=
DTreeMap.getKeyD_union_of_not_mem_right mem
/- getKey! -/
theorem getKey!_union [TransCmp cmp] [Inhabited α]
{k : α} :
(t₁ t₂).getKey! k = t₂.getKeyD k (t₁.getKey! k) :=
DTreeMap.getKey!_union
theorem getKey!_union_of_not_mem_left [Inhabited α]
[TransCmp cmp] {k : α}
(not_mem : ¬k ∈ t₁) :
(t₁ t₂).getKey! k = t₂.getKey! k :=
DTreeMap.getKey!_union_of_not_mem_left not_mem
theorem getKey!_union_of_not_mem_right [Inhabited α]
[TransCmp cmp] {k : α}
(not_mem : ¬k ∈ t₂) :
(t₁ t₂).getKey! k = t₁.getKey! k :=
DTreeMap.getKey!_union_of_not_mem_right not_mem
/- size -/
theorem size_union_of_not_mem [TransCmp cmp] : (∀ (a : α), a ∈ t₁ → ¬a ∈ t₂) →
(t₁ t₂).size = t₁.size + t₂.size :=
DTreeMap.size_union_of_not_mem
theorem size_left_le_size_union [TransCmp cmp] : t₁.size ≤ (t₁ t₂).size :=
DTreeMap.size_left_le_size_union
theorem size_right_le_size_union [TransCmp cmp] : t₂.size ≤ (t₁ t₂).size :=
DTreeMap.size_right_le_size_union
theorem size_union_le_size_add_size [TransCmp cmp] :
(t₁ t₂).size ≤ t₁.size + t₂.size :=
DTreeMap.size_union_le_size_add_size
/- isEmpty -/
@[simp]
theorem isEmpty_union [TransCmp cmp] :
(t₁ t₂).isEmpty = (t₁.isEmpty && t₂.isEmpty) :=
DTreeMap.isEmpty_union
end Union
section Inter
variable {t₁ t₂ : TreeMap α β cmp}
@[simp]
theorem inter_eq : t₁.inter t₂ = t₁ ∩ t₂ := by
simp only [Inter.inter]
/- contains -/
@[simp]
theorem contains_inter [TransCmp cmp] {k : α} :
(t₁ ∩ t₂).contains k = (t₁.contains k && t₂.contains k) :=
DTreeMap.contains_inter
/- mem -/
@[simp]
theorem mem_inter_iff [TransCmp cmp] {k : α} :
k ∈ t₁ ∩ t₂ ↔ k ∈ t₁ ∧ k ∈ t₂ :=
DTreeMap.mem_inter_iff
theorem not_mem_inter_of_not_mem_left [TransCmp cmp] {k : α}
(not_mem : k ∉ t₁) :
k ∉ t₁ ∩ t₂ :=
DTreeMap.not_mem_inter_of_not_mem_left not_mem
theorem not_mem_inter_of_not_mem_right [TransCmp cmp] {k : α}
(not_mem : k ∉ t₂) :
k ∉ t₁ ∩ t₂ :=
DTreeMap.not_mem_inter_of_not_mem_right not_mem
/- Equiv -/
theorem Equiv.inter_left {t₃ : TreeMap α β cmp} [TransCmp cmp]
(equiv : t₁ ~m t₂) :
(t₁ ∩ t₃).Equiv (t₂ ∩ t₃) := by
constructor
apply DTreeMap.Equiv.inter_left equiv.1
theorem Equiv.inter_right {t₃ : TreeMap α β cmp} [TransCmp cmp]
(equiv : t₂ ~m t₃) :
(t₁ ∩ t₂).Equiv (t₁ ∩ t₃) := by
constructor
apply DTreeMap.Equiv.inter_right equiv.1
theorem Equiv.inter_congr {t₃ t₄ : TreeMap α β cmp} [TransCmp cmp]
(equiv₁ : t₁ ~m t₃) (equiv₂ : t₂ ~m t₄) :
(t₁ ∩ t₂).Equiv (t₃ ∩ t₄) := by
constructor
apply DTreeMap.Equiv.inter_congr equiv₁.1 equiv₂.1
/- getElem? -/
theorem getElem?_inter [TransCmp cmp] {k : α} :
(t₁ ∩ t₂)[k]? = if k ∈ t₂ then t₁[k]? else none :=
DTreeMap.Const.get?_inter
theorem getElem?_inter_of_mem_right [TransCmp cmp]
{k : α} (mem : k ∈ t₂) :
(t₁ ∩ t₂)[k]? = t₁[k]? :=
DTreeMap.Const.get?_inter_of_mem_right mem
theorem getElem?_inter_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : k ∉ t₁) :
(t₁ ∩ t₂)[k]? = none :=
DTreeMap.Const.get?_inter_of_not_mem_left not_mem
theorem getElem?_inter_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : k ∉ t₂) :
(t₁ ∩ t₂)[k]? = none :=
DTreeMap.Const.get?_inter_of_not_mem_right not_mem
/- get? -/
@[deprecated getElem?_inter (since := "2025-12-10")]
theorem get?_inter [TransCmp cmp] {k : α} :
(t₁ ∩ t₂).get? k = if k ∈ t₂ then t₁.get? k else none :=
DTreeMap.Const.get?_inter
@[deprecated getElem?_inter_of_mem_right (since := "2025-12-10")]
theorem get?_inter_of_mem_right [TransCmp cmp]
{k : α} (mem : k ∈ t₂) :
(t₁ ∩ t₂).get? k = t₁.get? k :=
DTreeMap.Const.get?_inter_of_mem_right mem
@[deprecated getElem?_inter_of_not_mem_left (since := "2025-12-10")]
theorem get?_inter_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).get? k = none :=
DTreeMap.Const.get?_inter_of_not_mem_left not_mem
@[deprecated getElem?_inter_of_not_mem_right (since := "2025-12-10")]
theorem get?_inter_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).get? k = none :=
DTreeMap.Const.get?_inter_of_not_mem_right not_mem
/- getElem -/
@[simp]
theorem getElem_inter [TransCmp cmp]
{k : α} {h_mem : k ∈ t₁ ∩ t₂} :
(t₁ ∩ t₂)[k]'h_mem = t₁[k]'(mem_inter_iff.1 h_mem).1 :=
DTreeMap.Const.get_inter
/- get -/
@[deprecated getElem_inter (since := "2025-12-10")]
theorem get_inter [TransCmp cmp]
{k : α} {h_mem : k ∈ t₁ ∩ t₂} :
(t₁ ∩ t₂).get k h_mem = t₁.get k (mem_inter_iff.1 h_mem).1 :=
DTreeMap.Const.get_inter
/- getD -/
theorem getD_inter [TransCmp cmp] {k : α} {fallback : β} :
(t₁ ∩ t₂).getD k fallback =
if k ∈ t₂ then t₁.getD k fallback else fallback :=
DTreeMap.Const.getD_inter
theorem getD_inter_of_mem_right [TransCmp cmp]
{k : α} {fallback : β} (mem : k ∈ t₂) :
(t₁ ∩ t₂).getD k fallback = t₁.getD k fallback :=
DTreeMap.Const.getD_inter_of_mem_right mem
theorem getD_inter_of_not_mem_right [TransCmp cmp]
{k : α} {fallback : β} (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).getD k fallback = fallback :=
DTreeMap.Const.getD_inter_of_not_mem_right not_mem
theorem getD_inter_of_not_mem_left [TransCmp cmp]
{k : α} {fallback : β} (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).getD k fallback = fallback :=
DTreeMap.Const.getD_inter_of_not_mem_left not_mem
/- getElem! -/
theorem getElem!_inter [TransCmp cmp] {k : α} [Inhabited β] :
(t₁ ∩ t₂)[k]! = if k ∈ t₂ then t₁[k]! else default :=
DTreeMap.Const.get!_inter
theorem getElem!_inter_of_mem_right [TransCmp cmp]
{k : α} [Inhabited β] (mem : k ∈ t₂) :
(t₁ ∩ t₂)[k]! = t₁[k]! :=
DTreeMap.Const.get!_inter_of_mem_right mem
theorem getElem!_inter_of_not_mem_right [TransCmp cmp]
{k : α} [Inhabited β] (not_mem : k ∉ t₂) :
(t₁ ∩ t₂)[k]! = default :=
DTreeMap.Const.get!_inter_of_not_mem_right not_mem
theorem getElem!_inter_of_not_mem_left [TransCmp cmp]
{k : α} [Inhabited β] (not_mem : k ∉ t₁) :
(t₁ ∩ t₂)[k]! = default :=
DTreeMap.Const.get!_inter_of_not_mem_left not_mem
/- get! -/
@[deprecated getElem!_inter (since := "2025-12-10")]
theorem get!_inter [TransCmp cmp] {k : α} [Inhabited β] :
(t₁ ∩ t₂).get! k = if k ∈ t₂ then t₁.get! k else default :=
DTreeMap.Const.get!_inter
@[deprecated getElem!_inter_of_mem_right (since := "2025-12-10")]
theorem get!_inter_of_mem_right [TransCmp cmp]
{k : α} [Inhabited β] (mem : k ∈ t₂) :
(t₁ ∩ t₂).get! k = t₁.get! k :=
DTreeMap.Const.get!_inter_of_mem_right mem
@[deprecated getElem!_inter_of_not_mem_right (since := "2025-12-10")]
theorem get!_inter_of_not_mem_right [TransCmp cmp]
{k : α} [Inhabited β] (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).get! k = default :=
DTreeMap.Const.get!_inter_of_not_mem_right not_mem
@[deprecated getElem!_inter_of_not_mem_left (since := "2025-12-10")]
theorem get!_inter_of_not_mem_left [TransCmp cmp]
{k : α} [Inhabited β] (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).get! k = default :=
DTreeMap.Const.get!_inter_of_not_mem_left not_mem
/- getKey? -/
theorem getKey?_inter [TransCmp cmp] {k : α} :
(t₁ ∩ t₂).getKey? k =
if k ∈ t₂ then t₁.getKey? k else none :=
DTreeMap.getKey?_inter
theorem getKey?_inter_of_mem_right [TransCmp cmp]
{k : α} (mem : k ∈ t₂) :
(t₁ ∩ t₂).getKey? k = t₁.getKey? k :=
DTreeMap.getKey?_inter_of_mem_right mem
theorem getKey?_inter_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).getKey? k = none :=
DTreeMap.getKey?_inter_of_not_mem_right not_mem
theorem getKey?_inter_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).getKey? k = none :=
DTreeMap.getKey?_inter_of_not_mem_left not_mem
/- getKey -/
@[simp]
theorem getKey_inter [TransCmp cmp]
{k : α} {h_mem : k ∈ t₁ ∩ t₂} :
(t₁ ∩ t₂).getKey k h_mem =
t₁.getKey k (mem_inter_iff.1 h_mem).1 :=
DTreeMap.getKey_inter
/- getKeyD -/
theorem getKeyD_inter [TransCmp cmp] {k fallback : α} :
(t₁ ∩ t₂).getKeyD k fallback =
if k ∈ t₂ then t₁.getKeyD k fallback else fallback :=
DTreeMap.getKeyD_inter
theorem getKeyD_inter_of_mem_right [TransCmp cmp]
{k fallback : α} (mem : k ∈ t₂) :
(t₁ ∩ t₂).getKeyD k fallback = t₁.getKeyD k fallback :=
DTreeMap.getKeyD_inter_of_mem_right mem
theorem getKeyD_inter_of_not_mem_right [TransCmp cmp]
{k fallback : α} (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).getKeyD k fallback = fallback :=
DTreeMap.getKeyD_inter_of_not_mem_right not_mem
theorem getKeyD_inter_of_not_mem_left [TransCmp cmp]
{k fallback : α} (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).getKeyD k fallback = fallback :=
DTreeMap.getKeyD_inter_of_not_mem_left not_mem
/- getKey! -/
theorem getKey!_inter [TransCmp cmp] [Inhabited α] {k : α} :
(t₁ ∩ t₂).getKey! k =
if k ∈ t₂ then t₁.getKey! k else default :=
DTreeMap.getKey!_inter
theorem getKey!_inter_of_mem_right [TransCmp cmp] [Inhabited α]
{k : α} (mem : k ∈ t₂) :
(t₁ ∩ t₂).getKey! k = t₁.getKey! k :=
DTreeMap.getKey!_inter_of_mem_right mem
theorem getKey!_inter_of_not_mem_right [TransCmp cmp] [Inhabited α]
{k : α} (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).getKey! k = default :=
DTreeMap.getKey!_inter_of_not_mem_right not_mem
theorem getKey!_inter_of_not_mem_left [TransCmp cmp] [Inhabited α]
{k : α} (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).getKey! k = default :=
DTreeMap.getKey!_inter_of_not_mem_left not_mem
/- size -/
theorem size_inter_le_size_left [TransCmp cmp] :
(t₁ ∩ t₂).size ≤ t₁.size :=
DTreeMap.size_inter_le_size_left
theorem size_inter_le_size_right [TransCmp cmp] :
(t₁ ∩ t₂).size ≤ t₂.size :=
DTreeMap.size_inter_le_size_right
theorem size_inter_eq_size_left [TransCmp cmp]
(h : ∀ (a : α), a ∈ t₁ → a ∈ t₂) :
(t₁ ∩ t₂).size = t₁.size :=
DTreeMap.size_inter_eq_size_left h
theorem size_inter_eq_size_right [TransCmp cmp]
(h : ∀ (a : α), a ∈ t₂ → a ∈ t₁) :
(t₁ ∩ t₂).size = t₂.size :=
DTreeMap.size_inter_eq_size_right h
theorem size_add_size_eq_size_union_add_size_inter [TransCmp cmp] :
t₁.size + t₂.size = (t₁ t₂).size + (t₁ ∩ t₂).size :=
DTreeMap.size_add_size_eq_size_union_add_size_inter
/- isEmpty -/
@[simp]
theorem isEmpty_inter_left [TransCmp cmp] (h : t₁.isEmpty) :
(t₁ ∩ t₂).isEmpty = true :=
DTreeMap.isEmpty_inter_left h
@[simp]
theorem isEmpty_inter_right [TransCmp cmp] (h : t₂.isEmpty) :
(t₁ ∩ t₂).isEmpty = true :=
DTreeMap.isEmpty_inter_right h
theorem isEmpty_inter_iff [TransCmp cmp] :
(t₁ ∩ t₂).isEmpty ↔ ∀ k, k ∈ t₁ → k ∉ t₂ :=
DTreeMap.isEmpty_inter_iff
end Inter
section Diff
variable {t₁ t₂ : TreeMap α β cmp}
@[simp]
theorem diff_eq : t₁.diff t₂ = t₁ \ t₂ := by
simp only [SDiff.sdiff]
/- contains -/
@[simp]
theorem contains_diff [TransCmp cmp] {k : α} :
(t₁ \ t₂).contains k = (t₁.contains k && !t₂.contains k) :=
DTreeMap.contains_diff
/- mem -/
@[simp]
theorem mem_diff_iff [TransCmp cmp] {k : α} :
k ∈ t₁ \ t₂ ↔ k ∈ t₁ ∧ k ∉ t₂ :=
DTreeMap.mem_diff_iff
theorem not_mem_diff_of_not_mem_left [TransCmp cmp] {k : α}
(not_mem : k ∉ t₁) :
k ∉ t₁ \ t₂ :=
DTreeMap.not_mem_diff_of_not_mem_left not_mem
theorem not_mem_diff_of_mem_right [TransCmp cmp] {k : α}
(mem : k ∈ t₂) :
k ∉ t₁ \ t₂ :=
DTreeMap.not_mem_diff_of_mem_right mem
/- Equiv -/
theorem Equiv.diff_left {t₃ : TreeMap α β cmp} [TransCmp cmp]
(equiv : t₁ ~m t₂) :
(t₁ \ t₃).Equiv (t₂ \ t₃) := by
constructor
apply DTreeMap.Equiv.diff_left equiv.1
theorem Equiv.diff_right {t₃ : TreeMap α β cmp} [TransCmp cmp]
(equiv : t₂ ~m t₃) :
(t₁ \ t₂).Equiv (t₁ \ t₃) := by
constructor
apply DTreeMap.Equiv.diff_right equiv.1
theorem Equiv.diff_congr {t₃ t₄ : TreeMap α β cmp} [TransCmp cmp]
(equiv₁ : t₁ ~m t₃) (equiv₂ : t₂ ~m t₄) :
(t₁ \ t₂).Equiv (t₃ \ t₄) := by
constructor
apply DTreeMap.Equiv.diff_congr equiv₁.1 equiv₂.1
/- getElem? -/
theorem getElem?_diff [TransCmp cmp] {k : α} :
(t₁ \ t₂)[k]? = if k ∈ t₂ then none else t₁[k]? :=
DTreeMap.Const.get?_diff
theorem getElem?_diff_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : k ∉ t₂) :
(t₁ \ t₂)[k]? = t₁[k]? :=
DTreeMap.Const.get?_diff_of_not_mem_right not_mem
theorem getElem?_diff_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : k ∉ t₁) :
(t₁ \ t₂)[k]? = none :=
DTreeMap.Const.get?_diff_of_not_mem_left not_mem
theorem getElem?_diff_of_mem_right [TransCmp cmp]
{k : α} (mem : k ∈ t₂) :
(t₁ \ t₂)[k]? = none :=
DTreeMap.Const.get?_diff_of_mem_right mem
/- get? -/
@[deprecated getElem?_diff (since := "2025-12-10")]
theorem get?_diff [TransCmp cmp] {k : α} :
(t₁ \ t₂).get? k = if k ∈ t₂ then none else t₁.get? k :=
DTreeMap.Const.get?_diff
@[deprecated getElem?_diff_of_not_mem_right (since := "2025-12-10")]
theorem get?_diff_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : k ∉ t₂) :
(t₁ \ t₂).get? k = t₁.get? k :=
DTreeMap.Const.get?_diff_of_not_mem_right not_mem
@[deprecated getElem?_diff_of_not_mem_left (since := "2025-12-10")]
theorem get?_diff_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : k ∉ t₁) :
(t₁ \ t₂).get? k = none :=
DTreeMap.Const.get?_diff_of_not_mem_left not_mem
@[deprecated getElem?_diff_of_mem_right (since := "2025-12-10")]
theorem get?_diff_of_mem_right [TransCmp cmp]
{k : α} (mem : k ∈ t₂) :
(t₁ \ t₂).get? k = none :=
DTreeMap.Const.get?_diff_of_mem_right mem
/- getElem -/
theorem getElem_diff [TransCmp cmp]
{k : α} {h_mem : k ∈ t₁ \ t₂} :
(t₁ \ t₂)[k]'h_mem = t₁[k]'(mem_diff_iff.1 h_mem).1 :=
DTreeMap.Const.get_diff
/- get -/
@[deprecated getElem_diff (since := "2025-12-10")]
theorem get_diff [TransCmp cmp]
{k : α} {h_mem : k ∈ t₁ \ t₂} :
(t₁ \ t₂).get k h_mem = t₁.get k (mem_diff_iff.1 h_mem).1 :=
DTreeMap.Const.get_diff
/- getD -/
theorem getD_diff [TransCmp cmp] {k : α} {fallback : β} :
(t₁ \ t₂).getD k fallback =
if k ∈ t₂ then fallback else t₁.getD k fallback :=
DTreeMap.Const.getD_diff
theorem getD_diff_of_not_mem_right [TransCmp cmp]
{k : α} {fallback : β} (not_mem : k ∉ t₂) :
(t₁ \ t₂).getD k fallback = t₁.getD k fallback :=
DTreeMap.Const.getD_diff_of_not_mem_right not_mem
theorem getD_diff_of_mem_right [TransCmp cmp]
{k : α} {fallback : β} (mem : k ∈ t₂) :
(t₁ \ t₂).getD k fallback = fallback :=
DTreeMap.Const.getD_diff_of_mem_right mem
theorem getD_diff_of_not_mem_left [TransCmp cmp]
{k : α} {fallback : β} (not_mem : k ∉ t₁) :
(t₁ \ t₂).getD k fallback = fallback :=
DTreeMap.Const.getD_diff_of_not_mem_left not_mem
/- getElem! -/
theorem getElem!_diff [TransCmp cmp] {k : α} [Inhabited β] :
(t₁ \ t₂)[k]! = if k ∈ t₂ then default else t₁[k]! :=
DTreeMap.Const.get!_diff
theorem getElem!_diff_of_not_mem_right [TransCmp cmp]
{k : α} [Inhabited β] (not_mem : k ∉ t₂) :
(t₁ \ t₂)[k]! = t₁[k]! :=
DTreeMap.Const.get!_diff_of_not_mem_right not_mem
theorem getElem!_diff_of_mem_right [TransCmp cmp]
{k : α} [Inhabited β] (mem : k ∈ t₂) :
(t₁ \ t₂)[k]! = default :=
DTreeMap.Const.get!_diff_of_mem_right mem
theorem getElem!_diff_of_not_mem_left [TransCmp cmp]
{k : α} [Inhabited β] (not_mem : k ∉ t₁) :
(t₁ \ t₂)[k]! = default :=
DTreeMap.Const.get!_diff_of_not_mem_left not_mem
/- get! -/
@[deprecated getElem!_diff (since := "2025-12-10")]
theorem get!_diff [TransCmp cmp] {k : α} [Inhabited β] :
(t₁ \ t₂).get! k = if k ∈ t₂ then default else t₁.get! k :=
DTreeMap.Const.get!_diff
@[deprecated getElem!_diff_of_not_mem_right (since := "2025-12-10")]
theorem get!_diff_of_not_mem_right [TransCmp cmp]
{k : α} [Inhabited β] (not_mem : k ∉ t₂) :
(t₁ \ t₂).get! k = t₁.get! k :=
DTreeMap.Const.get!_diff_of_not_mem_right not_mem
@[deprecated getElem!_diff_of_mem_right (since := "2025-12-10")]
theorem get!_diff_of_mem_right [TransCmp cmp]
{k : α} [Inhabited β] (mem : k ∈ t₂) :
(t₁ \ t₂).get! k = default :=
DTreeMap.Const.get!_diff_of_mem_right mem
@[deprecated getElem!_diff_of_not_mem_left (since := "2025-12-10")]
theorem get!_diff_of_not_mem_left [TransCmp cmp]
{k : α} [Inhabited β] (not_mem : k ∉ t₁) :
(t₁ \ t₂).get! k = default :=
DTreeMap.Const.get!_diff_of_not_mem_left not_mem
/- getKey? -/
theorem getKey?_diff [TransCmp cmp] {k : α} :
(t₁ \ t₂).getKey? k =
if k ∈ t₂ then none else t₁.getKey? k :=
DTreeMap.getKey?_diff
theorem getKey?_diff_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : k ∉ t₂) :
(t₁ \ t₂).getKey? k = t₁.getKey? k :=
DTreeMap.getKey?_diff_of_not_mem_right not_mem
theorem getKey?_diff_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : k ∉ t₁) :
(t₁ \ t₂).getKey? k = none :=
DTreeMap.getKey?_diff_of_not_mem_left not_mem
theorem getKey?_diff_of_mem_right [TransCmp cmp]
{k : α} (mem : k ∈ t₂) :
(t₁ \ t₂).getKey? k = none :=
DTreeMap.getKey?_diff_of_mem_right mem
/- getKey -/
theorem getKey_diff [TransCmp cmp]
{k : α} {h_mem : k ∈ t₁ \ t₂} :
(t₁ \ t₂).getKey k h_mem =
t₁.getKey k (mem_diff_iff.1 h_mem).1 :=
DTreeMap.getKey_diff
/- getKeyD -/
theorem getKeyD_diff [TransCmp cmp] {k fallback : α} :
(t₁ \ t₂).getKeyD k fallback =
if k ∈ t₂ then fallback else t₁.getKeyD k fallback :=
DTreeMap.getKeyD_diff
theorem getKeyD_diff_of_not_mem_right [TransCmp cmp]
{k fallback : α} (not_mem : k ∉ t₂) :
(t₁ \ t₂).getKeyD k fallback = t₁.getKeyD k fallback :=
DTreeMap.getKeyD_diff_of_not_mem_right not_mem
theorem getKeyD_diff_of_mem_right [TransCmp cmp]
{k fallback : α} (mem : k ∈ t₂) :
(t₁ \ t₂).getKeyD k fallback = fallback :=
DTreeMap.getKeyD_diff_of_mem_right mem
theorem getKeyD_diff_of_not_mem_left [TransCmp cmp]
{k fallback : α} (not_mem : k ∉ t₁) :
(t₁ \ t₂).getKeyD k fallback = fallback :=
DTreeMap.getKeyD_diff_of_not_mem_left not_mem
/- getKey! -/
theorem getKey!_diff [TransCmp cmp] [Inhabited α] {k : α} :
(t₁ \ t₂).getKey! k =
if k ∈ t₂ then default else t₁.getKey! k :=
DTreeMap.getKey!_diff
theorem getKey!_diff_of_not_mem_right [TransCmp cmp] [Inhabited α]
{k : α} (not_mem : k ∉ t₂) :
(t₁ \ t₂).getKey! k = t₁.getKey! k :=
DTreeMap.getKey!_diff_of_not_mem_right not_mem
theorem getKey!_diff_of_mem_right [TransCmp cmp] [Inhabited α]
{k : α} (mem : k ∈ t₂) :
(t₁ \ t₂).getKey! k = default :=
DTreeMap.getKey!_diff_of_mem_right mem
theorem getKey!_diff_of_not_mem_left [TransCmp cmp] [Inhabited α]
{k : α} (not_mem : k ∉ t₁) :
(t₁ \ t₂).getKey! k = default :=
DTreeMap.getKey!_diff_of_not_mem_left not_mem
/- size -/
theorem size_diff_le_size_left [TransCmp cmp] :
(t₁ \ t₂).size ≤ t₁.size :=
DTreeMap.size_diff_le_size_left
theorem size_diff_eq_size_left [TransCmp cmp]
(h : ∀ (a : α), a ∈ t₁ → a ∉ t₂) :
(t₁ \ t₂).size = t₁.size :=
DTreeMap.size_diff_eq_size_left h
theorem size_diff_add_size_inter_eq_size_left [TransCmp cmp] :
(t₁ \ t₂).size + (t₁ ∩ t₂).size = t₁.size :=
DTreeMap.size_diff_add_size_inter_eq_size_left
/- isEmpty -/
@[simp]
theorem isEmpty_diff_left [TransCmp cmp] (h : t₁.isEmpty) :
(t₁ \ t₂).isEmpty = true :=
DTreeMap.isEmpty_diff_left h
theorem isEmpty_diff_iff [TransCmp cmp] :
(t₁ \ t₂).isEmpty ↔ ∀ k, k ∈ t₁ → k ∈ t₂ :=
DTreeMap.isEmpty_diff_iff
end Diff
section Alter
theorem isEmpty_alter_eq_isEmpty_erase [TransCmp cmp] {k : α}
{f : Option β → Option β} :
(alter t k f).isEmpty = ((t.erase k).isEmpty && (f t[k]?).isNone) :=
DTreeMap.Const.isEmpty_alter_eq_isEmpty_erase
@[simp, grind =]
theorem isEmpty_alter [TransCmp cmp] {k : α} {f : Option β → Option β} :
(alter t k f).isEmpty =
(((t.isEmpty || (t.size == 1 && t.contains k))) && (f t[k]?).isNone) :=
DTreeMap.Const.isEmpty_alter
@[grind =]
theorem contains_alter [TransCmp cmp] {k k' : α} {f : Option β → Option β} :
(alter t k f).contains k' =
if cmp k k' = .eq then (f t[k]?).isSome else t.contains k' :=
DTreeMap.Const.contains_alter
@[grind =]
theorem mem_alter [TransCmp cmp] {k k' : α} {f : Option β → Option β} :
k' ∈ alter t k f ↔
if cmp k k' = .eq then (f t[k]?).isSome = true else k' ∈ t :=
DTreeMap.Const.mem_alter
theorem mem_alter_of_compare_eq [TransCmp cmp] {k k' : α} {f : Option β → Option β}
(he : cmp k k' = .eq) :
k' ∈ alter t k f ↔ (f t[k]?).isSome :=
DTreeMap.Const.mem_alter_of_compare_eq he
@[simp]
theorem contains_alter_self [TransCmp cmp] {k : α} {f : Option β → Option β} :
(alter t k f).contains k = (f t[k]?).isSome :=
DTreeMap.Const.contains_alter_self
@[simp]
theorem mem_alter_self [TransCmp cmp] {k : α} {f : Option β → Option β} :
k ∈ alter t k f ↔ (f t[k]?).isSome :=
DTreeMap.Const.mem_alter_self
theorem contains_alter_of_not_compare_eq [TransCmp cmp] {k k' : α}
{f : Option β → Option β} (he : ¬ cmp k k' = .eq) :
(alter t k f).contains k' = t.contains k' :=
DTreeMap.Const.contains_alter_of_not_compare_eq he
theorem mem_alter_of_not_compare_eq [TransCmp cmp] {k k' : α} {f : Option β → Option β}
(he : ¬ cmp k k' = .eq) :
k' ∈ alter t k f ↔ k' ∈ t :=
DTreeMap.Const.mem_alter_of_not_compare_eq he
@[grind =]
theorem size_alter [TransCmp cmp] {k : α} {f : Option β → Option β} :
(alter t k f).size =
if k ∈ t ∧ (f t[k]?).isNone then
t.size - 1
else if k ∉ t ∧ (f t[k]?).isSome then
t.size + 1
else
t.size :=
DTreeMap.Const.size_alter
theorem size_alter_eq_add_one [TransCmp cmp] {k : α} {f : Option β → Option β}
(h₁ : k ∉ t) (h₂ : (f t[k]?).isSome) :
(alter t k f).size = t.size + 1 :=
DTreeMap.Const.size_alter_eq_add_one h₁ h₂
theorem size_alter_eq_sub_one [TransCmp cmp] {k : α} {f : Option β → Option β}
(h₁ : k ∈ t) (h₂ : (f t[k]?).isNone) :
(alter t k f).size = t.size - 1 :=
DTreeMap.Const.size_alter_eq_sub_one h₁ h₂
theorem size_alter_eq_self_of_not_mem [TransCmp cmp] {k : α} {f : Option β → Option β}
(h₁ : ¬ k ∈ t) (h₂ : (f t[k]?).isNone) :
(alter t k f).size = t.size :=
DTreeMap.Const.size_alter_eq_self_of_not_mem h₁ h₂
theorem size_alter_eq_self_of_mem [TransCmp cmp] {k : α} {f : Option β → Option β}
(h₁ : k ∈ t) (h₂ : (f t[k]?).isSome) :
(alter t k f).size = t.size :=
DTreeMap.Const.size_alter_eq_self_of_mem h₁ h₂
theorem size_alter_le_size [TransCmp cmp] {k : α} {f : Option β → Option β} :
(alter t k f).size ≤ t.size + 1 :=
DTreeMap.Const.size_alter_le_size
theorem size_le_size_alter [TransCmp cmp] {k : α} {f : Option β → Option β} :
t.size - 1 ≤ (alter t k f).size :=
DTreeMap.Const.size_le_size_alter
@[grind =]
theorem getElem?_alter [TransCmp cmp] {k k' : α} {f : Option β → Option β} :
(alter t k f)[k']? =
if cmp k k' = .eq then
f t[k]?
else
t[k']? :=
DTreeMap.Const.get?_alter
@[simp]
theorem getElem?_alter_self [TransCmp cmp] {k : α} {f : Option β → Option β} :
(alter t k f)[k]? = f t[k]? :=
DTreeMap.Const.get?_alter_self
@[grind =]
theorem getElem_alter [TransCmp cmp] {k k' : α} {f : Option β → Option β}
{hc : k' ∈ (alter t k f)} :
(alter t k f)[k']'hc =
if heq : cmp k k' = .eq then
haveI h' : (f t[k]?).isSome := mem_alter_of_compare_eq heq |>.mp hc
f t[k]? |>.get h'
else
haveI h' : k' ∈ t := mem_alter_of_not_compare_eq heq |>.mp hc
t[k']'h' :=
DTreeMap.Const.get_alter
@[simp]
theorem getElem_alter_self [TransCmp cmp] {k : α} {f : Option β → Option β}
{hc : k ∈ alter t k f} :
haveI h' : (f t[k]?).isSome := mem_alter_self.mp hc
(alter t k f)[k]'hc = (f t[k]?).get h' :=
DTreeMap.Const.get_alter_self
@[grind =]
theorem getElem!_alter [TransCmp cmp] {k k' : α} [Inhabited β] {f : Option β → Option β} :
(alter t k f)[k']! =
if cmp k k' = .eq then
f t[k]? |>.get!
else
t[k']! :=
DTreeMap.Const.get!_alter
@[simp]
theorem getElem!_alter_self [TransCmp cmp] {k : α} [Inhabited β] {f : Option β → Option β} :
(alter t k f)[k]! = (f t[k]?).get! :=
DTreeMap.Const.get!_alter_self
@[grind =]
theorem getD_alter [TransCmp cmp] {k k' : α} {fallback : β} {f : Option β → Option β} :
getD (alter t k f) k' fallback =
if cmp k k' = .eq then
f t[k]? |>.getD fallback
else
getD t k' fallback :=
DTreeMap.Const.getD_alter
@[simp]
theorem getD_alter_self [TransCmp cmp] {k : α} {fallback : β}
{f : Option β → Option β} :
getD (alter t k f) k fallback = (f t[k]?).getD fallback :=
DTreeMap.Const.getD_alter_self
@[grind =]
theorem getKey?_alter [TransCmp cmp] {k k' : α} {f : Option β → Option β} :
(alter t k f).getKey? k' =
if cmp k k' = .eq then
if (f t[k]?).isSome then some k else none
else
t.getKey? k' :=
DTreeMap.Const.getKey?_alter
theorem getKey?_alter_self [TransCmp cmp] {k : α} {f : Option β → Option β} :
(alter t k f).getKey? k = if (f t[k]?).isSome then some k else none :=
DTreeMap.Const.getKey?_alter_self
@[grind =]
theorem getKey!_alter [TransCmp cmp] [Inhabited α] {k k' : α} {f : Option β → Option β} :
(alter t k f).getKey! k' =
if cmp k k' = .eq then
if (f t[k]?).isSome then k else default
else
t.getKey! k' :=
DTreeMap.Const.getKey!_alter
theorem getKey!_alter_self [TransCmp cmp] [Inhabited α] {k : α}
{f : Option β → Option β} :
(alter t k f).getKey! k = if (f t[k]?).isSome then k else default :=
DTreeMap.Const.getKey!_alter_self
@[grind =]
theorem getKey_alter [TransCmp cmp] [Inhabited α] {k k' : α} {f : Option β → Option β}
{hc : k' ∈ alter t k f} :
(alter t k f).getKey k' hc =
if heq : cmp k k' = .eq then
k
else
haveI h' : k' ∈ t := mem_alter_of_not_compare_eq heq |>.mp hc
t.getKey k' h' :=
DTreeMap.Const.getKey_alter
@[simp]
theorem getKey_alter_self [TransCmp cmp] [Inhabited α] {k : α} {f : Option β → Option β}
{hc : k ∈ alter t k f} :
(alter t k f).getKey k hc = k :=
DTreeMap.Const.getKey_alter_self
@[grind =]
theorem getKeyD_alter [TransCmp cmp] {k k' fallback : α} {f : Option β → Option β} :
(alter t k f).getKeyD k' fallback =
if cmp k k' = .eq then
if (f t[k]?).isSome then k else fallback
else
t.getKeyD k' fallback :=
DTreeMap.Const.getKeyD_alter
@[simp]
theorem getKeyD_alter_self [TransCmp cmp] [Inhabited α] {k : α} {fallback : α}
{f : Option β → Option β} :
(alter t k f).getKeyD k fallback = if (f t[k]?).isSome then k else fallback :=
DTreeMap.Const.getKeyD_alter_self
end Alter
section Modify
@[simp, grind =]
theorem isEmpty_modify [TransCmp cmp] {k : α} {f : β → β} :
(modify t k f).isEmpty = t.isEmpty :=
DTreeMap.Const.isEmpty_modify
@[grind =]
theorem contains_modify [TransCmp cmp] {k k' : α} {f : β → β} :
(modify t k f).contains k' = t.contains k' :=
DTreeMap.Const.contains_modify
@[grind =]
theorem mem_modify [TransCmp cmp] {k k' : α} {f : β → β} :
k' ∈ modify t k f ↔ k' ∈ t :=
DTreeMap.Const.mem_modify
@[grind =]
theorem size_modify [TransCmp cmp] {k : α} {f : β → β} :
(modify t k f).size = t.size :=
DTreeMap.Const.size_modify
@[grind =]
theorem getElem?_modify [TransCmp cmp] {k k' : α} {f : β → β} :
(modify t k f)[k']? =
if cmp k k' = .eq then
t[k]?.map f
else
t[k']? :=
DTreeMap.Const.get?_modify
@[simp]
theorem getElem?_modify_self [TransCmp cmp] {k : α} {f : β → β} :
(modify t k f)[k]? = t[k]?.map f :=
DTreeMap.Const.get?_modify_self
@[grind =]
theorem getElem_modify [TransCmp cmp] {k k' : α} {f : β → β} {hc : k' ∈ modify t k f} :
(modify t k f)[k']'hc =
if heq : cmp k k' = .eq then
haveI h' : k ∈ t := mem_congr heq |>.mpr <| mem_modify.mp hc
f (t[k]'h')
else
haveI h' : k' ∈ t := mem_modify.mp hc
t[k']'h' :=
DTreeMap.Const.get_modify
@[simp]
theorem getElem_modify_self [TransCmp cmp] {k : α} {f : β → β} {hc : k ∈ modify t k f} :
haveI h' : k ∈ t := mem_modify.mp hc
(modify t k f)[k]'hc = f (t[k]'h') :=
DTreeMap.Const.get_modify_self
@[grind =]
theorem getElem!_modify [TransCmp cmp] {k k' : α} [hi : Inhabited β] {f : β → β} :
(modify t k f)[k']! =
if cmp k k' = .eq then
t[k]? |>.map f |>.get!
else
t[k']! :=
DTreeMap.Const.get!_modify
@[simp]
theorem getElem!_modify_self [TransCmp cmp] {k : α} [Inhabited β] {f : β → β} :
(modify t k f)[k]! = (t[k]?.map f).get! :=
DTreeMap.Const.get!_modify_self
@[grind =]
theorem getD_modify [TransCmp cmp] {k k' : α} {fallback : β} {f : β → β} :
getD (modify t k f) k' fallback =
if cmp k k' = .eq then
t[k]?.map f |>.getD fallback
else
getD t k' fallback :=
DTreeMap.Const.getD_modify
@[simp]
theorem getD_modify_self [TransCmp cmp] {k : α} {fallback : β} {f : β → β} :
getD (modify t k f) k fallback = (t[k]?.map f).getD fallback :=
DTreeMap.Const.getD_modify_self
@[grind =]
theorem getKey?_modify [TransCmp cmp] {k k' : α} {f : β → β} :
(modify t k f).getKey? k' =
if cmp k k' = .eq then
if k ∈ t then some k else none
else
t.getKey? k' :=
DTreeMap.Const.getKey?_modify
theorem getKey?_modify_self [TransCmp cmp] {k : α} {f : β → β} :
(modify t k f).getKey? k = if k ∈ t then some k else none :=
DTreeMap.Const.getKey?_modify_self
@[grind =]
theorem getKey!_modify [TransCmp cmp] [Inhabited α] {k k' : α} {f : β → β} :
(modify t k f).getKey! k' =
if cmp k k' = .eq then
if k ∈ t then k else default
else
t.getKey! k' :=
DTreeMap.Const.getKey!_modify
theorem getKey!_modify_self [TransCmp cmp] [Inhabited α] {k : α} {f : β → β} :
(modify t k f).getKey! k = if k ∈ t then k else default :=
DTreeMap.Const.getKey!_modify_self
@[grind =]
theorem getKey_modify [TransCmp cmp] [Inhabited α] {k k' : α} {f : β → β}
{hc : k' ∈ modify t k f} :
(modify t k f).getKey k' hc =
if cmp k k' = .eq then
k
else
haveI h' : k' ∈ t := mem_modify.mp hc
t.getKey k' h' :=
DTreeMap.Const.getKey_modify
@[simp]
theorem getKey_modify_self [TransCmp cmp] [Inhabited α] {k : α} {f : β → β}
{hc : k ∈ modify t k f} : (modify t k f).getKey k hc = k :=
DTreeMap.Const.getKey_modify_self
@[grind =]
theorem getKeyD_modify [TransCmp cmp] {k k' fallback : α} {f : β → β} :
(modify t k f).getKeyD k' fallback =
if cmp k k' = .eq then
if k ∈ t then k else fallback
else
t.getKeyD k' fallback :=
DTreeMap.Const.getKeyD_modify
theorem getKeyD_modify_self [TransCmp cmp] [Inhabited α] {k fallback : α} {f : β → β} :
(modify t k f).getKeyD k fallback = if k ∈ t then k else fallback :=
DTreeMap.Const.getKeyD_modify_self
end Modify
section Min
@[simp, grind =]
theorem minKey?_emptyc :
(∅ : TreeMap α β cmp).minKey? = none :=
DTreeMap.minKey?_emptyc
theorem minKey?_of_isEmpty [TransCmp cmp] :
(he : t.isEmpty) → t.minKey? = none :=
DTreeMap.minKey?_of_isEmpty
@[simp, grind =]
theorem minKey?_eq_none_iff [TransCmp cmp] :
t.minKey? = none ↔ t.isEmpty :=
DTreeMap.minKey?_eq_none_iff
theorem minKey?_eq_some_iff_getKey?_eq_self_and_forall [TransCmp cmp] {km} :
t.minKey? = some km ↔ t.getKey? km = some km ∧ ∀ k ∈ t, (cmp km k).isLE :=
DTreeMap.minKey?_eq_some_iff_getKey?_eq_self_and_forall
theorem minKey?_eq_some_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] {km} :
t.minKey? = some km ↔ km ∈ t ∧ ∀ k ∈ t, (cmp km k).isLE :=
DTreeMap.minKey?_eq_some_iff_mem_and_forall
@[simp, grind =]
theorem isNone_minKey?_eq_isEmpty [TransCmp cmp] :
t.minKey?.isNone = t.isEmpty :=
DTreeMap.isNone_minKey?_eq_isEmpty
@[simp, grind =]
theorem isSome_minKey?_eq_not_isEmpty [TransCmp cmp] :
t.minKey?.isSome = !t.isEmpty :=
DTreeMap.isSome_minKey?_eq_not_isEmpty
theorem isSome_minKey?_iff_isEmpty_eq_false [TransCmp cmp] :
t.minKey?.isSome ↔ t.isEmpty = false :=
DTreeMap.isSome_minKey?_iff_isEmpty_eq_false
@[grind =] theorem minKey?_insert [TransCmp cmp] {k v} :
(t.insert k v).minKey? =
some (t.minKey?.elim k fun k' => if cmp k k' |>.isLE then k else k') :=
DTreeMap.minKey?_insert
theorem minKey_insert_of_isEmpty [TransCmp cmp] {k v} (he : t.isEmpty) :
(t.insert k v).minKey isEmpty_insert = k :=
DTreeMap.minKey_insert_of_isEmpty he
theorem minKey?_insert_of_isEmpty [TransCmp cmp] {k v} (he : t.isEmpty) :
(t.insert k v).minKey? = some k :=
DTreeMap.minKey?_insert_of_isEmpty he
theorem minKey!_insert_of_isEmpty [TransCmp cmp] [Inhabited α] {k v} (he : t.isEmpty) :
(t.insert k v).minKey! = k :=
DTreeMap.minKey!_insert_of_isEmpty he
theorem minKeyD_insert_of_isEmpty [TransCmp cmp] {k v} (he : t.isEmpty) {fallback : α} :
(t.insert k v).minKeyD fallback = k :=
DTreeMap.minKeyD_insert_of_isEmpty he
theorem minKey_insertIfNew_of_isEmpty [TransCmp cmp] {k v} (he : t.isEmpty) :
(t.insertIfNew k v).minKey isEmpty_insertIfNew = k :=
DTreeMap.minKey_insertIfNew_of_isEmpty he
theorem minKey?_insertIfNew_of_isEmpty [TransCmp cmp] {k v} (he : t.isEmpty) :
(t.insertIfNew k v).minKey? = some k :=
DTreeMap.minKey?_insertIfNew_of_isEmpty he
theorem minKey!_insertIfNew_of_isEmpty [TransCmp cmp] [Inhabited α] {k v} (he : t.isEmpty) :
(t.insertIfNew k v).minKey! = k :=
DTreeMap.minKey!_insertIfNew_of_isEmpty he
theorem minKeyD_insertIfNew_of_isEmpty [TransCmp cmp] {k v} (he : t.isEmpty) {fallback : α} :
(t.insertIfNew k v).minKeyD fallback = k :=
DTreeMap.minKeyD_insertIfNew_of_isEmpty he
@[grind =] theorem isSome_minKey?_insert [TransCmp cmp] {k v} :
(t.insert k v).minKey?.isSome :=
DTreeMap.isSome_minKey?_insert
theorem minKey?_insert_le_minKey? [TransCmp cmp] {k v km kmi} :
(hkm : t.minKey? = some km) →
(hkmi : (t.insert k v |>.minKey? |>.get isSome_minKey?_insert) = kmi) →
cmp kmi km |>.isLE :=
DTreeMap.minKey?_insert_le_minKey?
theorem minKey?_insert_le_self [TransCmp cmp] {k v kmi} :
(hkmi : (t.insert k v |>.minKey?.get isSome_minKey?_insert) = kmi) →
cmp kmi k |>.isLE :=
DTreeMap.minKey?_insert_le_self
theorem contains_minKey? [TransCmp cmp] {km} :
(hkm : t.minKey? = some km) →
t.contains km :=
DTreeMap.contains_minKey?
theorem isSome_minKey?_of_contains [TransCmp cmp] {k} :
(hc : t.contains k) → t.minKey?.isSome :=
DTreeMap.isSome_minKey?_of_contains
theorem isSome_minKey?_of_mem [TransCmp cmp] {k} :
k ∈ t → t.minKey?.isSome :=
DTreeMap.isSome_minKey?_of_mem
theorem minKey?_le_of_contains [TransCmp cmp] {k km} :
(hc : t.contains k) → (hkm : (t.minKey?.get <| isSome_minKey?_of_contains hc) = km) →
cmp km k |>.isLE :=
DTreeMap.minKey?_le_of_contains
theorem minKey?_le_of_mem [TransCmp cmp] {k km} :
(hc : k ∈ t) → (hkm : (t.minKey?.get <| isSome_minKey?_of_mem hc) = km) →
cmp km k |>.isLE :=
DTreeMap.minKey?_le_of_mem
theorem le_minKey? [TransCmp cmp] {k} :
(∀ k', t.minKey? = some k' → (cmp k k').isLE) ↔
(∀ k', k' ∈ t → (cmp k k').isLE) :=
DTreeMap.le_minKey?
theorem getKey?_minKey? [TransCmp cmp] {km} :
(hkm : t.minKey? = some km) → t.getKey? km = some km :=
DTreeMap.getKey?_minKey?
theorem getKey_minKey? [TransCmp cmp] {km hc} :
(hkm : t.minKey?.get (isSome_minKey?_of_contains hc) = km) → t.getKey km hc = km :=
DTreeMap.getKey_minKey?
theorem getKey!_minKey? [TransCmp cmp] [Inhabited α] {km} :
(hkm : t.minKey? = some km) → t.getKey! km = km :=
DTreeMap.getKey!_minKey?
theorem getKeyD_minKey? [TransCmp cmp] {km fallback} :
(hkm : t.minKey? = some km) → t.getKeyD km fallback = km :=
DTreeMap.getKeyD_minKey?
@[simp]
theorem minKey?_bind_getKey? [TransCmp cmp] :
t.minKey?.bind t.getKey? = t.minKey? :=
DTreeMap.minKey?_bind_getKey?
theorem minKey?_erase_eq_iff_not_compare_eq_minKey? [TransCmp cmp] {k} :
(t.erase k |>.minKey?) = t.minKey? ↔
∀ {km}, t.minKey? = some km → ¬ cmp k km = .eq :=
DTreeMap.minKey?_erase_eq_iff_not_compare_eq_minKey?
theorem minKey?_erase_eq_of_not_compare_eq_minKey? [TransCmp cmp] {k} :
(hc : ∀ {km}, t.minKey? = some km → ¬ cmp k km = .eq) →
(t.erase k |>.minKey?) = t.minKey? :=
DTreeMap.minKey?_erase_eq_of_not_compare_eq_minKey?
theorem isSome_minKey?_of_isSome_minKey?_erase [TransCmp cmp] {k} :
(hs : t.erase k |>.minKey?.isSome) →
t.minKey?.isSome :=
DTreeMap.isSome_minKey?_of_isSome_minKey?_erase
theorem minKey?_le_minKey?_erase [TransCmp cmp] {k km kme} :
(hkme : (t.erase k |>.minKey?) = some kme) →
(hkm : (t.minKey?.get <|
isSome_minKey?_of_isSome_minKey?_erase <| hkme ▸ Option.isSome_some) = km) →
cmp km kme |>.isLE :=
DTreeMap.minKey?_le_minKey?_erase
@[grind =] theorem minKey?_insertIfNew [TransCmp cmp] {k v} :
(t.insertIfNew k v).minKey? =
some (t.minKey?.elim k fun k' => if cmp k k' = .lt then k else k') :=
DTreeMap.minKey?_insertIfNew
@[grind =] theorem isSome_minKey?_insertIfNew [TransCmp cmp] {k v} :
(t.insertIfNew k v).minKey?.isSome :=
DTreeMap.isSome_minKey?_insertIfNew
theorem minKey?_insertIfNew_le_minKey? [TransCmp cmp] {k v km kmi} :
(hkm : t.minKey? = some km) →
(hkmi : (t.insertIfNew k v |>.minKey? |>.get isSome_minKey?_insertIfNew) = kmi) →
cmp kmi km |>.isLE :=
DTreeMap.minKey?_insertIfNew_le_minKey?
theorem minKey?_insertIfNew_le_self [TransCmp cmp] {k v kmi} :
(hkmi : (t.insertIfNew k v |>.minKey?.get isSome_minKey?_insertIfNew) = kmi) →
cmp kmi k |>.isLE :=
DTreeMap.minKey?_insertIfNew_le_self
@[grind =_] theorem minKey?_eq_head?_keys [TransCmp cmp] :
t.minKey? = t.keys.head? :=
DTreeMap.minKey?_eq_head?_keys
theorem minKey?_modify [TransCmp cmp] {k f} :
(t.modify k f).minKey? = t.minKey?.map fun km => if cmp km k = .eq then k else km :=
DTreeMap.Const.minKey?_modify
@[simp, grind =]
theorem minKey?_modify_eq_minKey? [TransCmp cmp] [LawfulEqCmp cmp] {k f} :
(t.modify k f).minKey? = t.minKey? :=
DTreeMap.Const.minKey?_modify_eq_minKey?
@[grind =] theorem isSome_minKey?_modify [TransCmp cmp] {k f} :
(t.modify k f).minKey?.isSome = !t.isEmpty :=
DTreeMap.Const.isSome_minKey?_modify
theorem isSome_minKey?_modify_eq_isSome [TransCmp cmp] {k f} :
(t.modify k f).minKey?.isSome = t.minKey?.isSome :=
DTreeMap.Const.isSome_minKey?_modify_eq_isSome
theorem compare_minKey?_modify_eq [TransCmp cmp] {k f km kmm} :
(hkm : t.minKey? = some km) →
(hkmm : (t.modify k f |>.minKey? |>.get <|
isSome_minKey?_modify_eq_isSome.trans <| hkm ▸ Option.isSome_some) = kmm) →
cmp kmm km = .eq :=
DTreeMap.Const.compare_minKey?_modify_eq
theorem minKey?_alter_eq_self [TransCmp cmp] {k f} :
(t.alter k f).minKey? = some k ↔
(f t[k]?).isSome ∧ ∀ k', k' ∈ t → (cmp k k').isLE :=
DTreeMap.Const.minKey?_alter_eq_self
theorem minKey_eq_get_minKey? [TransCmp cmp] {he} :
t.minKey he = t.minKey?.get (isSome_minKey?_iff_isEmpty_eq_false.mpr he) :=
DTreeMap.minKey_eq_get_minKey?
theorem minKey?_eq_some_minKey [TransCmp cmp] {he} :
t.minKey? = some (t.minKey he) :=
DTreeMap.minKey?_eq_some_minKey
theorem minKey_eq_iff_getKey?_eq_self_and_forall [TransCmp cmp] {he km} :
t.minKey he = km ↔ t.getKey? km = some km ∧ ∀ k ∈ t, (cmp km k).isLE :=
DTreeMap.minKey_eq_iff_getKey?_eq_self_and_forall
theorem minKey_eq_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] {he km} :
t.minKey he = km ↔ km ∈ t ∧ ∀ k ∈ t, (cmp km k).isLE :=
DTreeMap.minKey_eq_iff_mem_and_forall
@[grind =] theorem minKey_insert [TransCmp cmp] {k v} :
(t.insert k v).minKey isEmpty_insert =
t.minKey?.elim k fun k' => if cmp k k' |>.isLE then k else k' :=
DTreeMap.minKey_insert
theorem minKey_insert_le_minKey [TransCmp cmp] {k v he} :
cmp (t.insert k v |>.minKey isEmpty_insert) (t.minKey he) |>.isLE :=
DTreeMap.minKey_insert_le_minKey
theorem minKey_insert_le_self [TransCmp cmp] {k v} :
cmp (t.insert k v |>.minKey isEmpty_insert) k |>.isLE :=
DTreeMap.minKey_insert_le_self
@[grind =] theorem contains_minKey [TransCmp cmp] {he} :
t.contains (t.minKey he) :=
DTreeMap.contains_minKey
theorem minKey_mem [TransCmp cmp] {he} :
t.minKey he ∈ t :=
DTreeMap.minKey_mem
grind_pattern minKey_mem => t.minKey he ∈ t
theorem minKey_le_of_contains [TransCmp cmp] {k} (hc : t.contains k) :
cmp (t.minKey <| isEmpty_eq_false_iff_exists_contains_eq_true.mpr ⟨k, hc⟩) k |>.isLE :=
DTreeMap.minKey_le_of_contains hc
theorem minKey_le_of_mem [TransCmp cmp] {k} (hc : k ∈ t) :
cmp (t.minKey <| isEmpty_eq_false_iff_exists_contains_eq_true.mpr ⟨k, hc⟩) k |>.isLE :=
DTreeMap.minKey_le_of_mem hc
theorem le_minKey [TransCmp cmp] {k he} :
(cmp k (t.minKey he)).isLE ↔ (∀ k', k' ∈ t → (cmp k k').isLE) :=
DTreeMap.le_minKey
@[simp, grind =]
theorem getKey?_minKey [TransCmp cmp] {he} :
t.getKey? (t.minKey he) = some (t.minKey he) :=
DTreeMap.getKey?_minKey
@[simp, grind =]
theorem getKey_minKey [TransCmp cmp] {he hc} :
t.getKey (t.minKey he) hc = t.minKey he :=
DTreeMap.getKey_minKey
@[simp, grind =]
theorem getKey!_minKey [TransCmp cmp] [Inhabited α] {he} :
t.getKey! (t.minKey he) = t.minKey he :=
DTreeMap.getKey!_minKey
@[simp, grind =]
theorem getKeyD_minKey [TransCmp cmp] {he fallback} :
t.getKeyD (t.minKey he) fallback = t.minKey he :=
DTreeMap.getKeyD_minKey
@[simp]
theorem minKey_erase_eq_iff_not_compare_eq_minKey [TransCmp cmp] {k he} :
(t.erase k |>.minKey he) =
t.minKey (isEmpty_eq_false_of_isEmpty_erase_eq_false he) ↔
¬ cmp k (t.minKey <| isEmpty_eq_false_of_isEmpty_erase_eq_false he) = .eq :=
DTreeMap.minKey_erase_eq_iff_not_compare_eq_minKey
theorem minKey_erase_eq_of_not_compare_eq_minKey [TransCmp cmp] {k he} :
(hc : ¬ cmp k (t.minKey (isEmpty_eq_false_of_isEmpty_erase_eq_false he)) = .eq) →
(t.erase k |>.minKey he) =
t.minKey (isEmpty_eq_false_of_isEmpty_erase_eq_false he) :=
DTreeMap.minKey_erase_eq_of_not_compare_eq_minKey
theorem minKey_le_minKey_erase [TransCmp cmp] {k he} :
cmp (t.minKey <| isEmpty_eq_false_of_isEmpty_erase_eq_false he)
(t.erase k |>.minKey he) |>.isLE :=
DTreeMap.minKey_le_minKey_erase
@[grind =] theorem minKey_insertIfNew [TransCmp cmp] {k v} :
(t.insertIfNew k v).minKey isEmpty_insertIfNew =
t.minKey?.elim k fun k' => if cmp k k' = .lt then k else k' :=
DTreeMap.minKey_insertIfNew
theorem minKey_insertIfNew_le_minKey [TransCmp cmp] {k v he} :
cmp (t.insertIfNew k v |>.minKey isEmpty_insertIfNew)
(t.minKey he) |>.isLE :=
DTreeMap.minKey_insertIfNew_le_minKey (t := t.inner) (he := he)
theorem minKey_insertIfNew_le_self [TransCmp cmp] {k v} :
cmp (t.insertIfNew k v |>.minKey <| isEmpty_insertIfNew) k |>.isLE :=
DTreeMap.minKey_insertIfNew_le_self
@[grind =_] theorem minKey_eq_head_keys [TransCmp cmp] {he} :
t.minKey he = t.keys.head (List.isEmpty_eq_false_iff.mp <| isEmpty_keys ▸ he) :=
DTreeMap.minKey_eq_head_keys
theorem minKey_modify [TransCmp cmp] {k f he} :
(modify t k f).minKey he =
if cmp (t.minKey <| cast (congrArg (· = false) isEmpty_modify) he) k = .eq then
k
else
(t.minKey <| cast (congrArg (· = false) isEmpty_modify) he) :=
DTreeMap.Const.minKey_modify
@[simp, grind =]
theorem minKey_modify_eq_minKey [TransCmp cmp] [LawfulEqCmp cmp] {k f he} :
(modify t k f).minKey he = t.minKey (cast (congrArg (· = false) isEmpty_modify) he) :=
DTreeMap.Const.minKey_modify_eq_minKey
theorem compare_minKey_modify_eq [TransCmp cmp] {k f he} :
cmp (modify t k f |>.minKey he)
(t.minKey <| cast (congrArg (· = false) isEmpty_modify) he) = .eq :=
DTreeMap.Const.compare_minKey_modify_eq
@[simp]
theorem ordCompare_minKey_modify_eq [Ord α] [TransOrd α] {t : TreeMap α β} {k f he} :
compare (modify t k f |>.minKey he)
(t.minKey <| cast (congrArg (· = false) isEmpty_modify) he) = .eq :=
compare_minKey_modify_eq
theorem minKey_alter_eq_self [TransCmp cmp] {k f he} :
(alter t k f).minKey he = k ↔
(f t[k]?).isSome ∧ ∀ k', k' ∈ t → (cmp k k').isLE :=
DTreeMap.Const.minKey_alter_eq_self
theorem minKey?_eq_some_minKey! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.minKey? = some t.minKey! :=
DTreeMap.minKey?_eq_some_minKey! he
theorem minKey_eq_minKey! [TransCmp cmp] [Inhabited α] {he : t.isEmpty = false} :
t.minKey he = t.minKey! :=
DTreeMap.minKey_eq_minKey!
theorem minKey!_eq_default [TransCmp cmp] [Inhabited α] (he : t.isEmpty) :
t.minKey! = default :=
DTreeMap.minKey!_eq_default he
theorem minKey!_eq_iff_getKey?_eq_self_and_forall [TransCmp cmp] [Inhabited α]
(he : t.isEmpty = false) {km} :
t.minKey! = km ↔ t.getKey? km = some km ∧ ∀ k, k ∈ t → (cmp km k).isLE :=
DTreeMap.minKey!_eq_iff_getKey?_eq_self_and_forall he
theorem minKey!_eq_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α]
(he : t.isEmpty = false) {km} :
t.minKey! = km ↔ km ∈ t ∧ ∀ k, k ∈ t → (cmp km k).isLE :=
DTreeMap.minKey!_eq_iff_mem_and_forall he
@[grind =]
theorem minKey!_insert [TransCmp cmp] [Inhabited α] {k v} :
(t.insert k v).minKey! =
(t.minKey?.elim k fun k' => if cmp k k' |>.isLE then k else k') :=
DTreeMap.minKey!_insert
theorem minKey!_insert_le_minKey! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {k v} :
cmp (t.insert k v).minKey! t.minKey! |>.isLE :=
DTreeMap.minKey!_insert_le_minKey! he
theorem minKey!_insert_le_self [TransCmp cmp] [Inhabited α] {k v} :
cmp (t.insert k v).minKey! k |>.isLE :=
DTreeMap.minKey!_insert_le_self
theorem contains_minKey! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.contains t.minKey! :=
DTreeMap.contains_minKey! he
theorem minKey!_mem [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.minKey! ∈ t :=
DTreeMap.minKey!_mem he
theorem minKey!_le_of_contains [TransCmp cmp] [Inhabited α] {k} (hc : t.contains k) :
cmp t.minKey! k |>.isLE :=
DTreeMap.minKey!_le_of_contains hc
theorem minKey!_le_of_mem [TransCmp cmp] [Inhabited α] {k} (hc : k ∈ t) :
cmp t.minKey! k |>.isLE :=
DTreeMap.minKey!_le_of_mem hc
theorem le_minKey! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {k} :
(cmp k t.minKey!).isLE ↔ (∀ k', k' ∈ t → (cmp k k').isLE) :=
DTreeMap.le_minKey! he
theorem getKey?_minKey! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.getKey? t.minKey! = some t.minKey! :=
DTreeMap.getKey?_minKey! he
@[grind =] theorem getKey_minKey! [TransCmp cmp] [Inhabited α] {hc} :
t.getKey t.minKey! hc = t.minKey! :=
DTreeMap.getKey_minKey!
@[simp, grind =]
theorem getKey_minKey!_eq_minKey [TransCmp cmp] [Inhabited α] {hc} :
t.getKey t.minKey! hc = t.minKey (isEmpty_eq_false_of_contains hc) :=
DTreeMap.getKey_minKey!_eq_minKey
theorem getKey!_minKey! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.getKey! t.minKey! = t.minKey! :=
DTreeMap.getKey!_minKey! he
theorem getKeyD_minKey! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {fallback} :
t.getKeyD t.minKey! fallback = t.minKey! :=
DTreeMap.getKeyD_minKey! he
theorem minKey!_erase_eq_of_not_compare_minKey!_eq [TransCmp cmp] [Inhabited α] {k}
(he : (t.erase k).isEmpty = false) (heq : ¬ cmp k t.minKey! = .eq) :
(t.erase k).minKey! = t.minKey! :=
DTreeMap.minKey!_erase_eq_of_not_compare_minKey!_eq he heq
theorem minKey!_le_minKey!_erase [TransCmp cmp] [Inhabited α] {k}
(he : (t.erase k).isEmpty = false) :
cmp t.minKey! (t.erase k).minKey! |>.isLE :=
DTreeMap.minKey!_le_minKey!_erase he
@[grind =]
theorem minKey!_insertIfNew [TransCmp cmp] [Inhabited α] {k v} :
(t.insertIfNew k v).minKey! =
t.minKey?.elim k fun k' => if cmp k k' = .lt then k else k' :=
DTreeMap.minKey!_insertIfNew
theorem minKey!_insertIfNew_le_minKey! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {k v} :
cmp (t.insertIfNew k v).minKey! t.minKey! |>.isLE :=
DTreeMap.minKey!_insertIfNew_le_minKey! he
theorem minKey!_insertIfNew_le_self [TransCmp cmp] [Inhabited α] {k v} :
cmp (t.insertIfNew k v).minKey! k |>.isLE :=
DTreeMap.minKey!_insertIfNew_le_self
@[grind =_]
theorem minKey!_eq_head!_keys [TransCmp cmp] [Inhabited α] :
t.minKey! = t.keys.head! :=
DTreeMap.minKey!_eq_head!_keys
theorem minKey!_modify [TransCmp cmp] [Inhabited α] {k f}
(he : (modify t k f).isEmpty = false) :
(modify t k f).minKey! = if cmp t.minKey! k = .eq then k else t.minKey! :=
DTreeMap.Const.minKey!_modify he
@[simp]
theorem minKey!_modify_eq_minKey! [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] {k f} :
(modify t k f).minKey! = t.minKey! :=
DTreeMap.Const.minKey!_modify_eq_minKey!
theorem compare_minKey!_modify_eq [TransCmp cmp] [Inhabited α] {k f} :
cmp (modify t k f).minKey! t.minKey! = .eq :=
DTreeMap.Const.compare_minKey!_modify_eq
@[simp]
theorem ordCompare_minKey!_modify_eq [Ord α] [TransOrd α] {t : TreeMap α β} [Inhabited α] {k f} :
compare (modify t k f).minKey! t.minKey! = .eq :=
compare_minKey!_modify_eq
theorem minKey!_alter_eq_self [TransCmp cmp] [Inhabited α] {k f}
(he : (alter t k f).isEmpty = false) :
(alter t k f).minKey! = k ↔
(f t[k]?).isSome ∧ ∀ k', k' ∈ t → (cmp k k').isLE :=
DTreeMap.Const.minKey!_alter_eq_self he
theorem minKey?_eq_some_minKeyD [TransCmp cmp] (he : t.isEmpty = false) {fallback} :
t.minKey? = some (t.minKeyD fallback) :=
DTreeMap.minKey?_eq_some_minKeyD he
theorem minKeyD_eq_fallback [TransCmp cmp] (he : t.isEmpty) {fallback} :
t.minKeyD fallback = fallback :=
DTreeMap.minKeyD_eq_fallback he
theorem minKey!_eq_minKeyD_default [TransCmp cmp] [Inhabited α] :
t.minKey! = t.minKeyD default :=
DTreeMap.minKey!_eq_minKeyD_default
theorem minKeyD_eq_iff_getKey?_eq_self_and_forall [TransCmp cmp]
(he : t.isEmpty = false) {km fallback} :
t.minKeyD fallback = km ↔ t.getKey? km = some km ∧ ∀ k, k ∈ t → (cmp km k).isLE :=
DTreeMap.minKeyD_eq_iff_getKey?_eq_self_and_forall he
theorem minKeyD_eq_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp]
(he : t.isEmpty = false) {km fallback} :
t.minKeyD fallback = km ↔ km ∈ t ∧ ∀ k, k ∈ t → (cmp km k).isLE :=
DTreeMap.minKeyD_eq_iff_mem_and_forall he
@[grind =]
theorem minKeyD_insert [TransCmp cmp] {k v fallback} :
(t.insert k v |>.minKeyD fallback) =
(t.minKey?.elim k fun k' => if cmp k k' |>.isLE then k else k') :=
DTreeMap.minKeyD_insert
theorem minKeyD_insert_le_minKeyD [TransCmp cmp] (he : t.isEmpty = false)
{k v fallback} :
cmp (t.insert k v |>.minKeyD fallback) (t.minKeyD fallback) |>.isLE :=
DTreeMap.minKeyD_insert_le_minKeyD he
theorem minKeyD_insert_le_self [TransCmp cmp] {k v fallback} :
cmp (t.insert k v |>.minKeyD fallback) k |>.isLE :=
DTreeMap.minKeyD_insert_le_self
theorem contains_minKeyD [TransCmp cmp] (he : t.isEmpty = false) {fallback} :
t.contains (t.minKeyD fallback) :=
DTreeMap.contains_minKeyD he
theorem minKeyD_mem [TransCmp cmp] (he : t.isEmpty = false) {fallback} :
t.minKeyD fallback ∈ t :=
DTreeMap.minKeyD_mem he
theorem minKeyD_le_of_contains [TransCmp cmp] {k} (hc : t.contains k) {fallback} :
cmp (t.minKeyD fallback) k |>.isLE :=
DTreeMap.minKeyD_le_of_contains hc
theorem minKeyD_le_of_mem [TransCmp cmp] {k} (hc : k ∈ t) {fallback} :
cmp (t.minKeyD fallback) k |>.isLE :=
DTreeMap.minKeyD_le_of_mem hc
theorem le_minKeyD [TransCmp cmp] (he : t.isEmpty = false) {k fallback} :
(cmp k (t.minKeyD fallback)).isLE ↔ (∀ k', k' ∈ t → (cmp k k').isLE) :=
DTreeMap.le_minKeyD he
theorem getKey?_minKeyD [TransCmp cmp] (he : t.isEmpty = false) {fallback} :
t.getKey? (t.minKeyD fallback) = some (t.minKeyD fallback) :=
DTreeMap.getKey?_minKeyD he
@[grind =] theorem getKey_minKeyD [TransCmp cmp] {fallback hc} :
t.getKey (t.minKeyD fallback) hc = t.minKeyD fallback :=
DTreeMap.getKey_minKeyD
theorem getKey!_minKeyD [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {fallback} :
t.getKey! (t.minKeyD fallback) = t.minKeyD fallback :=
DTreeMap.getKey!_minKeyD he
theorem getKeyD_minKeyD [TransCmp cmp] (he : t.isEmpty = false) {fallback fallback'} :
t.getKeyD (t.minKeyD fallback) fallback' = t.minKeyD fallback :=
DTreeMap.getKeyD_minKeyD he
theorem minKeyD_erase_eq_of_not_compare_minKeyD_eq [TransCmp cmp] {k fallback}
(he : (t.erase k).isEmpty = false) (heq : ¬ cmp k (t.minKeyD fallback) = .eq) :
(t.erase k |>.minKeyD fallback) = t.minKeyD fallback :=
DTreeMap.minKeyD_erase_eq_of_not_compare_minKeyD_eq he heq
theorem minKeyD_le_minKeyD_erase [TransCmp cmp] {k}
(he : (t.erase k).isEmpty = false) {fallback} :
cmp (t.minKeyD fallback) (t.erase k |>.minKeyD fallback) |>.isLE :=
DTreeMap.minKeyD_le_minKeyD_erase he
@[grind =]
theorem minKeyD_insertIfNew [TransCmp cmp] {k v fallback} :
(t.insertIfNew k v |>.minKeyD fallback) =
t.minKey?.elim k fun k' => if cmp k k' = .lt then k else k' :=
DTreeMap.minKeyD_insertIfNew
theorem minKeyD_insertIfNew_le_minKeyD [TransCmp cmp]
(he : t.isEmpty = false) {k v fallback} :
cmp (t.insertIfNew k v |>.minKeyD fallback) (t.minKeyD fallback) |>.isLE :=
DTreeMap.minKeyD_insertIfNew_le_minKeyD he
theorem minKeyD_insertIfNew_le_self [TransCmp cmp] {k v fallback} :
cmp (t.insertIfNew k v |>.minKeyD fallback) k |>.isLE :=
DTreeMap.minKeyD_insertIfNew_le_self
theorem minKeyD_eq_headD_keys [TransCmp cmp] {fallback} :
t.minKeyD fallback = t.keys.headD fallback :=
DTreeMap.minKeyD_eq_headD_keys
theorem minKeyD_modify [TransCmp cmp] {k f}
(he : (modify t k f).isEmpty = false) {fallback} :
(modify t k f |>.minKeyD fallback) =
if cmp (t.minKeyD fallback) k = .eq then k else (t.minKeyD fallback) :=
DTreeMap.Const.minKeyD_modify he
@[simp, grind =]
theorem minKeyD_modify_eq_minKeyD [TransCmp cmp] [LawfulEqCmp cmp] {k f fallback} :
(modify t k f |>.minKeyD fallback) = t.minKeyD fallback :=
DTreeMap.Const.minKeyD_modify_eq_minKeyD
theorem compare_minKeyD_modify_eq [TransCmp cmp] {k f fallback} :
cmp (modify t k f |>.minKeyD fallback) (t.minKeyD fallback) = .eq :=
DTreeMap.Const.compare_minKeyD_modify_eq
@[simp]
theorem ordCompare_minKeyD_modify_eq [Ord α] [TransOrd α] {t : TreeMap α β} {k f fallback} :
compare (modify t k f |>.minKeyD fallback) (t.minKeyD fallback) = .eq :=
compare_minKeyD_modify_eq
theorem minKeyD_alter_eq_self [TransCmp cmp] {k f}
(he : (alter t k f).isEmpty = false) {fallback} :
(alter t k f |>.minKeyD fallback) = k ↔
(f t[k]?).isSome ∧ ∀ k', k' ∈ t → (cmp k k').isLE :=
DTreeMap.Const.minKeyD_alter_eq_self he
end Min
section Max
@[simp, grind =]
theorem maxKey?_emptyc :
(∅ : TreeMap α β cmp).maxKey? = none :=
DTreeMap.maxKey?_emptyc
theorem maxKey?_of_isEmpty [TransCmp cmp] :
(he : t.isEmpty) → t.maxKey? = none :=
DTreeMap.maxKey?_of_isEmpty
@[simp, grind =]
theorem maxKey?_eq_none_iff [TransCmp cmp] :
t.maxKey? = none ↔ t.isEmpty :=
DTreeMap.maxKey?_eq_none_iff
theorem maxKey?_eq_some_iff_getKey?_eq_self_and_forall [TransCmp cmp] {km} :
t.maxKey? = some km ↔ t.getKey? km = some km ∧ ∀ k ∈ t, (cmp k km).isLE :=
DTreeMap.maxKey?_eq_some_iff_getKey?_eq_self_and_forall
theorem maxKey?_eq_some_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] {km} :
t.maxKey? = some km ↔ km ∈ t ∧ ∀ k ∈ t, (cmp k km).isLE :=
DTreeMap.maxKey?_eq_some_iff_mem_and_forall
@[simp, grind =]
theorem isNone_maxKey?_eq_isEmpty [TransCmp cmp] :
t.maxKey?.isNone = t.isEmpty :=
DTreeMap.isNone_maxKey?_eq_isEmpty
@[simp, grind =]
theorem isSome_maxKey?_eq_not_isEmpty [TransCmp cmp] :
t.maxKey?.isSome = !t.isEmpty :=
DTreeMap.isSome_maxKey?_eq_not_isEmpty
theorem isSome_maxKey?_iff_isEmpty_eq_false [TransCmp cmp] :
t.maxKey?.isSome ↔ t.isEmpty = false :=
DTreeMap.isSome_maxKey?_iff_isEmpty_eq_false
@[grind =]
theorem maxKey?_insert [TransCmp cmp] {k v} :
(t.insert k v).maxKey? =
some (t.maxKey?.elim k fun k' => if cmp k' k |>.isLE then k else k') :=
DTreeMap.maxKey?_insert
@[grind =]
theorem isSome_maxKey?_insert [TransCmp cmp] {k v} :
(t.insert k v).maxKey?.isSome :=
DTreeMap.isSome_maxKey?_insert
theorem maxKey?_le_maxKey?_insert [TransCmp cmp] {k v km kmi} :
(hkm : t.maxKey? = some km) →
(hkmi : (t.insert k v |>.maxKey? |>.get isSome_maxKey?_insert) = kmi) →
cmp km kmi |>.isLE :=
DTreeMap.maxKey?_le_maxKey?_insert
theorem self_le_maxKey?_insert [TransCmp cmp] {k v kmi} :
(hkmi : (t.insert k v |>.maxKey?.get isSome_maxKey?_insert) = kmi) →
cmp k kmi |>.isLE :=
DTreeMap.self_le_maxKey?_insert
theorem contains_maxKey? [TransCmp cmp] {km} :
(hkm : t.maxKey? = some km) →
t.contains km :=
DTreeMap.contains_maxKey?
theorem isSome_maxKey?_of_contains [TransCmp cmp] {k} :
(hc : t.contains k) → t.maxKey?.isSome :=
DTreeMap.isSome_maxKey?_of_contains
theorem isSome_maxKey?_of_mem [TransCmp cmp] {k} :
k ∈ t → t.maxKey?.isSome :=
DTreeMap.isSome_maxKey?_of_mem
theorem le_maxKey?_of_contains [TransCmp cmp] {k km} :
(hc : t.contains k) → (hkm : (t.maxKey?.get <| isSome_maxKey?_of_contains hc) = km) →
cmp k km |>.isLE :=
DTreeMap.le_maxKey?_of_contains
theorem le_maxKey?_of_mem [TransCmp cmp] {k km} :
(hc : k ∈ t) → (hkm : (t.maxKey?.get <| isSome_maxKey?_of_mem hc) = km) →
cmp k km |>.isLE :=
DTreeMap.le_maxKey?_of_mem
theorem maxKey?_le [TransCmp cmp] {k} :
(∀ k', t.maxKey? = some k' → (cmp k' k).isLE) ↔
(∀ k', k' ∈ t → (cmp k' k).isLE) :=
DTreeMap.maxKey?_le
theorem getKey?_maxKey? [TransCmp cmp] {km} :
(hkm : t.maxKey? = some km) → t.getKey? km = some km :=
DTreeMap.getKey?_maxKey?
theorem getKey_maxKey? [TransCmp cmp] {km hc} :
(hkm : t.maxKey?.get (isSome_maxKey?_of_contains hc) = km) → t.getKey km hc = km :=
DTreeMap.getKey_maxKey?
theorem getKey!_maxKey? [TransCmp cmp] [Inhabited α] {km} :
(hkm : t.maxKey? = some km) → t.getKey! km = km :=
DTreeMap.getKey!_maxKey?
theorem getKeyD_maxKey? [TransCmp cmp] {km fallback} :
(hkm : t.maxKey? = some km) → t.getKeyD km fallback = km :=
DTreeMap.getKeyD_maxKey?
@[simp]
theorem maxKey?_bind_getKey? [TransCmp cmp] :
t.maxKey?.bind t.getKey? = t.maxKey? :=
DTreeMap.maxKey?_bind_getKey?
theorem maxKey?_erase_eq_iff_not_compare_eq_maxKey? [TransCmp cmp] {k} :
(t.erase k |>.maxKey?) = t.maxKey? ↔
∀ {km}, t.maxKey? = some km → ¬ cmp k km = .eq :=
DTreeMap.maxKey?_erase_eq_iff_not_compare_eq_maxKey?
theorem maxKey?_erase_eq_of_not_compare_eq_maxKey? [TransCmp cmp] {k} :
(hc : ∀ {km}, t.maxKey? = some km → ¬ cmp k km = .eq) →
(t.erase k |>.maxKey?) = t.maxKey? :=
DTreeMap.maxKey?_erase_eq_of_not_compare_eq_maxKey?
theorem isSome_maxKey?_of_isSome_maxKey?_erase [TransCmp cmp] {k} :
(hs : t.erase k |>.maxKey?.isSome) →
t.maxKey?.isSome :=
DTreeMap.isSome_maxKey?_of_isSome_maxKey?_erase
theorem maxKey?_erase_le_maxKey? [TransCmp cmp] {k km kme} :
(hkme : (t.erase k |>.maxKey?) = some kme) →
(hkm : (t.maxKey?.get <|
isSome_maxKey?_of_isSome_maxKey?_erase <| hkme ▸ Option.isSome_some) = km) →
cmp kme km |>.isLE :=
DTreeMap.maxKey?_erase_le_maxKey?
@[grind =] theorem maxKey?_insertIfNew [TransCmp cmp] {k v} :
(t.insertIfNew k v).maxKey? =
some (t.maxKey?.elim k fun k' => if cmp k' k = .lt then k else k') :=
DTreeMap.maxKey?_insertIfNew
@[grind =] theorem isSome_maxKey?_insertIfNew [TransCmp cmp] {k v} :
(t.insertIfNew k v).maxKey?.isSome :=
DTreeMap.isSome_maxKey?_insertIfNew
theorem maxKey?_le_maxKey?_insertIfNew [TransCmp cmp] {k v km kmi} :
(hkm : t.maxKey? = some km) →
(hkmi : (t.insertIfNew k v |>.maxKey? |>.get isSome_maxKey?_insertIfNew) = kmi) →
cmp km kmi |>.isLE :=
DTreeMap.maxKey?_le_maxKey?_insertIfNew
theorem self_le_maxKey?_insertIfNew [TransCmp cmp] {k v kmi} :
(hkmi : (t.insertIfNew k v |>.maxKey?.get isSome_maxKey?_insertIfNew) = kmi) →
cmp k kmi |>.isLE :=
DTreeMap.self_le_maxKey?_insertIfNew
@[grind =_] theorem maxKey?_eq_getLast?_keys [TransCmp cmp] :
t.maxKey? = t.keys.getLast? :=
DTreeMap.maxKey?_eq_getLast?_keys
@[grind =] theorem maxKey?_modify [TransCmp cmp] {k f} :
(t.modify k f).maxKey? = t.maxKey?.map fun km => if cmp km k = .eq then k else km :=
DTreeMap.Const.maxKey?_modify
@[simp, grind =]
theorem maxKey?_modify_eq_maxKey? [TransCmp cmp] [LawfulEqCmp cmp] {k f} :
(t.modify k f).maxKey? = t.maxKey? :=
DTreeMap.Const.maxKey?_modify_eq_maxKey?
theorem isSome_maxKey?_modify [TransCmp cmp] {k f} :
(t.modify k f).maxKey?.isSome = !t.isEmpty :=
DTreeMap.Const.isSome_maxKey?_modify
theorem isSome_maxKey?_modify_eq_isSome [TransCmp cmp] {k f} :
(t.modify k f).maxKey?.isSome = t.maxKey?.isSome :=
DTreeMap.Const.isSome_maxKey?_modify_eq_isSome
theorem compare_maxKey?_modify_eq [TransCmp cmp] {k f km kmm} :
(hkm : t.maxKey? = some km) →
(hkmm : (t.modify k f |>.maxKey? |>.get <|
isSome_maxKey?_modify_eq_isSome.trans <| hkm ▸ Option.isSome_some) = kmm) →
cmp kmm km = .eq :=
DTreeMap.Const.compare_maxKey?_modify_eq
theorem maxKey?_alter_eq_self [TransCmp cmp] {k f} :
(t.alter k f).maxKey? = some k ↔
(f t[k]?).isSome ∧ ∀ k', k' ∈ t → (cmp k' k).isLE :=
DTreeMap.Const.maxKey?_alter_eq_self
theorem maxKey_eq_get_maxKey? [TransCmp cmp] {he} :
t.maxKey he = t.maxKey?.get (isSome_maxKey?_iff_isEmpty_eq_false.mpr he) :=
DTreeMap.maxKey_eq_get_maxKey?
theorem maxKey?_eq_some_maxKey [TransCmp cmp] {he} :
t.maxKey? = some (t.maxKey he) :=
DTreeMap.maxKey?_eq_some_maxKey
theorem maxKey_eq_iff_getKey?_eq_self_and_forall [TransCmp cmp] {he km} :
t.maxKey he = km ↔ t.getKey? km = some km ∧ ∀ k ∈ t, (cmp k km).isLE :=
DTreeMap.maxKey_eq_iff_getKey?_eq_self_and_forall
theorem maxKey_eq_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] {he km} :
t.maxKey he = km ↔ km ∈ t ∧ ∀ k ∈ t, (cmp k km).isLE :=
DTreeMap.maxKey_eq_iff_mem_and_forall
@[grind =] theorem maxKey_insert [TransCmp cmp] {k v} :
(t.insert k v).maxKey isEmpty_insert =
t.maxKey?.elim k fun k' => if cmp k' k |>.isLE then k else k' :=
DTreeMap.maxKey_insert
theorem maxKey_le_maxKey_insert [TransCmp cmp] {k v he} :
cmp (t.maxKey he) (t.insert k v |>.maxKey isEmpty_insert) |>.isLE :=
DTreeMap.maxKey_le_maxKey_insert
theorem self_le_maxKey_insert [TransCmp cmp] {k v} :
cmp k (t.insert k v |>.maxKey isEmpty_insert) |>.isLE :=
DTreeMap.self_le_maxKey_insert
@[grind =] theorem contains_maxKey [TransCmp cmp] {he} :
t.contains (t.maxKey he) :=
DTreeMap.contains_maxKey
theorem maxKey_mem [TransCmp cmp] {he} :
t.maxKey he ∈ t :=
DTreeMap.maxKey_mem
grind_pattern maxKey_mem => t.maxKey he ∈ t
theorem le_maxKey_of_contains [TransCmp cmp] {k} (hc : t.contains k) :
cmp k (t.maxKey <| isEmpty_eq_false_iff_exists_contains_eq_true.mpr ⟨k, hc⟩) |>.isLE :=
DTreeMap.le_maxKey_of_contains hc
theorem le_maxKey_of_mem [TransCmp cmp] {k} (hc : k ∈ t) :
cmp k (t.maxKey <| isEmpty_eq_false_iff_exists_contains_eq_true.mpr ⟨k, hc⟩) |>.isLE :=
DTreeMap.le_maxKey_of_mem hc
theorem maxKey_le [TransCmp cmp] {k he} :
(cmp (t.maxKey he) k).isLE ↔ (∀ k', k' ∈ t → (cmp k' k).isLE) :=
DTreeMap.maxKey_le
@[simp, grind =]
theorem getKey?_maxKey [TransCmp cmp] {he} :
t.getKey? (t.maxKey he) = some (t.maxKey he) :=
DTreeMap.getKey?_maxKey
@[simp, grind =]
theorem getKey_maxKey [TransCmp cmp] {he hc} :
t.getKey (t.maxKey he) hc = t.maxKey he :=
DTreeMap.getKey_maxKey
@[simp, grind =]
theorem getKey!_maxKey [TransCmp cmp] [Inhabited α] {he} :
t.getKey! (t.maxKey he) = t.maxKey he :=
DTreeMap.getKey!_maxKey
@[simp, grind =]
theorem getKeyD_maxKey [TransCmp cmp] {he fallback} :
t.getKeyD (t.maxKey he) fallback = t.maxKey he :=
DTreeMap.getKeyD_maxKey
@[simp]
theorem maxKey_erase_eq_iff_not_compare_eq_maxKey [TransCmp cmp] {k he} :
(t.erase k |>.maxKey he) =
t.maxKey (isEmpty_eq_false_of_isEmpty_erase_eq_false he) ↔
¬ cmp k (t.maxKey <| isEmpty_eq_false_of_isEmpty_erase_eq_false he) = .eq :=
DTreeMap.maxKey_erase_eq_iff_not_compare_eq_maxKey
theorem maxKey_erase_eq_of_not_compare_eq_maxKey [TransCmp cmp] {k he} :
(hc : ¬ cmp k (t.maxKey (isEmpty_eq_false_of_isEmpty_erase_eq_false he)) = .eq) →
(t.erase k |>.maxKey he) =
t.maxKey (isEmpty_eq_false_of_isEmpty_erase_eq_false he) :=
DTreeMap.maxKey_erase_eq_of_not_compare_eq_maxKey
theorem maxKey_erase_le_maxKey [TransCmp cmp] {k he} :
cmp (t.erase k |>.maxKey he)
(t.maxKey <| isEmpty_eq_false_of_isEmpty_erase_eq_false he) |>.isLE :=
DTreeMap.maxKey_erase_le_maxKey
@[grind =] theorem maxKey_insertIfNew [TransCmp cmp] {k v} :
(t.insertIfNew k v).maxKey isEmpty_insertIfNew =
t.maxKey?.elim k fun k' => if cmp k' k = .lt then k else k' :=
DTreeMap.maxKey_insertIfNew
theorem maxKey_le_maxKey_insertIfNew [TransCmp cmp] {k v he} :
cmp (t.maxKey he)
(t.insertIfNew k v |>.maxKey isEmpty_insertIfNew) |>.isLE :=
DTreeMap.maxKey_le_maxKey_insertIfNew (t := t.inner) (he := he)
theorem self_le_maxKey_insertIfNew [TransCmp cmp] {k v} :
cmp k (t.insertIfNew k v |>.maxKey <| isEmpty_insertIfNew) |>.isLE :=
DTreeMap.self_le_maxKey_insertIfNew
@[grind =_] theorem maxKey_eq_getLast_keys [TransCmp cmp] {he} :
t.maxKey he = t.keys.getLast (List.isEmpty_eq_false_iff.mp <| isEmpty_keys ▸ he) :=
DTreeMap.maxKey_eq_getLast_keys
theorem maxKey_modify [TransCmp cmp] {k f he} :
(modify t k f).maxKey he =
if cmp (t.maxKey <| cast (congrArg (· = false) isEmpty_modify) he) k = .eq then
k
else
(t.maxKey <| cast (congrArg (· = false) isEmpty_modify) he) :=
DTreeMap.Const.maxKey_modify
@[simp, grind =]
theorem maxKey_modify_eq_maxKey [TransCmp cmp] [LawfulEqCmp cmp] {k f he} :
(modify t k f).maxKey he = t.maxKey (cast (congrArg (· = false) isEmpty_modify) he) :=
DTreeMap.Const.maxKey_modify_eq_maxKey
theorem compare_maxKey_modify_eq [TransCmp cmp] {k f he} :
cmp (modify t k f |>.maxKey he)
(t.maxKey <| cast (congrArg (· = false) isEmpty_modify) he) = .eq :=
DTreeMap.Const.compare_maxKey_modify_eq
@[simp]
theorem ordCompare_maxKey_modify_eq [Ord α] [TransOrd α] {t : TreeMap α β} {k f he} :
compare (modify t k f |>.maxKey he)
(t.maxKey <| cast (congrArg (· = false) isEmpty_modify) he) = .eq :=
compare_maxKey_modify_eq
theorem maxKey_alter_eq_self [TransCmp cmp] {k f he} :
(alter t k f).maxKey he = k ↔
(f t[k]?).isSome ∧ ∀ k', k' ∈ t → (cmp k' k).isLE :=
DTreeMap.Const.maxKey_alter_eq_self
theorem maxKey?_eq_some_maxKey! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.maxKey? = some t.maxKey! :=
DTreeMap.maxKey?_eq_some_maxKey! he
theorem maxKey_eq_maxKey! [TransCmp cmp] [Inhabited α] {he : t.isEmpty = false} :
t.maxKey he = t.maxKey! :=
DTreeMap.maxKey_eq_maxKey!
theorem maxKey!_eq_default [TransCmp cmp] [Inhabited α] (he : t.isEmpty) :
t.maxKey! = default :=
DTreeMap.maxKey!_eq_default he
theorem maxKey!_eq_iff_getKey?_eq_self_and_forall [TransCmp cmp] [Inhabited α]
(he : t.isEmpty = false) {km} :
t.maxKey! = km ↔ t.getKey? km = some km ∧ ∀ k, k ∈ t → (cmp k km).isLE :=
DTreeMap.maxKey!_eq_iff_getKey?_eq_self_and_forall he
theorem maxKey!_eq_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α]
(he : t.isEmpty = false) {km} :
t.maxKey! = km ↔ km ∈ t ∧ ∀ k, k ∈ t → (cmp k km).isLE :=
DTreeMap.maxKey!_eq_iff_mem_and_forall he
@[grind =]
theorem maxKey!_insert [TransCmp cmp] [Inhabited α] {k v} :
(t.insert k v).maxKey! =
(t.maxKey?.elim k fun k' => if cmp k' k |>.isLE then k else k') :=
DTreeMap.maxKey!_insert
theorem maxKey!_le_maxKey!_insert [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {k v} :
cmp t.maxKey! (t.insert k v).maxKey! |>.isLE :=
DTreeMap.maxKey!_le_maxKey!_insert he
theorem self_le_maxKey!_insert [TransCmp cmp] [Inhabited α] {k v} :
cmp k (t.insert k v).maxKey! |>.isLE :=
DTreeMap.self_le_maxKey!_insert
theorem contains_maxKey! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.contains t.maxKey! :=
DTreeMap.contains_maxKey! he
theorem maxKey!_mem [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.maxKey! ∈ t :=
DTreeMap.maxKey!_mem he
theorem le_maxKey!_of_contains [TransCmp cmp] [Inhabited α] {k} (hc : t.contains k) :
cmp k t.maxKey! |>.isLE :=
DTreeMap.le_maxKey!_of_contains hc
theorem le_maxKey!_of_mem [TransCmp cmp] [Inhabited α] {k} (hc : k ∈ t) :
cmp k t.maxKey! |>.isLE :=
DTreeMap.le_maxKey!_of_mem hc
theorem maxKey!_le [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {k} :
(cmp t.maxKey! k).isLE ↔ (∀ k', k' ∈ t → (cmp k' k).isLE) :=
DTreeMap.maxKey!_le he
theorem getKey?_maxKey! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.getKey? t.maxKey! = some t.maxKey! :=
DTreeMap.getKey?_maxKey! he
@[grind =] theorem getKey_maxKey! [TransCmp cmp] [Inhabited α] {hc} :
t.getKey t.maxKey! hc = t.maxKey! :=
DTreeMap.getKey_maxKey!
@[simp, grind =]
theorem getKey_maxKey!_eq_maxKey [TransCmp cmp] [Inhabited α] {hc} :
t.getKey t.maxKey! hc = t.maxKey (isEmpty_eq_false_of_contains hc) :=
DTreeMap.getKey_maxKey!_eq_maxKey
theorem getKey!_maxKey! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.getKey! t.maxKey! = t.maxKey! :=
DTreeMap.getKey!_maxKey! he
theorem getKeyD_maxKey! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {fallback} :
t.getKeyD t.maxKey! fallback = t.maxKey! :=
DTreeMap.getKeyD_maxKey! he
theorem maxKey!_erase_eq_of_not_compare_maxKey!_eq [TransCmp cmp] [Inhabited α] {k}
(he : (t.erase k).isEmpty = false) (heq : ¬ cmp k t.maxKey! = .eq) :
(t.erase k).maxKey! = t.maxKey! :=
DTreeMap.maxKey!_erase_eq_of_not_compare_maxKey!_eq he heq
theorem maxKey!_erase_le_maxKey! [TransCmp cmp] [Inhabited α] {k}
(he : (t.erase k).isEmpty = false) :
cmp (t.erase k).maxKey! t.maxKey! |>.isLE :=
DTreeMap.maxKey!_erase_le_maxKey! he
@[grind =]
theorem maxKey!_insertIfNew [TransCmp cmp] [Inhabited α] {k v} :
(t.insertIfNew k v).maxKey! =
t.maxKey?.elim k fun k' => if cmp k' k = .lt then k else k' :=
DTreeMap.maxKey!_insertIfNew
theorem maxKey!_le_maxKey!_insertIfNew [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {k v} :
cmp t.maxKey! (t.insertIfNew k v).maxKey! |>.isLE :=
DTreeMap.maxKey!_le_maxKey!_insertIfNew he
theorem self_le_maxKey!_insertIfNew [TransCmp cmp] [Inhabited α] {k v} :
cmp k (t.insertIfNew k v).maxKey! |>.isLE :=
DTreeMap.self_le_maxKey!_insertIfNew
@[grind =_]
theorem maxKey!_eq_getLast!_keys [TransCmp cmp] [Inhabited α] :
t.maxKey! = t.keys.getLast! :=
DTreeMap.maxKey!_eq_getLast!_keys
theorem maxKey!_modify [TransCmp cmp] [Inhabited α] {k f}
(he : (modify t k f).isEmpty = false) :
(modify t k f).maxKey! = if cmp t.maxKey! k = .eq then k else t.maxKey! :=
DTreeMap.Const.maxKey!_modify he
@[simp]
theorem maxKey!_modify_eq_maxKey! [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] {k f} :
(modify t k f).maxKey! = t.maxKey! :=
DTreeMap.Const.maxKey!_modify_eq_maxKey!
theorem compare_maxKey!_modify_eq [TransCmp cmp] [Inhabited α] {k f} :
cmp (modify t k f).maxKey! t.maxKey! = .eq :=
DTreeMap.Const.compare_maxKey!_modify_eq
@[simp]
theorem ordCompare_maxKey!_modify_eq [Ord α] [TransOrd α] {t : TreeMap α β} [Inhabited α] {k f} :
compare (modify t k f).maxKey! t.maxKey! = .eq :=
compare_maxKey!_modify_eq
theorem maxKey!_alter_eq_self [TransCmp cmp] [Inhabited α] {k f}
(he : (alter t k f).isEmpty = false) :
(alter t k f).maxKey! = k ↔
(f t[k]?).isSome ∧ ∀ k', k' ∈ t → (cmp k' k).isLE :=
DTreeMap.Const.maxKey!_alter_eq_self he
theorem maxKey?_eq_some_maxKeyD [TransCmp cmp] (he : t.isEmpty = false) {fallback} :
t.maxKey? = some (t.maxKeyD fallback) :=
DTreeMap.maxKey?_eq_some_maxKeyD he
theorem maxKeyD_eq_fallback [TransCmp cmp] (he : t.isEmpty) {fallback} :
t.maxKeyD fallback = fallback :=
DTreeMap.maxKeyD_eq_fallback he
theorem maxKey!_eq_maxKeyD_default [TransCmp cmp] [Inhabited α] :
t.maxKey! = t.maxKeyD default :=
DTreeMap.maxKey!_eq_maxKeyD_default
theorem maxKeyD_eq_iff_getKey?_eq_self_and_forall [TransCmp cmp]
(he : t.isEmpty = false) {km fallback} :
t.maxKeyD fallback = km ↔ t.getKey? km = some km ∧ ∀ k, k ∈ t → (cmp k km).isLE :=
DTreeMap.maxKeyD_eq_iff_getKey?_eq_self_and_forall he
theorem maxKeyD_eq_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp]
(he : t.isEmpty = false) {km fallback} :
t.maxKeyD fallback = km ↔ km ∈ t ∧ ∀ k, k ∈ t → (cmp k km).isLE :=
DTreeMap.maxKeyD_eq_iff_mem_and_forall he
@[grind =]
theorem maxKeyD_insert [TransCmp cmp] {k v fallback} :
(t.insert k v |>.maxKeyD fallback) =
(t.maxKey?.elim k fun k' => if cmp k' k |>.isLE then k else k') :=
DTreeMap.maxKeyD_insert
theorem maxKeyD_le_maxKeyD_insert [TransCmp cmp] (he : t.isEmpty = false)
{k v fallback} :
cmp (t.maxKeyD fallback) (t.insert k v |>.maxKeyD fallback) |>.isLE :=
DTreeMap.maxKeyD_le_maxKeyD_insert he
theorem self_le_maxKeyD_insert [TransCmp cmp] {k v fallback} :
cmp k (t.insert k v |>.maxKeyD fallback) |>.isLE :=
DTreeMap.self_le_maxKeyD_insert
theorem contains_maxKeyD [TransCmp cmp] (he : t.isEmpty = false) {fallback} :
t.contains (t.maxKeyD fallback) :=
DTreeMap.contains_maxKeyD he
theorem maxKeyD_mem [TransCmp cmp] (he : t.isEmpty = false) {fallback} :
t.maxKeyD fallback ∈ t :=
DTreeMap.maxKeyD_mem he
theorem le_maxKeyD_of_contains [TransCmp cmp] {k} (hc : t.contains k) {fallback} :
cmp k (t.maxKeyD fallback) |>.isLE :=
DTreeMap.le_maxKeyD_of_contains hc
theorem le_maxKeyD_of_mem [TransCmp cmp] {k} (hc : k ∈ t) {fallback} :
cmp k (t.maxKeyD fallback) |>.isLE :=
DTreeMap.le_maxKeyD_of_mem hc
theorem maxKeyD_le [TransCmp cmp] (he : t.isEmpty = false) {k fallback} :
(cmp (t.maxKeyD fallback) k).isLE ↔ (∀ k', k' ∈ t → (cmp k' k).isLE) :=
DTreeMap.maxKeyD_le he
theorem getKey?_maxKeyD [TransCmp cmp] (he : t.isEmpty = false) {fallback} :
t.getKey? (t.maxKeyD fallback) = some (t.maxKeyD fallback) :=
DTreeMap.getKey?_maxKeyD he
@[grind =] theorem getKey_maxKeyD [TransCmp cmp] {fallback hc} :
t.getKey (t.maxKeyD fallback) hc = t.maxKeyD fallback :=
DTreeMap.getKey_maxKeyD
theorem getKey!_maxKeyD [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {fallback} :
t.getKey! (t.maxKeyD fallback) = t.maxKeyD fallback :=
DTreeMap.getKey!_maxKeyD he
theorem getKeyD_maxKeyD [TransCmp cmp] (he : t.isEmpty = false) {fallback fallback'} :
t.getKeyD (t.maxKeyD fallback) fallback' = t.maxKeyD fallback :=
DTreeMap.getKeyD_maxKeyD he
theorem maxKeyD_erase_eq_of_not_compare_maxKeyD_eq [TransCmp cmp] {k fallback}
(he : (t.erase k).isEmpty = false) (heq : ¬ cmp k (t.maxKeyD fallback) = .eq) :
(t.erase k |>.maxKeyD fallback) = t.maxKeyD fallback :=
DTreeMap.maxKeyD_erase_eq_of_not_compare_maxKeyD_eq he heq
theorem maxKeyD_erase_le_maxKeyD [TransCmp cmp] {k}
(he : (t.erase k).isEmpty = false) {fallback} :
cmp (t.erase k |>.maxKeyD fallback) (t.maxKeyD fallback) |>.isLE :=
DTreeMap.maxKeyD_erase_le_maxKeyD he
@[grind =]
theorem maxKeyD_insertIfNew [TransCmp cmp] {k v fallback} :
(t.insertIfNew k v |>.maxKeyD fallback) =
t.maxKey?.elim k fun k' => if cmp k' k = .lt then k else k' :=
DTreeMap.maxKeyD_insertIfNew
theorem maxKeyD_le_maxKeyD_insertIfNew [TransCmp cmp]
(he : t.isEmpty = false) {k v fallback} :
cmp (t.maxKeyD fallback) (t.insertIfNew k v |>.maxKeyD fallback) |>.isLE :=
DTreeMap.maxKeyD_le_maxKeyD_insertIfNew he
theorem self_le_maxKeyD_insertIfNew [TransCmp cmp] {k v fallback} :
cmp k (t.insertIfNew k v |>.maxKeyD fallback) |>.isLE :=
DTreeMap.self_le_maxKeyD_insertIfNew
theorem maxKeyD_eq_getLastD_keys [TransCmp cmp] {fallback} :
t.maxKeyD fallback = t.keys.getLastD fallback :=
DTreeMap.maxKeyD_eq_getLastD_keys
theorem maxKeyD_modify [TransCmp cmp] {k f}
(he : (modify t k f).isEmpty = false) {fallback} :
(modify t k f |>.maxKeyD fallback) =
if cmp (t.maxKeyD fallback) k = .eq then k else (t.maxKeyD fallback) :=
DTreeMap.Const.maxKeyD_modify he
@[simp, grind =]
theorem maxKeyD_modify_eq_maxKeyD [TransCmp cmp] [LawfulEqCmp cmp] {k f fallback} :
(modify t k f |>.maxKeyD fallback) = t.maxKeyD fallback :=
DTreeMap.Const.maxKeyD_modify_eq_maxKeyD
theorem compare_maxKeyD_modify_eq [TransCmp cmp] {k f fallback} :
cmp (modify t k f |>.maxKeyD fallback) (t.maxKeyD fallback) = .eq :=
DTreeMap.Const.compare_maxKeyD_modify_eq
@[simp]
theorem ordCompare_maxKeyD_modify_eq [Ord α] [TransOrd α] {t : TreeMap α β} {k f fallback} :
compare (modify t k f |>.maxKeyD fallback) (t.maxKeyD fallback) = .eq :=
compare_maxKeyD_modify_eq
theorem maxKeyD_alter_eq_self [TransCmp cmp] {k f}
(he : (alter t k f).isEmpty = false) {fallback} :
(alter t k f |>.maxKeyD fallback) = k ↔
(f t[k]?).isSome ∧ ∀ k', k' ∈ t → (cmp k' k).isLE :=
DTreeMap.Const.maxKeyD_alter_eq_self he
end Max
namespace Equiv
variable {t₁ t₂ t₃ t₄ : TreeMap α β cmp} {δ : Type w} {m : Type w → Type w'}
@[refl, simp] theorem rfl : Equiv t t := ⟨.rfl⟩
@[symm] theorem symm : Equiv t₁ t₂ → Equiv t₂ t₁
| ⟨h⟩ => ⟨h.symm⟩
theorem trans : Equiv t₁ t₂ → Equiv t₂ t₃ → Equiv t₁ t₃
| ⟨h⟩, ⟨h'⟩ => ⟨h.trans h'⟩
instance instTrans : @Trans (TreeMap α β cmp) _ _ Equiv Equiv Equiv := ⟨trans⟩
theorem comm : t₁ ~m t₂ ↔ t₂ ~m t₁ := ⟨symm, symm⟩
theorem congr_left (h : t₁ ~m t₂) : t₁ ~m t₃ ↔ t₂ ~m t₃ := ⟨h.symm.trans, h.trans⟩
theorem congr_right (h : t₁ ~m t₂) : t₃ ~m t₁ ↔ t₃ ~m t₂ :=
⟨fun h' => h'.trans h, fun h' => h'.trans h.symm⟩
-- congruence lemmas
theorem isEmpty_eq (h : t₁ ~m t₂) : t₁.isEmpty = t₂.isEmpty :=
h.1.isEmpty_eq
theorem contains_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
t₁.contains k = t₂.contains k :=
h.1.contains_eq
theorem mem_iff [TransCmp cmp] (h : t₁ ~m t₂) {k : α} :
k ∈ t₁ ↔ k ∈ t₂ :=
h.1.mem_iff
theorem size_eq (h : t₁ ~m t₂) : t₁.size = t₂.size :=
h.1.size_eq
theorem getElem?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) : t₁[k]? = t₂[k]? :=
h.1.constGet?_eq
theorem getElem_eq [TransCmp cmp] {k : α} {hk : k ∈ t₁} (h : t₁ ~m t₂) :
t₁[k] = t₂[k]'(h.mem_iff.mp hk) :=
h.1.constGet_eq
theorem getElem!_eq [TransCmp cmp] [Inhabited β] {k : α} (h : t₁ ~m t₂) :
t₁[k]! = t₂[k]! :=
h.1.constGet!_eq
theorem getD_eq [TransCmp cmp] {k : α} {fallback : β} (h : t₁ ~m t₂) :
t₁.getD k fallback = t₂.getD k fallback :=
h.1.constGetD_eq
theorem getKey?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
t₁.getKey? k = t₂.getKey? k :=
h.1.getKey?_eq
theorem getKey_eq [TransCmp cmp] {k : α} {hk : k ∈ t₁} (h : t₁ ~m t₂) :
t₁.getKey k hk = t₂.getKey k (h.mem_iff.mp hk) :=
h.1.getKey_eq
theorem getKey!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
t₁.getKey! k = t₂.getKey! k :=
h.1.getKey!_eq
theorem getKeyD_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
t₁.getKeyD k fallback = t₂.getKeyD k fallback :=
h.1.getKeyD_eq
theorem toList_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.toList = t₂.toList :=
h.1.constToList_eq
theorem toArray_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.toArray = t₂.toArray :=
h.1.constToArray_eq
theorem keys_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.keys = t₂.keys :=
h.1.keys_eq
theorem keysArray_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.keysArray = t₂.keysArray :=
h.1.keysArray_eq
theorem foldlM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : δ → α → β → m δ} {init : δ}
(h : t₁ ~m t₂) :
t₁.foldlM f init = t₂.foldlM f init :=
h.1.foldlM_eq
theorem foldl_eq [TransCmp cmp] {f : δ → α → β → δ} {init : δ} (h : t₁ ~m t₂) :
t₁.foldl f init = t₂.foldl f init :=
h.1.foldl_eq
theorem foldrM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : α → β → δ → m δ} {init : δ}
(h : t₁ ~m t₂) :
t₁.foldrM f init = t₂.foldrM f init :=
h.1.foldrM_eq
theorem foldr_eq [TransCmp cmp] {f : α → β → δ → δ} {init : δ} (h : t₁ ~m t₂) :
t₁.foldr f init = t₂.foldr f init :=
h.1.foldr_eq
theorem forIn_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {b : δ} {f : α × β → δ → m (ForInStep δ)}
(h : t₁ ~m t₂) : ForIn.forIn t₁ b f = ForIn.forIn t₂ b f :=
h.1.forIn_eq (f := fun ⟨a, b⟩ => f ⟨a, b⟩)
theorem forM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : α × β → m PUnit} (h : t₁ ~m t₂) :
ForM.forM t₁ f = ForM.forM t₂ f :=
h.1.forM_eq (f := fun x : (_ : α) × β => f (x.1, x.2))
theorem any_eq [TransCmp cmp] {p : α → β → Bool} (h : t₁ ~m t₂) : t₁.any p = t₂.any p :=
h.1.any_eq
theorem all_eq [TransCmp cmp] {p : α → β → Bool} (h : t₁ ~m t₂) : t₁.all p = t₂.all p :=
h.1.all_eq
theorem minKey?_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.minKey? = t₂.minKey? :=
h.1.minKey?_eq
theorem minKey_eq [TransCmp cmp] {h' : t₁.isEmpty = false} (h : t₁ ~m t₂) :
t₁.minKey h' = t₂.minKey (h.isEmpty_eq.symm.trans h') :=
h.1.minKey_eq
theorem minKey!_eq [TransCmp cmp] [Inhabited α] (h : t₁ ~m t₂) :
t₁.minKey! = t₂.minKey! :=
h.1.minKey!_eq
theorem minKeyD_eq [TransCmp cmp] {fallback : α} (h : t₁ ~m t₂) :
t₁.minKeyD fallback = t₂.minKeyD fallback :=
h.1.minKeyD_eq
theorem maxKey?_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.maxKey? = t₂.maxKey? :=
h.1.maxKey?_eq
theorem maxKey_eq [TransCmp cmp] {h' : t₁.isEmpty = false} (h : t₁ ~m t₂) :
t₁.maxKey h' = t₂.maxKey (h.isEmpty_eq.symm.trans h') :=
h.1.maxKey_eq
theorem maxKey!_eq [TransCmp cmp] [Inhabited α] (h : t₁ ~m t₂) :
t₁.maxKey! = t₂.maxKey! :=
h.1.maxKey!_eq
theorem maxKeyD_eq [TransCmp cmp] {fallback : α} (h : t₁ ~m t₂) :
t₁.maxKeyD fallback = t₂.maxKeyD fallback :=
h.1.maxKeyD_eq
theorem minEntry?_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.minEntry? = t₂.minEntry? :=
h.1.constMinEntry?_eq
theorem minEntry_eq [TransCmp cmp] {he : t₁.isEmpty = false} (h : t₁ ~m t₂) :
t₁.minEntry he = t₂.minEntry (h.isEmpty_eq.symm.trans he) :=
h.1.constMinEntry_eq
theorem minEntry!_eq [TransCmp cmp] [Inhabited (α × β)] (h : t₁ ~m t₂) :
t₁.minEntry! = t₂.minEntry! :=
h.1.constMinEntry!_eq
theorem minEntryD_eq [TransCmp cmp] {fallback : α × β} (h : t₁ ~m t₂) :
t₁.minEntryD fallback = t₂.minEntryD fallback :=
h.1.constMinEntryD_eq
theorem maxEntry?_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.maxEntry? = t₂.maxEntry? :=
h.1.constMaxEntry?_eq
theorem maxEntry_eq [TransCmp cmp] {he : t₁.isEmpty = false} (h : t₁ ~m t₂) :
t₁.maxEntry he = t₂.maxEntry (h.isEmpty_eq.symm.trans he) :=
h.1.constMaxEntry_eq
theorem maxEntry!_eq [TransCmp cmp] [Inhabited (α × β)] (h : t₁ ~m t₂) :
t₁.maxEntry! = t₂.maxEntry! :=
h.1.constMaxEntry!_eq
theorem maxEntryD_eq [TransCmp cmp] {fallback : α × β} (h : t₁ ~m t₂) :
t₁.maxEntryD fallback = t₂.maxEntryD fallback :=
h.1.constMaxEntryD_eq
theorem entryAtIdx?_eq [TransCmp cmp] {i : Nat} (h : t₁ ~m t₂) :
t₁.entryAtIdx? i = t₂.entryAtIdx? i :=
h.1.constEntryAtIdx?_eq
theorem entryAtIdx_eq [TransCmp cmp] {i : Nat} {h' : i < t₁.size} (h : t₁ ~m t₂) :
t₁.entryAtIdx i h' = t₂.entryAtIdx i (h.size_eq ▸ h') :=
h.1.constEntryAtIdx_eq
theorem entryAtIdx!_eq [TransCmp cmp] [Inhabited (α × β)] {i : Nat} (h : t₁ ~m t₂) :
t₁.entryAtIdx! i = t₂.entryAtIdx! i :=
h.1.constEntryAtIdx!_eq
theorem entryAtIdxD_eq [TransCmp cmp] {i : Nat} {fallback : α × β} (h : t₁ ~m t₂) :
t₁.entryAtIdxD i fallback = t₂.entryAtIdxD i fallback :=
h.1.constEntryAtIdxD_eq
theorem keyAtIdx?_eq [TransCmp cmp] {i : Nat} (h : t₁ ~m t₂) :
t₁.keyAtIdx? i = t₂.keyAtIdx? i :=
h.1.keyAtIdx?_eq
theorem keyAtIdx_eq [TransCmp cmp] {i : Nat} {h' : i < t₁.size} (h : t₁ ~m t₂) :
t₁.keyAtIdx i h' = t₂.keyAtIdx i (h.size_eq ▸ h') :=
h.1.keyAtIdx_eq
theorem keyAtIdx!_eq [TransCmp cmp] [Inhabited α] {i : Nat} (h : t₁ ~m t₂) :
t₁.keyAtIdx! i = t₂.keyAtIdx! i :=
h.1.keyAtIdx!_eq
theorem keyAtIdxD_eq [TransCmp cmp] {i : Nat} {fallback : α} (h : t₁ ~m t₂) :
t₁.keyAtIdxD i fallback = t₂.keyAtIdxD i fallback :=
h.1.keyAtIdxD_eq
theorem getEntryGE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
t₁.getEntryGE? k = t₂.getEntryGE? k :=
h.1.constGetEntryGE?_eq
theorem getEntryGE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
t₁.getEntryGE k h' = t₂.getEntryGE k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
h.1.constGetEntryGE_eq
theorem getEntryGE!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h : t₁ ~m t₂) :
t₁.getEntryGE! k = t₂.getEntryGE! k :=
h.1.constGetEntryGE!_eq
theorem getEntryGED_eq [TransCmp cmp] {k : α} {fallback : α × β} (h : t₁ ~m t₂) :
t₁.getEntryGED k fallback = t₂.getEntryGED k fallback :=
h.1.constGetEntryGED_eq
theorem getEntryGT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
t₁.getEntryGT? k = t₂.getEntryGT? k :=
h.1.constGetEntryGT?_eq
theorem getEntryGT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
t₁.getEntryGT k h' = t₂.getEntryGT k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
h.1.constGetEntryGT_eq
theorem getEntryGT!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h : t₁ ~m t₂) :
t₁.getEntryGT! k = t₂.getEntryGT! k :=
h.1.constGetEntryGT!_eq
theorem getEntryGTD_eq [TransCmp cmp] {k : α} {fallback : α × β} (h : t₁ ~m t₂) :
t₁.getEntryGTD k fallback = t₂.getEntryGTD k fallback :=
h.1.constGetEntryGTD_eq
theorem getEntryLE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
t₁.getEntryLE? k = t₂.getEntryLE? k :=
h.1.constGetEntryLE?_eq
theorem getEntryLE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
t₁.getEntryLE k h' = t₂.getEntryLE k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
h.1.constGetEntryLE_eq
theorem getEntryLE!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h : t₁ ~m t₂) :
t₁.getEntryLE! k = t₂.getEntryLE! k :=
h.1.constGetEntryLE!_eq
theorem getEntryLED_eq [TransCmp cmp] {k : α} {fallback : α × β} (h : t₁ ~m t₂) :
t₁.getEntryLED k fallback = t₂.getEntryLED k fallback :=
h.1.constGetEntryLED_eq
theorem getEntryLT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
t₁.getEntryLT? k = t₂.getEntryLT? k :=
h.1.constGetEntryLT?_eq
theorem getEntryLT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
t₁.getEntryLT k h' = t₂.getEntryLT k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
h.1.constGetEntryLT_eq
theorem getEntryLT!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h : t₁ ~m t₂) :
t₁.getEntryLT! k = t₂.getEntryLT! k :=
h.1.constGetEntryLT!_eq
theorem getEntryLTD_eq [TransCmp cmp] {k : α} {fallback : α × β} (h : t₁ ~m t₂) :
t₁.getEntryLTD k fallback = t₂.getEntryLTD k fallback :=
h.1.constGetEntryLTD_eq
theorem getKeyGE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
t₁.getKeyGE? k = t₂.getKeyGE? k :=
h.1.getKeyGE?_eq
theorem getKeyGE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
t₁.getKeyGE k h' = t₂.getKeyGE k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
h.1.getKeyGE_eq
theorem getKeyGE!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
t₁.getKeyGE! k = t₂.getKeyGE! k :=
h.1.getKeyGE!_eq
theorem getKeyGED_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
t₁.getKeyGED k fallback = t₂.getKeyGED k fallback :=
h.1.getKeyGED_eq
theorem getKeyGT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
t₁.getKeyGT? k = t₂.getKeyGT? k :=
h.1.getKeyGT?_eq
theorem getKeyGT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
t₁.getKeyGT k h' = t₂.getKeyGT k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
h.1.getKeyGT_eq
theorem getKeyGT!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
t₁.getKeyGT! k = t₂.getKeyGT! k :=
h.1.getKeyGT!_eq
theorem getKeyGTD_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
t₁.getKeyGTD k fallback = t₂.getKeyGTD k fallback :=
h.1.getKeyGTD_eq
theorem getKeyLE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
t₁.getKeyLE? k = t₂.getKeyLE? k :=
h.1.getKeyLE?_eq
theorem getKeyLE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
t₁.getKeyLE k h' = t₂.getKeyLE k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
h.1.getKeyLE_eq
theorem getKeyLE!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
t₁.getKeyLE! k = t₂.getKeyLE! k :=
h.1.getKeyLE!_eq
theorem getKeyLED_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
t₁.getKeyLED k fallback = t₂.getKeyLED k fallback :=
h.1.getKeyLED_eq
theorem getKeyLT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
t₁.getKeyLT? k = t₂.getKeyLT? k :=
h.1.getKeyLT?_eq
theorem getKeyLT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
t₁.getKeyLT k h' = t₂.getKeyLT k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
h.1.getKeyLT_eq
theorem getKeyLT!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
t₁.getKeyLT! k = t₂.getKeyLT! k :=
h.1.getKeyLT!_eq
theorem getKeyLTD_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
t₁.getKeyLTD k fallback = t₂.getKeyLTD k fallback :=
h.1.getKeyLTD_eq
theorem insert [TransCmp cmp] (h : t₁ ~m t₂) (k : α) (v : β) : t₁.insert k v ~m t₂.insert k v :=
⟨h.1.insert k v⟩
theorem erase [TransCmp cmp] (h : t₁ ~m t₂) (k : α) : t₁.erase k ~m t₂.erase k :=
⟨h.1.erase k⟩
theorem insertIfNew [TransCmp cmp] (h : t₁ ~m t₂) (k : α) (v : β) :
t₁.insertIfNew k v ~m t₂.insertIfNew k v :=
⟨h.1.insertIfNew k v⟩
theorem alter [TransCmp cmp] [LawfulEqCmp cmp] (h : t₁ ~m t₂)
(k : α) (f : Option β → Option β) : t₁.alter k f ~m t₂.alter k f :=
⟨h.1.constAlter k f⟩
theorem modify [TransCmp cmp] [LawfulEqCmp cmp] (h : t₁ ~m t₂)
(k : α) (f : β → β) : t₁.modify k f ~m t₂.modify k f :=
⟨h.1.constModify k f⟩
theorem filter (h : t₁ ~m t₂) (f : α → β → Bool) : t₁.filter f ~m t₂.filter f :=
⟨h.1.filter f⟩
theorem map (h : t₁ ~m t₂) (f : α → β → γ) : t₁.map f ~m t₂.map f :=
⟨h.1.map f⟩
theorem filterMap (h : t₁ ~m t₂) (f : α → β → Option γ) : t₁.filterMap f ~m t₂.filterMap f :=
⟨h.1.filterMap f⟩
theorem insertMany_list [TransCmp cmp] (h : t₁ ~m t₂) (l : List (α × β)) :
t₁.insertMany l ~m t₂.insertMany l :=
⟨h.1.constInsertMany_list l⟩
theorem insertManyIfNewUnit_list [TransCmp cmp] {t₁ t₂ : TreeMap α Unit cmp}
(h : t₁ ~m t₂) (l : List α) :
t₁.insertManyIfNewUnit l ~m t₂.insertManyIfNewUnit l :=
⟨h.1.constInsertManyIfNewUnit_list l⟩
theorem eraseMany_list [TransCmp cmp] (h : t₁ ~m t₂) (l : List α) :
t₁.eraseMany l ~m t₂.eraseMany l :=
⟨h.1.eraseMany_list l⟩
theorem mergeWith [TransCmp cmp] [LawfulEqCmp cmp] (f : α → β → β → β)
(h : t₁ ~m t₂) (h' : t₃ ~m t₄) : t₁.mergeWith f t₃ ~m t₂.mergeWith f t₄ :=
⟨h.1.constMergeWith f h'.1⟩
theorem values_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.values = t₂.values :=
h.1.values_eq
theorem valuesArray_eq [TransCmp cmp] (h : t₁ ~m t₂) :
t₁.valuesArray = t₂.valuesArray :=
h.1.valuesArray_eq
-- extensionalities
theorem of_forall_getKey_eq_of_forall_constGet?_eq [TransCmp cmp]
(hk : ∀ k hk hk', t₁.getKey k hk = t₂.getKey k hk')
(hv : ∀ k : α, t₁[k]? = t₂[k]?) : t₁ ~m t₂ :=
⟨.of_forall_getKey_eq_of_forall_constGet?_eq hk hv⟩
theorem of_forall_constGet?_eq [TransCmp cmp] [LawfulEqCmp cmp]
(h : ∀ k : α, t₁[k]? = t₂[k]?) : t₁ ~m t₂ :=
⟨.of_forall_constGet?_eq h⟩
theorem of_forall_getKey?_unit_eq [TransCmp cmp] {t₁ t₂ : TreeMap α Unit cmp}
(h : ∀ k, t₁.getKey? k = t₂.getKey? k) : t₁ ~m t₂ :=
⟨.of_forall_getKey?_unit_eq h⟩
theorem of_forall_contains_unit_eq [TransCmp cmp] [LawfulEqCmp cmp] {t₁ t₂ : TreeMap α Unit cmp}
(h : ∀ k, t₁.contains k = t₂.contains k) : t₁ ~m t₂ :=
⟨.of_forall_contains_unit_eq h⟩
theorem of_forall_mem_unit_iff [TransCmp cmp] [LawfulEqCmp cmp] {t₁ t₂ : TreeMap α Unit cmp}
(h : ∀ k, k ∈ t₁ ↔ k ∈ t₂) : t₁ ~m t₂ :=
⟨.of_forall_mem_unit_iff h⟩
end Equiv
section Equiv
variable {t₁ t₂ : TreeMap α β cmp}
private theorem equiv_iff_equiv : t₁ ~m t₂ ↔ t₁.1.Equiv t₂.1 :=
⟨fun ⟨h⟩ => h, fun h => ⟨h⟩⟩
theorem equiv_empty_iff_isEmpty : t ~m empty ↔ t.isEmpty :=
equiv_iff_equiv.trans DTreeMap.equiv_empty_iff_isEmpty
theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
Equiv.comm.trans equiv_empty_iff_isEmpty
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList :=
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_toList_perm
theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ :=
⟨.of_constToList_perm h⟩
theorem equiv_iff_toList_eq [TransCmp cmp] :
t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_toList_eq
theorem equiv_iff_keys_unit_perm {t₁ t₂ : TreeMap α Unit cmp} :
t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys :=
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_keys_unit_perm
theorem equiv_iff_keys_unit_eq [TransCmp cmp] {t₁ t₂ : TreeMap α Unit cmp} :
t₁ ~m t₂ ↔ t₁.keys = t₂.keys :=
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_keys_unit_eq
theorem Equiv.of_keys_unit_perm {t₁ t₂ : TreeMap α Unit cmp} : t₁.keys.Perm t₂.keys → t₁ ~m t₂ :=
equiv_iff_keys_unit_perm.mpr
end Equiv
section filterMap
variable {t : TreeMap α β cmp}
@[simp, grind =]
theorem toList_filterMap {f : (a : α) → β → Option γ} :
(t.filterMap f).toList =
t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x))) :=
DTreeMap.Const.toList_filterMap
@[grind =]
theorem isEmpty_filterMap_iff [TransCmp cmp]
{f : α → β → Option γ} :
(t.filterMap f).isEmpty ↔ ∀ k h, f (t.getKey k h) t[k] = none :=
DTreeMap.Const.isEmpty_filterMap_iff
theorem isEmpty_filterMap_eq_false_iff [TransCmp cmp]
{f : α → β → Option γ} :
(t.filterMap f).isEmpty = false ↔ ∃ k h, (f (t.getKey k h) t[k]).isSome :=
DTreeMap.Const.isEmpty_filterMap_eq_false_iff
-- TODO: `contains_filterMap` is missing
@[grind =]
theorem mem_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} :
k ∈ t.filterMap f ↔ ∃ h, (f (t.getKey k h) t[k]).isSome :=
DTreeMap.Const.mem_filterMap
theorem contains_of_contains_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} :
(t.filterMap f).contains k = true → t.contains k = true :=
DTreeMap.contains_of_contains_filterMap
theorem mem_of_mem_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} :
k ∈ t.filterMap f → k ∈ t :=
DTreeMap.mem_of_mem_filterMap
theorem size_filterMap_le_size [TransCmp cmp]
{f : α → β → Option γ} :
(t.filterMap f).size ≤ t.size :=
DTreeMap.size_filterMap_le_size
grind_pattern size_filterMap_le_size => (t.filterMap f).size
theorem size_filterMap_eq_size_iff [TransCmp cmp]
{f : α → β → Option γ} :
(t.filterMap f).size = t.size ↔ ∀ k h, (f (t.getKey k h) t[k]).isSome :=
DTreeMap.Const.size_filterMap_eq_size_iff
@[simp]
theorem getElem?_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} :
(t.filterMap f)[k]? = t[k]?.pbind (fun x h' =>
f (t.getKey k (mem_iff_isSome_getElem?.mpr (Option.isSome_of_eq_some h'))) x) :=
DTreeMap.Const.get?_filterMap
/-- Simpler variant of `getElem?_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getElem?_filterMap' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Option γ} {k : α} :
(t.filterMap f)[k]? = t[k]?.bind fun x => f k x := by
simp [getElem?_filterMap]
theorem getElem?_filterMap_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Option γ} {k k' : α} (h : t.getKey? k = some k') :
(t.filterMap f)[k]? = t[k]?.bind (f k') :=
DTreeMap.Const.get?_filterMap_of_getKey?_eq_some h
theorem isSome_apply_of_mem_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} :
∀ (h : k ∈ t.filterMap f),
(f (t.getKey k (mem_of_mem_filterMap h))
(t[k]'(mem_of_mem_filterMap h))).isSome :=
DTreeMap.Const.isSome_apply_of_mem_filterMap
@[simp]
theorem getElem_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} {h} :
(t.filterMap f)[k]'h =
(f (t.getKey k (mem_of_mem_filterMap h))
(t[k]'(mem_of_mem_filterMap h))).get
(isSome_apply_of_mem_filterMap h) :=
DTreeMap.Const.get_filterMap
/-- Simpler variant of `getElem_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getElem_filterMap' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Option γ} {k : α} {h} :
(t.filterMap f)[k]'h =
(f k (t[k]'(mem_of_mem_filterMap h))).get (by simpa using isSome_apply_of_mem_filterMap h) := by
simp [getElem_filterMap]
theorem getElem!_filterMap [TransCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k : α} :
(t.filterMap f)[k]! =
(t[k]?.pbind (fun x h' =>
f (t.getKey k (mem_iff_isSome_getElem?.mpr (Option.isSome_of_eq_some h'))) x)).get! :=
DTreeMap.Const.get!_filterMap
/-- Simpler variant of `getElem!_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getElem!_filterMap' [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k : α} :
(t.filterMap f)[k]! = (t[k]?.bind (f k)).get! := by
simp [getElem!_filterMap]
theorem getElem!_filterMap_of_getKey?_eq_some [TransCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k k' : α} (h : t.getKey? k = some k') :
(t.filterMap f)[k]! = (t[k]?.bind (f k')).get! :=
DTreeMap.Const.get!_filterMap_of_getKey?_eq_some h
theorem getD_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} {fallback : γ} :
(t.filterMap f).getD k fallback =
(t[k]?.pbind (fun x h' =>
f (t.getKey k (mem_iff_isSome_getElem?.mpr (Option.isSome_of_eq_some h'))) x)).getD fallback :=
DTreeMap.Const.getD_filterMap
/-- Simpler variant of `getD_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getD_filterMap' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Option γ} {k : α} {fallback : γ} :
(t.filterMap f).getD k fallback = (t[k]?.bind (f k)).getD fallback := by
simp [getD_filterMap]
theorem getD_filterMap_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Option γ} {k k' : α} {fallback : γ} (h : t.getKey? k = some k') :
(t.filterMap f).getD k fallback = (t[k]?.bind (f k')).getD fallback :=
DTreeMap.Const.getD_filterMap_of_getKey?_eq_some h
@[grind =]
theorem getKey?_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} :
(t.filterMap f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
(f x (t[x]'(mem_of_getKey?_eq_some h'))).isSome) :=
DTreeMap.Const.getKey?_filterMap
@[simp, grind =]
theorem getKey_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} {h'} :
(t.filterMap f).getKey k h' = t.getKey k (mem_of_mem_filterMap h') :=
DTreeMap.getKey_filterMap
@[grind =]
theorem getKey!_filterMap [TransCmp cmp] [Inhabited α]
{f : α → β → Option γ} {k : α} :
(t.filterMap f).getKey! k =
((t.getKey? k).pfilter (fun x h' =>
(f x (t[x]'(mem_of_getKey?_eq_some h'))).isSome)).get! :=
DTreeMap.Const.getKey!_filterMap
@[grind =]
theorem getKeyD_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k fallback : α} :
(t.filterMap f).getKeyD k fallback =
((t.getKey? k).pfilter (fun x h' =>
(f x (t[x]'(mem_of_getKey?_eq_some h'))).isSome)).getD fallback :=
DTreeMap.Const.getKeyD_filterMap
end filterMap
section filter
variable {t : TreeMap α β cmp}
theorem filterMap_equiv_filter {f : α → β → Bool} :
(t.filterMap (fun k => Option.guard (fun v => f k v))) ~m t.filter f :=
⟨DTreeMap.filterMap_equiv_filter⟩
@[simp, grind =]
theorem toList_filter {f : α → β → Bool} :
(t.filter f).toList = t.toList.filter (fun p => f p.1 p.2) :=
DTreeMap.Const.toList_filter
theorem keys_filter_key {f : α → Bool} :
(t.filter fun k _ => f k).keys = t.keys.filter f :=
DTreeMap.keys_filter_key
@[grind =]
theorem isEmpty_filter_iff [TransCmp cmp]
{f : α → β → Bool} :
(t.filter f).isEmpty = true ↔
∀ (k : α) (h : k ∈ t), f (t.getKey k h) t[k] = false :=
DTreeMap.Const.isEmpty_filter_iff
theorem isEmpty_filter_eq_false_iff [TransCmp cmp]
{f : α → β → Bool} :
(t.filter f).isEmpty = false ↔
∃ (k : α) (h : k ∈ t), f (t.getKey k h) t[k] = true :=
DTreeMap.Const.isEmpty_filter_eq_false_iff
-- TODO: `contains_filter` is missing
@[grind =]
theorem mem_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} :
k ∈ t.filter f ↔ ∃ (h' : k ∈ t), f (t.getKey k h') t[k] :=
DTreeMap.Const.mem_filter
theorem contains_of_contains_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} :
(t.filter f).contains k = true → t.contains k = true :=
DTreeMap.contains_of_contains_filter
theorem mem_of_mem_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} :
k ∈ t.filter f → k ∈ t :=
DTreeMap.mem_of_mem_filter
theorem size_filter_le_size [TransCmp cmp]
{f : α → β → Bool} :
(t.filter f).size ≤ t.size :=
DTreeMap.size_filter_le_size
grind_pattern size_filter_le_size => (t.filter f).size
theorem size_filter_eq_size_iff [TransCmp cmp]
{f : α → β → Bool} :
(t.filter f).size = t.size ↔ ∀ k h, f (t.getKey k h) (t[k]'h) :=
DTreeMap.Const.size_filter_eq_size_iff
theorem filter_equiv_self_iff [TransCmp cmp]
{f : α → β → Bool} :
t.filter f ~m t ↔ ∀ k h, f (t.getKey k h) (t[k]'h) :=
⟨fun h => DTreeMap.Const.filter_equiv_self_iff.mp h.1,
fun h => ⟨DTreeMap.Const.filter_equiv_self_iff.mpr h⟩⟩
@[simp]
theorem getElem?_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} :
(t.filter f)[k]? = t[k]?.pfilter (fun x h' =>
f (t.getKey k (mem_iff_isSome_getElem?.mpr (Option.isSome_of_eq_some h'))) x) :=
DTreeMap.Const.get?_filter
/-- Simpler variant of `getElem?_filter` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getElem?_filter' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Bool} {k : α} :
(t.filter f)[k]? = t[k]?.filter (f k) := by
simp [getElem?_filter]
theorem getElem?_filter_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Bool} {k k' : α} :
t.getKey? k = some k' →
(t.filter f)[k]? = t[k]?.filter (fun x => f k' x) :=
DTreeMap.Const.get?_filter_of_getKey?_eq_some
@[simp, grind =]
theorem getElem_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} {h'} :
(t.filter f)[k]'(h') = t[k]'(mem_of_mem_filter h') :=
DTreeMap.Const.get_filter
theorem getElem!_filter [TransCmp cmp] [Inhabited β]
{f : α → β → Bool} {k : α} :
(t.filter f)[k]! =
(t[k]?.pfilter (fun x h' =>
f (t.getKey k (mem_iff_isSome_getElem?.mpr (Option.isSome_of_eq_some h'))) x)).get! :=
DTreeMap.Const.get!_filter
/-- Simpler variant of `getElem!_filter` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getElem!_filter' [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited β]
{f : α → β → Bool} {k : α} :
(t.filter f)[k]! = (t[k]?.filter (f k)).get! := by
simp [getElem!_filter]
theorem getElem!_filter_of_getKey?_eq_some [TransCmp cmp] [Inhabited β]
{f : α → β → Bool} {k k' : α} :
t.getKey? k = some k' →
(t.filter f)[k]! = (t[k]?.filter (f k')).get! :=
DTreeMap.Const.get!_filter_of_getKey?_eq_some
theorem getD_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} {fallback : β} :
(t.filter f).getD k fallback = (t[k]?.pfilter (fun x h' =>
f (t.getKey k (mem_iff_isSome_getElem?.mpr (Option.isSome_of_eq_some h'))) x)).getD fallback :=
DTreeMap.Const.getD_filter
/-- Simpler variant of `getD_filter` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getD_filter' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Bool} {k : α} {fallback : β} :
(t.filter f).getD k fallback = (t[k]?.filter (f k)).getD fallback := by
simp [getD_filter]
theorem getD_filter_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Bool} {k k' : α} {fallback : β} :
t.getKey? k = some k' →
(t.filter f).getD k fallback =
(t[k]?.filter (fun x => f k' x)).getD fallback :=
DTreeMap.Const.getD_filter_of_getKey?_eq_some
theorem keys_filter [TransCmp cmp] {f : α → β → Bool} :
(t.filter f).keys =
(t.keys.attach.filter (fun ⟨x, h'⟩ => f x (t[x]'(mem_of_mem_keys h')))).unattach :=
DTreeMap.Const.keys_filter
@[grind =]
theorem getKey?_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} :
(t.filter f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
(f x (t[x]'(mem_of_getKey?_eq_some h')))) :=
DTreeMap.Const.getKey?_filter
theorem getKey?_filter_key [TransCmp cmp]
{f : α → Bool} {k : α} :
(t.filter fun k _ => f k).getKey? k = (t.getKey? k).filter f :=
DTreeMap.getKey?_filter_key
@[simp, grind =]
theorem getKey_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} {h'} :
(t.filter f).getKey k h' = t.getKey k (mem_of_mem_filter h') :=
DTreeMap.getKey_filter
@[grind =]
theorem getKey!_filter [TransCmp cmp] [Inhabited α]
{f : α → β → Bool} {k : α} :
(t.filter f).getKey! k =
((t.getKey? k).pfilter (fun x h' =>
(f x (t[x]'(mem_of_getKey?_eq_some h'))))).get! :=
DTreeMap.Const.getKey!_filter
theorem getKey!_filter_key [TransCmp cmp] [Inhabited α]
{f : α → Bool} {k : α} :
(t.filter fun k _ => f k).getKey! k = ((t.getKey? k).filter f).get! :=
DTreeMap.getKey!_filter_key
@[grind =]
theorem getKeyD_filter [TransCmp cmp]
{f : α → β → Bool} {k fallback : α} :
(t.filter f).getKeyD k fallback =
((t.getKey? k).pfilter (fun x h' =>
(f x (t[x]'(mem_of_getKey?_eq_some h'))))).getD fallback :=
DTreeMap.Const.getKeyD_filter
theorem getKeyD_filter_key [TransCmp cmp]
{f : α → Bool} {k fallback : α} :
(t.filter fun k _ => f k).getKeyD k fallback = ((t.getKey? k).filter f).getD fallback :=
DTreeMap.getKeyD_filter_key
end filter
section map
variable {t : TreeMap α β cmp}
theorem map_id_equiv : t.map (fun _ v => v) ~m t :=
⟨DTreeMap.map_id_equiv⟩
theorem map_map_equiv {f : α → β → γ} {g : αγ → δ} :
(t.map f).map g ~m t.map fun k v => g k (f k v) :=
⟨DTreeMap.map_map_equiv⟩
@[simp, grind =]
theorem toList_map {f : α → β → γ} :
(t.map f).toList = t.toList.map (fun p => (p.1, f p.1 p.2)) :=
DTreeMap.Const.toList_map
@[simp, grind =]
theorem keys_map {f : α → β → γ} : (t.map f).keys = t.keys :=
DTreeMap.keys_map
theorem filterMap_equiv_map [TransCmp cmp]
{f : α → β → γ} :
(t.filterMap (fun k v => some (f k v))) ~m t.map f :=
⟨DTreeMap.filterMap_equiv_map⟩
@[simp, grind =]
theorem isEmpty_map [TransCmp cmp]
{f : α → β → γ} :
(t.map f).isEmpty = t.isEmpty :=
DTreeMap.isEmpty_map
@[simp, grind =]
theorem contains_map [TransCmp cmp]
{f : α → β → γ} {k : α} :
(t.map f).contains k = t.contains k :=
DTreeMap.contains_map
theorem contains_of_contains_map [TransCmp cmp]
{f : α → β → γ} {k : α} :
(t.map f).contains k = true → t.contains k = true :=
DTreeMap.contains_of_contains_map
@[simp, grind =]
theorem mem_map [TransCmp cmp]
{f : α → β → γ} {k : α} :
k ∈ t.map f ↔ k ∈ t := by
simp only [mem_iff_contains, contains_map]
theorem mem_of_mem_map [TransCmp cmp]
{f : α → β → γ} {k : α} :
k ∈ t.map f → k ∈ t :=
DTreeMap.contains_of_contains_map
@[simp, grind =]
theorem size_map [TransCmp cmp]
{f : α → β → γ} :
(t.map f).size = t.size :=
DTreeMap.size_map
@[simp, grind =]
theorem getElem?_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} :
(t.map f)[k]? = t[k]?.map (f k) :=
DTreeMap.Const.get?_map
/-- Variant of `getElem?_map` that holds without `LawfulEqCmp`. -/
@[simp (low)]
theorem getElem?_map' [TransCmp cmp]
{f : α → β → γ} {k : α} :
(t.map f)[k]? = t[k]?.pmap (fun v h' => f (t.getKey k h') v)
(fun _ h' => mem_iff_isSome_getElem?.mpr (Option.isSome_of_eq_some h')) :=
DTreeMap.Const.get?_map'
theorem getElem?_map_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → γ} {k k' : α} (h : t.getKey? k = some k') :
(t.map f)[k]? = t[k]?.map (f k') :=
DTreeMap.Const.get?_map_of_getKey?_eq_some h
@[simp, grind =]
theorem getElem_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} {h'} :
(t.map f)[k]'(h') =
f k (t[k]'(mem_of_mem_map h')) :=
DTreeMap.Const.get_map
/-- Variant of `getElem_map` that holds without `LawfulEqCmp`. -/
@[simp (low)]
theorem getElem_map' [TransCmp cmp]
{f : α → β → γ} {k : α} {h'} :
(t.map f)[k]'(h') =
f (t.getKey k (mem_of_mem_map h')) (t[k]'(mem_of_mem_map h')) :=
DTreeMap.Const.get_map'
@[grind =]
theorem getElem!_map [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited γ]
{f : α → β → γ} {k : α} :
(t.map f)[k]! =
(t[k]?.map (f k)).get! :=
DTreeMap.Const.get!_map
/-- Variant of `getElem!_map` that holds without `LawfulEqCmp`. -/
theorem getElem!_map' [TransCmp cmp] [Inhabited γ]
{f : α → β → γ} {k : α} :
(t.map f)[k]! =
(t[k]?.pmap (fun v h => f (t.getKey k h) v)
(fun _ h' => mem_iff_isSome_getElem?.mpr (Option.isSome_of_mem h'))).get! :=
DTreeMap.Const.get!_map'
theorem getElem!_map_of_getKey?_eq_some [TransCmp cmp] [Inhabited γ]
{f : α → β → γ} {k k' : α} (h : t.getKey? k = some k') :
(t.map f)[k]! = (t[k]?.map (f k')).get! :=
DTreeMap.Const.get!_map_of_getKey?_eq_some h
@[grind =]
theorem getD_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} {fallback : γ} :
(t.map f).getD k fallback =
(t[k]?.map (f k)).getD fallback :=
DTreeMap.Const.getD_map
/-- Variant of `getD_map` that holds without `LawfulEqCmp`. -/
theorem getD_map' [TransCmp cmp]
{f : α → β → γ} {k : α} {fallback : γ} :
(t.map f).getD k fallback =
(t[k]?.pmap (fun v h => f (t.getKey k h) v)
(fun _ h' => mem_iff_isSome_getElem?.mpr (Option.isSome_of_eq_some h'))).getD fallback :=
DTreeMap.Const.getD_map'
theorem getD_map_of_getKey?_eq_some [TransCmp cmp] [Inhabited γ]
{f : α → β → γ} {k k' : α} {fallback : γ} (h : t.getKey? k = some k') :
(t.map f).getD k fallback = (t[k]?.map (f k')).getD fallback :=
DTreeMap.Const.getD_map_of_getKey?_eq_some h
@[simp, grind =]
theorem getKey?_map [TransCmp cmp]
{f : α → β → γ} {k : α} :
(t.map f).getKey? k = t.getKey? k :=
DTreeMap.getKey?_map
@[simp, grind =]
theorem getKey_map [TransCmp cmp]
{f : α → β → γ} {k : α} {h'} :
(t.map f).getKey k h' = t.getKey k (mem_of_mem_map h') :=
DTreeMap.getKey_map
@[simp, grind =]
theorem getKey!_map [TransCmp cmp] [Inhabited α]
{f : α → β → γ} {k : α} :
(t.map f).getKey! k = t.getKey! k :=
DTreeMap.getKey!_map
@[simp, grind =]
theorem getKeyD_map [TransCmp cmp]
{f : α → β → γ} {k fallback : α} :
(t.map f).getKeyD k fallback = t.getKeyD k fallback :=
DTreeMap.getKeyD_map
end map
end Std.TreeMap