feat: tree map lemmas for filter, map, filterMap (#9632)

This PR adds lemmas for the `TreeMap` operations `filter`, `map` and
`filterMap`. These lemmas existed already for hash maps and are simply
ported over from there.
This commit is contained in:
Rob23oba 2025-08-18 14:13:52 +02:00 committed by GitHub
parent 04f9baf4d3
commit 688b930bad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 5746 additions and 379 deletions

View file

@ -4045,7 +4045,7 @@ theorem get?_map' [EquivBEq α] [LawfulHashable α]
(fun _ h' => (contains_eq_isSome_get? m h).trans (Option.isSome_of_mem h')) := by
simp_to_model [map, Const.get?, contains, getKey] using Const.getValue?_map
theorem get?_map [LawfulBEq α] [LawfulHashable α]
theorem get?_map [LawfulBEq α]
{f : α → β → γ} {k : α} (h : m.1.WF) :
Const.get? (m.map f) k = (Const.get? m k).map (f k) := by
simp [get?_map' m h, getKey_eq m h]
@ -4063,7 +4063,7 @@ theorem get_map' [EquivBEq α] [LawfulHashable α]
(Const.get m k (contains_of_contains_map m h h'))) := by
simp_to_model [map, getKey, Const.get, contains] using List.getValue_map
theorem get_map [LawfulBEq α] [LawfulHashable α]
theorem get_map [LawfulBEq α]
{f : α → β → γ} {k : α} (h : m.1.WF) {h'} :
Const.get (m.map f) k h' = f k (Const.get m k (contains_of_contains_map m h h')) := by
simp [get_map' m h, getKey_eq m h]
@ -4076,7 +4076,7 @@ theorem get!_map' [EquivBEq α] [LawfulHashable α] [Inhabited γ]
(fun _ h' => (contains_eq_isSome_get? m h).trans (Option.isSome_of_mem h'))).get! := by
simp_to_model [map, getKey, Const.get!, Const.get?, contains] using List.Const.getValue!_map
theorem get!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ]
theorem get!_map [LawfulBEq α] [Inhabited γ]
{f : α → β → γ} {k : α} (h : m.1.WF) :
Const.get! (m.map f) k = ((Const.get? m k).map (f k)).get! := by
simp [get!_map' m h, getKey_eq m h]
@ -4094,7 +4094,7 @@ theorem getD_map' [EquivBEq α] [LawfulHashable α]
(fun _ h' => (contains_eq_isSome_get? m h).trans (Option.isSome_of_mem h'))).getD fallback := by
simp_to_model [map, getKey, Const.getD, Const.get?, contains] using List.Const.getValueD_map
theorem getD_map [LawfulBEq α] [LawfulHashable α]
theorem getD_map [LawfulBEq α]
{f : α → β → γ} {k : α} {fallback : γ} (h : m.1.WF) :
Const.getD (m.map f) k fallback = ((Const.get? m k).map (f k)).getD fallback := by
simp [getD_map' m h, getKey_eq m h]

View file

@ -3694,7 +3694,7 @@ theorem get?_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `get?_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem get?_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem get?_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} :
Const.get? (m.filterMap f) k = (Const.get? m k).bind fun x => f k x := by
simp [get?_filterMap]
@ -3722,7 +3722,7 @@ theorem get_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `get_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem get_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem get_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} {h} :
Const.get (m.filterMap f) k h =
(f k (Const.get m k (mem_of_mem_filterMap h))).get (by simpa using isSome_apply_of_mem_filterMap h) := by
@ -3737,7 +3737,7 @@ theorem get!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited γ]
/-- Simpler variant of `get!_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem get!_filterMap' [LawfulBEq α] [LawfulHashable α] [Inhabited γ]
theorem get!_filterMap' [LawfulBEq α] [Inhabited γ]
{f : α → β → Option γ} {k : α} :
Const.get! (m.filterMap f) k = ((Const.get? m k).bind (f k) ).get!:= by
simp [get!_filterMap]
@ -3756,7 +3756,7 @@ theorem getD_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getD_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem getD_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem getD_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} {fallback : γ} :
Const.getD (m.filterMap f) k fallback = ((Const.get? m k).bind (f k)).getD fallback := by
simp [getD_filterMap]
@ -4023,7 +4023,7 @@ theorem get?_filter [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `get?_filter` when `LawfulBEq` is available. -/
@[simp, grind =]
theorem get?_filter' [LawfulBEq α] [LawfulHashable α]
theorem get?_filter' [LawfulBEq α]
{f : α → β → Bool} {k : α} :
Const.get? (m.filter f) k = (Const.get? m k).filter (f k) := by
simp [get?_filter]
@ -4049,7 +4049,7 @@ theorem get!_filter [EquivBEq α] [LawfulHashable α] [Inhabited β]
/-- Simpler variant of `get!_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem get!_filter' [LawfulBEq α] [LawfulHashable α] [Inhabited β]
theorem get!_filter' [LawfulBEq α] [Inhabited β]
{f : α → β → Bool} {k : α} :
Const.get! (m.filter f) k = ((Const.get? m k).filter (f k)).get! := by
simp [get!_filter]
@ -4068,7 +4068,7 @@ theorem getD_filter [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getD_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem getD_filter' [LawfulBEq α] [LawfulHashable α]
theorem getD_filter' [LawfulBEq α]
{f : α → β → Bool} {k : α} {fallback : β} :
Const.getD (m.filter f) k fallback = ((Const.get? m k).filter (f k)).getD fallback := by
simp [getD_filter]
@ -4228,7 +4228,7 @@ namespace Const
variable {β : Type v} {γ : Type w} {m : DHashMap α fun _ => β}
@[simp, grind =]
theorem get?_map [LawfulBEq α] [LawfulHashable α]
theorem get?_map [LawfulBEq α]
{f : α → β → γ} {k : α} :
Const.get? (m.map f) k = (Const.get? m k).map (f k) :=
Raw₀.Const.get?_map ⟨m.1, _⟩ m.2
@ -4247,7 +4247,7 @@ theorem get?_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α]
Raw₀.Const.get?_map_of_getKey?_eq_some ⟨m.1, _⟩ m.2 h
@[simp, grind =]
theorem get_map [LawfulBEq α] [LawfulHashable α]
theorem get_map [LawfulBEq α]
{f : α → β → γ} {k : α} {h'} :
Const.get (m.map f) k h' = f k (Const.get m k (mem_of_mem_map h')) :=
Raw₀.Const.get_map ⟨m.1, _⟩ m.2
@ -4261,7 +4261,7 @@ theorem get_map' [EquivBEq α] [LawfulHashable α]
Raw₀.Const.get_map' ⟨m.1, _⟩ m.2
@[grind =]
theorem get!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ]
theorem get!_map [LawfulBEq α] [Inhabited γ]
{f : α → β → γ} {k : α} :
Const.get! (m.map f) k = ((Const.get? m k).map (f k)).get! :=
Raw₀.Const.get!_map ⟨m.1, _⟩ m.2
@ -4280,7 +4280,7 @@ theorem get!_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhabited
Raw₀.Const.get!_map_of_getKey?_eq_some ⟨m.1, _⟩ m.2 h
@[grind =]
theorem getD_map [LawfulBEq α] [LawfulHashable α]
theorem getD_map [LawfulBEq α]
{f : α → β → γ} {k : α} {fallback : γ} :
Const.getD (m.map f) k fallback = ((Const.get? m k).map (f k)).getD fallback :=
Raw₀.Const.getD_map ⟨m.1, _⟩ m.2
@ -4300,8 +4300,8 @@ theorem getD_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhabited
theorem toList_map {m : DHashMap α fun _ => β}
{f : α → β → γ} :
(Raw.Const.toList (m.map f).1).Perm
((Raw.Const.toList m.1).map (fun p => (p.1, f p.1 p.2))) :=
(Const.toList (m.map f)).Perm
((Const.toList m).map (fun p => (p.1, f p.1 p.2))) :=
Raw₀.Const.toList_map ⟨m.1, m.2.size_buckets_pos⟩
end Const

View file

@ -1217,7 +1217,7 @@ theorem contains_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} :
simp_to_raw using Raw₀.contains_keys ⟨m, _⟩ h
@[simp, grind =]
theorem mem_keys [LawfulBEq α] [LawfulHashable α] (h : m.WF) {k : α} :
theorem mem_keys [LawfulBEq α] (h : m.WF) {k : α} :
k ∈ m.keys ↔ k ∈ m := by
rw [mem_iff_contains]
simp_to_raw using Raw₀.mem_keys ⟨m, _⟩ h
@ -3905,7 +3905,7 @@ theorem get?_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `get?_filterMap` when `LawfulBEq` is available. -/
@[simp, grind =]
theorem get?_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem get?_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} (h : m.WF) :
Const.get? (m.filterMap f) k = (Const.get? m k).bind (f k) := by
simp [get?_filterMap, h]
@ -3942,7 +3942,7 @@ theorem get!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited γ]
/-- Simpler variant of `get!_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem get!_filterMap' [LawfulBEq α] [LawfulHashable α] [Inhabited γ]
theorem get!_filterMap' [LawfulBEq α] [Inhabited γ]
{f : α → β → Option γ} {k : α} (h : m.WF) :
Const.get! (m.filterMap f) k = ((Const.get? m k).bind (f k)).get! := by
simp [get!_filterMap, h]
@ -3962,7 +3962,7 @@ theorem getD_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getD_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem getD_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem getD_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} {fallback : γ} (h : m.WF) :
Const.getD (m.filterMap f) k fallback = ((Const.get? m k).bind (f k)).getD fallback := by
simp [getD_filterMap, h]
@ -4250,7 +4250,7 @@ theorem get?_filter [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `get?_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem get?_filter' [LawfulBEq α] [LawfulHashable α]
theorem get?_filter' [LawfulBEq α]
{f : α → β → Bool} {k : α} (h : m.WF) :
Const.get? (m.filter f) k = (Const.get? m k).filter (f k) := by
simp [get?_filter, h]
@ -4276,7 +4276,7 @@ theorem get!_filter [EquivBEq α] [LawfulHashable α] [Inhabited β]
/-- Simpler variant of `get!_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem get!_filter' [LawfulBEq α] [LawfulHashable α] [Inhabited β]
theorem get!_filter' [LawfulBEq α] [Inhabited β]
{f : α → β → Bool} {k : α} (h : m.WF) :
Const.get! (m.filter f) k = ((Const.get? m k).filter (f k)).get! := by
simp [get!_filter, h]
@ -4295,7 +4295,7 @@ theorem getD_filter [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getD_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem getD_filter' [LawfulBEq α] [LawfulHashable α]
theorem getD_filter' [LawfulBEq α]
{f : α → β → Bool} {k : α} {fallback : β} (h : m.WF) :
Const.getD (m.filter f) k fallback = ((Const.get? m k).filter (f k)).getD fallback := by
simp [getD_filter, h]
@ -4466,7 +4466,7 @@ theorem get?_map' [EquivBEq α] [LawfulHashable α]
simp_to_raw using Raw₀.Const.get?_map'
@[simp, grind =]
theorem get?_map [LawfulBEq α] [LawfulHashable α]
theorem get?_map [LawfulBEq α]
{f : α → β → γ} {k : α} (h : m.WF) :
Const.get? (m.map f) k = (Const.get? m k).map (f k) := by
simp [get?_map' h, getKey_eq h]
@ -4486,7 +4486,7 @@ theorem get_map' [EquivBEq α] [LawfulHashable α]
simp_to_raw using Raw₀.Const.get_map'
@[simp, grind =]
theorem get_map [LawfulBEq α] [LawfulHashable α]
theorem get_map [LawfulBEq α]
{f : α → β → γ} {k : α} (h : m.WF) {h'} :
Const.get (m.map f) k h' = f k (Const.get m k (mem_of_mem_map h h')) := by
simp [get_map' h, getKey_eq h]
@ -4501,7 +4501,7 @@ theorem get!_map' [EquivBEq α] [LawfulHashable α] [Inhabited γ]
simp_to_raw using Raw₀.Const.get!_map'
@[grind =]
theorem get!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ]
theorem get!_map [LawfulBEq α] [Inhabited γ]
{f : α → β → γ} {k : α} (h : m.WF) :
Const.get! (m.map f) k = ((Const.get? m k).map (f k)).get! := by
simp [get!_map' h, getKey_eq h]
@ -4521,7 +4521,7 @@ theorem getD_map' [EquivBEq α] [LawfulHashable α]
simp_to_raw using Raw₀.Const.getD_map'
@[grind =]
theorem getD_map [LawfulBEq α] [LawfulHashable α]
theorem getD_map [LawfulBEq α]
{f : α → β → γ} {k : α} {fallback : γ} (h : m.WF) :
Const.getD (m.map f) k fallback = ((Const.get? m k).map (f k)).getD fallback := by
simp [getD_map' h, getKey_eq h]

File diff suppressed because it is too large Load diff

View file

@ -1820,7 +1820,7 @@ theorem sameKeys_map [Ord α] {t : Impl α β} {f : (a : α) → β a → γ a}
| inner => apply SameKeys.inner <;> assumption
@[simp]
theorem size_map [Ord α] {t : Impl α β} {f : (a : α) → β a → γ a} : (t.map f).size = t.size :=
theorem size_map {instOrd : Ord α} {t : Impl α β} {f : (a : α) → β a → γ a} : (t.map f).size = t.size :=
sameKeys_map.size_eq
theorem WF.map [Ord α] {t : Impl α β} {f : (a : α) → β a → γ a} (h : t.WF) : (t.map f).WF :=

View file

@ -356,10 +356,18 @@ theorem get_erase [TransCmp cmp] [LawfulEqCmp cmp] {k a : α} {h'} :
(t.erase k).get a h' = t.get a (mem_of_mem_erase h') :=
Impl.get_erase t.wf
theorem get?_eq_some_get [TransCmp cmp] [LawfulEqCmp cmp] {a : α} {h'} :
theorem get?_eq_some_get [TransCmp cmp] [LawfulEqCmp cmp] {a : α} (h') :
t.get? a = some (t.get a h') :=
Impl.get?_eq_some_get t.wf
theorem get_eq_get_get? [TransCmp cmp] [LawfulEqCmp cmp] {a : α} {h} :
t.get a h = (t.get? a).get (mem_iff_isSome_get?.mp h) := by
simp only [get?_eq_some_get h, Option.get_some]
@[grind =] theorem get_get? [TransCmp cmp] [LawfulEqCmp cmp] {a : α} {h} :
(t.get? a).get h = t.get a (mem_iff_isSome_get?.mpr h) :=
get_eq_get_get?.symm
namespace Const
variable {β : Type v} {t : DTreeMap α β cmp}
@ -380,10 +388,18 @@ theorem get_erase [TransCmp cmp] {k a : α} {h'} :
get (t.erase k) a h' = get t a (mem_of_mem_erase h') :=
Impl.Const.get_erase t.wf
theorem get?_eq_some_get [TransCmp cmp] {a : α} {h} :
theorem get?_eq_some_get [TransCmp cmp] {a : α} (h) :
get? t a = some (get t a h) :=
Impl.Const.get?_eq_some_get t.wf
theorem get_eq_get_get? [TransCmp cmp] {a : α} {h} :
get t a h = (get? t a).get (mem_iff_isSome_get?.mp h) := by
simp only [get?_eq_some_get h, Option.get_some]
@[grind =] theorem get_get? [TransCmp cmp] {a : α} {h} :
(get? t a).get h = get t a (mem_iff_isSome_get?.mpr h) :=
get_eq_get_get?.symm
theorem get_eq_get [TransCmp cmp] [LawfulEqCmp cmp] {a : α} {h} : get t a h = t.get a h :=
Impl.Const.get_eq_get t.wf
@ -674,6 +690,10 @@ theorem isSome_getKey?_iff_mem [TransCmp cmp] {a : α} :
(t.getKey? a).isSome ↔ a ∈ t :=
mem_iff_isSome_getKey?.symm
theorem mem_of_getKey?_eq_some [TransCmp cmp] {k k' : α} :
t.getKey? k = some k' → k' ∈ t :=
Impl.mem_of_getKey?_eq_some t.wf
theorem getKey?_eq_none_of_contains_eq_false [TransCmp cmp] {a : α} :
t.contains a = false → t.getKey? a = none :=
Impl.getKey?_eq_none_of_contains_eq_false t.wf
@ -725,10 +745,19 @@ theorem getKey_erase [TransCmp cmp] {k a : α} {h'} :
(t.erase k).getKey a h' = t.getKey a (mem_of_mem_erase h') :=
Impl.getKey_erase t.wf
theorem getKey?_eq_some_getKey [TransCmp cmp] {a : α} {h'} :
theorem getKey?_eq_some_getKey [TransCmp cmp] {a : α} (h') :
t.getKey? a = some (t.getKey a h') :=
Impl.getKey?_eq_some_getKey t.wf
theorem getKey_eq_get_getKey? [TransCmp cmp] {a : α} {h} :
t.getKey a h = (t.getKey? a).get (mem_iff_isSome_getKey?.mp h) := by
simp only [getKey?_eq_some_getKey h, Option.get_some]
@[simp, grind =]
theorem get_getKey? [TransCmp cmp] {a : α} {h} :
(t.getKey? a).get h = t.getKey a (mem_iff_isSome_getKey?.mpr h) :=
getKey_eq_get_getKey?.symm
theorem compare_getKey_self [TransCmp cmp] {k : α} (h' : k ∈ t) :
cmp (t.getKey k h') k = .eq :=
Impl.compare_getKey_self t.wf h'
@ -1050,6 +1079,9 @@ theorem mem_keys [LawfulEqCmp cmp] [TransCmp cmp] {k : α} :
k ∈ t.keys ↔ k ∈ t :=
Impl.mem_keys t.wf
theorem mem_of_mem_keys [TransCmp cmp] {k : α} (h : k ∈ t.keys) : k ∈ t :=
Impl.mem_of_mem_keys t.wf h
theorem distinct_keys [TransCmp cmp] :
t.keys.Pairwise (fun a b => ¬ cmp a b = .eq) :=
Impl.distinct_keys t.wf
@ -4821,4 +4853,781 @@ end Const
end Equiv
section filterMap
variable {γ : α → Type w}
@[simp, grind =]
theorem toList_filterMap {f : (a : α) → β a → Option (γ a)} :
(t.filterMap f).toList =
t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) :=
Impl.toList_filterMap t.wf
@[grind =]
theorem isEmpty_filterMap_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} :
(t.filterMap f).isEmpty = true ↔
∀ (k : α) (h : k ∈ t), f k (t.get k h) = none :=
Impl.isEmpty_filterMap_iff t.wf
theorem isEmpty_filterMap_eq_false_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} :
(t.filterMap f).isEmpty = false ↔
∃ (k : α) (h : k ∈ t), (f k (t.get k h)).isSome :=
Impl.isEmpty_filterMap_eq_false_iff t.wf
@[grind =]
theorem contains_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} :
(t.filterMap f).contains k = (t.get? k).any (f k · |>.isSome) :=
Impl.contains_filterMap t.wf
@[grind =]
theorem mem_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} :
k ∈ t.filterMap f ↔ ∃ h, (f k (t.get k h)).isSome := by
simp only [mem_iff_contains, contains_filterMap, Option.any_eq_true_iff_get,
← contains_eq_isSome_get?, get_get?]
theorem contains_of_contains_filterMap [TransCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} :
(t.filterMap f).contains k = true → t.contains k = true :=
Impl.contains_of_contains_filterMap t.wf
theorem mem_of_mem_filterMap [TransCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} :
k ∈ t.filterMap f → k ∈ t :=
Impl.contains_of_contains_filterMap t.wf
theorem size_filterMap_le_size [TransCmp cmp]
{f : (a : α) → β a → Option (γ a)} :
(t.filterMap f).size ≤ t.size :=
Impl.size_filterMap_le_size t.wf
grind_pattern size_filterMap_le_size => (t.filterMap f).size
theorem size_filterMap_eq_size_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} :
(t.filterMap f).size = t.size ↔ ∀ (a : α) (h : a ∈ t), (f a (t.get a h)).isSome :=
Impl.size_filterMap_eq_size_iff t.wf
@[simp, grind =]
theorem get?_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} :
(t.filterMap f).get? k = (t.get? k).bind (f k) :=
Impl.get?_filterMap t.wf
theorem isSome_apply_of_mem_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} :
∀ (h' : k ∈ t.filterMap f),
(f k (t.get k (mem_of_mem_filterMap h'))).isSome :=
Impl.isSome_apply_of_contains_filterMap t.wf
@[simp, grind =]
theorem get_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} {h'} :
(t.filterMap f).get k h' =
(f k (t.get k (mem_of_mem_filterMap h'))).get
(isSome_apply_of_mem_filterMap h') :=
Impl.get_filterMap t.wf
@[simp, grind =]
theorem get!_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} [Inhabited (γ k)] :
(t.filterMap f).get! k = ((t.get? k).bind (f k)).get! :=
Impl.get!_filterMap t.wf
@[simp, grind =]
theorem getD_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} {fallback : γ k} :
(t.filterMap f).getD k fallback = ((t.get? k).bind (f k)).getD fallback :=
Impl.getD_filterMap t.wf
@[grind =]
theorem getKey?_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} :
(t.filterMap f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
(f x (t.get x (mem_of_getKey?_eq_some h'))).isSome) :=
Impl.getKey?_filterMap t.wf
@[simp, grind =]
theorem getKey_filterMap [TransCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} {h'} :
(t.filterMap f).getKey k h' = t.getKey k (mem_of_mem_filterMap h') :=
Impl.getKey_filterMap t.wf
@[grind =]
theorem getKey!_filterMap [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α]
{f : (a : α) → β a → Option (γ a)} {k : α} :
(t.filterMap f).getKey! k =
((t.getKey? k).pfilter (fun x h' =>
(f x (t.get x (mem_of_getKey?_eq_some h'))).isSome)).get! :=
Impl.getKey!_filterMap t.wf
@[grind =]
theorem getKeyD_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k fallback : α} :
(t.filterMap f).getKeyD k fallback =
((t.getKey? k).pfilter (fun x h' =>
(f x (t.get x (mem_of_getKey?_eq_some h'))).isSome)).getD fallback :=
Impl.getKeyD_filterMap t.wf
namespace Const
variable {β : Type v} {γ : Type w} {t : DTreeMap α (fun _ => β) cmp}
@[grind =]
theorem isEmpty_filterMap_iff [TransCmp cmp]
{f : α → β → Option γ} :
(t.filterMap f).isEmpty ↔ ∀ k h, f (t.getKey k h) (get t k h) = none :=
Impl.Const.isEmpty_filterMap_iff t.wf
theorem isEmpty_filterMap_eq_false_iff [TransCmp cmp]
{f : α → β → Option γ} :
(t.filterMap f).isEmpty = false ↔ ∃ k h, (f (t.getKey k h) (get t k h)).isSome :=
Impl.Const.isEmpty_filterMap_eq_false_iff t.wf
-- TODO: `contains_filterMap` is missing
@[grind =]
theorem mem_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} :
k ∈ t.filterMap f ↔ ∃ h, (f (t.getKey k h) (Const.get t k h)).isSome :=
Impl.Const.contains_filterMap_iff t.wf
-- TODO: `size_filterMap_le_size` is missing
theorem size_filterMap_eq_size_iff [TransCmp cmp]
{f : α → β → Option γ} :
(t.filterMap f).size = t.size ↔ ∀ k h, (f (t.getKey k h) (Const.get t k h)).isSome :=
Impl.Const.size_filterMap_eq_size_iff t.wf
@[simp]
theorem get?_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} :
Const.get? (t.filterMap f) k = (Const.get? t k).pbind (fun x h' =>
f (t.getKey k (mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))) x) :=
Impl.Const.get?_filterMap t.wf
/-- Simpler variant of `get?_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem get?_filterMap' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Option γ} {k : α} :
Const.get? (t.filterMap f) k = (Const.get? t k).bind fun x => f k x := by
simp [get?_filterMap]
theorem get?_filterMap_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Option γ} {k k' : α} (h : t.getKey? k = some k') :
Const.get? (t.filterMap f) k = (Const.get? t k).bind (f k') :=
Impl.Const.get?_filterMap_of_getKey?_eq_some t.wf 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))
(Const.get t k (mem_of_mem_filterMap h))).isSome :=
Impl.Const.isSome_apply_of_contains_filterMap t.wf
@[simp]
theorem get_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} {h} :
Const.get (t.filterMap f) k h =
(f (t.getKey k (mem_of_mem_filterMap h))
(Const.get t k (mem_of_mem_filterMap h))).get
(isSome_apply_of_mem_filterMap h) :=
Impl.Const.get_filterMap t.wf
/-- Simpler variant of `get_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem get_filterMap' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Option γ} {k : α} {h} :
Const.get (t.filterMap f) k h =
(f k (Const.get t k (mem_of_mem_filterMap h))).get (by simpa using isSome_apply_of_mem_filterMap h) := by
simp [get_filterMap]
theorem get!_filterMap [TransCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k : α} :
Const.get! (t.filterMap f) k =
((Const.get? t k).pbind (fun x h' =>
f (t.getKey k (mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))) x)).get! :=
Impl.Const.get!_filterMap t.wf
/-- Simpler variant of `get!_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem get!_filterMap' [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k : α} :
Const.get! (t.filterMap f) k = ((Const.get? t k).bind (f k) ).get!:= by
simp [get!_filterMap]
theorem get!_filterMap_of_getKey?_eq_some [TransCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k k' : α} (h : t.getKey? k = some k') :
Const.get! (t.filterMap f) k = ((Const.get? t k).bind (f k')).get! :=
Impl.Const.get!_filterMap_of_getKey?_eq_some t.wf h
theorem getD_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} {fallback : γ} :
Const.getD (t.filterMap f) k fallback =
((Const.get? t k).pbind (fun x h' =>
f (t.getKey k (mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))) x)).getD fallback :=
Impl.Const.getD_filterMap t.wf
/-- Simpler variant of `getD_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getD_filterMap' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Option γ} {k : α} {fallback : γ} :
Const.getD (t.filterMap f) k fallback = ((Const.get? 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') :
Const.getD (t.filterMap f) k fallback = ((Const.get? t k).bind (f k')).getD fallback :=
Impl.Const.getD_filterMap_of_getKey?_eq_some t.wf h
theorem toList_filterMap
{f : α → β → Option γ} :
Const.toList (t.filterMap fun k v => f k v) =
(Const.toList t).filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x))) :=
Impl.Const.toList_filterMap t.wf
@[grind =]
theorem getKey?_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} :
(t.filterMap f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
(f x (Const.get t x (mem_of_getKey?_eq_some h'))).isSome) :=
Impl.Const.getKey?_filterMap t.wf
@[grind =]
theorem getKey!_filterMap [TransCmp cmp] [Inhabited α]
{f : α → β → Option γ} {k : α} :
(t.filterMap f).getKey! k =
((t.getKey? k).pfilter (fun x h' =>
(f x (Const.get t x (mem_of_getKey?_eq_some h'))).isSome)).get! :=
Impl.Const.getKey!_filterMap t.wf
@[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 (Const.get t x (mem_of_getKey?_eq_some h'))).isSome)).getD fallback :=
Impl.Const.getKeyD_filterMap t.wf
end Const
end filterMap
section filter
theorem filterMap_equiv_filter {f : (a : α) → β a → Bool} :
t.filterMap (fun k => Option.guard (fun v => f k v)) ~m t.filter f :=
⟨Impl.filterMap_equiv_filter t.wf⟩
@[simp, grind =]
theorem toList_filter {f : (a : α) → β a → Bool} :
(t.filter f).toList = t.toList.filter (fun p => f p.1 p.2) :=
Impl.toList_filter t.wf
theorem keys_filter_key {f : α → Bool} :
(t.filter fun k _ => f k).keys = t.keys.filter f :=
Impl.keys_filter_key t.wf
@[grind =]
theorem isEmpty_filter_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} :
(t.filter f).isEmpty = true ↔
∀ (k : α) (h : k ∈ t), f k (t.get k h) = false :=
Impl.isEmpty_filter_iff t.wf
theorem isEmpty_filter_eq_false_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} :
(t.filter f).isEmpty = false ↔
∃ (k : α) (h : k ∈ t), f k (t.get k h) = true :=
Impl.isEmpty_filter_eq_false_iff t.wf
theorem isEmpty_filter_key_iff [TransCmp cmp]
{f : α → Bool} :
(t.filter (fun a _ => f a)).isEmpty ↔
∀ (k : α) (h : k ∈ t), f (t.getKey k h) = false :=
Impl.isEmpty_filter_key_iff t.wf
theorem isEmpty_filter_key_eq_false_iff [TransCmp cmp]
{f : α → Bool} :
(t.filter (fun a _ => f a)).isEmpty = false ↔
∃ (k : α) (h : k ∈ t), f (t.getKey k h) :=
Impl.isEmpty_filter_key_eq_false_iff t.wf
@[grind =]
theorem contains_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} :
(t.filter f).contains k = (t.get? k).any (f k) :=
Impl.contains_filter t.wf
@[grind =]
theorem mem_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} :
k ∈ t.filter f ↔ ∃ h, f k (t.get k h) := by
simp only [mem_iff_contains, contains_filter, Option.any_eq_true_iff_get,
← contains_eq_isSome_get?, get_get?]
theorem mem_filter_key [TransCmp cmp]
{f : α → Bool} {k : α} :
k ∈ t.filter (fun a _ => f a) ↔ ∃ h, f (t.getKey k h) :=
Impl.contains_filter_key_iff t.wf
theorem contains_of_contains_filter [TransCmp cmp]
{f : (a : α) → β a → Bool} {k : α} :
(t.filter f).contains k = true → t.contains k = true :=
Impl.contains_of_contains_filter t.wf
theorem mem_of_mem_filter [TransCmp cmp]
{f : (a : α) → β a → Bool} {k : α} :
k ∈ (t.filter f) → k ∈ t :=
Impl.contains_of_contains_filter t.wf
theorem size_filter_le_size [TransCmp cmp]
{f : (a : α) → β a → Bool} :
(t.filter f).size ≤ t.size :=
Impl.size_filter_le_size t.wf
grind_pattern size_filter_le_size => (t.filter f).size
theorem size_filter_eq_size_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} :
(t.filter f).size = t.size ↔ ∀ k h, f k (t.get k h) :=
Impl.size_filter_eq_size_iff t.wf
theorem filter_equiv_self_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} :
t.filter f ~m t ↔ ∀ k h, f k (t.get k h) :=
⟨fun h => (Impl.filter_equiv_self_iff t.wf).mp h.1,
fun h => ⟨(Impl.filter_equiv_self_iff t.wf).mpr h⟩⟩
theorem filter_key_equiv_self_iff [TransCmp cmp]
{f : (a : α) → Bool} :
t.filter (fun k _ => f k) ~m t ↔ ∀ k h, f (t.getKey k h) :=
⟨fun h => (Impl.filter_key_equiv_self_iff t.wf).mp h.1,
fun h => ⟨(Impl.filter_key_equiv_self_iff t.wf).mpr h⟩⟩
theorem size_filter_key_eq_size_iff [TransCmp cmp]
{f : α → Bool} :
(t.filter fun k _ => f k).size = t.size ↔ ∀ (k : α) (h : k ∈ t), f (t.getKey k h) :=
Impl.size_filter_key_eq_size_iff t.wf
@[simp, grind =]
theorem get?_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} :
(t.filter f).get? k = (t.get? k).filter (f k) :=
Impl.get?_filter t.wf
@[simp, grind =]
theorem get_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} {h'} :
(t.filter f).get k h' = t.get k (mem_of_mem_filter h') :=
Impl.get_filter t.wf
@[grind =]
theorem get!_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} [Inhabited (β k)] :
(t.filter f).get! k = ((t.get? k).filter (f k)).get! :=
Impl.get!_filter t.wf
@[grind =]
theorem getD_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} {fallback : β k} :
(t.filter f).getD k fallback = ((t.get? k).filter (f k)).getD fallback :=
Impl.getD_filter t.wf
theorem keys_filter [TransCmp cmp] [LawfulEqCmp cmp] {f : (a : α) → β a → Bool} :
(t.filter f).keys =
(t.keys.attach.filter (fun ⟨x, h'⟩ => f x (t.get x (mem_of_mem_keys h')))).unattach :=
Impl.keys_filter t.wf
@[grind =]
theorem getKey?_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} :
(t.filter f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
f x (t.get x (mem_of_getKey?_eq_some h'))) :=
Impl.getKey?_filter t.wf
theorem getKey?_filter_key [TransCmp cmp]
{f : α → Bool} {k : α} :
(t.filter fun k _ => f k).getKey? k = (t.getKey? k).filter f :=
Impl.getKey?_filter_key t.wf
@[simp, grind =]
theorem getKey_filter [TransCmp cmp]
{f : (a : α) → β a → Bool} {k : α} {h'} :
(t.filter f).getKey k h' = t.getKey k (mem_of_mem_filter h') :=
Impl.getKey_filter t.wf
@[grind =]
theorem getKey!_filter [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α]
{f : (a : α) → β a → Bool} {k : α} :
(t.filter f).getKey! k =
((t.getKey? k).pfilter (fun x h' =>
f x (t.get x (mem_of_getKey?_eq_some h')))).get! :=
Impl.getKey!_filter t.wf
theorem getKey!_filter_key [TransCmp cmp] [Inhabited α]
{f : α → Bool} {k : α} :
(t.filter fun k _ => f k).getKey! k = ((t.getKey? k).filter f).get! :=
Impl.getKey!_filter_key t.wf
@[grind =]
theorem getKeyD_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k fallback : α} :
(t.filter f).getKeyD k fallback =
((t.getKey? k).pfilter (fun x h' =>
f x (t.get x (mem_of_getKey?_eq_some h')))).getD fallback :=
Impl.getKeyD_filter t.wf
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 :=
Impl.getKeyD_filter_key t.wf
namespace Const
variable {β : Type v} {γ : Type w} {t : DTreeMap α (fun _ => β) cmp}
@[grind =]
theorem isEmpty_filter_iff [TransCmp cmp]
{f : α → β → Bool} :
(t.filter f).isEmpty = true ↔
∀ (k : α) (h : k ∈ t), f (t.getKey k h) (Const.get t k h) = false :=
Impl.Const.isEmpty_filter_iff t.wf
theorem isEmpty_filter_eq_false_iff [TransCmp cmp]
{f : α → β → Bool} :
(t.filter f).isEmpty = false ↔
∃ (k : α) (h : k ∈ t), (f (t.getKey k h) (Const.get t k h)) = true :=
Impl.Const.isEmpty_filter_eq_false_iff t.wf
-- 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') (Const.get t k h') :=
Impl.Const.contains_filter_iff t.wf
theorem size_filter_le_size [TransCmp cmp]
{f : α → β → Bool} :
(t.filter f).size ≤ t.size :=
Impl.Const.size_filter_le_size t.wf
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 ↔ ∀ (a : α) (h : a ∈ t),
f (t.getKey a h) (Const.get t a h) :=
Impl.Const.size_filter_eq_size_iff t.wf
theorem filter_equiv_self_iff [TransCmp cmp]
{f : α → β → Bool} :
t.filter f ~m t ↔ ∀ k h, f (t.getKey k h) (Const.get t k h) :=
⟨fun h => (Impl.Const.filter_equiv_self_iff t.wf).mp h.1,
fun h => ⟨(Impl.Const.filter_equiv_self_iff t.wf).mpr h⟩ ⟩
theorem get?_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} :
Const.get? (t.filter f) k = (Const.get? t k).pfilter (fun x h' =>
f (t.getKey k (mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))) x) :=
Impl.Const.get?_filter t.wf
/-- Simpler variant of `get?_filter` when `LawfulEqCmp` is available. -/
@[simp, grind =]
theorem get?_filter' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Bool} {k : α} :
Const.get? (t.filter f) k = (Const.get? t k).filter (f k) := by
simp [get?_filter]
theorem get?_filter_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Bool} {k k' : α} :
t.getKey? k = some k' →
Const.get? (t.filter f) k = (Const.get? t k).filter (fun x => f k' x) :=
Impl.Const.get?_filter_of_getKey?_eq_some t.wf
@[simp, grind =]
theorem get_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} {h'} :
Const.get (t.filter f) k h' = Const.get t k (mem_of_mem_filter h') :=
Impl.Const.get_filter t.wf
theorem get!_filter [TransCmp cmp] [Inhabited β]
{f : α → β → Bool} {k : α} :
Const.get! (t.filter f) k =
((Const.get? t k).pfilter (fun x h' =>
f (t.getKey k (mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))) x)).get! :=
Impl.Const.get!_filter t.wf
/-- Simpler variant of `get!_filter` when `LawfulEqCmp` is available. -/
@[grind =]
theorem get!_filter' [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited β]
{f : α → β → Bool} {k : α} :
Const.get! (t.filter f) k = ((Const.get? t k).filter (f k)).get! := by
simp [get!_filter]
theorem get!_filter_of_getKey?_eq_some [TransCmp cmp] [Inhabited β]
{f : α → β → Bool} {k k' : α} :
t.getKey? k = some k' →
Const.get! (t.filter f) k = ((Const.get? t k).filter (fun x => f k' x)).get! :=
Impl.Const.get!_filter_of_getKey?_eq_some t.wf
theorem getD_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} {fallback : β} :
Const.getD (t.filter f) k fallback = ((Const.get? t k).pfilter (fun x h' =>
f (t.getKey k (mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))) x)).getD fallback :=
Impl.Const.getD_filter t.wf
/-- Simpler variant of `getD_filter` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getD_filter' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Bool} {k : α} {fallback : β} :
Const.getD (t.filter f) k fallback = ((Const.get? 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' →
Const.getD (t.filter f) k fallback =
((Const.get? t k).filter (fun x => f k' x)).getD fallback :=
Impl.Const.getD_filter_of_getKey?_eq_some t.wf
@[simp, grind =]
theorem toList_filter {f : α → β → Bool} :
toList (t.filter f) =
(toList t).filter (fun p => f p.1 p.2) :=
Impl.Const.toList_filter t.wf
theorem keys_filter [TransCmp cmp] {f : α → β → Bool} :
(t.filter f).keys =
(t.keys.attach.filter (fun ⟨x, h'⟩ => f x (get t x (mem_of_mem_keys h')))).unattach :=
Impl.Const.keys_filter t.wf
@[grind =]
theorem getKey?_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} :
(t.filter f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
(f x (Const.get t x (mem_of_getKey?_eq_some h')))) :=
Impl.Const.getKey?_filter t.wf
@[grind =]
theorem getKey!_filter [TransCmp cmp] [Inhabited α]
{f : α → β → Bool} {k : α} :
(t.filter f).getKey! k =
((t.getKey? k).pfilter (fun x h' =>
(f x (Const.get t x (mem_of_getKey?_eq_some h'))))).get! :=
Impl.Const.getKey!_filter t.wf
@[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 (Const.get t x (mem_of_getKey?_eq_some h'))))).getD fallback :=
Impl.Const.getKeyD_filter t.wf
end Const
end filter
section map
variable {γ : α → Type w} {δ : α → Type w'}
theorem map_id_equiv : t.map (fun _ v => v) ~m t :=
⟨Impl.map_id_equiv⟩
theorem map_map_equiv {f : (a : α) → β a → γ a} {g : (a : α) → γ a → δ a} :
(t.map f).map g ~m t.map fun k v => g k (f k v) :=
⟨Impl.map_map_equiv⟩
@[simp, grind =]
theorem toList_map {f : (a : α) → β a → γ a} :
(t.map f).toList = t.toList.map (fun p => ⟨p.1, f p.1 p.2⟩) :=
Impl.toList_map
@[simp, grind =]
theorem keys_map {f : (a : α) → β a → γ a} : (t.map f).keys = t.keys :=
Impl.keys_map
theorem filterMap_equiv_map [TransCmp cmp]
{f : (a : α) → β a → γ a} :
(t.filterMap (fun k v => some (f k v))) ~m t.map f :=
⟨Impl.filterMap_equiv_map t.wf⟩
@[simp, grind =]
theorem isEmpty_map [TransCmp cmp]
{f : (a : α) → β a → γ a} :
(t.map f).isEmpty = t.isEmpty :=
Impl.isEmpty_map
@[grind =]
theorem contains_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} :
(t.map f).contains k = t.contains k :=
Impl.contains_map t.wf
theorem contains_of_contains_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} :
(t.map f).contains k = true → t.contains k = true :=
Impl.contains_of_contains_map t.wf
@[simp, grind =]
theorem mem_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} :
k ∈ t.map f ↔ k ∈ t := by
simp only [mem_iff_contains, contains_map]
theorem mem_of_mem_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} :
k ∈ t.map f → k ∈ t :=
Impl.contains_of_contains_map t.wf
@[simp, grind =]
theorem size_map [TransCmp cmp]
{f : (a : α) → β a → γ a} :
(t.map f).size = t.size :=
Impl.size_map
@[simp, grind =]
theorem get?_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → γ a} {k : α} :
(t.map f).get? k = (t.get? k).map (f k) :=
Impl.get?_map t.wf
@[simp, grind =]
theorem get_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → γ a} {k : α} {h'} :
(t.map f).get k h' = f k (t.get k (mem_of_mem_map h')) :=
Impl.get_map t.wf
@[grind =]
theorem get!_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → γ a} {k : α} [Inhabited (γ k)] :
(t.map f).get! k = ((t.get? k).map (f k)).get! :=
Impl.get!_map t.wf
@[grind =]
theorem getD_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → γ a} {k : α} {fallback : γ k} :
(t.map f).getD k fallback = ((t.get? k).map (f k)).getD fallback :=
Impl.getD_map t.wf
@[simp, grind =]
theorem getKey?_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} :
(t.map f).getKey? k = t.getKey? k :=
Impl.getKey?_map t.wf
@[simp, grind =]
theorem getKey_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} {h'} :
(t.map f).getKey k h' = t.getKey k (mem_of_mem_map h') :=
Impl.getKey_map t.wf
@[simp, grind =]
theorem getKey!_map [TransCmp cmp] [Inhabited α]
{f : (a : α) → β a → γ a} {k : α} :
(t.map f).getKey! k = t.getKey! k :=
Impl.getKey!_map t.wf
@[simp, grind =]
theorem getKeyD_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k fallback : α} :
(t.map f).getKeyD k fallback = t.getKeyD k fallback :=
Impl.getKeyD_map t.wf
namespace Const
variable {β : Type v} {γ : Type w} {t : DTreeMap α (fun _ => β) cmp}
@[simp, grind =]
theorem get?_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} :
Const.get? (t.map f) k = (Const.get? t k).map (f k) :=
Impl.Const.get?_map t.wf
/-- Variant of `get?_map` that holds without `LawfulEqCmp`. -/
@[simp (low)]
theorem get?_map' [TransCmp cmp]
{f : α → β → γ} {k : α} :
Const.get? (t.map f) k = (Const.get? t k).pmap (fun v h' => f (t.getKey k h') v)
(fun _ h' => mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h')) :=
Impl.Const.get?_map' t.wf
theorem get?_map_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → γ} {k k' : α} (h : t.getKey? k = some k') :
Const.get? (t.map f) k = (Const.get? t k).map (f k') :=
Impl.Const.get?_map_of_getKey?_eq_some t.wf h
@[simp, grind =]
theorem get_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} {h'} :
Const.get (t.map f) k h' = f k (Const.get t k (mem_of_mem_map h')) :=
Impl.Const.get_map t.wf
/-- Variant of `get_map` that holds without `LawfulEqCmp`. -/
@[simp (low)]
theorem get_map' [TransCmp cmp]
{f : α → β → γ} {k : α} {h'} :
Const.get (t.map f) k h' =
f (t.getKey k (mem_of_mem_map h')) (Const.get t k (mem_of_mem_map h')) :=
Impl.Const.get_map' t.wf
@[grind =]
theorem get!_map [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited γ]
{f : α → β → γ} {k : α} :
Const.get! (t.map f) k = ((Const.get? t k).map (f k)).get! :=
Impl.Const.get!_map t.wf
/-- Variant of `get!_map` that holds without `LawfulEqCmp`. -/
theorem get!_map' [TransCmp cmp] [Inhabited γ]
{f : α → β → γ} {k : α} :
Const.get! (t.map f) k =
((get? t k).pmap (fun v h => f (t.getKey k h) v)
(fun _ h' => mem_iff_isSome_get?.mpr (Option.isSome_of_mem h'))).get! :=
Impl.Const.get!_map' t.wf
theorem get!_map_of_getKey?_eq_some [TransCmp cmp] [Inhabited γ]
{f : α → β → γ} {k k' : α} (h : t.getKey? k = some k') :
Const.get! (t.map f) k = ((Const.get? t k).map (f k')).get! :=
Impl.Const.get!_map_of_getKey?_eq_some t.wf h
@[grind =]
theorem getD_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} {fallback : γ} :
Const.getD (t.map f) k fallback = ((Const.get? t k).map (f k)).getD fallback :=
Impl.Const.getD_map t.wf
/-- Variant of `getD_map` that holds without `LawfulEqCmp`. -/
theorem getD_map' [TransCmp cmp]
{f : α → β → γ} {k : α} {fallback : γ} :
Const.getD (t.map f) k fallback =
((get? t k).pmap (fun v h => f (t.getKey k h) v)
(fun _ h' => mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))).getD fallback :=
Impl.Const.getD_map' t.wf
theorem getD_map_of_getKey?_eq_some [TransCmp cmp] [Inhabited γ]
{f : α → β → γ} {k k' : α} {fallback : γ} (h : t.getKey? k = some k') :
Const.getD (t.map f) k fallback = ((Const.get? t k).map (f k')).getD fallback :=
Impl.Const.getD_map_of_getKey?_eq_some t.wf h
@[simp, grind =]
theorem toList_map {f : α → β → γ} :
(Const.toList (t.map f)) =
(Const.toList t).map (fun p => (p.1, f p.1 p.2)) :=
Impl.Const.toList_map
end Const
end map
end Std.DTreeMap

View file

@ -357,10 +357,18 @@ theorem get_erase [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k a : α} {h'} :
(t.erase k).get a h' = t.get a (mem_of_mem_erase h h') :=
Impl.get_erase! h
theorem get?_eq_some_get [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {a : α} {h'} :
theorem get?_eq_some_get [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {a : α} (h') :
t.get? a = some (t.get a h') :=
Impl.get?_eq_some_get h
theorem get_eq_get_get? [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {a : α} {h'} :
t.get a h' = (t.get? a).get ((mem_iff_isSome_get? h).mp h') := by
simp only [get?_eq_some_get h h', Option.get_some]
@[grind =] theorem get_get? [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {a : α} {h'} :
(t.get? a).get h' = t.get a ((mem_iff_isSome_get? h).mpr h') :=
(get_eq_get_get? h).symm
namespace Const
variable {β : Type v} {t : Raw α β cmp}
@ -381,10 +389,18 @@ theorem get_erase [TransCmp cmp] (h : t.WF) {k a : α} {h'} :
get (t.erase k) a h' = get t a (mem_of_mem_erase h h') :=
Impl.Const.get_erase! h
theorem get?_eq_some_get [TransCmp cmp] (h : t.WF) {a : α} {h'} :
theorem get?_eq_some_get [TransCmp cmp] (h : t.WF) {a : α} (h') :
get? t a = some (get t a h') :=
Impl.Const.get?_eq_some_get h
theorem get_eq_get_get? [TransCmp cmp] (h : t.WF) {a : α} {h'} :
get t a h' = (get? t a).get ((mem_iff_isSome_get? h).mp h') := by
simp only [get?_eq_some_get h h', Option.get_some]
@[grind =] theorem get_get? [TransCmp cmp] (h : t.WF) {a : α} {h'} :
(get? t a).get h' = get t a ((mem_iff_isSome_get? h).mpr h') :=
(get_eq_get_get? h).symm
theorem get_eq_get [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {a : α} {h'} :
get t a h' = t.get a h' :=
Impl.Const.get_eq_get h
@ -677,6 +693,10 @@ theorem isSome_getKey?_iff_mem [TransCmp cmp] (h : t.WF) {a : α} :
(t.getKey? a).isSome ↔ a ∈ t :=
(mem_iff_isSome_getKey? h).symm
theorem mem_of_getKey?_eq_some [TransCmp cmp] (h : t.WF) {k k' : α} :
t.getKey? k = some k' → k' ∈ t :=
Impl.mem_of_getKey?_eq_some h
theorem getKey?_eq_none_of_contains_eq_false [TransCmp cmp] (h : t.WF) {a : α} :
t.contains a = false → t.getKey? a = none :=
Impl.getKey?_eq_none_of_contains_eq_false h
@ -729,10 +749,19 @@ theorem getKey_erase [TransCmp cmp] (h : t.WF) {k a : α} {h'} :
(t.erase k).getKey a h' = t.getKey a (mem_of_mem_erase h h') :=
Impl.getKey_erase! h
theorem getKey?_eq_some_getKey [TransCmp cmp] (h : t.WF) {a : α} {h'} :
theorem getKey?_eq_some_getKey [TransCmp cmp] (h : t.WF) {a : α} (h') :
t.getKey? a = some (t.getKey a h') :=
Impl.getKey?_eq_some_getKey h
theorem getKey_eq_get_getKey? [TransCmp cmp] (h : t.WF) {a : α} {h'} :
t.getKey a h' = (t.getKey? a).get ((mem_iff_isSome_getKey? h).mp h') := by
simp only [getKey?_eq_some_getKey h h', Option.get_some]
@[simp, grind =]
theorem get_getKey? [TransCmp cmp] (h : t.WF) {a : α} {h'} :
(t.getKey? a).get h' = t.getKey a ((mem_iff_isSome_getKey? h).mpr h') :=
(getKey_eq_get_getKey? h).symm
theorem compare_getKey_self [TransCmp cmp] (h : t.WF) {k : α} (h' : k ∈ t) :
cmp (t.getKey k h') k = .eq :=
Impl.compare_getKey_self h h'
@ -1060,6 +1089,10 @@ theorem mem_keys [LawfulEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.keys ↔ k ∈ t :=
Impl.mem_keys h
theorem mem_of_mem_keys [TransCmp cmp] (h : t.WF) {k : α}
(h' : k ∈ t.keys) : k ∈ t :=
Impl.mem_of_mem_keys h h'
theorem distinct_keys [TransCmp cmp] (h : t.WF) :
t.keys.Pairwise (fun a b => ¬ cmp a b = .eq) :=
Impl.distinct_keys h.out
@ -4251,7 +4284,7 @@ theorem map (h : t₁ ~m t₂) (f : (a : α) → β a → γ a) :
t₁.map f ~m t₂.map f :=
⟨h.1.map⟩
theorem filterMap (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (f : (a : α) → β a → Option (γ a)) :
theorem filterMap (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (f : (a : α) → β a → Option (γ a)) :
t₁.filterMap f ~m t₂.filterMap f :=
⟨h.1.filterMap! h₁.1 h₂.1⟩
@ -4507,4 +4540,772 @@ end Const
end Equiv
section filterMap
theorem toList_filterMap {f : (a : α) → β a → Option (γ a)} (h : t.WF) :
(t.filterMap f).toList =
t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) :=
Impl.toList_filterMap! h
@[grind =]
theorem isEmpty_filterMap_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} (h : t.WF) :
(t.filterMap f).isEmpty = true ↔
∀ (k : α) (h : k ∈ t), f k (t.get k h) = none :=
Impl.isEmpty_filterMap!_iff h
theorem isEmpty_filterMap_eq_false_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} (h : t.WF) :
(t.filterMap f).isEmpty = false ↔
∃ (k : α) (h : k ∈ t), (f k (t.get k h)).isSome :=
Impl.isEmpty_filterMap!_eq_false_iff h
@[grind =]
theorem contains_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} (h : t.WF) :
(t.filterMap f).contains k = (t.get? k).any (f k · |>.isSome) :=
Impl.contains_filterMap! h
@[grind =]
theorem mem_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} (h : t.WF) :
k ∈ t.filterMap f ↔ ∃ h, (f k (t.get k h)).isSome := by
simp only [mem_iff_contains, contains_filterMap, Option.any_eq_true_iff_get,
← contains_eq_isSome_get?, get_get?, h]
theorem contains_of_contains_filterMap [TransCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} (h : t.WF) :
(t.filterMap f).contains k = true → t.contains k = true :=
Impl.contains_of_contains_filterMap! h
theorem mem_of_mem_filterMap [TransCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} (h : t.WF) :
k ∈ t.filterMap f → k ∈ t :=
contains_of_contains_filterMap h
theorem size_filterMap_le_size [TransCmp cmp]
{f : (a : α) → β a → Option (γ a)} (h : t.WF) :
(t.filterMap f).size ≤ t.size :=
Impl.size_filterMap!_le_size h
grind_pattern size_filterMap_le_size => (t.filterMap f).size
theorem size_filterMap_eq_size_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} (h : t.WF) :
(t.filterMap f).size = t.size ↔ ∀ (a : α) (h : a ∈ t), (f a (t.get a h)).isSome :=
Impl.size_filterMap!_eq_size_iff h
@[simp, grind =]
theorem get?_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} (h : t.WF) :
(t.filterMap f).get? k = (t.get? k).bind (f k) :=
Impl.get?_filterMap! h
theorem isSome_apply_of_mem_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} (h : t.WF) :
∀ (h' : k ∈ t.filterMap f),
(f k (t.get k (mem_of_mem_filterMap h h'))).isSome :=
Impl.isSome_apply_of_contains_filterMap! h
@[simp, grind =]
theorem get_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} {h'} (h : t.WF) :
(t.filterMap f).get k h' =
(f k (t.get k (mem_of_mem_filterMap h h'))).get
(isSome_apply_of_mem_filterMap h h') :=
Impl.get_filterMap! h
@[grind =]
theorem get!_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} [Inhabited (γ k)] (h : t.WF) :
(t.filterMap f).get! k = ((t.get? k).bind (f k)).get! :=
Impl.get!_filterMap! h
@[grind =]
theorem getD_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} {fallback : γ k} (h : t.WF) :
(t.filterMap f).getD k fallback = ((t.get? k).bind (f k)).getD fallback :=
Impl.getD_filterMap! h
@[grind =]
theorem getKey?_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} (h : t.WF) :
(t.filterMap f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
(f x (t.get x (mem_of_getKey?_eq_some h h'))).isSome) :=
Impl.getKey?_filterMap! h
@[simp, grind =]
theorem getKey_filterMap [TransCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} {h'} (h : t.WF) :
(t.filterMap f).getKey k h' = t.getKey k (mem_of_mem_filterMap h h') :=
Impl.getKey_filterMap! h
@[grind =]
theorem getKey!_filterMap [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α]
{f : (a : α) → β a → Option (γ a)} {k : α} (h : t.WF) :
(t.filterMap f).getKey! k =
((t.getKey? k).pfilter (fun x h' =>
(f x (t.get x (mem_of_getKey?_eq_some h h'))).isSome)).get! :=
Impl.getKey!_filterMap! h
@[grind =]
theorem getKeyD_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k fallback : α} (h : t.WF) :
(t.filterMap f).getKeyD k fallback =
((t.getKey? k).pfilter (fun x h' =>
(f x (t.get x (mem_of_getKey?_eq_some h h'))).isSome)).getD fallback :=
Impl.getKeyD_filterMap! h
namespace Const
variable {β : Type v} {γ : Type w} {t : Raw α (fun _ => β) cmp}
@[grind =]
theorem isEmpty_filterMap_iff [TransCmp cmp]
{f : α → β → Option γ} (h : t.WF) :
(t.filterMap f).isEmpty = true ↔
∀ (k : α) (h : k ∈ t), f (t.getKey k h) (Const.get t k h) = none :=
Impl.Const.isEmpty_filterMap!_iff h
theorem isEmpty_filterMap_eq_false_iff [TransCmp cmp]
{f : α → β → Option γ} (h : t.WF) :
(t.filterMap f).isEmpty = false ↔
∃ (k : α) (h : k ∈ t), (f (t.getKey k h) (Const.get t k h)).isSome :=
Impl.Const.isEmpty_filterMap!_eq_false_iff h
-- TODO: `contains_filterMap` is missing
@[grind =]
theorem mem_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} (h : t.WF) :
k ∈ t.filterMap f ↔ ∃ h, (f (t.getKey k h) (Const.get t k h)).isSome :=
Impl.Const.contains_filterMap!_iff h
theorem size_filterMap_eq_size_iff [TransCmp cmp]
{f : α → β → Option γ} (h : t.WF) :
(t.filterMap f).size = t.size ↔ ∀ k h, (f (t.getKey k h) (Const.get t k h)).isSome :=
Impl.Const.size_filterMap!_eq_size_iff h
-- TODO: `size_filterMap_le_size` is missing
theorem get?_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} (h : t.WF) :
Const.get? (t.filterMap f) k = (Const.get? t k).pbind (fun x h' =>
f (t.getKey k ((mem_iff_isSome_get? h).mpr (Option.isSome_of_eq_some h'))) x) :=
Impl.Const.get?_filterMap! h
/-- Simpler variant of `get?_filterMap` when `LawfulEqCmp` is available. -/
@[simp, grind =]
theorem get?_filterMap' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Option γ} {k : α} (h : t.WF) :
Const.get? (t.filterMap f) k = (Const.get? t k).bind (f k) := by
simp [get?_filterMap, h]
theorem get?_filterMap_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Option γ} {k k' : α} (h : t.WF) :
t.getKey? k = some k' → Const.get? (t.filterMap f) k = (Const.get? t k).bind (f k') :=
Impl.Const.get?_filterMap!_of_getKey?_eq_some h
theorem isSome_apply_of_mem_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} (h : t.WF) :
∀ (h' : k ∈ t.filterMap f),
(f (t.getKey k (mem_of_mem_filterMap h h'))
(Const.get t k (mem_of_mem_filterMap h h'))).isSome :=
Impl.Const.isSome_apply_of_contains_filterMap! h
@[simp, grind =]
theorem get_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} {h'} (h : t.WF) :
Const.get (t.filterMap f) k h' =
(f (t.getKey k (mem_of_mem_filterMap h h'))
(Const.get t k (mem_of_mem_filterMap h h'))).get
(isSome_apply_of_mem_filterMap h h') :=
Impl.Const.get_filterMap! h
theorem get!_filterMap [TransCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k : α} (h : t.WF) :
Const.get! (t.filterMap f) k =
((Const.get? t k).pbind (fun x h' =>
f (t.getKey k ((mem_iff_isSome_get? h).mpr (Option.isSome_of_eq_some h')))
x)).get! :=
Impl.Const.get!_filterMap! h
/-- Simpler variant of `get!_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem get!_filterMap' [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k : α} (h : t.WF) :
Const.get! (t.filterMap f) k = ((Const.get? t k).bind (f k)).get! := by
simp [get!_filterMap, h]
theorem get!_filterMap_of_getKey?_eq_some [TransCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k k' : α} (h : t.WF) :
t.getKey? k = some k' → Const.get! (t.filterMap f) k = ((Const.get? t k).bind
fun x => f k' x).get! :=
Impl.Const.get!_filterMap!_of_getKey?_eq_some h
theorem getD_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} {fallback : γ} (h : t.WF) :
Const.getD (t.filterMap f) k fallback =
((Const.get? t k).pbind (fun x h' =>
f (t.getKey k ((mem_iff_isSome_get? h).mpr (Option.isSome_of_eq_some h'))) x)).getD fallback :=
Impl.Const.getD_filterMap! h
/-- Simpler variant of `getD_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getD_filterMap' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Option γ} {k : α} {fallback : γ} (h : t.WF) :
Const.getD (t.filterMap f) k fallback = ((Const.get? t k).bind (f k)).getD fallback := by
simp [getD_filterMap, h]
theorem getD_filterMap_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Option γ} {k k' : α} {fallback : γ} (h : t.WF) :
t.getKey? k = some k' → Const.getD (t.filterMap f) k fallback = ((Const.get? t k).bind
fun x => f k' x).getD fallback :=
Impl.Const.getD_filterMap!_of_getKey?_eq_some h
theorem toList_filterMap
{f : α → β → Option γ} (h : t.WF) :
Const.toList (t.filterMap f) =
(Const.toList t).filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x))) :=
Impl.Const.toList_filterMap! h
@[grind =]
theorem getKey?_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} (h : t.WF) :
(t.filterMap f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
(f x (Const.get t x (mem_of_getKey?_eq_some h h'))).isSome) :=
Impl.Const.getKey?_filterMap! h
@[simp, grind =]
theorem getKey_filterMap [TransCmp cmp]
{f : (a : α) → β → Option γ} {k : α} {h'} (h : t.WF) :
(t.filterMap f).getKey k h' = t.getKey k (mem_of_mem_filterMap h h') :=
Impl.getKey_filterMap! h
@[grind =]
theorem getKey!_filterMap [TransCmp cmp] [Inhabited α]
{f : α → β → Option γ} {k : α} (h : t.WF) :
(t.filterMap f).getKey! k =
((t.getKey? k).pfilter (fun x h' =>
(f x (Const.get t x (mem_of_getKey?_eq_some h h'))).isSome)).get! :=
Impl.Const.getKey!_filterMap! h
@[grind =]
theorem getKeyD_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k fallback : α} (h : t.WF) :
(t.filterMap f).getKeyD k fallback =
((t.getKey? k).pfilter (fun x h' =>
(f x (Const.get t x (mem_of_getKey?_eq_some h h'))).isSome)).getD fallback :=
Impl.Const.getKeyD_filterMap! h
end Const
end filterMap
section filter
theorem filterMap_equiv_filter {f : (a : α) → β a → Bool} (h : t.WF) :
t.filterMap (fun k => Option.guard (fun v => f k v)) ~m t.filter f :=
⟨Impl.filterMap!_equiv_filter! h⟩
theorem toList_filter {f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter f).toList = t.toList.filter (fun p => f p.1 p.2) :=
Impl.toList_filter! h
theorem keys_filter_key {f : α → Bool} (h : t.WF) :
(t.filter fun k _ => f k).keys = t.keys.filter f :=
Impl.keys_filter!_key h
@[grind =]
theorem isEmpty_filter_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter f).isEmpty = true ↔
∀ (k : α) (h : k ∈ t), f k (t.get k h) = false :=
Impl.isEmpty_filter!_iff h
theorem isEmpty_filter_eq_false_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter f).isEmpty = false ↔
∃ (k : α) (h : k ∈ t), f k (t.get k h) = true :=
Impl.isEmpty_filter!_eq_false_iff h
theorem isEmpty_filter_key_iff [TransCmp cmp]
{f : α → Bool} (h : t.WF) :
(t.filter (fun a _ => f a)).isEmpty ↔
∀ (k : α) (h : k ∈ t), f (t.getKey k h) = false :=
Impl.isEmpty_filter!_key_iff h
theorem isEmpty_filter_key_eq_false_iff [TransCmp cmp]
{f : α → Bool} (h : t.WF) :
(t.filter (fun a _ => f a)).isEmpty = false ↔
∃ (k : α) (h : k ∈ t), f (t.getKey k h) :=
Impl.isEmpty_filter!_key_eq_false_iff h
@[grind =]
theorem contains_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} (h : t.WF) :
(t.filter f).contains k = (t.get? k).any (f k) :=
Impl.contains_filter! h
@[grind =]
theorem mem_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} (h : t.WF) :
k ∈ t.filter f ↔ (t.get? k).any (f k) := by
simpa only [mem_iff_contains, Bool.coe_iff_coe] using contains_filter h
theorem mem_filter_key [TransCmp cmp]
{f : α → Bool} {k : α} (h : t.WF) :
k ∈ (t.filter (fun a _ => f a)) ↔ ∃ h : k ∈ t, f (t.getKey k h) :=
Impl.contains_filter!_key_iff h
theorem contains_of_contains_filter [TransCmp cmp]
{f : (a : α) → β a → Bool} {k : α} (h : t.WF) :
(t.filter f).contains k = true → t.contains k = true :=
Impl.contains_of_contains_filter! h
theorem mem_of_mem_filter [TransCmp cmp]
{f : (a : α) → β a → Bool} {k : α} (h : t.WF) :
k ∈ t.filter f → k ∈ t :=
Impl.contains_of_contains_filter! h
theorem size_filter_le_size [TransCmp cmp]
{f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter f).size ≤ t.size :=
Impl.size_filter!_le_size h
grind_pattern size_filter_le_size => (t.filter f).size
theorem size_filter_eq_size_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter f).size = t.size ↔ ∀ k h, f k (t.get k h) = true :=
Impl.size_filter!_eq_size_iff h
theorem filter_equiv_self_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} (h : t.WF) :
t.filter f ~m t ↔ ∀ k h, f k (t.get k h) = true :=
equiv_iff.trans (Impl.filter!_equiv_self_iff h)
theorem filter_key_equiv_self_iff [TransCmp cmp]
{f : (a : α) → Bool} (h : t.WF) :
t.filter (fun k _ => f k) ~m t ↔ ∀ k h, f (t.getKey k h) = true :=
equiv_iff.trans (Impl.filter!_key_equiv_self_iff h)
theorem size_filter_key_eq_size_iff [TransCmp cmp]
{f : α → Bool} (h : t.WF) :
(t.filter fun k _ => f k).size = t.size ↔ ∀ (k : α) (h : k ∈ t), f (t.getKey k h) :=
Impl.size_filter!_key_eq_size_iff h
@[simp, grind =]
theorem get?_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} (h : t.WF) :
(t.filter f).get? k = (t.get? k).filter (f k) :=
Impl.get?_filter! h
@[simp, grind =]
theorem get_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} {h'} (h : t.WF) :
(t.filter f).get k h' = t.get k (mem_of_mem_filter h h') :=
Impl.get_filter! h
@[grind =]
theorem get!_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} [Inhabited (β k)] (h : t.WF) :
(t.filter f).get! k = ((t.get? k).filter (f k)).get! :=
Impl.get!_filter! h
@[grind =]
theorem getD_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} {fallback : β k} (h : t.WF) :
(t.filter f).getD k fallback = ((t.get? k).filter (f k)).getD fallback :=
Impl.getD_filter! h
theorem keys_filter [TransCmp cmp] [LawfulEqCmp cmp] {f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter f).keys =
(t.keys.attach.filter (fun ⟨x, h'⟩ => f x (t.get x (mem_of_mem_keys h h')))).unattach :=
Impl.keys_filter! h
@[grind =]
theorem getKey?_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} (h : t.WF) :
(t.filter f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
f x (t.get x (mem_of_getKey?_eq_some h h'))) :=
Impl.getKey?_filter! h
theorem getKey?_filter_key [TransCmp cmp]
{f : α → Bool} {k : α} (h : t.WF) :
(t.filter fun k _ => f k).getKey? k = (t.getKey? k).filter f :=
Impl.getKey?_filter!_key h
@[simp, grind =]
theorem getKey_filter [TransCmp cmp]
{f : (a : α) → β a → Bool} {k : α} {h'} (h : t.WF) :
(t.filter f).getKey k h' = t.getKey k (mem_of_mem_filter h h') :=
Impl.getKey_filter! h
@[grind =]
theorem getKey!_filter [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α]
{f : (a : α) → β a → Bool} {k : α} (h : t.WF) :
(t.filter f).getKey! k =
((t.getKey? k).pfilter (fun x h' =>
f x (t.get x (mem_of_getKey?_eq_some h h')))).get! :=
Impl.getKey!_filter! h
theorem getKey!_filter_key [TransCmp cmp] [Inhabited α]
{f : α → Bool} {k : α} (h : t.WF) :
(t.filter fun k _ => f k).getKey! k = ((t.getKey? k).filter f).get! :=
Impl.getKey!_filter!_key h
@[grind =]
theorem getKeyD_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k fallback : α} (h : t.WF) :
(t.filter f).getKeyD k fallback =
((t.getKey? k).pfilter (fun x h' =>
f x (t.get x (mem_of_getKey?_eq_some h h')))).getD fallback :=
Impl.getKeyD_filter! h
theorem getKeyD_filter_key [TransCmp cmp]
{f : α → Bool} {k fallback : α} (h : t.WF) :
(t.filter fun k _ => f k).getKeyD k fallback = ((t.getKey? k).filter f).getD fallback :=
Impl.getKeyD_filter!_key h
namespace Const
variable {β : Type v} {γ : Type w} {t : Raw α (fun _ => β) cmp}
@[grind =]
theorem isEmpty_filter_iff [TransCmp cmp]
{f : α → β → Bool} (h : t.WF) :
(t.filter f).isEmpty = true ↔
∀ (k : α) (h : k ∈ t), f (t.getKey k h) (Const.get t k h) = false :=
Impl.Const.isEmpty_filter!_iff h
theorem isEmpty_filter_eq_false_iff [TransCmp cmp]
{f : α → β → Bool} (h : t.WF) :
(t.filter f).isEmpty = false ↔
∃ (k : α) (h : k ∈ t), (f (t.getKey k h) (Const.get t k h)) = true :=
Impl.Const.isEmpty_filter!_eq_false_iff h
-- TODO: `contains_filter` is missing
@[grind =]
theorem mem_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} (h : t.WF) :
k ∈ t.filter f ↔ ∃ (h' : k ∈ t),
f (t.getKey k h') (Const.get t k h') :=
Impl.Const.contains_filter!_iff h
theorem size_filter_le_size [TransCmp cmp]
{f : α → β → Bool} (h : t.WF) :
(t.filter f).size ≤ t.size :=
Impl.Const.size_filter!_le_size h
grind_pattern size_filter_le_size => (t.filter f).size
theorem size_filter_eq_size_iff [TransCmp cmp]
{f : α → β → Bool} (h : t.WF) :
(t.filter f).size = t.size ↔ ∀ (a : α) (h : a ∈ t),
f (t.getKey a h) (Const.get t a h) :=
Impl.Const.size_filter!_eq_size_iff h
theorem filter_equiv_self_iff [TransCmp cmp]
{f : α → β → Bool} (h : t.WF) :
t.filter f ~m t ↔ ∀ (a : α) (h : a ∈ t),
f (t.getKey a h) (Const.get t a h) :=
equiv_iff.trans (Impl.Const.filter!_equiv_self_iff h)
@[simp]
theorem get?_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} (h : t.WF) :
Const.get? (t.filter f) k = (Const.get? t k).pfilter (fun x h' =>
f (t.getKey k ((mem_iff_isSome_get? h).mpr (Option.isSome_of_eq_some h'))) x) :=
Impl.Const.get?_filter! h
/-- Simpler variant of `get?_filter` when `LawfulEqCmp` is available. -/
@[grind =]
theorem get?_filter' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Bool} {k : α} (h : t.WF) :
Const.get? (t.filter f) k = (Const.get? t k).filter (f k) := by
simp [get?_filter, h]
theorem get?_filter_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Bool} {k k' : α} (h : t.WF) :
t.getKey? k = some k' →
Const.get? (t.filter f) k = (Const.get? t k).filter (fun x => f k' x) :=
Impl.Const.get?_filter!_of_getKey?_eq_some h
@[simp, grind =]
theorem get_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} {h'} (h : t.WF) :
Const.get (t.filter f) k h' = Const.get t k (mem_of_mem_filter h h') :=
Impl.Const.get_filter! h
theorem get!_filter [TransCmp cmp] [Inhabited β]
{f : α → β → Bool} {k : α} (h : t.WF) :
Const.get! (t.filter f) k =
((Const.get? t k).pfilter (fun x h' =>
f (t.getKey k ((mem_iff_isSome_get? h).mpr (Option.isSome_of_eq_some h'))) x)).get! :=
Impl.Const.get!_filter! h
/-- Simpler variant of `get!_filter` when `LawfulEqCmp` is available. -/
@[grind =]
theorem get!_filter' [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited β]
{f : α → β → Bool} {k : α} (h : t.WF) :
Const.get! (t.filter f) k = ((Const.get? t k).filter (f k)).get! := by
simp [get!_filter, h]
theorem get!_filter_of_getKey?_eq_some [TransCmp cmp] [Inhabited β]
{f : α → β → Bool} {k k' : α} (h : t.WF) :
t.getKey? k = some k' →
Const.get! (t.filter f) k = ((Const.get? t k).filter (fun x => f k' x)).get! :=
Impl.Const.get!_filter!_of_getKey?_eq_some h
theorem getD_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} {fallback : β} (h : t.WF) :
Const.getD (t.filter f) k fallback = ((Const.get? t k).pfilter (fun x h' =>
f (t.getKey k ((mem_iff_isSome_get? h).mpr (Option.isSome_of_eq_some h'))) x)).getD fallback :=
Impl.Const.getD_filter! h
/-- Simpler variant of `getD_filter` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getD_filter' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Bool} {k : α} {fallback : β} (h : t.WF) :
Const.getD (t.filter f) k fallback = ((Const.get? t k).filter (f k)).getD fallback := by
simp [getD_filter, h]
theorem getD_filter_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Bool} {k k' : α} {fallback : β} (h : t.WF) :
t.getKey? k = some k' →
Const.getD (t.filter f) k fallback =
((Const.get? t k).filter (fun x => f k' x)).getD fallback :=
Impl.Const.getD_filter!_of_getKey?_eq_some h
theorem toList_filter {f : α → β → Bool} (h : t.WF) :
Const.toList (t.filter f) =
(Const.toList t).filter (fun p => f p.1 p.2) :=
Impl.Const.toList_filter! h
theorem keys_filter [TransCmp cmp] {f : α → β → Bool} (h : t.WF) :
(t.filter f).keys =
(t.keys.attach.filter (fun ⟨x, h'⟩ => f x (get t x (mem_of_mem_keys h h')))).unattach :=
Impl.Const.keys_filter! h
@[grind =]
theorem getKey?_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} (h : t.WF) :
(t.filter f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
(f x (Const.get t x (mem_of_getKey?_eq_some h h')))) :=
Impl.Const.getKey?_filter! h
@[grind =]
theorem getKey!_filter [TransCmp cmp] [Inhabited α]
{f : α → β → Bool} {k : α} (h : t.WF) :
(t.filter f).getKey! k =
((t.getKey? k).pfilter (fun x h' =>
(f x (Const.get t x (mem_of_getKey?_eq_some h h'))))).get! :=
Impl.Const.getKey!_filter! h
@[grind =]
theorem getKeyD_filter [TransCmp cmp]
{f : α → β → Bool} {k fallback : α} (h : t.WF) :
(t.filter f).getKeyD k fallback =
((t.getKey? k).pfilter (fun x h' =>
(f x (Const.get t x (mem_of_getKey?_eq_some h h'))))).getD fallback :=
Impl.Const.getKeyD_filter! h
end Const
end filter
section map
variable {γ : α → Type w} {δ : α → Type w'}
theorem map_id_equiv : t.map (fun _ v => v) ~m t :=
⟨Impl.map_id_equiv⟩
theorem map_map_equiv {f : (a : α) → β a → γ a} {g : (a : α) → γ a → δ a} :
(t.map f).map g ~m t.map fun k v => g k (f k v) :=
⟨Impl.map_map_equiv⟩
theorem toList_map {f : (a : α) → β a → γ a} :
(t.map f).toList = t.toList.map (fun p => ⟨p.1, f p.1 p.2⟩) :=
Impl.toList_map
theorem keys_map {f : (a : α) → β a → γ a} : (t.map f).keys = t.keys :=
Impl.keys_map
theorem filterMap_equiv_map [TransCmp cmp]
{f : (a : α) → β a → γ a} (h : t.WF) :
(t.filterMap (fun k v => some (f k v))) ~m t.map f :=
⟨Impl.filterMap!_equiv_map h⟩
@[simp, grind =]
theorem isEmpty_map [TransCmp cmp] {f : (a : α) → β a → γ a} :
(t.map f).isEmpty = t.isEmpty :=
Impl.isEmpty_map
@[grind =]
theorem contains_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} (h : t.WF) :
(t.map f).contains k = t.contains k :=
Impl.contains_map h
theorem contains_of_contains_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} (h : t.WF) :
(t.map f).contains k = true → t.contains k = true :=
Impl.contains_of_contains_map h
@[simp, grind =]
theorem mem_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} (h : t.WF) :
k ∈ (t.map f) ↔ k ∈ t := by
simpa only [mem_iff_contains, Bool.coe_iff_coe] using Impl.contains_map h
theorem mem_of_mem_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} (h : t.WF) :
k ∈ (t.map f) → k ∈ t :=
Impl.contains_of_contains_map h
@[simp, grind =]
theorem size_map [TransCmp cmp] {f : (a : α) → β a → γ a} :
(t.map f).size = t.size :=
Impl.size_map
@[simp, grind =]
theorem get?_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → γ a} {k : α} (h : t.WF) :
(t.map f).get? k = (t.get? k).map (f k) :=
Impl.get?_map h
@[simp, grind =]
theorem get_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → γ a} {k : α} {h'} (h : t.WF) :
(t.map f).get k h' = f k (t.get k (mem_of_mem_map h h')) :=
Impl.get_map h
@[grind =]
theorem get!_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → γ a} {k : α} [Inhabited (γ k)] (h : t.WF) :
(t.map f).get! k = ((t.get? k).map (f k)).get! :=
Impl.get!_map h
@[grind =]
theorem getD_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → γ a} {k : α} {fallback : γ k} (h : t.WF) :
(t.map f).getD k fallback = ((t.get? k).map (f k)).getD fallback :=
Impl.getD_map h
@[simp, grind =]
theorem getKey?_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} (h : t.WF) :
(t.map f).getKey? k = t.getKey? k :=
Impl.getKey?_map h
@[simp, grind =]
theorem getKey_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} {h'} (h : t.WF) :
(t.map f).getKey k h' = t.getKey k (mem_of_mem_map h h') :=
Impl.getKey_map h
@[simp, grind =]
theorem getKey!_map [TransCmp cmp] [Inhabited α]
{f : (a : α) → β a → γ a} {k : α} (h : t.WF) :
(t.map f).getKey! k = t.getKey! k :=
Impl.getKey!_map h
@[simp, grind =]
theorem getKeyD_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k fallback : α} (h : t.WF) :
(t.map f).getKeyD k fallback = t.getKeyD k fallback :=
Impl.getKeyD_map h
namespace Const
variable {β : Type v} {γ : Type w} {t : Raw α (fun _ => β) cmp}
/-- Variant of `get?_map` that holds without `LawfulEqCmp`. -/
@[simp (low)]
theorem get?_map' [TransCmp cmp]
{f : α → β → γ} {k : α} (h : t.WF) :
Const.get? (t.map f) k = (Const.get? t k).pmap (fun v h' => f (t.getKey k h') v)
(fun _ h' => (mem_iff_isSome_get? h).mpr (Option.isSome_of_eq_some h')) :=
Impl.Const.get?_map' h
@[simp, grind =]
theorem get?_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} (h : t.WF) :
Const.get? (t.map f) k = (Const.get? t k).map (f k) := by
simp [get?_map' h, getKey_eq h]
theorem get?_map_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → γ} {k k' : α} (h : t.WF) :
t.getKey? k = some k' → Const.get? (t.map f) k = (Const.get? t k).map (f k') :=
Impl.Const.get?_map_of_getKey?_eq_some h
/-- Variant of `get_map` that holds without `LawfulEqCmp`. -/
@[simp (low)]
theorem get_map' [TransCmp cmp]
{f : α → β → γ} {k : α} {h'} (h : t.WF) :
Const.get (t.map f) k h' =
(f (t.getKey k (mem_of_mem_map h h'))
(Const.get t k (mem_of_mem_map h h'))) :=
Impl.Const.get_map' h
@[simp, grind =]
theorem get_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} (h : t.WF) {h'} :
Const.get (t.map f) k h' = f k (Const.get t k (mem_of_mem_map h h')) := by
simp [get_map' h, getKey_eq h]
/-- Variant of `get!_map` that holds without `LawfulEqCmp`. -/
theorem get!_map' [TransCmp cmp] [Inhabited γ]
{f : α → β → γ} {k : α} (h : t.WF) :
Const.get! (t.map f) k =
((get? t k).pmap (fun v h => f (t.getKey k h) v)
(fun _ h' => (mem_iff_isSome_get? h).mpr (Option.isSome_of_eq_some h'))).get! :=
Impl.Const.get!_map' h
@[grind =]
theorem get!_map [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited γ]
{f : α → β → γ} {k : α} (h : t.WF) :
Const.get! (t.map f) k = ((Const.get? t k).map (f k)).get! := by
simp [get!_map' h, getKey_eq h]
theorem get!_map_of_getKey?_eq_some [TransCmp cmp] [Inhabited γ]
{f : α → β → γ} {k k' : α} (h : t.WF) :
t.getKey? k = some k' → Const.get! (t.map f) k = ((Const.get? t k).map (f k')).get! :=
Impl.Const.get!_map_of_getKey?_eq_some h
/-- Variant of `getD_map` that holds without `LawfulEqCmp`. -/
theorem getD_map' [TransCmp cmp]
{f : α → β → γ} {k : α} {fallback : γ} (h : t.WF) :
Const.getD (t.map f) k fallback =
((get? t k).pmap (fun v h => f (t.getKey k h) v)
(fun _ h' => (mem_iff_isSome_get? h).mpr (Option.isSome_of_eq_some h'))).getD fallback :=
Impl.Const.getD_map' h
@[grind =]
theorem getD_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} {fallback : γ} (h : t.WF) :
Const.getD (t.map f) k fallback = ((Const.get? t k).map (f k)).getD fallback := by
simp [getD_map' h, getKey_eq h]
theorem getD_map_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → γ} {k k' : α} {fallback : γ} (h : t.WF) :
t.getKey? k = some k' → Const.getD (t.map f) k fallback = ((Const.get? t k).map (f k')).getD fallback :=
Impl.Const.getD_map_of_getKey?_eq_some h
theorem toList_map {f : α → β → γ} :
Const.toList (t.map f) =
(Const.toList t).map (fun p => (p.1, f p.1 p.2)) :=
Impl.Const.toList_map
end Const
end map
end Std.DTreeMap.Raw

View file

@ -2952,7 +2952,7 @@ theorem get?_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `get?_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem get?_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem get?_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} :
Const.get? (m.filterMap f) k = (Const.get? m k).bind (f k) := by
simp [get?_filterMap]
@ -2980,7 +2980,7 @@ theorem get_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `get_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem get_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem get_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} {h} :
Const.get (m.filterMap f) k h = (f k (Const.get m k (mem_of_mem_filterMap h))).get (by simpa using isSome_apply_of_mem_filterMap h) := by
simp [get_filterMap]
@ -2994,7 +2994,7 @@ theorem get!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited γ]
/-- Simpler variant of `get!_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem get!_filterMap' [LawfulBEq α] [LawfulHashable α] [Inhabited γ]
theorem get!_filterMap' [LawfulBEq α] [Inhabited γ]
{f : α → β → Option γ} {k : α} :
Const.get! (m.filterMap f) k = ((Const.get? m k).bind (f k)).get! := by
simp [get!_filterMap]
@ -3013,7 +3013,7 @@ theorem getD_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getD_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem getD_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem getD_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} {fallback : γ} :
Const.getD (m.filterMap f) k fallback = ((Const.get? m k).bind (f k)).getD fallback := by
simp [getD_filterMap]
@ -3057,7 +3057,6 @@ theorem filterMap_eq_filter [EquivBEq α] [LawfulHashable α] {f : (a : α) →
m.filterMap (fun k => Option.guard (fun v => f k v)) = m.filter f :=
m.inductionOn fun _ => sound DHashMap.filterMap_equiv_filter
@[simp]
theorem filter_eq_empty_iff [LawfulBEq α]
{f : (a : α) → β a → Bool} :
m.filter f = ∅ ↔ ∀ k h, f k (m.get k h) = false :=
@ -3217,7 +3216,7 @@ theorem get?_filter [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `get?_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem get?_filter' [LawfulBEq α] [LawfulHashable α]
theorem get?_filter' [LawfulBEq α]
{f : α → β → Bool} {k : α} :
Const.get? (m.filter f) k = (Const.get? m k).filter (f k) := by
simp [get?_filter]
@ -3243,7 +3242,7 @@ theorem get!_filter [EquivBEq α] [LawfulHashable α] [Inhabited β]
/-- Simpler variant of `get!_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem get!_filter' [LawfulBEq α] [LawfulHashable α] [Inhabited β]
theorem get!_filter' [LawfulBEq α] [Inhabited β]
{f : α → β → Bool} {k : α} :
Const.get! (m.filter f) k = ((Const.get? m k).filter (f k)).get! := by
simp [get!_filter]
@ -3262,7 +3261,7 @@ theorem getD_filter [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getD_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem getD_filter' [LawfulBEq α] [LawfulHashable α]
theorem getD_filter' [LawfulBEq α]
{f : α → β → Bool} {k : α} {fallback : β} :
Const.getD (m.filter f) k fallback = ((Const.get? m k).filter (f k)).getD fallback := by
simp [getD_filter]
@ -3402,7 +3401,7 @@ namespace Const
variable {β : Type v} {γ : Type w} {m : ExtDHashMap α fun _ => β}
@[simp, grind =]
theorem get?_map [LawfulBEq α] [LawfulHashable α]
theorem get?_map [LawfulBEq α]
{f : α → β → γ} {k : α} :
Const.get? (m.map f) k = (Const.get? m k).map (f k) :=
m.inductionOn fun _ => DHashMap.Const.get?_map
@ -3421,7 +3420,7 @@ theorem get?_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α]
m.inductionOn (fun _ h => DHashMap.Const.get?_map_of_getKey?_eq_some h) h
@[simp, grind =]
theorem get_map [LawfulBEq α] [LawfulHashable α]
theorem get_map [LawfulBEq α]
{f : α → β → γ} {k : α} {h'} :
Const.get (m.map f) k h' = f k (Const.get m k (mem_of_mem_map h')) :=
m.inductionOn (fun _ _ => DHashMap.Const.get_map) h'
@ -3434,7 +3433,7 @@ theorem get_map' [EquivBEq α] [LawfulHashable α]
f (m.getKey k (mem_of_mem_map h')) (Const.get m k (mem_of_mem_map h')) :=
m.inductionOn (fun _ _ => DHashMap.Const.get_map') h'
@[grind =] theorem get!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ]
@[grind =] theorem get!_map [LawfulBEq α] [Inhabited γ]
{f : α → β → γ} {k : α} :
Const.get! (m.map f) k = ((Const.get? m k).map (f k)).get! :=
m.inductionOn fun _ => DHashMap.Const.get!_map
@ -3452,7 +3451,7 @@ theorem get!_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhabited
Const.get! (m.map f) k = ((Const.get? m k).map (f k')).get! :=
m.inductionOn (fun _ h => DHashMap.Const.get!_map_of_getKey?_eq_some h) h
@[grind =] theorem getD_map [LawfulBEq α] [LawfulHashable α]
@[grind =] theorem getD_map [LawfulBEq α]
{f : α → β → γ} {k : α} {fallback : γ} :
Const.getD (m.map f) k fallback = ((Const.get? m k).map (f k)).getD fallback :=
m.inductionOn fun _ => DHashMap.Const.getD_map

View file

@ -334,7 +334,15 @@ theorem get_erase [TransCmp cmp] [LawfulEqCmp cmp] {k a : α} {h'} :
theorem get?_eq_some_get [TransCmp cmp] [LawfulEqCmp cmp] {a : α} (h') :
t.get? a = some (t.get a h') :=
t.inductionOn (fun _ _ => DTreeMap.get?_eq_some_get) h'
t.inductionOn (fun _ => DTreeMap.get?_eq_some_get) h'
theorem get_eq_get_get? [TransCmp cmp] [LawfulEqCmp cmp] {a : α} {h} :
t.get a h = (t.get? a).get (mem_iff_isSome_get?.mp h) :=
t.inductionOn (fun _ _ => DTreeMap.get_eq_get_get?) h
@[grind =] theorem get_get? [TransCmp cmp] [LawfulEqCmp cmp] {a : α} {h} :
(t.get? a).get h = t.get a (mem_iff_isSome_get?.mpr h) :=
t.inductionOn (fun _ _ => DTreeMap.get_get?) h
namespace Const
@ -358,7 +366,15 @@ theorem get_erase [TransCmp cmp] {k a : α} {h'} :
theorem get?_eq_some_get [TransCmp cmp] {a : α} (h) :
get? t a = some (get t a h) :=
t.inductionOn (fun _ _ => DTreeMap.Const.get?_eq_some_get) h
t.inductionOn (fun _ => DTreeMap.Const.get?_eq_some_get) h
theorem get_eq_get_get? [TransCmp cmp] {a : α} {h} :
get t a h = (get? t a).get (mem_iff_isSome_get?.mp h) :=
t.inductionOn (fun _ _ => DTreeMap.Const.get_eq_get_get?) h
@[grind =] theorem get_get? [TransCmp cmp] {a : α} {h} :
(get? t a).get h = get t a (mem_iff_isSome_get?.mpr h) :=
t.inductionOn (fun _ _ => DTreeMap.Const.get_get?) h
theorem get_eq_get [TransCmp cmp] [LawfulEqCmp cmp] {a : α} {h} : get t a h = t.get a h :=
t.inductionOn (fun _ _ => DTreeMap.Const.get_eq_get) h
@ -630,6 +646,10 @@ theorem isSome_getKey?_iff_mem [TransCmp cmp] {a : α} :
(t.getKey? a).isSome ↔ a ∈ t :=
t.inductionOn fun _ => DTreeMap.isSome_getKey?_iff_mem
theorem mem_of_getKey?_eq_some [TransCmp cmp] {k k' : α} :
t.getKey? k = some k' → k' ∈ t :=
t.inductionOn fun _ => DTreeMap.mem_of_getKey?_eq_some
theorem getKey?_eq_none_of_contains_eq_false [TransCmp cmp] {a : α} :
t.contains a = false → t.getKey? a = none :=
t.inductionOn fun _ => DTreeMap.getKey?_eq_none_of_contains_eq_false
@ -683,7 +703,16 @@ theorem getKey_erase [TransCmp cmp] {k a : α} {h'} :
theorem getKey?_eq_some_getKey [TransCmp cmp] {a : α} (h') :
t.getKey? a = some (t.getKey a h') :=
t.inductionOn (fun _ _ => DTreeMap.getKey?_eq_some_getKey) h'
t.inductionOn (fun _ => 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) :=
t.inductionOn (fun _ _ => DTreeMap.getKey_eq_get_getKey?) h
@[simp, grind =]
theorem get_getKey? [TransCmp cmp] {a : α} {h} :
(t.getKey? a).get h = t.getKey a (mem_iff_isSome_getKey?.mpr h) :=
t.inductionOn (fun _ _ => DTreeMap.get_getKey?) h
theorem compare_getKey_self [TransCmp cmp] {k : α} (h' : k ∈ t) :
cmp (t.getKey k h') k = .eq :=
@ -1004,6 +1033,9 @@ theorem mem_keys [LawfulEqCmp cmp] [TransCmp cmp] {k : α} :
k ∈ t.keys ↔ k ∈ t :=
t.inductionOn fun _ => DTreeMap.mem_keys
theorem mem_of_mem_keys [TransCmp cmp] {k : α} (h : k ∈ t.keys) : k ∈ t :=
t.inductionOn (fun _ => DTreeMap.mem_of_mem_keys) h
theorem distinct_keys [TransCmp cmp] :
t.keys.Pairwise (fun a b => ¬ cmp a b = .eq) :=
t.inductionOn fun _ => DTreeMap.distinct_keys
@ -4378,4 +4410,739 @@ end Const
end Ext
section filterMap
variable {γ : α → Type w}
@[simp, grind =]
theorem toList_filterMap [TransCmp cmp] {f : (a : α) → β a → Option (γ a)} :
(t.filterMap f).toList =
t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) :=
t.inductionOn fun _ => DTreeMap.toList_filterMap
theorem filterMap_eq_empty_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} :
t.filterMap f = ∅ ↔ ∀ k h, f k (t.get k h) = none :=
isEmpty_iff.symm.trans <| t.inductionOn fun _ => DTreeMap.isEmpty_filterMap_iff
@[grind =]
theorem contains_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} :
(t.filterMap f).contains k = (t.get? k).any (f k · |>.isSome) :=
t.inductionOn fun _ => DTreeMap.contains_filterMap
@[grind =]
theorem mem_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} :
k ∈ t.filterMap f ↔ ∃ h, (f k (t.get k h)).isSome := by
simp only [mem_iff_contains, contains_filterMap, Option.any_eq_true_iff_get,
← contains_eq_isSome_get?, get_get?]
theorem contains_of_contains_filterMap [TransCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} :
(t.filterMap f).contains k = true → t.contains k = true :=
t.inductionOn fun _ => DTreeMap.contains_of_contains_filterMap
theorem mem_of_mem_filterMap [TransCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} :
k ∈ t.filterMap f → k ∈ t :=
t.inductionOn fun _ => DTreeMap.contains_of_contains_filterMap
theorem size_filterMap_le_size [TransCmp cmp]
{f : (a : α) → β a → Option (γ a)} :
(t.filterMap f).size ≤ t.size :=
t.inductionOn fun _ => DTreeMap.size_filterMap_le_size
grind_pattern size_filterMap_le_size => (t.filterMap f).size
theorem size_filterMap_eq_size_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} :
(t.filterMap f).size = t.size ↔ ∀ (a : α) (h : a ∈ t), (f a (t.get a h)).isSome :=
t.inductionOn fun _ => DTreeMap.size_filterMap_eq_size_iff
@[simp, grind =]
theorem get?_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} :
(t.filterMap f).get? k = (t.get? k).bind (f k) :=
t.inductionOn fun _ => DTreeMap.get?_filterMap
theorem isSome_apply_of_mem_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} :
∀ (h' : k ∈ t.filterMap f),
(f k (t.get k (mem_of_mem_filterMap h'))).isSome :=
t.inductionOn fun _ => DTreeMap.isSome_apply_of_mem_filterMap
@[simp, grind =]
theorem get_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} {h'} :
(t.filterMap f).get k h' =
(f k (t.get k (mem_of_mem_filterMap h'))).get
(isSome_apply_of_mem_filterMap h') :=
t.inductionOn (fun _ _ => DTreeMap.get_filterMap) h'
@[simp, grind =]
theorem get!_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} [Inhabited (γ k)] :
(t.filterMap f).get! k = ((t.get? k).bind (f k)).get! :=
t.inductionOn fun _ => DTreeMap.get!_filterMap
@[simp, grind =]
theorem getD_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} {fallback : γ k} :
(t.filterMap f).getD k fallback = ((t.get? k).bind (f k)).getD fallback :=
t.inductionOn fun _ => DTreeMap.getD_filterMap
@[grind =]
theorem getKey?_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} :
(t.filterMap f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
(f x (t.get x (mem_of_getKey?_eq_some h'))).isSome) :=
t.inductionOn fun _ => DTreeMap.getKey?_filterMap
@[simp, grind =]
theorem getKey_filterMap [TransCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k : α} {h'} :
(t.filterMap f).getKey k h' = t.getKey k (mem_of_mem_filterMap h') :=
t.inductionOn (fun _ _ => DTreeMap.getKey_filterMap) h'
@[grind =]
theorem getKey!_filterMap [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α]
{f : (a : α) → β a → Option (γ a)} {k : α} :
(t.filterMap f).getKey! k =
((t.getKey? k).pfilter (fun x h' =>
(f x (t.get x (mem_of_getKey?_eq_some h'))).isSome)).get! :=
t.inductionOn fun _ => DTreeMap.getKey!_filterMap
@[grind =]
theorem getKeyD_filterMap [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} {k fallback : α} :
(t.filterMap f).getKeyD k fallback =
((t.getKey? k).pfilter (fun x h' =>
(f x (t.get x (mem_of_getKey?_eq_some h'))).isSome)).getD fallback :=
t.inductionOn fun _ => DTreeMap.getKeyD_filterMap
namespace Const
variable {β : Type v} {γ : Type w} {t : ExtDTreeMap α (fun _ => β) cmp}
theorem filterMap_eq_empty_iff [TransCmp cmp] {f : α → β → Option γ} :
t.filterMap f = ∅ ↔ ∀ k h, f (t.getKey k h) (get t k h) = none :=
isEmpty_iff.symm.trans <| t.inductionOn fun _ => DTreeMap.Const.isEmpty_filterMap_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) (Const.get t k h)).isSome :=
t.inductionOn fun _ => DTreeMap.Const.mem_filterMap
-- TODO: `size_filterMap_le_size` is missing
theorem size_filterMap_eq_size_iff [TransCmp cmp]
{f : α → β → Option γ} :
(t.filterMap f).size = t.size ↔ ∀ k h, (f (t.getKey k h) (Const.get t k h)).isSome :=
t.inductionOn fun _ => DTreeMap.Const.size_filterMap_eq_size_iff
@[simp]
theorem get?_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} :
Const.get? (t.filterMap f) k = (Const.get? t k).pbind (fun x h' =>
f (t.getKey k (mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))) x) :=
t.inductionOn fun _ => DTreeMap.Const.get?_filterMap
/-- Simpler variant of `get?_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem get?_filterMap' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Option γ} {k : α} :
Const.get? (t.filterMap f) k = (Const.get? t k).bind fun x => f k x := by
simp [get?_filterMap]
theorem get?_filterMap_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Option γ} {k k' : α} (h : t.getKey? k = some k') :
Const.get? (t.filterMap f) k = (Const.get? t k).bind (f k') :=
t.inductionOn (fun _ => 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))
(Const.get t k (mem_of_mem_filterMap h))).isSome :=
t.inductionOn fun _ => DTreeMap.Const.isSome_apply_of_mem_filterMap
@[simp]
theorem get_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} {h} :
Const.get (t.filterMap f) k h =
(f (t.getKey k (mem_of_mem_filterMap h))
(Const.get t k (mem_of_mem_filterMap h))).get
(isSome_apply_of_mem_filterMap h) :=
t.inductionOn (fun _ _ => DTreeMap.Const.get_filterMap) h
/-- Simpler variant of `get_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem get_filterMap' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Option γ} {k : α} {h} :
Const.get (t.filterMap f) k h =
(f k (Const.get t k (mem_of_mem_filterMap h))).get (by simpa using isSome_apply_of_mem_filterMap h) := by
simp [get_filterMap]
theorem get!_filterMap [TransCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k : α} :
Const.get! (t.filterMap f) k =
((Const.get? t k).pbind (fun x h' =>
f (t.getKey k (mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))) x)).get! :=
t.inductionOn fun _ => DTreeMap.Const.get!_filterMap
/-- Simpler variant of `get!_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem get!_filterMap' [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k : α} :
Const.get! (t.filterMap f) k = ((Const.get? t k).bind (f k) ).get!:= by
simp [get!_filterMap]
theorem get!_filterMap_of_getKey?_eq_some [TransCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k k' : α} (h : t.getKey? k = some k') :
Const.get! (t.filterMap f) k = ((Const.get? t k).bind (f k')).get! :=
t.inductionOn (fun _ => DTreeMap.Const.get!_filterMap_of_getKey?_eq_some) h
theorem getD_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} {fallback : γ} :
Const.getD (t.filterMap f) k fallback =
((Const.get? t k).pbind (fun x h' =>
f (t.getKey k (mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))) x)).getD fallback :=
t.inductionOn fun _ => 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 : γ} :
Const.getD (t.filterMap f) k fallback = ((Const.get? 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') :
Const.getD (t.filterMap f) k fallback = ((Const.get? t k).bind (f k')).getD fallback :=
t.inductionOn (fun _ => DTreeMap.Const.getD_filterMap_of_getKey?_eq_some) h
theorem toList_filterMap [TransCmp cmp] {f : α → β → Option γ} :
Const.toList (t.filterMap fun k v => f k v) =
(Const.toList t).filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x))) :=
t.inductionOn fun _ => DTreeMap.Const.toList_filterMap
@[grind =]
theorem getKey?_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} :
(t.filterMap f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
(f x (Const.get t x (mem_of_getKey?_eq_some h'))).isSome) :=
t.inductionOn fun _ => DTreeMap.Const.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 (Const.get t x (mem_of_getKey?_eq_some h'))).isSome)).get! :=
t.inductionOn fun _ => 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 (Const.get t x (mem_of_getKey?_eq_some h'))).isSome)).getD fallback :=
t.inductionOn fun _ => DTreeMap.Const.getKeyD_filterMap
end Const
end filterMap
section filter
theorem filterMap_eq_filter {f : (a : α) → β a → Bool} :
t.filterMap (fun k => Option.guard (fun v => f k v)) = t.filter f :=
t.inductionOn fun _ => sound DTreeMap.filterMap_equiv_filter
@[simp, grind =]
theorem toList_filter [TransCmp cmp] {f : (a : α) → β a → Bool} :
(t.filter f).toList = t.toList.filter (fun p => f p.1 p.2) :=
t.inductionOn fun _ => DTreeMap.toList_filter
theorem keys_filter_key [TransCmp cmp] {f : α → Bool} :
(t.filter fun k _ => f k).keys = t.keys.filter f :=
t.inductionOn fun _ => DTreeMap.keys_filter_key
theorem filter_eq_empty_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} :
t.filter f = ∅ ↔ ∀ k h, f k (t.get k h) = false :=
isEmpty_iff.symm.trans <| t.inductionOn fun _ => DTreeMap.isEmpty_filter_iff
theorem filter_key_eq_empty_iff [TransCmp cmp] {f : α → Bool} :
t.filter (fun a _ => f a) = ∅ ↔ ∀ k h, f (t.getKey k h) = false :=
isEmpty_iff.symm.trans <| t.inductionOn fun _ => DTreeMap.isEmpty_filter_key_iff
@[grind =]
theorem contains_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} :
(t.filter f).contains k = (t.get? k).any (f k) :=
t.inductionOn fun _ => DTreeMap.contains_filter
@[grind =]
theorem mem_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} :
k ∈ t.filter f ↔ ∃ h, f k (t.get k h) := by
simp only [mem_iff_contains, contains_filter, Option.any_eq_true_iff_get,
← contains_eq_isSome_get?, get_get?]
theorem mem_filter_key [TransCmp cmp]
{f : α → Bool} {k : α} :
k ∈ t.filter (fun a _ => f a) ↔ ∃ h, f (t.getKey k h) :=
t.inductionOn fun _ => DTreeMap.mem_filter_key
theorem contains_of_contains_filter [TransCmp cmp]
{f : (a : α) → β a → Bool} {k : α} :
(t.filter f).contains k = true → t.contains k = true :=
t.inductionOn fun _ => DTreeMap.contains_of_contains_filter
theorem mem_of_mem_filter [TransCmp cmp]
{f : (a : α) → β a → Bool} {k : α} :
k ∈ (t.filter f) → k ∈ t :=
t.inductionOn fun _ => DTreeMap.contains_of_contains_filter
theorem size_filter_le_size [TransCmp cmp]
{f : (a : α) → β a → Bool} :
(t.filter f).size ≤ t.size :=
t.inductionOn fun _ => DTreeMap.size_filter_le_size
grind_pattern size_filter_le_size => (t.filter f).size
theorem size_filter_eq_size_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} :
(t.filter f).size = t.size ↔ ∀ k h, f k (t.get k h) :=
t.inductionOn fun _ => DTreeMap.size_filter_eq_size_iff
theorem filter_eq_self_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} :
t.filter f = t ↔ ∀ k h, f k (t.get k h) :=
t.inductionOn fun _ => Iff.trans ⟨exact, sound⟩ DTreeMap.filter_equiv_self_iff
theorem filter_key_equiv_self_iff [TransCmp cmp]
{f : (a : α) → Bool} :
t.filter (fun k _ => f k) = t ↔ ∀ k h, f (t.getKey k h) :=
t.inductionOn fun _ => Iff.trans ⟨exact, sound⟩ DTreeMap.filter_key_equiv_self_iff
theorem size_filter_key_eq_size_iff [TransCmp cmp]
{f : α → Bool} :
(t.filter fun k _ => f k).size = t.size ↔ ∀ (k : α) (h : k ∈ t), f (t.getKey k h) :=
t.inductionOn fun _ => DTreeMap.size_filter_key_eq_size_iff
@[simp, grind =]
theorem get?_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} :
(t.filter f).get? k = (t.get? k).filter (f k) :=
t.inductionOn fun _ => DTreeMap.get?_filter
@[simp, grind =]
theorem get_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} {h'} :
(t.filter f).get k h' = t.get k (mem_of_mem_filter h') :=
t.inductionOn (fun _ _ => DTreeMap.get_filter) h'
@[grind =]
theorem get!_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} [Inhabited (β k)] :
(t.filter f).get! k = ((t.get? k).filter (f k)).get! :=
t.inductionOn fun _ => DTreeMap.get!_filter
@[grind =]
theorem getD_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} {fallback : β k} :
(t.filter f).getD k fallback = ((t.get? k).filter (f k)).getD fallback :=
t.inductionOn fun _ => DTreeMap.getD_filter
theorem keys_filter [TransCmp cmp] [LawfulEqCmp cmp] {f : (a : α) → β a → Bool} :
(t.filter f).keys =
(t.keys.attach.filter (fun ⟨x, h'⟩ => f x (t.get x (mem_of_mem_keys h')))).unattach :=
t.inductionOn fun _ => DTreeMap.keys_filter
@[grind =]
theorem getKey?_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k : α} :
(t.filter f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
f x (t.get x (mem_of_getKey?_eq_some h'))) :=
t.inductionOn fun _ => DTreeMap.getKey?_filter
theorem getKey?_filter_key [TransCmp cmp]
{f : α → Bool} {k : α} :
(t.filter fun k _ => f k).getKey? k = (t.getKey? k).filter f :=
t.inductionOn fun _ => DTreeMap.getKey?_filter_key
@[simp, grind =]
theorem getKey_filter [TransCmp cmp]
{f : (a : α) → β a → Bool} {k : α} {h'} :
(t.filter f).getKey k h' = t.getKey k (mem_of_mem_filter h') :=
t.inductionOn (fun _ _ => DTreeMap.getKey_filter) h'
@[grind =]
theorem getKey!_filter [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α]
{f : (a : α) → β a → Bool} {k : α} :
(t.filter f).getKey! k =
((t.getKey? k).pfilter (fun x h' =>
f x (t.get x (mem_of_getKey?_eq_some h')))).get! :=
t.inductionOn fun _ => DTreeMap.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! :=
t.inductionOn fun _ => DTreeMap.getKey!_filter_key
@[grind =]
theorem getKeyD_filter [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} {k fallback : α} :
(t.filter f).getKeyD k fallback =
((t.getKey? k).pfilter (fun x h' =>
f x (t.get x (mem_of_getKey?_eq_some h')))).getD fallback :=
t.inductionOn fun _ => DTreeMap.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 :=
t.inductionOn fun _ => DTreeMap.getKeyD_filter_key
namespace Const
variable {β : Type v} {γ : Type w} {t : ExtDTreeMap α (fun _ => β) cmp}
theorem filter_eq_empty_iff [TransCmp cmp] {f : α → β → Bool} :
t.filter f = ∅ ↔ ∀ k h, f (t.getKey k h) (Const.get t k h) = false :=
isEmpty_iff.symm.trans <| t.inductionOn fun _ => DTreeMap.Const.isEmpty_filter_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') (Const.get t k h') :=
t.inductionOn fun _ => DTreeMap.Const.mem_filter
theorem size_filter_le_size [TransCmp cmp]
{f : α → β → Bool} :
(t.filter f).size ≤ t.size :=
t.inductionOn fun _ => DTreeMap.Const.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 ↔ ∀ (a : α) (h : a ∈ t),
f (t.getKey a h) (Const.get t a h) :=
t.inductionOn fun _ => DTreeMap.Const.size_filter_eq_size_iff
theorem filter_eq_self_iff [TransCmp cmp]
{f : α → β → Bool} :
t.filter f = t ↔ ∀ k h, f (t.getKey k h) (Const.get t k h) :=
t.inductionOn fun _ => Iff.trans ⟨exact, sound⟩ DTreeMap.Const.filter_equiv_self_iff
theorem get?_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} :
Const.get? (t.filter f) k = (Const.get? t k).pfilter (fun x h' =>
f (t.getKey k (mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))) x) :=
t.inductionOn fun _ => DTreeMap.Const.get?_filter
/-- Simpler variant of `get?_filter` when `LawfulEqCmp` is available. -/
@[simp, grind =]
theorem get?_filter' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Bool} {k : α} :
Const.get? (t.filter f) k = (Const.get? t k).filter (f k) := by
simp [get?_filter]
theorem get?_filter_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Bool} {k k' : α} :
t.getKey? k = some k' →
Const.get? (t.filter f) k = (Const.get? t k).filter (fun x => f k' x) :=
t.inductionOn fun _ => DTreeMap.Const.get?_filter_of_getKey?_eq_some
@[simp, grind =]
theorem get_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} {h'} :
Const.get (t.filter f) k h' = Const.get t k (mem_of_mem_filter h') :=
t.inductionOn (fun _ _ => DTreeMap.Const.get_filter) h'
theorem get!_filter [TransCmp cmp] [Inhabited β]
{f : α → β → Bool} {k : α} :
Const.get! (t.filter f) k =
((Const.get? t k).pfilter (fun x h' =>
f (t.getKey k (mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))) x)).get! :=
t.inductionOn fun _ => DTreeMap.Const.get!_filter
/-- Simpler variant of `get!_filter` when `LawfulEqCmp` is available. -/
@[grind =]
theorem get!_filter' [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited β]
{f : α → β → Bool} {k : α} :
Const.get! (t.filter f) k = ((Const.get? t k).filter (f k)).get! := by
simp [get!_filter]
theorem get!_filter_of_getKey?_eq_some [TransCmp cmp] [Inhabited β]
{f : α → β → Bool} {k k' : α} :
t.getKey? k = some k' →
Const.get! (t.filter f) k = ((Const.get? t k).filter (fun x => f k' x)).get! :=
t.inductionOn fun _ => DTreeMap.Const.get!_filter_of_getKey?_eq_some
theorem getD_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} {fallback : β} :
Const.getD (t.filter f) k fallback = ((Const.get? t k).pfilter (fun x h' =>
f (t.getKey k (mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))) x)).getD fallback :=
t.inductionOn fun _ => 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 : β} :
Const.getD (t.filter f) k fallback = ((Const.get? 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' →
Const.getD (t.filter f) k fallback =
((Const.get? t k).filter (fun x => f k' x)).getD fallback :=
t.inductionOn fun _ => DTreeMap.Const.getD_filter_of_getKey?_eq_some
@[simp, grind =]
theorem toList_filter [TransCmp cmp] {f : α → β → Bool} :
toList (t.filter f) =
(toList t).filter (fun p => f p.1 p.2) :=
t.inductionOn fun _ => DTreeMap.Const.toList_filter
theorem keys_filter [TransCmp cmp] {f : α → β → Bool} :
(t.filter f).keys =
(t.keys.attach.filter (fun ⟨x, h'⟩ => f x (get t x (mem_of_mem_keys h')))).unattach :=
t.inductionOn fun _ => 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 (Const.get t x (mem_of_getKey?_eq_some h')))) :=
t.inductionOn fun _ => DTreeMap.Const.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 (Const.get t x (mem_of_getKey?_eq_some h'))))).get! :=
t.inductionOn fun _ => DTreeMap.Const.getKey!_filter
@[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 (Const.get t x (mem_of_getKey?_eq_some h'))))).getD fallback :=
t.inductionOn fun _ => DTreeMap.Const.getKeyD_filter
end Const
end filter
section map
variable {γ : α → Type w} {δ : α → Type w'}
@[simp]
theorem map_id : t.map (fun _ v => v) = t :=
t.inductionOn fun _ => sound DTreeMap.map_id_equiv
@[simp, grind =]
theorem map_map {f : (a : α) → β a → γ a} {g : (a : α) → γ a → δ a} :
(t.map f).map g = t.map fun k v => g k (f k v) :=
t.inductionOn fun _ => sound DTreeMap.map_map_equiv
@[simp, grind =]
theorem toList_map [TransCmp cmp] {f : (a : α) → β a → γ a} :
(t.map f).toList = t.toList.map (fun p => ⟨p.1, f p.1 p.2⟩) :=
t.inductionOn fun _ => DTreeMap.toList_map
@[simp, grind =]
theorem keys_map [TransCmp cmp] {f : (a : α) → β a → γ a} : (t.map f).keys = t.keys :=
t.inductionOn fun _ => DTreeMap.keys_map
theorem filterMap_eq_map [TransCmp cmp]
{f : (a : α) → β a → γ a} :
(t.filterMap (fun k v => some (f k v))) = t.map f :=
t.inductionOn fun _ => sound DTreeMap.filterMap_equiv_map
@[simp]
theorem map_eq_empty_iff [TransCmp cmp] {f : (a : α) → β a → γ a} :
t.map f = ∅ ↔ t = ∅ := by
simp only [← isEmpty_iff, Bool.coe_iff_coe]
exact t.inductionOn fun _ => DTreeMap.isEmpty_map
@[grind =]
theorem contains_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} :
(t.map f).contains k = t.contains k :=
t.inductionOn fun _ => DTreeMap.contains_map
theorem contains_of_contains_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} :
(t.map f).contains k = true → t.contains k = true :=
t.inductionOn fun _ => DTreeMap.contains_of_contains_map
@[simp, grind =]
theorem mem_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} :
k ∈ t.map f ↔ k ∈ t := by
simp only [mem_iff_contains, contains_map]
theorem mem_of_mem_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} :
k ∈ t.map f → k ∈ t :=
t.inductionOn fun _ => DTreeMap.contains_of_contains_map
@[simp, grind =]
theorem size_map [TransCmp cmp]
{f : (a : α) → β a → γ a} :
(t.map f).size = t.size :=
t.inductionOn fun _ => DTreeMap.size_map
@[simp, grind =]
theorem get?_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → γ a} {k : α} :
(t.map f).get? k = (t.get? k).map (f k) :=
t.inductionOn fun _ => DTreeMap.get?_map
@[simp, grind =]
theorem get_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → γ a} {k : α} {h'} :
(t.map f).get k h' = f k (t.get k (mem_of_mem_map h')) :=
t.inductionOn (fun _ _ => DTreeMap.get_map) h'
@[grind =]
theorem get!_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → γ a} {k : α} [Inhabited (γ k)] :
(t.map f).get! k = ((t.get? k).map (f k)).get! :=
t.inductionOn fun _ => DTreeMap.get!_map
@[grind =]
theorem getD_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → γ a} {k : α} {fallback : γ k} :
(t.map f).getD k fallback = ((t.get? k).map (f k)).getD fallback :=
t.inductionOn fun _ => DTreeMap.getD_map
@[simp, grind =]
theorem getKey?_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} :
(t.map f).getKey? k = t.getKey? k :=
t.inductionOn fun _ => DTreeMap.getKey?_map
@[simp, grind =]
theorem getKey_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k : α} {h'} :
(t.map f).getKey k h' = t.getKey k (mem_of_mem_map h') :=
t.inductionOn (fun _ _ => DTreeMap.getKey_map) h'
@[simp, grind =]
theorem getKey!_map [TransCmp cmp] [Inhabited α]
{f : (a : α) → β a → γ a} {k : α} :
(t.map f).getKey! k = t.getKey! k :=
t.inductionOn fun _ => DTreeMap.getKey!_map
@[simp, grind =]
theorem getKeyD_map [TransCmp cmp]
{f : (a : α) → β a → γ a} {k fallback : α} :
(t.map f).getKeyD k fallback = t.getKeyD k fallback :=
t.inductionOn fun _ => DTreeMap.getKeyD_map
namespace Const
variable {β : Type v} {γ : Type w} {t : ExtDTreeMap α (fun _ => β) cmp}
@[simp, grind =]
theorem get?_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} :
Const.get? (t.map f) k = (Const.get? t k).map (f k) :=
t.inductionOn fun _ => DTreeMap.Const.get?_map
/-- Variant of `get?_map` that holds without `LawfulEqCmp`. -/
@[simp (low)]
theorem get?_map' [TransCmp cmp]
{f : α → β → γ} {k : α} :
Const.get? (t.map f) k = (Const.get? t k).pmap (fun v h' => f (t.getKey k h') v)
(fun _ h' => mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h')) :=
t.inductionOn fun _ => DTreeMap.Const.get?_map'
theorem get?_map_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → γ} {k k' : α} (h : t.getKey? k = some k') :
Const.get? (t.map f) k = (Const.get? t k).map (f k') :=
t.inductionOn (fun _ => DTreeMap.Const.get?_map_of_getKey?_eq_some) h
@[simp, grind =]
theorem get_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} {h'} :
Const.get (t.map f) k h' = f k (Const.get t k (mem_of_mem_map h')) :=
t.inductionOn (fun _ _ => DTreeMap.Const.get_map) h'
/-- Variant of `get_map` that holds without `LawfulEqCmp`. -/
@[simp (low)]
theorem get_map' [TransCmp cmp]
{f : α → β → γ} {k : α} {h'} :
Const.get (t.map f) k h' =
f (t.getKey k (mem_of_mem_map h')) (Const.get t k (mem_of_mem_map h')) :=
t.inductionOn (fun _ _ => DTreeMap.Const.get_map') h'
@[grind =]
theorem get!_map [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited γ]
{f : α → β → γ} {k : α} :
Const.get! (t.map f) k = ((Const.get? t k).map (f k)).get! :=
t.inductionOn fun _ => DTreeMap.Const.get!_map
/-- Variant of `get!_map` that holds without `LawfulEqCmp`. -/
theorem get!_map' [TransCmp cmp] [Inhabited γ]
{f : α → β → γ} {k : α} :
Const.get! (t.map f) k =
((get? t k).pmap (fun v h => f (t.getKey k h) v)
(fun _ h' => mem_iff_isSome_get?.mpr (Option.isSome_of_mem h'))).get! :=
t.inductionOn fun _ => DTreeMap.Const.get!_map'
theorem get!_map_of_getKey?_eq_some [TransCmp cmp] [Inhabited γ]
{f : α → β → γ} {k k' : α} (h : t.getKey? k = some k') :
Const.get! (t.map f) k = ((Const.get? t k).map (f k')).get! :=
t.inductionOn (fun _ => DTreeMap.Const.get!_map_of_getKey?_eq_some) h
@[grind =]
theorem getD_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} {fallback : γ} :
Const.getD (t.map f) k fallback = ((Const.get? t k).map (f k)).getD fallback :=
t.inductionOn fun _ => DTreeMap.Const.getD_map
/-- Variant of `getD_map` that holds without `LawfulEqCmp`. -/
theorem getD_map' [TransCmp cmp]
{f : α → β → γ} {k : α} {fallback : γ} :
Const.getD (t.map f) k fallback =
((get? t k).pmap (fun v h => f (t.getKey k h) v)
(fun _ h' => mem_iff_isSome_get?.mpr (Option.isSome_of_eq_some h'))).getD fallback :=
t.inductionOn fun _ => DTreeMap.Const.getD_map'
theorem getD_map_of_getKey?_eq_some [TransCmp cmp] [Inhabited γ]
{f : α → β → γ} {k k' : α} {fallback : γ} (h : t.getKey? k = some k') :
Const.getD (t.map f) k fallback = ((Const.get? t k).map (f k')).getD fallback :=
t.inductionOn (fun _ => DTreeMap.Const.getD_map_of_getKey?_eq_some) h
@[simp, grind =]
theorem toList_map [TransCmp cmp] {f : α → β → γ} :
Const.toList (t.map f) =
(Const.toList t).map (fun p => (p.1, f p.1 p.2)) :=
t.inductionOn fun _ => DTreeMap.Const.toList_map
end Const
end map
end Std.ExtDTreeMap

View file

@ -1854,7 +1854,7 @@ theorem getElem?_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getElem?_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem getElem?_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem getElem?_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} :
(m.filterMap f)[k]? = m[k]?.bind fun x => f k x := by
simp [getElem?_filterMap]
@ -1881,7 +1881,7 @@ theorem isSome_apply_of_mem_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getElem_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem getElem_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem getElem_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} {h} :
(m.filterMap f)[k]'h =
(f k (m[k]'(mem_of_mem_filterMap h))).get (by simpa using isSome_apply_of_mem_filterMap h) := by
@ -1992,7 +1992,7 @@ theorem getElem?_filter [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getElem?_filter` when `LawfulBEq` is available. -/
@[simp, grind =]
theorem getElem?_filter' [LawfulBEq α] [LawfulHashable α]
theorem getElem?_filter' [LawfulBEq α]
{f : α → β → Bool} {k : α} :
(m.filter f)[k]? = m[k]?.filter (f k) := by
simp [getElem?_filter]
@ -2017,7 +2017,7 @@ theorem getElem!_filter [EquivBEq α] [LawfulHashable α] [Inhabited β]
/-- Simpler variant of `getElem!_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem getElem!_filter' [LawfulBEq α] [LawfulHashable α] [Inhabited β]
theorem getElem!_filter' [LawfulBEq α] [Inhabited β]
{f : α → β → Bool} {k : α} :
(m.filter f)[k]! = (m[k]?.filter (f k)).get! := by
simp [getElem!_filter]
@ -2036,7 +2036,7 @@ theorem getD_filter [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getD_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem getD_filter' [LawfulBEq α] [LawfulHashable α]
theorem getD_filter' [LawfulBEq α]
{f : α → β → Bool} {k : α} {fallback : β} :
(m.filter f).getD k fallback = (m[k]?.filter (f k)).getD fallback := by
simp [getD_filter]
@ -2144,7 +2144,7 @@ theorem size_map [EquivBEq α] [LawfulHashable α]
ExtDHashMap.size_map
@[simp, grind =]
theorem getElem?_map [LawfulBEq α] [LawfulHashable α]
theorem getElem?_map [LawfulBEq α]
{f : α → β → γ} {k : α} :
(m.map f)[k]? = m[k]?.map (f k) :=
ExtDHashMap.Const.get?_map
@ -2163,7 +2163,7 @@ theorem getElem?_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α]
ExtDHashMap.Const.get?_map_of_getKey?_eq_some h
@[simp, grind =]
theorem getElem_map [LawfulBEq α] [LawfulHashable α]
theorem getElem_map [LawfulBEq α]
{f : α → β → γ} {k : α} {h'} :
(m.map f)[k]' h' =
f k (m[k]'(mem_of_mem_map h')) :=
@ -2177,7 +2177,7 @@ theorem getElem_map' [EquivBEq α] [LawfulHashable α]
f (m.getKey k (mem_of_mem_map h')) (m[k]'(mem_of_mem_map h')) :=
ExtDHashMap.Const.get_map' (h' := h')
@[grind =] theorem getElem!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ]
@[grind =] theorem getElem!_map [LawfulBEq α] [Inhabited γ]
{f : α → β → γ} {k : α} :
(m.map f)[k]! =
(m[k]?.map (f k)).get! :=
@ -2196,7 +2196,7 @@ theorem getElem!_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhab
(m.map f)[k]! = (m[k]?.map (f k')).get! :=
ExtDHashMap.Const.get!_map_of_getKey?_eq_some h
@[grind =] theorem getD_map [LawfulBEq α] [LawfulHashable α]
@[grind =] theorem getD_map [LawfulBEq α]
{f : α → β → γ} {k : α} {fallback : γ} :
(m.map f).getD k fallback =
(m[k]?.map (f k)).getD fallback :=

View file

@ -209,6 +209,10 @@ theorem isSome_get?_iff_mem [EquivBEq α] [LawfulHashable α] {a : α} :
(m.get? a).isSome ↔ a ∈ m :=
mem_iff_isSome_get?.symm
theorem mem_of_get?_eq_some [EquivBEq α] [LawfulHashable α] {k k' : α}
(h : m.get? k = some k') : k' ∈ m :=
ExtHashMap.mem_of_getKey?_eq_some h
theorem get?_eq_none_of_contains_eq_false [EquivBEq α] [LawfulHashable α] {a : α} :
m.contains a = false → m.get? a = none :=
ExtHashMap.getKey?_eq_none_of_contains_eq_false

View file

@ -24,7 +24,7 @@ universe u v w w'
namespace Std.ExtTreeMap
variable {α : Type u} {β : Type v} {γ : Type w} {cmp : αα → Ordering} {t : ExtTreeMap α β cmp}
variable {α : Type u} {β : Type v} {γ : Type w} {δ : Type w'} {cmp : αα → Ordering} {t : ExtTreeMap α β cmp}
private theorem ext {t t' : ExtTreeMap α β cmp} : t.inner = t'.inner → t = t' := by
cases t; cases t'; rintro rfl; rfl
@ -284,6 +284,14 @@ theorem getElem?_eq_some_getElem [TransCmp cmp] {a : α} (h) :
t[a]? = some (t[a]'h) :=
ExtDTreeMap.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) :=
ExtDTreeMap.Const.get_eq_get_get? (h := h)
@[grind =] theorem get_getElem? [TransCmp cmp] {a : α} {h} :
t[a]?.get h = t[a]'(mem_iff_isSome_getElem?.mpr h) :=
ExtDTreeMap.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') :=
ExtDTreeMap.Const.get_congr hab (h' := h')
@ -433,6 +441,10 @@ theorem isSome_getKey?_iff_mem [TransCmp cmp] {a : α} :
(t.getKey? a).isSome ↔ a ∈ t :=
mem_iff_isSome_getKey?.symm
theorem mem_of_getKey?_eq_some [TransCmp cmp] {k k' : α} :
t.getKey? k = some k' → k' ∈ t :=
ExtDTreeMap.mem_of_getKey?_eq_some
theorem getKey?_eq_none_of_contains_eq_false [TransCmp cmp] {a : α} :
t.contains a = false → t.getKey? a = none :=
ExtDTreeMap.getKey?_eq_none_of_contains_eq_false
@ -486,6 +498,15 @@ theorem getKey?_eq_some_getKey [TransCmp cmp] {a : α} (h') :
t.getKey? a = some (t.getKey a h') :=
ExtDTreeMap.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) :=
ExtDTreeMap.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) :=
ExtDTreeMap.get_getKey?
theorem compare_getKey_self [TransCmp cmp] {k : α} (h' : k ∈ t) :
cmp (t.getKey k h') k = .eq :=
ExtDTreeMap.compare_getKey_self h'
@ -763,6 +784,10 @@ theorem mem_keys [LawfulEqCmp cmp] [TransCmp cmp] {k : α} :
k ∈ t.keys ↔ k ∈ t :=
ExtDTreeMap.mem_keys
theorem mem_of_mem_keys [TransCmp cmp] {k : α} :
k ∈ t.keys → k ∈ t :=
ExtDTreeMap.mem_of_mem_keys
theorem distinct_keys [TransCmp cmp] :
t.keys.Pairwise (fun a b => ¬ cmp a b = .eq) :=
ExtDTreeMap.distinct_keys
@ -3020,4 +3045,495 @@ theorem ext_keys_unit [TransCmp cmp] {t₁ t₂ : ExtTreeMap α Unit cmp} (h : t
end Ext
section filterMap
variable {t : ExtTreeMap α β cmp}
@[simp, grind =]
theorem toList_filterMap [TransCmp cmp] {f : (a : α) → β → Option γ} :
(t.filterMap f).toList =
t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x))) :=
ExtDTreeMap.Const.toList_filterMap
theorem filterMap_eq_empty_iff [TransCmp cmp] {f : α → β → Option γ} :
t.filterMap f = ∅ ↔ ∀ k h, f (t.getKey k h) (t[k]'h) = none :=
ext_iff.trans ExtDTreeMap.Const.filterMap_eq_empty_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 :=
ExtDTreeMap.Const.mem_filterMap
theorem contains_of_contains_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} :
(t.filterMap f).contains k = true → t.contains k = true :=
ExtDTreeMap.contains_of_contains_filterMap
theorem mem_of_mem_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} :
k ∈ t.filterMap f → k ∈ t :=
ExtDTreeMap.mem_of_mem_filterMap
theorem size_filterMap_le_size [TransCmp cmp]
{f : α → β → Option γ} :
(t.filterMap f).size ≤ t.size :=
ExtDTreeMap.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 :=
ExtDTreeMap.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) :=
ExtDTreeMap.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') :=
ExtDTreeMap.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 :=
ExtDTreeMap.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) :=
ExtDTreeMap.Const.get_filterMap (h := h)
/-- 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! :=
ExtDTreeMap.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! :=
ExtDTreeMap.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 :=
ExtDTreeMap.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 :=
ExtDTreeMap.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) :=
ExtDTreeMap.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') :=
ExtDTreeMap.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! :=
ExtDTreeMap.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 :=
ExtDTreeMap.Const.getKeyD_filterMap
end filterMap
section filter
variable {t : ExtTreeMap α β cmp}
theorem filterMap_equiv_filter {f : α → β → Bool} :
t.filterMap (fun k => Option.guard (fun v => f k v)) = t.filter f :=
ext ExtDTreeMap.filterMap_eq_filter
@[simp, grind =]
theorem toList_filter [TransCmp cmp] {f : α → β → Bool} :
(t.filter f).toList = t.toList.filter (fun p => f p.1 p.2) :=
ExtDTreeMap.Const.toList_filter
theorem keys_filter_key [TransCmp cmp] {f : α → Bool} :
(t.filter fun k _ => f k).keys = t.keys.filter f :=
ExtDTreeMap.keys_filter_key
theorem filter_eq_empty_iff [TransCmp cmp] {f : α → β → Bool} :
t.filter f = ∅ ↔ ∀ k h, f (t.getKey k h) (t[k]'h) = false :=
ext_iff.trans ExtDTreeMap.Const.filter_eq_empty_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] :=
ExtDTreeMap.Const.mem_filter
theorem contains_of_contains_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} :
(t.filter f).contains k = true → t.contains k = true :=
ExtDTreeMap.contains_of_contains_filter
theorem mem_of_mem_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} :
k ∈ t.filter f → k ∈ t :=
ExtDTreeMap.mem_of_mem_filter
theorem size_filter_le_size [TransCmp cmp]
{f : α → β → Bool} :
(t.filter f).size ≤ t.size :=
ExtDTreeMap.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.get k h) :=
ExtDTreeMap.Const.size_filter_eq_size_iff
theorem filter_eq_self_iff [TransCmp cmp]
{f : α → β → Bool} :
t.filter f = t ↔ ∀ k h, f (t.getKey k h) (t.get k h) :=
ext_iff.trans ExtDTreeMap.Const.filter_eq_self_iff
@[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) :=
ExtDTreeMap.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) :=
ExtDTreeMap.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') :=
ExtDTreeMap.Const.get_filter (h' := h')
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! :=
ExtDTreeMap.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! :=
ExtDTreeMap.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 :=
ExtDTreeMap.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 :=
ExtDTreeMap.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 (get t x (mem_of_mem_keys h')))).unattach :=
ExtDTreeMap.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')))) :=
ExtDTreeMap.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 :=
ExtDTreeMap.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') :=
ExtDTreeMap.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! :=
ExtDTreeMap.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! :=
ExtDTreeMap.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 :=
ExtDTreeMap.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 :=
ExtDTreeMap.getKeyD_filter_key
end filter
section map
variable {t : ExtTreeMap α β cmp}
@[simp]
theorem map_id : t.map (fun _ v => v) = t :=
ext ExtDTreeMap.map_id
@[simp, grind =]
theorem map_map {f : α → β → γ} {g : αγ → δ} :
(t.map f).map g = t.map fun k v => g k (f k v) :=
ext ExtDTreeMap.map_map
@[simp, grind =]
theorem toList_map [TransCmp cmp] {f : α → β → γ} :
(t.map f).toList = t.toList.map (fun p => (p.1, f p.1 p.2)) :=
ExtDTreeMap.Const.toList_map
@[simp, grind =]
theorem keys_map [TransCmp cmp] {f : α → β → γ} : (t.map f).keys = t.keys :=
ExtDTreeMap.keys_map
theorem filterMap_eq_map [TransCmp cmp]
{f : α → β → γ} :
t.filterMap (fun k v => some (f k v)) = t.map f :=
ext ExtDTreeMap.filterMap_eq_map
@[simp]
theorem map_eq_empty_iff [TransCmp cmp] {f : α → β → γ} :
t.map f = ∅ ↔ t = ∅ := by
simpa only [ext_iff] using ExtDTreeMap.map_eq_empty_iff
@[simp, grind =]
theorem contains_map [TransCmp cmp]
{f : α → β → γ} {k : α} :
(t.map f).contains k = t.contains k :=
ExtDTreeMap.contains_map
theorem contains_of_contains_map [TransCmp cmp]
{f : α → β → γ} {k : α} :
(t.map f).contains k = true → t.contains k = true :=
ExtDTreeMap.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 :=
ExtDTreeMap.contains_of_contains_map
@[simp, grind =]
theorem size_map [TransCmp cmp]
{f : α → β → γ} :
(t.map f).size = t.size :=
ExtDTreeMap.size_map
@[simp, grind =]
theorem getElem?_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} :
(t.map f)[k]? = t[k]?.map (f k) :=
ExtDTreeMap.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')) :=
ExtDTreeMap.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') :=
ExtDTreeMap.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')) :=
ExtDTreeMap.Const.get_map (h' := h')
/-- 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')) :=
ExtDTreeMap.Const.get_map' (h' := h')
@[grind =]
theorem getElem!_map [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited γ]
{f : α → β → γ} {k : α} :
(t.map f)[k]! =
(t[k]?.map (f k)).get! :=
ExtDTreeMap.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! :=
ExtDTreeMap.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! :=
ExtDTreeMap.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 :=
ExtDTreeMap.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 :=
ExtDTreeMap.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 :=
ExtDTreeMap.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 :=
ExtDTreeMap.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') :=
ExtDTreeMap.getKey_map
@[simp, grind =]
theorem getKey!_map [TransCmp cmp] [Inhabited α]
{f : α → β → γ} {k : α} :
(t.map f).getKey! k = t.getKey! k :=
ExtDTreeMap.getKey!_map
@[simp, grind =]
theorem getKeyD_map [TransCmp cmp]
{f : α → β → γ} {k fallback : α} :
(t.map f).getKeyD k fallback = t.getKeyD k fallback :=
ExtDTreeMap.getKeyD_map
end map
end Std.ExtTreeMap

View file

@ -221,6 +221,10 @@ theorem isSome_get?_iff_mem [TransCmp cmp] {a : α} :
(t.get? a).isSome ↔ a ∈ t :=
mem_iff_isSome_get?.symm
theorem mem_of_get?_eq_some [TransCmp cmp] {k k' : α}
(h : t.get? k = some k') : k' ∈ t :=
ExtTreeMap.mem_of_getKey?_eq_some h
theorem get?_eq_none_of_contains_eq_false [TransCmp cmp] {a : α} :
t.contains a = false → t.get? a = none :=
ExtTreeMap.getKey?_eq_none_of_contains_eq_false
@ -268,6 +272,14 @@ theorem get?_eq_some_get [TransCmp cmp] {a : α} (h') :
t.get? a = some (t.get a h') :=
ExtTreeMap.getKey?_eq_some_getKey h'
theorem get_eq_get_get? [TransCmp cmp] {k : α} {h} :
t.get k h = (t.get? k).get (mem_iff_isSome_get?.mp h) :=
ExtTreeMap.getKey_eq_get_getKey?
@[grind =] theorem get_get? [TransCmp cmp] {k : α} {h} :
(t.get? k).get h = t.get k (mem_iff_isSome_get?.mpr h) :=
ExtTreeMap.get_getKey?
theorem compare_get_self [TransCmp cmp] {k : α} (h' : k ∈ t) :
cmp (t.get k h') k = .eq :=
ExtTreeMap.compare_getKey_self h'
@ -1540,4 +1552,77 @@ theorem toList_inj [TransCmp cmp] : t₁.toList = t₂.toList ↔ t₁ = t₂ :=
end Ext
section filter
variable {t : ExtTreeSet α cmp}
theorem toList_filter [TransCmp cmp] {f : α → Bool} :
(t.filter f).toList = t.toList.filter f :=
ExtTreeMap.keys_filter_key
theorem filter_eq_empty_iff [TransCmp cmp] {f : α → Bool} :
t.filter f = ∅ ↔ ∀ k h, f (t.get k h) = false :=
ext_iff.trans ExtTreeMap.filter_eq_empty_iff
-- TODO: `contains_filter` is missing.
@[simp, grind =]
theorem mem_filter [TransCmp cmp]
{f : α → Bool} {k : α} :
k ∈ t.filter f ↔ ∃ h, f (t.get k h) :=
ExtTreeMap.mem_filter
theorem contains_of_contains_filter [TransCmp cmp]
{f : α → Bool} {k : α} :
(t.filter f).contains k → t.contains k :=
ExtTreeMap.contains_of_contains_filter
theorem mem_of_mem_filter [TransCmp cmp]
{f : α → Bool} {k : α} :
k ∈ t.filter f → k ∈ t :=
ExtTreeMap.mem_of_mem_filter
theorem size_filter_le_size [TransCmp cmp]
{f : α → Bool} :
(t.filter f).size ≤ t.size :=
ExtTreeMap.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.get k h) :=
ExtTreeMap.size_filter_eq_size_iff
theorem filter_eq_self_iff [TransCmp cmp]
{f : α → Bool} :
t.filter f = t ↔ ∀ k h, f (t.get k h) :=
ext_iff.trans ExtTreeMap.filter_eq_self_iff
@[simp, grind =]
theorem get?_filter [TransCmp cmp]
{f : α → Bool} {k : α} :
(t.filter f).get? k = (t.get? k).filter f :=
ExtTreeMap.getKey?_filter_key
@[simp, grind =]
theorem get_filter [TransCmp cmp]
{f : α → Bool} {k : α} {h} :
(t.filter f).get k h = t.get k (mem_of_mem_filter h) :=
ExtTreeMap.getKey_filter
@[grind =]
theorem get!_filter [TransCmp cmp] [Inhabited α]
{f : α → Bool} {k : α} :
(t.filter f).get! k = ((t.get? k).filter f).get! :=
ExtTreeMap.getKey!_filter_key
@[grind =]
theorem getD_filter [TransCmp cmp]
{f : α → Bool} {k fallback : α} :
(t.filter f).getD k fallback = ((t.get? k).filter f).getD fallback :=
ExtTreeMap.getKeyD_filter_key
end filter
end Std.ExtTreeSet

View file

@ -848,7 +848,7 @@ theorem contains_keys [EquivBEq α] [LawfulHashable α] {k : α} :
DHashMap.contains_keys
@[simp, grind =]
theorem mem_keys [LawfulBEq α] [LawfulHashable α] {k : α} :
theorem mem_keys [LawfulBEq α] {k : α} :
k ∈ m.keys ↔ k ∈ m :=
DHashMap.mem_keys
@ -2430,7 +2430,7 @@ theorem getElem?_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getElem?_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem getElem?_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem getElem?_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} :
(m.filterMap f)[k]? = m[k]?.bind fun x => f k x := by
simp [getElem?_filterMap]
@ -2458,7 +2458,7 @@ theorem getElem_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getElem_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem getElem_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem getElem_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} {h} :
(m.filterMap f)[k]'h =
(f k (m[k]'(mem_of_mem_filterMap h))).get (by simpa using isSome_apply_of_mem_filterMap h) := by
@ -2473,7 +2473,7 @@ theorem getElem!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited γ]
/-- Simpler variant of `getElem!_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem getElem!_filterMap' [LawfulBEq α] [LawfulHashable α] [Inhabited γ]
theorem getElem!_filterMap' [LawfulBEq α] [Inhabited γ]
{f : α → β → Option γ} {k : α} :
(m.filterMap f)[k]! = (m[k]?.bind (f k)).get! := by
simp [getElem!_filterMap]
@ -2492,7 +2492,7 @@ theorem getD_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getD_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem getD_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem getD_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} {fallback : γ} :
(m.filterMap f).getD k fallback = (m[k]?.bind (f k)).getD fallback := by
simp [getD_filterMap]
@ -2608,7 +2608,7 @@ theorem getElem?_filter [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getElem?_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem getElem?_filter' [LawfulBEq α] [LawfulHashable α]
theorem getElem?_filter' [LawfulBEq α]
{f : α → β → Bool} {k : α} :
(m.filter f)[k]? = m[k]?.filter (f k) := by
simp [getElem?_filter]
@ -2634,7 +2634,7 @@ theorem getElem!_filter [EquivBEq α] [LawfulHashable α] [Inhabited β]
/-- Simpler variant of `getElem!_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem getElem!_filter' [LawfulBEq α] [LawfulHashable α] [Inhabited β]
theorem getElem!_filter' [LawfulBEq α] [Inhabited β]
{f : α → β → Bool} {k : α} :
(m.filter f)[k]! = (m[k]?.filter (f k)).get! := by
simp [getElem!_filter]
@ -2653,7 +2653,7 @@ theorem getD_filter [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getD_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem getD_filter' [LawfulBEq α] [LawfulHashable α]
theorem getD_filter' [LawfulBEq α]
{f : α → β → Bool} {k : α} {fallback : β} :
(m.filter f).getD k fallback = (m[k]?.filter (f k)).getD fallback := by
simp [getD_filter]
@ -2775,7 +2775,7 @@ theorem size_map [EquivBEq α] [LawfulHashable α]
DHashMap.size_map
@[simp, grind =]
theorem getElem?_map [LawfulBEq α] [LawfulHashable α]
theorem getElem?_map [LawfulBEq α]
{f : α → β → γ} {k : α} :
(m.map f)[k]? = m[k]?.map (f k) :=
DHashMap.Const.get?_map
@ -2794,7 +2794,7 @@ theorem getElem?_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α]
DHashMap.Const.get?_map_of_getKey?_eq_some h
@[simp, grind =]
theorem getElem_map [LawfulBEq α] [LawfulHashable α]
theorem getElem_map [LawfulBEq α]
{f : α → β → γ} {k : α} {h'} :
(m.map f)[k]'(h') =
f k (m[k]'(mem_of_mem_map h')) :=
@ -2809,7 +2809,7 @@ theorem getElem_map' [EquivBEq α] [LawfulHashable α]
DHashMap.Const.get_map'
@[grind =]
theorem getElem!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ]
theorem getElem!_map [LawfulBEq α] [Inhabited γ]
{f : α → β → γ} {k : α} :
(m.map f)[k]! =
(m[k]?.map (f k)).get! :=
@ -2829,7 +2829,7 @@ theorem getElem!_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhab
DHashMap.Const.get!_map_of_getKey?_eq_some h
@[grind =]
theorem getD_map [LawfulBEq α] [LawfulHashable α]
theorem getD_map [LawfulBEq α]
{f : α → β → γ} {k : α} {fallback : γ} :
(m.map f).getD k fallback =
(m[k]?.map (f k)).getD fallback :=

View file

@ -2451,7 +2451,7 @@ theorem getElem?_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getElem?_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem getElem?_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem getElem?_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} (h : m.WF) :
(m.filterMap f)[k]? = m[k]?.bind fun x => f k x := by
simp [getElem?_filterMap, h]
@ -2480,7 +2480,7 @@ theorem getElem_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getElem_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem getElem_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem getElem_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} {g} (h : m.WF) :
(m.filterMap f)[k]'g =
(f k (m[k]'(mem_of_mem_filterMap h g))).get (by simpa [h] using isSome_apply_of_mem_filterMap h g) := by
@ -2496,7 +2496,7 @@ theorem getElem!_filterMap [EquivBEq α] [LawfulHashable α] [Inhabited γ]
/-- Simpler variant of `getElem!_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem getElem!_filterMap' [LawfulBEq α] [LawfulHashable α] [Inhabited γ]
theorem getElem!_filterMap' [LawfulBEq α] [Inhabited γ]
{f : α → β → Option γ} {k : α} (h : m.WF) :
(m.filterMap f)[k]! = (m[k]?.bind (f k)).get! := by
simp [getElem!_filterMap, h]
@ -2516,7 +2516,7 @@ theorem getD_filterMap [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getD_filterMap` when `LawfulBEq` is available. -/
@[grind =]
theorem getD_filterMap' [LawfulBEq α] [LawfulHashable α]
theorem getD_filterMap' [LawfulBEq α]
{f : α → β → Option γ} {k : α} {fallback : γ} (h : m.WF) :
getD (m.filterMap f) k fallback = (m[k]?.bind (f k)).getD fallback := by
simp [getD_filterMap, h]
@ -2630,7 +2630,7 @@ theorem getElem?_filter [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getElem?_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem getElem?_filter' [LawfulBEq α] [LawfulHashable α]
theorem getElem?_filter' [LawfulBEq α]
{f : α → β → Bool} {k : α} (h : m.WF) :
(m.filter f)[k]? = m[k]?.filter (f k) := by
simp [getElem?_filter, h]
@ -2656,7 +2656,7 @@ theorem getElem!_filter [EquivBEq α] [LawfulHashable α] [Inhabited β]
/-- Simpler variant of `getElem!_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem getElem!_filter' [LawfulBEq α] [LawfulHashable α] [Inhabited β]
theorem getElem!_filter' [LawfulBEq α] [Inhabited β]
{f : α → β → Bool} {k : α} (h : m.WF) :
(m.filter f)[k]! = (m[k]?.filter (f k)).get! := by
simp [getElem!_filter, h]
@ -2675,7 +2675,7 @@ theorem getD_filter [EquivBEq α] [LawfulHashable α]
/-- Simpler variant of `getD_filter` when `LawfulBEq` is available. -/
@[grind =]
theorem getD_filter' [LawfulBEq α] [LawfulHashable α]
theorem getD_filter' [LawfulBEq α]
{f : α → β → Bool} {k : α} {fallback : β} (h : m.WF) :
getD (m.filter f) k fallback = (m[k]?.filter (f k)).getD fallback := by
simp [getD_filter, h]
@ -2819,7 +2819,7 @@ theorem getKeyD_map [EquivBEq α] [LawfulHashable α]
DHashMap.Raw.getKeyD_map h.out
@[simp, grind =]
theorem getElem?_map [LawfulBEq α] [LawfulHashable α]
theorem getElem?_map [LawfulBEq α]
{f : α → β → γ} {k : α} (h : m.WF) :
(m.map f)[k]? = m[k]?.map (f k) :=
DHashMap.Raw.Const.get?_map h.out
@ -2838,7 +2838,7 @@ theorem getElem?_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α]
DHashMap.Raw.Const.get?_map_of_getKey?_eq_some h.out h'
@[simp, grind =]
theorem getElem_map [LawfulBEq α] [LawfulHashable α]
theorem getElem_map [LawfulBEq α]
{f : α → β → γ} {k : α} {h'} (h : m.WF) :
(m.map f)[k]' h' =
(f k (m[k]' (mem_of_mem_map h h'))) :=
@ -2854,7 +2854,7 @@ theorem getElem_map' [EquivBEq α] [LawfulHashable α]
DHashMap.Raw.Const.get_map' h.out (h':= h')
@[grind =]
theorem getElem!_map [LawfulBEq α] [LawfulHashable α] [Inhabited γ]
theorem getElem!_map [LawfulBEq α] [Inhabited γ]
{f : α → β → γ} {k : α} (h : m.WF) :
(m.map f)[k]! =
(m[k]?.map (f k)).get! :=
@ -2874,7 +2874,7 @@ theorem getElem!_map_of_getKey?_eq_some [EquivBEq α] [LawfulHashable α] [Inhab
DHashMap.Raw.Const.get!_map_of_getKey?_eq_some h.out h'
@[grind =]
theorem getD_map [LawfulBEq α] [LawfulHashable α]
theorem getD_map [LawfulBEq α]
{f : α → β → γ} {k : α} {fallback : γ} (h : m.WF) :
(m.map f).getD k fallback =
(m[k]?.map (f k)).getD fallback :=

View file

@ -257,6 +257,10 @@ theorem isSome_get?_iff_mem [EquivBEq α] [LawfulHashable α] {a : α} :
(m.get? a).isSome ↔ a ∈ m :=
mem_iff_isSome_get?.symm
theorem mem_of_get?_eq_some [EquivBEq α] [LawfulHashable α] {k k' : α}
(h : m.get? k = some k') : k' ∈ m :=
HashMap.mem_of_getKey?_eq_some h
theorem get?_eq_none_of_contains_eq_false [EquivBEq α] [LawfulHashable α] {a : α} :
m.contains a = false → m.get? a = none :=
HashMap.getKey?_eq_none_of_contains_eq_false
@ -474,11 +478,15 @@ theorem contains_toList [EquivBEq α] [LawfulHashable α] {k : α} :
HashMap.contains_keys
@[simp, grind =]
theorem mem_toList [LawfulBEq α] [LawfulHashable α] {k : α} :
theorem mem_toList [LawfulBEq α] {k : α} :
k ∈ m.toList ↔ k ∈ m :=
HashMap.mem_keys
theorem distinct_toList [EquivBEq α] [LawfulHashable α]:
theorem mem_of_mem_toList [EquivBEq α] [LawfulHashable α] {k : α} :
k ∈ m.toList → k ∈ m :=
HashMap.mem_of_mem_keys
theorem distinct_toList [EquivBEq α] [LawfulHashable α] :
m.toList.Pairwise (fun a b => (a == b) = false) :=
HashMap.distinct_keys

View file

@ -269,6 +269,10 @@ theorem isSome_get?_iff_mem [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α
(m.get? a).isSome ↔ a ∈ m :=
(mem_iff_isSome_get? h).symm
theorem mem_of_get?_eq_some [EquivBEq α] [LawfulHashable α] (h : m.WF) {a a' : α} :
m.get? a = some a' → a' ∈ m :=
HashMap.Raw.mem_of_getKey?_eq_some h.out
theorem get?_eq_none_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.WF) {a : α} :
m.contains a = false → m.get? a = none :=
HashMap.Raw.getKey?_eq_none_of_contains_eq_false h.out
@ -498,10 +502,14 @@ theorem contains_toList [EquivBEq α] [LawfulHashable α] {k : α} (h : m.WF) :
HashMap.Raw.contains_keys h.1
@[simp, grind =]
theorem mem_toList [LawfulBEq α] [LawfulHashable α] (h : m.WF) {k : α} :
theorem mem_toList [LawfulBEq α] (h : m.WF) {k : α} :
k ∈ m.toList ↔ k ∈ m :=
HashMap.Raw.mem_keys h.1
theorem mem_of_mem_toList [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} :
k ∈ m.toList → k ∈ m :=
HashMap.Raw.mem_of_mem_keys h.1
theorem distinct_toList [EquivBEq α] [LawfulHashable α] (h : m.WF) :
m.toList.Pairwise (fun a b => (a == b) = false) :=
HashMap.Raw.distinct_keys h.1

View file

@ -26,7 +26,7 @@ universe u v w w'
namespace Std.TreeMap
variable {α : Type u} {β : Type v} {γ : Type w} {cmp : αα → Ordering} {t : TreeMap α β cmp}
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
@ -255,6 +255,10 @@ theorem isSome_getElem?_iff_mem [TransCmp cmp] {a : α} :
t[a]?.isSome ↔ a ∈ t :=
mem_iff_isSome_getElem?.symm
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 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
@ -292,9 +296,17 @@ 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} :
theorem getElem?_eq_some_getElem [TransCmp cmp] {a : α} (h) :
t[a]? = some (t[a]'h) :=
DTreeMap.Const.get?_eq_some_get
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') :=
@ -506,9 +518,18 @@ 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'} :
theorem getKey?_eq_some_getKey [TransCmp cmp] {a : α} (h') :
t.getKey? a = some (t.getKey a h') :=
DTreeMap.getKey?_eq_some_getKey
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 :=
@ -762,7 +783,7 @@ theorem getThenInsertIfNew?_snd [TransCmp cmp] {k : α} {v : β} :
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_some_getElem _
· exact getElem?_eq_none _
getElem!_def m a := by
rw [getElem!_eq_get!_getElem?]
@ -792,6 +813,9 @@ 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
@ -3444,4 +3468,511 @@ theorem Equiv.of_keys_unit_perm {t₁ t₂ : TreeMap α Unit cmp} : t₁.keys.Pe
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.get 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.get 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 (get 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

View file

@ -27,7 +27,7 @@ universe u v w w'
namespace Std.TreeMap.Raw
variable {α : Type u} {β : Type v} {γ : Type w} {cmp : αα → Ordering} {t : TreeMap.Raw α β cmp}
variable {α : Type u} {β : Type v} {γ : Type w} {δ : Type w'} {cmp : αα → Ordering} {t : TreeMap.Raw α β cmp}
private theorem ext {t t' : Raw α β cmp} : t.inner = t'.inner → t = t' := by
cases t; cases t'; rintro rfl; rfl
@ -292,9 +292,17 @@ theorem getElem_erase [TransCmp cmp] (h : t.WF) {k a : α} {h'} :
(t.erase k)[a]'h' = t[a]'(mem_of_mem_erase h h') :=
DTreeMap.Raw.Const.get_erase h
theorem getElem?_eq_some_getElem [TransCmp cmp] (h : t.WF) {a : α} {h'} :
theorem getElem?_eq_some_getElem [TransCmp cmp] (h : t.WF) {a : α} (h') :
t[a]? = some (t[a]'h') :=
DTreeMap.Raw.Const.get?_eq_some_get h
DTreeMap.Raw.Const.get?_eq_some_get h h'
theorem getElem_eq_get_getElem? [TransCmp cmp] (h : t.WF) {a : α} {h'} :
t[a] = t[a]?.get ((mem_iff_isSome_getElem? h).mp h') :=
DTreeMap.Raw.Const.get_eq_get_get? h
@[grind =] theorem get_getElem? [TransCmp cmp] (h : t.WF) {a : α} {h'} :
t[a]?.get h' = t[a]'((mem_iff_isSome_getElem? h).mpr h') :=
DTreeMap.Raw.Const.get_get? h
theorem getElem_congr [TransCmp cmp] (h : t.WF) {a b : α} (hab : cmp a b = .eq) {h'} :
t[a]'h' = t[b]'((mem_congr h hab).mp h') :=
@ -457,6 +465,10 @@ theorem isSome_getKey?_iff_mem [TransCmp cmp] (h : t.WF) {a : α} :
(t.getKey? a).isSome ↔ a ∈ t :=
(mem_iff_isSome_getKey? h).symm
theorem mem_of_getKey?_eq_some [TransCmp cmp] {a a' : α} (h : t.WF) :
t.getKey? a = some a' → a' ∈ t :=
DTreeMap.Raw.mem_of_getKey?_eq_some h
theorem getKey?_eq_none_of_contains_eq_false [TransCmp cmp] (h : t.WF) {a : α} :
t.contains a = false → t.getKey? a = none :=
DTreeMap.Raw.getKey?_eq_none_of_contains_eq_false h
@ -506,9 +518,18 @@ theorem getKey_erase [TransCmp cmp] (h : t.WF) {k a : α} {h'} :
(t.erase k).getKey a h' = t.getKey a (mem_of_mem_erase h h') :=
DTreeMap.Raw.getKey_erase h
theorem getKey?_eq_some_getKey [TransCmp cmp] (h : t.WF) {a : α} {h'} :
theorem getKey?_eq_some_getKey [TransCmp cmp] (h : t.WF) {a : α} (h') :
t.getKey? a = some (t.getKey a h') :=
DTreeMap.Raw.getKey?_eq_some_getKey h
DTreeMap.Raw.getKey?_eq_some_getKey h h'
theorem getKey_eq_get_getKey? [TransCmp cmp] (h : t.WF) {a : α} {h' : a ∈ t} :
t.getKey a h' = (t.getKey? a).get ((mem_iff_isSome_getKey? h).mp h') :=
DTreeMap.Raw.getKey_eq_get_getKey? h.out
@[simp, grind =]
theorem get_getKey? [TransCmp cmp] (h : t.WF) {a : α} {h'} :
(t.getKey? a).get h' = t.getKey a ((mem_iff_isSome_getKey? h).mpr h') :=
DTreeMap.Raw.get_getKey? h.out
theorem compare_getKey_self [TransCmp cmp] (h : t.WF) {k : α} (h' : k ∈ t) :
cmp (t.getKey k h') k = .eq :=
@ -786,6 +807,10 @@ theorem mem_keys [LawfulEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.keys ↔ k ∈ t :=
DTreeMap.Raw.mem_keys h
theorem mem_of_mem_keys [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.keys → k ∈ t :=
DTreeMap.Raw.mem_of_mem_keys h
theorem distinct_keys [TransCmp cmp] (h : t.WF) :
t.keys.Pairwise (fun a b => ¬ cmp a b = .eq) :=
DTreeMap.Raw.distinct_keys h
@ -3150,4 +3175,501 @@ theorem Equiv.of_keys_unit_perm {t₁ t₂ : Raw α Unit cmp} : t₁.keys.Perm t
end Equiv
section filterMap
theorem toList_filterMap {f : α → β → Option γ} (h : t.WF) :
(t.filterMap f).toList =
(t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩))) :=
DTreeMap.Raw.Const.toList_filterMap h
@[grind =]
theorem isEmpty_filterMap_iff [TransCmp cmp]
{f : α → β → Option γ} (h : t.WF) :
(t.filterMap f).isEmpty = true ↔
∀ (k : α) (h : k ∈ t), f (t.getKey k h) (t[k]'h) = none :=
DTreeMap.Raw.Const.isEmpty_filterMap_iff h.out
theorem isEmpty_filterMap_eq_false_iff [TransCmp cmp]
{f : α → β → Option γ} (h : t.WF) :
(t.filterMap f).isEmpty = false ↔
∃ (k : α) (h : k ∈ t), (f (t.getKey k h) (t[k]'h)).isSome :=
DTreeMap.Raw.Const.isEmpty_filterMap_eq_false_iff h.out
-- TODO: `contains_filterMap` is missing
@[grind =]
theorem mem_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} (h : t.WF) :
k ∈ (t.filterMap f) ↔ ∃ (g : k ∈ t),
(f (t.getKey k g) (t[k]'g)).isSome :=
DTreeMap.Raw.Const.mem_filterMap h.out
theorem mem_of_mem_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} (h : t.WF) (h' : k ∈ (t.filterMap f)) :
k ∈ t :=
DTreeMap.Raw.mem_of_mem_filterMap h.out h'
theorem size_filterMap_le_size [TransCmp cmp]
{f : α → β → Option γ} (h : t.WF) :
(t.filterMap f).size ≤ t.size :=
DTreeMap.Raw.size_filterMap_le_size h.out
grind_pattern size_filterMap_le_size => (t.filterMap f).size
theorem size_filterMap_eq_size_iff [TransCmp cmp]
{f : α → β → Option γ} (h : t.WF) :
(t.filterMap f).size = t.size ↔ ∀ (a : α) (h : a ∈ t),
(f (t.getKey a h) (t[a]'h)).isSome :=
DTreeMap.Raw.Const.size_filterMap_eq_size_iff h.out
@[simp]
theorem getElem?_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} (h : t.WF) :
(t.filterMap f)[k]? = t[k]?.pbind (fun x h' =>
f (t.getKey k ((mem_iff_isSome_getElem? h).mpr (Option.isSome_of_eq_some h'))) x) :=
DTreeMap.Raw.Const.get?_filterMap h.out
/-- Simpler variant of `getElem?_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getElem?_filterMap' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Option γ} {k : α} (h : t.WF) :
(t.filterMap f)[k]? = t[k]?.bind fun x => f k x := by
simp [getElem?_filterMap, h]
theorem getElem?_filterMap_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Option γ} {k k' : α} (h : t.WF) :
t.getKey? k = some k' → (t.filterMap f)[k]? = t[k]?.bind
fun x => f k' x :=
DTreeMap.Raw.Const.get?_filterMap_of_getKey?_eq_some h.out
theorem isSome_apply_of_mem_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} (h : t.WF) :
∀ (h' : k ∈ t.filterMap f),
(f (t.getKey k (mem_of_mem_filterMap h h'))
(t[k]'(mem_of_mem_filterMap h h'))).isSome :=
DTreeMap.Raw.Const.isSome_apply_of_mem_filterMap h.out
@[simp]
theorem getElem_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} {g} (h : t.WF) :
(t.filterMap f)[k]'g =
(f (t.getKey k (mem_of_mem_filterMap h g))
(t[k]'(mem_of_mem_filterMap h g))).get
(isSome_apply_of_mem_filterMap h g) :=
DTreeMap.Raw.Const.get_filterMap h.out (h':= g)
/-- Simpler variant of `getElem_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getElem_filterMap' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Option γ} {k : α} {g} (h : t.WF) :
(t.filterMap f)[k]'g =
(f k (t[k]'(mem_of_mem_filterMap h g))).get (by simpa [h] using isSome_apply_of_mem_filterMap h g) := by
simp [getElem_filterMap, h]
theorem getElem!_filterMap [TransCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k : α} (h : t.WF) :
(t.filterMap f)[k]! =
(t[k]?.pbind (fun x h' =>
f (t.getKey k ((mem_iff_isSome_getElem? h).mpr (Option.isSome_of_eq_some h')))
x)).get! :=
DTreeMap.Raw.Const.get!_filterMap h.out
/-- Simpler variant of `getElem!_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getElem!_filterMap' [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k : α} (h : t.WF) :
(t.filterMap f)[k]! = (t[k]?.bind (f k)).get! := by
simp [getElem!_filterMap, h]
theorem getElem!_filterMap_of_getKey?_eq_some [TransCmp cmp] [Inhabited γ]
{f : α → β → Option γ} {k k' : α} (h : t.WF) :
t.getKey? k = some k' → (t.filterMap f)[k]! = (t[k]?.bind
fun x => f k' x).get! :=
DTreeMap.Raw.Const.get!_filterMap_of_getKey?_eq_some h.out
theorem getD_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} {fallback : γ} (h : t.WF) :
getD (t.filterMap f) k fallback =
(t[k]?.pbind (fun x h' =>
f (t.getKey k ((mem_iff_isSome_getElem? h).mpr (Option.isSome_of_eq_some h'))) x)).getD fallback :=
DTreeMap.Raw.Const.getD_filterMap h.out
/-- Simpler variant of `getD_filterMap` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getD_filterMap' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Option γ} {k : α} {fallback : γ} (h : t.WF) :
getD (t.filterMap f) k fallback = (t[k]?.bind (f k)).getD fallback := by
simp [getD_filterMap, h]
theorem getD_filterMap_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Option γ} {k k' : α} {fallback : γ} (h : t.WF) :
t.getKey? k = some k' → getD (t.filterMap f) k fallback = (t[k]?.bind
fun x => f k' x).getD fallback :=
DTreeMap.Raw.Const.getD_filterMap_of_getKey?_eq_some h.out
@[grind =]
theorem getKey?_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} (h : t.WF) :
(t.filterMap f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
(f x (t[x]'(mem_of_getKey?_eq_some h h'))).isSome) :=
DTreeMap.Raw.Const.getKey?_filterMap h.out
@[simp]
theorem getKey_filterMap [TransCmp cmp]
{f : (a : α) → β → Option γ} {k : α} {h'} (h : t.WF) :
(t.filterMap f).getKey k h' = t.getKey k (mem_of_mem_filterMap h h') :=
DTreeMap.Raw.getKey_filterMap h.out
@[grind =]
theorem getKey!_filterMap [TransCmp cmp] [Inhabited α]
{f : α → β → Option γ} {k : α} (h : t.WF) :
(t.filterMap f).getKey! k =
((t.getKey? k).pfilter (fun x h' =>
(f x (t[x]'(mem_of_getKey?_eq_some h h'))).isSome)).get! :=
DTreeMap.Raw.Const.getKey!_filterMap h.out
@[grind =]
theorem getKeyD_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k fallback : α} (h : t.WF) :
(t.filterMap f).getKeyD k fallback =
((t.getKey? k).pfilter (fun x h' =>
(f x (t[x]'(mem_of_getKey?_eq_some h h'))).isSome)).getD fallback :=
DTreeMap.Raw.Const.getKeyD_filterMap h.out
end filterMap
section filter
theorem filterMap_equiv_filter {f : α → β → Bool} (h : t.WF) :
(t.filterMap (fun k => Option.guard (fun v => f k v))) ~m (t.filter f) :=
⟨DTreeMap.Raw.filterMap_equiv_filter h.out⟩
theorem toList_filter
{f : (a : α) → β → Bool} (h : t.WF) :
(t.filter f).toList = t.toList.filter (fun p => f p.1 p.2) :=
DTreeMap.Raw.Const.toList_filter h.out
theorem keys_filter_key {f : α → Bool} (h : t.WF) :
(t.filter fun k _ => f k).keys = t.keys.filter f :=
DTreeMap.Raw.keys_filter_key h.out
@[grind =]
theorem isEmpty_filter_iff [TransCmp cmp]
{f : α → β → Bool} (h : t.WF) :
(t.filter f).isEmpty = true ↔
∀ (k : α) (h : k ∈ t), f (t.getKey k h) (t[k]' h) = false :=
DTreeMap.Raw.Const.isEmpty_filter_iff h.out
theorem isEmpty_filter_eq_false_iff [TransCmp cmp]
{f : α → β → Bool} (h : t.WF) :
(t.filter f).isEmpty = false ↔
∃ (k : α) (h : k ∈ t), f (t.getKey k h) (t[k]'h) :=
DTreeMap.Raw.Const.isEmpty_filter_eq_false_iff h.out
-- TODO: `contains_filter` is missing
@[grind =]
theorem mem_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} (h : t.WF) :
k ∈ t.filter f ↔ ∃ (h' : k ∈ t),
f (t.getKey k h') (t[k]' h') :=
DTreeMap.Raw.Const.mem_filter h.out
theorem mem_of_mem_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} (h : t.WF) :
k ∈ t.filter f → k ∈ t :=
DTreeMap.Raw.mem_of_mem_filter h.out
theorem size_filter_le_size [TransCmp cmp]
{f : α → β → Bool} (h : t.WF) :
(t.filter f).size ≤ t.size :=
DTreeMap.Raw.size_filter_le_size h.out
grind_pattern size_filter_le_size => (t.filter f).size
theorem size_filter_eq_size_iff [TransCmp cmp]
{f : α → β → Bool} (h : t.WF) :
(t.filter f).size = t.size ↔ ∀ (a : α) (h : a ∈ t),
f (t.getKey a h) t[a] :=
DTreeMap.Raw.Const.size_filter_eq_size_iff h.out
theorem filter_equiv_self_iff [TransCmp cmp]
{f : α → β → Bool} (h : t.WF) :
(t.filter f) ~m t ↔ ∀ (a : α) (h : a ∈ t),
f (t.getKey a h) t[a] :=
⟨fun h' => (DTreeMap.Raw.Const.filter_equiv_self_iff h.out).mp h'.1,
fun h' => ⟨(DTreeMap.Raw.Const.filter_equiv_self_iff h.out).mpr h'⟩⟩
@[simp]
theorem getElem?_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} (h : t.WF) :
(t.filter f)[k]? = t[k]?.pfilter (fun x h' =>
f (t.getKey k ((mem_iff_isSome_getElem? h).mpr (Option.isSome_of_eq_some h'))) x) :=
DTreeMap.Raw.Const.get?_filter h.out
/-- Simpler variant of `getElem?_filter` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getElem?_filter' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Bool} {k : α} (h : t.WF) :
(t.filter f)[k]? = t[k]?.filter (f k) := by
simp [getElem?_filter, h]
theorem getElem?_filter_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Bool} {k k' : α} (h : t.WF) :
t.getKey? k = some k' →
(t.filter f)[k]? = t[k]?.filter (f k') :=
DTreeMap.Raw.Const.get?_filter_of_getKey?_eq_some h.out
@[simp, grind =]
theorem getElem_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} {h'} (h : t.WF) :
(t.filter f)[k]' h' = t[k]' (mem_of_mem_filter h h') :=
DTreeMap.Raw.Const.get_filter h.out (h' := h')
theorem getElem!_filter [TransCmp cmp] [Inhabited β]
{f : α → β → Bool} {k : α} (h : t.WF) :
(t.filter f)[k]! =
(t[k]?.pfilter (fun x h' =>
f (t.getKey k ((mem_iff_isSome_getElem? h).mpr (Option.isSome_of_eq_some h'))) x)).get! :=
DTreeMap.Raw.Const.get!_filter h.out
/-- Simpler variant of `getElem!_filter` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getElem!_filter' [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited β]
{f : α → β → Bool} {k : α} (h : t.WF) :
(t.filter f)[k]! = (t[k]?.filter (f k)).get! := by
simp [getElem!_filter, h]
theorem getElem!_filter_of_getKey?_eq_some [TransCmp cmp] [Inhabited β]
{f : α → β → Bool} {k k' : α} (h : t.WF) :
t.getKey? k = some k' →
(t.filter f)[k]! = (t[k]?.filter (fun x => f k' x)).get! :=
DTreeMap.Raw.Const.get!_filter_of_getKey?_eq_some h.out
theorem getD_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} {fallback : β} (h : t.WF) :
getD (t.filter f) k fallback = (t[k]?.pfilter (fun x h' =>
f (t.getKey k ((mem_iff_isSome_getElem? h).mpr (Option.isSome_of_eq_some h'))) x)).getD fallback :=
DTreeMap.Raw.Const.getD_filter h.out
/-- Simpler variant of `getD_filter` when `LawfulEqCmp` is available. -/
@[grind =]
theorem getD_filter' [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → Bool} {k : α} {fallback : β} (h : t.WF) :
getD (t.filter f) k fallback = (t[k]?.filter (f k)).getD fallback := by
simp [getD_filter, h]
theorem getD_filter_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → Bool} {k k' : α} {fallback : β} (h : t.WF) :
t.getKey? k = some k' →
getD (t.filter f) k fallback =
(t[k]?.filter (fun x => f k' x)).getD fallback :=
DTreeMap.Raw.Const.getD_filter_of_getKey?_eq_some h.out
theorem keys_filter [TransCmp cmp] {f : α → β → Bool} (h : t.WF) :
(t.filter f).keys =
(t.keys.attach.filter (fun ⟨x, h'⟩ => f x (t[x]' (mem_of_mem_keys h h')))).unattach :=
DTreeMap.Raw.Const.keys_filter h.out
@[grind =]
theorem getKey?_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} (h : t.WF) :
(t.filter f).getKey? k =
(t.getKey? k).pfilter (fun x h' =>
(f x (t[x]' (mem_of_getKey?_eq_some h h')))) :=
DTreeMap.Raw.Const.getKey?_filter h.out
theorem getKey?_filter_key [TransCmp cmp]
{f : α → Bool} {k : α} (h : t.WF) :
(t.filter fun k _ => f k).getKey? k = (t.getKey? k).filter f :=
DTreeMap.Raw.getKey?_filter_key h.out
@[simp, grind =]
theorem getKey_filter [TransCmp cmp]
{f : α → β → Bool} {k : α} (h : t.WF) {h'} :
(t.filter f).getKey k h' = t.getKey k (mem_of_mem_filter h h') :=
DTreeMap.Raw.getKey_filter h.out
@[grind =]
theorem getKey!_filter [TransCmp cmp] [Inhabited α]
{f : α → β → Bool} {k : α} (h : t.WF) :
(t.filter f).getKey! k =
((t.getKey? k).pfilter (fun x h' =>
(f x (t[x]' (mem_of_getKey?_eq_some h h'))))).get! :=
DTreeMap.Raw.Const.getKey!_filter h.out
theorem getKey!_filter_key [TransCmp cmp] [Inhabited α]
{f : α → Bool} {k : α} (h : t.WF) :
(t.filter fun k _ => f k).getKey! k = ((t.getKey? k).filter f).get! :=
DTreeMap.Raw.getKey!_filter_key h.out
@[grind =]
theorem getKeyD_filter [TransCmp cmp]
{f : α → β → Bool} {k fallback : α} (h : t.WF) :
(t.filter f).getKeyD k fallback =
((t.getKey? k).pfilter (fun x h' =>
(f x (t[x]' (mem_of_getKey?_eq_some h h'))))).getD fallback :=
DTreeMap.Raw.Const.getKeyD_filter h.out
theorem getKeyD_filter_key [TransCmp cmp]
{f : α → Bool} {k fallback : α} (h : t.WF) :
(t.filter fun k _ => f k).getKeyD k fallback = ((t.getKey? k).filter f).getD fallback :=
DTreeMap.Raw.getKeyD_filter_key h.out
end filter
section map
theorem map_id_equiv : (t.map fun _ v => v) ~m t :=
⟨DTreeMap.Raw.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.Raw.map_map_equiv⟩
theorem toList_map {f : (a : α) → β → γ} :
(t.map f).toList = t.toList.map (fun p => ⟨p.1, f p.1 p.2⟩) :=
DTreeMap.Raw.Const.toList_map
theorem keys_map {f : α → β → γ} : (t.map f).keys = t.keys :=
DTreeMap.Raw.keys_map
theorem filterMap_equiv_map [TransCmp cmp]
{f : α → β → γ} (h : t.WF) :
(t.filterMap (fun k v => Option.some (f k v))) ~m (t.map f) :=
⟨DTreeMap.Raw.filterMap_equiv_map h.out⟩
@[simp, grind =]
theorem isEmpty_map [TransCmp cmp] {f : α → β → γ} :
(t.map f).isEmpty = t.isEmpty :=
DTreeMap.Raw.isEmpty_map
@[simp, grind =]
theorem contains_map [TransCmp cmp]
{f : α → β → γ} {k : α} (h : t.WF) :
(t.map f).contains k = t.contains k :=
DTreeMap.Raw.contains_map h.out
theorem contains_of_contains_map [TransCmp cmp]
{f : α → β → γ} {k : α} (h : t.WF) :
(t.map f).contains k = true → t.contains k = true :=
DTreeMap.Raw.contains_of_contains_map h.out
@[simp, grind =]
theorem mem_map [TransCmp cmp]
{f : (a : α) → β → γ} {k : α} (h : t.WF) :
k ∈ (t.map f) ↔ k ∈ t :=
DTreeMap.Raw.mem_map h.out
theorem mem_of_mem_map [TransCmp cmp]
{f : α → β → γ} {k : α} (h : t.WF) :
k ∈ (t.map f) → k ∈ t :=
DTreeMap.Raw.mem_of_mem_map h.out
@[simp, grind =]
theorem size_map [TransCmp cmp] {f : α → β → γ} :
(t.map f).size = t.size :=
DTreeMap.Raw.size_map
@[simp, grind =]
theorem getKey?_map [TransCmp cmp]
{f : α → β → γ} {k : α} (h : t.WF) :
(t.map f).getKey? k = t.getKey? k :=
DTreeMap.Raw.getKey?_map h.out
@[simp, grind =]
theorem getKey_map [TransCmp cmp]
{f : α → β → γ} {k : α} {h'} (h : t.WF) :
(t.map f).getKey k h' = t.getKey k (mem_of_mem_map h h') :=
DTreeMap.Raw.getKey_map h.out
@[simp, grind =]
theorem getKey!_map [TransCmp cmp] [Inhabited α]
{f : α → β → γ} {k : α} (h : t.WF) :
(t.map f).getKey! k = t.getKey! k :=
DTreeMap.Raw.getKey!_map h.out
@[simp, grind =]
theorem getKeyD_map [TransCmp cmp]
{f : α → β → γ} {k fallback : α} (h : t.WF) :
(t.map f).getKeyD k fallback = t.getKeyD k fallback :=
DTreeMap.Raw.getKeyD_map h.out
@[simp, grind =]
theorem getElem?_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} (h : t.WF) :
(t.map f)[k]? = t[k]?.map (f k) :=
DTreeMap.Raw.Const.get?_map h.out
/-- Variant of `getElem?_map` that holds without `LawfulEqCmp`. -/
@[simp (low)]
theorem getElem?_map' [TransCmp cmp]
{f : α → β → γ} {k : α} (h : t.WF) :
(t.map f)[k]? = t[k]?.pmap (fun v h' => f (t.getKey k h') v)
(fun _ h' => (mem_iff_isSome_getElem? h).mpr (Option.isSome_of_eq_some h')) :=
DTreeMap.Raw.Const.get?_map' h.out
theorem getElem?_map_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → γ} {k k' : α} (h : t.WF) (h' : t.getKey? k = some k') :
(t.map f)[k]? = t[k]?.map (f k') :=
DTreeMap.Raw.Const.get?_map_of_getKey?_eq_some h.out h'
@[simp, grind =]
theorem getElem_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} {h'} (h : t.WF) :
(t.map f)[k]' h' =
(f k (t[k]' (mem_of_mem_map h h'))) :=
DTreeMap.Raw.Const.get_map h.out (h':= h')
/-- Variant of `getElem_map` that holds without `LawfulEqCmp`. -/
@[simp (low)]
theorem getElem_map' [TransCmp cmp]
{f : α → β → γ} {k : α} {h'} (h : t.WF) :
(t.map f)[k]' h' =
(f (t.getKey k (mem_of_mem_map h h'))
(t[k]' (mem_of_mem_map h h'))) :=
DTreeMap.Raw.Const.get_map' h.out (h':= h')
@[grind =]
theorem getElem!_map [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited γ]
{f : α → β → γ} {k : α} (h : t.WF) :
(t.map f)[k]! =
(t[k]?.map (f k)).get! :=
DTreeMap.Raw.Const.get!_map h.out
/-- Variant of `getElem!_map` that holds without `LawfulEqCmp`. -/
theorem getElem!_map' [TransCmp cmp] [Inhabited γ]
{f : α → β → γ} {k : α} (h : t.WF) :
(t.map f)[k]! =
((get? t k).pmap (fun v h => f (t.getKey k h) v)
(fun _ h' => (mem_iff_isSome_getElem? h).mpr (Option.isSome_of_eq_some h'))).get! :=
DTreeMap.Raw.Const.get!_map' h.out
theorem getElem!_map_of_getKey?_eq_some [TransCmp cmp] [Inhabited γ]
{f : α → β → γ} {k k' : α} (h : t.WF) (h' : t.getKey? k = some k') :
(t.map f)[k]! = (t[k]?.map (f k')).get! :=
DTreeMap.Raw.Const.get!_map_of_getKey?_eq_some h.out h'
@[grind =]
theorem getD_map [TransCmp cmp] [LawfulEqCmp cmp]
{f : α → β → γ} {k : α} {fallback : γ} (h : t.WF) :
(t.map f).getD k fallback =
(t[k]?.map (f k)).getD fallback :=
DTreeMap.Raw.Const.getD_map h.out
/-- Variant of `getD_map` that holds without `LawfulEqCmp`. -/
theorem getD_map' [TransCmp cmp]
{f : α → β → γ} {k : α} {fallback : γ} (h : t.WF) :
getD (t.map f) k fallback =
((get? t k).pmap (fun v h => f (t.getKey k h) v)
(fun _ h' => (mem_iff_isSome_getElem? h).mpr (Option.isSome_of_eq_some h'))).getD fallback :=
DTreeMap.Raw.Const.getD_map' h.out
theorem getD_map_of_getKey?_eq_some [TransCmp cmp]
{f : α → β → γ} {k k' : α} {fallback : γ} (h : t.WF) (h' : t.getKey? k = some k') :
(t.map f).getD k fallback = (t[k]?.map (f k')).getD fallback :=
DTreeMap.Raw.Const.getD_map_of_getKey?_eq_some h.out h'
end map
end Std.TreeMap.Raw

View file

@ -65,31 +65,31 @@ theorem not_mem_emptyc {k : α} : k ∉ (∅ : TreeSet α cmp) :=
theorem contains_of_isEmpty [TransCmp cmp] {a : α} :
t.isEmpty → t.contains a = false :=
DTreeMap.contains_of_isEmpty
TreeMap.contains_of_isEmpty
theorem not_mem_of_isEmpty [TransCmp cmp] {a : α} :
t.isEmpty → a ∉ t :=
DTreeMap.not_mem_of_isEmpty
TreeMap.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
TreeMap.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
TreeMap.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
TreeMap.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
TreeMap.isEmpty_iff_forall_contains
theorem isEmpty_iff_forall_not_mem [TransCmp cmp] :
t.isEmpty = true ↔ ∀ a, ¬a ∈ t :=
DTreeMap.isEmpty_iff_forall_not_mem
TreeMap.isEmpty_iff_forall_not_mem
@[simp]
theorem insert_eq_insert {p : α} : Insert.insert p t = t.insert p :=
@ -165,7 +165,7 @@ theorem isEmpty_erase [TransCmp cmp] {k : α} :
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
TreeMap.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) :
@ -224,6 +224,19 @@ theorem isSome_get?_eq_contains [TransCmp cmp] {a : α} :
(t.get? a).isSome = t.contains a :=
contains_eq_isSome_get?.symm
theorem mem_iff_isSome_get? [TransCmp cmp] {a : α} :
a ∈ t ↔ (t.get? a).isSome :=
TreeMap.mem_iff_isSome_getKey?
@[simp]
theorem isSome_get?_iff_mem [TransCmp cmp] {a : α} :
(t.get? a).isSome ↔ a ∈ t :=
mem_iff_isSome_get?.symm
theorem mem_of_get?_eq_some [TransCmp cmp] {k k' : α}
(h : t.get? k = some k') : k' ∈ t :=
TreeMap.mem_of_getKey?_eq_some h
theorem get?_eq_none_of_contains_eq_false [TransCmp cmp] {a : α} :
t.contains a = false → t.get? a = none :=
TreeMap.getKey?_eq_none_of_contains_eq_false
@ -241,21 +254,21 @@ theorem get?_erase_self [TransCmp cmp] {k : α} :
(t.erase k).get? k = none :=
TreeMap.getKey?_erase_self
theorem get?_beq [TransCmp cmp] {k : α} :
theorem compare_getKey?_self [TransCmp cmp] {k : α} :
(t.get? k).all (cmp · k = .eq) :=
DTreeMap.compare_getKey?_self
TreeMap.compare_getKey?_self
theorem get?_congr [TransCmp cmp] {k k' : α} (h' : cmp k k' = .eq) :
t.get? k = t.get? k' :=
DTreeMap.getKey?_congr h'
TreeMap.getKey?_congr h'
theorem get?_eq_some_of_contains [TransCmp cmp] [LawfulEqCmp cmp] {k : α} (h' : t.contains k) :
t.get? k = some k :=
DTreeMap.getKey?_eq_some_of_contains h'
TreeMap.getKey?_eq_some_of_contains h'
theorem get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} (h' : k ∈ t) :
t.get? k = some k :=
DTreeMap.getKey?_eq_some_of_contains h'
TreeMap.getKey?_eq_some_of_contains h'
@[grind =] theorem get_insert [TransCmp cmp] {k a : α} {h₁} :
(t.insert k).get a h₁ =
@ -267,22 +280,30 @@ theorem get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} (h' : k ∈ t) :
(t.erase k).get a h' = t.get a (mem_of_mem_erase h') :=
TreeMap.getKey_erase
theorem get?_eq_some_get [TransCmp cmp] {a : α} {h'} :
theorem get?_eq_some_get [TransCmp cmp] {a : α} (h') :
t.get? a = some (t.get a h') :=
TreeMap.getKey?_eq_some_getKey
TreeMap.getKey?_eq_some_getKey h'
theorem get_beq [TransCmp cmp] {k : α} (h' : k ∈ t) :
theorem get_eq_get_get? [TransCmp cmp] {k : α} {h} :
t.get k h = (t.get? k).get (mem_iff_isSome_get?.mp h) :=
TreeMap.getKey_eq_get_getKey?
@[grind =] theorem get_get? [TransCmp cmp] {k : α} {h} :
(t.get? k).get h = t.get k (mem_iff_isSome_get?.mpr h) :=
TreeMap.get_getKey?
theorem compare_get_self [TransCmp cmp] {k : α} (h' : k ∈ t) :
cmp (t.get k h') k = .eq :=
DTreeMap.compare_getKey_self h'
TreeMap.compare_getKey_self h'
theorem get_congr [TransCmp cmp] {k₁ k₂ : α} (h' : cmp k₁ k₂ = .eq)
(h₁ : k₁ ∈ t) : t.get k₁ h₁ = t.get k₂ ((mem_congr h').mp h₁) :=
DTreeMap.getKey_congr h' h₁
TreeMap.getKey_congr h' h₁
@[simp, grind =]
theorem get_eq [TransCmp cmp] [LawfulEqCmp cmp] {k : α} (h' : k ∈ t) :
t.get k h' = k :=
DTreeMap.getKey_eq h'
TreeMap.getKey_eq h'
@[simp, grind =]
theorem get!_emptyc {a : α} [Inhabited α] :
@ -332,16 +353,16 @@ theorem get_eq_get! [TransCmp cmp] [Inhabited α] {a : α} {h} :
theorem get!_congr [TransCmp cmp] [Inhabited α] {k k' : α} (h' : cmp k k' = .eq) :
t.get! k = t.get! k' :=
DTreeMap.getKey!_congr h'
TreeMap.getKey!_congr h'
theorem get!_eq_of_contains [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] {k : α}
(h' : t.contains k) :
t.get! k = k :=
DTreeMap.getKey!_eq_of_contains h'
TreeMap.getKey!_eq_of_contains h'
theorem get!_eq_of_mem [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] {k : α} (h' : k ∈ t) :
t.get! k = k :=
DTreeMap.getKey!_eq_of_mem h'
TreeMap.getKey!_eq_of_mem h'
@[simp, grind =]
theorem getD_emptyc {a : α} {fallback : α} :
@ -397,15 +418,15 @@ theorem get!_eq_getD_default [TransCmp cmp] [Inhabited α] {a : α} :
theorem getD_congr [TransCmp cmp] {k k' fallback : α} (h' : cmp k k' = .eq) :
t.getD k fallback = t.getD k' fallback :=
DTreeMap.getKeyD_congr h'
TreeMap.getKeyD_congr h'
theorem getD_eq_of_contains [TransCmp cmp] [LawfulEqCmp cmp] {k fallback : α} (h' : t.contains k) :
t.getD k fallback = k :=
DTreeMap.getKeyD_eq_of_contains h'
TreeMap.getKeyD_eq_of_contains h'
theorem getD_eq_of_mem [TransCmp cmp] [LawfulEqCmp cmp] {k fallback : α} (h' : k ∈ t) :
t.getD k fallback = k :=
DTreeMap.getKeyD_eq_of_contains h'
TreeMap.getKeyD_eq_of_contains h'
@[simp, grind =]
theorem containsThenInsert_fst [TransCmp cmp] {k : α} :
@ -420,30 +441,34 @@ theorem containsThenInsert_snd [TransCmp cmp] {k : α} :
@[simp, grind =]
theorem length_toList [TransCmp cmp] :
t.toList.length = t.size :=
DTreeMap.length_keys
TreeMap.length_keys
@[simp, grind =]
theorem isEmpty_toList :
t.toList.isEmpty = t.isEmpty :=
DTreeMap.isEmpty_keys
TreeMap.isEmpty_keys
@[simp, grind =]
theorem contains_toList [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] {k : α} :
t.toList.contains k = t.contains k :=
DTreeMap.contains_keys
TreeMap.contains_keys
@[simp]
theorem mem_toList [LawfulEqCmp cmp] [TransCmp cmp] {k : α} :
k ∈ t.toList ↔ k ∈ t :=
DTreeMap.mem_keys
TreeMap.mem_keys
theorem mem_of_mem_toList [TransCmp cmp] {k : α} :
k ∈ t.toList → k ∈ t :=
TreeMap.mem_of_mem_keys
theorem distinct_toList [TransCmp cmp] :
t.toList.Pairwise (fun a b => ¬ cmp a b = .eq) :=
DTreeMap.distinct_keys
TreeMap.distinct_keys
theorem ordered_toList [TransCmp cmp] :
t.toList.Pairwise (fun a b => cmp a b = .lt) :=
DTreeMap.ordered_keys
TreeMap.ordered_keys
section monadic
@ -746,7 +771,7 @@ theorem isSome_min?_eq_not_isEmpty [TransCmp cmp] :
theorem isSome_min?_iff_isEmpty_eq_false [TransCmp cmp] :
t.min?.isSome ↔ t.isEmpty = false :=
DTreeMap.isSome_minKey?_iff_isEmpty_eq_false
TreeMap.isSome_minKey?_iff_isEmpty_eq_false
@[grind =] theorem min?_insert [TransCmp cmp] {k} :
(t.insert k).min? =
@ -797,19 +822,19 @@ theorem le_min? [TransCmp cmp] {k} :
theorem get?_min? [TransCmp cmp] {km} :
(hkm : t.min? = some km) → t.get? km = some km :=
DTreeMap.getKey?_minKey?
TreeMap.getKey?_minKey?
theorem get_min? [TransCmp cmp] {km hc} :
(hkm : t.min?.get (isSome_min?_of_contains hc) = km) → t.get km hc = km :=
DTreeMap.getKey_minKey?
TreeMap.getKey_minKey?
theorem get!_min? [TransCmp cmp] [Inhabited α] {km} :
(hkm : t.min? = some km) → t.get! km = km :=
DTreeMap.getKey!_minKey?
TreeMap.getKey!_minKey?
theorem getD_min? [TransCmp cmp] {km fallback} :
(hkm : t.min? = some km) → t.getD km fallback = km :=
DTreeMap.getKeyD_minKey?
TreeMap.getKeyD_minKey?
@[simp]
theorem min?_bind_get? [TransCmp cmp] :
@ -861,164 +886,164 @@ theorem min_eq_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] {he km} :
@[grind =] theorem min_insert [TransCmp cmp] {k} :
(t.insert k).min isEmpty_insert =
t.min?.elim k fun k' => if cmp k k' = .lt then k else k' :=
DTreeMap.minKey_insertIfNew
TreeMap.minKey_insertIfNew
theorem min_insert_le_min [TransCmp cmp] {k he} :
cmp (t.insert k |>.min isEmpty_insert)
(t.min he) |>.isLE :=
DTreeMap.minKey_insertIfNew_le_minKey
TreeMap.minKey_insertIfNew_le_minKey
theorem min_insert_le_self [TransCmp cmp] {k} :
cmp (t.insert k |>.min <| isEmpty_insert) k |>.isLE :=
DTreeMap.minKey_insertIfNew_le_self
TreeMap.minKey_insertIfNew_le_self
@[grind =] theorem contains_min [TransCmp cmp] {he} :
t.contains (t.min he) :=
DTreeMap.contains_minKey
TreeMap.contains_minKey
@[grind] theorem min_mem [TransCmp cmp] {he} :
t.min he ∈ t :=
DTreeMap.minKey_mem
TreeMap.minKey_mem
theorem min_le_of_contains [TransCmp cmp] {k} (hc : t.contains k) :
cmp (t.min <| isEmpty_eq_false_iff_exists_contains_eq_true.mpr ⟨k, hc⟩) k |>.isLE :=
DTreeMap.minKey_le_of_contains hc
TreeMap.minKey_le_of_contains hc
theorem min_le_of_mem [TransCmp cmp] {k} (hc : k ∈ t) :
cmp (t.min <| isEmpty_eq_false_iff_exists_contains_eq_true.mpr ⟨k, hc⟩) k |>.isLE :=
DTreeMap.minKey_le_of_mem hc
TreeMap.minKey_le_of_mem hc
theorem le_min [TransCmp cmp] {k he} :
(cmp k (t.min he)).isLE ↔ (∀ k', k' ∈ t → (cmp k k').isLE) :=
DTreeMap.le_minKey
TreeMap.le_minKey
@[simp, grind =]
theorem get?_min [TransCmp cmp] {he} :
t.get? (t.min he) = some (t.min he) :=
DTreeMap.getKey?_minKey
TreeMap.getKey?_minKey
@[simp, grind =]
theorem get_min [TransCmp cmp] {he hc} :
t.get (t.min he) hc = t.min he :=
DTreeMap.getKey_minKey
TreeMap.getKey_minKey
@[simp, grind =]
theorem get!_min [TransCmp cmp] [Inhabited α] {he} :
t.get! (t.min he) = t.min he :=
DTreeMap.getKey!_minKey
TreeMap.getKey!_minKey
@[simp, grind =]
theorem getD_min [TransCmp cmp] {he fallback} :
t.getD (t.min he) fallback = t.min he :=
DTreeMap.getKeyD_minKey
TreeMap.getKeyD_minKey
@[simp]
theorem min_erase_eq_iff_not_compare_eq_min [TransCmp cmp] {k he} :
(t.erase k |>.min he) =
t.min (isEmpty_eq_false_of_isEmpty_erase_eq_false he) ↔
¬ cmp k (t.min <| isEmpty_eq_false_of_isEmpty_erase_eq_false he) = .eq :=
DTreeMap.minKey_erase_eq_iff_not_compare_eq_minKey
TreeMap.minKey_erase_eq_iff_not_compare_eq_minKey
theorem min_erase_eq_of_not_compare_eq_min [TransCmp cmp] {k he} :
(hc : ¬ cmp k (t.min (isEmpty_eq_false_of_isEmpty_erase_eq_false he)) = .eq) →
(t.erase k |>.min he) =
t.min (isEmpty_eq_false_of_isEmpty_erase_eq_false he) :=
DTreeMap.minKey_erase_eq_of_not_compare_eq_minKey
TreeMap.minKey_erase_eq_of_not_compare_eq_minKey
theorem min_le_min_erase [TransCmp cmp] {k he} :
cmp (t.min <| isEmpty_eq_false_of_isEmpty_erase_eq_false he)
(t.erase k |>.min he) |>.isLE :=
DTreeMap.minKey_le_minKey_erase
TreeMap.minKey_le_minKey_erase
theorem min_eq_head_toList [TransCmp cmp] {he} :
t.min he = t.toList.head (List.isEmpty_eq_false_iff.mp <| isEmpty_toList ▸ he) :=
DTreeMap.minKey_eq_head_keys
TreeMap.minKey_eq_head_keys
theorem min?_eq_some_min! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.min? = some t.min! :=
DTreeMap.minKey?_eq_some_minKey! he
TreeMap.minKey?_eq_some_minKey! he
theorem min_eq_min! [TransCmp cmp] [Inhabited α] {he : t.isEmpty = false} :
t.min he = t.min! :=
DTreeMap.minKey_eq_minKey!
TreeMap.minKey_eq_minKey!
theorem min!_eq_default [TransCmp cmp] [Inhabited α] (he : t.isEmpty) :
t.min! = default :=
DTreeMap.minKey!_eq_default he
TreeMap.minKey!_eq_default he
theorem min!_eq_iff_get?_eq_self_and_forall [TransCmp cmp] [Inhabited α]
(he : t.isEmpty = false) {km} :
t.min! = km ↔ t.get? km = some km ∧ ∀ k, k ∈ t → (cmp km k).isLE :=
DTreeMap.minKey!_eq_iff_getKey?_eq_self_and_forall he
TreeMap.minKey!_eq_iff_getKey?_eq_self_and_forall he
theorem min!_eq_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α]
(he : t.isEmpty = false) {km} :
t.min! = km ↔ km ∈ t ∧ ∀ k, k ∈ t → (cmp km k).isLE :=
DTreeMap.minKey!_eq_iff_mem_and_forall he
TreeMap.minKey!_eq_iff_mem_and_forall he
@[grind =] theorem min!_insert [TransCmp cmp] [Inhabited α] {k} :
(t.insert k |>.min!) =
t.min?.elim k fun k' => if cmp k k' = .lt then k else k' :=
DTreeMap.minKey!_insertIfNew
TreeMap.minKey!_insertIfNew
theorem min!_insert_le_min! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {k} :
cmp (t.insert k |>.min!) t.min! |>.isLE :=
DTreeMap.minKey!_insertIfNew_le_minKey! he
TreeMap.minKey!_insertIfNew_le_minKey! he
theorem min!_insert_le_self [TransCmp cmp] [Inhabited α] {k} :
cmp (t.insert k |>.min!) k |>.isLE :=
DTreeMap.minKey!_insertIfNew_le_self
TreeMap.minKey!_insertIfNew_le_self
@[grind =] theorem contains_min! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.contains t.min! :=
DTreeMap.contains_minKey! he
TreeMap.contains_minKey! he
@[grind] theorem min!_mem [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.min! ∈ t :=
DTreeMap.minKey!_mem he
TreeMap.minKey!_mem he
theorem min!_le_of_contains [TransCmp cmp] [Inhabited α] {k} (hc : t.contains k) :
cmp t.min! k |>.isLE :=
DTreeMap.minKey!_le_of_contains hc
TreeMap.minKey!_le_of_contains hc
theorem min!_le_of_mem [TransCmp cmp] [Inhabited α] {k} (hc : k ∈ t) :
cmp t.min! k |>.isLE :=
DTreeMap.minKey!_le_of_mem hc
TreeMap.minKey!_le_of_mem hc
theorem le_min! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {k} :
(cmp k t.min!).isLE ↔ (∀ k', k' ∈ t → (cmp k k').isLE) :=
DTreeMap.le_minKey! he
TreeMap.le_minKey! he
theorem get?_min! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.get? t.min! = some t.min! :=
DTreeMap.getKey?_minKey! he
TreeMap.getKey?_minKey! he
@[grind =] theorem get_min! [TransCmp cmp] [Inhabited α] {hc} :
t.get t.min! hc = t.min! :=
DTreeMap.getKey_minKey!
TreeMap.getKey_minKey!
@[simp, grind =]
theorem get_min!_eq_min [TransCmp cmp] [Inhabited α] {hc} :
t.get t.min! hc = t.min (isEmpty_eq_false_of_contains hc) :=
DTreeMap.getKey_minKey!_eq_minKey
TreeMap.getKey_minKey!_eq_minKey
theorem get!_min! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.get! t.min! = t.min! :=
DTreeMap.getKey!_minKey! he
TreeMap.getKey!_minKey! he
theorem getD_min! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {fallback} :
t.getD t.min! fallback = t.min! :=
DTreeMap.getKeyD_minKey! he
TreeMap.getKeyD_minKey! he
theorem min!_erase_eq_of_not_compare_min!_eq [TransCmp cmp] [Inhabited α] {k}
(he : (t.erase k).isEmpty = false) (heq : ¬ cmp k t.min! = .eq) :
(t.erase k |>.min!) = t.min! :=
DTreeMap.minKey!_erase_eq_of_not_compare_minKey!_eq he heq
TreeMap.minKey!_erase_eq_of_not_compare_minKey!_eq he heq
theorem min!_le_min!_erase [TransCmp cmp] [Inhabited α] {k}
(he : (t.erase k).isEmpty = false) :
cmp t.min! (t.erase k |>.min!) |>.isLE :=
DTreeMap.minKey!_le_minKey!_erase he
TreeMap.minKey!_le_minKey!_erase he
theorem min!_eq_head!_toList [TransCmp cmp] [Inhabited α] :
t.min! = t.toList.head! :=
@ -1148,7 +1173,7 @@ theorem isSome_max?_eq_not_isEmpty [TransCmp cmp] :
theorem isSome_max?_iff_isEmpty_eq_false [TransCmp cmp] :
t.max?.isSome ↔ t.isEmpty = false :=
DTreeMap.isSome_maxKey?_iff_isEmpty_eq_false
TreeMap.isSome_maxKey?_iff_isEmpty_eq_false
@[grind =] theorem max?_insert [TransCmp cmp] {k} :
(t.insert k).max? =
@ -1199,19 +1224,19 @@ theorem max?_le [TransCmp cmp] {k} :
theorem get?_max? [TransCmp cmp] {km} :
(hkm : t.max? = some km) → t.get? km = some km :=
DTreeMap.getKey?_maxKey?
TreeMap.getKey?_maxKey?
theorem get_max? [TransCmp cmp] {km hc} :
(hkm : t.max?.get (isSome_max?_of_contains hc) = km) → t.get km hc = km :=
DTreeMap.getKey_maxKey?
TreeMap.getKey_maxKey?
theorem get!_max? [TransCmp cmp] [Inhabited α] {km} :
(hkm : t.max? = some km) → t.get! km = km :=
DTreeMap.getKey!_maxKey?
TreeMap.getKey!_maxKey?
theorem getD_max? [TransCmp cmp] {km fallback} :
(hkm : t.max? = some km) → t.getD km fallback = km :=
DTreeMap.getKeyD_maxKey?
TreeMap.getKeyD_maxKey?
@[simp]
theorem max?_bind_get? [TransCmp cmp] :
@ -1339,89 +1364,89 @@ theorem max_eq_getLast_toList [TransCmp cmp] {he} :
theorem max?_eq_some_max! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.max? = some t.max! :=
DTreeMap.maxKey?_eq_some_maxKey! he
TreeMap.maxKey?_eq_some_maxKey! he
theorem max_eq_max! [TransCmp cmp] [Inhabited α] {he : t.isEmpty = false} :
t.max he = t.max! :=
DTreeMap.maxKey_eq_maxKey!
TreeMap.maxKey_eq_maxKey!
theorem max!_eq_default [TransCmp cmp] [Inhabited α] (he : t.isEmpty) :
t.max! = default :=
DTreeMap.maxKey!_eq_default he
TreeMap.maxKey!_eq_default he
theorem max!_eq_iff_get?_eq_self_and_forall [TransCmp cmp] [Inhabited α]
(he : t.isEmpty = false) {km} :
t.max! = km ↔ t.get? km = some km ∧ ∀ k, k ∈ t → (cmp k km).isLE :=
DTreeMap.maxKey!_eq_iff_getKey?_eq_self_and_forall he
TreeMap.maxKey!_eq_iff_getKey?_eq_self_and_forall he
theorem max!_eq_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α]
(he : t.isEmpty = false) {km} :
t.max! = km ↔ km ∈ t ∧ ∀ k, k ∈ t → (cmp k km).isLE :=
DTreeMap.maxKey!_eq_iff_mem_and_forall he
TreeMap.maxKey!_eq_iff_mem_and_forall he
@[grind =] theorem max!_insert [TransCmp cmp] [Inhabited α] {k} :
(t.insert k |>.max!) =
t.max?.elim k fun k' => if cmp k' k = .lt then k else k' :=
DTreeMap.maxKey!_insertIfNew
TreeMap.maxKey!_insertIfNew
theorem max!_le_max!_insert [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {k} :
cmp t.max! (t.insert k |>.max!) |>.isLE :=
DTreeMap.maxKey!_le_maxKey!_insertIfNew he
TreeMap.maxKey!_le_maxKey!_insertIfNew he
theorem self_le_max!_insert [TransCmp cmp] [Inhabited α] {k} :
cmp k (t.insert k |>.max!) |>.isLE :=
DTreeMap.self_le_maxKey!_insertIfNew
TreeMap.self_le_maxKey!_insertIfNew
@[grind =] theorem contains_max! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.contains t.max! :=
DTreeMap.contains_maxKey! he
TreeMap.contains_maxKey! he
@[grind] theorem max!_mem [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.max! ∈ t :=
DTreeMap.maxKey!_mem he
TreeMap.maxKey!_mem he
theorem le_max!_of_contains [TransCmp cmp] [Inhabited α] {k} (hc : t.contains k) :
cmp k t.max! |>.isLE :=
DTreeMap.le_maxKey!_of_contains hc
TreeMap.le_maxKey!_of_contains hc
theorem le_max!_of_mem [TransCmp cmp] [Inhabited α] {k} (hc : k ∈ t) :
cmp k t.max! |>.isLE :=
DTreeMap.le_maxKey!_of_mem hc
TreeMap.le_maxKey!_of_mem hc
theorem max!_le [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {k} :
(cmp t.max! k).isLE ↔ (∀ k', k' ∈ t → (cmp k' k).isLE) :=
DTreeMap.maxKey!_le he
TreeMap.maxKey!_le he
theorem get?_max! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.get? t.max! = some t.max! :=
DTreeMap.getKey?_maxKey! he
TreeMap.getKey?_maxKey! he
@[grind =] theorem get_max! [TransCmp cmp] [Inhabited α] {hc} :
t.get t.max! hc = t.max! :=
DTreeMap.getKey_maxKey!
TreeMap.getKey_maxKey!
@[simp, grind =]
theorem get_max!_eq_max [TransCmp cmp] [Inhabited α] {hc} :
t.get t.max! hc = t.max (isEmpty_eq_false_of_contains hc) :=
DTreeMap.getKey_maxKey!_eq_maxKey
TreeMap.getKey_maxKey!_eq_maxKey
theorem get!_max! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.get! t.max! = t.max! :=
DTreeMap.getKey!_maxKey! he
TreeMap.getKey!_maxKey! he
theorem getD_max! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) {fallback} :
t.getD t.max! fallback = t.max! :=
DTreeMap.getKeyD_maxKey! he
TreeMap.getKeyD_maxKey! he
theorem max!_erase_eq_of_not_compare_max!_eq [TransCmp cmp] [Inhabited α] {k}
(he : (t.erase k).isEmpty = false) (heq : ¬ cmp k t.max! = .eq) :
(t.erase k |>.max!) = t.max! :=
DTreeMap.maxKey!_erase_eq_of_not_compare_maxKey!_eq he heq
TreeMap.maxKey!_erase_eq_of_not_compare_maxKey!_eq he heq
theorem max!_erase_le_max! [TransCmp cmp] [Inhabited α] {k}
(he : (t.erase k).isEmpty = false) :
cmp (t.erase k |>.max!) t.max! |>.isLE :=
DTreeMap.maxKey!_erase_le_maxKey! he
TreeMap.maxKey!_erase_le_maxKey! he
@[grind =_]
theorem max!_eq_getLast!_toList [TransCmp cmp] [Inhabited α] :
@ -1776,4 +1801,84 @@ theorem equiv_iff_toList_eq [TransCmp cmp] :
end Equiv
section filter
variable {t : TreeSet α cmp}
theorem toList_filter {f : α → Bool} :
(t.filter f).toList = t.toList.filter f :=
TreeMap.keys_filter_key
@[grind =] theorem isEmpty_filter_iff [TransCmp cmp]
{f : α → Bool} :
(t.filter f).isEmpty ↔ ∀ k h, f (t.get k h) = false :=
TreeMap.isEmpty_filter_iff
theorem isEmpty_filter_eq_false_iff [TransCmp cmp]
{f : α → Bool} :
(t.filter f).isEmpty = false ↔ ∃ k h, f (t.get k h) :=
TreeMap.isEmpty_filter_eq_false_iff
-- TODO: `contains_filter` is missing.
@[simp, grind =]
theorem mem_filter [TransCmp cmp]
{f : α → Bool} {k : α} :
k ∈ t.filter f ↔ ∃ h, f (t.get k h) :=
TreeMap.mem_filter
theorem contains_of_contains_filter [TransCmp cmp]
{f : α → Bool} {k : α} :
(t.filter f).contains k → t.contains k :=
TreeMap.contains_of_contains_filter
theorem mem_of_mem_filter [TransCmp cmp]
{f : α → Bool} {k : α} :
k ∈ t.filter f → k ∈ t :=
TreeMap.mem_of_mem_filter
theorem size_filter_le_size [TransCmp cmp]
{f : α → Bool} :
(t.filter f).size ≤ t.size :=
TreeMap.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.get k h) :=
TreeMap.size_filter_eq_size_iff
theorem filter_equiv_self_iff [TransCmp cmp]
{f : α → Bool} :
t.filter f ~m t ↔ ∀ k h, f (t.get k h) :=
⟨fun h => TreeMap.filter_equiv_self_iff.mp h.1,
fun h => ⟨TreeMap.filter_equiv_self_iff.mpr h⟩⟩
@[simp, grind =]
theorem get?_filter [TransCmp cmp]
{f : α → Bool} {k : α} :
(t.filter f).get? k = (t.get? k).filter f :=
TreeMap.getKey?_filter_key
@[simp, grind =]
theorem get_filter [TransCmp cmp]
{f : α → Bool} {k : α} {h} :
(t.filter f).get k h = t.get k (mem_of_mem_filter h) :=
TreeMap.getKey_filter
@[grind =]
theorem get!_filter [TransCmp cmp] [Inhabited α]
{f : α → Bool} {k : α} :
(t.filter f).get! k = ((t.get? k).filter f).get! :=
TreeMap.getKey!_filter_key
@[grind =]
theorem getD_filter [TransCmp cmp]
{f : α → Bool} {k fallback : α} :
(t.filter f).getD k fallback = ((t.get? k).filter f).getD fallback :=
TreeMap.getKeyD_filter_key
end filter
end Std.TreeSet

View file

@ -65,19 +65,19 @@ theorem not_mem_emptyc {k : α} : k ∉ (∅ : Raw α cmp) :=
theorem contains_of_isEmpty [TransCmp cmp] (h : t.WF) {a : α} :
t.isEmpty → t.contains a = false :=
DTreeMap.Raw.contains_of_isEmpty h
TreeMap.Raw.contains_of_isEmpty h
theorem not_mem_of_isEmpty [TransCmp cmp] (h : t.WF) {a : α} :
t.isEmpty → a ∉ t :=
DTreeMap.Raw.not_mem_of_isEmpty h
TreeMap.Raw.not_mem_of_isEmpty h
theorem isEmpty_eq_false_iff_exists_contains_eq_true [TransCmp cmp] (h : t.WF) :
t.isEmpty = false ↔ ∃ a, t.contains a = true :=
DTreeMap.Raw.isEmpty_eq_false_iff_exists_contains_eq_true h
TreeMap.Raw.isEmpty_eq_false_iff_exists_contains_eq_true h
theorem isEmpty_eq_false_iff_exists_mem [TransCmp cmp] (h : t.WF) :
t.isEmpty = false ↔ ∃ a, a ∈ t :=
DTreeMap.Raw.isEmpty_eq_false_iff_exists_mem h
TreeMap.Raw.isEmpty_eq_false_iff_exists_mem h
theorem isEmpty_eq_false_of_contains [TransCmp cmp] (h : t.WF) {a : α} (hc : t.contains a = true) :
t.isEmpty = false :=
@ -85,11 +85,11 @@ theorem isEmpty_eq_false_of_contains [TransCmp cmp] (h : t.WF) {a : α} (hc : t.
theorem isEmpty_iff_forall_contains [TransCmp cmp] (h : t.WF) :
t.isEmpty = true ↔ ∀ a, t.contains a = false :=
DTreeMap.Raw.isEmpty_iff_forall_contains h
TreeMap.Raw.isEmpty_iff_forall_contains h
theorem isEmpty_iff_forall_not_mem [TransCmp cmp] (h : t.WF) :
t.isEmpty = true ↔ ∀ a, ¬a ∈ t :=
DTreeMap.Raw.isEmpty_iff_forall_not_mem h
TreeMap.Raw.isEmpty_iff_forall_not_mem h
@[simp]
theorem insert_eq_insert {p : α} : Insert.insert p t = t.insert p :=
@ -222,6 +222,19 @@ theorem isSome_get?_eq_contains [TransCmp cmp] (h : t.WF) {a : α} :
(t.get? a).isSome = t.contains a :=
(contains_eq_isSome_get? h).symm
theorem mem_iff_isSome_get? [TransCmp cmp] (h : t.WF) {a : α} :
a ∈ t ↔ (t.get? a).isSome :=
TreeMap.Raw.mem_iff_isSome_getKey? h
@[simp]
theorem isSome_get?_iff_mem [TransCmp cmp] (h : t.WF) {a : α} :
(t.get? a).isSome ↔ a ∈ t :=
(mem_iff_isSome_get? h).symm
theorem mem_of_get?_eq_some [TransCmp cmp] (h : t.WF) {a a' : α} :
t.get? a = some a' → a' ∈ t :=
TreeMap.Raw.mem_of_getKey?_eq_some h
theorem get?_eq_none_of_contains_eq_false [TransCmp cmp] (h : t.WF) {a : α} :
t.contains a = false → t.get? a = none :=
TreeMap.Raw.getKey?_eq_none_of_contains_eq_false h
@ -239,7 +252,7 @@ theorem get?_erase_self [TransCmp cmp] (h : t.WF) {k : α} :
(t.erase k).get? k = none :=
TreeMap.Raw.getKey?_erase_self h
theorem get?_beq [TransCmp cmp] (h : t.WF) {k : α} :
theorem compare_get?_self [TransCmp cmp] (h : t.WF) {k : α} :
(t.get? k).all (cmp · k = .eq) :=
TreeMap.Raw.compare_getKey?_self h
@ -267,11 +280,20 @@ theorem get_erase [TransCmp cmp] (h : t.WF) {k a : α} {h'} :
(t.erase k).get a h' = t.get a (mem_of_mem_erase h h') :=
TreeMap.Raw.getKey_erase h
theorem get?_eq_some_get [TransCmp cmp] (h : t.WF) {a : α} {h'} :
theorem get?_eq_some_get [TransCmp cmp] (h : t.WF) {a : α} (h') :
t.get? a = some (t.get a h') :=
TreeMap.Raw.getKey?_eq_some_getKey h
TreeMap.Raw.getKey?_eq_some_getKey h h'
theorem get_beq [TransCmp cmp] (h : t.WF) {k : α} (h' : k ∈ t) :
theorem get_eq_get_get? [TransCmp cmp] (h : t.WF) {a : α} {h' : a ∈ t} :
t.get a h' = (t.get? a).get ((mem_iff_isSome_get? h).mp h') :=
TreeMap.Raw.getKey_eq_get_getKey? h.out
@[simp, grind =]
theorem get_get? [TransCmp cmp] (h : t.WF) {a : α} {h'} :
(t.get? a).get h' = t.get a ((mem_iff_isSome_get? h).mpr h') :=
TreeMap.Raw.get_getKey? h.out
theorem compare_get_self [TransCmp cmp] (h : t.WF) {k : α} (h' : k ∈ t) :
cmp (t.get k h') k = .eq :=
TreeMap.Raw.compare_getKey_self h h'
@ -421,30 +443,34 @@ theorem containsThenInsert_snd [TransCmp cmp] (h : t.WF) {k : α} :
@[simp, grind =]
theorem length_toList [TransCmp cmp] (h : t.WF) :
t.toList.length = t.size :=
DTreeMap.Raw.length_keys h
TreeMap.Raw.length_keys h
@[simp, grind =]
theorem isEmpty_toList :
t.toList.isEmpty = t.isEmpty :=
DTreeMap.Raw.isEmpty_keys
TreeMap.Raw.isEmpty_keys
@[simp, grind =]
theorem contains_toList [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} :
t.toList.contains k = t.contains k :=
DTreeMap.Raw.contains_keys h
TreeMap.Raw.contains_keys h
@[simp, grind =]
theorem mem_toList [LawfulEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.toList ↔ k ∈ t :=
DTreeMap.Raw.mem_keys h
TreeMap.Raw.mem_keys h
theorem mem_of_mem_toList [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.toList → k ∈ t :=
TreeMap.Raw.mem_of_mem_keys h
theorem distinct_toList [TransCmp cmp] (h : t.WF) :
t.toList.Pairwise (fun a b => ¬ cmp a b = .eq) :=
DTreeMap.Raw.distinct_keys h
TreeMap.Raw.distinct_keys h
theorem ordered_toList [TransCmp cmp] (h : t.WF) :
t.toList.Pairwise (fun a b => cmp a b = .lt) :=
DTreeMap.Raw.ordered_keys h
TreeMap.Raw.ordered_keys h
section monadic
@ -723,11 +749,11 @@ theorem min?_eq_none_iff [TransCmp cmp] (h : t.WF) :
theorem min?_eq_some_iff_get?_eq_self_and_forall [TransCmp cmp] (h : t.WF) {km} :
t.min? = some km ↔ t.get? km = some km ∧ ∀ k ∈ t, (cmp km k).isLE :=
DTreeMap.Raw.minKey?_eq_some_iff_getKey?_eq_self_and_forall h
TreeMap.Raw.minKey?_eq_some_iff_getKey?_eq_self_and_forall h
theorem min?_eq_some_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {km} :
t.min? = some km ↔ km ∈ t ∧ ∀ k ∈ t, (cmp km k).isLE :=
DTreeMap.Raw.minKey?_eq_some_iff_mem_and_forall h
TreeMap.Raw.minKey?_eq_some_iff_mem_and_forall h
@[simp, grind =]
theorem isNone_min?_eq_isEmpty [TransCmp cmp] (h : t.WF) :
@ -841,81 +867,81 @@ theorem min?_eq_head?_toList [TransCmp cmp] (h : t.WF) :
theorem min?_eq_some_min! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) :
t.min? = some t.min! :=
DTreeMap.Raw.minKey?_eq_some_minKey! h he
TreeMap.Raw.minKey?_eq_some_minKey! h he
theorem min!_eq_default [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty) :
t.min! = default :=
DTreeMap.Raw.minKey!_eq_default h he
TreeMap.Raw.minKey!_eq_default h he
theorem min!_eq_iff_get?_eq_self_and_forall [TransCmp cmp] [Inhabited α] (h : t.WF)
(he : t.isEmpty = false) {km} :
t.min! = km ↔ t.get? km = some km ∧ ∀ k, k ∈ t → (cmp km k).isLE :=
DTreeMap.Raw.minKey!_eq_iff_getKey?_eq_self_and_forall h he
TreeMap.Raw.minKey!_eq_iff_getKey?_eq_self_and_forall h he
theorem min!_eq_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] (h : t.WF)
(he : t.isEmpty = false) {km} :
t.min! = km ↔ km ∈ t ∧ ∀ k, k ∈ t → (cmp km k).isLE :=
DTreeMap.Raw.minKey!_eq_iff_mem_and_forall h he
TreeMap.Raw.minKey!_eq_iff_mem_and_forall h he
@[grind =] theorem min!_insert [TransCmp cmp] [Inhabited α] (h : t.WF) {k} :
(t.insert k |>.min!) =
t.min?.elim k fun k' => if cmp k k' = .lt then k else k' :=
DTreeMap.Raw.minKey!_insertIfNew h
TreeMap.Raw.minKey!_insertIfNew h
theorem min!_insert_le_min! [TransCmp cmp] [Inhabited α] (h : t.WF)
(he : t.isEmpty = false) {k} :
cmp (t.insert k |>.min!) t.min! |>.isLE :=
DTreeMap.Raw.minKey!_insertIfNew_le_minKey! h he
TreeMap.Raw.minKey!_insertIfNew_le_minKey! h he
theorem min!_insert_le_self [TransCmp cmp] [Inhabited α] (h : t.WF) {k} :
cmp (t.insert k |>.min!) k |>.isLE :=
DTreeMap.Raw.minKey!_insertIfNew_le_self h
TreeMap.Raw.minKey!_insertIfNew_le_self h
@[grind =] theorem contains_min! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) :
t.contains t.min! :=
DTreeMap.Raw.contains_minKey! h he
TreeMap.Raw.contains_minKey! h he
@[grind] theorem min!_mem [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) :
t.min! ∈ t :=
DTreeMap.Raw.minKey!_mem h he
TreeMap.Raw.minKey!_mem h he
theorem min!_le_of_contains [TransCmp cmp] [Inhabited α] (h : t.WF) {k} (hc : t.contains k) :
cmp t.min! k |>.isLE :=
DTreeMap.Raw.minKey!_le_of_contains h hc
TreeMap.Raw.minKey!_le_of_contains h hc
theorem min!_le_of_mem [TransCmp cmp] [Inhabited α] (h : t.WF) {k} (hc : k ∈ t) :
cmp t.min! k |>.isLE :=
DTreeMap.Raw.minKey!_le_of_mem h hc
TreeMap.Raw.minKey!_le_of_mem h hc
theorem le_min! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) {k} :
(cmp k t.min!).isLE ↔ (∀ k', k' ∈ t → (cmp k k').isLE) :=
DTreeMap.Raw.le_minKey! h he
TreeMap.Raw.le_minKey! h he
theorem get?_min! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) :
t.get? t.min! = some t.min! :=
DTreeMap.Raw.getKey?_minKey! h he
TreeMap.Raw.getKey?_minKey! h he
theorem get_min! [TransCmp cmp] [Inhabited α] (h : t.WF) {hc} :
t.get t.min! hc = t.min! :=
DTreeMap.Raw.getKey_minKey! h
TreeMap.Raw.getKey_minKey! h
theorem get!_min! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) :
t.get! t.min! = t.min! :=
DTreeMap.Raw.getKey!_minKey! h he
TreeMap.Raw.getKey!_minKey! h he
theorem getD_min! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) {fallback} :
t.getD t.min! fallback = t.min! :=
DTreeMap.Raw.getKeyD_minKey! h he
TreeMap.Raw.getKeyD_minKey! h he
theorem min!_erase_eq_of_not_compare_min!_eq [TransCmp cmp] [Inhabited α] (h : t.WF) {k}
(he : (t.erase k).isEmpty = false) (heq : ¬ cmp k t.min! = .eq) :
(t.erase k |>.min!) = t.min! :=
DTreeMap.Raw.minKey!_erase_eq_of_not_compare_minKey!_eq h he heq
TreeMap.Raw.minKey!_erase_eq_of_not_compare_minKey!_eq h he heq
theorem min!_le_min!_erase [TransCmp cmp] [Inhabited α] (h : t.WF) {k}
(he : (t.erase k).isEmpty = false) :
cmp t.min! (t.erase k |>.min!) |>.isLE :=
DTreeMap.Raw.minKey!_le_minKey!_erase h he
TreeMap.Raw.minKey!_le_minKey!_erase h he
@[grind =_]
theorem min!_eq_head!_toList [TransCmp cmp] [Inhabited α] (h : t.WF) :
@ -924,85 +950,85 @@ theorem min!_eq_head!_toList [TransCmp cmp] [Inhabited α] (h : t.WF) :
theorem min?_eq_some_minD [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {fallback} :
t.min? = some (t.minD fallback) :=
DTreeMap.Raw.minKey?_eq_some_minKeyD h he
TreeMap.Raw.minKey?_eq_some_minKeyD h he
theorem minD_eq_fallback [TransCmp cmp] (h : t.WF) (he : t.isEmpty) {fallback} :
t.minD fallback = fallback :=
DTreeMap.Raw.minKeyD_eq_fallback h he
TreeMap.Raw.minKeyD_eq_fallback h he
theorem min!_eq_minD_default [TransCmp cmp] [Inhabited α] (h : t.WF) :
t.min! = t.minD default :=
DTreeMap.Raw.minKey!_eq_minKeyD_default h
TreeMap.Raw.minKey!_eq_minKeyD_default h
theorem minD_eq_iff_get?_eq_self_and_forall [TransCmp cmp] (h : t.WF)
(he : t.isEmpty = false) {km fallback} :
t.minD fallback = km ↔ t.get? km = some km ∧ ∀ k, k ∈ t → (cmp km k).isLE :=
DTreeMap.Raw.minKeyD_eq_iff_getKey?_eq_self_and_forall h he
TreeMap.Raw.minKeyD_eq_iff_getKey?_eq_self_and_forall h he
theorem minD_eq_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF)
(he : t.isEmpty = false) {km fallback} :
t.minD fallback = km ↔ km ∈ t ∧ ∀ k, k ∈ t → (cmp km k).isLE :=
DTreeMap.Raw.minKeyD_eq_iff_mem_and_forall h he
TreeMap.Raw.minKeyD_eq_iff_mem_and_forall h he
@[grind =] theorem minD_insert [TransCmp cmp] (h : t.WF) {k fallback} :
(t.insert k |>.minD fallback) =
t.min?.elim k fun k' => if cmp k k' = .lt then k else k' :=
DTreeMap.Raw.minKeyD_insertIfNew h
TreeMap.Raw.minKeyD_insertIfNew h
theorem minD_insert_le_minD [TransCmp cmp] (h : t.WF)
(he : t.isEmpty = false) {k fallback} :
cmp (t.insert k |>.minD fallback) (t.minD fallback) |>.isLE :=
DTreeMap.Raw.minKeyD_insertIfNew_le_minKeyD h he
TreeMap.Raw.minKeyD_insertIfNew_le_minKeyD h he
theorem minD_insert_le_self [TransCmp cmp] (h : t.WF) {k fallback} :
cmp (t.insert k |>.minD fallback) k |>.isLE :=
DTreeMap.Raw.minKeyD_insertIfNew_le_self h
TreeMap.Raw.minKeyD_insertIfNew_le_self h
@[grind =] theorem contains_minD [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {fallback} :
t.contains (t.minD fallback) :=
DTreeMap.Raw.contains_minKeyD h he
TreeMap.Raw.contains_minKeyD h he
@[grind] theorem minD_mem [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {fallback} :
t.minD fallback ∈ t :=
DTreeMap.Raw.minKeyD_mem h he
TreeMap.Raw.minKeyD_mem h he
theorem minD_le_of_contains [TransCmp cmp] (h : t.WF) {k} (hc : t.contains k) {fallback} :
cmp (t.minD fallback) k |>.isLE :=
DTreeMap.Raw.minKeyD_le_of_contains h hc
TreeMap.Raw.minKeyD_le_of_contains h hc
theorem minD_le_of_mem [TransCmp cmp] (h : t.WF) {k} (hc : k ∈ t) {fallback} :
cmp (t.minD fallback) k |>.isLE :=
DTreeMap.Raw.minKeyD_le_of_mem h hc
TreeMap.Raw.minKeyD_le_of_mem h hc
theorem le_minD [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {k fallback} :
(cmp k (t.minD fallback)).isLE ↔ (∀ k', k' ∈ t → (cmp k k').isLE) :=
DTreeMap.Raw.le_minKeyD h he
TreeMap.Raw.le_minKeyD h he
theorem get?_minD [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {fallback} :
t.get? (t.minD fallback) = some (t.minD fallback) :=
DTreeMap.Raw.getKey?_minKeyD h he
TreeMap.Raw.getKey?_minKeyD h he
theorem get_minD [TransCmp cmp] (h : t.WF) {fallback hc} :
t.get (t.minD fallback) hc = t.minD fallback :=
DTreeMap.Raw.getKey_minKeyD h
TreeMap.Raw.getKey_minKeyD h
theorem get!_minD [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) {fallback} :
t.get! (t.minD fallback) = t.minD fallback :=
DTreeMap.Raw.getKey!_minKeyD h he
TreeMap.Raw.getKey!_minKeyD h he
theorem getD_minD [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {fallback fallback'} :
t.getD (t.minD fallback) fallback' = t.minD fallback :=
DTreeMap.Raw.getKeyD_minKeyD h he
TreeMap.Raw.getKeyD_minKeyD h he
theorem minD_erase_eq_of_not_compare_minD_eq [TransCmp cmp] (h : t.WF) {k fallback}
(he : (t.erase k).isEmpty = false) (heq : ¬ cmp k (t.minD fallback) = .eq) :
(t.erase k |>.minD fallback) = t.minD fallback :=
DTreeMap.Raw.minKeyD_erase_eq_of_not_compare_minKeyD_eq h he heq
TreeMap.Raw.minKeyD_erase_eq_of_not_compare_minKeyD_eq h he heq
theorem minD_le_minD_erase [TransCmp cmp] (h : t.WF) {k}
(he : (t.erase k).isEmpty = false) {fallback} :
cmp (t.minD fallback) (t.erase k |>.minD fallback) |>.isLE :=
DTreeMap.Raw.minKeyD_le_minKeyD_erase h he
TreeMap.Raw.minKeyD_le_minKeyD_erase h he
@[grind =_]
theorem minD_eq_headD_toList [TransCmp cmp] (h : t.WF) {fallback} :
@ -1029,11 +1055,11 @@ theorem max?_eq_none_iff [TransCmp cmp] (h : t.WF) :
theorem max?_eq_some_iff_get?_eq_self_and_forall [TransCmp cmp] (h : t.WF) {km} :
t.max? = some km ↔ t.get? km = some km ∧ ∀ k ∈ t, (cmp k km).isLE :=
DTreeMap.Raw.maxKey?_eq_some_iff_getKey?_eq_self_and_forall h
TreeMap.Raw.maxKey?_eq_some_iff_getKey?_eq_self_and_forall h
theorem max?_eq_some_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {km} :
t.max? = some km ↔ km ∈ t ∧ ∀ k ∈ t, (cmp k km).isLE :=
DTreeMap.Raw.maxKey?_eq_some_iff_mem_and_forall h
TreeMap.Raw.maxKey?_eq_some_iff_mem_and_forall h
@[simp, grind =]
theorem isNone_max?_eq_isEmpty [TransCmp cmp] (h : t.WF) :
@ -1151,81 +1177,81 @@ theorem max?_eq_head?_toList [TransCmp cmp] (h : t.WF) :
theorem max?_eq_some_max! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) :
t.max? = some t.max! :=
DTreeMap.Raw.maxKey?_eq_some_maxKey! h he
TreeMap.Raw.maxKey?_eq_some_maxKey! h he
theorem max!_eq_default [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty) :
t.max! = default :=
DTreeMap.Raw.maxKey!_eq_default h he
TreeMap.Raw.maxKey!_eq_default h he
theorem max!_eq_iff_get?_eq_self_and_forall [TransCmp cmp] [Inhabited α] (h : t.WF)
(he : t.isEmpty = false) {km} :
t.max! = km ↔ t.get? km = some km ∧ ∀ k, k ∈ t → (cmp k km).isLE :=
DTreeMap.Raw.maxKey!_eq_iff_getKey?_eq_self_and_forall h he
TreeMap.Raw.maxKey!_eq_iff_getKey?_eq_self_and_forall h he
theorem max!_eq_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] (h : t.WF)
(he : t.isEmpty = false) {km} :
t.max! = km ↔ km ∈ t ∧ ∀ k, k ∈ t → (cmp k km).isLE :=
DTreeMap.Raw.maxKey!_eq_iff_mem_and_forall h he
TreeMap.Raw.maxKey!_eq_iff_mem_and_forall h he
@[grind =] theorem max!_insert [TransCmp cmp] [Inhabited α] (h : t.WF) {k} :
(t.insert k |>.max!) =
t.max?.elim k fun k' => if cmp k' k = .lt then k else k' :=
DTreeMap.Raw.maxKey!_insertIfNew h
TreeMap.Raw.maxKey!_insertIfNew h
theorem max!_le_max!_insert [TransCmp cmp] [Inhabited α] (h : t.WF)
(he : t.isEmpty = false) {k} :
cmp t.max! (t.insert k |>.max!) |>.isLE :=
DTreeMap.Raw.maxKey!_le_maxKey!_insertIfNew h he
TreeMap.Raw.maxKey!_le_maxKey!_insertIfNew h he
theorem self_le_max!_insert [TransCmp cmp] [Inhabited α] (h : t.WF) {k} :
cmp k (t.insert k |>.max!) |>.isLE :=
DTreeMap.Raw.self_le_maxKey!_insertIfNew h
TreeMap.Raw.self_le_maxKey!_insertIfNew h
@[grind =] theorem contains_max! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) :
t.contains t.max! :=
DTreeMap.Raw.contains_maxKey! h he
TreeMap.Raw.contains_maxKey! h he
@[grind] theorem max!_mem [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) :
t.max! ∈ t :=
DTreeMap.Raw.maxKey!_mem h he
TreeMap.Raw.maxKey!_mem h he
theorem le_max!_of_contains [TransCmp cmp] [Inhabited α] (h : t.WF) {k} (hc : t.contains k) :
cmp k t.max! |>.isLE :=
DTreeMap.Raw.le_maxKey!_of_contains h hc
TreeMap.Raw.le_maxKey!_of_contains h hc
theorem le_max!_of_mem [TransCmp cmp] [Inhabited α] (h : t.WF) {k} (hc : k ∈ t) :
cmp k t.max! |>.isLE :=
DTreeMap.Raw.le_maxKey!_of_mem h hc
TreeMap.Raw.le_maxKey!_of_mem h hc
theorem max!_le [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) {k} :
(cmp t.max! k).isLE ↔ (∀ k', k' ∈ t → (cmp k' k).isLE) :=
DTreeMap.Raw.maxKey!_le h he
TreeMap.Raw.maxKey!_le h he
theorem get?_max! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) :
t.get? t.max! = some t.max! :=
DTreeMap.Raw.getKey?_maxKey! h he
TreeMap.Raw.getKey?_maxKey! h he
theorem get_max! [TransCmp cmp] [Inhabited α] (h : t.WF) {hc} :
t.get t.max! hc = t.max! :=
DTreeMap.Raw.getKey_maxKey! h
TreeMap.Raw.getKey_maxKey! h
theorem get!_max! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) :
t.get! t.max! = t.max! :=
DTreeMap.Raw.getKey!_maxKey! h he
TreeMap.Raw.getKey!_maxKey! h he
theorem getD_max! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) {fallback} :
t.getD t.max! fallback = t.max! :=
DTreeMap.Raw.getKeyD_maxKey! h he
TreeMap.Raw.getKeyD_maxKey! h he
theorem max!_erase_eq_of_not_compare_max!_eq [TransCmp cmp] [Inhabited α] (h : t.WF) {k}
(he : (t.erase k).isEmpty = false) (heq : ¬ cmp k t.max! = .eq) :
(t.erase k |>.max!) = t.max! :=
DTreeMap.Raw.maxKey!_erase_eq_of_not_compare_maxKey!_eq h he heq
TreeMap.Raw.maxKey!_erase_eq_of_not_compare_maxKey!_eq h he heq
theorem max!_erase_le_max! [TransCmp cmp] [Inhabited α] (h : t.WF) {k}
(he : (t.erase k).isEmpty = false) :
cmp (t.erase k |>.max!) t.max! |>.isLE :=
DTreeMap.Raw.maxKey!_erase_le_maxKey! h he
TreeMap.Raw.maxKey!_erase_le_maxKey! h he
@[grind =_]
theorem max!_eq_getLast!_toList [TransCmp cmp] [Inhabited α] (h : t.WF) :
@ -1234,85 +1260,85 @@ theorem max!_eq_getLast!_toList [TransCmp cmp] [Inhabited α] (h : t.WF) :
theorem max?_eq_some_maxD [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {fallback} :
t.max? = some (t.maxD fallback) :=
DTreeMap.Raw.maxKey?_eq_some_maxKeyD h he
TreeMap.Raw.maxKey?_eq_some_maxKeyD h he
theorem maxD_eq_fallback [TransCmp cmp] (h : t.WF) (he : t.isEmpty) {fallback} :
t.maxD fallback = fallback :=
DTreeMap.Raw.maxKeyD_eq_fallback h he
TreeMap.Raw.maxKeyD_eq_fallback h he
theorem max!_eq_maxD_default [TransCmp cmp] [Inhabited α] (h : t.WF) :
t.max! = t.maxD default :=
DTreeMap.Raw.maxKey!_eq_maxKeyD_default h
TreeMap.Raw.maxKey!_eq_maxKeyD_default h
theorem maxD_eq_iff_get?_eq_self_and_forall [TransCmp cmp] (h : t.WF)
(he : t.isEmpty = false) {km fallback} :
t.maxD fallback = km ↔ t.get? km = some km ∧ ∀ k, k ∈ t → (cmp k km).isLE :=
DTreeMap.Raw.maxKeyD_eq_iff_getKey?_eq_self_and_forall h he
TreeMap.Raw.maxKeyD_eq_iff_getKey?_eq_self_and_forall h he
theorem maxD_eq_iff_mem_and_forall [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF)
(he : t.isEmpty = false) {km fallback} :
t.maxD fallback = km ↔ km ∈ t ∧ ∀ k, k ∈ t → (cmp k km).isLE :=
DTreeMap.Raw.maxKeyD_eq_iff_mem_and_forall h he
TreeMap.Raw.maxKeyD_eq_iff_mem_and_forall h he
@[grind =] theorem maxD_insert [TransCmp cmp] (h : t.WF) {k fallback} :
(t.insert k |>.maxD fallback) =
t.max?.elim k fun k' => if cmp k' k = .lt then k else k' :=
DTreeMap.Raw.maxKeyD_insertIfNew h
TreeMap.Raw.maxKeyD_insertIfNew h
theorem maxD_le_maxD_insert [TransCmp cmp] (h : t.WF)
(he : t.isEmpty = false) {k fallback} :
cmp (t.maxD fallback) (t.insert k |>.maxD fallback) |>.isLE :=
DTreeMap.Raw.maxKeyD_le_maxKeyD_insertIfNew h he
TreeMap.Raw.maxKeyD_le_maxKeyD_insertIfNew h he
theorem self_le_maxD_insert [TransCmp cmp] (h : t.WF) {k fallback} :
cmp k (t.insert k |>.maxD fallback) |>.isLE :=
DTreeMap.Raw.self_le_maxKeyD_insertIfNew h
TreeMap.Raw.self_le_maxKeyD_insertIfNew h
@[grind =] theorem contains_maxD [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {fallback} :
t.contains (t.maxD fallback) :=
DTreeMap.Raw.contains_maxKeyD h he
TreeMap.Raw.contains_maxKeyD h he
@[grind] theorem maxD_mem [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {fallback} :
t.maxD fallback ∈ t :=
DTreeMap.Raw.maxKeyD_mem h he
TreeMap.Raw.maxKeyD_mem h he
theorem le_maxD_of_contains [TransCmp cmp] (h : t.WF) {k} (hc : t.contains k) {fallback} :
cmp k (t.maxD fallback) |>.isLE :=
DTreeMap.Raw.le_maxKeyD_of_contains h hc
TreeMap.Raw.le_maxKeyD_of_contains h hc
theorem le_maxD_of_mem [TransCmp cmp] (h : t.WF) {k} (hc : k ∈ t) {fallback} :
cmp k (t.maxD fallback) |>.isLE :=
DTreeMap.Raw.le_maxKeyD_of_mem h hc
TreeMap.Raw.le_maxKeyD_of_mem h hc
theorem maxD_le [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {k fallback} :
(cmp (t.maxD fallback) k).isLE ↔ (∀ k', k' ∈ t → (cmp k' k).isLE) :=
DTreeMap.Raw.maxKeyD_le h he
TreeMap.Raw.maxKeyD_le h he
theorem get?_maxD [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {fallback} :
t.get? (t.maxD fallback) = some (t.maxD fallback) :=
DTreeMap.Raw.getKey?_maxKeyD h he
TreeMap.Raw.getKey?_maxKeyD h he
theorem get_maxD [TransCmp cmp] (h : t.WF) {fallback hc} :
t.get (t.maxD fallback) hc = t.maxD fallback :=
DTreeMap.Raw.getKey_maxKeyD h
TreeMap.Raw.getKey_maxKeyD h
theorem get!_maxD [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) {fallback} :
t.get! (t.maxD fallback) = t.maxD fallback :=
DTreeMap.Raw.getKey!_maxKeyD h he
TreeMap.Raw.getKey!_maxKeyD h he
theorem getD_maxD [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {fallback fallback'} :
t.getD (t.maxD fallback) fallback' = t.maxD fallback :=
DTreeMap.Raw.getKeyD_maxKeyD h he
TreeMap.Raw.getKeyD_maxKeyD h he
theorem maxD_erase_eq_of_not_compare_maxD_eq [TransCmp cmp] (h : t.WF) {k fallback}
(he : (t.erase k).isEmpty = false) (heq : ¬ cmp k (t.maxD fallback) = .eq) :
(t.erase k |>.maxD fallback) = t.maxD fallback :=
DTreeMap.Raw.maxKeyD_erase_eq_of_not_compare_maxKeyD_eq h he heq
TreeMap.Raw.maxKeyD_erase_eq_of_not_compare_maxKeyD_eq h he heq
theorem maxD_erase_le_maxD [TransCmp cmp] (h : t.WF) {k}
(he : (t.erase k).isEmpty = false) {fallback} :
cmp (t.erase k |>.maxD fallback) (t.maxD fallback) |>.isLE :=
DTreeMap.Raw.maxKeyD_erase_le_maxKeyD h he
TreeMap.Raw.maxKeyD_erase_le_maxKeyD h he
@[grind =_]
theorem maxD_eq_getLastD_toList [TransCmp cmp] (h : t.WF) {fallback} :
@ -1571,4 +1597,77 @@ theorem equiv_iff_toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
end Equiv
section filter
theorem toList_filter {f : α → Bool} (h : t.WF) :
(t.filter f).toList = t.toList.filter f :=
TreeMap.Raw.keys_filter_key h
@[grind =] theorem isEmpty_filter_iff [TransCmp cmp]
{f : α → Bool} (h : t.WF) :
(t.filter f).isEmpty ↔
∀ (k : α) (h : k ∈ t), f (t.get k h) = false :=
TreeMap.Raw.isEmpty_filter_iff h.out
theorem isEmpty_filter_eq_false_iff [TransCmp cmp]
{f : α → Bool} (h : t.WF) :
(t.filter f).isEmpty = false ↔
∃ (k : α) (h : k ∈ t), f (t.get k h) :=
TreeMap.Raw.isEmpty_filter_eq_false_iff h.out
-- TODO: `contains_filter` is missing.
@[simp, grind =]
theorem mem_filter [TransCmp cmp]
{f : α → Bool} {k : α} (h : t.WF) :
(k ∈ t.filter f) ↔ ∃ (h' : k ∈ t), f (t.get k h') :=
TreeMap.Raw.mem_filter h.out
theorem mem_of_mem_filter [TransCmp cmp]
{f : α → Bool} {k : α} (h : t.WF) :
k ∈ (t.filter f) → k ∈ t :=
TreeMap.Raw.mem_of_mem_filter h.out
theorem size_filter_le_size [TransCmp cmp]
{f : α → Bool} (h : t.WF) :
(t.filter f).size ≤ t.size :=
TreeMap.Raw.size_filter_le_size h.out
grind_pattern size_filter_le_size => (t.filter f).size
theorem size_filter_eq_size_iff [TransCmp cmp]
{f : α → Bool} (h : t.WF) :
(t.filter f).size = t.size ↔ ∀ (k : α) (h : k ∈ t), f (t.get k h) :=
TreeMap.Raw.size_filter_eq_size_iff h.out
theorem filter_equiv_self_iff [TransCmp cmp]
{f : (a : α) → Bool} (h : t.WF) :
(t.filter f) ~m t ↔ ∀ (a : α) (h : a ∈ t), f (t.get a h) = true :=
⟨fun h' => (TreeMap.Raw.filter_equiv_self_iff h.out).mp h'.1,
fun h' => ⟨(TreeMap.Raw.filter_equiv_self_iff h.out).mpr h'⟩⟩
@[simp, grind =]
theorem get?_filter [TransCmp cmp]
{f : α → Bool} {k : α} (h : t.WF) :
(t.filter f).get? k = (t.get? k).filter f :=
TreeMap.Raw.getKey?_filter_key h.out
@[simp, grind =]
theorem get_filter [TransCmp cmp]
{f : α → Bool} {k : α} {h'} (h : t.WF) :
(t.filter f).get k h' = (t.get k (mem_of_mem_filter h h')) :=
TreeMap.Raw.getKey_filter h.out
@[grind =] theorem get!_filter [TransCmp cmp] [Inhabited α]
{f : α → Bool} {k : α} (h : t.WF) :
(t.filter f).get! k = ((t.get? k).filter f).get! :=
TreeMap.Raw.getKey!_filter_key h.out
@[grind =] theorem getD_filter [TransCmp cmp]
{f : α → Bool} {k fallback : α} (h : t.WF) :
(t.filter f).getD k fallback = ((t.get? k).filter f).getD fallback :=
TreeMap.Raw.getKeyD_filter_key h.out
end filter
end Std.TreeSet.Raw