feat: tree map toArray/keysArray lemmas (#12481)

This PR provides lemmas about `toArray` and `keysArray` on tree maps and
tree sets that are analogous to the existing `toList` and `keys` lemmas.
This commit is contained in:
Paul Reichert 2026-03-09 21:04:59 +01:00 committed by GitHub
parent 2e06fb5008
commit cdfde63734
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 1666 additions and 2 deletions

View file

@ -148,6 +148,9 @@ end List
namespace Array namespace Array
@[simp, grind =] theorem getElem!_toList [Inhabited α] {xs : Array α} {i : Nat} : xs.toList[i]! = xs[i]! := by
rw [List.getElem!_toArray]
theorem size_eq_length_toList {xs : Array α} : xs.size = xs.toList.length := rfl theorem size_eq_length_toList {xs : Array α} : xs.size = xs.toList.length := rfl
/-! ### Externs -/ /-! ### Externs -/

View file

@ -936,6 +936,12 @@ theorem getElem_zero_eq_head {l : List α} (h : 0 < l.length) :
| nil => simp at h | nil => simp at h
| cons _ _ => simp | cons _ _ => simp
theorem head!_eq_getElem! [Inhabited α] {l : List α} : head! l = l[0]! := by
cases l <;> rfl
theorem headD_eq_getD {l : List α} {fallback} : headD l fallback = l.getD 0 fallback := by
cases l <;> rfl
theorem head_eq_iff_head?_eq_some {xs : List α} (h) : xs.head h = a ↔ xs.head? = some a := by theorem head_eq_iff_head?_eq_some {xs : List α} (h) : xs.head h = a ↔ xs.head? = some a := by
cases xs with cases xs with
| nil => simp at h | nil => simp at h

View file

@ -8,6 +8,7 @@ module
prelude prelude
public import Std.Data.HashMap.Basic public import Std.Data.HashMap.Basic
public import Std.Data.DTreeMap.Internal.WF.Lemmas public import Std.Data.DTreeMap.Internal.WF.Lemmas
public import Init.Data.Array.Perm
public meta import Std.Data.HashMap.Basic public meta import Std.Data.HashMap.Basic
import Init.Data.List.Find import Init.Data.List.Find
import Init.Data.List.Pairwise import Init.Data.List.Pairwise
@ -104,10 +105,13 @@ private meta def queryMap : Std.DHashMap Name (fun _ => Name × Array (MacroM (T
⟨`getKeyD, (``getKeyD_eq_getKeyD, #[``(getKeyD_of_perm _)])⟩, ⟨`getKeyD, (``getKeyD_eq_getKeyD, #[``(getKeyD_of_perm _)])⟩,
⟨`getKey!, (``getKey!_eq_getKey!, #[``(getKey!_of_perm _)])⟩, ⟨`getKey!, (``getKey!_eq_getKey!, #[``(getKey!_of_perm _)])⟩,
⟨`toList, (``toList_eq_toListModel, #[])⟩, ⟨`toList, (``toList_eq_toListModel, #[])⟩,
⟨`toArray, (``toArray_eq_toArray, #[])⟩,
⟨`beq, (``beq_eq_beqModel, #[])⟩, ⟨`beq, (``beq_eq_beqModel, #[])⟩,
⟨`Const.beq, (``Internal.Impl.Const.beq_eq_beqModel, #[])⟩, ⟨`Const.beq, (``Internal.Impl.Const.beq_eq_beqModel, #[])⟩,
⟨`keys, (``keys_eq_keys, #[])⟩, ⟨`keys, (``keys_eq_keys, #[])⟩,
⟨`keysArray, (``keysArray_eq_toArray_keys, #[])⟩,
⟨`Const.toList, (``Const.toList_eq_toListModel_map, #[])⟩, ⟨`Const.toList, (``Const.toList_eq_toListModel_map, #[])⟩,
⟨`Const.toArray, (``Const.toArray_eq_toArray_map, #[])⟩,
⟨`foldlM, (``foldlM_eq_foldlM_toListModel, #[])⟩, ⟨`foldlM, (``foldlM_eq_foldlM_toListModel, #[])⟩,
⟨`foldl, (``foldl_eq_foldl, #[])⟩, ⟨`foldl, (``foldl_eq_foldl, #[])⟩,
⟨`foldrM, (``foldrM_eq_foldrM, #[])⟩, ⟨`foldrM, (``foldrM_eq_foldrM, #[])⟩,
@ -228,6 +232,18 @@ theorem isEmpty_iff_forall_not_mem [TransOrd α] (h : t.WF) :
t.isEmpty = true ↔ ∀ a, ¬a ∈ t := by t.isEmpty = true ↔ ∀ a, ¬a ∈ t := by
simpa only [mem_iff_contains, Bool.not_eq_true] using isEmpty_iff_forall_contains h simpa only [mem_iff_contains, Bool.not_eq_true] using isEmpty_iff_forall_contains h
theorem toArray_toList : t.toList.toArray = t.toArray := by
simp_to_model [toList, toArray]
theorem toList_toArray : t.toArray.toList = t.toList := by
simp_to_model [toList, toArray]
theorem toArray_keys : t.keys.toArray = t.keysArray := by
simp_to_model [Const.toList, keys, keysArray]
theorem toList_keysArray : t.keysArray.toList = t.keys := by
simp_to_model [Const.toList, keys, keysArray]
theorem contains_insert [TransOrd α] (h : t.WF) {k a : α} {v : β k} : theorem contains_insert [TransOrd α] (h : t.WF) {k a : α} {v : β k} :
(t.insert k v h.balanced).impl.contains a = (compare k a == .eq || t.contains a) := by (t.insert k v h.balanced).impl.contains a = (compare k a == .eq || t.contains a) := by
simp_to_model [insert, contains] using List.containsKey_insertEntry simp_to_model [insert, contains] using List.containsKey_insertEntry
@ -580,6 +596,12 @@ namespace Const
variable {β : Type v} {t : Impl α β} variable {β : Type v} {t : Impl α β}
theorem toArray_toList : (toList t).toArray = toArray t := by
simp_to_model [Const.toList, Const.toArray]
theorem toList_toArray : (toArray t).toList = toList t := by
simp_to_model [Const.toList, Const.toArray]
theorem get?_empty [TransOrd α] {a : α} : get? (empty : Impl α β) a = none := by theorem get?_empty [TransOrd α] {a : α} : get? (empty : Impl α β) a = none := by
simp_to_model [Const.get?] using List.getValue?_nil simp_to_model [Const.get?] using List.getValue?_nil
@ -676,6 +698,18 @@ theorem toList_insert!_perm [BEq α] [TransOrd α] [LawfulBEqOrd α] (h : t.WF)
(t.insert! k v).toList.Perm (⟨k, v⟩ :: t.toList.filter (¬k == ·.1)) := by (t.insert! k v).toList.Perm (⟨k, v⟩ :: t.toList.filter (¬k == ·.1)) := by
simpa only [insert_eq_insert!] using toList_insert_perm h simpa only [insert_eq_insert!] using toList_insert_perm h
theorem toArray_insert_perm [BEq α] [TransOrd α] [LawfulBEqOrd α] (h : t.WF) {k : α} {v : β k} :
(t.insert k v h.balanced).1.toArray.Perm (t.toArray.filter (¬k == ·.1) |>.push ⟨k, v⟩) := by
simp only [← toArray_toList, List.filter_toArray', List.push_toArray,
← List.perm_iff_toArray_perm, List.size_toArray]
refine (toList_insert_perm h).trans ?_
rw [← List.singleton_append]
apply List.perm_append_comm
theorem toArray_insert!_perm [BEq α] [TransOrd α] [LawfulBEqOrd α] (h : t.WF) {k : α} {v : β k} :
(t.insert! k v).toArray.Perm (t.toArray.filter (¬k == ·.1) |>.push ⟨k, v⟩) := by
simpa only [insert_eq_insert!] using toArray_insert_perm h
theorem Const.toList_insert_perm {β : Type v} {t : Impl α (fun _ => β)} [BEq α] [TransOrd α] [LawfulBEqOrd α] (h : t.WF) {k : α} {v : β} : theorem Const.toList_insert_perm {β : Type v} {t : Impl α (fun _ => β)} [BEq α] [TransOrd α] [LawfulBEqOrd α] (h : t.WF) {k : α} {v : β} :
(Const.toList (t.insert k v h.balanced).1).Perm (⟨k, v⟩ :: (Const.toList t).filter (¬k == ·.1)) := by (Const.toList (t.insert k v h.balanced).1).Perm (⟨k, v⟩ :: (Const.toList t).filter (¬k == ·.1)) := by
simp_to_model simp_to_model
@ -687,6 +721,18 @@ theorem Const.toList_insert!_perm {β : Type v} {t : Impl α (fun _ => β)} [BEq
(Const.toList (t.insert! k v)).Perm (⟨k, v⟩ :: (Const.toList t).filter (¬k == ·.1)) := by (Const.toList (t.insert! k v)).Perm (⟨k, v⟩ :: (Const.toList t).filter (¬k == ·.1)) := by
simpa only [insert_eq_insert!] using Const.toList_insert_perm h simpa only [insert_eq_insert!] using Const.toList_insert_perm h
theorem Const.toArray_insert_perm {β : Type v} {t : Impl α (fun _ => β)} [BEq α] [TransOrd α] [LawfulBEqOrd α] (h : t.WF) {k : α} {v : β} :
(Const.toArray (t.insert k v h.balanced).1).Perm ((Const.toArray t).filter (¬k == ·.1) |>.push ⟨k, v⟩) := by
simp only [← toArray_toList, List.size_toArray, List.filter_toArray', List.push_toArray,
← List.perm_iff_toArray_perm]
refine (toList_insert_perm h).trans ?_
rw [← List.singleton_append]
apply List.perm_append_comm
theorem Const.toArray_insert!_perm {β : Type v} {t : Impl α (fun _ => β)} [BEq α] [TransOrd α] [LawfulBEqOrd α] (h : t.WF) {k : α} {v : β} :
(Const.toArray (t.insert! k v)).Perm ((Const.toArray t).filter (¬k == ·.1) |>.push ⟨k, v⟩) := by
simpa only [insert_eq_insert!] using Const.toArray_insert_perm h
theorem keys_insertIfNew_perm [BEq α] [TransOrd α] [LawfulBEqOrd α] (h : t.WF) {k : α} {v : β k} : theorem keys_insertIfNew_perm [BEq α] [TransOrd α] [LawfulBEqOrd α] (h : t.WF) {k : α} {v : β k} :
(t.insertIfNew k v h.balanced).1.keys.Perm (if t.contains k then t.keys else k :: t.keys) := by (t.insertIfNew k v h.balanced).1.keys.Perm (if t.contains k then t.keys else k :: t.keys) := by
simp_to_model simp_to_model
@ -698,10 +744,22 @@ theorem keys_insertIfNew_perm [BEq α] [TransOrd α] [LawfulBEqOrd α] (h : t.WF
apply List.keys_insertEntryIfNew_perm apply List.keys_insertEntryIfNew_perm
simp simp
theorem keysArray_insertIfNew_perm [BEq α] [TransOrd α] [LawfulBEqOrd α] (h : t.WF) {k : α} {v : β k} :
(t.insertIfNew k v h.balanced).1.keysArray.Perm (if t.contains k then t.keysArray else t.keysArray.push k) := by
rw [← toArray_keys, ← toArray_keys, Array.perm_iff_toList_perm, List.toList_toArray]
refine (keys_insertIfNew_perm h).trans ?_
split
· simp
· simpa using (List.perm_append_singleton ..).symm
theorem keys_insertIfNew!_perm {t : Impl α β} [BEq α] [TransOrd α] [LawfulBEqOrd α] (h : t.WF) {k : α} {v : β k} : theorem keys_insertIfNew!_perm {t : Impl α β} [BEq α] [TransOrd α] [LawfulBEqOrd α] (h : t.WF) {k : α} {v : β k} :
(t.insertIfNew! k v).keys.Perm (if t.contains k then t.keys else k :: t.keys) := by (t.insertIfNew! k v).keys.Perm (if t.contains k then t.keys else k :: t.keys) := by
simpa only [insertIfNew_eq_insertIfNew!] using keys_insertIfNew_perm h simpa only [insertIfNew_eq_insertIfNew!] using keys_insertIfNew_perm h
theorem keysArray_insertIfNew!_perm {t : Impl α β} [BEq α] [TransOrd α] [LawfulBEqOrd α] (h : t.WF) {k : α} {v : β k} :
(t.insertIfNew! k v).keysArray.Perm (if t.contains k then t.keysArray else t.keysArray.push k) := by
simpa only [insertIfNew_eq_insertIfNew!] using keysArray_insertIfNew_perm h
theorem get_insert_self [TransOrd α] [LawfulEqOrd α] (h : t.WF) {k : α} {v : β k} : theorem get_insert_self [TransOrd α] [LawfulEqOrd α] (h : t.WF) {k : α} {v : β k} :
(t.insert k v h.balanced).impl.get k (contains_insert_self h) = v := by (t.insert k v h.balanced).impl.get k (contains_insert_self h) = v := by
simp_to_model [insert, get] using List.getValueCast_insertEntry_self simp_to_model [insert, get] using List.getValueCast_insertEntry_self
@ -1638,22 +1696,43 @@ theorem length_keys [TransOrd α] (h : t.WF) :
t.keys.length = t.size := by t.keys.length = t.size := by
simp_to_model [size, keys] using List.length_keys_eq_length simp_to_model [size, keys] using List.length_keys_eq_length
theorem size_keysArray [TransOrd α] (h : t.WF) :
t.keysArray.size = t.size := by
rw [← toArray_keys, List.size_toArray, length_keys h]
theorem isEmpty_keys : theorem isEmpty_keys :
t.keys.isEmpty = t.isEmpty := by t.keys.isEmpty = t.isEmpty := by
simp_to_model [isEmpty, keys] using List.isEmpty_keys_eq_isEmpty simp_to_model [isEmpty, keys] using List.isEmpty_keys_eq_isEmpty
theorem isEmpty_keysArray :
t.keysArray.isEmpty = t.isEmpty := by
rw [← toArray_keys, List.isEmpty_toArray, isEmpty_keys]
theorem contains_keys [BEq α] [beqOrd : LawfulBEqOrd α] [TransOrd α] {k : α} (h : t.WF) : theorem contains_keys [BEq α] [beqOrd : LawfulBEqOrd α] [TransOrd α] {k : α} (h : t.WF) :
t.keys.contains k = t.contains k := by t.keys.contains k = t.contains k := by
simp_to_model [contains, keys] using (List.containsKey_eq_keys_contains).symm simp_to_model [contains, keys] using (List.containsKey_eq_keys_contains).symm
theorem contains_keysArray [BEq α] [beqOrd : LawfulBEqOrd α] [TransOrd α] {k : α} (h : t.WF) :
t.keysArray.contains k = t.contains k := by
rw [← toArray_keys, List.contains_toArray, contains_keys h]
theorem mem_keys [LawfulEqOrd α] [TransOrd α] {k : α} (h : t.WF) : theorem mem_keys [LawfulEqOrd α] [TransOrd α] {k : α} (h : t.WF) :
k ∈ t.keys ↔ k ∈ t := by k ∈ t.keys ↔ k ∈ t := by
simpa only [mem_iff_contains, ← List.contains_iff_mem, ← Bool.eq_iff_iff] using contains_keys h simpa only [mem_iff_contains, ← List.contains_iff_mem, ← Bool.eq_iff_iff] using contains_keys h
theorem mem_keysArray [LawfulEqOrd α] [TransOrd α] {k : α} (h : t.WF) :
k ∈ t.keysArray ↔ k ∈ t := by
rw [← toArray_keys, List.mem_toArray, mem_keys h]
theorem mem_of_mem_keys [TransOrd α] (h : t.WF) {k : α} theorem mem_of_mem_keys [TransOrd α] (h : t.WF) {k : α}
(h' : k ∈ t.keys) : k ∈ t := (h' : k ∈ t.keys) : k ∈ t :=
(contains_keys h).symm.trans (List.elem_eq_true_of_mem h') (contains_keys h).symm.trans (List.elem_eq_true_of_mem h')
theorem mem_of_mem_keysArray [TransOrd α] (h : t.WF) {k : α}
(h' : k ∈ t.keysArray) : k ∈ t := by
rw [← toArray_keys, List.mem_toArray] at h'
exact mem_of_mem_keys h h'
theorem distinct_keys [TransOrd α] (h : t.WF) : theorem distinct_keys [TransOrd α] (h : t.WF) :
t.keys.Pairwise (fun a b => ¬ compare a b = .eq) := by t.keys.Pairwise (fun a b => ¬ compare a b = .eq) := by
simp_to_model [keys] using h.ordered.distinctKeys.distinct simp_to_model [keys] using h.ordered.distinctKeys.distinct
@ -1667,31 +1746,60 @@ theorem map_fst_toList_eq_keys :
t.toList.map Sigma.fst = t.keys := by t.toList.map Sigma.fst = t.keys := by
simp_to_model [toList, keys] using (List.keys_eq_map ..).symm simp_to_model [toList, keys] using (List.keys_eq_map ..).symm
theorem map_fst_toArray_eq_keysArray :
t.toArray.map Sigma.fst = t.keysArray := by
rw [← toArray_toList, List.map_toArray, map_fst_toList_eq_keys, toArray_keys]
theorem length_toList [TransOrd α] (h : t.WF) : theorem length_toList [TransOrd α] (h : t.WF) :
t.toList.length = t.size := by t.toList.length = t.size := by
simp_to_model [toList, size] simp_to_model [toList, size]
theorem size_toArray [TransOrd α] (h : t.WF) :
t.toArray.size = t.size := by
rw [← toArray_toList, List.size_toArray, length_toList h]
theorem isEmpty_toList : theorem isEmpty_toList :
t.toList.isEmpty = t.isEmpty := by t.toList.isEmpty = t.isEmpty := by
simp_to_model [toList, isEmpty] simp_to_model [toList, isEmpty]
theorem isEmpty_toArray :
t.toArray.isEmpty = t.isEmpty := by
rw [← toArray_toList, List.isEmpty_toArray, isEmpty_toList]
theorem mem_toList_iff_get?_eq_some [TransOrd α] [LawfulEqOrd α] {k : α} {v : β k} (h : t.WF) : theorem mem_toList_iff_get?_eq_some [TransOrd α] [LawfulEqOrd α] {k : α} {v : β k} (h : t.WF) :
⟨k, v⟩ ∈ t.toList ↔ t.get? k = some v := by ⟨k, v⟩ ∈ t.toList ↔ t.get? k = some v := by
simp_to_model [toList, get?] using List.mem_iff_getValueCast?_eq_some simp_to_model [toList, get?] using List.mem_iff_getValueCast?_eq_some
theorem mem_toArray_iff_get?_eq_some [TransOrd α] [LawfulEqOrd α] {k : α} {v : β k} (h : t.WF) :
⟨k, v⟩ ∈ t.toArray ↔ t.get? k = some v := by
rw [← toArray_toList, List.mem_toArray, mem_toList_iff_get?_eq_some h]
theorem find?_toList_eq_some_iff_get?_eq_some [TransOrd α] [LawfulEqOrd α] {k : α} {v : β k} theorem find?_toList_eq_some_iff_get?_eq_some [TransOrd α] [LawfulEqOrd α] {k : α} {v : β k}
(h : t.WF) : (h : t.WF) :
t.toList.find? (compare ·.1 k == .eq) = some ⟨k, v⟩ ↔ t.get? k = some v := by t.toList.find? (compare ·.1 k == .eq) = some ⟨k, v⟩ ↔ t.get? k = some v := by
simp_to_model [toList, get?] using List.find?_eq_some_iff_getValueCast?_eq_some simp_to_model [toList, get?] using List.find?_eq_some_iff_getValueCast?_eq_some
theorem find?_toArray_eq_some_iff_get?_eq_some [TransOrd α] [LawfulEqOrd α] {k : α} {v : β k}
(h : t.WF) :
t.toArray.find? (compare ·.1 k == .eq) = some ⟨k, v⟩ ↔ t.get? k = some v := by
rw [← toArray_toList, List.find?_toArray, find?_toList_eq_some_iff_get?_eq_some h]
theorem find?_toList_eq_none_iff_contains_eq_false [TransOrd α] {k : α} (h : t.WF) : theorem find?_toList_eq_none_iff_contains_eq_false [TransOrd α] {k : α} (h : t.WF) :
t.toList.find? (compare ·.1 k == .eq) = none ↔ t.contains k = false := by t.toList.find? (compare ·.1 k == .eq) = none ↔ t.contains k = false := by
simp_to_model [toList, contains] using List.find?_eq_none_iff_containsKey_eq_false simp_to_model [toList, contains] using List.find?_eq_none_iff_containsKey_eq_false
theorem find?_toArray_eq_none_iff_contains_eq_false [TransOrd α] {k : α} (h : t.WF) :
t.toArray.find? (compare ·.1 k == .eq) = none ↔ t.contains k = false := by
rw [← toArray_toList, List.find?_toArray, find?_toList_eq_none_iff_contains_eq_false h]
theorem find?_toList_eq_none_iff_not_mem [TransOrd α] {k : α} (h : t.WF) : theorem find?_toList_eq_none_iff_not_mem [TransOrd α] {k : α} (h : t.WF) :
t.toList.find? (compare ·.1 k == .eq) = none ↔ ¬ k ∈ t := by t.toList.find? (compare ·.1 k == .eq) = none ↔ ¬ k ∈ t := by
simpa only [Bool.not_eq_true, mem_iff_contains] using find?_toList_eq_none_iff_contains_eq_false h simpa only [Bool.not_eq_true, mem_iff_contains] using find?_toList_eq_none_iff_contains_eq_false h
theorem find?_toArray_eq_none_iff_not_mem [TransOrd α] {k : α} (h : t.WF) :
t.toArray.find? (compare ·.1 k == .eq) = none ↔ ¬ k ∈ t := by
simpa only [Bool.not_eq_true, mem_iff_contains] using find?_toArray_eq_none_iff_contains_eq_false h
theorem distinct_keys_toList [TransOrd α] (h : t.WF) : theorem distinct_keys_toList [TransOrd α] (h : t.WF) :
t.toList.Pairwise (fun a b => ¬ compare a.1 b.1 = .eq) := by t.toList.Pairwise (fun a b => ¬ compare a.1 b.1 = .eq) := by
simp_to_model [toList] using List.pairwise_fst_eq_false simp_to_model [toList] using List.pairwise_fst_eq_false
@ -1708,52 +1816,97 @@ theorem map_fst_toList_eq_keys :
(toList t).map Prod.fst = t.keys := by (toList t).map Prod.fst = t.keys := by
simp_to_model [Const.toList, keys] using List.map_fst_map_toProd_eq_keys simp_to_model [Const.toList, keys] using List.map_fst_map_toProd_eq_keys
theorem map_fst_toArray_eq_keysArray :
(toArray t).map Prod.fst = t.keysArray := by
rw [← toArray_toList, List.map_toArray, map_fst_toList_eq_keys, toArray_keys]
theorem length_toList (h : t.WF) : theorem length_toList (h : t.WF) :
(toList t).length = t.size := by (toList t).length = t.size := by
simp_to_model [Const.toList, size] using List.length_map simp_to_model [Const.toList, size] using List.length_map
theorem size_toArray (h : t.WF) :
(toArray t).size = t.size := by
rw [← toArray_toList, List.size_toArray, length_toList h]
theorem isEmpty_toList : theorem isEmpty_toList :
(toList t).isEmpty = t.isEmpty := by (toList t).isEmpty = t.isEmpty := by
rw [Bool.eq_iff_iff, List.isEmpty_iff, isEmpty_eq_isEmpty, List.isEmpty_iff] rw [Bool.eq_iff_iff, List.isEmpty_iff, isEmpty_eq_isEmpty, List.isEmpty_iff]
simp_to_model [Const.toList, isEmpty] using List.map_eq_nil_iff simp_to_model [Const.toList, isEmpty] using List.map_eq_nil_iff
theorem isEmpty_toArray :
(toArray t).isEmpty = t.isEmpty := by
rw [← toArray_toList, List.isEmpty_toArray, isEmpty_toList]
theorem mem_toList_iff_get?_eq_some [TransOrd α] [LawfulEqOrd α] {k : α} {v : β} (h : t.WF) : theorem mem_toList_iff_get?_eq_some [TransOrd α] [LawfulEqOrd α] {k : α} {v : β} (h : t.WF) :
(k, v) ∈ toList t ↔ get? t k = some v := by (k, v) ∈ toList t ↔ get? t k = some v := by
simp_to_model [Const.toList, Const.get?] using List.mem_map_toProd_iff_getValue?_eq_some simp_to_model [Const.toList, Const.get?] using List.mem_map_toProd_iff_getValue?_eq_some
theorem mem_toArray_iff_get?_eq_some [TransOrd α] [LawfulEqOrd α] {k : α} {v : β} (h : t.WF) :
(k, v) ∈ toArray t ↔ get? t k = some v := by
rw [← toArray_toList, List.mem_toArray, mem_toList_iff_get?_eq_some h]
theorem mem_toList_iff_getKey?_eq_some_and_get?_eq_some [TransOrd α] {k : α} {v : β} (h : t.WF) : theorem mem_toList_iff_getKey?_eq_some_and_get?_eq_some [TransOrd α] {k : α} {v : β} (h : t.WF) :
(k, v) ∈ toList t ↔ t.getKey? k = some k ∧ get? t k = some v := by (k, v) ∈ toList t ↔ t.getKey? k = some k ∧ get? t k = some v := by
simp_to_model [Const.toList, getKey?, Const.get?] simp_to_model [Const.toList, getKey?, Const.get?]
using List.mem_map_toProd_iff_getKey?_eq_some_and_getValue?_eq_some using List.mem_map_toProd_iff_getKey?_eq_some_and_getValue?_eq_some
theorem mem_toArray_iff_getKey?_eq_some_and_get?_eq_some [TransOrd α] {k : α} {v : β} (h : t.WF) :
(k, v) ∈ toArray t ↔ t.getKey? k = some k ∧ get? t k = some v := by
rw [← toArray_toList, List.mem_toArray, mem_toList_iff_getKey?_eq_some_and_get?_eq_some h]
theorem get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList [TransOrd α] {k : α} {v : β} (h : t.WF) : theorem get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList [TransOrd α] {k : α} {v : β} (h : t.WF) :
get? t k = some v ↔ ∃ (k' : α), compare k k' = .eq ∧ (k', v) ∈ toList t := by get? t k = some v ↔ ∃ (k' : α), compare k k' = .eq ∧ (k', v) ∈ toList t := by
simp_to_model [Const.toList, Const.get?] simp_to_model [Const.toList, Const.get?]
using List.getValue?_eq_some_iff_exists_beq_and_mem_toList using List.getValue?_eq_some_iff_exists_beq_and_mem_toList
theorem get?_eq_some_iff_exists_compare_eq_eq_and_mem_toArray [TransOrd α] {k : α} {v : β} (h : t.WF) :
get? t k = some v ↔ ∃ (k' : α), compare k k' = .eq ∧ (k', v) ∈ toArray t := by
simp [← toArray_toList, List.mem_toArray, ← get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList h]
theorem find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some [TransOrd α] {k k' : α} {v : β} theorem find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some [TransOrd α] {k k' : α} {v : β}
(h : t.WF) : (toList t).find? (fun a => compare a.1 k == .eq) = some ⟨k', v⟩ ↔ (h : t.WF) : (toList t).find? (fun a => compare a.1 k == .eq) = some ⟨k', v⟩ ↔
t.getKey? k = some k' ∧ get? t k = some v := by t.getKey? k = some k' ∧ get? t k = some v := by
simp_to_model [Const.toList, getKey?, Const.get?] simp_to_model [Const.toList, getKey?, Const.get?]
using List.find?_map_toProd_eq_some_iff_getKey?_eq_some_and_getValue?_eq_some using List.find?_map_toProd_eq_some_iff_getKey?_eq_some_and_getValue?_eq_some
theorem find?_toArray_eq_some_iff_getKey?_eq_some_and_get?_eq_some [TransOrd α] {k k' : α} {v : β}
(h : t.WF) : (toArray t).find? (fun a => compare a.1 k == .eq) = some ⟨k', v⟩ ↔
t.getKey? k = some k' ∧ get? t k = some v := by
rw [← toArray_toList, List.find?_toArray, find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some h]
theorem find?_toList_eq_none_iff_contains_eq_false [TransOrd α] {k : α} (h : t.WF) : theorem find?_toList_eq_none_iff_contains_eq_false [TransOrd α] {k : α} (h : t.WF) :
(toList t).find? (compare ·.1 k == .eq) = none ↔ t.contains k = false := by (toList t).find? (compare ·.1 k == .eq) = none ↔ t.contains k = false := by
simp_to_model [Const.toList, contains] using List.find?_map_eq_none_iff_containsKey_eq_false simp_to_model [Const.toList, contains] using List.find?_map_eq_none_iff_containsKey_eq_false
theorem find?_toArray_eq_none_iff_contains_eq_false [TransOrd α] {k : α} (h : t.WF) :
(toArray t).find? (compare ·.1 k == .eq) = none ↔ t.contains k = false := by
rw [← toArray_toList, List.find?_toArray, find?_toList_eq_none_iff_contains_eq_false h]
theorem find?_toList_eq_none_iff_not_mem [TransOrd α] {k : α} (h : t.WF) : theorem find?_toList_eq_none_iff_not_mem [TransOrd α] {k : α} (h : t.WF) :
(toList t).find? (compare ·.1 k == .eq) = none ↔ ¬ k ∈ t := by (toList t).find? (compare ·.1 k == .eq) = none ↔ ¬ k ∈ t := by
simpa only [Bool.not_eq_true, mem_iff_contains] using find?_toList_eq_none_iff_contains_eq_false h simpa only [Bool.not_eq_true, mem_iff_contains] using find?_toList_eq_none_iff_contains_eq_false h
theorem find?_toArray_eq_none_iff_not_mem [TransOrd α] {k : α} (h : t.WF) :
(toArray t).find? (compare ·.1 k == .eq) = none ↔ ¬ k ∈ t := by
simpa only [Bool.not_eq_true, mem_iff_contains] using find?_toArray_eq_none_iff_contains_eq_false h
theorem distinct_keys_toList [TransOrd α] (h : t.WF) : theorem distinct_keys_toList [TransOrd α] (h : t.WF) :
(toList t).Pairwise (fun a b => ¬ compare a.1 b.1 = .eq) := by (toList t).Pairwise (fun a b => ¬ compare a.1 b.1 = .eq) := by
simp_to_model [Const.toList] using List.pairwise_fst_eq_false_map_toProd simp_to_model [Const.toList] using List.pairwise_fst_eq_false_map_toProd
theorem distinct_keys_toArray [TransOrd α] (h : t.WF) :
(toArray t).toList.Pairwise (fun a b => ¬ compare a.1 b.1 = .eq) := by
simp [toList_toArray, distinct_keys_toList h]
theorem ordered_keys_toList [TransOrd α] (h : t.WF) : theorem ordered_keys_toList [TransOrd α] (h : t.WF) :
(toList t).Pairwise (fun a b => compare a.1 b.1 = .lt) := by (toList t).Pairwise (fun a b => compare a.1 b.1 = .lt) := by
simp_to_model [Const.toList] simp_to_model [Const.toList]
exact h.ordered.map _ fun _ _ hcmp => hcmp exact h.ordered.map _ fun _ _ hcmp => hcmp
theorem ordered_keys_toArray [TransOrd α] (h : t.WF) :
(toArray t).toList.Pairwise (fun a b => compare a.1 b.1 = .lt) := by
simp [toList_toArray, ordered_keys_toList h]
end Const end Const
section monadic section monadic
@ -1765,53 +1918,105 @@ theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m]
t.foldlM f init = t.toList.foldlM (fun a b => f a b.1 b.2) init := by t.foldlM f init = t.toList.foldlM (fun a b => f a b.1 b.2) init := by
simp_to_model [toList, foldlM] simp_to_model [toList, foldlM]
theorem foldlM_eq_foldlM_toArray [Monad m] [LawfulMonad m]
{f : δ → (a : α) → β a → m δ} {init : δ} :
t.foldlM f init = t.toArray.foldlM (fun a b => f a b.1 b.2) init := by
rw [foldlM_eq_foldlM_toList, ← toArray_toList, List.foldlM_toArray]
theorem foldl_eq_foldl_toList {f : δ → (a : α) → β a → δ} {init : δ} : theorem foldl_eq_foldl_toList {f : δ → (a : α) → β a → δ} {init : δ} :
t.foldl f init = t.toList.foldl (fun a b => f a b.1 b.2) init := by t.foldl f init = t.toList.foldl (fun a b => f a b.1 b.2) init := by
simp_to_model [toList, foldl] simp_to_model [toList, foldl]
theorem foldl_eq_foldl_toArray {f : δ → (a : α) → β a → δ} {init : δ} :
t.foldl f init = t.toArray.foldl (fun a b => f a b.1 b.2) init := by
rw [foldl_eq_foldl_toList, ← toArray_toList, List.foldl_toArray]
theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m]
{f : (a : α) → β a → δ → m δ} {init : δ} : {f : (a : α) → β a → δ → m δ} {init : δ} :
t.foldrM f init = t.toList.foldrM (fun a b => f a.1 a.2 b) init := by t.foldrM f init = t.toList.foldrM (fun a b => f a.1 a.2 b) init := by
simp_to_model [toList, foldrM] simp_to_model [toList, foldrM]
theorem foldrM_eq_foldrM_toArray [Monad m] [LawfulMonad m]
{f : (a : α) → β a → δ → m δ} {init : δ} :
t.foldrM f init = t.toArray.foldrM (fun a b => f a.1 a.2 b) init := by
rw [foldrM_eq_foldrM_toList, ← toArray_toList, List.foldrM_toArray]
theorem foldr_eq_foldr_toList {f : (a : α) → β a → δ → δ} {init : δ} : theorem foldr_eq_foldr_toList {f : (a : α) → β a → δ → δ} {init : δ} :
t.foldr f init = t.toList.foldr (fun a b => f a.1 a.2 b) init := by t.foldr f init = t.toList.foldr (fun a b => f a.1 a.2 b) init := by
simp_to_model [toList, foldr] simp_to_model [toList, foldr]
theorem foldr_eq_foldr_toArray {f : (a : α) → β a → δ → δ} {init : δ} :
t.foldr f init = t.toArray.foldr (fun a b => f a.1 a.2 b) init := by
rw [foldr_eq_foldr_toList, ← toArray_toList, List.foldr_toArray]
theorem forM_eq_forM_toList [Monad m] [LawfulMonad m] {f : (a : α) × β a → m PUnit} : theorem forM_eq_forM_toList [Monad m] [LawfulMonad m] {f : (a : α) × β a → m PUnit} :
t.forM (fun k v => f ⟨k, v⟩) = ForM.forM t.toList f := by t.forM (fun k v => f ⟨k, v⟩) = ForM.forM t.toList f := by
simp_to_model [toList, forM] using rfl simp_to_model [toList, forM] using rfl
theorem forM_eq_forM_toArray [Monad m] [LawfulMonad m] {f : (a : α) × β a → m PUnit} :
t.forM (fun k v => f ⟨k, v⟩) = ForM.forM t.toArray f := by
simp [forM_eq_forM_toList, ← toArray_toList, List.forM_toArray]
theorem forIn_eq_forIn_toList [Monad m] [LawfulMonad m] theorem forIn_eq_forIn_toList [Monad m] [LawfulMonad m]
{f : (a : α) × β a → δ → m (ForInStep δ)} {init : δ} : {f : (a : α) × β a → δ → m (ForInStep δ)} {init : δ} :
t.forIn (fun k v => f ⟨k, v⟩) init = ForIn.forIn t.toList init f := by t.forIn (fun k v => f ⟨k, v⟩) init = ForIn.forIn t.toList init f := by
simp_to_model [toList, forIn] simp_to_model [toList, forIn]
theorem forIn_eq_forIn_toArray [Monad m] [LawfulMonad m]
{f : (a : α) × β a → δ → m (ForInStep δ)} {init : δ} :
t.forIn (fun k v => f ⟨k, v⟩) init = ForIn.forIn t.toArray init f := by
rw [forIn_eq_forIn_toList, ← toArray_toList, List.forIn_toArray]
theorem foldlM_eq_foldlM_keys [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} : theorem foldlM_eq_foldlM_keys [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} :
t.foldlM (fun d a _ => f d a) init = t.keys.foldlM f init := by t.foldlM (fun d a _ => f d a) init = t.keys.foldlM f init := by
simp_to_model [foldlM, keys] using List.foldlM_eq_foldlM_keys simp_to_model [foldlM, keys] using List.foldlM_eq_foldlM_keys
theorem foldlM_eq_foldlM_keysArray [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} :
t.foldlM (fun d a _ => f d a) init = t.keysArray.foldlM f init := by
rw [foldlM_eq_foldlM_keys, ← toArray_keys, List.foldlM_toArray]
theorem foldl_eq_foldl_keys {f : δ → α → δ} {init : δ} : theorem foldl_eq_foldl_keys {f : δ → α → δ} {init : δ} :
t.foldl (fun d a _ => f d a) init = t.keys.foldl f init := by t.foldl (fun d a _ => f d a) init = t.keys.foldl f init := by
simp_to_model [foldl, keys] using List.foldl_eq_foldl_keys simp_to_model [foldl, keys] using List.foldl_eq_foldl_keys
theorem foldl_eq_foldl_keysArray {f : δ → α → δ} {init : δ} :
t.foldl (fun d a _ => f d a) init = t.keysArray.foldl f init := by
rw [foldl_eq_foldl_keys, ← toArray_keys, List.foldl_toArray]
theorem foldrM_eq_foldrM_keys [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} : theorem foldrM_eq_foldrM_keys [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} :
t.foldrM (fun a _ d => f a d) init = t.keys.foldrM f init := by t.foldrM (fun a _ d => f a d) init = t.keys.foldrM f init := by
simp_to_model [foldrM, keys] using List.foldrM_eq_foldrM_keys simp_to_model [foldrM, keys] using List.foldrM_eq_foldrM_keys
theorem foldrM_eq_foldrM_keysArray [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} :
t.foldrM (fun a _ d => f a d) init = t.keysArray.foldrM f init := by
rw [foldrM_eq_foldrM_keys, ← toArray_keys, List.foldrM_toArray]
theorem foldr_eq_foldr_keys {f : α → δ → δ} {init : δ} : theorem foldr_eq_foldr_keys {f : α → δ → δ} {init : δ} :
t.foldr (fun a _ d => f a d) init = t.keys.foldr f init := by t.foldr (fun a _ d => f a d) init = t.keys.foldr f init := by
simp_to_model [foldr, keys] using List.foldr_eq_foldr_keys simp_to_model [foldr, keys] using List.foldr_eq_foldr_keys
theorem foldr_eq_foldr_keysArray {f : α → δ → δ} {init : δ} :
t.foldr (fun a _ d => f a d) init = t.keysArray.foldr f init := by
rw [foldr_eq_foldr_keys, ← toArray_keys, List.foldr_toArray]
theorem forM_eq_forM_keys [Monad m] [LawfulMonad m] {f : α → m PUnit} : theorem forM_eq_forM_keys [Monad m] [LawfulMonad m] {f : α → m PUnit} :
t.forM (fun a _ => f a) = t.keys.forM f := by t.forM (fun a _ => f a) = t.keys.forM f := by
simp_to_model [forM, keys] using List.forM_eq_forM_keys simp_to_model [forM, keys] using List.forM_eq_forM_keys
theorem forM_eq_forM_keysArray [Monad m] [LawfulMonad m] {f : α → m PUnit} :
t.forM (fun a _ => f a) = t.keysArray.forM f := by
rw [forM_eq_forM_keys, ← toArray_keys, List.forM_toArray' _ _ rfl]
theorem forIn_eq_forIn_keys [Monad m] [LawfulMonad m] {f : α → δ → m (ForInStep δ)} theorem forIn_eq_forIn_keys [Monad m] [LawfulMonad m] {f : α → δ → m (ForInStep δ)}
{init : δ} : {init : δ} :
t.forIn (fun a _ d => f a d) init = ForIn.forIn t.keys init f := by t.forIn (fun a _ d => f a d) init = ForIn.forIn t.keys init f := by
simp_to_model [forIn, keys] using List.forIn_eq_forIn_keys simp_to_model [forIn, keys] using List.forIn_eq_forIn_keys
theorem forIn_eq_forIn_keysArray [Monad m] [LawfulMonad m] {f : α → δ → m (ForInStep δ)}
{init : δ} :
t.forIn (fun a _ d => f a d) init = ForIn.forIn t.keysArray init f := by
rw [forIn_eq_forIn_keys, ← toArray_keys, List.forIn_toArray]
namespace Const namespace Const
variable {β : Type v} {t : Impl α β} variable {β : Type v} {t : Impl α β}
@ -1821,28 +2026,55 @@ theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m]
t.foldlM f init = (Const.toList t).foldlM (fun a b => f a b.1 b.2) init := by t.foldlM f init = (Const.toList t).foldlM (fun a b => f a b.1 b.2) init := by
simp_to_model [foldlM, Const.toList] using List.foldlM_eq_foldlM_toProd simp_to_model [foldlM, Const.toList] using List.foldlM_eq_foldlM_toProd
theorem foldlM_eq_foldlM_toArray [Monad m] [LawfulMonad m]
{f : δ → (a : α) → β → m δ} {init : δ} :
t.foldlM f init = (Const.toArray t).foldlM (fun a b => f a b.1 b.2) init := by
rw [foldlM_eq_foldlM_toList, ← toArray_toList, List.foldlM_toArray]
theorem foldl_eq_foldl_toList {f : δ → (a : α) → β → δ} {init : δ} : theorem foldl_eq_foldl_toList {f : δ → (a : α) → β → δ} {init : δ} :
t.foldl f init = (Const.toList t).foldl (fun a b => f a b.1 b.2) init := by t.foldl f init = (Const.toList t).foldl (fun a b => f a b.1 b.2) init := by
simp_to_model [foldl, Const.toList] using List.foldl_eq_foldl_toProd simp_to_model [foldl, Const.toList] using List.foldl_eq_foldl_toProd
theorem foldl_eq_foldl_toArray {f : δ → (a : α) → β → δ} {init : δ} :
t.foldl f init = (Const.toArray t).foldl (fun a b => f a b.1 b.2) init := by
rw [foldl_eq_foldl_toList, ← toArray_toList, List.foldl_toArray]
theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m]
{f : (a : α) → β → δ → m δ} {init : δ} : {f : (a : α) → β → δ → m δ} {init : δ} :
t.foldrM f init = (Const.toList t).foldrM (fun a b => f a.1 a.2 b) init := by t.foldrM f init = (Const.toList t).foldrM (fun a b => f a.1 a.2 b) init := by
simp_to_model [foldrM, Const.toList] using List.foldrM_eq_foldrM_toProd simp_to_model [foldrM, Const.toList] using List.foldrM_eq_foldrM_toProd
theorem foldrM_eq_foldrM_toArray [Monad m] [LawfulMonad m]
{f : (a : α) → β → δ → m δ} {init : δ} :
t.foldrM f init = (Const.toArray t).foldrM (fun a b => f a.1 a.2 b) init := by
rw [foldrM_eq_foldrM_toList, ← toArray_toList, List.foldrM_toArray]
theorem foldr_eq_foldr_toList {f : (a : α) → β → δ → δ} {init : δ} : theorem foldr_eq_foldr_toList {f : (a : α) → β → δ → δ} {init : δ} :
t.foldr f init = (Const.toList t).foldr (fun a b => f a.1 a.2 b) init := by t.foldr f init = (Const.toList t).foldr (fun a b => f a.1 a.2 b) init := by
simp_to_model [foldr, Const.toList] using List.foldr_eq_foldr_toProd simp_to_model [foldr, Const.toList] using List.foldr_eq_foldr_toProd
theorem foldr_eq_foldr_toArray {f : (a : α) → β → δ → δ} {init : δ} :
t.foldr f init = (Const.toArray t).foldr (fun a b => f a.1 a.2 b) init := by
rw [foldr_eq_foldr_toList, ← toArray_toList, List.foldr_toArray]
theorem forM_eq_forM_toList [Monad m] [LawfulMonad m] {f : (a : α) → β → m PUnit} : theorem forM_eq_forM_toList [Monad m] [LawfulMonad m] {f : (a : α) → β → m PUnit} :
t.forM f = (Const.toList t).forM (fun a => f a.1 a.2) := by t.forM f = (Const.toList t).forM (fun a => f a.1 a.2) := by
simp_to_model [forM, Const.toList] using List.forM_eq_forM_toProd simp_to_model [forM, Const.toList] using List.forM_eq_forM_toProd
theorem forM_eq_forM_toArray [Monad m] [LawfulMonad m] {f : (a : α) → β → m PUnit} :
t.forM f = (Const.toArray t).forM (fun a => f a.1 a.2) := by
rw [forM_eq_forM_toList, ← toArray_toList, List.forM_toArray' _ _ rfl]
theorem forIn_eq_forIn_toList [Monad m] [LawfulMonad m] theorem forIn_eq_forIn_toList [Monad m] [LawfulMonad m]
{f : α → β → δ → m (ForInStep δ)} {init : δ} : {f : α → β → δ → m (ForInStep δ)} {init : δ} :
t.forIn f init = ForIn.forIn (Const.toList t) init (fun a b => f a.1 a.2 b) := by t.forIn f init = ForIn.forIn (Const.toList t) init (fun a b => f a.1 a.2 b) := by
simp_to_model [forIn, Const.toList] using List.forIn_eq_forIn_toProd simp_to_model [forIn, Const.toList] using List.forIn_eq_forIn_toProd
theorem forIn_eq_forIn_toArray [Monad m] [LawfulMonad m]
{f : α → β → δ → m (ForInStep δ)} {init : δ} :
t.forIn f init = ForIn.forIn (Const.toArray t) init (fun a b => f a.1 a.2 b) := by
rw [forIn_eq_forIn_toList, ← toArray_toList, List.forIn_toArray]
end Const end Const
end monadic end monadic
@ -7108,6 +7340,10 @@ theorem minKey?_eq_head?_keys [TransOrd α] (h : t.WF) :
t.minKey? = t.keys.head? := by t.minKey? = t.keys.head? := by
simp_to_model [minKey?, keys] using List.minKey?_eq_head?_keys h.ordered simp_to_model [minKey?, keys] using List.minKey?_eq_head?_keys h.ordered
theorem minKey?_eq_getElem?_keysArray [TransOrd α] (h : t.WF) :
t.minKey? = t.keysArray[0]? := by
simp [minKey?_eq_head?_keys h, ← toList_keysArray, List.head?_eq_getElem?, Array.getElem?_toList]
theorem minKey?_modify [TransOrd α] [LawfulEqOrd α] {k f} (h : t.WF) : theorem minKey?_modify [TransOrd α] [LawfulEqOrd α] {k f} (h : t.WF) :
(t.modify k f).minKey? = t.minKey? := by (t.modify k f).minKey? = t.minKey? := by
simp_to_model [modify, minKey?] using List.minKey?_modifyKey simp_to_model [modify, minKey?] using List.minKey?_modifyKey
@ -7262,6 +7498,11 @@ theorem minKey_eq_head_keys [TransOrd α] (h : t.WF) {he} :
t.minKey he = t.keys.head (List.isEmpty_eq_false_iff.mp <| isEmpty_keys ▸ he) := by t.minKey he = t.keys.head (List.isEmpty_eq_false_iff.mp <| isEmpty_keys ▸ he) := by
simp_to_model [minKey, keys] using List.minKey_eq_head_keys h.ordered simp_to_model [minKey, keys] using List.minKey_eq_head_keys h.ordered
theorem minKey_eq_getElem_keysArray [TransOrd α] (h : t.WF) {he} :
t.minKey he = t.keysArray[0]'(Nat.zero_lt_of_ne_zero (by simpa [size_keysArray h, isEmpty_eq_size_eq_zero h] using he)) := by
simp [minKey_eq_head_keys h, List.head_eq_iff_head?_eq_some, ← toList_keysArray, List.head?_eq_getElem?, Array.getElem?_toList,
getElem?_eq_some_getElem_iff]
theorem minKey_modify [TransOrd α] [LawfulEqOrd α] (h : t.WF) {k f he} : theorem minKey_modify [TransOrd α] [LawfulEqOrd α] (h : t.WF) {k f he} :
(t.modify k f).minKey he = t.minKey (isEmpty_modify h ▸ he):= by (t.modify k f).minKey he = t.minKey (isEmpty_modify h ▸ he):= by
simp_to_model [minKey, modify] using List.minKey_modifyKey simp_to_model [minKey, modify] using List.minKey_modifyKey
@ -7460,6 +7701,10 @@ theorem minKey!_eq_head!_keys [TransOrd α] [Inhabited α] (h : t.WF) :
t.minKey! = t.keys.head! := by t.minKey! = t.keys.head! := by
simp_to_model [minKey!, keys] using List.minKey!_eq_head!_keys h.ordered simp_to_model [minKey!, keys] using List.minKey!_eq_head!_keys h.ordered
theorem minKey!_eq_getElem!_keysArray [TransOrd α] [Inhabited α] (h : t.WF) :
t.minKey! = t.keysArray[0]! := by
simp [minKey!_eq_head!_keys h, ← toList_keysArray, List.head!_eq_getElem!, Array.getElem!_eq_getD]
theorem minKey!_modify [TransOrd α] [LawfulEqOrd α] [Inhabited α] (h : t.WF) : ∀ {k f}, theorem minKey!_modify [TransOrd α] [LawfulEqOrd α] [Inhabited α] (h : t.WF) : ∀ {k f},
(t.modify k f).minKey! = t.minKey! := by (t.modify k f).minKey! = t.minKey! := by
simp_to_model [minKey!, modify] using List.minKey!_modifyKey simp_to_model [minKey!, modify] using List.minKey!_modifyKey
@ -7677,6 +7922,10 @@ theorem minKeyD_eq_headD_keys [TransOrd α] (h : t.WF) {fallback} :
t.minKeyD fallback = t.keys.headD fallback := by t.minKeyD fallback = t.keys.headD fallback := by
simp_to_model [minKeyD, keys] using List.minKeyD_eq_headD_keys h.ordered simp_to_model [minKeyD, keys] using List.minKeyD_eq_headD_keys h.ordered
theorem minKeyD_eq_getD_keysArray [TransOrd α] (h : t.WF) {fallback} :
t.minKeyD fallback = t.keysArray.getD 0 fallback := by
simp [minKeyD_eq_headD_keys h, ← toList_keysArray, List.head?_eq_getElem?]
theorem minKeyD_modify [TransOrd α] [LawfulEqOrd α] (h : t.WF) : ∀ {k f fallback}, theorem minKeyD_modify [TransOrd α] [LawfulEqOrd α] (h : t.WF) : ∀ {k f fallback},
(t.modify k f |>.minKeyD fallback) = t.minKeyD fallback := by (t.modify k f |>.minKeyD fallback) = t.minKeyD fallback := by
simp_to_model [minKeyD, modify] using List.minKeyD_modifyKey simp_to_model [minKeyD, modify] using List.minKeyD_modifyKey
@ -7945,6 +8194,10 @@ theorem maxKey?_eq_getLast?_keys [TransOrd α] (h : t.WF) :
t.maxKey? = t.keys.getLast? := by t.maxKey? = t.keys.getLast? := by
simp_to_model [maxKey?, keys] using List.maxKey?_eq_getLast?_keys _ h.ordered simp_to_model [maxKey?, keys] using List.maxKey?_eq_getLast?_keys _ h.ordered
theorem maxKey?_eq_back?_keysArray [TransOrd α] (h : t.WF) :
t.maxKey? = t.keysArray.back? := by
simp [maxKey?_eq_getLast?_keys h, ← toList_keysArray]
theorem maxKey?_modify [TransOrd α] [LawfulEqOrd α] {k f} (h : t.WF) : theorem maxKey?_modify [TransOrd α] [LawfulEqOrd α] {k f} (h : t.WF) :
(t.modify k f).maxKey? = t.maxKey? := by (t.modify k f).maxKey? = t.maxKey? := by
simp_to_model [modify, maxKey?] using List.maxKey?_modifyKey simp_to_model [modify, maxKey?] using List.maxKey?_modifyKey
@ -8095,6 +8348,10 @@ theorem maxKey_eq_getLast_keys [TransOrd α] (h : t.WF) {he} :
t.maxKey he = t.keys.getLast (List.isEmpty_eq_false_iff.mp <| isEmpty_keys ▸ he) := by t.maxKey he = t.keys.getLast (List.isEmpty_eq_false_iff.mp <| isEmpty_keys ▸ he) := by
simp_to_model [maxKey, keys] using List.maxKey_eq_getLast_keys h.ordered.distinctKeys h.ordered simp_to_model [maxKey, keys] using List.maxKey_eq_getLast_keys h.ordered.distinctKeys h.ordered
theorem maxKey_eq_back_keysArray [TransOrd α] (h : t.WF) {he} :
t.maxKey he = t.keysArray.back (Nat.zero_lt_of_ne_zero (by simpa [size_keysArray h, isEmpty_eq_size_eq_zero h] using he)) := by
simp [maxKey_eq_getLast_keys h, ← toArray_keys, List.back_toArray]
theorem maxKey_modify [TransOrd α] [LawfulEqOrd α] (h : t.WF) {k f he} : theorem maxKey_modify [TransOrd α] [LawfulEqOrd α] (h : t.WF) {k f he} :
(t.modify k f).maxKey he = t.maxKey (isEmpty_modify h ▸ he):= by (t.modify k f).maxKey he = t.maxKey (isEmpty_modify h ▸ he):= by
simp_to_model [maxKey, modify] using List.maxKey_modifyKey simp_to_model [maxKey, modify] using List.maxKey_modifyKey
@ -8293,6 +8550,10 @@ theorem maxKey!_eq_getLast!_keys [TransOrd α] [Inhabited α] (h : t.WF) :
t.maxKey! = t.keys.getLast! := by t.maxKey! = t.keys.getLast! := by
simp_to_model [maxKey!, keys] using List.maxKey!_eq_getLast!_keys h.ordered.distinctKeys h.ordered simp_to_model [maxKey!, keys] using List.maxKey!_eq_getLast!_keys h.ordered.distinctKeys h.ordered
theorem maxKey!_eq_back!_keysArray [TransOrd α] [Inhabited α] (h : t.WF) :
t.maxKey! = t.keysArray.back! := by
simp [maxKey!_eq_getLast!_keys h, ← toArray_keys]
theorem maxKey!_modify [TransOrd α] [LawfulEqOrd α] [Inhabited α] (h : t.WF) : ∀ {k f}, theorem maxKey!_modify [TransOrd α] [LawfulEqOrd α] [Inhabited α] (h : t.WF) : ∀ {k f},
(t.modify k f).maxKey! = t.maxKey! := by (t.modify k f).maxKey! = t.maxKey! := by
simp_to_model [maxKey!, modify] using List.maxKey!_modifyKey simp_to_model [maxKey!, modify] using List.maxKey!_modifyKey
@ -8510,6 +8771,10 @@ theorem maxKeyD_eq_getLastD_keys [TransOrd α] (h : t.WF) {fallback} :
t.maxKeyD fallback = t.keys.getLastD fallback := by t.maxKeyD fallback = t.keys.getLastD fallback := by
simp_to_model [maxKeyD, keys] using List.maxKeyD_eq_getLastD_keys h.ordered.distinctKeys h.ordered simp_to_model [maxKeyD, keys] using List.maxKeyD_eq_getLastD_keys h.ordered.distinctKeys h.ordered
theorem maxKeyD_eq_getD_back?_keysArray [TransOrd α] (h : t.WF) {fallback} :
t.maxKeyD fallback = t.keysArray.back?.getD fallback := by
simp [maxKeyD_eq_getLastD_keys h, ← toList_keysArray]
theorem maxKeyD_modify [TransOrd α] [LawfulEqOrd α] (h : t.WF) : ∀ {k f fallback}, theorem maxKeyD_modify [TransOrd α] [LawfulEqOrd α] (h : t.WF) : ∀ {k f fallback},
(t.modify k f |>.maxKeyD fallback) = t.maxKeyD fallback := by (t.modify k f |>.maxKeyD fallback) = t.maxKeyD fallback := by
simp_to_model [maxKeyD, modify] using List.maxKeyD_modifyKey simp_to_model [maxKeyD, modify] using List.maxKeyD_modifyKey
@ -9306,13 +9571,24 @@ theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList := by theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList := by
simp_to_model [toList, Equiv] simp_to_model [toList, Equiv]
theorem equiv_iff_toArray_perm : t₁ ~m t₂ ↔ t₁.toArray.Perm t₂.toArray := by
rw [equiv_iff_toList_perm, ← toArray_toList (t := t₁), ← toArray_toList (t := t₂),
Array.perm_iff_toList_perm]
theorem Equiv.of_toList_perm : t₁.toList.Perm t₂.toList → t₁ ~m t₂ := theorem Equiv.of_toList_perm : t₁.toList.Perm t₂.toList → t₁ ~m t₂ :=
equiv_iff_toList_perm.mpr equiv_iff_toList_perm.mpr
theorem Equiv.of_toArray_perm : t₁.toArray.Perm t₂.toArray → t₁ ~m t₂ :=
equiv_iff_toArray_perm.mpr
theorem equiv_iff_toList_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) : theorem equiv_iff_toList_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ t₁.toList = t₂.toList := t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
⟨Equiv.toList_eq h₁ h₂, .of_toList_perm ∘ .of_eq⟩ ⟨Equiv.toList_eq h₁ h₂, .of_toList_perm ∘ .of_eq⟩
theorem equiv_iff_toArray_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ t₁.toArray = t₂.toArray := by
simp [equiv_iff_toList_eq h₁ h₂, ← toArray_toList (t := t₁), ← toArray_toList (t := t₂)]
theorem insertMany_list_equiv_foldl {l : List ((a : α) × β a)} (h : t₁.WF) : theorem insertMany_list_equiv_foldl {l : List ((a : α) × β a)} (h : t₁.WF) :
t₁.insertMany l h.balanced ~m (l.foldl (init := t₁) fun acc p => acc.insert! p.1 p.2) := by t₁.insertMany l h.balanced ~m (l.foldl (init := t₁) fun acc p => acc.insert! p.1 p.2) := by
rw [insertMany_eq_foldl] rw [insertMany_eq_foldl]
@ -9341,12 +9617,20 @@ theorem Const.equiv_iff_toList_perm : t₁ ~m t₂ ↔ (Const.toList t₁).Perm
have := h.map (fun (x, y) => (⟨x, y⟩ : (_ : α) × β)) have := h.map (fun (x, y) => (⟨x, y⟩ : (_ : α) × β))
simpa only [List.map_map, Function.comp_def, List.map_id'] using this simpa only [List.map_map, Function.comp_def, List.map_id'] using this
theorem Const.equiv_iff_toArray_perm : t₁ ~m t₂ ↔ (Const.toArray t₁).Perm (Const.toArray t₂) := by
rw [Const.equiv_iff_toList_perm, ← toArray_toList (t := t₁), ← toArray_toList (t := t₂),
Array.perm_iff_toList_perm]
theorem Const.equiv_iff_toList_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) : theorem Const.equiv_iff_toList_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ Const.toList t₁ = Const.toList t₂ := by t₁ ~m t₂ ↔ Const.toList t₁ = Const.toList t₂ := by
simp_to_model [Const.toList] simp_to_model [Const.toList]
rw [List.map_inj_right fun _ _ => congrArg fun x : α × β => (⟨x.1, x.2⟩ : (_ : α) × β)] rw [List.map_inj_right fun _ _ => congrArg fun x : α × β => (⟨x.1, x.2⟩ : (_ : α) × β)]
exact ⟨(·.toListModel_eq h₁.ordered h₂.ordered), .mk ∘ .of_eq⟩ exact ⟨(·.toListModel_eq h₁.ordered h₂.ordered), .mk ∘ .of_eq⟩
theorem Const.equiv_iff_toArray_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ Const.toArray t₁ = Const.toArray t₂ := by
simp [Const.equiv_iff_toList_eq h₁ h₂, ← toArray_toList (t := t₁), ← toArray_toList (t := t₂)]
theorem Const.equiv_iff_keys_perm {t₁ t₂ : Impl α Unit} : theorem Const.equiv_iff_keys_perm {t₁ t₂ : Impl α Unit} :
t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys := by t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys := by
simp_to_model [keys, Equiv] simp_to_model [keys, Equiv]
@ -9357,6 +9641,19 @@ theorem Const.equiv_iff_keys_perm {t₁ t₂ : Impl α Unit} :
have := h.map (fun x => (⟨x, ()⟩ : (_ : α) × Unit)) have := h.map (fun x => (⟨x, ()⟩ : (_ : α) × Unit))
simpa only [List.map_map, Function.comp_def, List.map_id'] using this simpa only [List.map_map, Function.comp_def, List.map_id'] using this
theorem Const.Equiv.of_keys_perm {t₁ t₂ : Impl α Unit} :
t₁.keys.Perm t₂.keys → t₁ ~m t₂ :=
Const.equiv_iff_keys_perm.mpr
theorem Const.equiv_iff_keysArray_perm {t₁ t₂ : Impl α Unit} :
t₁ ~m t₂ ↔ t₁.keysArray.Perm t₂.keysArray := by
rw [Const.equiv_iff_keys_perm, ← toArray_keys (t := t₁), ← toArray_keys (t := t₂),
Array.perm_iff_toList_perm]
theorem Const.Equiv.of_keysArray_perm {t₁ t₂ : Impl α Unit} :
t₁.keysArray.Perm t₂.keysArray → t₁ ~m t₂ :=
Const.equiv_iff_keysArray_perm.mpr
theorem Const.equiv_iff_keys_eq {t₁ t₂ : Impl α Unit} [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) : theorem Const.equiv_iff_keys_eq {t₁ t₂ : Impl α Unit} [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ t₁.keys = t₂.keys := by t₁ ~m t₂ ↔ t₁.keys = t₂.keys := by
simp_to_model [keys] simp_to_model [keys]
@ -9364,6 +9661,10 @@ theorem Const.equiv_iff_keys_eq {t₁ t₂ : Impl α Unit} [TransOrd α] (h₁ :
rw [List.map_inj_right fun _ _ => congrArg fun x : α => (⟨x, ()⟩ : (_ : α) × Unit)] rw [List.map_inj_right fun _ _ => congrArg fun x : α => (⟨x, ()⟩ : (_ : α) × Unit)]
exact ⟨(·.toListModel_eq h₁.ordered h₂.ordered), .mk ∘ .of_eq⟩ exact ⟨(·.toListModel_eq h₁.ordered h₂.ordered), .mk ∘ .of_eq⟩
theorem Const.equiv_iff_keysArray_eq {t₁ t₂ : Impl α Unit} [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ t₁.keysArray = t₂.keysArray := by
simp [Const.equiv_iff_keys_eq h₁ h₂, ← toArray_keys (t := t₁), ← toArray_keys (t := t₂)]
theorem Const.insertMany_list_equiv_foldl {l : List (α × β)} (h : t₁.WF) : theorem Const.insertMany_list_equiv_foldl {l : List (α × β)} (h : t₁.WF) :
insertMany t₁ l h.balanced ~m (l.foldl (init := t₁) fun acc p => acc.insert! p.1 p.2) := by insertMany t₁ l h.balanced ~m (l.foldl (init := t₁) fun acc p => acc.insert! p.1 p.2) := by
rw [insertMany_eq_foldl] rw [insertMany_eq_foldl]
@ -9393,11 +9694,21 @@ theorem toList_filterMap {f : (a : α) → β a → Option (γ a)} (h : t.WF) :
t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) := by t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) := by
simp_to_model [filterMap, toList, Equiv] simp_to_model [filterMap, toList, Equiv]
theorem toArray_filterMap {f : (a : α) → β a → Option (γ a)} (h : t.WF) :
(t.filterMap f h.balanced).1.toArray =
t.toArray.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) := by
rw [← toArray_toList, toList_filterMap h, ← toArray_toList, List.filterMap_toArray]
theorem toList_filterMap! {f : (a : α) → β a → Option (γ a)} (h : t.WF) : theorem toList_filterMap! {f : (a : α) → β a → Option (γ a)} (h : t.WF) :
(t.filterMap! f).toList = (t.filterMap! f).toList =
t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) := by t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) := by
simpa only [filterMap_eq_filterMap!] using toList_filterMap h simpa only [filterMap_eq_filterMap!] using toList_filterMap h
theorem toArray_filterMap! {f : (a : α) → β a → Option (γ a)} (h : t.WF) :
(t.filterMap! f).toArray =
t.toArray.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) := by
simpa only [filterMap_eq_filterMap!] using toArray_filterMap h
theorem isEmpty_filterMap_iff [TransOrd α] [LawfulEqOrd α] theorem isEmpty_filterMap_iff [TransOrd α] [LawfulEqOrd α]
{f : (a : α) → β a → Option (γ a)} (h : t.WF) : {f : (a : α) → β a → Option (γ a)} (h : t.WF) :
(t.filterMap f h.balanced).1.isEmpty = true ↔ (t.filterMap f h.balanced).1.isEmpty = true ↔
@ -9740,11 +10051,21 @@ theorem toList_filterMap {f : α → β → Option γ} (h : t.WF) :
simp_to_model [Const.toList, filterMap] simp_to_model [Const.toList, filterMap]
simp only [List.map_filterMap, List.filterMap_map, Function.comp_def, Option.map_map] simp only [List.map_filterMap, List.filterMap_map, Function.comp_def, Option.map_map]
theorem toArray_filterMap {f : α → β → Option γ} (h : t.WF) :
Const.toArray (t.filterMap f h.balanced).1 =
(Const.toArray t).filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) := by
rw [← toArray_toList, toList_filterMap h, ← toArray_toList, List.filterMap_toArray]
theorem toList_filterMap! {f : α → β → Option γ} (h : t.WF) : theorem toList_filterMap! {f : α → β → Option γ} (h : t.WF) :
Const.toList (t.filterMap! f) = Const.toList (t.filterMap! f) =
(Const.toList t).filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) := by (Const.toList t).filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) := by
simpa only [filterMap_eq_filterMap!] using toList_filterMap h simpa only [filterMap_eq_filterMap!] using toList_filterMap h
theorem toArray_filterMap! {f : α → β → Option γ} (h : t.WF) :
Const.toArray (t.filterMap! f) =
(Const.toArray t).filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) := by
simpa only [filterMap_eq_filterMap!] using toArray_filterMap h
theorem getKey?_filterMap [TransOrd α] theorem getKey?_filterMap [TransOrd α]
{f : α → β → Option γ} {k : α} (h : t.WF) : {f : α → β → Option γ} {k : α} (h : t.WF) :
(t.filterMap f h.balanced).1.getKey? k = (t.filterMap f h.balanced).1.getKey? k =
@ -9808,19 +10129,36 @@ theorem toList_filter {f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter f h.balanced).1.toList = t.toList.filter (fun p => f p.1 p.2) := by (t.filter f h.balanced).1.toList = t.toList.filter (fun p => f p.1 p.2) := by
simp_to_model [filter, toList, Equiv] simp_to_model [filter, toList, Equiv]
theorem toArray_filter {f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter f h.balanced).1.toArray = t.toArray.filter (fun p => f p.1 p.2) := by
simp_to_model [filter, toArray, Equiv]
simp
theorem toList_filter! {f : (a : α) → β a → Bool} (h : t.WF) : theorem toList_filter! {f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter! f).toList = t.toList.filter (fun p => f p.1 p.2) := by (t.filter! f).toList = t.toList.filter (fun p => f p.1 p.2) := by
simpa only [filter_eq_filter!] using toList_filter h simpa only [filter_eq_filter!] using toList_filter h
theorem toArray_filter! {f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter! f).toArray = t.toArray.filter (fun p => f p.1 p.2) := by
simpa only [filter_eq_filter!] using toArray_filter h
theorem keys_filter_key {f : α → Bool} (h : t.WF) : theorem keys_filter_key {f : α → Bool} (h : t.WF) :
(t.filter (fun k _ => f k) h.balanced).1.keys = t.keys.filter f := by (t.filter (fun k _ => f k) h.balanced).1.keys = t.keys.filter f := by
simp_to_model [keys, filter] simp_to_model [keys, filter]
simp only [List.keys_eq_map, List.filter_map, Function.comp_def] simp only [List.keys_eq_map, List.filter_map, Function.comp_def]
theorem keysArray_filter_key {f : α → Bool} (h : t.WF) :
(t.filter (fun k _ => f k) h.balanced).1.keysArray = t.keysArray.filter f := by
rw [← toArray_keys, keys_filter_key h, ← toArray_keys, List.filter_toArray]
theorem keys_filter!_key {f : α → Bool} (h : t.WF) : theorem keys_filter!_key {f : α → Bool} (h : t.WF) :
(t.filter! (fun k _ => f k)).keys = t.keys.filter f := by (t.filter! (fun k _ => f k)).keys = t.keys.filter f := by
simpa only [filter_eq_filter!] using keys_filter_key h simpa only [filter_eq_filter!] using keys_filter_key h
theorem keysArray_filter!_key {f : α → Bool} (h : t.WF) :
(t.filter! (fun k _ => f k)).keysArray = t.keysArray.filter f := by
simpa only [filter_eq_filter!] using keysArray_filter_key h
theorem isEmpty_filter_iff [TransOrd α] [LawfulEqOrd α] theorem isEmpty_filter_iff [TransOrd α] [LawfulEqOrd α]
{f : (a : α) → β a → Bool} (h : t.WF) : {f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter f h.balanced).1.isEmpty = true ↔ (t.filter f h.balanced).1.isEmpty = true ↔
@ -10001,11 +10339,36 @@ theorem keys_filter [TransOrd α] [LawfulEqOrd α] {f : (a : α) → β a → Bo
rw [List.keys_filter h.ordered.distinctKeys] rw [List.keys_filter h.ordered.distinctKeys]
simp only [List.filter_map, Function.comp_def, List.unattach, List.map_map] simp only [List.filter_map, Function.comp_def, List.unattach, List.map_map]
private theorem List.unattach_filter_eq_if {p : α → Prop} {l : List { x // p x }}
{f : { x // p x } → Bool} :
open scoped Classical in
(l.filter f).unattach = l.unattach.filter (fun x => if h : p x then f ⟨x, h⟩ else false) := by
apply List.unattach_filter
simp +contextual
private theorem Array.unattach_filter_eq_if {p : α → Prop} {xs : Array { x // p x }}
{f : { x // p x } → Bool} :
open scoped Classical in
(xs.filter f).unattach = xs.unattach.filter (fun x => if h : p x then f ⟨x, h⟩ else false) := by
apply Array.unattach_filter
simp +contextual
theorem keysArray_filter [TransOrd α] [LawfulEqOrd α] {f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter f h.balanced).1.keysArray =
(t.keysArray.attach.filter (fun ⟨x, h'⟩ => f x (t.get x (mem_of_mem_keysArray h h')))).unattach := by
simp only [← toArray_keys, keys_filter h, List.unattach_filter_eq_if, Array.unattach_filter_eq_if]
simp [← toArray_keys]
theorem keys_filter! [TransOrd α] [LawfulEqOrd α] {f : (a : α) → β a → Bool} (h : t.WF) : theorem keys_filter! [TransOrd α] [LawfulEqOrd α] {f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter! f).keys = (t.filter! f).keys =
(t.keys.attach.filter (fun ⟨x, h'⟩ => f x (t.get x (mem_of_mem_keys h h')))).unattach := by (t.keys.attach.filter (fun ⟨x, h'⟩ => f x (t.get x (mem_of_mem_keys h h')))).unattach := by
simpa only [filter_eq_filter!] using keys_filter h simpa only [filter_eq_filter!] using keys_filter h
theorem keysArray_filter! [TransOrd α] [LawfulEqOrd α] {f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter! f).keysArray =
(t.keysArray.attach.filter (fun ⟨x, h'⟩ => f x (t.get x (mem_of_mem_keysArray h h')))).unattach := by
simpa only [filter_eq_filter!] using keysArray_filter h
theorem getKey?_filter [TransOrd α] [LawfulEqOrd α] theorem getKey?_filter [TransOrd α] [LawfulEqOrd α]
{f : (a : α) → β a → Bool} {k : α} (h : t.WF) : {f : (a : α) → β a → Bool} {k : α} (h : t.WF) :
(t.filter f h.balanced).1.getKey? k = (t.filter f h.balanced).1.getKey? k =
@ -10259,11 +10622,21 @@ theorem toList_filter {f : α → β → Bool} (h : t.WF) :
simp_to_model [filter, Const.toList] simp_to_model [filter, Const.toList]
simp only [List.filter_map, Function.comp_def] simp only [List.filter_map, Function.comp_def]
theorem toArray_filter {f : α → β → Bool} (h : t.WF) :
Const.toArray (t.filter f h.balanced).1 =
(Const.toArray t).filter (fun p => f p.1 p.2) := by
rw [← toArray_toList, toList_filter h, ← toArray_toList, List.filter_toArray]
theorem toList_filter! {f : α → β → Bool} (h : t.WF) : theorem toList_filter! {f : α → β → Bool} (h : t.WF) :
Const.toList (t.filter! f) = Const.toList (t.filter! f) =
(Const.toList t).filter (fun p => f p.1 p.2) := by (Const.toList t).filter (fun p => f p.1 p.2) := by
simpa only [filter_eq_filter!] using toList_filter h simpa only [filter_eq_filter!] using toList_filter h
theorem toArray_filter! {f : α → β → Bool} (h : t.WF) :
Const.toArray (t.filter! f) =
(Const.toArray t).filter (fun p => f p.1 p.2) := by
simpa only [filter_eq_filter!] using toArray_filter h
theorem keys_filter [TransOrd α] {f : α → β → Bool} (h : t.WF): theorem keys_filter [TransOrd α] {f : α → β → Bool} (h : t.WF):
(t.filter f h.balanced).1.keys = (t.filter f h.balanced).1.keys =
(t.keys.attach.filter (fun ⟨x, h'⟩ => f x (get t x (mem_of_mem_keys h h')))).unattach := by (t.keys.attach.filter (fun ⟨x, h'⟩ => f x (get t x (mem_of_mem_keys h h')))).unattach := by
@ -10272,11 +10645,29 @@ theorem keys_filter [TransOrd α] {f : α → β → Bool} (h : t.WF):
rw [List.Const.keys_filter h.ordered.distinctKeys] rw [List.Const.keys_filter h.ordered.distinctKeys]
simp only [List.filter_map, Function.comp_def, List.unattach, List.map_map] simp only [List.filter_map, Function.comp_def, List.unattach, List.map_map]
theorem keysArray_filter [TransOrd α] {f : α → β → Bool} (h : t.WF):
(t.filter f h.balanced).1.keysArray =
(t.keysArray.attach.filter (fun ⟨x, h'⟩ => f x (get t x (mem_of_mem_keysArray h h')))).unattach := by
simp only [← toArray_keys, keys_filter h]
simp only [List.unattach_filter_eq_if, Array.unattach_filter_eq_if]
simp only [List.unattach_attach, Array.unattach_attach, ← toArray_keys, List.mem_toArray,
List.size_toArray, List.filter_toArray']
congr; ext x
split <;> rename_i h'
all_goals
rw [← toList_keysArray, Array.mem_toList_iff] at h'
simp [h']
theorem keys_filter! [TransOrd α] {f : α → β → Bool} (h : t.WF): theorem keys_filter! [TransOrd α] {f : α → β → Bool} (h : t.WF):
(t.filter! f).keys = (t.filter! f).keys =
(t.keys.attach.filter (fun ⟨x, h'⟩ => f x (get t x (mem_of_mem_keys h h')))).unattach := by (t.keys.attach.filter (fun ⟨x, h'⟩ => f x (get t x (mem_of_mem_keys h h')))).unattach := by
simpa only [filter_eq_filter!] using keys_filter h simpa only [filter_eq_filter!] using keys_filter h
theorem keysArray_filter! [TransOrd α] {f : α → β → Bool} (h : t.WF):
(t.filter! f).keysArray =
(t.keysArray.attach.filter (fun ⟨x, h'⟩ => f x (get t x (mem_of_mem_keysArray h h')))).unattach := by
simpa only [filter_eq_filter!] using keysArray_filter h
theorem getKey?_filter [TransOrd α] theorem getKey?_filter [TransOrd α]
{f : α → β → Bool} {k : α} (h : t.WF) : {f : α → β → Bool} {k : α} (h : t.WF) :
(t.filter f h.balanced).1.getKey? k = (t.filter f h.balanced).1.getKey? k =
@ -10338,10 +10729,17 @@ theorem toList_map {f : (a : α) → β a → γ a} :
(t.map f).toList = t.toList.map (fun p => ⟨p.1, f p.1 p.2⟩) := by (t.map f).toList = t.toList.map (fun p => ⟨p.1, f p.1 p.2⟩) := by
simp_to_model [map, toList, Equiv] simp_to_model [map, toList, Equiv]
theorem toArray_map {f : (a : α) → β a → γ a} :
(t.map f).toArray = t.toArray.map (fun p => ⟨p.1, f p.1 p.2⟩) := by
rw [← toArray_toList, toList_map, ← toArray_toList, List.map_toArray]
theorem keys_map {f : (a : α) → β a → γ a} : (t.map f).keys = t.keys := by theorem keys_map {f : (a : α) → β a → γ a} : (t.map f).keys = t.keys := by
simp_to_model [keys, map, Equiv] simp_to_model [keys, map, Equiv]
rw [List.keys_map] rw [List.keys_map]
theorem keysArray_map {f : (a : α) → β a → γ a} : (t.map f).keysArray = t.keysArray := by
rw [← toArray_keys, keys_map, toArray_keys]
theorem filterMap_equiv_map theorem filterMap_equiv_map
{f : (a : α) → β a → γ a} (h : t.WF) : {f : (a : α) → β a → γ a} (h : t.WF) :
(t.filterMap (fun k v => some (f k v)) h.balanced).1.Equiv (t.map f) := by (t.filterMap (fun k v => some (f k v)) h.balanced).1.Equiv (t.map f) := by
@ -10483,6 +10881,10 @@ theorem toList_map {f : α → β → γ} :
simp_to_model [map, Const.toList] simp_to_model [map, Const.toList]
simp only [List.map_map, Function.comp_def] simp only [List.map_map, Function.comp_def]
theorem toArray_map {f : α → β → γ} :
Const.toArray (t.map f) = (Const.toArray t).map (fun p => (p.1, f p.1 p.2)) := by
rw [← toArray_toList, toList_map, ← toArray_toList, List.map_toArray]
end Const end Const
end map end map

View file

@ -661,7 +661,7 @@ theorem minKey?_eq_minEntry?_map_fst {l : Impl α β} : l.minKey? = l.minEntry?.
theorem minKey_eq_minEntry_fst {l : Impl α β} {he} : l.minKey he = (l.minEntry he).fst := by theorem minKey_eq_minEntry_fst {l : Impl α β} {he} : l.minKey he = (l.minEntry he).fst := by
induction l, he using minKey.induct_unfolding <;> simp only [minEntry] <;> trivial induction l, he using minKey.induct_unfolding <;> simp only [minEntry] <;> trivial
theorem minKey!_eq_get!_minKey? [Inhabited α] {l : Impl α β} : theorem minKey!_eq_getElem!_minKey? [Inhabited α] {l : Impl α β} :
l.minKey! = l.minKey?.get! := by l.minKey! = l.minKey?.get! := by
induction l using minKey!.induct_unfolding <;> simp only [minKey?] <;> trivial induction l using minKey!.induct_unfolding <;> simp only [minKey?] <;> trivial

View file

@ -2296,7 +2296,7 @@ theorem minKey_eq_minKey [Ord α] [TransOrd α] [BEq α] [LawfulBEqOrd α] {l :
theorem minKey!_eq_minKey! [Ord α] [TransOrd α] [Inhabited α] [BEq α] [LawfulBEqOrd α] theorem minKey!_eq_minKey! [Ord α] [TransOrd α] [Inhabited α] [BEq α] [LawfulBEqOrd α]
{l : Impl α β} (hlo : l.Ordered) : {l : Impl α β} (hlo : l.Ordered) :
l.minKey! = List.minKey! l.toListModel := by l.minKey! = List.minKey! l.toListModel := by
simp [Impl.minKey!_eq_get!_minKey?, List.minKey!_eq_get!_minKey?, minKey?_eq_minKey? hlo] simp [Impl.minKey!_eq_getElem!_minKey?, List.minKey!_eq_get!_minKey?, minKey?_eq_minKey? hlo]
theorem minKeyD_eq_minKeyD [Ord α] [TransOrd α] [BEq α] [LawfulBEqOrd α] {l : Impl α β} theorem minKeyD_eq_minKeyD [Ord α] [TransOrd α] [BEq α] [LawfulBEqOrd α] {l : Impl α β}
(hlo : l.Ordered) {fallback} : (hlo : l.Ordered) {fallback} :

View file

@ -8,6 +8,7 @@ module
prelude prelude
import Std.Data.DTreeMap.Internal.Lemmas import Std.Data.DTreeMap.Internal.Lemmas
public import Std.Data.DTreeMap.AdditionalOperations public import Std.Data.DTreeMap.AdditionalOperations
public import Init.Data.Array.Perm
import Init.Data.List.Pairwise import Init.Data.List.Pairwise
import Init.Data.Prod import Init.Data.Prod
@ -362,14 +363,26 @@ end Const
theorem toList_insert_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} {v : β k} : theorem toList_insert_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} {v : β k} :
(t.insert k v).toList.Perm (⟨k, v⟩ :: t.toList.filter (¬k == ·.1)) := Impl.toList_insert_perm t.wf (t.insert k v).toList.Perm (⟨k, v⟩ :: t.toList.filter (¬k == ·.1)) := Impl.toList_insert_perm t.wf
theorem toArray_insert_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} {v : β k} :
(t.insert k v).toArray.Perm (t.toArray.filter (¬k == ·.1) |>.push ⟨k, v⟩) :=
Impl.toArray_insert_perm t.wf
theorem Const.toList_insert_perm {β : Type v} {t : DTreeMap α (fun _ => β) cmp} [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} {v : β} : theorem Const.toList_insert_perm {β : Type v} {t : DTreeMap α (fun _ => β) cmp} [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} {v : β} :
(Const.toList (t.insert k v)).Perm (⟨k, v⟩ :: (Const.toList t).filter (¬k == ·.1)) := (Const.toList (t.insert k v)).Perm (⟨k, v⟩ :: (Const.toList t).filter (¬k == ·.1)) :=
Impl.Const.toList_insert_perm t.2 Impl.Const.toList_insert_perm t.2
theorem Const.toArray_insert_perm {β : Type v} {t : DTreeMap α (fun _ => β) cmp} [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} {v : β} :
(Const.toArray (t.insert k v)).Perm ((Const.toArray t).filter (¬k == ·.1) |>.push ⟨k, v⟩) :=
Impl.Const.toArray_insert_perm t.2
theorem keys_insertIfNew_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} {v : β k} : theorem keys_insertIfNew_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} {v : β k} :
(t.insertIfNew k v).keys.Perm (if k ∈ t then t.keys else k :: t.keys) := (t.insertIfNew k v).keys.Perm (if k ∈ t then t.keys else k :: t.keys) :=
Impl.keys_insertIfNew_perm t.2 Impl.keys_insertIfNew_perm t.2
theorem keysArray_insertIfNew_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} {v : β k} :
(t.insertIfNew k v).keysArray.Perm (if k ∈ t then t.keysArray else t.keysArray.push k) :=
Impl.keysArray_insertIfNew_perm t.2
@[simp] @[simp]
theorem get_insert_self [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β k} : theorem get_insert_self [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β k} :
(t.insert k v).get k mem_insert_self = v := (t.insert k v).get k mem_insert_self = v :=
@ -1094,24 +1107,47 @@ theorem length_keys [TransCmp cmp] :
t.keys.length = t.size := t.keys.length = t.size :=
Impl.length_keys t.wf Impl.length_keys t.wf
@[simp, grind =]
theorem size_keysArray [TransCmp cmp] :
t.keysArray.size = t.size :=
Impl.size_keysArray t.wf
@[simp, grind =] @[simp, grind =]
theorem isEmpty_keys : theorem isEmpty_keys :
t.keys.isEmpty = t.isEmpty := t.keys.isEmpty = t.isEmpty :=
Impl.isEmpty_keys Impl.isEmpty_keys
@[simp, grind =]
theorem isEmpty_keysArray :
t.keysArray.isEmpty = t.isEmpty :=
Impl.isEmpty_keysArray
@[simp, grind =] @[simp, grind =]
theorem contains_keys [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] {k : α} : theorem contains_keys [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] {k : α} :
t.keys.contains k = t.contains k := t.keys.contains k = t.contains k :=
Impl.contains_keys t.wf Impl.contains_keys t.wf
@[simp, grind =]
theorem contains_keysArray [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] {k : α} :
t.keysArray.contains k = t.contains k :=
Impl.contains_keysArray t.wf
@[simp, grind =] @[simp, grind =]
theorem mem_keys [LawfulEqCmp cmp] [TransCmp cmp] {k : α} : theorem mem_keys [LawfulEqCmp cmp] [TransCmp cmp] {k : α} :
k ∈ t.keys ↔ k ∈ t := k ∈ t.keys ↔ k ∈ t :=
Impl.mem_keys t.wf Impl.mem_keys t.wf
@[simp, grind =]
theorem mem_keysArray [LawfulEqCmp cmp] [TransCmp cmp] {k : α} :
k ∈ t.keysArray ↔ k ∈ t :=
Impl.mem_keysArray t.wf
theorem mem_of_mem_keys [TransCmp cmp] {k : α} (h : k ∈ t.keys) : k ∈ t := theorem mem_of_mem_keys [TransCmp cmp] {k : α} (h : k ∈ t.keys) : k ∈ t :=
Impl.mem_of_mem_keys t.wf h Impl.mem_of_mem_keys t.wf h
theorem mem_of_mem_keysArray [TransCmp cmp] {k : α} (h : k ∈ t.keysArray) : k ∈ t :=
Impl.mem_of_mem_keysArray t.wf h
theorem distinct_keys [TransCmp cmp] : theorem distinct_keys [TransCmp cmp] :
t.keys.Pairwise (fun a b => ¬ cmp a b = .eq) := t.keys.Pairwise (fun a b => ¬ cmp a b = .eq) :=
Impl.distinct_keys t.wf Impl.distinct_keys t.wf
@ -1129,34 +1165,67 @@ theorem map_fst_toList_eq_keys :
t.toList.map Sigma.fst = t.keys := t.toList.map Sigma.fst = t.keys :=
Impl.map_fst_toList_eq_keys Impl.map_fst_toList_eq_keys
@[simp, grind _=_]
theorem map_fst_toArray_eq_keysArray :
t.toArray.map Sigma.fst = t.keysArray :=
Impl.map_fst_toArray_eq_keysArray
@[simp, grind =] @[simp, grind =]
theorem length_toList [TransCmp cmp] : theorem length_toList [TransCmp cmp] :
t.toList.length = t.size := t.toList.length = t.size :=
Impl.length_toList t.wf Impl.length_toList t.wf
@[simp, grind =]
theorem size_toArray [TransCmp cmp] :
t.toArray.size = t.size :=
Impl.size_toArray t.wf
@[simp, grind =] @[simp, grind =]
theorem isEmpty_toList : theorem isEmpty_toList :
t.toList.isEmpty = t.isEmpty := t.toList.isEmpty = t.isEmpty :=
Impl.isEmpty_toList Impl.isEmpty_toList
@[simp, grind =]
theorem isEmpty_toArray :
t.toArray.isEmpty = t.isEmpty :=
Impl.isEmpty_toArray
@[simp, grind =] @[simp, grind =]
theorem mem_toList_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β k} : theorem mem_toList_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β k} :
⟨k, v⟩ ∈ t.toList ↔ t.get? k = some v := ⟨k, v⟩ ∈ t.toList ↔ t.get? k = some v :=
Impl.mem_toList_iff_get?_eq_some t.wf Impl.mem_toList_iff_get?_eq_some t.wf
@[simp, grind =]
theorem mem_toArray_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β k} :
⟨k, v⟩ ∈ t.toArray ↔ t.get? k = some v :=
Impl.mem_toArray_iff_get?_eq_some t.wf
theorem find?_toList_eq_some_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β k} : theorem find?_toList_eq_some_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β k} :
t.toList.find? (cmp ·.1 k == .eq) = some ⟨k, v⟩ ↔ t.get? k = some v := t.toList.find? (cmp ·.1 k == .eq) = some ⟨k, v⟩ ↔ t.get? k = some v :=
Impl.find?_toList_eq_some_iff_get?_eq_some t.wf Impl.find?_toList_eq_some_iff_get?_eq_some t.wf
theorem find?_toArray_eq_some_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β k} :
t.toArray.find? (cmp ·.1 k == .eq) = some ⟨k, v⟩ ↔ t.get? k = some v :=
Impl.find?_toArray_eq_some_iff_get?_eq_some t.wf
theorem find?_toList_eq_none_iff_contains_eq_false [TransCmp cmp] {k : α} : theorem find?_toList_eq_none_iff_contains_eq_false [TransCmp cmp] {k : α} :
t.toList.find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false := t.toList.find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false :=
Impl.find?_toList_eq_none_iff_contains_eq_false t.wf Impl.find?_toList_eq_none_iff_contains_eq_false t.wf
theorem find?_toArray_eq_none_iff_contains_eq_false [TransCmp cmp] {k : α} :
t.toArray.find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false :=
Impl.find?_toArray_eq_none_iff_contains_eq_false t.wf
@[simp] @[simp]
theorem find?_toList_eq_none_iff_not_mem [TransCmp cmp] {k : α} : theorem find?_toList_eq_none_iff_not_mem [TransCmp cmp] {k : α} :
t.toList.find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t := by t.toList.find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t := by
simpa only [Bool.not_eq_true, mem_iff_contains] using find?_toList_eq_none_iff_contains_eq_false simpa only [Bool.not_eq_true, mem_iff_contains] using find?_toList_eq_none_iff_contains_eq_false
@[simp]
theorem find?_toArray_eq_none_iff_not_mem [TransCmp cmp] {k : α} :
t.toArray.find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t :=
Impl.find?_toArray_eq_none_iff_not_mem t.wf
theorem distinct_keys_toList [TransCmp cmp] : theorem distinct_keys_toList [TransCmp cmp] :
t.toList.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq) := t.toList.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq) :=
Impl.distinct_keys_toList t.wf Impl.distinct_keys_toList t.wf
@ -1174,44 +1243,87 @@ theorem map_fst_toList_eq_keys :
(toList t).map Prod.fst = t.keys := (toList t).map Prod.fst = t.keys :=
Impl.Const.map_fst_toList_eq_keys Impl.Const.map_fst_toList_eq_keys
@[simp, grind _=_]
theorem map_fst_toArray_eq_keysArray :
(toArray t).map Prod.fst = t.keysArray :=
Impl.Const.map_fst_toArray_eq_keysArray
@[simp, grind =] @[simp, grind =]
theorem length_toList : theorem length_toList :
(toList t).length = t.size := (toList t).length = t.size :=
Impl.Const.length_toList t.wf Impl.Const.length_toList t.wf
@[simp, grind =]
theorem size_toArray :
(toArray t).size = t.size :=
Impl.Const.size_toArray t.wf
@[simp, grind =] @[simp, grind =]
theorem isEmpty_toList : theorem isEmpty_toList :
(toList t).isEmpty = t.isEmpty := (toList t).isEmpty = t.isEmpty :=
Impl.Const.isEmpty_toList Impl.Const.isEmpty_toList
@[simp, grind =]
theorem isEmpty_toArray :
(toArray t).isEmpty = t.isEmpty :=
Impl.Const.isEmpty_toArray
@[simp, grind =] @[simp, grind =]
theorem mem_toList_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β} : theorem mem_toList_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β} :
(k, v) ∈ toList t ↔ get? t k = some v := (k, v) ∈ toList t ↔ get? t k = some v :=
Impl.Const.mem_toList_iff_get?_eq_some t.wf Impl.Const.mem_toList_iff_get?_eq_some t.wf
@[simp, grind =]
theorem mem_toArray_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β} :
(k, v) ∈ toArray t ↔ get? t k = some v :=
Impl.Const.mem_toArray_iff_get?_eq_some t.wf
@[simp] @[simp]
theorem mem_toList_iff_getKey?_eq_some_and_get?_eq_some [TransCmp cmp] {k : α} {v : β} : theorem mem_toList_iff_getKey?_eq_some_and_get?_eq_some [TransCmp cmp] {k : α} {v : β} :
(k, v) ∈ toList t ↔ t.getKey? k = some k ∧ get? t k = some v := (k, v) ∈ toList t ↔ t.getKey? k = some k ∧ get? t k = some v :=
Impl.Const.mem_toList_iff_getKey?_eq_some_and_get?_eq_some t.wf Impl.Const.mem_toList_iff_getKey?_eq_some_and_get?_eq_some t.wf
@[simp]
theorem mem_toArray_iff_getKey?_eq_some_and_get?_eq_some [TransCmp cmp] {k : α} {v : β} :
(k, v) ∈ toArray t ↔ t.getKey? k = some k ∧ get? t k = some v :=
Impl.Const.mem_toArray_iff_getKey?_eq_some_and_get?_eq_some t.wf
theorem get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList [TransCmp cmp] {k : α} {v : β} : theorem get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList [TransCmp cmp] {k : α} {v : β} :
get? t k = some v ↔ ∃ (k' : α), cmp k k' = .eq ∧ (k', v) ∈ toList t := get? t k = some v ↔ ∃ (k' : α), cmp k k' = .eq ∧ (k', v) ∈ toList t :=
Impl.Const.get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList t.wf Impl.Const.get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList t.wf
theorem get?_eq_some_iff_exists_compare_eq_eq_and_mem_toArray [TransCmp cmp] {k : α} {v : β} :
get? t k = some v ↔ ∃ (k' : α), cmp k k' = .eq ∧ (k', v) ∈ toArray t :=
Impl.Const.get?_eq_some_iff_exists_compare_eq_eq_and_mem_toArray t.wf
theorem find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some [TransCmp cmp] {k k' : α} {v : β} : theorem find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some [TransCmp cmp] {k k' : α} {v : β} :
(toList t).find? (cmp ·.1 k == .eq) = some ⟨k', v⟩ ↔ (toList t).find? (cmp ·.1 k == .eq) = some ⟨k', v⟩ ↔
t.getKey? k = some k' ∧ get? t k = some v := t.getKey? k = some k' ∧ get? t k = some v :=
Impl.Const.find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some t.wf Impl.Const.find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some t.wf
theorem find?_toArray_eq_some_iff_getKey?_eq_some_and_get?_eq_some [TransCmp cmp] {k k' : α} {v : β} :
(toArray t).find? (cmp ·.1 k == .eq) = some (k', v) ↔
t.getKey? k = some k' ∧ get? t k = some v :=
Impl.Const.find?_toArray_eq_some_iff_getKey?_eq_some_and_get?_eq_some t.wf
theorem find?_toList_eq_none_iff_contains_eq_false [TransCmp cmp] {k : α} : theorem find?_toList_eq_none_iff_contains_eq_false [TransCmp cmp] {k : α} :
(toList t).find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false := (toList t).find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false :=
Impl.Const.find?_toList_eq_none_iff_contains_eq_false t.wf Impl.Const.find?_toList_eq_none_iff_contains_eq_false t.wf
theorem find?_toArray_eq_none_iff_contains_eq_false [TransCmp cmp] {k : α} :
(toArray t).find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false :=
Impl.Const.find?_toArray_eq_none_iff_contains_eq_false t.wf
@[simp] @[simp]
theorem find?_toList_eq_none_iff_not_mem [TransCmp cmp] {k : α} : theorem find?_toList_eq_none_iff_not_mem [TransCmp cmp] {k : α} :
(toList t).find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t := (toList t).find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t :=
Impl.Const.find?_toList_eq_none_iff_not_mem t.wf Impl.Const.find?_toList_eq_none_iff_not_mem t.wf
@[simp]
theorem find?_toArray_eq_none_iff_not_mem [TransCmp cmp] {k : α} :
(toArray t).find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t :=
Impl.Const.find?_toArray_eq_none_iff_not_mem t.wf
theorem distinct_keys_toList [TransCmp cmp] : theorem distinct_keys_toList [TransCmp cmp] :
(toList t).Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq) := (toList t).Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq) :=
Impl.Const.distinct_keys_toList t.wf Impl.Const.distinct_keys_toList t.wf
@ -1231,18 +1343,35 @@ theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m]
t.foldlM f init = t.toList.foldlM (fun a b => f a b.1 b.2) init := t.foldlM f init = t.toList.foldlM (fun a b => f a b.1 b.2) init :=
Impl.foldlM_eq_foldlM_toList Impl.foldlM_eq_foldlM_toList
theorem foldlM_eq_foldlM_toArray [Monad m] [LawfulMonad m]
{f : δ → (a : α) → β a → m δ} {init : δ} :
t.foldlM f init = t.toArray.foldlM (fun a b => f a b.1 b.2) init :=
Impl.foldlM_eq_foldlM_toArray
theorem foldl_eq_foldl_toList {f : δ → (a : α) → β a → δ} {init : δ} : theorem foldl_eq_foldl_toList {f : δ → (a : α) → β a → δ} {init : δ} :
t.foldl f init = t.toList.foldl (fun a b => f a b.1 b.2) init := t.foldl f init = t.toList.foldl (fun a b => f a b.1 b.2) init :=
Impl.foldl_eq_foldl_toList Impl.foldl_eq_foldl_toList
theorem foldl_eq_foldl_toArray {f : δ → (a : α) → β a → δ} {init : δ} :
t.foldl f init = t.toArray.foldl (fun a b => f a b.1 b.2) init :=
Impl.foldl_eq_foldl_toArray
theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] {f : (a : α) → β a → δ → m δ} {init : δ} : theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] {f : (a : α) → β a → δ → m δ} {init : δ} :
t.foldrM f init = t.toList.foldrM (fun a b => f a.1 a.2 b) init := t.foldrM f init = t.toList.foldrM (fun a b => f a.1 a.2 b) init :=
Impl.foldrM_eq_foldrM_toList Impl.foldrM_eq_foldrM_toList
theorem foldrM_eq_foldrM_toArray [Monad m] [LawfulMonad m] {f : (a : α) → β a → δ → m δ} {init : δ} :
t.foldrM f init = t.toArray.foldrM (fun a b => f a.1 a.2 b) init :=
Impl.foldrM_eq_foldrM_toArray
theorem foldr_eq_foldr_toList {f : (a : α) → β a → δ → δ} {init : δ} : theorem foldr_eq_foldr_toList {f : (a : α) → β a → δ → δ} {init : δ} :
t.foldr f init = t.toList.foldr (fun a b => f a.1 a.2 b) init := t.foldr f init = t.toList.foldr (fun a b => f a.1 a.2 b) init :=
Impl.foldr_eq_foldr_toList Impl.foldr_eq_foldr_toList
theorem foldr_eq_foldr_toArray {f : (a : α) → β a → δ → δ} {init : δ} :
t.foldr f init = t.toArray.foldr (fun a b => f a.1 a.2 b) init :=
Impl.foldr_eq_foldr_toArray
@[simp, grind =] @[simp, grind =]
theorem forM_eq_forM [Monad m] [LawfulMonad m] {f : (a : α) → β a → m PUnit} : theorem forM_eq_forM [Monad m] [LawfulMonad m] {f : (a : α) → β a → m PUnit} :
t.forM f = ForM.forM t (fun a => f a.1 a.2) := rfl t.forM f = ForM.forM t (fun a => f a.1 a.2) := rfl
@ -1251,6 +1380,10 @@ theorem forM_eq_forM_toList [Monad m] [LawfulMonad m] {f : (a : α) × β a →
ForM.forM t f = ForM.forM t.toList f := ForM.forM t f = ForM.forM t.toList f :=
Impl.forM_eq_forM_toList Impl.forM_eq_forM_toList
theorem forM_eq_forM_toArray [Monad m] [LawfulMonad m] {f : (a : α) × β a → m PUnit} :
ForM.forM t f = ForM.forM t.toArray f :=
Impl.forM_eq_forM_toArray
@[simp, grind =] @[simp, grind =]
theorem forIn_eq_forIn [Monad m] [LawfulMonad m] theorem forIn_eq_forIn [Monad m] [LawfulMonad m]
{f : (a : α) → β a → δ → m (ForInStep δ)} {init : δ} : {f : (a : α) → β a → δ → m (ForInStep δ)} {init : δ} :
@ -1261,32 +1394,63 @@ theorem forIn_eq_forIn_toList [Monad m] [LawfulMonad m]
ForIn.forIn t init f = ForIn.forIn t.toList init f := ForIn.forIn t init f = ForIn.forIn t.toList init f :=
Impl.forIn_eq_forIn_toList (f := f) Impl.forIn_eq_forIn_toList (f := f)
theorem forIn_eq_forIn_toArray [Monad m] [LawfulMonad m]
{f : (a : α) × β a → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init f = ForIn.forIn t.toArray init f :=
Impl.forIn_eq_forIn_toArray (f := f)
theorem foldlM_eq_foldlM_keys [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} : theorem foldlM_eq_foldlM_keys [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} :
t.foldlM (fun d a _ => f d a) init = t.keys.foldlM f init := t.foldlM (fun d a _ => f d a) init = t.keys.foldlM f init :=
Impl.foldlM_eq_foldlM_keys Impl.foldlM_eq_foldlM_keys
theorem foldlM_eq_foldlM_keysArray [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} :
t.foldlM (fun d a _ => f d a) init = t.keysArray.foldlM f init :=
Impl.foldlM_eq_foldlM_keysArray
theorem foldl_eq_foldl_keys {f : δ → α → δ} {init : δ} : theorem foldl_eq_foldl_keys {f : δ → α → δ} {init : δ} :
t.foldl (fun d a _ => f d a) init = t.keys.foldl f init := t.foldl (fun d a _ => f d a) init = t.keys.foldl f init :=
Impl.foldl_eq_foldl_keys Impl.foldl_eq_foldl_keys
theorem foldl_eq_foldl_keysArray {f : δ → α → δ} {init : δ} :
t.foldl (fun d a _ => f d a) init = t.keysArray.foldl f init :=
Impl.foldl_eq_foldl_keysArray
theorem foldrM_eq_foldrM_keys [Monad m] [LawfulMonad m] theorem foldrM_eq_foldrM_keys [Monad m] [LawfulMonad m]
{f : α → δ → m δ} {init : δ} : {f : α → δ → m δ} {init : δ} :
t.foldrM (fun a _ d => f a d) init = t.keys.foldrM f init := t.foldrM (fun a _ d => f a d) init = t.keys.foldrM f init :=
Impl.foldrM_eq_foldrM_keys Impl.foldrM_eq_foldrM_keys
theorem foldrM_eq_foldrM_keysArray [Monad m] [LawfulMonad m]
{f : α → δ → m δ} {init : δ} :
t.foldrM (fun a _ d => f a d) init = t.keysArray.foldrM f init :=
Impl.foldrM_eq_foldrM_keysArray
theorem foldr_eq_foldr_keys {f : α → δ → δ} {init : δ} : theorem foldr_eq_foldr_keys {f : α → δ → δ} {init : δ} :
t.foldr (fun a _ d => f a d) init = t.keys.foldr f init := t.foldr (fun a _ d => f a d) init = t.keys.foldr f init :=
Impl.foldr_eq_foldr_keys Impl.foldr_eq_foldr_keys
theorem foldr_eq_foldr_keysArray {f : α → δ → δ} {init : δ} :
t.foldr (fun a _ d => f a d) init = t.keysArray.foldr f init :=
Impl.foldr_eq_foldr_keysArray
theorem forM_eq_forM_keys [Monad m] [LawfulMonad m] {f : α → m PUnit} : theorem forM_eq_forM_keys [Monad m] [LawfulMonad m] {f : α → m PUnit} :
ForM.forM t (fun a => f a.1) = t.keys.forM f := ForM.forM t (fun a => f a.1) = t.keys.forM f :=
Impl.forM_eq_forM_keys Impl.forM_eq_forM_keys
theorem forM_eq_forM_keysArray [Monad m] [LawfulMonad m] {f : α → m PUnit} :
ForM.forM t (fun a => f a.1) = t.keysArray.forM f :=
Impl.forM_eq_forM_keysArray
theorem forIn_eq_forIn_keys [Monad m] [LawfulMonad m] theorem forIn_eq_forIn_keys [Monad m] [LawfulMonad m]
{f : α → δ → m (ForInStep δ)} {init : δ} : {f : α → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init (fun a d => f a.1 d) = ForIn.forIn t.keys init f := ForIn.forIn t init (fun a d => f a.1 d) = ForIn.forIn t.keys init f :=
Impl.forIn_eq_forIn_keys Impl.forIn_eq_forIn_keys
theorem forIn_eq_forIn_keysArray [Monad m] [LawfulMonad m]
{f : α → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init (fun a d => f a.1 d) = ForIn.forIn t.keysArray init f :=
Impl.forIn_eq_forIn_keysArray
namespace Const namespace Const
variable {β : Type v} {t : DTreeMap α β cmp} variable {β : Type v} {t : DTreeMap α β cmp}
@ -1296,19 +1460,37 @@ theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m]
t.foldlM f init = (Const.toList t).foldlM (fun a b => f a b.1 b.2) init := t.foldlM f init = (Const.toList t).foldlM (fun a b => f a b.1 b.2) init :=
Impl.Const.foldlM_eq_foldlM_toList Impl.Const.foldlM_eq_foldlM_toList
theorem foldlM_eq_foldlM_toArray [Monad m] [LawfulMonad m]
{f : δ → α → β → m δ} {init : δ} :
t.foldlM f init = (Const.toArray t).foldlM (fun a b => f a b.1 b.2) init :=
Impl.Const.foldlM_eq_foldlM_toArray
theorem foldl_eq_foldl_toList {f : δ → α → β → δ} {init : δ} : theorem foldl_eq_foldl_toList {f : δ → α → β → δ} {init : δ} :
t.foldl f init = (Const.toList t).foldl (fun a b => f a b.1 b.2) init := t.foldl f init = (Const.toList t).foldl (fun a b => f a b.1 b.2) init :=
Impl.Const.foldl_eq_foldl_toList Impl.Const.foldl_eq_foldl_toList
theorem foldl_eq_foldl_toArray {f : δ → α → β → δ} {init : δ} :
t.foldl f init = (Const.toArray t).foldl (fun a b => f a b.1 b.2) init :=
Impl.Const.foldl_eq_foldl_toArray
theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m]
{f : α → β → δ → m δ} {init : δ} : {f : α → β → δ → m δ} {init : δ} :
t.foldrM f init = (Const.toList t).foldrM (fun a b => f a.1 a.2 b) init := t.foldrM f init = (Const.toList t).foldrM (fun a b => f a.1 a.2 b) init :=
Impl.Const.foldrM_eq_foldrM_toList Impl.Const.foldrM_eq_foldrM_toList
theorem foldrM_eq_foldrM_toArray [Monad m] [LawfulMonad m]
{f : α → β → δ → m δ} {init : δ} :
t.foldrM f init = (Const.toArray t).foldrM (fun a b => f a.1 a.2 b) init :=
Impl.Const.foldrM_eq_foldrM_toArray
theorem foldr_eq_foldr_toList {f : α → β → δ → δ} {init : δ} : theorem foldr_eq_foldr_toList {f : α → β → δ → δ} {init : δ} :
t.foldr f init = (Const.toList t).foldr (fun a b => f a.1 a.2 b) init := t.foldr f init = (Const.toList t).foldr (fun a b => f a.1 a.2 b) init :=
Impl.Const.foldr_eq_foldr_toList Impl.Const.foldr_eq_foldr_toList
theorem foldr_eq_foldr_toArray {f : α → β → δ → δ} {init : δ} :
t.foldr f init = (Const.toArray t).foldr (fun a b => f a.1 a.2 b) init :=
Impl.Const.foldr_eq_foldr_toArray
theorem forM_eq_forMUncurried [Monad m] [LawfulMonad m] {f : α → β → m PUnit} : theorem forM_eq_forMUncurried [Monad m] [LawfulMonad m] {f : α → β → m PUnit} :
t.forM f = forMUncurried (fun a => f a.1 a.2) t := rfl t.forM f = forMUncurried (fun a => f a.1 a.2) t := rfl
@ -1316,6 +1498,10 @@ theorem forMUncurried_eq_forM_toList [Monad m] [LawfulMonad m] {f : α × β →
forMUncurried f t = (Const.toList t).forM f := forMUncurried f t = (Const.toList t).forM f :=
Impl.Const.forM_eq_forM_toList Impl.Const.forM_eq_forM_toList
theorem forMUncurried_eq_forM_toArray [Monad m] [LawfulMonad m] {f : α × β → m PUnit} :
forMUncurried f t = (Const.toArray t).forM f :=
Impl.Const.forM_eq_forM_toArray
theorem forIn_eq_forInUncurried [Monad m] [LawfulMonad m] theorem forIn_eq_forInUncurried [Monad m] [LawfulMonad m]
{f : α → β → δ → m (ForInStep δ)} {init : δ} : {f : α → β → δ → m (ForInStep δ)} {init : δ} :
t.forIn f init = forInUncurried (fun a b => f a.1 a.2 b) init t := rfl t.forIn f init = forInUncurried (fun a b => f a.1 a.2 b) init t := rfl
@ -1325,6 +1511,11 @@ theorem forInUncurried_eq_forIn_toList [Monad m] [LawfulMonad m]
forInUncurried f init t = ForIn.forIn (Const.toList t) init f := forInUncurried f init t = ForIn.forIn (Const.toList t) init f :=
Impl.Const.forIn_eq_forIn_toList Impl.Const.forIn_eq_forIn_toList
theorem forInUncurried_eq_forIn_toArray [Monad m] [LawfulMonad m]
{f : α × β → δ → m (ForInStep δ)} {init : δ} :
forInUncurried f init t = ForIn.forIn (Const.toArray t) init f :=
Impl.Const.forIn_eq_forIn_toArray
end Const end Const
end monadic end monadic
@ -4173,6 +4364,11 @@ theorem minKey?_insertIfNew_le_self [TransCmp cmp] {k v kmi} :
t.minKey? = t.keys.head? := t.minKey? = t.keys.head? :=
Impl.minKey?_eq_head?_keys t.wf Impl.minKey?_eq_head?_keys t.wf
@[grind =_]
theorem minKey?_eq_getElem?_keysArray [TransCmp cmp] :
t.minKey? = t.keysArray[0]? :=
Impl.minKey?_eq_getElem?_keysArray t.wf
@[simp, grind =] @[simp, grind =]
theorem minKey?_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f} : theorem minKey?_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f} :
(t.modify k f).minKey? = t.minKey? := (t.modify k f).minKey? = t.minKey? :=
@ -4325,6 +4521,10 @@ theorem minKey_insertIfNew_le_self [TransCmp cmp] {k v} :
t.minKey he = t.keys.head (List.isEmpty_eq_false_iff.mp <| isEmpty_keys ▸ he) := t.minKey he = t.keys.head (List.isEmpty_eq_false_iff.mp <| isEmpty_keys ▸ he) :=
Impl.minKey_eq_head_keys t.wf Impl.minKey_eq_head_keys t.wf
@[grind =_] theorem minKey_eq_getElem_keysArray [TransCmp cmp] {he} :
t.minKey he = t.keysArray[0]'(Nat.zero_lt_of_ne_zero (by simpa [size_keysArray, isEmpty_eq_size_eq_zero, - Array.size_eq_zero_iff] using he)) :=
Impl.minKey_eq_getElem_keysArray t.wf
@[simp, grind =] @[simp, grind =]
theorem minKey_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f he} : theorem minKey_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f he} :
(t.modify k f).minKey he = t.minKey (cast (congrArg (· = false) isEmpty_modify) he) := (t.modify k f).minKey he = t.minKey (cast (congrArg (· = false) isEmpty_modify) he) :=
@ -4473,6 +4673,10 @@ theorem minKey!_insertIfNew_le_self [TransCmp cmp] [Inhabited α] {k v} :
t.minKey! = t.keys.head! := t.minKey! = t.keys.head! :=
Impl.minKey!_eq_head!_keys t.wf Impl.minKey!_eq_head!_keys t.wf
theorem minKey!_eq_getElem!_keysArray [TransCmp cmp] [Inhabited α] :
t.minKey! = t.keysArray[0]! :=
Impl.minKey!_eq_getElem!_keysArray t.wf
@[simp] @[simp]
theorem minKey!_modify [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] {k f} : theorem minKey!_modify [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] {k f} :
(t.modify k f).minKey! = t.minKey! := (t.modify k f).minKey! = t.minKey! :=
@ -4614,6 +4818,10 @@ theorem minKeyD_eq_headD_keys [TransCmp cmp] {fallback} :
t.minKeyD fallback = t.keys.headD fallback := t.minKeyD fallback = t.keys.headD fallback :=
Impl.minKeyD_eq_headD_keys t.wf Impl.minKeyD_eq_headD_keys t.wf
theorem minKeyD_eq_getD_keysArray [TransCmp cmp] {fallback} :
t.minKeyD fallback = t.keysArray.getD 0 fallback :=
Impl.minKeyD_eq_getD_keysArray t.wf
@[simp, grind =] @[simp, grind =]
theorem minKeyD_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f fallback} : theorem minKeyD_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f fallback} :
(t.modify k f |>.minKeyD fallback) = t.minKeyD fallback := (t.modify k f |>.minKeyD fallback) = t.minKeyD fallback :=
@ -4816,6 +5024,10 @@ theorem self_le_maxKey?_insertIfNew [TransCmp cmp] {k v kmi} :
t.maxKey? = t.keys.getLast? := t.maxKey? = t.keys.getLast? :=
Impl.maxKey?_eq_getLast?_keys t.wf Impl.maxKey?_eq_getLast?_keys t.wf
@[grind =_] theorem maxKey?_eq_back?_keysArray [TransCmp cmp] :
t.maxKey? = t.keysArray.back? :=
Impl.maxKey?_eq_back?_keysArray t.wf
@[simp, grind =] @[simp, grind =]
theorem maxKey?_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f} : theorem maxKey?_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f} :
(t.modify k f).maxKey? = t.maxKey? := (t.modify k f).maxKey? = t.maxKey? :=
@ -4969,6 +5181,10 @@ theorem self_le_maxKey_insertIfNew [TransCmp cmp] {k v} :
t.maxKey he = t.keys.getLast (List.isEmpty_eq_false_iff.mp <| isEmpty_keys ▸ he) := t.maxKey he = t.keys.getLast (List.isEmpty_eq_false_iff.mp <| isEmpty_keys ▸ he) :=
Impl.maxKey_eq_getLast_keys t.wf Impl.maxKey_eq_getLast_keys t.wf
@[grind =_] theorem maxKey_eq_back_keysArray [TransCmp cmp] {he} :
t.maxKey he = t.keysArray.back (Nat.zero_lt_of_ne_zero (by simpa [size_keysArray, isEmpty_eq_size_eq_zero, - Array.size_eq_zero_iff] using he)) :=
Impl.maxKey_eq_back_keysArray t.wf
@[simp] @[simp]
theorem maxKey_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f he} : theorem maxKey_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f he} :
(t.modify k f).maxKey he = t.maxKey (cast (congrArg (· = false) isEmpty_modify) he) := (t.modify k f).maxKey he = t.maxKey (cast (congrArg (· = false) isEmpty_modify) he) :=
@ -5118,6 +5334,10 @@ theorem maxKey!_eq_getLast!_keys [TransCmp cmp] [Inhabited α] :
t.maxKey! = t.keys.getLast! := t.maxKey! = t.keys.getLast! :=
Impl.maxKey!_eq_getLast!_keys t.wf Impl.maxKey!_eq_getLast!_keys t.wf
theorem maxKey!_eq_back!_keysArray [TransCmp cmp] [Inhabited α] :
t.maxKey! = t.keysArray.back! :=
Impl.maxKey!_eq_back!_keysArray t.wf
@[simp] @[simp]
theorem maxKey!_modify [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] {k f} : theorem maxKey!_modify [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] {k f} :
(t.modify k f).maxKey! = t.maxKey! := (t.modify k f).maxKey! = t.maxKey! :=
@ -5261,6 +5481,10 @@ theorem maxKeyD_eq_getLastD_keys [TransCmp cmp] {fallback} :
t.maxKeyD fallback = t.keys.getLastD fallback := t.maxKeyD fallback = t.keys.getLastD fallback :=
Impl.maxKeyD_eq_getLastD_keys t.wf Impl.maxKeyD_eq_getLastD_keys t.wf
theorem maxKeyD_eq_getD_back?_keysArray [TransCmp cmp] {fallback} :
t.maxKeyD fallback = t.keysArray.back?.getD fallback :=
Impl.maxKeyD_eq_getD_back?_keysArray t.wf
@[simp] @[simp]
theorem maxKeyD_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f fallback} : theorem maxKeyD_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f fallback} :
(t.modify k f |>.maxKeyD fallback) = t.maxKeyD fallback := (t.modify k f |>.maxKeyD fallback) = t.maxKeyD fallback :=
@ -5906,13 +6130,23 @@ theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList := theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList :=
equiv_iff_equiv.trans Impl.equiv_iff_toList_perm equiv_iff_equiv.trans Impl.equiv_iff_toList_perm
theorem equiv_iff_toArray_perm : t₁ ~m t₂ ↔ t₁.toArray.Perm t₂.toArray :=
equiv_iff_equiv.trans Impl.equiv_iff_toArray_perm
theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ := theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ :=
⟨.of_toList_perm h⟩ ⟨.of_toList_perm h⟩
theorem Equiv.of_toArray_perm (h : t₁.toArray.Perm t₂.toArray) : t₁ ~m t₂ :=
⟨.of_toArray_perm h⟩
theorem equiv_iff_toList_eq [TransCmp cmp] : theorem equiv_iff_toList_eq [TransCmp cmp] :
t₁ ~m t₂ ↔ t₁.toList = t₂.toList := t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
equiv_iff_equiv.trans (Impl.equiv_iff_toList_eq t₁.2 t₂.2) equiv_iff_equiv.trans (Impl.equiv_iff_toList_eq t₁.2 t₂.2)
theorem equiv_iff_toArray_eq [TransCmp cmp] :
t₁ ~m t₂ ↔ t₁.toArray = t₂.toArray :=
equiv_iff_equiv.trans (Impl.equiv_iff_toArray_eq t₁.2 t₂.2)
theorem insertMany_list_equiv_foldl {l : List ((a : α) × β a)} : theorem insertMany_list_equiv_foldl {l : List ((a : α) × β a)} :
t₁.insertMany l ~m l.foldl (init := t₁) fun acc p => acc.insert p.1 p.2 := by t₁.insertMany l ~m l.foldl (init := t₁) fun acc p => acc.insert p.1 p.2 := by
constructor constructor
@ -5940,22 +6174,43 @@ variable {β : Type v} {t₁ t₂ : DTreeMap α β cmp}
theorem Const.equiv_iff_toList_perm : t₁ ~m t₂ ↔ (Const.toList t₁).Perm (Const.toList t₂) := theorem Const.equiv_iff_toList_perm : t₁ ~m t₂ ↔ (Const.toList t₁).Perm (Const.toList t₂) :=
equiv_iff_equiv.trans Impl.Const.equiv_iff_toList_perm equiv_iff_equiv.trans Impl.Const.equiv_iff_toList_perm
theorem Const.equiv_iff_toArray_perm : t₁ ~m t₂ ↔ (Const.toArray t₁).Perm (Const.toArray t₂) :=
equiv_iff_equiv.trans Impl.Const.equiv_iff_toArray_perm
theorem Const.equiv_iff_toList_eq [TransCmp cmp] : t₁ ~m t₂ ↔ Const.toList t₁ = Const.toList t₂ := theorem Const.equiv_iff_toList_eq [TransCmp cmp] : t₁ ~m t₂ ↔ Const.toList t₁ = Const.toList t₂ :=
equiv_iff_equiv.trans (Impl.Const.equiv_iff_toList_eq t₁.2 t₂.2) equiv_iff_equiv.trans (Impl.Const.equiv_iff_toList_eq t₁.2 t₂.2)
theorem Const.equiv_iff_toArray_eq [TransCmp cmp] : t₁ ~m t₂ ↔ Const.toArray t₁ = Const.toArray t₂ :=
equiv_iff_equiv.trans (Impl.Const.equiv_iff_toArray_eq t₁.2 t₂.2)
theorem Const.equiv_iff_keys_unit_perm {t₁ t₂ : DTreeMap α Unit cmp} : t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys := theorem Const.equiv_iff_keys_unit_perm {t₁ t₂ : DTreeMap α Unit cmp} : t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys :=
equiv_iff_equiv.trans Impl.Const.equiv_iff_keys_perm equiv_iff_equiv.trans Impl.Const.equiv_iff_keys_perm
theorem Const.equiv_iff_keysArray_unit_perm {t₁ t₂ : DTreeMap α Unit cmp} :
t₁ ~m t₂ ↔ t₁.keysArray.Perm t₂.keysArray :=
equiv_iff_equiv.trans Impl.Const.equiv_iff_keysArray_perm
theorem Const.equiv_iff_keys_unit_eq [TransCmp cmp] {t₁ t₂ : DTreeMap α Unit cmp} : theorem Const.equiv_iff_keys_unit_eq [TransCmp cmp] {t₁ t₂ : DTreeMap α Unit cmp} :
t₁ ~m t₂ ↔ t₁.keys = t₂.keys := t₁ ~m t₂ ↔ t₁.keys = t₂.keys :=
equiv_iff_equiv.trans (Impl.Const.equiv_iff_keys_eq t₁.2 t₂.2) equiv_iff_equiv.trans (Impl.Const.equiv_iff_keys_eq t₁.2 t₂.2)
theorem Const.equiv_iff_keysArray_unit_eq [TransCmp cmp] {t₁ t₂ : DTreeMap α Unit cmp} :
t₁ ~m t₂ ↔ t₁.keysArray = t₂.keysArray :=
equiv_iff_equiv.trans (Impl.Const.equiv_iff_keysArray_eq t₁.2 t₂.2)
theorem Equiv.of_constToList_perm : (Const.toList t₁).Perm (Const.toList t₂) → t₁ ~m t₂ := theorem Equiv.of_constToList_perm : (Const.toList t₁).Perm (Const.toList t₂) → t₁ ~m t₂ :=
Const.equiv_iff_toList_perm.mpr Const.equiv_iff_toList_perm.mpr
theorem Equiv.of_constToArray_perm : (Const.toArray t₁).Perm (Const.toArray t₂) → t₁ ~m t₂ :=
Const.equiv_iff_toArray_perm.mpr
theorem Equiv.of_keys_unit_perm {t₁ t₂ : DTreeMap α Unit cmp} : t₁.keys.Perm t₂.keys → t₁ ~m t₂ := theorem Equiv.of_keys_unit_perm {t₁ t₂ : DTreeMap α Unit cmp} : t₁.keys.Perm t₂.keys → t₁ ~m t₂ :=
Const.equiv_iff_keys_unit_perm.mpr Const.equiv_iff_keys_unit_perm.mpr
theorem Equiv.of_keysArray_unit_perm {t₁ t₂ : DTreeMap α Unit cmp} :
t₁.keysArray.Perm t₂.keysArray → t₁ ~m t₂ :=
Const.equiv_iff_keysArray_unit_perm.mpr
theorem Const.insertMany_list_equiv_foldl {l : List (α × β)} : theorem Const.insertMany_list_equiv_foldl {l : List (α × β)} :
insertMany t₁ l ~m l.foldl (init := t₁) (fun acc p => acc.insert p.1 p.2) := by insertMany t₁ l ~m l.foldl (init := t₁) (fun acc p => acc.insert p.1 p.2) := by
constructor constructor
@ -5994,6 +6249,12 @@ theorem toList_filterMap {f : (a : α) → β a → Option (γ a)} :
t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) := t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) :=
Impl.toList_filterMap t.wf Impl.toList_filterMap t.wf
@[simp, grind =]
theorem toArray_filterMap {f : (a : α) → β a → Option (γ a)} :
(t.filterMap f).toArray =
t.toArray.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) :=
Impl.toArray_filterMap t.wf
@[grind =] @[grind =]
theorem isEmpty_filterMap_iff [TransCmp cmp] [LawfulEqCmp cmp] theorem isEmpty_filterMap_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} : {f : (a : α) → β a → Option (γ a)} :
@ -6221,6 +6482,12 @@ theorem toList_filterMap
(Const.toList t).filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x))) := (Const.toList t).filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x))) :=
Impl.Const.toList_filterMap t.wf Impl.Const.toList_filterMap t.wf
theorem toArray_filterMap
{f : α → β → Option γ} :
Const.toArray (t.filterMap fun k v => f k v) =
(Const.toArray t).filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x))) :=
Impl.Const.toArray_filterMap t.wf
@[grind =] @[grind =]
theorem getKey?_filterMap [TransCmp cmp] theorem getKey?_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} : {f : α → β → Option γ} {k : α} :
@ -6260,10 +6527,19 @@ theorem toList_filter {f : (a : α) → β a → Bool} :
(t.filter f).toList = t.toList.filter (fun p => f p.1 p.2) := (t.filter f).toList = t.toList.filter (fun p => f p.1 p.2) :=
Impl.toList_filter t.wf Impl.toList_filter t.wf
@[simp, grind =]
theorem toArray_filter {f : (a : α) → β a → Bool} :
(t.filter f).toArray = t.toArray.filter (fun p => f p.1 p.2) :=
Impl.toArray_filter t.wf
theorem keys_filter_key {f : α → Bool} : theorem keys_filter_key {f : α → Bool} :
(t.filter fun k _ => f k).keys = t.keys.filter f := (t.filter fun k _ => f k).keys = t.keys.filter f :=
Impl.keys_filter_key t.wf Impl.keys_filter_key t.wf
theorem keysArray_filter_key {f : α → Bool} :
(t.filter fun k _ => f k).keysArray = t.keysArray.filter f :=
Impl.keysArray_filter_key t.wf
@[grind =] @[grind =]
theorem isEmpty_filter_iff [TransCmp cmp] [LawfulEqCmp cmp] theorem isEmpty_filter_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} : {f : (a : α) → β a → Bool} :
@ -6536,6 +6812,12 @@ theorem toList_filter {f : α → β → Bool} :
(toList t).filter (fun p => f p.1 p.2) := (toList t).filter (fun p => f p.1 p.2) :=
Impl.Const.toList_filter t.wf Impl.Const.toList_filter t.wf
@[simp, grind =]
theorem toArray_filter {f : α → β → Bool} :
toArray (t.filter f) =
(toArray t).filter (fun p => f p.1 p.2) :=
Impl.Const.toArray_filter t.wf
theorem keys_filter [TransCmp cmp] {f : α → β → Bool} : theorem keys_filter [TransCmp cmp] {f : α → β → Bool} :
(t.filter f).keys = (t.filter f).keys =
(t.keys.attach.filter (fun ⟨x, h'⟩ => f x (get t x (mem_of_mem_keys h')))).unattach := (t.keys.attach.filter (fun ⟨x, h'⟩ => f x (get t x (mem_of_mem_keys h')))).unattach :=
@ -6585,10 +6867,19 @@ theorem toList_map {f : (a : α) → β a → γ a} :
(t.map f).toList = t.toList.map (fun p => ⟨p.1, f p.1 p.2⟩) := (t.map f).toList = t.toList.map (fun p => ⟨p.1, f p.1 p.2⟩) :=
Impl.toList_map Impl.toList_map
@[simp, grind =]
theorem toArray_map {f : (a : α) → β a → γ a} :
(t.map f).toArray = t.toArray.map (fun p => ⟨p.1, f p.1 p.2⟩) :=
Impl.toArray_map
@[simp, grind =] @[simp, grind =]
theorem keys_map {f : (a : α) → β a → γ a} : (t.map f).keys = t.keys := theorem keys_map {f : (a : α) → β a → γ a} : (t.map f).keys = t.keys :=
Impl.keys_map Impl.keys_map
@[simp, grind =]
theorem keysArray_map {f : (a : α) → β a → γ a} : (t.map f).keysArray = t.keysArray :=
Impl.keysArray_map
theorem filterMap_equiv_map [TransCmp cmp] theorem filterMap_equiv_map [TransCmp cmp]
{f : (a : α) → β a → γ a} : {f : (a : α) → β a → γ a} :
(t.filterMap (fun k v => some (f k v))) ~m t.map f := (t.filterMap (fun k v => some (f k v))) ~m t.map f :=
@ -6757,8 +7048,32 @@ theorem toList_map {f : α → β → γ} :
(Const.toList t).map (fun p => (p.1, f p.1 p.2)) := (Const.toList t).map (fun p => (p.1, f p.1 p.2)) :=
Impl.Const.toList_map Impl.Const.toList_map
@[simp, grind =]
theorem toArray_map {f : α → β → γ} :
(Const.toArray (t.map f)) =
(Const.toArray t).map (fun p => (p.1, f p.1 p.2)) :=
Impl.Const.toArray_map
theorem toArray_toList : (toList t).toArray = toArray t :=
Impl.Const.toArray_toList
theorem toList_toArray : (toArray t).toList = toList t :=
Impl.Const.toList_toArray
end Const end Const
end map end map
theorem toArray_toList : t.toList.toArray = t.toArray :=
Impl.toArray_toList
theorem toList_toArray : t.toArray.toList = t.toList :=
Impl.toList_toArray
theorem toArray_keys : t.keys.toArray = t.keysArray :=
Impl.toArray_keys
theorem toList_keysArray : t.keysArray.toList = t.keys :=
Impl.toList_keysArray
end Std.DTreeMap end Std.DTreeMap

View file

@ -8,6 +8,7 @@ module
prelude prelude
import Std.Data.DTreeMap.Internal.Lemmas import Std.Data.DTreeMap.Internal.Lemmas
public import Std.Data.DTreeMap.Raw.AdditionalOperations public import Std.Data.DTreeMap.Raw.AdditionalOperations
public import Init.Data.Array.Perm
import Init.Data.List.Find import Init.Data.List.Find
import Init.Data.List.Pairwise import Init.Data.List.Pairwise
import Init.Data.Prod import Init.Data.Prod
@ -100,6 +101,18 @@ theorem isEmpty_iff_forall_not_mem [TransCmp cmp] (h : t.WF) :
t.isEmpty = true ↔ ∀ a, ¬a ∈ t := t.isEmpty = true ↔ ∀ a, ¬a ∈ t :=
Impl.isEmpty_iff_forall_not_mem h Impl.isEmpty_iff_forall_not_mem h
theorem toArray_toList : t.toList.toArray = t.toArray :=
Impl.toArray_toList
theorem toList_toArray : t.toArray.toList = t.toList :=
Impl.toList_toArray
theorem toArray_keys : t.keys.toArray = t.keysArray :=
Impl.toArray_keys
theorem toList_keysArray : t.keysArray.toList = t.keys :=
Impl.toList_keysArray
@[simp] @[simp]
theorem insert_eq_insert {p : (a : α) × β a} : Insert.insert p t = t.insert p.1 p.2 := theorem insert_eq_insert {p : (a : α) × β a} : Insert.insert p t = t.insert p.1 p.2 :=
rfl rfl
@ -286,6 +299,12 @@ namespace Const
variable {β : Type v} {t : Raw α β cmp} variable {β : Type v} {t : Raw α β cmp}
theorem toArray_toList : (toList t).toArray = toArray t :=
Impl.Const.toArray_toList
theorem toList_toArray : (toArray t).toList = toList t :=
Impl.Const.toList_toArray
@[simp, grind =] @[simp, grind =]
theorem get?_emptyc [TransCmp cmp] {a : α} : theorem get?_emptyc [TransCmp cmp] {a : α} :
get? (∅ : Raw α β cmp) a = none := get? (∅ : Raw α β cmp) a = none :=
@ -357,14 +376,26 @@ theorem toList_insert_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] (h : t.WF)
(t.insert k v).toList.Perm (⟨k, v⟩ :: t.toList.filter (¬k == ·.1)) := (t.insert k v).toList.Perm (⟨k, v⟩ :: t.toList.filter (¬k == ·.1)) :=
Impl.toList_insert!_perm h Impl.toList_insert!_perm h
theorem toArray_insert_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] (h : t.WF) {k : α} {v : β k} :
(t.insert k v).toArray.Perm (t.toArray.filter (¬k == ·.1) |>.push ⟨k, v⟩) :=
Impl.toArray_insert!_perm h
theorem Const.toList_insert_perm {β : Type v} {t : Raw α (fun _ => β) cmp} [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] (h : t.WF) {k : α} {v : β} : theorem Const.toList_insert_perm {β : Type v} {t : Raw α (fun _ => β) cmp} [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] (h : t.WF) {k : α} {v : β} :
(Const.toList (t.insert k v)).Perm (⟨k, v⟩ :: (Const.toList t).filter (¬k == ·.1)) := (Const.toList (t.insert k v)).Perm (⟨k, v⟩ :: (Const.toList t).filter (¬k == ·.1)) :=
Impl.Const.toList_insert!_perm h Impl.Const.toList_insert!_perm h
theorem Const.toArray_insert_perm {β : Type v} {t : Raw α (fun _ => β) cmp} [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] (h : t.WF) {k : α} {v : β} :
(Const.toArray (t.insert k v)).Perm ((Const.toArray t).filter (¬k == ·.1) |>.push ⟨k, v⟩) :=
Impl.Const.toArray_insert!_perm h
theorem keys_insertIfNew_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] (h : t.WF) {k : α} {v : β k} : theorem keys_insertIfNew_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] (h : t.WF) {k : α} {v : β k} :
(t.insertIfNew k v).keys.Perm (if k ∈ t then t.keys else k :: t.keys) := (t.insertIfNew k v).keys.Perm (if k ∈ t then t.keys else k :: t.keys) :=
Impl.keys_insertIfNew!_perm h Impl.keys_insertIfNew!_perm h
theorem keysArray_insertIfNew_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] (h : t.WF) {k : α} {v : β k} :
(t.insertIfNew k v).keysArray.Perm (if k ∈ t then t.keysArray else t.keysArray.push k) :=
Impl.keysArray_insertIfNew!_perm h.out
@[grind =] theorem get_insert [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k a : α} {v : β k} {h₁} : @[grind =] theorem get_insert [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k a : α} {v : β k} {h₁} :
(t.insert k v).get a h₁ = (t.insert k v).get a h₁ =
if h₂ : cmp k a = .eq then if h₂ : cmp k a = .eq then
@ -1106,25 +1137,49 @@ theorem length_keys [TransCmp cmp] (h : t.WF) :
t.keys.length = t.size := t.keys.length = t.size :=
Impl.length_keys h.out Impl.length_keys h.out
@[simp, grind =]
theorem size_keysArray [TransCmp cmp] (h : t.WF) :
t.keysArray.size = t.size :=
Impl.size_keysArray h.out
@[simp, grind =] @[simp, grind =]
theorem isEmpty_keys : theorem isEmpty_keys :
t.keys.isEmpty = t.isEmpty := t.keys.isEmpty = t.isEmpty :=
Impl.isEmpty_keys Impl.isEmpty_keys
@[simp, grind =]
theorem isEmpty_keysArray :
t.keysArray.isEmpty = t.isEmpty :=
Impl.isEmpty_keysArray
@[simp, grind =] @[simp, grind =]
theorem contains_keys [BEq α] [LawfulBEqCmp cmp] (h : t.WF) [TransCmp cmp] {k : α} : theorem contains_keys [BEq α] [LawfulBEqCmp cmp] (h : t.WF) [TransCmp cmp] {k : α} :
t.keys.contains k = t.contains k := t.keys.contains k = t.contains k :=
Impl.contains_keys h Impl.contains_keys h
@[simp, grind =]
theorem contains_keysArray [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] {k : α} (h : t.WF) :
t.keysArray.contains k = t.contains k :=
Impl.contains_keysArray h.out
@[simp, grind =] @[simp, grind =]
theorem mem_keys [LawfulEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} : theorem mem_keys [LawfulEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.keys ↔ k ∈ t := k ∈ t.keys ↔ k ∈ t :=
Impl.mem_keys h Impl.mem_keys h
@[simp, grind =]
theorem mem_keysArray [LawfulEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.keysArray ↔ k ∈ t :=
Impl.mem_keysArray h
theorem mem_of_mem_keys [TransCmp cmp] (h : t.WF) {k : α} theorem mem_of_mem_keys [TransCmp cmp] (h : t.WF) {k : α}
(h' : k ∈ t.keys) : k ∈ t := (h' : k ∈ t.keys) : k ∈ t :=
Impl.mem_of_mem_keys h h' Impl.mem_of_mem_keys h h'
theorem mem_of_mem_keysArray [TransCmp cmp] (h : t.WF) {k : α}
(h' : k ∈ t.keysArray) : k ∈ t :=
Impl.mem_of_mem_keysArray h h'
theorem distinct_keys [TransCmp cmp] (h : t.WF) : theorem distinct_keys [TransCmp cmp] (h : t.WF) :
t.keys.Pairwise (fun a b => ¬ cmp a b = .eq) := t.keys.Pairwise (fun a b => ¬ cmp a b = .eq) :=
Impl.distinct_keys h.out Impl.distinct_keys h.out
@ -1142,34 +1197,67 @@ theorem map_fst_toList_eq_keys :
t.toList.map Sigma.fst = t.keys := t.toList.map Sigma.fst = t.keys :=
Impl.map_fst_toList_eq_keys Impl.map_fst_toList_eq_keys
@[simp, grind _=_]
theorem map_fst_toArray_eq_keysArray :
t.toArray.map Sigma.fst = t.keysArray :=
Impl.map_fst_toArray_eq_keysArray
@[simp, grind =] @[simp, grind =]
theorem length_toList [TransCmp cmp] (h : t.WF) : theorem length_toList [TransCmp cmp] (h : t.WF) :
t.toList.length = t.size := t.toList.length = t.size :=
Impl.length_toList h.out Impl.length_toList h.out
@[simp, grind =]
theorem size_toArray [TransCmp cmp] (h : t.WF) :
t.toArray.size = t.size :=
Impl.size_toArray h.out
@[simp, grind =] @[simp, grind =]
theorem isEmpty_toList : theorem isEmpty_toList :
t.toList.isEmpty = t.isEmpty := t.toList.isEmpty = t.isEmpty :=
Impl.isEmpty_toList Impl.isEmpty_toList
@[simp, grind =]
theorem isEmpty_toArray :
t.toArray.isEmpty = t.isEmpty :=
Impl.isEmpty_toArray
@[simp, grind =] @[simp, grind =]
theorem mem_toList_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k : α} {v : β k} : theorem mem_toList_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k : α} {v : β k} :
⟨k, v⟩ ∈ t.toList ↔ t.get? k = some v := ⟨k, v⟩ ∈ t.toList ↔ t.get? k = some v :=
Impl.mem_toList_iff_get?_eq_some h.out Impl.mem_toList_iff_get?_eq_some h.out
@[simp, grind =]
theorem mem_toArray_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k : α} {v : β k} :
⟨k, v⟩ ∈ t.toArray ↔ t.get? k = some v :=
Impl.mem_toArray_iff_get?_eq_some h.out
theorem find?_toList_eq_some_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k : α} theorem find?_toList_eq_some_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k : α}
{v : β k} : t.toList.find? (cmp ·.1 k == .eq) = some ⟨k, v⟩ ↔ t.get? k = some v := {v : β k} : t.toList.find? (cmp ·.1 k == .eq) = some ⟨k, v⟩ ↔ t.get? k = some v :=
Impl.find?_toList_eq_some_iff_get?_eq_some h.out Impl.find?_toList_eq_some_iff_get?_eq_some h.out
theorem find?_toArray_eq_some_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k : α}
{v : β k} : t.toArray.find? (cmp ·.1 k == .eq) = some ⟨k, v⟩ ↔ t.get? k = some v :=
Impl.find?_toArray_eq_some_iff_get?_eq_some h.out
theorem find?_toList_eq_none_iff_contains_eq_false [TransCmp cmp] (h : t.WF) {k : α} : theorem find?_toList_eq_none_iff_contains_eq_false [TransCmp cmp] (h : t.WF) {k : α} :
t.toList.find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false := t.toList.find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false :=
Impl.find?_toList_eq_none_iff_contains_eq_false h.out Impl.find?_toList_eq_none_iff_contains_eq_false h.out
theorem find?_toArray_eq_none_iff_contains_eq_false [TransCmp cmp] (h : t.WF) {k : α} :
t.toArray.find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false :=
Impl.find?_toArray_eq_none_iff_contains_eq_false h.out
@[simp] @[simp]
theorem find?_toList_eq_none_iff_not_mem [TransCmp cmp] (h : t.WF) {k : α} : theorem find?_toList_eq_none_iff_not_mem [TransCmp cmp] (h : t.WF) {k : α} :
t.toList.find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t := by t.toList.find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t := by
simpa only [Bool.not_eq_true, mem_iff_contains] using find?_toList_eq_none_iff_contains_eq_false h simpa only [Bool.not_eq_true, mem_iff_contains] using find?_toList_eq_none_iff_contains_eq_false h
@[simp]
theorem find?_toArray_eq_none_iff_not_mem [TransCmp cmp] (h : t.WF) {k : α} :
t.toArray.find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t :=
Impl.find?_toArray_eq_none_iff_not_mem h.out
theorem distinct_keys_toList [TransCmp cmp] (h : t.WF) : theorem distinct_keys_toList [TransCmp cmp] (h : t.WF) :
t.toList.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq) := t.toList.Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq) :=
Impl.distinct_keys_toList h.out Impl.distinct_keys_toList h.out
@ -1187,45 +1275,89 @@ theorem map_fst_toList_eq_keys :
(toList t).map Prod.fst = t.keys := (toList t).map Prod.fst = t.keys :=
Impl.Const.map_fst_toList_eq_keys Impl.Const.map_fst_toList_eq_keys
@[simp, grind _=_]
theorem map_fst_toArray_eq_keysArray :
(toArray t).map Prod.fst = t.keysArray :=
Impl.Const.map_fst_toArray_eq_keysArray
@[simp, grind =] @[simp, grind =]
theorem length_toList (h : t.WF) : theorem length_toList (h : t.WF) :
(toList t).length = t.size := (toList t).length = t.size :=
Impl.Const.length_toList h.out Impl.Const.length_toList h.out
@[simp, grind =]
theorem size_toArray (h : t.WF) :
(toArray t).size = t.size :=
Impl.Const.size_toArray h.out
@[simp, grind =] @[simp, grind =]
theorem isEmpty_toList : theorem isEmpty_toList :
(toList t).isEmpty = t.isEmpty := (toList t).isEmpty = t.isEmpty :=
Impl.Const.isEmpty_toList Impl.Const.isEmpty_toList
@[simp, grind =]
theorem isEmpty_toArray :
(toArray t).isEmpty = t.isEmpty :=
Impl.Const.isEmpty_toArray
@[simp, grind =] @[simp, grind =]
theorem mem_toList_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k : α} {v : β} : theorem mem_toList_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k : α} {v : β} :
(k, v) ∈ toList t ↔ get? t k = some v := (k, v) ∈ toList t ↔ get? t k = some v :=
Impl.Const.mem_toList_iff_get?_eq_some h Impl.Const.mem_toList_iff_get?_eq_some h
@[simp, grind =]
theorem mem_toArray_iff_get?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k : α} {v : β} :
(k, v) ∈ toArray t ↔ get? t k = some v :=
Impl.Const.mem_toArray_iff_get?_eq_some h
@[simp] @[simp]
theorem mem_toList_iff_getKey?_eq_some_and_get?_eq_some [TransCmp cmp] (h : t.WF) {k : α} {v : β} : theorem mem_toList_iff_getKey?_eq_some_and_get?_eq_some [TransCmp cmp] (h : t.WF) {k : α} {v : β} :
(k, v) ∈ toList t ↔ t.getKey? k = some k ∧ get? t k = some v := (k, v) ∈ toList t ↔ t.getKey? k = some k ∧ get? t k = some v :=
Impl.Const.mem_toList_iff_getKey?_eq_some_and_get?_eq_some h Impl.Const.mem_toList_iff_getKey?_eq_some_and_get?_eq_some h
@[simp]
theorem mem_toArray_iff_getKey?_eq_some_and_get?_eq_some [TransCmp cmp] (h : t.WF) {k : α} {v : β} :
(k, v) ∈ toArray t ↔ t.getKey? k = some k ∧ get? t k = some v :=
Impl.Const.mem_toArray_iff_getKey?_eq_some_and_get?_eq_some h
theorem get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList [TransCmp cmp] (h : t.WF) {k : α} {v : β} : theorem get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList [TransCmp cmp] (h : t.WF) {k : α} {v : β} :
get? t k = some v ↔ ∃ (k' : α), cmp k k' = .eq ∧ (k', v) ∈ toList t := get? t k = some v ↔ ∃ (k' : α), cmp k k' = .eq ∧ (k', v) ∈ toList t :=
Impl.Const.get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList h Impl.Const.get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList h
theorem get?_eq_some_iff_exists_compare_eq_eq_and_mem_toArray [TransCmp cmp] (h : t.WF) {k : α} {v : β} :
get? t k = some v ↔ ∃ (k' : α), cmp k k' = .eq ∧ (k', v) ∈ toArray t :=
Impl.Const.get?_eq_some_iff_exists_compare_eq_eq_and_mem_toArray h
theorem find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some [TransCmp cmp] (h : t.WF) theorem find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some [TransCmp cmp] (h : t.WF)
{k k' : α} {v : β} : {k k' : α} {v : β} :
(toList t).find? (fun a => cmp a.1 k = .eq) = some ⟨k', v⟩ ↔ (toList t).find? (fun a => cmp a.1 k = .eq) = some ⟨k', v⟩ ↔
t.getKey? k = some k' ∧ get? t k = some v := t.getKey? k = some k' ∧ get? t k = some v :=
Impl.Const.find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some h.out Impl.Const.find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some h.out
theorem find?_toArray_eq_some_iff_getKey?_eq_some_and_get?_eq_some [TransCmp cmp] (h : t.WF)
{k k' : α} {v : β} :
(toArray t).find? (fun a => cmp a.1 k = .eq) = some ⟨k', v⟩ ↔
t.getKey? k = some k' ∧ get? t k = some v :=
Impl.Const.find?_toArray_eq_some_iff_getKey?_eq_some_and_get?_eq_some h.out
theorem find?_toList_eq_none_iff_contains_eq_false [TransCmp cmp] (h : t.WF) {k : α} : theorem find?_toList_eq_none_iff_contains_eq_false [TransCmp cmp] (h : t.WF) {k : α} :
(toList t).find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false := (toList t).find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false :=
Impl.Const.find?_toList_eq_none_iff_contains_eq_false h.out Impl.Const.find?_toList_eq_none_iff_contains_eq_false h.out
theorem find?_toArray_eq_none_iff_contains_eq_false [TransCmp cmp] (h : t.WF) {k : α} :
(toArray t).find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false :=
Impl.Const.find?_toArray_eq_none_iff_contains_eq_false h.out
@[simp] @[simp]
theorem find?_toList_eq_none_iff_not_mem [TransCmp cmp] (h : t.WF) {k : α} : theorem find?_toList_eq_none_iff_not_mem [TransCmp cmp] (h : t.WF) {k : α} :
(toList t).find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t := (toList t).find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t :=
Impl.Const.find?_toList_eq_none_iff_not_mem h.out Impl.Const.find?_toList_eq_none_iff_not_mem h.out
@[simp]
theorem find?_toArray_eq_none_iff_not_mem [TransCmp cmp] (h : t.WF) {k : α} :
(toArray t).find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t :=
Impl.Const.find?_toArray_eq_none_iff_not_mem h.out
theorem distinct_keys_toList [TransCmp cmp] (h : t.WF) : theorem distinct_keys_toList [TransCmp cmp] (h : t.WF) :
(toList t).Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq) := (toList t).Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq) :=
Impl.Const.distinct_keys_toList h.out Impl.Const.distinct_keys_toList h.out
@ -1244,18 +1376,34 @@ theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m] {f : δ → (a : α)
t.foldlM f init = t.toList.foldlM (fun a b => f a b.1 b.2) init := t.foldlM f init = t.toList.foldlM (fun a b => f a b.1 b.2) init :=
Impl.foldlM_eq_foldlM_toList Impl.foldlM_eq_foldlM_toList
theorem foldlM_eq_foldlM_toArray [Monad m] [LawfulMonad m] {f : δ → (a : α) → β a → m δ} {init : δ} :
t.foldlM f init = t.toArray.foldlM (fun a b => f a b.1 b.2) init :=
Impl.foldlM_eq_foldlM_toArray
theorem foldl_eq_foldl_toList {f : δ → (a : α) → β a → δ} {init : δ} : theorem foldl_eq_foldl_toList {f : δ → (a : α) → β a → δ} {init : δ} :
t.foldl f init = t.toList.foldl (fun a b => f a b.1 b.2) init := t.foldl f init = t.toList.foldl (fun a b => f a b.1 b.2) init :=
Impl.foldl_eq_foldl_toList Impl.foldl_eq_foldl_toList
theorem foldl_eq_foldl_toArray {f : δ → (a : α) → β a → δ} {init : δ} :
t.foldl f init = t.toArray.foldl (fun a b => f a b.1 b.2) init :=
Impl.foldl_eq_foldl_toArray
theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] {f : (a : α) → β a → δ → m δ} {init : δ} : theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] {f : (a : α) → β a → δ → m δ} {init : δ} :
t.foldrM f init = t.toList.foldrM (fun a b => f a.1 a.2 b) init := t.foldrM f init = t.toList.foldrM (fun a b => f a.1 a.2 b) init :=
Impl.foldrM_eq_foldrM_toList Impl.foldrM_eq_foldrM_toList
theorem foldrM_eq_foldrM_toArray [Monad m] [LawfulMonad m] {f : (a : α) → β a → δ → m δ} {init : δ} :
t.foldrM f init = t.toArray.foldrM (fun a b => f a.1 a.2 b) init :=
Impl.foldrM_eq_foldrM_toArray
theorem foldr_eq_foldr_toList {f : (a : α) → β a → δ → δ} {init : δ} : theorem foldr_eq_foldr_toList {f : (a : α) → β a → δ → δ} {init : δ} :
t.foldr f init = t.toList.foldr (fun a b => f a.1 a.2 b) init := t.foldr f init = t.toList.foldr (fun a b => f a.1 a.2 b) init :=
Impl.foldr_eq_foldr_toList Impl.foldr_eq_foldr_toList
theorem foldr_eq_foldr_toArray {f : (a : α) → β a → δ → δ} {init : δ} :
t.foldr f init = t.toArray.foldr (fun a b => f a.1 a.2 b) init :=
Impl.foldr_eq_foldr_toArray
@[simp, grind =] @[simp, grind =]
theorem forM_eq_forM [Monad m] [LawfulMonad m] {f : (a : α) → β a → m PUnit} : theorem forM_eq_forM [Monad m] [LawfulMonad m] {f : (a : α) → β a → m PUnit} :
t.forM f = ForM.forM t (fun a => f a.1 a.2) := rfl t.forM f = ForM.forM t (fun a => f a.1 a.2) := rfl
@ -1264,6 +1412,10 @@ theorem forM_eq_forM_toList [Monad m] [LawfulMonad m] {f : (a : α) × β a →
ForM.forM t f = ForM.forM t.toList f := ForM.forM t f = ForM.forM t.toList f :=
Impl.forM_eq_forM_toList Impl.forM_eq_forM_toList
theorem forM_eq_forM_toArray [Monad m] [LawfulMonad m] {f : (a : α) × β a → m PUnit} :
ForM.forM t f = ForM.forM t.toArray f :=
Impl.forM_eq_forM_toArray
@[simp, grind =] @[simp, grind =]
theorem forIn_eq_forIn [Monad m] [LawfulMonad m] theorem forIn_eq_forIn [Monad m] [LawfulMonad m]
{f : (a : α) → β a → δ → m (ForInStep δ)} {init : δ} : {f : (a : α) → β a → δ → m (ForInStep δ)} {init : δ} :
@ -1274,31 +1426,61 @@ theorem forIn_eq_forIn_toList [Monad m] [LawfulMonad m]
ForIn.forIn t init f = ForIn.forIn t.toList init f := ForIn.forIn t init f = ForIn.forIn t.toList init f :=
Impl.forIn_eq_forIn_toList (f := f) Impl.forIn_eq_forIn_toList (f := f)
theorem forIn_eq_forIn_toArray [Monad m] [LawfulMonad m]
{f : (a : α) × β a → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init f = ForIn.forIn t.toArray init f :=
Impl.forIn_eq_forIn_toArray (f := f)
theorem foldlM_eq_foldlM_keys [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} : theorem foldlM_eq_foldlM_keys [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} :
t.foldlM (fun d a _ => f d a) init = t.keys.foldlM f init := t.foldlM (fun d a _ => f d a) init = t.keys.foldlM f init :=
Impl.foldlM_eq_foldlM_keys Impl.foldlM_eq_foldlM_keys
theorem foldlM_eq_foldlM_keysArray [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} :
t.foldlM (fun d a _ => f d a) init = t.keysArray.foldlM f init :=
Impl.foldlM_eq_foldlM_keysArray
theorem foldl_eq_foldl_keys {f : δ → α → δ} {init : δ} : theorem foldl_eq_foldl_keys {f : δ → α → δ} {init : δ} :
t.foldl (fun d a _ => f d a) init = t.keys.foldl f init := t.foldl (fun d a _ => f d a) init = t.keys.foldl f init :=
Impl.foldl_eq_foldl_keys Impl.foldl_eq_foldl_keys
theorem foldl_eq_foldl_keysArray {f : δ → α → δ} {init : δ} :
t.foldl (fun d a _ => f d a) init = t.keysArray.foldl f init :=
Impl.foldl_eq_foldl_keysArray
theorem foldrM_eq_foldrM_keys [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} : theorem foldrM_eq_foldrM_keys [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} :
t.foldrM (fun a _ d => f a d) init = t.keys.foldrM f init := t.foldrM (fun a _ d => f a d) init = t.keys.foldrM f init :=
Impl.foldrM_eq_foldrM_keys Impl.foldrM_eq_foldrM_keys
theorem foldrM_eq_foldrM_keysArray [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} :
t.foldrM (fun a _ d => f a d) init = t.keysArray.foldrM f init :=
Impl.foldrM_eq_foldrM_keysArray
theorem foldr_eq_foldr_keys {f : α → δ → δ} {init : δ} : theorem foldr_eq_foldr_keys {f : α → δ → δ} {init : δ} :
t.foldr (fun a _ d => f a d) init = t.keys.foldr f init := t.foldr (fun a _ d => f a d) init = t.keys.foldr f init :=
Impl.foldr_eq_foldr_keys Impl.foldr_eq_foldr_keys
theorem foldr_eq_foldr_keysArray {f : α → δ → δ} {init : δ} :
t.foldr (fun a _ d => f a d) init = t.keysArray.foldr f init :=
Impl.foldr_eq_foldr_keysArray
theorem forM_eq_forM_keys [Monad m] [LawfulMonad m] {f : α → m PUnit} : theorem forM_eq_forM_keys [Monad m] [LawfulMonad m] {f : α → m PUnit} :
ForM.forM t (fun a => f a.1) = t.keys.forM f := ForM.forM t (fun a => f a.1) = t.keys.forM f :=
Impl.forM_eq_forM_keys Impl.forM_eq_forM_keys
theorem forM_eq_forM_keysArray [Monad m] [LawfulMonad m] {f : α → m PUnit} :
ForM.forM t (fun a => f a.1) = t.keysArray.forM f :=
Impl.forM_eq_forM_keysArray
theorem forIn_eq_forIn_keys [Monad m] [LawfulMonad m] theorem forIn_eq_forIn_keys [Monad m] [LawfulMonad m]
{f : α → δ → m (ForInStep δ)} {init : δ} : {f : α → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init (fun a d => f a.1 d) = ForIn.forIn t.keys init f := ForIn.forIn t init (fun a d => f a.1 d) = ForIn.forIn t.keys init f :=
Impl.forIn_eq_forIn_keys Impl.forIn_eq_forIn_keys
theorem forIn_eq_forIn_keysArray [Monad m] [LawfulMonad m]
{f : α → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init (fun a d => f a.1 d) = ForIn.forIn t.keysArray init f :=
Impl.forIn_eq_forIn_keysArray
namespace Const namespace Const
variable {β : Type v} {t : Raw α β cmp} variable {β : Type v} {t : Raw α β cmp}
@ -1307,18 +1489,34 @@ theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m] {f : δ → α → β
t.foldlM f init = (Const.toList t).foldlM (fun a b => f a b.1 b.2) init := t.foldlM f init = (Const.toList t).foldlM (fun a b => f a b.1 b.2) init :=
Impl.Const.foldlM_eq_foldlM_toList Impl.Const.foldlM_eq_foldlM_toList
theorem foldlM_eq_foldlM_toArray [Monad m] [LawfulMonad m] {f : δ → α → β → m δ} {init : δ} :
t.foldlM f init = (Const.toArray t).foldlM (fun a b => f a b.1 b.2) init :=
Impl.Const.foldlM_eq_foldlM_toArray
theorem foldl_eq_foldl_toList {f : δ → α → β → δ} {init : δ} : theorem foldl_eq_foldl_toList {f : δ → α → β → δ} {init : δ} :
t.foldl f init = (Const.toList t).foldl (fun a b => f a b.1 b.2) init := t.foldl f init = (Const.toList t).foldl (fun a b => f a b.1 b.2) init :=
Impl.Const.foldl_eq_foldl_toList Impl.Const.foldl_eq_foldl_toList
theorem foldl_eq_foldl_toArray {f : δ → α → β → δ} {init : δ} :
t.foldl f init = (Const.toArray t).foldl (fun a b => f a b.1 b.2) init :=
Impl.Const.foldl_eq_foldl_toArray
theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] {f : α → β → δ → m δ} {init : δ} : theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] {f : α → β → δ → m δ} {init : δ} :
t.foldrM f init = (Const.toList t).foldrM (fun a b => f a.1 a.2 b) init := t.foldrM f init = (Const.toList t).foldrM (fun a b => f a.1 a.2 b) init :=
Impl.Const.foldrM_eq_foldrM_toList Impl.Const.foldrM_eq_foldrM_toList
theorem foldrM_eq_foldrM_toArray [Monad m] [LawfulMonad m] {f : α → β → δ → m δ} {init : δ} :
t.foldrM f init = (Const.toArray t).foldrM (fun a b => f a.1 a.2 b) init :=
Impl.Const.foldrM_eq_foldrM_toArray
theorem foldr_eq_foldr_toList {f : α → β → δ → δ} {init : δ} : theorem foldr_eq_foldr_toList {f : α → β → δ → δ} {init : δ} :
t.foldr f init = (Const.toList t).foldr (fun a b => f a.1 a.2 b) init := t.foldr f init = (Const.toList t).foldr (fun a b => f a.1 a.2 b) init :=
Impl.Const.foldr_eq_foldr_toList Impl.Const.foldr_eq_foldr_toList
theorem foldr_eq_foldr_toArray {f : α → β → δ → δ} {init : δ} :
t.foldr f init = (Const.toArray t).foldr (fun a b => f a.1 a.2 b) init :=
Impl.Const.foldr_eq_foldr_toArray
theorem forM_eq_forMUncurried [Monad m] [LawfulMonad m] {f : α → β → m PUnit} : theorem forM_eq_forMUncurried [Monad m] [LawfulMonad m] {f : α → β → m PUnit} :
t.forM f = forMUncurried (fun a => f a.1 a.2) t := rfl t.forM f = forMUncurried (fun a => f a.1 a.2) t := rfl
@ -1326,6 +1524,10 @@ theorem forMUncurried_eq_forM_toList [Monad m] [LawfulMonad m] {f : α × β →
forMUncurried f t = (Const.toList t).forM f := forMUncurried f t = (Const.toList t).forM f :=
Impl.Const.forM_eq_forM_toList Impl.Const.forM_eq_forM_toList
theorem forMUncurried_eq_forM_toArray [Monad m] [LawfulMonad m] {f : α × β → m PUnit} :
forMUncurried f t = (Const.toArray t).forM f :=
Impl.Const.forM_eq_forM_toArray
theorem forIn_eq_forInUncurried [Monad m] [LawfulMonad m] theorem forIn_eq_forInUncurried [Monad m] [LawfulMonad m]
{f : α → β → δ → m (ForInStep δ)} {init : δ} : {f : α → β → δ → m (ForInStep δ)} {init : δ} :
t.forIn f init = forInUncurried (fun a b => f a.1 a.2 b) init t := rfl t.forIn f init = forInUncurried (fun a b => f a.1 a.2 b) init t := rfl
@ -1335,6 +1537,11 @@ theorem forInUncurried_eq_forIn_toList [Monad m] [LawfulMonad m]
forInUncurried f init t = ForIn.forIn (Const.toList t) init f := forInUncurried f init t = ForIn.forIn (Const.toList t) init f :=
Impl.Const.forIn_eq_forIn_toList Impl.Const.forIn_eq_forIn_toList
theorem forInUncurried_eq_forIn_toArray [Monad m] [LawfulMonad m]
{f : α × β → δ → m (ForInStep δ)} {init : δ} :
forInUncurried f init t = ForIn.forIn (Const.toArray t) init f :=
Impl.Const.forIn_eq_forIn_toArray
end Const end Const
end monadic end monadic
@ -4383,6 +4590,11 @@ theorem minKey?_eq_head?_keys [TransCmp cmp] (h : t.WF) :
t.minKey? = t.keys.head? := t.minKey? = t.keys.head? :=
Impl.minKey?_eq_head?_keys h (instOrd := ⟨cmp⟩) Impl.minKey?_eq_head?_keys h (instOrd := ⟨cmp⟩)
@[grind =_]
theorem minKey?_eq_getElem?_keysArray [TransCmp cmp] (h : t.WF) :
t.minKey? = t.keysArray[0]? :=
Impl.minKey?_eq_getElem?_keysArray h (instOrd := ⟨cmp⟩)
@[simp, grind =] @[simp, grind =]
theorem minKey?_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f} (h : t.WF) : theorem minKey?_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f} (h : t.WF) :
(t.modify k f).minKey? = t.minKey? := (t.modify k f).minKey? = t.minKey? :=
@ -4532,6 +4744,11 @@ theorem minKey!_eq_head!_keys [TransCmp cmp] [Inhabited α] (h : t.WF) :
t.minKey! = t.keys.head! := t.minKey! = t.keys.head! :=
Impl.minKey!_eq_head!_keys h (instOrd := ⟨cmp⟩) Impl.minKey!_eq_head!_keys h (instOrd := ⟨cmp⟩)
@[grind =_]
theorem minKey!_eq_getElem!_keysArray [TransCmp cmp] [Inhabited α] (h : t.WF) :
t.minKey! = t.keysArray[0]! :=
Impl.minKey!_eq_getElem!_keysArray h (instOrd := ⟨cmp⟩)
@[simp] @[simp]
theorem minKey!_modify [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] (h : t.WF) {k f} : theorem minKey!_modify [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] (h : t.WF) {k f} :
(t.modify k f).minKey! = t.minKey! := (t.modify k f).minKey! = t.minKey! :=
@ -4678,6 +4895,10 @@ theorem minKeyD_eq_headD_keys [TransCmp cmp] (h : t.WF) {fallback} :
t.minKeyD fallback = t.keys.headD fallback := t.minKeyD fallback = t.keys.headD fallback :=
Impl.minKeyD_eq_headD_keys h (instOrd := ⟨cmp⟩) Impl.minKeyD_eq_headD_keys h (instOrd := ⟨cmp⟩)
theorem minKeyD_eq_getD_keysArray [TransCmp cmp] (h : t.WF) {fallback} :
t.minKeyD fallback = t.keysArray.getD 0 fallback :=
Impl.minKeyD_eq_getD_keysArray h (instOrd := ⟨cmp⟩)
@[simp, grind =] @[simp, grind =]
theorem minKeyD_modify [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k f fallback} : theorem minKeyD_modify [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k f fallback} :
(t.modify k f |>.minKeyD fallback) = t.minKeyD fallback := (t.modify k f |>.minKeyD fallback) = t.minKeyD fallback :=
@ -4885,6 +5106,11 @@ theorem maxKey?_eq_getLast?_keys [TransCmp cmp] (h : t.WF) :
t.maxKey? = t.keys.getLast? := t.maxKey? = t.keys.getLast? :=
Impl.maxKey?_eq_getLast?_keys h (instOrd := ⟨cmp⟩) Impl.maxKey?_eq_getLast?_keys h (instOrd := ⟨cmp⟩)
@[grind =_]
theorem maxKey?_eq_back?_keysArray [TransCmp cmp] (h : t.WF) :
t.maxKey? = t.keysArray.back? :=
Impl.maxKey?_eq_back?_keysArray h (instOrd := ⟨cmp⟩)
@[simp, grind =] @[simp, grind =]
theorem maxKey?_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f} (h : t.WF) : theorem maxKey?_modify [TransCmp cmp] [LawfulEqCmp cmp] {k f} (h : t.WF) :
(t.modify k f).maxKey? = t.maxKey? := (t.modify k f).maxKey? = t.maxKey? :=
@ -5032,6 +5258,11 @@ theorem maxKey!_eq_getLast!_keys [TransCmp cmp] [Inhabited α] (h : t.WF) :
t.maxKey! = t.keys.getLast! := t.maxKey! = t.keys.getLast! :=
Impl.maxKey!_eq_getLast!_keys h (instOrd := ⟨cmp⟩) Impl.maxKey!_eq_getLast!_keys h (instOrd := ⟨cmp⟩)
@[grind =_]
theorem maxKey!_eq_back!_keysArray [TransCmp cmp] [Inhabited α] (h : t.WF) :
t.maxKey! = t.keysArray.back! :=
Impl.maxKey!_eq_back!_keysArray h (instOrd := ⟨cmp⟩)
@[simp, grind =] @[simp, grind =]
theorem maxKey!_modify [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] (h : t.WF) {k f} : theorem maxKey!_modify [TransCmp cmp] [LawfulEqCmp cmp] [Inhabited α] (h : t.WF) {k f} :
(t.modify k f).maxKey! = t.maxKey! := (t.modify k f).maxKey! = t.maxKey! :=
@ -5180,6 +5411,11 @@ theorem maxKeyD_eq_getLastD_keys [TransCmp cmp] (h : t.WF) {fallback} :
t.maxKeyD fallback = t.keys.getLastD fallback := t.maxKeyD fallback = t.keys.getLastD fallback :=
Impl.maxKeyD_eq_getLastD_keys h (instOrd := ⟨cmp⟩) Impl.maxKeyD_eq_getLastD_keys h (instOrd := ⟨cmp⟩)
@[grind =_]
theorem maxKeyD_eq_getD_back?_keysArray [TransCmp cmp] (h : t.WF) {fallback} :
t.maxKeyD fallback = t.keysArray.back?.getD fallback :=
Impl.maxKeyD_eq_getD_back?_keysArray h (instOrd := ⟨cmp⟩)
@[simp, grind =] @[simp, grind =]
theorem maxKeyD_modify [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k f fallback} : theorem maxKeyD_modify [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k f fallback} :
(t.modify k f |>.maxKeyD fallback) = t.maxKeyD fallback := (t.modify k f |>.maxKeyD fallback) = t.maxKeyD fallback :=
@ -5762,13 +5998,23 @@ theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList := theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList :=
equiv_iff.trans Impl.equiv_iff_toList_perm equiv_iff.trans Impl.equiv_iff_toList_perm
theorem equiv_iff_toArray_perm : t₁ ~m t₂ ↔ t₁.toArray.Perm t₂.toArray :=
equiv_iff.trans Impl.equiv_iff_toArray_perm
theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ := theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ :=
⟨.of_toList_perm h⟩ ⟨.of_toList_perm h⟩
theorem Equiv.of_toArray_perm (h : t₁.toArray.Perm t₂.toArray) : t₁ ~m t₂ :=
⟨.of_toArray_perm h⟩
theorem equiv_iff_toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) : theorem equiv_iff_toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ t₁.toList = t₂.toList := t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
equiv_iff.trans (Impl.equiv_iff_toList_eq h₁.1 h₂.1) equiv_iff.trans (Impl.equiv_iff_toList_eq h₁.1 h₂.1)
theorem equiv_iff_toArray_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ t₁.toArray = t₂.toArray :=
equiv_iff.trans (Impl.equiv_iff_toArray_eq h₁.1 h₂.1)
theorem insertMany_list_equiv_foldl {l : List ((a : α) × β a)} : theorem insertMany_list_equiv_foldl {l : List ((a : α) × β a)} :
t₁.insertMany l ~m l.foldl (init := t₁) fun acc p => acc.insert p.1 p.2 := by t₁.insertMany l ~m l.foldl (init := t₁) fun acc p => acc.insert p.1 p.2 := by
constructor constructor
@ -5788,24 +6034,46 @@ variable {β : Type v} {t₁ t₂ : Raw α β cmp}
theorem Const.equiv_iff_toList_perm : t₁ ~m t₂ ↔ (Const.toList t₁).Perm (Const.toList t₂) := theorem Const.equiv_iff_toList_perm : t₁ ~m t₂ ↔ (Const.toList t₁).Perm (Const.toList t₂) :=
equiv_iff.trans Impl.Const.equiv_iff_toList_perm equiv_iff.trans Impl.Const.equiv_iff_toList_perm
theorem Const.equiv_iff_toArray_perm : t₁ ~m t₂ ↔ (Const.toArray t₁).Perm (Const.toArray t₂) :=
equiv_iff.trans Impl.Const.equiv_iff_toArray_perm
theorem Const.equiv_iff_toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) : theorem Const.equiv_iff_toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ Const.toList t₁ = Const.toList t₂ := t₁ ~m t₂ ↔ Const.toList t₁ = Const.toList t₂ :=
equiv_iff.trans (Impl.Const.equiv_iff_toList_eq h₁.1 h₂.1) equiv_iff.trans (Impl.Const.equiv_iff_toList_eq h₁.1 h₂.1)
theorem Const.equiv_iff_toArray_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ Const.toArray t₁ = Const.toArray t₂ :=
equiv_iff.trans (Impl.Const.equiv_iff_toArray_eq h₁.1 h₂.1)
theorem Const.equiv_iff_keys_unit_perm {t₁ t₂ : Raw α Unit cmp} : theorem Const.equiv_iff_keys_unit_perm {t₁ t₂ : Raw α Unit cmp} :
t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys := t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys :=
equiv_iff.trans Impl.Const.equiv_iff_keys_perm equiv_iff.trans Impl.Const.equiv_iff_keys_perm
theorem Const.equiv_iff_keysArray_unit_perm {t₁ t₂ : Raw α Unit cmp} :
t₁ ~m t₂ ↔ t₁.keysArray.Perm t₂.keysArray :=
equiv_iff.trans Impl.Const.equiv_iff_keysArray_perm
theorem Const.equiv_iff_keys_unit_eq {t₁ t₂ : Raw α Unit cmp} [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) : theorem Const.equiv_iff_keys_unit_eq {t₁ t₂ : Raw α Unit cmp} [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ t₁.keys = t₂.keys := t₁ ~m t₂ ↔ t₁.keys = t₂.keys :=
equiv_iff.trans (Impl.Const.equiv_iff_keys_eq h₁.1 h₂.1) equiv_iff.trans (Impl.Const.equiv_iff_keys_eq h₁.1 h₂.1)
theorem Const.equiv_iff_keysArray_unit_eq {t₁ t₂ : Raw α Unit cmp} [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ t₁.keysArray = t₂.keysArray :=
equiv_iff.trans (Impl.Const.equiv_iff_keysArray_eq h₁.1 h₂.1)
theorem Equiv.of_constToList_perm : (Const.toList t₁).Perm (Const.toList t₂) → t₁ ~m t₂ := theorem Equiv.of_constToList_perm : (Const.toList t₁).Perm (Const.toList t₂) → t₁ ~m t₂ :=
Const.equiv_iff_toList_perm.mpr Const.equiv_iff_toList_perm.mpr
theorem Equiv.of_constToArray_perm : (Const.toArray t₁).Perm (Const.toArray t₂) → t₁ ~m t₂ :=
Const.equiv_iff_toArray_perm.mpr
theorem Equiv.of_keys_unit_perm {t₁ t₂ : Raw α Unit cmp} : t₁.keys.Perm t₂.keys → t₁ ~m t₂ := theorem Equiv.of_keys_unit_perm {t₁ t₂ : Raw α Unit cmp} : t₁.keys.Perm t₂.keys → t₁ ~m t₂ :=
Const.equiv_iff_keys_unit_perm.mpr Const.equiv_iff_keys_unit_perm.mpr
theorem Equiv.of_keysArray_unit_perm {t₁ t₂ : Raw α Unit cmp} :
t₁.keysArray.Perm t₂.keysArray → t₁ ~m t₂ :=
Const.equiv_iff_keysArray_unit_perm.mpr
theorem Const.insertMany_list_equiv_foldl {l : List (α × β)} : theorem Const.insertMany_list_equiv_foldl {l : List (α × β)} :
insertMany t₁ l ~m l.foldl (init := t₁) (fun acc p => acc.insert p.1 p.2) := by insertMany t₁ l ~m l.foldl (init := t₁) (fun acc p => acc.insert p.1 p.2) := by
constructor constructor
@ -5841,6 +6109,11 @@ theorem toList_filterMap {f : (a : α) → β a → Option (γ a)} (h : t.WF) :
t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) := t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) :=
Impl.toList_filterMap! h Impl.toList_filterMap! h
theorem toArray_filterMap {f : (a : α) → β a → Option (γ a)} (h : t.WF) :
(t.filterMap f).toArray =
t.toArray.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩)) :=
Impl.toArray_filterMap! h
@[grind =] @[grind =]
theorem isEmpty_filterMap_iff [TransCmp cmp] [LawfulEqCmp cmp] theorem isEmpty_filterMap_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Option (γ a)} (h : t.WF) : {f : (a : α) → β a → Option (γ a)} (h : t.WF) :
@ -6064,6 +6337,12 @@ theorem toList_filterMap
(Const.toList t).filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x))) := (Const.toList t).filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x))) :=
Impl.Const.toList_filterMap! h Impl.Const.toList_filterMap! h
theorem toArray_filterMap
{f : α → β → Option γ} (h : t.WF) :
Const.toArray (t.filterMap f) =
(Const.toArray t).filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x))) :=
Impl.Const.toArray_filterMap! h
@[grind =] @[grind =]
theorem getKey?_filterMap [TransCmp cmp] theorem getKey?_filterMap [TransCmp cmp]
{f : α → β → Option γ} {k : α} (h : t.WF) : {f : α → β → Option γ} {k : α} (h : t.WF) :
@ -6108,10 +6387,18 @@ theorem toList_filter {f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter f).toList = t.toList.filter (fun p => f p.1 p.2) := (t.filter f).toList = t.toList.filter (fun p => f p.1 p.2) :=
Impl.toList_filter! h Impl.toList_filter! h
theorem toArray_filter {f : (a : α) → β a → Bool} (h : t.WF) :
(t.filter f).toArray = t.toArray.filter (fun p => f p.1 p.2) :=
Impl.toArray_filter! h
theorem keys_filter_key {f : α → Bool} (h : t.WF) : theorem keys_filter_key {f : α → Bool} (h : t.WF) :
(t.filter fun k _ => f k).keys = t.keys.filter f := (t.filter fun k _ => f k).keys = t.keys.filter f :=
Impl.keys_filter!_key h Impl.keys_filter!_key h
theorem keysArray_filter_key {f : α → Bool} (h : t.WF) :
(t.filter fun k _ => f k).keysArray = t.keysArray.filter f :=
Impl.keysArray_filter!_key h
@[grind =] @[grind =]
theorem isEmpty_filter_iff [TransCmp cmp] [LawfulEqCmp cmp] theorem isEmpty_filter_iff [TransCmp cmp] [LawfulEqCmp cmp]
{f : (a : α) → β a → Bool} (h : t.WF) : {f : (a : α) → β a → Bool} (h : t.WF) :
@ -6381,6 +6668,11 @@ theorem toList_filter {f : α → β → Bool} (h : t.WF) :
(Const.toList t).filter (fun p => f p.1 p.2) := (Const.toList t).filter (fun p => f p.1 p.2) :=
Impl.Const.toList_filter! h Impl.Const.toList_filter! h
theorem toArray_filter {f : α → β → Bool} (h : t.WF) :
Const.toArray (t.filter f) =
(Const.toArray t).filter (fun p => f p.1 p.2) :=
Impl.Const.toArray_filter! h
theorem keys_filter [TransCmp cmp] {f : α → β → Bool} (h : t.WF) : theorem keys_filter [TransCmp cmp] {f : α → β → Bool} (h : t.WF) :
(t.filter f).keys = (t.filter f).keys =
(t.keys.attach.filter (fun ⟨x, h'⟩ => f x (get t x (mem_of_mem_keys h h')))).unattach := (t.keys.attach.filter (fun ⟨x, h'⟩ => f x (get t x (mem_of_mem_keys h h')))).unattach :=
@ -6429,9 +6721,16 @@ theorem toList_map {f : (a : α) → β a → γ a} :
(t.map f).toList = t.toList.map (fun p => ⟨p.1, f p.1 p.2⟩) := (t.map f).toList = t.toList.map (fun p => ⟨p.1, f p.1 p.2⟩) :=
Impl.toList_map Impl.toList_map
theorem toArray_map {f : (a : α) → β a → γ a} :
(t.map f).toArray = t.toArray.map (fun p => ⟨p.1, f p.1 p.2⟩) :=
Impl.toArray_map
theorem keys_map {f : (a : α) → β a → γ a} : (t.map f).keys = t.keys := theorem keys_map {f : (a : α) → β a → γ a} : (t.map f).keys = t.keys :=
Impl.keys_map Impl.keys_map
theorem keysArray_map {f : (a : α) → β a → γ a} : (t.map f).keysArray = t.keysArray :=
Impl.keysArray_map
theorem filterMap_equiv_map [TransCmp cmp] theorem filterMap_equiv_map [TransCmp cmp]
{f : (a : α) → β a → γ a} (h : t.WF) : {f : (a : α) → β a → γ a} (h : t.WF) :
(t.filterMap (fun k v => some (f k v))) ~m t.map f := (t.filterMap (fun k v => some (f k v))) ~m t.map f :=
@ -6598,6 +6897,11 @@ theorem toList_map {f : α → β → γ} :
(Const.toList t).map (fun p => (p.1, f p.1 p.2)) := (Const.toList t).map (fun p => (p.1, f p.1 p.2)) :=
Impl.Const.toList_map Impl.Const.toList_map
theorem toArray_map {f : α → β → γ} :
Const.toArray (t.map f) =
(Const.toArray t).map (fun p => (p.1, f p.1 p.2)) :=
Impl.Const.toArray_map
end Const end Const
end map end map

View file

@ -8,6 +8,7 @@ module
prelude prelude
import Std.Data.DTreeMap.Lemmas import Std.Data.DTreeMap.Lemmas
public import Std.Data.TreeMap.AdditionalOperations public import Std.Data.TreeMap.AdditionalOperations
public import Init.Data.Array.Perm
import Init.Data.List.Pairwise import Init.Data.List.Pairwise
@[expose] public section @[expose] public section
@ -297,10 +298,17 @@ theorem getElem?_congr [TransCmp cmp] {a b : α} (hab : cmp a b = .eq) :
theorem toList_insert_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} {v : β} : theorem toList_insert_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} {v : β} :
(t.insert k v).toList.Perm (⟨k, v⟩ :: t.toList.filter (¬k == ·.1)) := DTreeMap.Const.toList_insert_perm (t.insert k v).toList.Perm (⟨k, v⟩ :: t.toList.filter (¬k == ·.1)) := DTreeMap.Const.toList_insert_perm
theorem toArray_insert_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} {v : β} :
(t.insert k v).toArray.Perm ((t.toArray.filter (¬k == ·.1)).push ⟨k, v⟩) := DTreeMap.Const.toArray_insert_perm
theorem keys_insertIfNew_perm {t : TreeMap α Unit cmp} [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} : theorem keys_insertIfNew_perm {t : TreeMap α Unit cmp} [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} :
(t.insertIfNew k ()).keys.Perm (if k ∈ t then t.keys else k :: t.keys) := (t.insertIfNew k ()).keys.Perm (if k ∈ t then t.keys else k :: t.keys) :=
DTreeMap.keys_insertIfNew_perm DTreeMap.keys_insertIfNew_perm
theorem keysArray_insertIfNew_perm {t : TreeMap α Unit cmp} [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} :
(t.insertIfNew k ()).keysArray.Perm (if k ∈ t then t.keysArray else t.keysArray.push k) :=
DTreeMap.keysArray_insertIfNew_perm
@[simp] @[simp]
theorem getElem_insert_self [TransCmp cmp] {k : α} {v : β} : theorem getElem_insert_self [TransCmp cmp] {k : α} {v : β} :
(t.insert k v)[k]'mem_insert_self = v := (t.insert k v)[k]'mem_insert_self = v :=
@ -804,24 +812,47 @@ theorem length_keys [TransCmp cmp] :
t.keys.length = t.size := t.keys.length = t.size :=
DTreeMap.length_keys DTreeMap.length_keys
@[simp, grind =]
theorem size_keysArray [TransCmp cmp] :
t.keysArray.size = t.size :=
DTreeMap.size_keysArray
@[simp, grind =] @[simp, grind =]
theorem isEmpty_keys : theorem isEmpty_keys :
t.keys.isEmpty = t.isEmpty := t.keys.isEmpty = t.isEmpty :=
DTreeMap.isEmpty_keys DTreeMap.isEmpty_keys
@[simp, grind =]
theorem isEmpty_keysArray :
t.keysArray.isEmpty = t.isEmpty :=
DTreeMap.isEmpty_keysArray
@[simp, grind =] @[simp, grind =]
theorem contains_keys [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] {k : α} : theorem contains_keys [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] {k : α} :
t.keys.contains k = t.contains k := t.keys.contains k = t.contains k :=
DTreeMap.contains_keys DTreeMap.contains_keys
@[simp, grind =]
theorem contains_keysArray [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] {k : α} :
t.keysArray.contains k = t.contains k :=
DTreeMap.contains_keysArray
@[simp, grind =] @[simp, grind =]
theorem mem_keys [LawfulEqCmp cmp] [TransCmp cmp] {k : α} : theorem mem_keys [LawfulEqCmp cmp] [TransCmp cmp] {k : α} :
k ∈ t.keys ↔ k ∈ t := k ∈ t.keys ↔ k ∈ t :=
DTreeMap.mem_keys DTreeMap.mem_keys
@[simp, grind =]
theorem mem_keysArray [LawfulEqCmp cmp] [TransCmp cmp] {k : α} :
k ∈ t.keysArray ↔ k ∈ t :=
DTreeMap.mem_keysArray
theorem mem_of_mem_keys [TransCmp cmp] {k : α} (h : k ∈ t.keys) : k ∈ t := theorem mem_of_mem_keys [TransCmp cmp] {k : α} (h : k ∈ t.keys) : k ∈ t :=
DTreeMap.mem_of_mem_keys h DTreeMap.mem_of_mem_keys h
theorem mem_of_mem_keysArray [TransCmp cmp] {k : α} (h : k ∈ t.keysArray) : k ∈ t :=
DTreeMap.mem_of_mem_keysArray h
theorem distinct_keys [TransCmp cmp] : theorem distinct_keys [TransCmp cmp] :
t.keys.Pairwise (fun a b => ¬ cmp a b = .eq) := t.keys.Pairwise (fun a b => ¬ cmp a b = .eq) :=
DTreeMap.distinct_keys DTreeMap.distinct_keys
@ -839,45 +870,89 @@ theorem map_fst_toList_eq_keys :
(toList t).map Prod.fst = t.keys := (toList t).map Prod.fst = t.keys :=
DTreeMap.Const.map_fst_toList_eq_keys DTreeMap.Const.map_fst_toList_eq_keys
@[simp, grind _=_]
theorem map_fst_toArray_eq_keysArray :
(toArray t).map Prod.fst = t.keysArray :=
DTreeMap.Const.map_fst_toArray_eq_keysArray
@[simp, grind =] @[simp, grind =]
theorem length_toList : theorem length_toList :
(toList t).length = t.size := (toList t).length = t.size :=
DTreeMap.Const.length_toList DTreeMap.Const.length_toList
@[simp, grind =]
theorem size_toArray :
(toArray t).size = t.size :=
DTreeMap.Const.size_toArray
@[simp, grind =] @[simp, grind =]
theorem isEmpty_toList : theorem isEmpty_toList :
(toList t).isEmpty = t.isEmpty := (toList t).isEmpty = t.isEmpty :=
DTreeMap.Const.isEmpty_toList DTreeMap.Const.isEmpty_toList
@[simp, grind =]
theorem isEmpty_toArray :
(toArray t).isEmpty = t.isEmpty :=
DTreeMap.Const.isEmpty_toArray
@[simp, grind =] @[simp, grind =]
theorem mem_toList_iff_getElem?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β} : theorem mem_toList_iff_getElem?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β} :
(k, v) ∈ toList t ↔ t[k]? = some v := (k, v) ∈ toList t ↔ t[k]? = some v :=
DTreeMap.Const.mem_toList_iff_get?_eq_some DTreeMap.Const.mem_toList_iff_get?_eq_some
@[simp, grind =]
theorem mem_toArray_iff_getElem?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {v : β} :
(k, v) ∈ toArray t ↔ t[k]? = some v :=
DTreeMap.Const.mem_toArray_iff_get?_eq_some
@[simp] @[simp]
theorem mem_toList_iff_getKey?_eq_some_and_getElem?_eq_some [TransCmp cmp] {k : α} {v : β} : theorem mem_toList_iff_getKey?_eq_some_and_getElem?_eq_some [TransCmp cmp] {k : α} {v : β} :
(k, v) ∈ toList t ↔ t.getKey? k = some k ∧ t[k]? = some v := (k, v) ∈ toList t ↔ t.getKey? k = some k ∧ t[k]? = some v :=
DTreeMap.Const.mem_toList_iff_getKey?_eq_some_and_get?_eq_some DTreeMap.Const.mem_toList_iff_getKey?_eq_some_and_get?_eq_some
@[simp]
theorem mem_toArray_iff_getKey?_eq_some_and_getElem?_eq_some [TransCmp cmp] {k : α} {v : β} :
(k, v) ∈ toArray t ↔ t.getKey? k = some k ∧ t[k]? = some v :=
DTreeMap.Const.mem_toArray_iff_getKey?_eq_some_and_get?_eq_some
theorem getElem?_eq_some_iff_exists_compare_eq_eq_and_mem_toList [TransCmp cmp] {k : α} {v : β} : theorem getElem?_eq_some_iff_exists_compare_eq_eq_and_mem_toList [TransCmp cmp] {k : α} {v : β} :
t[k]? = some v ↔ ∃ (k' : α), cmp k k' = .eq ∧ (k', v) ∈ toList t := t[k]? = some v ↔ ∃ (k' : α), cmp k k' = .eq ∧ (k', v) ∈ toList t :=
DTreeMap.Const.get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList DTreeMap.Const.get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList
theorem getElem?_eq_some_iff_exists_compare_eq_eq_and_mem_toArray [TransCmp cmp] {k : α} {v : β} :
t[k]? = some v ↔ ∃ (k' : α), cmp k k' = .eq ∧ (k', v) ∈ toArray t :=
DTreeMap.Const.get?_eq_some_iff_exists_compare_eq_eq_and_mem_toArray
theorem find?_toList_eq_some_iff_getKey?_eq_some_and_getElem?_eq_some [TransCmp cmp] {k k' : α} theorem find?_toList_eq_some_iff_getKey?_eq_some_and_getElem?_eq_some [TransCmp cmp] {k k' : α}
{v : β} : {v : β} :
t.toList.find? (cmp ·.1 k == .eq) = some ⟨k', v⟩ ↔ t.toList.find? (cmp ·.1 k == .eq) = some ⟨k', v⟩ ↔
t.getKey? k = some k' ∧ t[k]? = some v := t.getKey? k = some k' ∧ t[k]? = some v :=
DTreeMap.Const.find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some DTreeMap.Const.find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some
theorem find?_toArray_eq_some_iff_getKey?_eq_some_and_getElem?_eq_some [TransCmp cmp] {k k' : α}
{v : β} :
t.toArray.find? (cmp ·.1 k == .eq) = some (k', v) ↔
t.getKey? k = some k' ∧ t[k]? = some v :=
DTreeMap.Const.find?_toArray_eq_some_iff_getKey?_eq_some_and_get?_eq_some
theorem find?_toList_eq_none_iff_contains_eq_false [TransCmp cmp] {k : α} : theorem find?_toList_eq_none_iff_contains_eq_false [TransCmp cmp] {k : α} :
(toList t).find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false := (toList t).find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false :=
DTreeMap.Const.find?_toList_eq_none_iff_contains_eq_false DTreeMap.Const.find?_toList_eq_none_iff_contains_eq_false
theorem find?_toArray_eq_none_iff_contains_eq_false [TransCmp cmp] {k : α} :
(toArray t).find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false :=
DTreeMap.Const.find?_toArray_eq_none_iff_contains_eq_false
@[simp] @[simp]
theorem find?_toList_eq_none_iff_not_mem [TransCmp cmp] {k : α} : theorem find?_toList_eq_none_iff_not_mem [TransCmp cmp] {k : α} :
(toList t).find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t := (toList t).find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t :=
DTreeMap.Const.find?_toList_eq_none_iff_not_mem DTreeMap.Const.find?_toList_eq_none_iff_not_mem
@[simp]
theorem find?_toArray_eq_none_iff_not_mem [TransCmp cmp] {k : α} :
(toArray t).find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t :=
DTreeMap.Const.find?_toArray_eq_none_iff_not_mem
theorem distinct_keys_toList [TransCmp cmp] : theorem distinct_keys_toList [TransCmp cmp] :
(toList t).Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq) := (toList t).Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq) :=
DTreeMap.Const.distinct_keys_toList DTreeMap.Const.distinct_keys_toList
@ -894,18 +969,34 @@ theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m] {f : δ → α → β
t.foldlM f init = t.toList.foldlM (fun a b => f a b.1 b.2) init := t.foldlM f init = t.toList.foldlM (fun a b => f a b.1 b.2) init :=
DTreeMap.Const.foldlM_eq_foldlM_toList DTreeMap.Const.foldlM_eq_foldlM_toList
theorem foldlM_eq_foldlM_toArray [Monad m] [LawfulMonad m] {f : δ → α → β → m δ} {init : δ} :
t.foldlM f init = t.toArray.foldlM (fun a b => f a b.1 b.2) init :=
DTreeMap.Const.foldlM_eq_foldlM_toArray
theorem foldl_eq_foldl_toList {f : δ → α → β → δ} {init : δ} : theorem foldl_eq_foldl_toList {f : δ → α → β → δ} {init : δ} :
t.foldl f init = t.toList.foldl (fun a b => f a b.1 b.2) init := t.foldl f init = t.toList.foldl (fun a b => f a b.1 b.2) init :=
DTreeMap.Const.foldl_eq_foldl_toList DTreeMap.Const.foldl_eq_foldl_toList
theorem foldl_eq_foldl_toArray {f : δ → α → β → δ} {init : δ} :
t.foldl f init = t.toArray.foldl (fun a b => f a b.1 b.2) init :=
DTreeMap.Const.foldl_eq_foldl_toArray
theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] {f : α → β → δ → m δ} {init : δ} : theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] {f : α → β → δ → m δ} {init : δ} :
t.foldrM f init = t.toList.foldrM (fun a b => f a.1 a.2 b) init := t.foldrM f init = t.toList.foldrM (fun a b => f a.1 a.2 b) init :=
DTreeMap.Const.foldrM_eq_foldrM_toList DTreeMap.Const.foldrM_eq_foldrM_toList
theorem foldrM_eq_foldrM_toArray [Monad m] [LawfulMonad m] {f : α → β → δ → m δ} {init : δ} :
t.foldrM f init = t.toArray.foldrM (fun a b => f a.1 a.2 b) init :=
DTreeMap.Const.foldrM_eq_foldrM_toArray
theorem foldr_eq_foldr_toList {f : α → β → δ → δ} {init : δ} : theorem foldr_eq_foldr_toList {f : α → β → δ → δ} {init : δ} :
t.foldr f init = t.toList.foldr (fun a b => f a.1 a.2 b) init := t.foldr f init = t.toList.foldr (fun a b => f a.1 a.2 b) init :=
DTreeMap.Const.foldr_eq_foldr_toList DTreeMap.Const.foldr_eq_foldr_toList
theorem foldr_eq_foldr_toArray {f : α → β → δ → δ} {init : δ} :
t.foldr f init = t.toArray.foldr (fun a b => f a.1 a.2 b) init :=
DTreeMap.Const.foldr_eq_foldr_toArray
@[simp, grind =] @[simp, grind =]
theorem forM_eq_forM [Monad m] [LawfulMonad m] {f : α → β → m PUnit} : theorem forM_eq_forM [Monad m] [LawfulMonad m] {f : α → β → m PUnit} :
t.forM f = ForM.forM t (fun a => f a.1 a.2) := rfl t.forM f = ForM.forM t (fun a => f a.1 a.2) := rfl
@ -914,6 +1005,10 @@ theorem forM_eq_forM_toList [Monad m] [LawfulMonad m] {f : α × β → m PUnit}
ForM.forM t f = ForM.forM t.toList f := ForM.forM t f = ForM.forM t.toList f :=
DTreeMap.Const.forMUncurried_eq_forM_toList (f := f) DTreeMap.Const.forMUncurried_eq_forM_toList (f := f)
theorem forM_eq_forM_toArray [Monad m] [LawfulMonad m] {f : α × β → m PUnit} :
ForM.forM t f = ForM.forM t.toArray f :=
DTreeMap.Const.forMUncurried_eq_forM_toArray (f := f)
@[simp, grind =] @[simp, grind =]
theorem forIn_eq_forIn [Monad m] [LawfulMonad m] theorem forIn_eq_forIn [Monad m] [LawfulMonad m]
{f : α → β → δ → m (ForInStep δ)} {init : δ} : {f : α → β → δ → m (ForInStep δ)} {init : δ} :
@ -924,30 +1019,60 @@ theorem forIn_eq_forIn_toList [Monad m] [LawfulMonad m]
ForIn.forIn t init f = ForIn.forIn t.toList init f := ForIn.forIn t init f = ForIn.forIn t.toList init f :=
DTreeMap.Const.forInUncurried_eq_forIn_toList DTreeMap.Const.forInUncurried_eq_forIn_toList
theorem forIn_eq_forIn_toArray [Monad m] [LawfulMonad m]
{f : α × β → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init f = ForIn.forIn t.toArray init f :=
DTreeMap.Const.forInUncurried_eq_forIn_toArray
theorem foldlM_eq_foldlM_keys [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} : theorem foldlM_eq_foldlM_keys [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} :
t.foldlM (fun d a _ => f d a) init = t.keys.foldlM f init := t.foldlM (fun d a _ => f d a) init = t.keys.foldlM f init :=
DTreeMap.foldlM_eq_foldlM_keys DTreeMap.foldlM_eq_foldlM_keys
theorem foldlM_eq_foldlM_keysArray [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} :
t.foldlM (fun d a _ => f d a) init = t.keysArray.foldlM f init :=
DTreeMap.foldlM_eq_foldlM_keysArray
theorem foldl_eq_foldl_keys {f : δ → α → δ} {init : δ} : theorem foldl_eq_foldl_keys {f : δ → α → δ} {init : δ} :
t.foldl (fun d a _ => f d a) init = t.keys.foldl f init := t.foldl (fun d a _ => f d a) init = t.keys.foldl f init :=
DTreeMap.foldl_eq_foldl_keys DTreeMap.foldl_eq_foldl_keys
theorem foldl_eq_foldl_keysArray {f : δ → α → δ} {init : δ} :
t.foldl (fun d a _ => f d a) init = t.keysArray.foldl f init :=
DTreeMap.foldl_eq_foldl_keysArray
theorem foldrM_eq_foldrM_keys [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} : theorem foldrM_eq_foldrM_keys [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} :
t.foldrM (fun a _ d => f a d) init = t.keys.foldrM f init := t.foldrM (fun a _ d => f a d) init = t.keys.foldrM f init :=
DTreeMap.foldrM_eq_foldrM_keys DTreeMap.foldrM_eq_foldrM_keys
theorem foldrM_eq_foldrM_keysArray [Monad m] [LawfulMonad m]
{f : α → δ → m δ} {init : δ} :
t.foldrM (fun a _ d => f a d) init = t.keysArray.foldrM f init :=
DTreeMap.foldrM_eq_foldrM_keysArray
theorem foldr_eq_foldr_keys {f : α → δ → δ} {init : δ} : theorem foldr_eq_foldr_keys {f : α → δ → δ} {init : δ} :
t.foldr (fun a _ d => f a d) init = t.keys.foldr f init := t.foldr (fun a _ d => f a d) init = t.keys.foldr f init :=
DTreeMap.foldr_eq_foldr_keys DTreeMap.foldr_eq_foldr_keys
theorem foldr_eq_foldr_keysArray {f : α → δ → δ} {init : δ} :
t.foldr (fun a _ d => f a d) init = t.keysArray.foldr f init :=
DTreeMap.foldr_eq_foldr_keysArray
theorem forM_eq_forM_keys [Monad m] [LawfulMonad m] {f : α → m PUnit} : theorem forM_eq_forM_keys [Monad m] [LawfulMonad m] {f : α → m PUnit} :
ForM.forM t (fun a => f a.1) = t.keys.forM f := ForM.forM t (fun a => f a.1) = t.keys.forM f :=
DTreeMap.forM_eq_forM_keys DTreeMap.forM_eq_forM_keys
theorem forM_eq_forM_keysArray [Monad m] [LawfulMonad m] {f : α → m PUnit} :
ForM.forM t (fun a => f a.1) = t.keysArray.forM f :=
DTreeMap.forM_eq_forM_keysArray
theorem forIn_eq_forIn_keys [Monad m] [LawfulMonad m] {f : α → δ → m (ForInStep δ)} {init : δ} : theorem forIn_eq_forIn_keys [Monad m] [LawfulMonad m] {f : α → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init (fun a d => f a.1 d) = ForIn.forIn t.keys init f := ForIn.forIn t init (fun a d => f a.1 d) = ForIn.forIn t.keys init f :=
DTreeMap.forIn_eq_forIn_keys DTreeMap.forIn_eq_forIn_keys
theorem forIn_eq_forIn_keysArray [Monad m] [LawfulMonad m] {f : α → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init (fun a d => f a.1 d) = ForIn.forIn t.keysArray init f :=
DTreeMap.forIn_eq_forIn_keysArray
end monadic end monadic
@[simp, grind =] @[simp, grind =]
@ -2901,6 +3026,10 @@ theorem minKey?_insertIfNew_le_self [TransCmp cmp] {k v kmi} :
t.minKey? = t.keys.head? := t.minKey? = t.keys.head? :=
DTreeMap.minKey?_eq_head?_keys DTreeMap.minKey?_eq_head?_keys
@[grind =_] theorem minKey?_eq_getElem?_keysArray [TransCmp cmp] :
t.minKey? = t.keysArray[0]? :=
DTreeMap.minKey?_eq_getElem?_keysArray
theorem minKey?_modify [TransCmp cmp] {k f} : theorem minKey?_modify [TransCmp cmp] {k f} :
(t.modify k f).minKey? = t.minKey?.map fun km => if cmp km k = .eq then k else km := (t.modify k f).minKey? = t.minKey?.map fun km => if cmp km k = .eq then k else km :=
DTreeMap.Const.minKey?_modify DTreeMap.Const.minKey?_modify
@ -3049,6 +3178,10 @@ theorem minKey_insertIfNew_le_self [TransCmp cmp] {k v} :
t.minKey he = t.keys.head (List.isEmpty_eq_false_iff.mp <| isEmpty_keys ▸ he) := t.minKey he = t.keys.head (List.isEmpty_eq_false_iff.mp <| isEmpty_keys ▸ he) :=
DTreeMap.minKey_eq_head_keys DTreeMap.minKey_eq_head_keys
theorem minKey_eq_getElem_keysArray [TransCmp cmp] {he} :
t.minKey he = t.keysArray[0]'(Nat.zero_lt_of_ne_zero (by simpa [size_keysArray, isEmpty_eq_size_eq_zero, - Array.size_eq_zero_iff] using he)) :=
DTreeMap.minKey_eq_getElem_keysArray
theorem minKey_modify [TransCmp cmp] {k f he} : theorem minKey_modify [TransCmp cmp] {k f he} :
(modify t k f).minKey he = (modify t k f).minKey he =
if cmp (t.minKey <| cast (congrArg (· = false) isEmpty_modify) he) k = .eq then if cmp (t.minKey <| cast (congrArg (· = false) isEmpty_modify) he) k = .eq then
@ -3184,6 +3317,10 @@ theorem minKey!_eq_head!_keys [TransCmp cmp] [Inhabited α] :
t.minKey! = t.keys.head! := t.minKey! = t.keys.head! :=
DTreeMap.minKey!_eq_head!_keys DTreeMap.minKey!_eq_head!_keys
theorem minKey!_eq_getElem!_keysArray [TransCmp cmp] [Inhabited α] :
t.minKey! = t.keysArray[0]! :=
DTreeMap.minKey!_eq_getElem!_keysArray
theorem minKey!_modify [TransCmp cmp] [Inhabited α] {k f} theorem minKey!_modify [TransCmp cmp] [Inhabited α] {k f}
(he : (modify t k f).isEmpty = false) : (he : (modify t k f).isEmpty = false) :
(modify t k f).minKey! = if cmp t.minKey! k = .eq then k else t.minKey! := (modify t k f).minKey! = if cmp t.minKey! k = .eq then k else t.minKey! :=
@ -3311,6 +3448,10 @@ theorem minKeyD_eq_headD_keys [TransCmp cmp] {fallback} :
t.minKeyD fallback = t.keys.headD fallback := t.minKeyD fallback = t.keys.headD fallback :=
DTreeMap.minKeyD_eq_headD_keys DTreeMap.minKeyD_eq_headD_keys
theorem minKeyD_eq_getD_keysArray [TransCmp cmp] {fallback} :
t.minKeyD fallback = t.keysArray.getD 0 fallback :=
DTreeMap.minKeyD_eq_getD_keysArray
theorem minKeyD_modify [TransCmp cmp] {k f} theorem minKeyD_modify [TransCmp cmp] {k f}
(he : (modify t k f).isEmpty = false) {fallback} : (he : (modify t k f).isEmpty = false) {fallback} :
(modify t k f |>.minKeyD fallback) = (modify t k f |>.minKeyD fallback) =
@ -3494,6 +3635,10 @@ theorem self_le_maxKey?_insertIfNew [TransCmp cmp] {k v kmi} :
t.maxKey? = t.keys.getLast? := t.maxKey? = t.keys.getLast? :=
DTreeMap.maxKey?_eq_getLast?_keys DTreeMap.maxKey?_eq_getLast?_keys
@[grind =_] theorem maxKey?_eq_back?_keysArray [TransCmp cmp] :
t.maxKey? = t.keysArray.back? :=
DTreeMap.maxKey?_eq_back?_keysArray
@[grind =] theorem maxKey?_modify [TransCmp cmp] {k f} : @[grind =] theorem maxKey?_modify [TransCmp cmp] {k f} :
(t.modify k f).maxKey? = t.maxKey?.map fun km => if cmp km k = .eq then k else km := (t.modify k f).maxKey? = t.maxKey?.map fun km => if cmp km k = .eq then k else km :=
DTreeMap.Const.maxKey?_modify DTreeMap.Const.maxKey?_modify
@ -3630,6 +3775,10 @@ theorem self_le_maxKey_insertIfNew [TransCmp cmp] {k v} :
t.maxKey he = t.keys.getLast (List.isEmpty_eq_false_iff.mp <| isEmpty_keys ▸ he) := t.maxKey he = t.keys.getLast (List.isEmpty_eq_false_iff.mp <| isEmpty_keys ▸ he) :=
DTreeMap.maxKey_eq_getLast_keys DTreeMap.maxKey_eq_getLast_keys
@[grind =_] theorem maxKey_eq_back_keysArray [TransCmp cmp] {he} :
t.maxKey he = t.keysArray.back (Nat.zero_lt_of_ne_zero (by simpa [size_keysArray, isEmpty_eq_size_eq_zero, - Array.size_eq_zero_iff] using he)) :=
DTreeMap.maxKey_eq_back_keysArray
theorem maxKey_modify [TransCmp cmp] {k f he} : theorem maxKey_modify [TransCmp cmp] {k f he} :
(modify t k f).maxKey he = (modify t k f).maxKey he =
if cmp (t.maxKey <| cast (congrArg (· = false) isEmpty_modify) he) k = .eq then if cmp (t.maxKey <| cast (congrArg (· = false) isEmpty_modify) he) k = .eq then
@ -3765,6 +3914,10 @@ theorem maxKey!_eq_getLast!_keys [TransCmp cmp] [Inhabited α] :
t.maxKey! = t.keys.getLast! := t.maxKey! = t.keys.getLast! :=
DTreeMap.maxKey!_eq_getLast!_keys DTreeMap.maxKey!_eq_getLast!_keys
theorem maxKey!_eq_back!_keysArray [TransCmp cmp] [Inhabited α] :
t.maxKey! = t.keysArray.back! :=
DTreeMap.maxKey!_eq_back!_keysArray
theorem maxKey!_modify [TransCmp cmp] [Inhabited α] {k f} theorem maxKey!_modify [TransCmp cmp] [Inhabited α] {k f}
(he : (modify t k f).isEmpty = false) : (he : (modify t k f).isEmpty = false) :
(modify t k f).maxKey! = if cmp t.maxKey! k = .eq then k else t.maxKey! := (modify t k f).maxKey! = if cmp t.maxKey! k = .eq then k else t.maxKey! :=
@ -3892,6 +4045,10 @@ theorem maxKeyD_eq_getLastD_keys [TransCmp cmp] {fallback} :
t.maxKeyD fallback = t.keys.getLastD fallback := t.maxKeyD fallback = t.keys.getLastD fallback :=
DTreeMap.maxKeyD_eq_getLastD_keys DTreeMap.maxKeyD_eq_getLastD_keys
theorem maxKeyD_eq_getD_back?_keysArray [TransCmp cmp] {fallback} :
t.maxKeyD fallback = t.keysArray.back?.getD fallback :=
DTreeMap.maxKeyD_eq_getD_back?_keysArray
theorem maxKeyD_modify [TransCmp cmp] {k f} theorem maxKeyD_modify [TransCmp cmp] {k f}
(he : (modify t k f).isEmpty = false) {fallback} : (he : (modify t k f).isEmpty = false) {fallback} :
(modify t k f |>.maxKeyD fallback) = (modify t k f |>.maxKeyD fallback) =
@ -4342,24 +4499,46 @@ theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList := theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList :=
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_toList_perm equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_toList_perm
theorem equiv_iff_toArray_perm : t₁ ~m t₂ ↔ t₁.toArray.Perm t₂.toArray :=
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_toArray_perm
theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ := theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ :=
⟨.of_constToList_perm h⟩ ⟨.of_constToList_perm h⟩
theorem Equiv.of_toArray_perm (h : t₁.toArray.Perm t₂.toArray) : t₁ ~m t₂ :=
⟨.of_constToArray_perm h⟩
theorem equiv_iff_toList_eq [TransCmp cmp] : theorem equiv_iff_toList_eq [TransCmp cmp] :
t₁ ~m t₂ ↔ t₁.toList = t₂.toList := t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_toList_eq equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_toList_eq
theorem equiv_iff_toArray_eq [TransCmp cmp] :
t₁ ~m t₂ ↔ t₁.toArray = t₂.toArray :=
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_toArray_eq
theorem equiv_iff_keys_unit_perm {t₁ t₂ : TreeMap α Unit cmp} : theorem equiv_iff_keys_unit_perm {t₁ t₂ : TreeMap α Unit cmp} :
t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys := t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys :=
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_keys_unit_perm equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_keys_unit_perm
theorem equiv_iff_keysArray_unit_perm {t₁ t₂ : TreeMap α Unit cmp} :
t₁ ~m t₂ ↔ t₁.keysArray.Perm t₂.keysArray :=
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_keysArray_unit_perm
theorem equiv_iff_keys_unit_eq [TransCmp cmp] {t₁ t₂ : TreeMap α Unit cmp} : theorem equiv_iff_keys_unit_eq [TransCmp cmp] {t₁ t₂ : TreeMap α Unit cmp} :
t₁ ~m t₂ ↔ t₁.keys = t₂.keys := t₁ ~m t₂ ↔ t₁.keys = t₂.keys :=
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_keys_unit_eq equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_keys_unit_eq
theorem equiv_iff_keysArray_unit_eq [TransCmp cmp] {t₁ t₂ : TreeMap α Unit cmp} :
t₁ ~m t₂ ↔ t₁.keysArray = t₂.keysArray :=
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_keysArray_unit_eq
theorem Equiv.of_keys_unit_perm {t₁ t₂ : TreeMap α Unit cmp} : t₁.keys.Perm t₂.keys → t₁ ~m t₂ := theorem Equiv.of_keys_unit_perm {t₁ t₂ : TreeMap α Unit cmp} : t₁.keys.Perm t₂.keys → t₁ ~m t₂ :=
equiv_iff_keys_unit_perm.mpr equiv_iff_keys_unit_perm.mpr
theorem Equiv.of_keysArray_unit_perm {t₁ t₂ : TreeMap α Unit cmp} :
t₁.keysArray.Perm t₂.keysArray → t₁ ~m t₂ :=
equiv_iff_keysArray_unit_perm.mpr
theorem insertMany_list_equiv_foldl {l : List (α × β)} : theorem insertMany_list_equiv_foldl {l : List (α × β)} :
insertMany t₁ l ~m l.foldl (init := t₁) (fun acc p => acc.insert p.1 p.2) := by insertMany t₁ l ~m l.foldl (init := t₁) (fun acc p => acc.insert p.1 p.2) := by
constructor constructor
@ -4394,6 +4573,12 @@ theorem toList_filterMap {f : (a : α) → β → Option γ} :
t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x))) := t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x))) :=
DTreeMap.Const.toList_filterMap DTreeMap.Const.toList_filterMap
@[simp, grind =]
theorem toArray_filterMap {f : α → β → Option γ} :
(t.filterMap f).toArray =
t.toArray.filterMap (fun p => (f p.1 p.2).map (fun x => (p.1, x))) :=
DTreeMap.Const.toArray_filterMap
@[grind =] @[grind =]
theorem isEmpty_filterMap_iff [TransCmp cmp] theorem isEmpty_filterMap_iff [TransCmp cmp]
{f : α → β → Option γ} : {f : α → β → Option γ} :
@ -4561,10 +4746,19 @@ theorem toList_filter {f : α → β → Bool} :
(t.filter f).toList = t.toList.filter (fun p => f p.1 p.2) := (t.filter f).toList = t.toList.filter (fun p => f p.1 p.2) :=
DTreeMap.Const.toList_filter DTreeMap.Const.toList_filter
@[simp, grind =]
theorem toArray_filter {f : α → β → Bool} :
(t.filter f).toArray = t.toArray.filter (fun p => f p.1 p.2) :=
DTreeMap.Const.toArray_filter
theorem keys_filter_key {f : α → Bool} : theorem keys_filter_key {f : α → Bool} :
(t.filter fun k _ => f k).keys = t.keys.filter f := (t.filter fun k _ => f k).keys = t.keys.filter f :=
DTreeMap.keys_filter_key DTreeMap.keys_filter_key
theorem keysArray_filter_key {f : α → Bool} :
(t.filter fun k _ => f k).keysArray = t.keysArray.filter f :=
DTreeMap.keysArray_filter_key
@[grind =] @[grind =]
theorem isEmpty_filter_iff [TransCmp cmp] theorem isEmpty_filter_iff [TransCmp cmp]
{f : α → β → Bool} : {f : α → β → Bool} :
@ -4748,10 +4942,19 @@ theorem toList_map {f : α → β → γ} :
(t.map f).toList = t.toList.map (fun p => (p.1, f p.1 p.2)) := (t.map f).toList = t.toList.map (fun p => (p.1, f p.1 p.2)) :=
DTreeMap.Const.toList_map DTreeMap.Const.toList_map
@[simp, grind =]
theorem toArray_map {f : α → β → γ} :
(t.map f).toArray = t.toArray.map (fun p => (p.1, f p.1 p.2)) :=
DTreeMap.Const.toArray_map
@[simp, grind =] @[simp, grind =]
theorem keys_map {f : α → β → γ} : (t.map f).keys = t.keys := theorem keys_map {f : α → β → γ} : (t.map f).keys = t.keys :=
DTreeMap.keys_map DTreeMap.keys_map
@[simp, grind =]
theorem keysArray_map {f : α → β → γ} : (t.map f).keysArray = t.keysArray :=
DTreeMap.keysArray_map
theorem filterMap_equiv_map [TransCmp cmp] theorem filterMap_equiv_map [TransCmp cmp]
{f : α → β → γ} : {f : α → β → γ} :
(t.filterMap (fun k v => some (f k v))) ~m t.map f := (t.filterMap (fun k v => some (f k v))) ~m t.map f :=
@ -4891,4 +5094,16 @@ theorem getKeyD_map [TransCmp cmp]
end map end map
theorem toArray_toList : t.toList.toArray = t.toArray :=
DTreeMap.Const.toArray_toList
theorem toList_toArray : t.toArray.toList = t.toList :=
DTreeMap.Const.toList_toArray
theorem toArray_keys : t.keys.toArray = t.keysArray :=
DTreeMap.toArray_keys
theorem toList_keysArray : t.keysArray.toList = t.keys :=
DTreeMap.toList_keysArray
end Std.TreeMap end Std.TreeMap

View file

@ -8,6 +8,7 @@ module
prelude prelude
import Std.Data.DTreeMap.Raw.Lemmas import Std.Data.DTreeMap.Raw.Lemmas
public import Std.Data.TreeMap.Raw.AdditionalOperations public import Std.Data.TreeMap.Raw.AdditionalOperations
public import Init.Data.Array.Perm
import Init.Data.List.Find import Init.Data.List.Find
import Init.Data.List.Impl import Init.Data.List.Impl
import Init.Data.List.Pairwise import Init.Data.List.Pairwise
@ -293,10 +294,18 @@ theorem toList_insert_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] (h : t.WF)
(t.insert k v).toList.Perm (⟨k, v⟩ :: t.toList.filter (¬k == ·.1)) := (t.insert k v).toList.Perm (⟨k, v⟩ :: t.toList.filter (¬k == ·.1)) :=
DTreeMap.Raw.Const.toList_insert_perm h DTreeMap.Raw.Const.toList_insert_perm h
theorem toArray_insert_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] (h : t.WF) {k : α} {v : β} :
(t.insert k v).toArray.Perm ((t.toArray.filter (¬k == ·.1)).push ⟨k, v⟩) :=
DTreeMap.Raw.Const.toArray_insert_perm h
theorem keys_insertIfNew_perm {t : Raw α Unit cmp} [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] (h : t.WF) {k : α} : theorem keys_insertIfNew_perm {t : Raw α Unit cmp} [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] (h : t.WF) {k : α} :
(t.insertIfNew k ()).keys.Perm (if k ∈ t then t.keys else k :: t.keys) := (t.insertIfNew k ()).keys.Perm (if k ∈ t then t.keys else k :: t.keys) :=
DTreeMap.Raw.keys_insertIfNew_perm h DTreeMap.Raw.keys_insertIfNew_perm h
theorem keysArray_insertIfNew_perm {t : Raw α Unit cmp} [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] (h : t.WF) {k : α} :
(t.insertIfNew k ()).keysArray.Perm (if k ∈ t then t.keysArray else t.keysArray.push k) :=
DTreeMap.Raw.keysArray_insertIfNew_perm h
@[simp] @[simp]
theorem getElem_insert_self [TransCmp cmp] (h : t.WF) {k : α} {v : β} : theorem getElem_insert_self [TransCmp cmp] (h : t.WF) {k : α} {v : β} :
(t.insert k v)[k]'(mem_insert_self h) = v := (t.insert k v)[k]'(mem_insert_self h) = v :=
@ -806,25 +815,49 @@ theorem length_keys [TransCmp cmp] (h : t.WF) :
t.keys.length = t.size := t.keys.length = t.size :=
DTreeMap.Raw.length_keys h DTreeMap.Raw.length_keys h
@[simp, grind =]
theorem size_keysArray [TransCmp cmp] (h : t.WF) :
t.keysArray.size = t.size :=
DTreeMap.Raw.size_keysArray h
@[simp, grind =] @[simp, grind =]
theorem isEmpty_keys : theorem isEmpty_keys :
t.keys.isEmpty = t.isEmpty := t.keys.isEmpty = t.isEmpty :=
DTreeMap.Raw.isEmpty_keys DTreeMap.Raw.isEmpty_keys
@[simp, grind =]
theorem isEmpty_keysArray :
t.keysArray.isEmpty = t.isEmpty :=
DTreeMap.Raw.isEmpty_keysArray
@[simp, grind =] @[simp, grind =]
theorem contains_keys [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} : theorem contains_keys [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} :
t.keys.contains k = t.contains k := t.keys.contains k = t.contains k :=
DTreeMap.Raw.contains_keys h DTreeMap.Raw.contains_keys h
@[simp, grind =]
theorem contains_keysArray [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} :
t.keysArray.contains k = t.contains k :=
DTreeMap.Raw.contains_keysArray h
@[simp, grind =] @[simp, grind =]
theorem mem_keys [LawfulEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} : theorem mem_keys [LawfulEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.keys ↔ k ∈ t := k ∈ t.keys ↔ k ∈ t :=
DTreeMap.Raw.mem_keys h DTreeMap.Raw.mem_keys h
@[simp, grind =]
theorem mem_keysArray [LawfulEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.keysArray ↔ k ∈ t :=
DTreeMap.Raw.mem_keysArray h
theorem mem_of_mem_keys [TransCmp cmp] (h : t.WF) {k : α} : theorem mem_of_mem_keys [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.keys → k ∈ t := k ∈ t.keys → k ∈ t :=
DTreeMap.Raw.mem_of_mem_keys h DTreeMap.Raw.mem_of_mem_keys h
theorem mem_of_mem_keysArray [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.keysArray → k ∈ t :=
DTreeMap.Raw.mem_of_mem_keysArray h
theorem distinct_keys [TransCmp cmp] (h : t.WF) : theorem distinct_keys [TransCmp cmp] (h : t.WF) :
t.keys.Pairwise (fun a b => ¬ cmp a b = .eq) := t.keys.Pairwise (fun a b => ¬ cmp a b = .eq) :=
DTreeMap.Raw.distinct_keys h DTreeMap.Raw.distinct_keys h
@ -842,46 +875,91 @@ theorem map_fst_toList_eq_keys :
(toList t).map Prod.fst = t.keys := (toList t).map Prod.fst = t.keys :=
DTreeMap.Raw.Const.map_fst_toList_eq_keys DTreeMap.Raw.Const.map_fst_toList_eq_keys
@[simp, grind _=_]
theorem map_fst_toArray_eq_keysArray :
(toArray t).map Prod.fst = t.keysArray :=
DTreeMap.Raw.Const.map_fst_toArray_eq_keysArray
@[simp, grind =] @[simp, grind =]
theorem length_toList (h : t.WF) : theorem length_toList (h : t.WF) :
(toList t).length = t.size := (toList t).length = t.size :=
DTreeMap.Raw.Const.length_toList h DTreeMap.Raw.Const.length_toList h
@[simp, grind =]
theorem size_toArray (h : t.WF) :
(toArray t).size = t.size :=
DTreeMap.Raw.Const.size_toArray h
@[simp, grind =] @[simp, grind =]
theorem isEmpty_toList : theorem isEmpty_toList :
(toList t).isEmpty = t.isEmpty := (toList t).isEmpty = t.isEmpty :=
DTreeMap.Raw.Const.isEmpty_toList DTreeMap.Raw.Const.isEmpty_toList
@[simp, grind =]
theorem isEmpty_toArray :
(toArray t).isEmpty = t.isEmpty :=
DTreeMap.Raw.Const.isEmpty_toArray
@[simp, grind =] @[simp, grind =]
theorem mem_toList_iff_getElem?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k : α} {v : β} : theorem mem_toList_iff_getElem?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k : α} {v : β} :
(k, v) ∈ toList t ↔ t[k]? = some v := (k, v) ∈ toList t ↔ t[k]? = some v :=
DTreeMap.Raw.Const.mem_toList_iff_get?_eq_some h DTreeMap.Raw.Const.mem_toList_iff_get?_eq_some h
@[simp, grind =]
theorem mem_toArray_iff_getElem?_eq_some [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k : α} {v : β} :
(k, v) ∈ toArray t ↔ t[k]? = some v :=
DTreeMap.Raw.Const.mem_toArray_iff_get?_eq_some h
@[simp] @[simp]
theorem mem_toList_iff_getKey?_eq_some_and_getElem?_eq_some [TransCmp cmp] (h : t.WF) {k : α} {v : β} : theorem mem_toList_iff_getKey?_eq_some_and_getElem?_eq_some [TransCmp cmp] (h : t.WF) {k : α} {v : β} :
(k, v) ∈ toList t ↔ t.getKey? k = some k ∧ t[k]? = some v := (k, v) ∈ toList t ↔ t.getKey? k = some k ∧ t[k]? = some v :=
DTreeMap.Raw.Const.mem_toList_iff_getKey?_eq_some_and_get?_eq_some h DTreeMap.Raw.Const.mem_toList_iff_getKey?_eq_some_and_get?_eq_some h
@[simp]
theorem mem_toArray_iff_getKey?_eq_some_and_getElem?_eq_some [TransCmp cmp] (h : t.WF) {k : α} {v : β} :
(k, v) ∈ toArray t ↔ t.getKey? k = some k ∧ t[k]? = some v :=
DTreeMap.Raw.Const.mem_toArray_iff_getKey?_eq_some_and_get?_eq_some h
theorem getElem?_eq_some_iff_exists_compare_eq_eq_and_mem_toList [TransCmp cmp] (h : t.WF) {k : α} theorem getElem?_eq_some_iff_exists_compare_eq_eq_and_mem_toList [TransCmp cmp] (h : t.WF) {k : α}
{v : β} : {v : β} :
t[k]? = some v ↔ ∃ (k' : α), cmp k k' = .eq ∧ (k', v) ∈ toList t := t[k]? = some v ↔ ∃ (k' : α), cmp k k' = .eq ∧ (k', v) ∈ toList t :=
DTreeMap.Raw.Const.get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList h DTreeMap.Raw.Const.get?_eq_some_iff_exists_compare_eq_eq_and_mem_toList h
theorem getElem?_eq_some_iff_exists_compare_eq_eq_and_mem_toArray [TransCmp cmp] (h : t.WF) {k : α}
{v : β} :
t[k]? = some v ↔ ∃ (k' : α), cmp k k' = .eq ∧ (k', v) ∈ toArray t :=
DTreeMap.Raw.Const.get?_eq_some_iff_exists_compare_eq_eq_and_mem_toArray h
theorem find?_toList_eq_some_iff_getKey?_eq_some_and_getElem?_eq_some [TransCmp cmp] (h : t.WF) theorem find?_toList_eq_some_iff_getKey?_eq_some_and_getElem?_eq_some [TransCmp cmp] (h : t.WF)
{k k' : α} {v : β} : {k k' : α} {v : β} :
t.toList.find? (cmp ·.1 k == .eq) = some ⟨k', v⟩ ↔ t.toList.find? (cmp ·.1 k == .eq) = some ⟨k', v⟩ ↔
t.getKey? k = some k' ∧ t[k]? = some v := t.getKey? k = some k' ∧ t[k]? = some v :=
DTreeMap.Raw.Const.find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some h DTreeMap.Raw.Const.find?_toList_eq_some_iff_getKey?_eq_some_and_get?_eq_some h
theorem find?_toArray_eq_some_iff_getKey?_eq_some_and_getElem?_eq_some [TransCmp cmp] (h : t.WF)
{k k' : α} {v : β} :
t.toArray.find? (cmp ·.1 k == .eq) = some ⟨k', v⟩ ↔
t.getKey? k = some k' ∧ t[k]? = some v :=
DTreeMap.Raw.Const.find?_toArray_eq_some_iff_getKey?_eq_some_and_get?_eq_some h
theorem find?_toList_eq_none_iff_contains_eq_false [TransCmp cmp] (h : t.WF) {k : α} : theorem find?_toList_eq_none_iff_contains_eq_false [TransCmp cmp] (h : t.WF) {k : α} :
(toList t).find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false := (toList t).find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false :=
DTreeMap.Raw.Const.find?_toList_eq_none_iff_contains_eq_false h DTreeMap.Raw.Const.find?_toList_eq_none_iff_contains_eq_false h
theorem find?_toArray_eq_none_iff_contains_eq_false [TransCmp cmp] (h : t.WF) {k : α} :
(toArray t).find? (cmp ·.1 k == .eq) = none ↔ t.contains k = false :=
DTreeMap.Raw.Const.find?_toArray_eq_none_iff_contains_eq_false h
@[simp] @[simp]
theorem find?_toList_eq_none_iff_not_mem [TransCmp cmp] (h : t.WF) {k : α} : theorem find?_toList_eq_none_iff_not_mem [TransCmp cmp] (h : t.WF) {k : α} :
(toList t).find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t := (toList t).find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t :=
DTreeMap.Raw.Const.find?_toList_eq_none_iff_not_mem h DTreeMap.Raw.Const.find?_toList_eq_none_iff_not_mem h
@[simp]
theorem find?_toArray_eq_none_iff_not_mem [TransCmp cmp] (h : t.WF) {k : α} :
(toArray t).find? (cmp ·.1 k == .eq) = none ↔ ¬ k ∈ t :=
DTreeMap.Raw.Const.find?_toArray_eq_none_iff_not_mem h
theorem distinct_keys_toList [TransCmp cmp] (h : t.WF) : theorem distinct_keys_toList [TransCmp cmp] (h : t.WF) :
(toList t).Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq) := (toList t).Pairwise (fun a b => ¬ cmp a.1 b.1 = .eq) :=
DTreeMap.Raw.Const.distinct_keys_toList h DTreeMap.Raw.Const.distinct_keys_toList h
@ -898,18 +976,34 @@ theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m] {f : δ → α → β
t.foldlM f init = t.toList.foldlM (fun a b => f a b.1 b.2) init := t.foldlM f init = t.toList.foldlM (fun a b => f a b.1 b.2) init :=
DTreeMap.Raw.Const.foldlM_eq_foldlM_toList DTreeMap.Raw.Const.foldlM_eq_foldlM_toList
theorem foldlM_eq_foldlM_toArray [Monad m] [LawfulMonad m] {f : δ → α → β → m δ} {init : δ} :
t.foldlM f init = t.toArray.foldlM (fun a b => f a b.1 b.2) init :=
DTreeMap.Raw.Const.foldlM_eq_foldlM_toArray
theorem foldl_eq_foldl_toList {f : δ → α → β → δ} {init : δ} : theorem foldl_eq_foldl_toList {f : δ → α → β → δ} {init : δ} :
t.foldl f init = t.toList.foldl (fun a b => f a b.1 b.2) init := t.foldl f init = t.toList.foldl (fun a b => f a b.1 b.2) init :=
DTreeMap.Raw.Const.foldl_eq_foldl_toList DTreeMap.Raw.Const.foldl_eq_foldl_toList
theorem foldl_eq_foldl_toArray {f : δ → α → β → δ} {init : δ} :
t.foldl f init = t.toArray.foldl (fun a b => f a b.1 b.2) init :=
DTreeMap.Raw.Const.foldl_eq_foldl_toArray
theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] {f : α → β → δ → m δ} {init : δ} : theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] {f : α → β → δ → m δ} {init : δ} :
t.foldrM f init = t.toList.foldrM (fun a b => f a.1 a.2 b) init := t.foldrM f init = t.toList.foldrM (fun a b => f a.1 a.2 b) init :=
DTreeMap.Raw.Const.foldrM_eq_foldrM_toList DTreeMap.Raw.Const.foldrM_eq_foldrM_toList
theorem foldrM_eq_foldrM_toArray [Monad m] [LawfulMonad m] {f : α → β → δ → m δ} {init : δ} :
t.foldrM f init = t.toArray.foldrM (fun a b => f a.1 a.2 b) init :=
DTreeMap.Raw.Const.foldrM_eq_foldrM_toArray
theorem foldr_eq_foldr_toList {f : α → β → δ → δ} {init : δ} : theorem foldr_eq_foldr_toList {f : α → β → δ → δ} {init : δ} :
t.foldr f init = t.toList.foldr (fun a b => f a.1 a.2 b) init := t.foldr f init = t.toList.foldr (fun a b => f a.1 a.2 b) init :=
DTreeMap.Raw.Const.foldr_eq_foldr_toList DTreeMap.Raw.Const.foldr_eq_foldr_toList
theorem foldr_eq_foldr_toArray {f : α → β → δ → δ} {init : δ} :
t.foldr f init = t.toArray.foldr (fun a b => f a.1 a.2 b) init :=
DTreeMap.Raw.Const.foldr_eq_foldr_toArray
@[simp, grind =] @[simp, grind =]
theorem forM_eq_forM [Monad m] [LawfulMonad m] {f : α → β → m PUnit} : theorem forM_eq_forM [Monad m] [LawfulMonad m] {f : α → β → m PUnit} :
t.forM f = ForM.forM t (fun a => f a.1 a.2) := rfl t.forM f = ForM.forM t (fun a => f a.1 a.2) := rfl
@ -918,6 +1012,10 @@ theorem forM_eq_forM_toList [Monad m] [LawfulMonad m] {f : α × β → m PUnit}
ForM.forM t f = t.toList.forM f := ForM.forM t f = t.toList.forM f :=
DTreeMap.Raw.Const.forMUncurried_eq_forM_toList (f := f) DTreeMap.Raw.Const.forMUncurried_eq_forM_toList (f := f)
theorem forM_eq_forM_toArray [Monad m] [LawfulMonad m] {f : α × β → m PUnit} :
ForM.forM t f = t.toArray.forM f :=
DTreeMap.Raw.Const.forMUncurried_eq_forM_toArray (f := f)
@[simp, grind =] @[simp, grind =]
theorem forIn_eq_forIn [Monad m] [LawfulMonad m] {f : α → β → δ → m (ForInStep δ)} {init : δ} : theorem forIn_eq_forIn [Monad m] [LawfulMonad m] {f : α → β → δ → m (ForInStep δ)} {init : δ} :
t.forIn f init = ForIn.forIn t init (fun a d => f a.1 a.2 d) := rfl t.forIn f init = ForIn.forIn t init (fun a d => f a.1 a.2 d) := rfl
@ -927,31 +1025,61 @@ theorem forIn_eq_forIn_toList [Monad m] [LawfulMonad m]
ForIn.forIn t init f = ForIn.forIn t.toList init f := ForIn.forIn t init f = ForIn.forIn t.toList init f :=
DTreeMap.Raw.Const.forInUncurried_eq_forIn_toList DTreeMap.Raw.Const.forInUncurried_eq_forIn_toList
theorem forIn_eq_forIn_toArray [Monad m] [LawfulMonad m]
{f : α × β → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init f = ForIn.forIn t.toArray init f :=
DTreeMap.Raw.Const.forInUncurried_eq_forIn_toArray
theorem foldlM_eq_foldlM_keys [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} : theorem foldlM_eq_foldlM_keys [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} :
t.foldlM (fun d a _ => f d a) init = t.keys.foldlM f init := t.foldlM (fun d a _ => f d a) init = t.keys.foldlM f init :=
DTreeMap.Raw.foldlM_eq_foldlM_keys DTreeMap.Raw.foldlM_eq_foldlM_keys
theorem foldlM_eq_foldlM_keysArray [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} :
t.foldlM (fun d a _ => f d a) init = t.keysArray.foldlM f init :=
DTreeMap.Raw.foldlM_eq_foldlM_keysArray
theorem foldl_eq_foldl_keys {f : δ → α → δ} {init : δ} : theorem foldl_eq_foldl_keys {f : δ → α → δ} {init : δ} :
t.foldl (fun d a _ => f d a) init = t.keys.foldl f init := t.foldl (fun d a _ => f d a) init = t.keys.foldl f init :=
DTreeMap.Raw.foldl_eq_foldl_keys DTreeMap.Raw.foldl_eq_foldl_keys
theorem foldl_eq_foldl_keysArray {f : δ → α → δ} {init : δ} :
t.foldl (fun d a _ => f d a) init = t.keysArray.foldl f init :=
DTreeMap.Raw.foldl_eq_foldl_keysArray
theorem foldrM_eq_foldrM_keys [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} : theorem foldrM_eq_foldrM_keys [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} :
t.foldrM (fun a _ d => f a d) init = t.keys.foldrM f init := t.foldrM (fun a _ d => f a d) init = t.keys.foldrM f init :=
DTreeMap.Raw.foldrM_eq_foldrM_keys DTreeMap.Raw.foldrM_eq_foldrM_keys
theorem foldrM_eq_foldrM_keysArray [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} :
t.foldrM (fun a _ d => f a d) init = t.keysArray.foldrM f init :=
DTreeMap.Raw.foldrM_eq_foldrM_keysArray
theorem foldr_eq_foldr_keys {f : α → δ → δ} {init : δ} : theorem foldr_eq_foldr_keys {f : α → δ → δ} {init : δ} :
t.foldr (fun a _ d => f a d) init = t.keys.foldr f init := t.foldr (fun a _ d => f a d) init = t.keys.foldr f init :=
DTreeMap.Raw.foldr_eq_foldr_keys DTreeMap.Raw.foldr_eq_foldr_keys
theorem foldr_eq_foldr_keysArray {f : α → δ → δ} {init : δ} :
t.foldr (fun a _ d => f a d) init = t.keysArray.foldr f init :=
DTreeMap.Raw.foldr_eq_foldr_keysArray
theorem forM_eq_forM_keys [Monad m] [LawfulMonad m] {f : α → m PUnit} : theorem forM_eq_forM_keys [Monad m] [LawfulMonad m] {f : α → m PUnit} :
ForM.forM t (fun a => f a.1) = t.keys.forM f := ForM.forM t (fun a => f a.1) = t.keys.forM f :=
DTreeMap.Raw.forM_eq_forM_keys DTreeMap.Raw.forM_eq_forM_keys
theorem forM_eq_forM_keysArray [Monad m] [LawfulMonad m] {f : α → m PUnit} :
ForM.forM t (fun a => f a.1) = t.keysArray.forM f :=
DTreeMap.Raw.forM_eq_forM_keysArray
theorem forIn_eq_forIn_keys [Monad m] [LawfulMonad m] theorem forIn_eq_forIn_keys [Monad m] [LawfulMonad m]
{f : α → δ → m (ForInStep δ)} {init : δ} : {f : α → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init (fun a d => f a.1 d) = ForIn.forIn t.keys init f := ForIn.forIn t init (fun a d => f a.1 d) = ForIn.forIn t.keys init f :=
DTreeMap.Raw.forIn_eq_forIn_keys DTreeMap.Raw.forIn_eq_forIn_keys
theorem forIn_eq_forIn_keysArray [Monad m] [LawfulMonad m]
{f : α → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init (fun a d => f a.1 d) = ForIn.forIn t.keysArray init f :=
DTreeMap.Raw.forIn_eq_forIn_keysArray
end monadic end monadic
@[simp, grind =] @[simp, grind =]
@ -2961,6 +3089,10 @@ theorem minKey?_eq_head?_keys [TransCmp cmp] (h : t.WF) :
t.minKey? = t.keys.head? := t.minKey? = t.keys.head? :=
DTreeMap.Raw.minKey?_eq_head?_keys h DTreeMap.Raw.minKey?_eq_head?_keys h
theorem minKey?_eq_getElem?_keysArray [TransCmp cmp] (h : t.WF) :
t.minKey? = t.keysArray[0]? :=
DTreeMap.Raw.minKey?_eq_getElem?_keysArray h
@[grind =] @[grind =]
theorem minKey?_modify [TransCmp cmp] (h : t.WF) {k f} : theorem minKey?_modify [TransCmp cmp] (h : t.WF) {k f} :
(t.modify k f).minKey? = t.minKey?.map fun km => if cmp km k = .eq then k else km := (t.modify k f).minKey? = t.minKey?.map fun km => if cmp km k = .eq then k else km :=
@ -3102,6 +3234,10 @@ theorem minKey!_insertIfNew_le_self [TransCmp cmp] [Inhabited α] (h : t.WF) {k
t.minKey! = t.keys.head! := t.minKey! = t.keys.head! :=
DTreeMap.Raw.minKey!_eq_head!_keys h DTreeMap.Raw.minKey!_eq_head!_keys h
theorem minKey!_eq_getElem!_keysArray [TransCmp cmp] [Inhabited α] (h : t.WF) :
t.minKey! = t.keysArray[0]! :=
DTreeMap.Raw.minKey!_eq_getElem!_keysArray h
theorem minKey!_modify [TransCmp cmp] [Inhabited α] (h : t.WF) {k f} theorem minKey!_modify [TransCmp cmp] [Inhabited α] (h : t.WF) {k f}
(he : (modify t k f).isEmpty = false) : (he : (modify t k f).isEmpty = false) :
(modify t k f).minKey! = if cmp t.minKey! k = .eq then k else t.minKey! := (modify t k f).minKey! = if cmp t.minKey! k = .eq then k else t.minKey! :=
@ -3229,6 +3365,10 @@ theorem minKeyD_eq_headD_keys [TransCmp cmp] (h : t.WF) {fallback} :
t.minKeyD fallback = t.keys.headD fallback := t.minKeyD fallback = t.keys.headD fallback :=
DTreeMap.Raw.minKeyD_eq_headD_keys h DTreeMap.Raw.minKeyD_eq_headD_keys h
theorem minKeyD_eq_getD_keysArray [TransCmp cmp] (h : t.WF) {fallback} :
t.minKeyD fallback = t.keysArray.getD 0 fallback :=
DTreeMap.Raw.minKeyD_eq_getD_keysArray h
theorem minKeyD_modify [TransCmp cmp] (h : t.WF) {k f} theorem minKeyD_modify [TransCmp cmp] (h : t.WF) {k f}
(he : (modify t k f).isEmpty = false) {fallback} : (he : (modify t k f).isEmpty = false) {fallback} :
(modify t k f |>.minKeyD fallback) = (modify t k f |>.minKeyD fallback) =
@ -3414,6 +3554,11 @@ theorem self_le_maxKey?_insertIfNew [TransCmp cmp] (h : t.WF) {k v kmi} :
t.maxKey? = t.keys.getLast? := t.maxKey? = t.keys.getLast? :=
DTreeMap.Raw.maxKey?_eq_getLast?_keys h DTreeMap.Raw.maxKey?_eq_getLast?_keys h
@[grind =_]
theorem maxKey?_eq_back?_keysArray [TransCmp cmp] (h : t.WF) :
t.maxKey? = t.keysArray.back? :=
DTreeMap.Raw.maxKey?_eq_back?_keysArray h
theorem maxKey?_modify [TransCmp cmp] (h : t.WF) {k f} : theorem maxKey?_modify [TransCmp cmp] (h : t.WF) {k f} :
(t.modify k f).maxKey? = t.maxKey?.map fun km => if cmp km k = .eq then k else km := (t.modify k f).maxKey? = t.maxKey?.map fun km => if cmp km k = .eq then k else km :=
DTreeMap.Raw.Const.maxKey?_modify h DTreeMap.Raw.Const.maxKey?_modify h
@ -3542,6 +3687,10 @@ theorem maxKey!_eq_getLast!_keys [TransCmp cmp] [Inhabited α] (h : t.WF) :
t.maxKey! = t.keys.getLast! := t.maxKey! = t.keys.getLast! :=
DTreeMap.Raw.maxKey!_eq_getLast!_keys h DTreeMap.Raw.maxKey!_eq_getLast!_keys h
theorem maxKey!_eq_back!_keysArray [TransCmp cmp] [Inhabited α] (h : t.WF) :
t.maxKey! = t.keysArray.back! :=
DTreeMap.Raw.maxKey!_eq_back!_keysArray h
theorem maxKey!_modify [TransCmp cmp] [Inhabited α] (h : t.WF) {k f} theorem maxKey!_modify [TransCmp cmp] [Inhabited α] (h : t.WF) {k f}
(he : (modify t k f).isEmpty = false) : (he : (modify t k f).isEmpty = false) :
(modify t k f).maxKey! = if cmp t.maxKey! k = .eq then k else t.maxKey! := (modify t k f).maxKey! = if cmp t.maxKey! k = .eq then k else t.maxKey! :=
@ -3669,6 +3818,10 @@ theorem maxKeyD_eq_getLastD_keys [TransCmp cmp] (h : t.WF) {fallback} :
t.maxKeyD fallback = t.keys.getLastD fallback := t.maxKeyD fallback = t.keys.getLastD fallback :=
DTreeMap.Raw.maxKeyD_eq_getLastD_keys h DTreeMap.Raw.maxKeyD_eq_getLastD_keys h
theorem maxKeyD_eq_getD_back?_keysArray [TransCmp cmp] (h : t.WF) {fallback} :
t.maxKeyD fallback = t.keysArray.back?.getD fallback :=
DTreeMap.Raw.maxKeyD_eq_getD_back?_keysArray h
theorem maxKeyD_modify [TransCmp cmp] (h : t.WF) {k f} theorem maxKeyD_modify [TransCmp cmp] (h : t.WF) {k f}
(he : (modify t k f).isEmpty = false) {fallback} : (he : (modify t k f).isEmpty = false) {fallback} :
(modify t k f |>.maxKeyD fallback) = (modify t k f |>.maxKeyD fallback) =
@ -4087,24 +4240,46 @@ theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList := theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList :=
equiv_iff.trans DTreeMap.Raw.Const.equiv_iff_toList_perm equiv_iff.trans DTreeMap.Raw.Const.equiv_iff_toList_perm
theorem equiv_iff_toArray_perm : t₁ ~m t₂ ↔ t₁.toArray.Perm t₂.toArray :=
equiv_iff.trans DTreeMap.Raw.Const.equiv_iff_toArray_perm
theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ := theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ :=
⟨.of_constToList_perm h⟩ ⟨.of_constToList_perm h⟩
theorem Equiv.of_toArray_perm (h : t₁.toArray.Perm t₂.toArray) : t₁ ~m t₂ :=
⟨.of_constToArray_perm h⟩
theorem equiv_iff_toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) : theorem equiv_iff_toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ t₁.toList = t₂.toList := t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
equiv_iff.trans (DTreeMap.Raw.Const.equiv_iff_toList_eq h₁.1 h₂.1) equiv_iff.trans (DTreeMap.Raw.Const.equiv_iff_toList_eq h₁.1 h₂.1)
theorem equiv_iff_toArray_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ t₁.toArray = t₂.toArray :=
equiv_iff.trans (DTreeMap.Raw.Const.equiv_iff_toArray_eq h₁.1 h₂.1)
theorem equiv_iff_keys_unit_perm {t₁ t₂ : Raw α Unit cmp} : theorem equiv_iff_keys_unit_perm {t₁ t₂ : Raw α Unit cmp} :
t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys := t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys :=
equiv_iff.trans DTreeMap.Raw.Const.equiv_iff_keys_unit_perm equiv_iff.trans DTreeMap.Raw.Const.equiv_iff_keys_unit_perm
theorem equiv_iff_keysArray_unit_perm {t₁ t₂ : Raw α Unit cmp} :
t₁ ~m t₂ ↔ t₁.keysArray.Perm t₂.keysArray :=
equiv_iff.trans DTreeMap.Raw.Const.equiv_iff_keysArray_unit_perm
theorem equiv_iff_keys_unit_eq {t₁ t₂ : Raw α Unit cmp} [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) : theorem equiv_iff_keys_unit_eq {t₁ t₂ : Raw α Unit cmp} [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ t₁.keys = t₂.keys := t₁ ~m t₂ ↔ t₁.keys = t₂.keys :=
equiv_iff.trans (DTreeMap.Raw.Const.equiv_iff_keys_unit_eq h₁.1 h₂.1) equiv_iff.trans (DTreeMap.Raw.Const.equiv_iff_keys_unit_eq h₁.1 h₂.1)
theorem equiv_iff_keysArray_unit_eq {t₁ t₂ : Raw α Unit cmp} [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ t₁.keysArray = t₂.keysArray :=
equiv_iff.trans (DTreeMap.Raw.Const.equiv_iff_keysArray_unit_eq h₁.1 h₂.1)
theorem Equiv.of_keys_unit_perm {t₁ t₂ : Raw α Unit cmp} : t₁.keys.Perm t₂.keys → t₁ ~m t₂ := theorem Equiv.of_keys_unit_perm {t₁ t₂ : Raw α Unit cmp} : t₁.keys.Perm t₂.keys → t₁ ~m t₂ :=
equiv_iff_keys_unit_perm.mpr equiv_iff_keys_unit_perm.mpr
theorem Equiv.of_keysArray_unit_perm {t₁ t₂ : Raw α Unit cmp} :
t₁.keysArray.Perm t₂.keysArray → t₁ ~m t₂ :=
equiv_iff_keysArray_unit_perm.mpr
theorem insertMany_list_equiv_foldl {l : List (α × β)} : theorem insertMany_list_equiv_foldl {l : List (α × β)} :
insertMany t₁ l ~m l.foldl (init := t₁) (fun acc p => acc.insert p.1 p.2) := by insertMany t₁ l ~m l.foldl (init := t₁) (fun acc p => acc.insert p.1 p.2) := by
constructor constructor
@ -4136,6 +4311,11 @@ theorem toList_filterMap {f : α → β → Option γ} (h : t.WF) :
(t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩))) := (t.toList.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩))) :=
DTreeMap.Raw.Const.toList_filterMap h DTreeMap.Raw.Const.toList_filterMap h
theorem toArray_filterMap {f : α → β → Option γ} (h : t.WF) :
(t.filterMap f).toArray =
(t.toArray.filterMap (fun p => (f p.1 p.2).map (fun x => ⟨p.1, x⟩))) :=
DTreeMap.Raw.Const.toArray_filterMap h
@[grind =] @[grind =]
theorem isEmpty_filterMap_iff [TransCmp cmp] theorem isEmpty_filterMap_iff [TransCmp cmp]
{f : α → β → Option γ} (h : t.WF) : {f : α → β → Option γ} (h : t.WF) :
@ -4303,10 +4483,19 @@ theorem toList_filter
(t.filter f).toList = t.toList.filter (fun p => f p.1 p.2) := (t.filter f).toList = t.toList.filter (fun p => f p.1 p.2) :=
DTreeMap.Raw.Const.toList_filter h.out DTreeMap.Raw.Const.toList_filter h.out
theorem toArray_filter
{f : (a : α) → β → Bool} (h : t.WF) :
(t.filter f).toArray = t.toArray.filter (fun p => f p.1 p.2) :=
DTreeMap.Raw.Const.toArray_filter h.out
theorem keys_filter_key {f : α → Bool} (h : t.WF) : theorem keys_filter_key {f : α → Bool} (h : t.WF) :
(t.filter fun k _ => f k).keys = t.keys.filter f := (t.filter fun k _ => f k).keys = t.keys.filter f :=
DTreeMap.Raw.keys_filter_key h.out DTreeMap.Raw.keys_filter_key h.out
theorem keysArray_filter_key {f : α → Bool} (h : t.WF) :
(t.filter fun k _ => f k).keysArray = t.keysArray.filter f :=
DTreeMap.Raw.keysArray_filter_key h.out
@[grind =] @[grind =]
theorem isEmpty_filter_iff [TransCmp cmp] theorem isEmpty_filter_iff [TransCmp cmp]
{f : α → β → Bool} (h : t.WF) : {f : α → β → Bool} (h : t.WF) :
@ -4485,9 +4674,16 @@ theorem toList_map {f : (a : α) → β → γ} :
(t.map f).toList = t.toList.map (fun p => ⟨p.1, f p.1 p.2⟩) := (t.map f).toList = t.toList.map (fun p => ⟨p.1, f p.1 p.2⟩) :=
DTreeMap.Raw.Const.toList_map DTreeMap.Raw.Const.toList_map
theorem toArray_map {f : (a : α) → β → γ} :
(t.map f).toArray = t.toArray.map (fun p => ⟨p.1, f p.1 p.2⟩) :=
DTreeMap.Raw.Const.toArray_map
theorem keys_map {f : α → β → γ} : (t.map f).keys = t.keys := theorem keys_map {f : α → β → γ} : (t.map f).keys = t.keys :=
DTreeMap.Raw.keys_map DTreeMap.Raw.keys_map
theorem keysArray_map {f : α → β → γ} : (t.map f).keysArray = t.keysArray :=
DTreeMap.Raw.keysArray_map
theorem filterMap_equiv_map [TransCmp cmp] theorem filterMap_equiv_map [TransCmp cmp]
{f : α → β → γ} (h : t.WF) : {f : α → β → γ} (h : t.WF) :
(t.filterMap (fun k v => Option.some (f k v))) ~m (t.map f) := (t.filterMap (fun k v => Option.some (f k v))) ~m (t.map f) :=
@ -4626,4 +4822,16 @@ theorem getD_map_of_getKey?_eq_some [TransCmp cmp]
end map end map
theorem toArray_toList : t.toList.toArray = t.toArray :=
DTreeMap.Raw.Const.toArray_toList
theorem toList_toArray : t.toArray.toList = t.toList :=
DTreeMap.Raw.Const.toList_toArray
theorem toArray_keys : t.keys.toArray = t.keysArray :=
DTreeMap.Raw.toArray_keys
theorem toList_keysArray : t.keysArray.toList = t.keys :=
DTreeMap.Raw.toList_keysArray
end Std.TreeMap.Raw end Std.TreeMap.Raw

View file

@ -8,6 +8,7 @@ module
prelude prelude
import Std.Data.TreeMap.Lemmas import Std.Data.TreeMap.Lemmas
import Std.Data.DTreeMap.Lemmas import Std.Data.DTreeMap.Lemmas
public import Init.Data.Array.Perm
public import Std.Data.TreeSet.AdditionalOperations public import Std.Data.TreeSet.AdditionalOperations
@[expose] public section @[expose] public section
@ -91,6 +92,12 @@ theorem isEmpty_iff_forall_not_mem [TransCmp cmp] :
t.isEmpty = true ↔ ∀ a, ¬a ∈ t := t.isEmpty = true ↔ ∀ a, ¬a ∈ t :=
TreeMap.isEmpty_iff_forall_not_mem TreeMap.isEmpty_iff_forall_not_mem
theorem toArray_toList : t.toList.toArray = t.toArray :=
TreeMap.toArray_keys
theorem toList_toArray : t.toArray.toList = t.toList :=
TreeMap.toList_keysArray
@[simp] @[simp]
theorem insert_eq_insert {p : α} : Insert.insert p t = t.insert p := theorem insert_eq_insert {p : α} : Insert.insert p t = t.insert p :=
rfl rfl
@ -286,6 +293,10 @@ theorem toList_insert_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} :
(t.insert k).toList.Perm (if k ∈ t then t.toList else k :: t.toList) := (t.insert k).toList.Perm (if k ∈ t then t.toList else k :: t.toList) :=
DTreeMap.keys_insertIfNew_perm DTreeMap.keys_insertIfNew_perm
theorem toArray_insert_perm [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] {k : α} :
(t.insert k).toArray.Perm (if k ∈ t then t.toArray else t.toArray.push k) :=
DTreeMap.keysArray_insertIfNew_perm
@[simp, grind =] theorem get_erase [TransCmp cmp] {k a : α} {h'} : @[simp, grind =] theorem get_erase [TransCmp cmp] {k a : α} {h'} :
(t.erase k).get a h' = t.get a (mem_of_mem_erase h') := (t.erase k).get a h' = t.get a (mem_of_mem_erase h') :=
TreeMap.getKey_erase TreeMap.getKey_erase
@ -453,25 +464,49 @@ theorem length_toList [TransCmp cmp] :
t.toList.length = t.size := t.toList.length = t.size :=
TreeMap.length_keys TreeMap.length_keys
@[simp, grind =]
theorem size_toArray [TransCmp cmp] :
t.toArray.size = t.size := by
simp [← toArray_toList, length_toList]
@[simp, grind =] @[simp, grind =]
theorem isEmpty_toList : theorem isEmpty_toList :
t.toList.isEmpty = t.isEmpty := t.toList.isEmpty = t.isEmpty :=
TreeMap.isEmpty_keys TreeMap.isEmpty_keys
@[simp, grind =]
theorem isEmpty_toArray :
t.toArray.isEmpty = t.isEmpty := by
simp [← toArray_toList, isEmpty_toList]
@[simp, grind =] @[simp, grind =]
theorem contains_toList [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] {k : α} : theorem contains_toList [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] {k : α} :
t.toList.contains k = t.contains k := t.toList.contains k = t.contains k :=
TreeMap.contains_keys TreeMap.contains_keys
@[simp, grind =]
theorem contains_toArray [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] {k : α} :
t.toArray.contains k = t.contains k := by
simp [← toArray_toList, contains_toList]
@[simp, grind =] @[simp, grind =]
theorem mem_toList [LawfulEqCmp cmp] [TransCmp cmp] {k : α} : theorem mem_toList [LawfulEqCmp cmp] [TransCmp cmp] {k : α} :
k ∈ t.toList ↔ k ∈ t := k ∈ t.toList ↔ k ∈ t :=
TreeMap.mem_keys TreeMap.mem_keys
@[simp, grind =]
theorem mem_toArray [LawfulEqCmp cmp] [TransCmp cmp] {k : α} :
k ∈ t.toArray ↔ k ∈ t :=
TreeMap.mem_keysArray
theorem mem_of_mem_toList [TransCmp cmp] {k : α} : theorem mem_of_mem_toList [TransCmp cmp] {k : α} :
k ∈ t.toList → k ∈ t := k ∈ t.toList → k ∈ t :=
TreeMap.mem_of_mem_keys TreeMap.mem_of_mem_keys
theorem mem_of_mem_toArray [TransCmp cmp] {k : α} :
k ∈ t.toArray → k ∈ t := by
simpa [← toArray_toList] using mem_of_mem_toList
theorem distinct_toList [TransCmp cmp] : theorem distinct_toList [TransCmp cmp] :
t.toList.Pairwise (fun a b => ¬ cmp a b = .eq) := t.toList.Pairwise (fun a b => ¬ cmp a b = .eq) :=
TreeMap.distinct_keys TreeMap.distinct_keys
@ -948,18 +983,34 @@ theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m] {f : δ → α → m
t.foldlM f init = t.toList.foldlM f init := t.foldlM f init = t.toList.foldlM f init :=
TreeMap.foldlM_eq_foldlM_keys TreeMap.foldlM_eq_foldlM_keys
theorem foldlM_eq_foldlM_toArray [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} :
t.foldlM f init = t.toArray.foldlM f init := by
simp [foldlM_eq_foldlM_toList, ← toArray_toList]
theorem foldl_eq_foldl_toList {f : δ → α → δ} {init : δ} : theorem foldl_eq_foldl_toList {f : δ → α → δ} {init : δ} :
t.foldl f init = t.toList.foldl f init := t.foldl f init = t.toList.foldl f init :=
TreeMap.foldl_eq_foldl_keys TreeMap.foldl_eq_foldl_keys
theorem foldl_eq_foldl_toArray {f : δ → α → δ} {init : δ} :
t.foldl f init = t.toArray.foldl f init := by
simp [foldl_eq_foldl_toList, ← toArray_toList]
theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} : theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} :
t.foldrM f init = t.toList.foldrM f init := t.foldrM f init = t.toList.foldrM f init :=
TreeMap.foldrM_eq_foldrM_keys TreeMap.foldrM_eq_foldrM_keys
theorem foldrM_eq_foldrM_toArray [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ} :
t.foldrM f init = t.toArray.foldrM f init := by
simp [foldrM_eq_foldrM_toList, ← toArray_toList]
theorem foldr_eq_foldr_toList {f : α → δ → δ} {init : δ} : theorem foldr_eq_foldr_toList {f : α → δ → δ} {init : δ} :
t.foldr f init = t.toList.foldr f init := t.foldr f init = t.toList.foldr f init :=
TreeMap.foldr_eq_foldr_keys TreeMap.foldr_eq_foldr_keys
theorem foldr_eq_foldr_toArray {f : α → δ → δ} {init : δ} :
t.foldr f init = t.toArray.foldr f init := by
simp [foldr_eq_foldr_toList, ← toArray_toList]
@[simp, grind =] @[simp, grind =]
theorem forM_eq_forM [Monad m] [LawfulMonad m] {f : α → m PUnit} : theorem forM_eq_forM [Monad m] [LawfulMonad m] {f : α → m PUnit} :
t.forM f = ForM.forM t f := rfl t.forM f = ForM.forM t f := rfl
@ -968,6 +1019,10 @@ theorem forM_eq_forM_toList [Monad m] [LawfulMonad m] {f : α → m PUnit} :
ForM.forM t f = t.toList.forM f := ForM.forM t f = t.toList.forM f :=
TreeMap.forM_eq_forM_keys TreeMap.forM_eq_forM_keys
theorem forM_eq_forM_toArray [Monad m] [LawfulMonad m] {f : α → m PUnit} :
ForM.forM t f = t.toArray.forM f :=
TreeMap.forM_eq_forM_keysArray
@[simp, grind =] @[simp, grind =]
theorem forIn_eq_forIn [Monad m] [LawfulMonad m] {f : α → δ → m (ForInStep δ)} {init : δ} : theorem forIn_eq_forIn [Monad m] [LawfulMonad m] {f : α → δ → m (ForInStep δ)} {init : δ} :
t.forIn f init = ForIn.forIn t init f := rfl t.forIn f init = ForIn.forIn t init f := rfl
@ -976,6 +1031,10 @@ theorem forIn_eq_forIn_toList [Monad m] [LawfulMonad m] {f : α → δ → m (Fo
ForIn.forIn t init f = ForIn.forIn t.toList init f := ForIn.forIn t init f = ForIn.forIn t.toList init f :=
TreeMap.forIn_eq_forIn_keys TreeMap.forIn_eq_forIn_keys
theorem forIn_eq_forIn_toArray [Monad m] [LawfulMonad m] {f : α → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init f = ForIn.forIn t.toArray init f := by
simp [forIn_eq_forIn_toList, ← toArray_toList]
end monadic end monadic
@[simp, grind =] @[simp, grind =]
@ -1361,6 +1420,10 @@ theorem min?_le_min?_erase [TransCmp cmp] {k km kme} :
t.min? = t.toList.head? := t.min? = t.toList.head? :=
TreeMap.minKey?_eq_head?_keys TreeMap.minKey?_eq_head?_keys
@[grind =_] theorem min?_eq_getElem?_toArray [TransCmp cmp] :
t.min? = t.toArray[0]? :=
TreeMap.minKey?_eq_getElem?_keysArray
theorem min_eq_get_min? [TransCmp cmp] {he} : theorem min_eq_get_min? [TransCmp cmp] {he} :
t.min he = t.min?.get (isSome_min?_iff_isEmpty_eq_false.mpr he) := t.min he = t.min?.get (isSome_min?_iff_isEmpty_eq_false.mpr he) :=
TreeMap.minKey_eq_get_minKey? TreeMap.minKey_eq_get_minKey?
@ -1455,6 +1518,10 @@ theorem min_eq_head_toList [TransCmp cmp] {he} :
t.min he = t.toList.head (List.isEmpty_eq_false_iff.mp <| isEmpty_toList ▸ he) := t.min he = t.toList.head (List.isEmpty_eq_false_iff.mp <| isEmpty_toList ▸ he) :=
TreeMap.minKey_eq_head_keys TreeMap.minKey_eq_head_keys
theorem min_eq_getElem_toArray [TransCmp cmp] {he} :
t.min he = t.toArray[0]'(Nat.zero_lt_of_ne_zero (by simpa [isEmpty_eq_size_eq_zero] using he)) :=
TreeMap.minKey_eq_getElem_keysArray
theorem min?_eq_some_min! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) : theorem min?_eq_some_min! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.min? = some t.min! := t.min? = some t.min! :=
TreeMap.minKey?_eq_some_minKey! he TreeMap.minKey?_eq_some_minKey! he
@ -1547,6 +1614,10 @@ theorem min!_eq_head!_toList [TransCmp cmp] [Inhabited α] :
t.min! = t.toList.head! := t.min! = t.toList.head! :=
TreeMap.minKey!_eq_head!_keys TreeMap.minKey!_eq_head!_keys
theorem min!_eq_getElem!_toArray [TransCmp cmp] [Inhabited α] :
t.min! = t.toArray[0]! :=
TreeMap.minKey!_eq_getElem!_keysArray
theorem min?_eq_some_minD [TransCmp cmp] (he : t.isEmpty = false) {fallback} : theorem min?_eq_some_minD [TransCmp cmp] (he : t.isEmpty = false) {fallback} :
t.min? = some (t.minD fallback) := t.min? = some (t.minD fallback) :=
TreeMap.minKey?_eq_some_minKeyD he TreeMap.minKey?_eq_some_minKeyD he
@ -1635,6 +1706,10 @@ theorem minD_eq_headD_toList [TransCmp cmp] {fallback} :
t.minD fallback = t.toList.headD fallback := t.minD fallback = t.toList.headD fallback :=
TreeMap.minKeyD_eq_headD_keys TreeMap.minKeyD_eq_headD_keys
theorem minD_eq_getD_toArray [TransCmp cmp] {fallback} :
t.minD fallback = t.toArray.getD 0 fallback :=
TreeMap.minKeyD_eq_getD_keysArray
end Min end Min
section Max section Max
@ -1769,6 +1844,10 @@ theorem max?_eq_getLast?_toList [TransCmp cmp] :
t.max? = t.toList.getLast? := t.max? = t.toList.getLast? :=
TreeMap.maxKey?_eq_getLast?_keys TreeMap.maxKey?_eq_getLast?_keys
theorem max?_eq_back?_toArray [TransCmp cmp] :
t.max? = t.toArray.back? := by
rw [max?_eq_getLast?_toList, ← Array.getLast?_toList, toList_toArray]
theorem max_eq_get_max? [TransCmp cmp] {he} : theorem max_eq_get_max? [TransCmp cmp] {he} :
t.max he = t.max?.get (isSome_max?_iff_isEmpty_eq_false.mpr he) := t.max he = t.max?.get (isSome_max?_iff_isEmpty_eq_false.mpr he) :=
TreeMap.maxKey_eq_get_maxKey? TreeMap.maxKey_eq_get_maxKey?
@ -1864,6 +1943,11 @@ theorem max_eq_getLast_toList [TransCmp cmp] {he} :
t.max he = t.toList.getLast (List.isEmpty_eq_false_iff.mp <| isEmpty_toList ▸ he) := t.max he = t.toList.getLast (List.isEmpty_eq_false_iff.mp <| isEmpty_toList ▸ he) :=
TreeMap.maxKey_eq_getLast_keys TreeMap.maxKey_eq_getLast_keys
@[grind =_]
theorem max_eq_back_toArray [TransCmp cmp] {he} :
t.max he = t.toArray.back (Nat.zero_lt_of_ne_zero (by simpa [isEmpty_eq_size_eq_zero] using he)) := by
exact TreeMap.maxKey_eq_back_keysArray
theorem max?_eq_some_max! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) : theorem max?_eq_some_max! [TransCmp cmp] [Inhabited α] (he : t.isEmpty = false) :
t.max? = some t.max! := t.max? = some t.max! :=
TreeMap.maxKey?_eq_some_maxKey! he TreeMap.maxKey?_eq_some_maxKey! he
@ -1957,6 +2041,11 @@ theorem max!_eq_getLast!_toList [TransCmp cmp] [Inhabited α] :
t.max! = t.toList.getLast! := t.max! = t.toList.getLast! :=
TreeMap.maxKey!_eq_getLast!_keys TreeMap.maxKey!_eq_getLast!_keys
@[grind =_]
theorem max!_eq_back!_toArray [TransCmp cmp] [Inhabited α] :
t.max! = t.toArray.back! := by
rw [max!_eq_getLast!_toList, ← Array.getLast!_toList, toList_toArray]
theorem max?_eq_some_maxD [TransCmp cmp] (he : t.isEmpty = false) {fallback} : theorem max?_eq_some_maxD [TransCmp cmp] (he : t.isEmpty = false) {fallback} :
t.max? = some (t.maxD fallback) := t.max? = some (t.maxD fallback) :=
TreeMap.maxKey?_eq_some_maxKeyD he TreeMap.maxKey?_eq_some_maxKeyD he
@ -2045,6 +2134,10 @@ theorem maxD_eq_getLastD_toList [TransCmp cmp] {fallback} :
t.maxD fallback = t.toList.getLastD fallback := t.maxD fallback = t.toList.getLastD fallback :=
TreeMap.maxKeyD_eq_getLastD_keys TreeMap.maxKeyD_eq_getLastD_keys
theorem maxD_eq_getD_back?_toArray [TransCmp cmp] {fallback} :
t.maxD fallback = t.toArray.back?.getD fallback :=
TreeMap.maxKeyD_eq_getD_back?_keysArray
end Max end Max
namespace Equiv namespace Equiv
@ -2298,6 +2391,9 @@ theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList := theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList :=
equiv_iff_equiv.trans TreeMap.equiv_iff_keys_unit_perm equiv_iff_equiv.trans TreeMap.equiv_iff_keys_unit_perm
theorem equiv_iff_toArray_perm : t₁ ~m t₂ ↔ t₁.toArray.Perm t₂.toArray :=
equiv_iff_equiv.trans TreeMap.equiv_iff_keysArray_unit_perm
theorem equiv_iff_forall_mem_iff [TransCmp cmp] [LawfulEqCmp cmp] : theorem equiv_iff_forall_mem_iff [TransCmp cmp] [LawfulEqCmp cmp] :
t₁ ~m t₂ ↔ (∀ k, k ∈ t₁ ↔ k ∈ t₂) := t₁ ~m t₂ ↔ (∀ k, k ∈ t₁ ↔ k ∈ t₂) :=
⟨fun h _ => h.mem_iff, Equiv.of_forall_mem_iff⟩ ⟨fun h _ => h.mem_iff, Equiv.of_forall_mem_iff⟩
@ -2305,10 +2401,17 @@ theorem equiv_iff_forall_mem_iff [TransCmp cmp] [LawfulEqCmp cmp] :
theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ := theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ :=
⟨.of_keys_unit_perm h⟩ ⟨.of_keys_unit_perm h⟩
theorem Equiv.of_toArray_perm (h : t₁.toArray.Perm t₂.toArray) : t₁ ~m t₂ :=
⟨.of_keysArray_unit_perm h⟩
theorem equiv_iff_toList_eq [TransCmp cmp] : theorem equiv_iff_toList_eq [TransCmp cmp] :
t₁ ~m t₂ ↔ t₁.toList = t₂.toList := t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
equiv_iff_equiv.trans TreeMap.equiv_iff_keys_unit_eq equiv_iff_equiv.trans TreeMap.equiv_iff_keys_unit_eq
theorem equiv_iff_toArray_eq [TransCmp cmp] :
t₁ ~m t₂ ↔ t₁.toArray = t₂.toArray :=
equiv_iff_equiv.trans TreeMap.equiv_iff_keysArray_unit_eq
theorem insertMany_list_equiv_foldl {l : List α} : theorem insertMany_list_equiv_foldl {l : List α} :
insertMany t₁ l ~m l.foldl (init := t₁) fun acc a => acc.insert a := by insertMany t₁ l ~m l.foldl (init := t₁) fun acc a => acc.insert a := by
constructor constructor
@ -2330,6 +2433,10 @@ theorem toList_filter {f : α → Bool} :
(t.filter f).toList = t.toList.filter f := (t.filter f).toList = t.toList.filter f :=
TreeMap.keys_filter_key TreeMap.keys_filter_key
theorem toArray_filter {f : α → Bool} :
(t.filter f).toArray = t.toArray.filter f :=
TreeMap.keysArray_filter_key
@[grind =] theorem isEmpty_filter_iff [TransCmp cmp] @[grind =] theorem isEmpty_filter_iff [TransCmp cmp]
{f : α → Bool} : {f : α → Bool} :
(t.filter f).isEmpty ↔ ∀ k h, f (t.get k h) = false := (t.filter f).isEmpty ↔ ∀ k h, f (t.get k h) = false :=

View file

@ -10,6 +10,7 @@ import Std.Data.TreeMap.Raw.Lemmas
import Std.Data.DTreeMap.Raw.Lemmas import Std.Data.DTreeMap.Raw.Lemmas
public import Std.Data.TreeSet.Raw.Basic public import Std.Data.TreeSet.Raw.Basic
public import Init.Data.List.BasicAux public import Init.Data.List.BasicAux
public import Init.Data.Array.Perm
public import Init.Data.Order.ClassesExtra public import Init.Data.Order.ClassesExtra
public import Init.Data.Order.Classes public import Init.Data.Order.Classes
@ -289,6 +290,10 @@ theorem toList_insert_perm {t : Raw α cmp} [BEq α] [TransCmp cmp] [LawfulBEqCm
(t.insert k).toList.Perm (if k ∈ t then t.toList else k :: t.toList) := (t.insert k).toList.Perm (if k ∈ t then t.toList else k :: t.toList) :=
TreeMap.Raw.keys_insertIfNew_perm h TreeMap.Raw.keys_insertIfNew_perm h
theorem toArray_insert_perm {t : Raw α cmp} [BEq α] [TransCmp cmp] [LawfulBEqCmp cmp] (h : t.WF) {k : α} :
(t.insert k).toArray.Perm (if k ∈ t then t.toArray else t.toArray.push k) :=
TreeMap.Raw.keysArray_insertIfNew_perm h
@[simp, grind =] @[simp, grind =]
theorem get_erase [TransCmp cmp] (h : t.WF) {k a : α} {h'} : 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') := (t.erase k).get a h' = t.get a (mem_of_mem_erase h h') :=
@ -459,25 +464,49 @@ theorem length_toList [TransCmp cmp] (h : t.WF) :
t.toList.length = t.size := t.toList.length = t.size :=
TreeMap.Raw.length_keys h TreeMap.Raw.length_keys h
@[simp, grind =]
theorem size_toArray [TransCmp cmp] (h : t.WF) :
t.toArray.size = t.size :=
TreeMap.Raw.size_keysArray h
@[simp, grind =] @[simp, grind =]
theorem isEmpty_toList : theorem isEmpty_toList :
t.toList.isEmpty = t.isEmpty := t.toList.isEmpty = t.isEmpty :=
TreeMap.Raw.isEmpty_keys TreeMap.Raw.isEmpty_keys
@[simp, grind =]
theorem isEmpty_toArray :
t.toArray.isEmpty = t.isEmpty :=
TreeMap.Raw.isEmpty_keysArray
@[simp, grind =] @[simp, grind =]
theorem contains_toList [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} : theorem contains_toList [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} :
t.toList.contains k = t.contains k := t.toList.contains k = t.contains k :=
TreeMap.Raw.contains_keys h TreeMap.Raw.contains_keys h
@[simp, grind =]
theorem contains_toArray [BEq α] [LawfulBEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} :
t.toArray.contains k = t.contains k :=
TreeMap.Raw.contains_keysArray h
@[simp, grind =] @[simp, grind =]
theorem mem_toList [LawfulEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} : theorem mem_toList [LawfulEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.toList ↔ k ∈ t := k ∈ t.toList ↔ k ∈ t :=
TreeMap.Raw.mem_keys h TreeMap.Raw.mem_keys h
@[simp, grind =]
theorem mem_toArray [LawfulEqCmp cmp] [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.toArray ↔ k ∈ t :=
TreeMap.Raw.mem_keysArray h
theorem mem_of_mem_toList [TransCmp cmp] (h : t.WF) {k : α} : theorem mem_of_mem_toList [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.toList → k ∈ t := k ∈ t.toList → k ∈ t :=
TreeMap.Raw.mem_of_mem_keys h TreeMap.Raw.mem_of_mem_keys h
theorem mem_of_mem_toArray [TransCmp cmp] (h : t.WF) {k : α} :
k ∈ t.toArray → k ∈ t :=
TreeMap.Raw.mem_of_mem_keysArray h
theorem distinct_toList [TransCmp cmp] (h : t.WF) : theorem distinct_toList [TransCmp cmp] (h : t.WF) :
t.toList.Pairwise (fun a b => ¬ cmp a b = .eq) := t.toList.Pairwise (fun a b => ¬ cmp a b = .eq) :=
TreeMap.Raw.distinct_keys h TreeMap.Raw.distinct_keys h
@ -1005,28 +1034,55 @@ theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m]
t.foldlM f init = t.toList.foldlM f init := t.foldlM f init = t.toList.foldlM f init :=
TreeMap.Raw.foldlM_eq_foldlM_keys TreeMap.Raw.foldlM_eq_foldlM_keys
theorem foldlM_eq_foldlM_toArray [Monad m] [LawfulMonad m]
{f : δ → α → m δ} {init : δ} :
t.foldlM f init = t.toArray.foldlM f init :=
TreeMap.Raw.foldlM_eq_foldlM_keysArray
theorem foldl_eq_foldl_toList {f : δ → α → δ} {init : δ} : theorem foldl_eq_foldl_toList {f : δ → α → δ} {init : δ} :
t.foldl f init = t.toList.foldl f init := t.foldl f init = t.toList.foldl f init :=
TreeMap.Raw.foldl_eq_foldl_keys TreeMap.Raw.foldl_eq_foldl_keys
theorem foldl_eq_foldl_toArray {f : δ → α → δ} {init : δ} :
t.foldl f init = t.toArray.foldl f init :=
TreeMap.Raw.foldl_eq_foldl_keysArray
theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m] theorem foldrM_eq_foldrM_toList [Monad m] [LawfulMonad m]
{f : α → δ → m δ} {init : δ} : {f : α → δ → m δ} {init : δ} :
t.foldrM f init = t.toList.foldrM f init := t.foldrM f init = t.toList.foldrM f init :=
TreeMap.Raw.foldrM_eq_foldrM_keys TreeMap.Raw.foldrM_eq_foldrM_keys
theorem foldrM_eq_foldrM_toArray [Monad m] [LawfulMonad m]
{f : α → δ → m δ} {init : δ} :
t.foldrM f init = t.toArray.foldrM f init :=
TreeMap.Raw.foldrM_eq_foldrM_keysArray
theorem foldr_eq_foldr_toList {f : α → δ → δ} {init : δ} : theorem foldr_eq_foldr_toList {f : α → δ → δ} {init : δ} :
t.foldr f init = t.toList.foldr f init := t.foldr f init = t.toList.foldr f init :=
TreeMap.Raw.foldr_eq_foldr_keys TreeMap.Raw.foldr_eq_foldr_keys
theorem foldr_eq_foldr_toArray {f : α → δ → δ} {init : δ} :
t.foldr f init = t.toArray.foldr f init :=
TreeMap.Raw.foldr_eq_foldr_keysArray
theorem forM_eq_forM_toList [Monad m] [LawfulMonad m] {f : α → m PUnit} : theorem forM_eq_forM_toList [Monad m] [LawfulMonad m] {f : α → m PUnit} :
ForM.forM t f = t.toList.forM f := ForM.forM t f = t.toList.forM f :=
TreeMap.Raw.forM_eq_forM_keys TreeMap.Raw.forM_eq_forM_keys
theorem forM_eq_forM_toArray [Monad m] [LawfulMonad m] {f : α → m PUnit} :
ForM.forM t f = t.toArray.forM f :=
TreeMap.Raw.forM_eq_forM_keysArray
theorem forIn_eq_forIn_toList [Monad m] [LawfulMonad m] theorem forIn_eq_forIn_toList [Monad m] [LawfulMonad m]
{f : α → δ → m (ForInStep δ)} {init : δ} : {f : α → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init f = ForIn.forIn t.toList init f := ForIn.forIn t init f = ForIn.forIn t.toList init f :=
TreeMap.Raw.forIn_eq_forIn_keys TreeMap.Raw.forIn_eq_forIn_keys
theorem forIn_eq_forIn_toArray [Monad m] [LawfulMonad m]
{f : α → δ → m (ForInStep δ)} {init : δ} :
ForIn.forIn t init f = ForIn.forIn t.toArray init f :=
TreeMap.Raw.forIn_eq_forIn_keysArray
end monadic end monadic
@[simp, grind =] @[simp, grind =]
@ -1413,6 +1469,11 @@ theorem min?_eq_head?_toList [TransCmp cmp] (h : t.WF) :
t.min? = t.toList.head? := t.min? = t.toList.head? :=
TreeMap.Raw.minKey?_eq_head?_keys h TreeMap.Raw.minKey?_eq_head?_keys h
@[grind =_]
theorem min?_eq_getElem?_toArray [TransCmp cmp] (h : t.WF) :
t.min? = t.toArray[0]? :=
TreeMap.Raw.minKey?_eq_getElem?_keysArray h
theorem min?_eq_some_min! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) : theorem min?_eq_some_min! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) :
t.min? = some t.min! := t.min? = some t.min! :=
TreeMap.Raw.minKey?_eq_some_minKey! h he TreeMap.Raw.minKey?_eq_some_minKey! h he
@ -1498,6 +1559,11 @@ theorem min!_eq_head!_toList [TransCmp cmp] [Inhabited α] (h : t.WF) :
t.min! = t.toList.head! := t.min! = t.toList.head! :=
TreeMap.Raw.minKey!_eq_head!_keys h TreeMap.Raw.minKey!_eq_head!_keys h
@[grind =_]
theorem min!_eq_getElem!_toArray [TransCmp cmp] [Inhabited α] (h : t.WF) :
t.min! = t.toArray[0]! :=
TreeMap.Raw.minKey!_eq_getElem!_keysArray h
theorem min?_eq_some_minD [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {fallback} : theorem min?_eq_some_minD [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {fallback} :
t.min? = some (t.minD fallback) := t.min? = some (t.minD fallback) :=
TreeMap.Raw.minKey?_eq_some_minKeyD h he TreeMap.Raw.minKey?_eq_some_minKeyD h he
@ -1587,6 +1653,10 @@ theorem minD_eq_headD_toList [TransCmp cmp] (h : t.WF) {fallback} :
t.minD fallback = t.toList.headD fallback := t.minD fallback = t.toList.headD fallback :=
TreeMap.Raw.minKeyD_eq_headD_keys h TreeMap.Raw.minKeyD_eq_headD_keys h
theorem minD_eq_getD_toArray [TransCmp cmp] (h : t.WF) {fallback} :
t.minD fallback = t.toArray.getD 0 fallback :=
TreeMap.Raw.minKeyD_eq_getD_keysArray h
end Min end Min
section Max section Max
@ -1722,6 +1792,10 @@ theorem max?_erase_le_max? [TransCmp cmp] (h : t.WF) {k km kme} :
t.max? = t.toList.getLast? := t.max? = t.toList.getLast? :=
TreeMap.Raw.maxKey?_eq_getLast?_keys h TreeMap.Raw.maxKey?_eq_getLast?_keys h
@[grind =_] theorem max?_eq_back?_toArray [TransCmp cmp] (h : t.WF) :
t.max? = t.toArray.back? :=
TreeMap.Raw.maxKey?_eq_back?_keysArray h
theorem max?_eq_some_max! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) : theorem max?_eq_some_max! [TransCmp cmp] [Inhabited α] (h : t.WF) (he : t.isEmpty = false) :
t.max? = some t.max! := t.max? = some t.max! :=
TreeMap.Raw.maxKey?_eq_some_maxKey! h he TreeMap.Raw.maxKey?_eq_some_maxKey! h he
@ -1807,6 +1881,11 @@ theorem max!_eq_getLast!_toList [TransCmp cmp] [Inhabited α] (h : t.WF) :
t.max! = t.toList.getLast! := t.max! = t.toList.getLast! :=
TreeMap.Raw.maxKey!_eq_getLast!_keys h TreeMap.Raw.maxKey!_eq_getLast!_keys h
@[grind =_]
theorem max!_eq_back!_toArray [TransCmp cmp] [Inhabited α] (h : t.WF) :
t.max! = t.toArray.back! :=
TreeMap.Raw.maxKey!_eq_back!_keysArray h
theorem max?_eq_some_maxD [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {fallback} : theorem max?_eq_some_maxD [TransCmp cmp] (h : t.WF) (he : t.isEmpty = false) {fallback} :
t.max? = some (t.maxD fallback) := t.max? = some (t.maxD fallback) :=
TreeMap.Raw.maxKey?_eq_some_maxKeyD h he TreeMap.Raw.maxKey?_eq_some_maxKeyD h he
@ -1896,6 +1975,11 @@ theorem maxD_eq_getLastD_toList [TransCmp cmp] (h : t.WF) {fallback} :
t.maxD fallback = t.toList.getLastD fallback := t.maxD fallback = t.toList.getLastD fallback :=
TreeMap.Raw.maxKeyD_eq_getLastD_keys h TreeMap.Raw.maxKeyD_eq_getLastD_keys h
@[grind =_]
theorem maxD_eq_getD_back?_toArray [TransCmp cmp] (h : t.WF) {fallback} :
t.maxD fallback = t.toArray.back?.getD fallback :=
TreeMap.Raw.maxKeyD_eq_getD_back?_keysArray h
end Max end Max
namespace Equiv namespace Equiv
@ -2139,13 +2223,23 @@ theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList := theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList :=
equiv_iff.trans TreeMap.Raw.equiv_iff_keys_unit_perm equiv_iff.trans TreeMap.Raw.equiv_iff_keys_unit_perm
theorem equiv_iff_toArray_perm : t₁ ~m t₂ ↔ t₁.toArray.Perm t₂.toArray :=
equiv_iff.trans TreeMap.Raw.equiv_iff_keysArray_unit_perm
theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ := theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ :=
⟨.of_keys_unit_perm h⟩ ⟨.of_keys_unit_perm h⟩
theorem Equiv.of_toArray_perm (h : t₁.toArray.Perm t₂.toArray) : t₁ ~m t₂ :=
⟨.of_keysArray_unit_perm h⟩
theorem equiv_iff_toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) : theorem equiv_iff_toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ t₁.toList = t₂.toList := t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
equiv_iff.trans (TreeMap.Raw.equiv_iff_keys_unit_eq h₁.1 h₂.1) equiv_iff.trans (TreeMap.Raw.equiv_iff_keys_unit_eq h₁.1 h₂.1)
theorem equiv_iff_toArray_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ t₁.toArray = t₂.toArray :=
equiv_iff.trans (TreeMap.Raw.equiv_iff_keysArray_unit_eq h₁.1 h₂.1)
theorem equiv_iff_forall_mem_iff [TransCmp cmp] [LawfulEqCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) : theorem equiv_iff_forall_mem_iff [TransCmp cmp] [LawfulEqCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
t₁ ~m t₂ ↔ (∀ k, k ∈ t₁ ↔ k ∈ t₂) := t₁ ~m t₂ ↔ (∀ k, k ∈ t₁ ↔ k ∈ t₂) :=
⟨fun h _ => h.mem_iff h₁ h₂, Equiv.of_forall_mem_iff h₁ h₂⟩ ⟨fun h _ => h.mem_iff h₁ h₂, Equiv.of_forall_mem_iff h₁ h₂⟩
@ -2169,6 +2263,10 @@ theorem toList_filter {f : α → Bool} (h : t.WF) :
(t.filter f).toList = t.toList.filter f := (t.filter f).toList = t.toList.filter f :=
TreeMap.Raw.keys_filter_key h TreeMap.Raw.keys_filter_key h
theorem toArray_filter {f : α → Bool} (h : t.WF) :
(t.filter f).toArray = t.toArray.filter f :=
TreeMap.Raw.keysArray_filter_key h
@[grind =] theorem isEmpty_filter_iff [TransCmp cmp] @[grind =] theorem isEmpty_filter_iff [TransCmp cmp]
{f : α → Bool} (h : t.WF) : {f : α → Bool} (h : t.WF) :
(t.filter f).isEmpty ↔ (t.filter f).isEmpty ↔
@ -2236,4 +2334,10 @@ theorem get_filter [TransCmp cmp]
end filter end filter
theorem toArray_toList : t.toList.toArray = t.toArray :=
TreeMap.Raw.toArray_keys
theorem toList_toArray : t.toArray.toList = t.toList :=
TreeMap.Raw.toList_keysArray
end Std.TreeSet.Raw end Std.TreeSet.Raw