feat: equivalence of tree maps (#8210)
This PR adds an equivalence relation to tree maps akin to the existing one for hash maps. In order to get many congruence lemmas to eventually use for defining functions on extensional tree maps, almost all of the remaining tree map functions have also been given lemmas to relate them to list functions, although these aren't currently used to prove lemmas other than congruence lemmas.
This commit is contained in:
parent
2344e3f254
commit
be4ebb8ac3
23 changed files with 4264 additions and 181 deletions
|
|
@ -3621,8 +3621,8 @@ We can prove that two folds over the same array are related (by some arbitrary r
|
|||
if we know that the initial elements are related and the folding function, for each element of the array,
|
||||
preserves the relation.
|
||||
-/
|
||||
theorem foldl_rel {xs : Array α} {f g : β → α → β} {a b : β} {r : β → β → Prop}
|
||||
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c c' : β), r c c' → r (f c a) (g c' a)) :
|
||||
theorem foldl_rel {xs : Array α} {f : β → α → β} {g : γ → α → γ} {a : β} {b : γ} {r : β → γ → Prop}
|
||||
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c : β) (c' : γ), r c c' → r (f c a) (g c' a)) :
|
||||
r (xs.foldl (fun acc a => f acc a) a) (xs.foldl (fun acc a => g acc a) b) := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simpa using List.foldl_rel h (by simpa using h')
|
||||
|
|
@ -3632,8 +3632,8 @@ We can prove that two folds over the same array are related (by some arbitrary r
|
|||
if we know that the initial elements are related and the folding function, for each element of the array,
|
||||
preserves the relation.
|
||||
-/
|
||||
theorem foldr_rel {xs : Array α} {f g : α → β → β} {a b : β} {r : β → β → Prop}
|
||||
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c c' : β), r c c' → r (f a c) (g a c')) :
|
||||
theorem foldr_rel {xs : Array α} {f : α → β → β} {g : α → γ → γ} {a : β} {b : γ} {r : β → γ → Prop}
|
||||
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c : β) (c' : γ), r c c' → r (f a c) (g a c')) :
|
||||
r (xs.foldr (fun a acc => f a acc) a) (xs.foldr (fun a acc => g a acc) b) := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simpa using List.foldr_rel h (by simpa using h')
|
||||
|
|
|
|||
|
|
@ -2778,8 +2778,8 @@ We can prove that two folds over the same list are related (by some arbitrary re
|
|||
if we know that the initial elements are related and the folding function, for each element of the list,
|
||||
preserves the relation.
|
||||
-/
|
||||
theorem foldl_rel {l : List α} {f g : β → α → β} {a b : β} {r : β → β → Prop}
|
||||
(h : r a b) (h' : ∀ (a : α), a ∈ l → ∀ (c c' : β), r c c' → r (f c a) (g c' a)) :
|
||||
theorem foldl_rel {l : List α} {f : β → α → β} {g : γ → α → γ} {a : β} {b : γ} {r : β → γ → Prop}
|
||||
(h : r a b) (h' : ∀ (a : α), a ∈ l → ∀ (c : β) (c' : γ), r c c' → r (f c a) (g c' a)) :
|
||||
r (l.foldl (fun acc a => f acc a) a) (l.foldl (fun acc a => g acc a) b) := by
|
||||
induction l generalizing a b with
|
||||
| nil => simp_all
|
||||
|
|
@ -2794,8 +2794,8 @@ We can prove that two folds over the same list are related (by some arbitrary re
|
|||
if we know that the initial elements are related and the folding function, for each element of the list,
|
||||
preserves the relation.
|
||||
-/
|
||||
theorem foldr_rel {l : List α} {f g : α → β → β} {a b : β} {r : β → β → Prop}
|
||||
(h : r a b) (h' : ∀ (a : α), a ∈ l → ∀ (c c' : β), r c c' → r (f a c) (g a c')) :
|
||||
theorem foldr_rel {l : List α} {f : α → β → β} {g : α → γ → γ} {a : β} {b : γ} {r : β → γ → Prop}
|
||||
(h : r a b) (h' : ∀ (a : α), a ∈ l → ∀ (c : β) (c' : γ), r c c' → r (f a c) (g a c')) :
|
||||
r (l.foldr (fun a acc => f a acc) a) (l.foldr (fun a acc => g a acc) b) := by
|
||||
induction l generalizing a b with
|
||||
| nil => simp_all
|
||||
|
|
|
|||
|
|
@ -2538,23 +2538,23 @@ theorem foldr_hom (f : β₁ → β₂) {g₁ : α → β₁ → β₁} {g₂ :
|
|||
rw [Array.foldr_hom _ H]
|
||||
|
||||
/--
|
||||
We can prove that two folds over the same array are related (by some arbitrary relation)
|
||||
if we know that the initial elements are related and the folding function, for each element of the array,
|
||||
preserves the relation.
|
||||
We can prove that two folds over the same vector are related (by some arbitrary relation)
|
||||
if we know that the initial elements are related and the folding function, for each element of the
|
||||
vector, preserves the relation.
|
||||
-/
|
||||
theorem foldl_rel {xs : Vector α n} {f g : β → α → β} {a b : β} {r : β → β → Prop}
|
||||
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c c' : β), r c c' → r (f c a) (g c' a)) :
|
||||
theorem foldl_rel {xs : Vector α n} {f : β → α → β} {g : γ → α → γ} {a : β} {b : γ} {r : β → γ → Prop}
|
||||
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c : β) (c' : γ), r c c' → r (f c a) (g c' a)) :
|
||||
r (xs.foldl (fun acc a => f acc a) a) (xs.foldl (fun acc a => g acc a) b) := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simpa using Array.foldl_rel h (by simpa using h')
|
||||
|
||||
/--
|
||||
We can prove that two folds over the same array are related (by some arbitrary relation)
|
||||
if we know that the initial elements are related and the folding function, for each element of the array,
|
||||
preserves the relation.
|
||||
We can prove that two folds over the same vector are related (by some arbitrary relation)
|
||||
if we know that the initial elements are related and the folding function, for each element of the
|
||||
vector, preserves the relation.
|
||||
-/
|
||||
theorem foldr_rel {xs : Vector α n} {f g : α → β → β} {a b : β} {r : β → β → Prop}
|
||||
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c c' : β), r c c' → r (f a c) (g a c')) :
|
||||
theorem foldr_rel {xs : Vector α n} {f : α → β → β} {g : α → γ → γ} {a : β} {b : γ} {r : β → γ → Prop}
|
||||
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c : β) (c' : γ), r c c' → r (f a c) (g a c')) :
|
||||
r (xs.foldr (fun a acc => f a acc) a) (xs.foldr (fun a acc => g a acc) b) := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simpa using Array.foldr_rel h (by simpa using h')
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ def getEntryLE [TransCmp cmp] (t : DTreeMap α β cmp) (k : α) (h : ∃ a ∈ t
|
|||
letI : Ord α := ⟨cmp⟩; Impl.getEntryLE k t.inner t.wf.ordered h
|
||||
|
||||
/--
|
||||
Given a proof that such a mapping exists, retrieves the key-value pair with the smallest key that is
|
||||
Given a proof that such a mapping exists, retrieves the key-value pair with the largest key that is
|
||||
less than the given key.
|
||||
-/
|
||||
@[inline]
|
||||
|
|
@ -99,7 +99,7 @@ def getKeyLE [TransCmp cmp] (t : DTreeMap α β cmp) (k : α) (h : ∃ a ∈ t,
|
|||
letI : Ord α := ⟨cmp⟩; Impl.getKeyLE k t.inner t.wf.ordered h
|
||||
|
||||
/--
|
||||
Given a proof that such a mapping exists, retrieves the smallest key that is
|
||||
Given a proof that such a mapping exists, retrieves the largest key that is
|
||||
less than the given key.
|
||||
-/
|
||||
@[inline]
|
||||
|
|
@ -138,7 +138,7 @@ def getEntryLE [TransCmp cmp] (t : DTreeMap α β cmp) (k : α) (h : ∃ a ∈ t
|
|||
letI : Ord α := ⟨cmp⟩; Impl.Const.getEntryLE k t.inner t.wf.ordered h
|
||||
|
||||
/--
|
||||
Given a proof that such a mapping exists, retrieves the key-value pair with the smallest key that is
|
||||
Given a proof that such a mapping exists, retrieves the key-value pair with the largest key that is
|
||||
less than the given key.
|
||||
-/
|
||||
@[inline]
|
||||
|
|
|
|||
|
|
@ -83,6 +83,13 @@ instance : EmptyCollection (DTreeMap α β cmp) where
|
|||
instance : Inhabited (DTreeMap α β cmp) where
|
||||
default := ∅
|
||||
|
||||
@[inherit_doc Impl.Equiv]
|
||||
structure Equiv (m₁ m₂ : DTreeMap α β cmp) where
|
||||
/-- Internal implementation detail of the tree map -/
|
||||
inner : m₁.1.Equiv m₂.1
|
||||
|
||||
@[inherit_doc] scoped infix:50 " ~m " => Equiv
|
||||
|
||||
@[simp]
|
||||
theorem empty_eq_emptyc : (empty : DTreeMap α β cmp) = ∅ :=
|
||||
rfl
|
||||
|
|
@ -500,7 +507,7 @@ def getEntryLE? (t : DTreeMap α β cmp) (k : α) : Option ((a : α) × β a) :=
|
|||
letI : Ord α := ⟨cmp⟩; Impl.getEntryLE? k t.inner
|
||||
|
||||
/--
|
||||
Tries to retrieve the key-value pair with the smallest key that is less than the given key,
|
||||
Tries to retrieve the key-value pair with the largest key that is less than the given key,
|
||||
returning `none` if no such pair exists.
|
||||
-/
|
||||
@[inline]
|
||||
|
|
@ -537,7 +544,7 @@ def getEntryLE! [Inhabited (Sigma β)] (t : DTreeMap α β cmp) (k : α) : (a :
|
|||
letI : Ord α := ⟨cmp⟩; Impl.getEntryLE! k t.inner
|
||||
|
||||
/--
|
||||
Tries to retrieve the key-value pair with the smallest key that is less than the given key,
|
||||
Tries to retrieve the key-value pair with the largest key that is less than the given key,
|
||||
panicking if no such pair exists.
|
||||
-/
|
||||
@[inline]
|
||||
|
|
@ -569,7 +576,7 @@ def getEntryLED (t : DTreeMap α β cmp) (k : α) (fallback : Sigma β) : (a :
|
|||
letI : Ord α := ⟨cmp⟩; Impl.getEntryLED k t.inner fallback
|
||||
|
||||
/--
|
||||
Tries to retrieve the key-value pair with the smallest key that is less than the given key,
|
||||
Tries to retrieve the key-value pair with the largest key that is less than the given key,
|
||||
returning `fallback` if no such pair exists.
|
||||
-/
|
||||
@[inline]
|
||||
|
|
@ -601,7 +608,7 @@ def getKeyLE? (t : DTreeMap α β cmp) (k : α) : Option α :=
|
|||
letI : Ord α := ⟨cmp⟩; t.inner.getKeyLE? k
|
||||
|
||||
/--
|
||||
Tries to retrieve the smallest key that is less than the given key,
|
||||
Tries to retrieve the largest key that is less than the given key,
|
||||
returning `none` if no such key exists.
|
||||
-/
|
||||
@[inline]
|
||||
|
|
@ -638,7 +645,7 @@ def getKeyLE! [Inhabited α] (t : DTreeMap α β cmp) (k : α) : α :=
|
|||
letI : Ord α := ⟨cmp⟩; Impl.getKeyLE! k t.inner
|
||||
|
||||
/--
|
||||
Tries to retrieve the smallest key that is less than the given key,
|
||||
Tries to retrieve the largest key that is less than the given key,
|
||||
panicking if no such key exists.
|
||||
-/
|
||||
@[inline]
|
||||
|
|
@ -670,7 +677,7 @@ def getKeyLED (t : DTreeMap α β cmp) (k : α) (fallback : α) : α :=
|
|||
letI : Ord α := ⟨cmp⟩; Impl.getKeyLED k t.inner fallback
|
||||
|
||||
/--
|
||||
Tries to retrieve the smallest key that is less than the given key,
|
||||
Tries to retrieve the largest key that is less than the given key,
|
||||
returning `fallback` if no such key exists.
|
||||
-/
|
||||
@[inline]
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@ set_option autoImplicit false
|
|||
open Std.Internal.List
|
||||
open Std.Internal
|
||||
|
||||
universe u v w
|
||||
universe u v w w'
|
||||
|
||||
namespace Std.DTreeMap.Internal.Impl
|
||||
|
||||
variable {α : Type u} {β : α → Type v} {instOrd : Ord α} {t : Impl α β}
|
||||
variable {α : Type u} {β : α → Type v} {γ : α → Type w} {instOrd : Ord α} {t : Impl α β}
|
||||
private local instance : Coe (Type v) (α → Type v) where coe γ := fun _ => γ
|
||||
|
||||
attribute [local instance low] beqOfOrd
|
||||
|
|
@ -41,7 +41,8 @@ macro_rules
|
|||
| apply WF.erase | apply WF.insertMany
|
||||
| apply WF.constInsertMany | apply WF.constInsertManyIfNewUnit
|
||||
| apply WF.alter | apply WF.constAlter
|
||||
| apply WF.modify | apply WF.constModify) <;> wf_trivial)
|
||||
| apply WF.modify | apply WF.constModify
|
||||
| apply WF.filterMap | apply WF.filter | apply WF.map) <;> wf_trivial)
|
||||
|
||||
/-- Internal implementation detail of the tree map -/
|
||||
scoped macro "empty" : tactic => `(tactic| { intros; simp_all [List.isEmpty_iff] } )
|
||||
|
|
@ -67,7 +68,10 @@ private def modifyMap : Std.HashMap Name Name :=
|
|||
(`alter, ``toListModel_alter),
|
||||
(`Const.alter, ``Const.toListModel_alter),
|
||||
(`modify, ``toListModel_modify),
|
||||
(`Const.modify, ``Const.toListModel_modify)]
|
||||
(`Const.modify, ``Const.toListModel_modify),
|
||||
(`filter, ``toListModel_filter),
|
||||
(`map, ``toListModel_map),
|
||||
(`filterMap, ``toListModel_filterMap)]
|
||||
|
||||
private def queryMap : Std.DHashMap Name (fun _ => Name × Array (MacroM (TSyntax `term))) :=
|
||||
.ofList
|
||||
|
|
@ -102,7 +106,22 @@ private def queryMap : Std.DHashMap Name (fun _ => Name × Array (MacroM (TSynta
|
|||
⟨`maxKey?, (``maxKey?_eq_maxKey?, #[``(maxKey?_of_perm _)])⟩,
|
||||
⟨`maxKey, (``maxKey_eq_maxKey, #[``(maxKey_of_perm _)])⟩,
|
||||
⟨`maxKey!, (``maxKey!_eq_maxKey!, #[``(maxKey!_of_perm _)])⟩,
|
||||
⟨`maxKeyD, (``maxKeyD_eq_maxKeyD, #[``(maxKeyD_of_perm _)])⟩]
|
||||
⟨`maxKeyD, (``maxKeyD_eq_maxKeyD, #[``(maxKeyD_of_perm _)])⟩,
|
||||
⟨`minEntry?, (``minEntry?_eq_minEntry?, #[``(minEntry?_of_perm _)])⟩,
|
||||
⟨`entryAtIdx?, (``entryAtIdx?_eq_getElem?, #[])⟩,
|
||||
⟨`entryAtIdx, (``entryAtIdx_eq_getElem, #[])⟩,
|
||||
⟨`entryAtIdx!, (``entryAtIdx!_eq_getElem!, #[])⟩,
|
||||
⟨`entryAtIdxD, (``entryAtIdxD_eq_getD, #[])⟩,
|
||||
⟨`Const.entryAtIdx?, (``Const.entryAtIdx?_eq_getElem?, #[])⟩,
|
||||
⟨`Const.entryAtIdx, (``Const.entryAtIdx_eq_getElem, #[])⟩,
|
||||
⟨`Const.entryAtIdx!, (``Const.entryAtIdx!_eq_get!_map_getElem?, #[])⟩,
|
||||
⟨`Const.entryAtIdxD, (``Const.entryAtIdxD_eq_getD_map_getElem?, #[])⟩,
|
||||
⟨`keyAtIdx?, (``keyAtIdx?_eq_getElem?, #[])⟩,
|
||||
⟨`keyAtIdx, (``keyAtIdx_eq_getElem_fst, #[])⟩,
|
||||
⟨`keyAtIdx!, (``keyAtIdx!_eq_get!_map_getElem?, #[])⟩,
|
||||
⟨`keyAtIdxD, (``keyAtIdxD_eq_getD_map_getElem?, #[])⟩,
|
||||
⟨`Equiv, (``equiv_iff_toListModel_perm,
|
||||
#[``(_root_.List.Perm.congr_left), ``(_root_.List.Perm.congr_right)])⟩]
|
||||
|
||||
/-- Internal implementation detail of the tree map -/
|
||||
scoped syntax "simp_to_model" (" [" (ident,*) "]")? ("using" term)? : tactic
|
||||
|
|
@ -1663,7 +1682,7 @@ end Const
|
|||
|
||||
section monadic
|
||||
|
||||
variable {t : Impl α β} {δ : Type w} {m : Type w → Type w}
|
||||
variable {t : Impl α β} {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m]
|
||||
{f : δ → (a : α) → β a → m δ} {init : δ} :
|
||||
|
|
@ -6005,4 +6024,795 @@ end Const
|
|||
|
||||
end Max
|
||||
|
||||
namespace Equiv
|
||||
|
||||
variable {t₁ t₂ t₃ t₄ : Impl α β} {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
@[refl, simp] theorem rfl : Equiv t t := ⟨.rfl⟩
|
||||
|
||||
@[symm] theorem symm : Equiv t₁ t₂ → Equiv t₂ t₁
|
||||
| ⟨h⟩ => ⟨h.symm⟩
|
||||
|
||||
theorem trans : Equiv t₁ t₂ → Equiv t₂ t₃ → Equiv t₁ t₃
|
||||
| ⟨h⟩, ⟨h'⟩ => ⟨h.trans h'⟩
|
||||
|
||||
instance instTrans : @Trans (Impl α β) _ _ Equiv Equiv Equiv := ⟨trans⟩
|
||||
|
||||
theorem comm : t₁ ~m t₂ ↔ t₂ ~m t₁ := ⟨symm, symm⟩
|
||||
theorem congr_left (h : t₁ ~m t₂) : t₁ ~m t₃ ↔ t₂ ~m t₃ := ⟨h.symm.trans, h.trans⟩
|
||||
theorem congr_right (h : t₁ ~m t₂) : t₃ ~m t₁ ↔ t₃ ~m t₂ :=
|
||||
⟨fun h' => h'.trans h, fun h' => h'.trans h.symm⟩
|
||||
|
||||
-- congruence lemmas
|
||||
|
||||
theorem isEmpty_eq (h : t₁ ~m t₂) : t₁.isEmpty = t₂.isEmpty := by
|
||||
simp_to_model [isEmpty] using List.Perm.isEmpty_eq h.1
|
||||
|
||||
theorem contains_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
t₁.contains k = t₂.contains k := by
|
||||
simp_to_model [contains] using List.containsKey_of_perm h.1
|
||||
|
||||
theorem mem_iff [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
k ∈ t₁ ↔ k ∈ t₂ := by
|
||||
simp only [mem_iff_contains, Bool.coe_iff_coe, contains_eq h₁ h₂ h]
|
||||
|
||||
theorem size_eq (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.size = t₂.size := by
|
||||
simp_to_model [size] using List.Perm.length_eq h.1
|
||||
|
||||
theorem get?_eq [TransOrd α] [LawfulEqOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
t₁.get? k = t₂.get? k := by
|
||||
simp_to_model [get?] using List.getValueCast?_of_perm _ h.1
|
||||
|
||||
theorem get_eq [TransOrd α] [LawfulEqOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} (hk : k ∈ t₁) : t₁.get k hk = t₂.get k ((h.mem_iff h₁ h₂).mp hk) := by
|
||||
simp_to_model [get] using List.getValueCast_of_perm _ h.1
|
||||
|
||||
theorem get!_eq [TransOrd α] [LawfulEqOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} [Inhabited (β k)] : t₁.get! k = t₂.get! k := by
|
||||
simp_to_model [get!] using List.getValueCast!_of_perm _ h.1
|
||||
|
||||
theorem getD_eq [TransOrd α] [LawfulEqOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {fallback : β k} : t₁.getD k fallback = t₂.getD k fallback := by
|
||||
simp_to_model [getD] using List.getValueCastD_of_perm _ h.1
|
||||
|
||||
theorem getKey?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
t₁.getKey? k = t₂.getKey? k := by
|
||||
simp_to_model [getKey?] using List.getKey?_of_perm _ h.1
|
||||
|
||||
theorem getKey_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} (hk : k ∈ t₁) : t₁.getKey k hk = t₂.getKey k ((h.mem_iff h₁ h₂).mp hk) := by
|
||||
simp_to_model [getKey] using List.getKey_of_perm _ h.1
|
||||
|
||||
theorem getKey!_eq [TransOrd α] [Inhabited α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} : t₁.getKey! k = t₂.getKey! k := by
|
||||
simp_to_model [getKey!] using List.getKey!_of_perm _ h.1
|
||||
|
||||
theorem getKeyD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k fallback : α} : t₁.getKeyD k fallback = t₂.getKeyD k fallback := by
|
||||
simp_to_model [getKeyD] using List.getKeyD_of_perm _ h.1
|
||||
|
||||
theorem toList_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.toList = t₂.toList := by
|
||||
simp_to_model [toList] using h.toListModel_eq
|
||||
|
||||
theorem toArray_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.toArray = t₂.toArray := by
|
||||
simp only [toArray_eq_toArray, h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem keys_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.keys = t₂.keys := by
|
||||
simp_to_model [keys]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem keysArray_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.keysArray = t₂.keysArray := by
|
||||
simp only [keysArray_eq_toArray_keys, h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem foldlM_eq [TransOrd α] [Monad m] [LawfulMonad m] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{f : δ → (a : α) → β a → m δ} {init : δ} :
|
||||
t₁.foldlM f init = t₂.foldlM f init := by
|
||||
simp_to_model [foldlM]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem foldl_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{f : δ → (a : α) → β a → δ} {init : δ} :
|
||||
t₁.foldl f init = t₂.foldl f init := by
|
||||
simp_to_model [foldl]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem foldrM_eq [TransOrd α] [Monad m] [LawfulMonad m] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{f : (a : α) → β a → δ → m δ} {init : δ} :
|
||||
t₁.foldrM f init = t₂.foldrM f init := by
|
||||
simp_to_model [foldrM]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem foldr_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{f : (a : α) → β a → δ → δ} {init : δ} :
|
||||
t₁.foldr f init = t₂.foldr f init := by
|
||||
simp_to_model [foldr]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem forIn_eq [TransOrd α] [Monad m] [LawfulMonad m] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{f : (a : α) → β a → δ → m (ForInStep δ)} {init : δ} :
|
||||
t₁.forIn f init = t₂.forIn f init := by
|
||||
simp_to_model [forIn]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem forM_eq [TransOrd α] [Monad m] [LawfulMonad m] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{f : (a : α) → β a → m PUnit} :
|
||||
t₁.forM f = t₂.forM f := by
|
||||
simp_to_model [forM]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem minKey?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.minKey? = t₂.minKey? := by
|
||||
simp_to_model [minKey?]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem minKey_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (h' : t₁.isEmpty = false) :
|
||||
t₁.minKey h' = t₂.minKey (h.isEmpty_eq.symm.trans h') := by
|
||||
simp_to_model [minKey]
|
||||
simp only [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem minKey!_eq [TransOrd α] [Inhabited α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.minKey! = t₂.minKey! := by
|
||||
simp_to_model [minKey!]
|
||||
simp only [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem minKeyD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {fallback : α} :
|
||||
t₁.minKeyD fallback = t₂.minKeyD fallback := by
|
||||
simp_to_model [minKeyD]
|
||||
simp only [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem maxKey?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.maxKey? = t₂.maxKey? := by
|
||||
simp_to_model [maxKey?]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem maxKey_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (h' : t₁.isEmpty = false) :
|
||||
t₁.maxKey h' = t₂.maxKey (h.isEmpty_eq.symm.trans h') := by
|
||||
simp_to_model [maxKey]
|
||||
simp only [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem maxKey!_eq [TransOrd α] [Inhabited α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.maxKey! = t₂.maxKey! := by
|
||||
simp_to_model [maxKey!]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem maxKeyD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {fallback : α} :
|
||||
t₁.maxKeyD fallback = t₂.maxKeyD fallback := by
|
||||
simp_to_model [maxKeyD]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem minEntry?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.minEntry? = t₂.minEntry? := by
|
||||
simp_to_model [minEntry?]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem minEntry_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {he} :
|
||||
t₁.minEntry he = t₂.minEntry (h.isEmpty_eq.symm.trans he) := by
|
||||
simp only [minEntry_eq_get_minEntry?, h.minEntry?_eq h₁ h₂]
|
||||
|
||||
theorem minEntry!_eq [TransOrd α] [Inhabited ((a : α) × β a)]
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.minEntry! = t₂.minEntry! := by
|
||||
simp only [minEntry!_eq_get!_minEntry?, h.minEntry?_eq h₁ h₂]
|
||||
|
||||
theorem minEntryD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{fallback : (a : α) × β a} : t₁.minEntryD fallback = t₂.minEntryD fallback := by
|
||||
simp only [minEntryD_eq_getD_minEntry?, h.minEntry?_eq h₁ h₂]
|
||||
|
||||
theorem maxEntry?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.maxEntry? = t₂.maxEntry? := by
|
||||
simp only [maxEntry?_eq_minEntry?, h₁.ordered, h₂.ordered]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem maxEntry_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {he} :
|
||||
t₁.maxEntry he = t₂.maxEntry (h.isEmpty_eq.symm.trans he) := by
|
||||
apply Option.some.inj
|
||||
simp only [some_maxEntry_eq_maxEntry?, h.maxEntry?_eq h₁ h₂]
|
||||
|
||||
theorem maxEntry!_eq [TransOrd α] [Inhabited ((a : α) × β a)]
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.maxEntry! = t₂.maxEntry! := by
|
||||
simp only [maxEntry!_eq_get!_maxEntry?, h.maxEntry?_eq h₁ h₂]
|
||||
|
||||
theorem maxEntryD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{fallback : (a : α) × β a} : t₁.maxEntryD fallback = t₂.maxEntryD fallback := by
|
||||
simp only [maxEntryD_eq_getD_maxEntry?, h.maxEntry?_eq h₁ h₂]
|
||||
|
||||
theorem entryAtIdx?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {i : Nat} :
|
||||
t₁.entryAtIdx? i = t₂.entryAtIdx? i := by
|
||||
simp_to_model [entryAtIdx?]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem entryAtIdx_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {i : Nat} {h'} :
|
||||
t₁.entryAtIdx h₁.balanced i h' = t₂.entryAtIdx h₂.balanced i (h.size_eq h₁ h₂ ▸ h') := by
|
||||
simp_to_model [entryAtIdx]
|
||||
simp only [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem entryAtIdx!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {i : Nat}
|
||||
[Inhabited ((a : α) × β a)] : t₁.entryAtIdx! i = t₂.entryAtIdx! i := by
|
||||
simp_to_model [entryAtIdx!]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem entryAtIdxD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {i : Nat}
|
||||
{fallback : (a : α) × β a} : t₁.entryAtIdxD i fallback = t₂.entryAtIdxD i fallback := by
|
||||
simp_to_model [entryAtIdxD]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem keyAtIdx?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {i : Nat} :
|
||||
t₁.keyAtIdx? i = t₂.keyAtIdx? i := by
|
||||
simp_to_model [keyAtIdx?]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem keyAtIdx_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {i : Nat} {h'} :
|
||||
t₁.keyAtIdx h₁.balanced i h' = t₂.keyAtIdx h₂.balanced i (h.size_eq h₁ h₂ ▸ h') := by
|
||||
simp_to_model [keyAtIdx]
|
||||
simp only [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem keyAtIdx!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {i : Nat}
|
||||
[Inhabited α] : t₁.keyAtIdx! i = t₂.keyAtIdx! i := by
|
||||
simp_to_model [keyAtIdx!]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem keyAtIdxD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {i : Nat}
|
||||
{fallback : α} : t₁.keyAtIdxD i fallback = t₂.keyAtIdxD i fallback := by
|
||||
simp_to_model [keyAtIdxD]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem getEntryGE?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
t₁.getEntryGE? k = t₂.getEntryGE? k := by
|
||||
simp only [getEntryGE?_eq_find?, h₁.ordered, h₂.ordered]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem getEntryGE_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} {he} :
|
||||
t₁.getEntryGE k h₁.ordered he = t₂.getEntryGE k h₂.ordered (by simpa only [← h.mem_iff h₁ h₂]) := by
|
||||
apply Option.some.inj
|
||||
simp only [some_getEntryGE_eq_getEntryGE?, h.getEntryGE?_eq h₁ h₂]
|
||||
|
||||
theorem getEntryGE!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} [Inhabited ((a : α) × β a)] : t₁.getEntryGE! k = t₂.getEntryGE! k := by
|
||||
simp only [getEntryGE!_eq_get!_getEntryGE?, h.getEntryGE?_eq h₁ h₂]
|
||||
|
||||
theorem getEntryGED_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {fallback : (a : α) × β a} : t₁.getEntryGED k fallback = t₂.getEntryGED k fallback := by
|
||||
simp only [getEntryGED_eq_getD_getEntryGE?, h.getEntryGE?_eq h₁ h₂]
|
||||
|
||||
theorem getEntryGT?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
t₁.getEntryGT? k = t₂.getEntryGT? k := by
|
||||
simp only [getEntryGT?_eq_find?, h₁.ordered, h₂.ordered]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem getEntryGT_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} {he} :
|
||||
t₁.getEntryGT k h₁.ordered he = t₂.getEntryGT k h₂.ordered (by simpa only [← h.mem_iff h₁ h₂]) := by
|
||||
apply Option.some.inj
|
||||
simp only [some_getEntryGT_eq_getEntryGT?, h.getEntryGT?_eq h₁ h₂]
|
||||
|
||||
theorem getEntryGT!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} [Inhabited ((a : α) × β a)] : t₁.getEntryGT! k = t₂.getEntryGT! k := by
|
||||
simp only [getEntryGT!_eq_get!_getEntryGT?, h.getEntryGT?_eq h₁ h₂]
|
||||
|
||||
theorem getEntryGTD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {fallback : (a : α) × β a} : t₁.getEntryGTD k fallback = t₂.getEntryGTD k fallback := by
|
||||
simp only [getEntryGTD_eq_getD_getEntryGT?, h.getEntryGT?_eq h₁ h₂]
|
||||
|
||||
theorem getEntryLE?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
t₁.getEntryLE? k = t₂.getEntryLE? k := by
|
||||
simp only [getEntryLE?_eq_findRev?, h₁.ordered, h₂.ordered]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem getEntryLE_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} {he} :
|
||||
t₁.getEntryLE k h₁.ordered he = t₂.getEntryLE k h₂.ordered (by simpa only [← h.mem_iff h₁ h₂]) := by
|
||||
apply Option.some.inj
|
||||
simp only [some_getEntryLE_eq_getEntryLE?, h.getEntryLE?_eq h₁ h₂]
|
||||
|
||||
theorem getEntryLE!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} [Inhabited ((a : α) × β a)] : t₁.getEntryLE! k = t₂.getEntryLE! k := by
|
||||
simp only [getEntryLE!_eq_get!_getEntryLE?, h.getEntryLE?_eq h₁ h₂]
|
||||
|
||||
theorem getEntryLED_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {fallback : (a : α) × β a} : t₁.getEntryLED k fallback = t₂.getEntryLED k fallback := by
|
||||
simp only [getEntryLED_eq_getD_getEntryLE?, h.getEntryLE?_eq h₁ h₂]
|
||||
|
||||
theorem getEntryLT?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
t₁.getEntryLT? k = t₂.getEntryLT? k := by
|
||||
simp only [getEntryLT?_eq_findRev?, h₁.ordered, h₂.ordered]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem getEntryLT_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} {he} :
|
||||
t₁.getEntryLT k h₁.ordered he = t₂.getEntryLT k h₂.ordered (by simpa only [← h.mem_iff h₁ h₂]) := by
|
||||
apply Option.some.inj
|
||||
simp only [some_getEntryLT_eq_getEntryLT?, h.getEntryLT?_eq h₁ h₂]
|
||||
|
||||
theorem getEntryLT!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} [Inhabited ((a : α) × β a)] : t₁.getEntryLT! k = t₂.getEntryLT! k := by
|
||||
simp only [getEntryLT!_eq_get!_getEntryLT?, h.getEntryLT?_eq h₁ h₂]
|
||||
|
||||
theorem getEntryLTD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {fallback : (a : α) × β a} : t₁.getEntryLTD k fallback = t₂.getEntryLTD k fallback := by
|
||||
simp only [getEntryLTD_eq_getD_getEntryLT?, h.getEntryLT?_eq h₁ h₂]
|
||||
|
||||
theorem getKeyGE?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
t₁.getKeyGE? k = t₂.getKeyGE? k := by
|
||||
simp only [getKeyGE?_eq_getEntryGE?, h.getEntryGE?_eq h₁ h₂]
|
||||
|
||||
theorem getKeyGE_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} {he} :
|
||||
t₁.getKeyGE k h₁.ordered he = t₂.getKeyGE k h₂.ordered (by simpa only [← h.mem_iff h₁ h₂]) := by
|
||||
simp only [getKeyGE_eq_getEntryGE, h.getEntryGE_eq h₁ h₂]
|
||||
|
||||
theorem getKeyGE!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} [Inhabited α] : t₁.getKeyGE! k = t₂.getKeyGE! k := by
|
||||
simp only [getKeyGE!_eq_get!_getKeyGE?, h.getKeyGE?_eq h₁ h₂]
|
||||
|
||||
theorem getKeyGED_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k fallback : α} : t₁.getKeyGED k fallback = t₂.getKeyGED k fallback := by
|
||||
simp only [getKeyGED_eq_getD_getKeyGE?, h.getKeyGE?_eq h₁ h₂]
|
||||
|
||||
theorem getKeyGT?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
t₁.getKeyGT? k = t₂.getKeyGT? k := by
|
||||
simp only [getKeyGT?_eq_getEntryGT?, h.getEntryGT?_eq h₁ h₂]
|
||||
|
||||
theorem getKeyGT_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} {he} :
|
||||
t₁.getKeyGT k h₁.ordered he = t₂.getKeyGT k h₂.ordered (by simpa only [← h.mem_iff h₁ h₂]) := by
|
||||
simp only [getKeyGT_eq_getEntryGT, h.getEntryGT_eq h₁ h₂]
|
||||
|
||||
theorem getKeyGT!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} [Inhabited α] : t₁.getKeyGT! k = t₂.getKeyGT! k := by
|
||||
simp only [getKeyGT!_eq_get!_getKeyGT?, h.getKeyGT?_eq h₁ h₂]
|
||||
|
||||
theorem getKeyGTD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k fallback : α} : t₁.getKeyGTD k fallback = t₂.getKeyGTD k fallback := by
|
||||
simp only [getKeyGTD_eq_getD_getKeyGT?, h.getKeyGT?_eq h₁ h₂]
|
||||
|
||||
theorem getKeyLE?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
t₁.getKeyLE? k = t₂.getKeyLE? k := by
|
||||
simp only [getKeyLE?_eq_getEntryLE?, h.getEntryLE?_eq h₁ h₂]
|
||||
|
||||
theorem getKeyLE_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} {he} :
|
||||
t₁.getKeyLE k h₁.ordered he = t₂.getKeyLE k h₂.ordered (by simpa only [← h.mem_iff h₁ h₂]) := by
|
||||
simp only [getKeyLE_eq_getEntryLE, h.getEntryLE_eq h₁ h₂]
|
||||
|
||||
theorem getKeyLE!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} [Inhabited α] : t₁.getKeyLE! k = t₂.getKeyLE! k := by
|
||||
simp only [getKeyLE!_eq_get!_getKeyLE?, h.getKeyLE?_eq h₁ h₂]
|
||||
|
||||
theorem getKeyLED_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k fallback : α} : t₁.getKeyLED k fallback = t₂.getKeyLED k fallback := by
|
||||
simp only [getKeyLED_eq_getD_getKeyLE?, h.getKeyLE?_eq h₁ h₂]
|
||||
|
||||
theorem getKeyLT?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
t₁.getKeyLT? k = t₂.getKeyLT? k := by
|
||||
simp only [getKeyLT?_eq_getEntryLT?, h.getEntryLT?_eq h₁ h₂]
|
||||
|
||||
theorem getKeyLT_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} {he} :
|
||||
t₁.getKeyLT k h₁.ordered he = t₂.getKeyLT k h₂.ordered (by simpa only [← h.mem_iff h₁ h₂]) := by
|
||||
simp only [getKeyLT_eq_getEntryLT, h.getEntryLT_eq h₁ h₂]
|
||||
|
||||
theorem getKeyLT!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} [Inhabited α] : t₁.getKeyLT! k = t₂.getKeyLT! k := by
|
||||
simp only [getKeyLT!_eq_get!_getKeyLT?, h.getKeyLT?_eq h₁ h₂]
|
||||
|
||||
theorem getKeyLTD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k fallback : α} : t₁.getKeyLTD k fallback = t₂.getKeyLTD k fallback := by
|
||||
simp only [getKeyLTD_eq_getD_getKeyLT?, h.getKeyLT?_eq h₁ h₂]
|
||||
|
||||
theorem insert [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {v : β k} : (t₁.insert k v h₁.balanced).impl ~m (t₂.insert k v h₂.balanced).impl := by
|
||||
simp_to_model [insert, Equiv] using List.insertEntry_of_perm _ h.1
|
||||
|
||||
theorem insert! [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {v : β k} : t₁.insert! k v ~m t₂.insert! k v := by
|
||||
simpa only [insert_eq_insert!] using h.insert h₁ h₂
|
||||
|
||||
theorem erase [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} : (t₁.erase k h₁.balanced).impl ~m (t₂.erase k h₂.balanced).impl := by
|
||||
simp_to_model [erase, Equiv] using List.eraseKey_of_perm _ h.1
|
||||
|
||||
theorem erase! [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} : t₁.erase! k ~m t₂.erase! k := by
|
||||
simpa only [erase_eq_erase!] using h.erase h₁ h₂
|
||||
|
||||
theorem insertIfNew [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {v : β k} : (t₁.insertIfNew k v h₁.balanced).impl ~m (t₂.insertIfNew k v h₂.balanced).impl := by
|
||||
simp_to_model [insertIfNew, Equiv] using List.insertEntryIfNew_of_perm _ h.1
|
||||
|
||||
theorem insertIfNew! [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {v : β k} : t₁.insertIfNew! k v ~m t₂.insertIfNew! k v := by
|
||||
simpa only [insertIfNew_eq_insertIfNew!] using h.insertIfNew h₁ h₂
|
||||
|
||||
theorem alter [TransOrd α] [LawfulEqOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {f : Option (β k) → Option (β k)} :
|
||||
(t₁.alter k f h₁.balanced).impl ~m (t₂.alter k f h₂.balanced).impl := by
|
||||
simp_to_model [alter, Equiv] using List.alterKey_of_perm _ h.1
|
||||
|
||||
theorem alter! [TransOrd α] [LawfulEqOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {f : Option (β k) → Option (β k)} :
|
||||
t₁.alter! k f ~m t₂.alter! k f := by
|
||||
simpa only [alter_eq_alter!] using h.alter h₁ h₂
|
||||
|
||||
theorem modify [TransOrd α] [LawfulEqOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {f : β k → β k} : t₁.modify k f ~m t₂.modify k f := by
|
||||
simp_to_model [modify, Equiv] using List.modifyKey_of_perm _ h.1
|
||||
|
||||
theorem filter (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {f : (a : α) → β a → Bool} :
|
||||
(t₁.filter f h₁.balanced).impl ~m (t₂.filter f h₂.balanced).impl := by
|
||||
simpa only [equiv_iff_toListModel_perm, toListModel_filter] using h.impl.filter _
|
||||
|
||||
theorem filter! (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {f : (a : α) → β a → Bool} :
|
||||
t₁.filter! f ~m t₂.filter! f := by
|
||||
simpa only [filter_eq_filter!] using h.filter h₁ h₂
|
||||
|
||||
theorem map (h : t₁ ~m t₂) {f : (a : α) → β a → γ a} : t₁.map f ~m t₂.map f := by
|
||||
simpa only [equiv_iff_toListModel_perm, toListModel_map] using h.impl.map _
|
||||
|
||||
theorem filterMap (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {f : (a : α) → β a → Option (γ a)} :
|
||||
(t₁.filterMap f h₁.balanced).impl ~m (t₂.filterMap f h₂.balanced).impl := by
|
||||
simpa only [equiv_iff_toListModel_perm, toListModel_filterMap] using h.impl.filterMap _
|
||||
|
||||
theorem filterMap! (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {f : (a : α) → β a → Option (γ a)} :
|
||||
t₁.filterMap! f ~m t₂.filterMap! f := by
|
||||
simpa only [filterMap_eq_filterMap!] using h.filterMap h₁ h₂
|
||||
|
||||
theorem insertMany_list [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{l : List ((a : α) × β a)} :
|
||||
(t₁.insertMany l h₁.balanced).1 ~m (t₂.insertMany l h₂.balanced).1 := by
|
||||
simp only [insertMany_eq_foldl]
|
||||
refine (List.foldl_rel (r := fun a b : Impl α β => a.WF ∧ b.WF ∧ a ~m b) ⟨h₁, h₂, h⟩ ?_).2.2
|
||||
intro a ha c c' hc
|
||||
refine ⟨hc.1.insert!, hc.2.1.insert!, hc.2.2.insert! hc.1 hc.2.1⟩
|
||||
|
||||
theorem insertMany!_list [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{l : List ((a : α) × β a)} :
|
||||
(t₁.insertMany! l).1 ~m (t₂.insertMany! l).1 := by
|
||||
simpa only [insertMany_eq_insertMany!] using h.insertMany_list h₁ h₂
|
||||
|
||||
theorem eraseMany_list [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{l : List α} :
|
||||
(t₁.eraseMany l h₁.balanced).1 ~m (t₂.eraseMany l h₂.balanced).1 := by
|
||||
simp only [eraseMany, bind_pure_comp, map_pure, List.forIn_pure_yield_eq_foldl, bind_pure,
|
||||
Id.run_pure]
|
||||
refine (List.foldl_rel (r := fun (a : t₁.IteratedErasureFrom) (b : t₂.IteratedErasureFrom) =>
|
||||
a.1.WF ∧ b.1.WF ∧ a.1 ~m b.1) ⟨h₁, h₂, h⟩ ?_).2.2
|
||||
intro a ha c c' hc
|
||||
refine ⟨hc.1.erase, hc.2.1.erase, hc.2.2.erase hc.1 hc.2.1⟩
|
||||
|
||||
theorem eraseMany!_list [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{l : List α} :
|
||||
(t₁.eraseMany! l).1 ~m (t₂.eraseMany! l).1 := by
|
||||
simp only [eraseMany!, bind_pure_comp, map_pure, List.forIn_pure_yield_eq_foldl, bind_pure,
|
||||
Id.run_pure]
|
||||
refine (List.foldl_rel (r := fun (a : t₁.IteratedSlowErasureFrom) (b : t₂.IteratedSlowErasureFrom) =>
|
||||
a.1.WF ∧ b.1.WF ∧ a.1 ~m b.1) ⟨h₁, h₂, h⟩ ?_).2.2
|
||||
intro a ha c c' hc
|
||||
refine ⟨hc.1.erase!, hc.2.1.erase!, hc.2.2.erase! hc.1 hc.2.1⟩
|
||||
|
||||
theorem mergeWith [TransOrd α] [LawfulEqOrd α]
|
||||
(h : t₁ ~m t₂) (h' : t₃ ~m t₄)
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h₃ : t₃.WF) (h₄ : t₄.WF)
|
||||
{f : (a : α) → β a → β a → β a} :
|
||||
(t₁.mergeWith f t₃ h₁.balanced).impl ~m (t₂.mergeWith f t₄ h₂.balanced).impl := by
|
||||
simp only [Impl.mergeWith, h'.foldl_eq h₃ h₄, foldl_eq_foldl]
|
||||
refine (List.foldl_rel (r := fun a b : BalancedTree α β =>
|
||||
a.impl.WF ∧ b.impl.WF ∧ a.impl ~m b.impl) ⟨h₁, h₂, h⟩ ?_).2.2
|
||||
intro a ha c c' hc
|
||||
exact ⟨hc.1.alter, hc.2.1.alter, hc.2.2.alter hc.1 hc.2.1⟩
|
||||
|
||||
theorem mergeWith! [TransOrd α] [LawfulEqOrd α]
|
||||
(h : t₁ ~m t₂) (h' : t₃ ~m t₄)
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h₃ : t₃.WF) (h₄ : t₄.WF)
|
||||
{f : (a : α) → β a → β a → β a} :
|
||||
t₁.mergeWith! f t₃ ~m t₂.mergeWith! f t₄ := by
|
||||
simpa only [mergeWith_eq_mergeWith!] using h.mergeWith h' h₁ h₂ h₃ h₄
|
||||
|
||||
section Const
|
||||
|
||||
variable {β : Type v} {t₁ t₂ t₃ t₄ : Impl α β} {δ : Type w} {m : Type w → Type w}
|
||||
|
||||
theorem constGet?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
Const.get? t₁ k = Const.get? t₂ k := by
|
||||
simp_to_model [Const.get?] using List.getValue?_of_perm _ h.1
|
||||
|
||||
theorem constGet_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} (hk : k ∈ t₁) : Const.get t₁ k hk = Const.get t₂ k ((h.mem_iff h₁ h₂).mp hk) := by
|
||||
simp_to_model [Const.get] using List.getValue_of_perm _ h.1
|
||||
|
||||
theorem constGet!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} [Inhabited β] : Const.get! t₁ k = Const.get! t₂ k := by
|
||||
simp_to_model [Const.get!] using List.getValue!_of_perm _ h.1
|
||||
|
||||
theorem constGetD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {fallback : β} : Const.getD t₁ k fallback = Const.getD t₂ k fallback := by
|
||||
simp_to_model [Const.getD] using List.getValueD_of_perm _ h.1
|
||||
|
||||
theorem constToList_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.toList t₁ = Const.toList t₂ := by
|
||||
simp_to_model [Const.toList] using congrArg _ (h.toListModel_eq ..)
|
||||
|
||||
theorem constToArray_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.toArray t₁ = Const.toArray t₂ := by
|
||||
simp only [Const.toArray_eq_toArray_map, h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem values_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.values = t₂.values := by
|
||||
simp only [values_eq_map_snd, h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem valuesArray_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.valuesArray = t₂.valuesArray := by
|
||||
simp only [valuesArray_eq_toArray_map, h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem constMinEntry?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.minEntry? t₁ = Const.minEntry? t₂ := by
|
||||
simp only [Const.minEntry?_eq_minEntry?, h.minEntry?_eq h₁ h₂]
|
||||
|
||||
theorem constMinEntry_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {he} :
|
||||
Const.minEntry t₁ he = Const.minEntry t₂ (h.isEmpty_eq.symm.trans he) := by
|
||||
apply Option.some.inj
|
||||
simp only [Const.some_minEntry_eq_minEntry?, h.constMinEntry?_eq h₁ h₂]
|
||||
|
||||
theorem constMinEntry!_eq [TransOrd α] [Inhabited (α × β)]
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : Const.minEntry! t₁ = Const.minEntry! t₂ := by
|
||||
simp only [Const.minEntry!_eq_get!_minEntry?, h.constMinEntry?_eq h₁ h₂]
|
||||
|
||||
theorem constMinEntryD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{fallback : α × β} : Const.minEntryD t₁ fallback = Const.minEntryD t₂ fallback := by
|
||||
simp only [Const.minEntryD_eq_getD_minEntry?, h.constMinEntry?_eq h₁ h₂]
|
||||
|
||||
theorem constMaxEntry?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.maxEntry? t₁ = Const.maxEntry? t₂ := by
|
||||
simp only [Const.maxEntry?_eq_maxEntry?, h.maxEntry?_eq h₁ h₂]
|
||||
|
||||
theorem constMaxEntry_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {he} :
|
||||
Const.maxEntry t₁ he = Const.maxEntry t₂ (h.isEmpty_eq.symm.trans he) := by
|
||||
apply Option.some.inj
|
||||
simp only [Const.some_maxEntry_eq_maxEntry?, h.constMaxEntry?_eq h₁ h₂]
|
||||
|
||||
theorem constMaxEntry!_eq [TransOrd α] [Inhabited (α × β)]
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : Const.maxEntry! t₁ = Const.maxEntry! t₂ := by
|
||||
simp only [Const.maxEntry!_eq_get!_maxEntry?, h.constMaxEntry?_eq h₁ h₂]
|
||||
|
||||
theorem constMaxEntryD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{fallback : α × β} : Const.maxEntryD t₁ fallback = Const.maxEntryD t₂ fallback := by
|
||||
simp only [Const.maxEntryD_eq_getD_maxEntry?, h.constMaxEntry?_eq h₁ h₂]
|
||||
|
||||
theorem constEntryAtIdx?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {i : Nat} :
|
||||
Const.entryAtIdx? t₁ i = Const.entryAtIdx? t₂ i := by
|
||||
simp_to_model [Const.entryAtIdx?]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem constEntryAtIdx_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {i : Nat} {h'} :
|
||||
Const.entryAtIdx t₁ h₁.balanced i h' = Const.entryAtIdx t₂ h₂.balanced i (h.size_eq h₁ h₂ ▸ h') := by
|
||||
simp_to_model [Const.entryAtIdx]
|
||||
simp only [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem constEntryAtIdx!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {i : Nat}
|
||||
[Inhabited (α × β)] : Const.entryAtIdx! t₁ i = Const.entryAtIdx! t₂ i := by
|
||||
simp_to_model [Const.entryAtIdx!]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem constEntryAtIdxD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {i : Nat}
|
||||
{fallback : α × β} : Const.entryAtIdxD t₁ i fallback = Const.entryAtIdxD t₂ i fallback := by
|
||||
simp_to_model [Const.entryAtIdxD]
|
||||
rw [h.toListModel_eq h₁.ordered h₂.ordered]
|
||||
|
||||
theorem constGetEntryGE?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
Const.getEntryGE? k t₁ = Const.getEntryGE? k t₂ := by
|
||||
simp only [Const.getEntryGE?_eq_map, h.getEntryGE?_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryGE_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} {he} :
|
||||
Const.getEntryGE k t₁ h₁.ordered he = Const.getEntryGE k t₂ h₂.ordered (by simpa only [← h.mem_iff h₁ h₂]) := by
|
||||
simp only [Const.getEntryGE_eq, h.getEntryGE_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryGE!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} [Inhabited (α × β)] : Const.getEntryGE! k t₁ = Const.getEntryGE! k t₂ := by
|
||||
simp only [Const.getEntryGE!_eq_get!_getEntryGE?, h.constGetEntryGE?_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryGED_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {fallback : α × β} : Const.getEntryGED k t₁ fallback = Const.getEntryGED k t₂ fallback := by
|
||||
simp only [Const.getEntryGED_eq_getD_getEntryGE?, h.constGetEntryGE?_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryGT?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
Const.getEntryGT? k t₁ = Const.getEntryGT? k t₂ := by
|
||||
simp only [Const.getEntryGT?_eq_map, h.getEntryGT?_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryGT_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} {he} :
|
||||
Const.getEntryGT k t₁ h₁.ordered he = Const.getEntryGT k t₂ h₂.ordered (by simpa only [← h.mem_iff h₁ h₂]) := by
|
||||
simp only [Const.getEntryGT_eq, h.getEntryGT_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryGT!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} [Inhabited (α × β)] : Const.getEntryGT! k t₁ = Const.getEntryGT! k t₂ := by
|
||||
simp only [Const.getEntryGT!_eq_get!_getEntryGT?, h.constGetEntryGT?_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryGTD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α}
|
||||
{fallback : α × β} : Const.getEntryGTD k t₁ fallback = Const.getEntryGTD k t₂ fallback := by
|
||||
simp only [Const.getEntryGTD_eq_getD_getEntryGT?, h.constGetEntryGT?_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryLE?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
Const.getEntryLE? k t₁ = Const.getEntryLE? k t₂ := by
|
||||
simp only [Const.getEntryLE?_eq_map, h.getEntryLE?_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryLE_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} {he} :
|
||||
Const.getEntryLE k t₁ h₁.ordered he = Const.getEntryLE k t₂ h₂.ordered (by simpa only [← h.mem_iff h₁ h₂]) := by
|
||||
simp only [Const.getEntryLE_eq, h.getEntryLE_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryLE!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} [Inhabited (α × β)] : Const.getEntryLE! k t₁ = Const.getEntryLE! k t₂ := by
|
||||
simp only [Const.getEntryLE!_eq_get!_getEntryLE?, h.constGetEntryLE?_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryLED_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α}
|
||||
{fallback : α × β} : Const.getEntryLED k t₁ fallback = Const.getEntryLED k t₂ fallback := by
|
||||
simp only [Const.getEntryLED_eq_getD_getEntryLE?, h.constGetEntryLE?_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryLT?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} :
|
||||
Const.getEntryLT? k t₁ = Const.getEntryLT? k t₂ := by
|
||||
simp only [Const.getEntryLT?_eq_map, h.getEntryLT?_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryLT_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α} {he} :
|
||||
Const.getEntryLT k t₁ h₁.ordered he = Const.getEntryLT k t₂ h₂.ordered (by simpa only [← h.mem_iff h₁ h₂]) := by
|
||||
simp only [Const.getEntryLT_eq, h.getEntryLT_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryLT!_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} [Inhabited (α × β)] : Const.getEntryLT! k t₁ = Const.getEntryLT! k t₂ := by
|
||||
simp only [Const.getEntryLT!_eq_get!_getEntryLT?, h.constGetEntryLT?_eq h₁ h₂]
|
||||
|
||||
theorem constGetEntryLTD_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {k : α}
|
||||
{fallback : α × β} : Const.getEntryLTD k t₁ fallback = Const.getEntryLTD k t₂ fallback := by
|
||||
simp only [Const.getEntryLTD_eq_getD_getEntryLT?, h.constGetEntryLT?_eq h₁ h₂]
|
||||
|
||||
theorem constAlter [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {f : Option β → Option β} :
|
||||
(Const.alter k f t₁ h₁.balanced).impl ~m (Const.alter k f t₂ h₂.balanced).impl := by
|
||||
simp_to_model [Const.alter, Equiv] using List.Const.alterKey_of_perm _ h.1
|
||||
|
||||
theorem constAlter! [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {f : Option β → Option β} :
|
||||
Const.alter! k f t₁ ~m Const.alter! k f t₂ := by
|
||||
simpa only [Const.alter_eq_alter!] using h.constAlter h₁ h₂
|
||||
|
||||
theorem constModify [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{k : α} {f : β → β} : Const.modify k f t₁ ~m Const.modify k f t₂ := by
|
||||
simp_to_model [Const.modify, Equiv] using List.Const.modifyKey_of_perm _ h.1
|
||||
|
||||
theorem constInsertMany_list [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{l : List (α × β)} :
|
||||
(Const.insertMany t₁ l h₁.balanced).1 ~m (Const.insertMany t₂ l h₂.balanced).1 := by
|
||||
simp only [Const.insertMany_eq_foldl]
|
||||
refine (List.foldl_rel (r := fun a b : Impl α β => a.WF ∧ b.WF ∧ a ~m b) ⟨h₁, h₂, h⟩ ?_).2.2
|
||||
intro a ha c c' hc
|
||||
refine ⟨hc.1.insert!, hc.2.1.insert!, hc.2.2.insert! hc.1 hc.2.1⟩
|
||||
|
||||
theorem constInsertMany!_list [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
{l : List (α × β)} :
|
||||
(Const.insertMany! t₁ l).1 ~m (Const.insertMany! t₂ l).1 := by
|
||||
simpa only [Const.insertMany_eq_insertMany!] using h.constInsertMany_list h₁ h₂
|
||||
|
||||
theorem constInsertManyIfNewUnit_list [TransOrd α] {t₁ t₂ : Impl α Unit}
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {l : List α} :
|
||||
(Const.insertManyIfNewUnit t₁ l h₁.balanced).1 ~m (Const.insertManyIfNewUnit t₂ l h₂.balanced).1 := by
|
||||
simp only [Const.insertManyIfNewUnit_eq_foldl]
|
||||
refine (List.foldl_rel (r := fun a b : Impl α Unit => a.WF ∧ b.WF ∧ a ~m b) ⟨h₁, h₂, h⟩ ?_).2.2
|
||||
intro a ha c c' hc
|
||||
refine ⟨hc.1.insertIfNew!, hc.2.1.insertIfNew!, hc.2.2.insertIfNew! hc.1 hc.2.1⟩
|
||||
|
||||
theorem constInsertManyIfNewUnit!_list [TransOrd α] {t₁ t₂ : Impl α Unit}
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) {l : List α} :
|
||||
(Const.insertManyIfNewUnit! t₁ l).1 ~m (Const.insertManyIfNewUnit! t₂ l).1 := by
|
||||
simpa only [Const.insertManyIfNewUnit_eq_insertManyIfNewUnit!] using h.constInsertManyIfNewUnit_list h₁ h₂
|
||||
|
||||
theorem constMergeWith [TransOrd α]
|
||||
(h : t₁ ~m t₂) (h' : t₃ ~m t₄)
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h₃ : t₃.WF) (h₄ : t₄.WF)
|
||||
{f : α → β → β → β} :
|
||||
(Const.mergeWith f t₁ t₃ h₁.balanced).impl ~m (Const.mergeWith f t₂ t₄ h₂.balanced).impl := by
|
||||
simp only [Impl.Const.mergeWith, h'.foldl_eq h₃ h₄, foldl_eq_foldl]
|
||||
refine (List.foldl_rel (r := fun a b : BalancedTree α β =>
|
||||
a.impl.WF ∧ b.impl.WF ∧ a.impl ~m b.impl) ⟨h₁, h₂, h⟩ ?_).2.2
|
||||
intro a ha c c' hc
|
||||
exact ⟨hc.1.constAlter, hc.2.1.constAlter, hc.2.2.constAlter hc.1 hc.2.1⟩
|
||||
|
||||
theorem constMergeWith! [TransOrd α]
|
||||
(h : t₁ ~m t₂) (h' : t₃ ~m t₄)
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h₃ : t₃.WF) (h₄ : t₄.WF)
|
||||
{f : α → β → β → β} :
|
||||
Const.mergeWith! f t₁ t₃ ~m Const.mergeWith! f t₂ t₄ := by
|
||||
simpa only [Const.mergeWith_eq_mergeWith!] using h.constMergeWith h' h₁ h₂ h₃ h₄
|
||||
|
||||
end Const
|
||||
|
||||
-- extensionalities
|
||||
|
||||
theorem of_forall_get?_eq [TransOrd α] [LawfulEqOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) :
|
||||
(∀ k, t₁.get? k = t₂.get? k) → t₁ ~m t₂ := by
|
||||
simp_to_model [get?, Equiv] using List.getValueCast?_ext
|
||||
|
||||
section Const
|
||||
|
||||
variable {β : Type v} {t₁ t₂ : Impl α β}
|
||||
|
||||
theorem of_forall_getKey_eq_of_forall_constGet?_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) :
|
||||
(∀ k hk hk', t₁.getKey k hk = t₂.getKey k hk') →
|
||||
(∀ k, Const.get? t₁ k = Const.get? t₂ k) → t₁ ~m t₂ := by
|
||||
simp_to_model [Const.get?, Equiv, getKey, contains] using List.getKey_getValue?_ext
|
||||
|
||||
theorem of_forall_constGet?_eq [TransOrd α] [LawfulEqOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) :
|
||||
(∀ k, Const.get? t₁ k = Const.get? t₂ k) → t₁ ~m t₂ := by
|
||||
simp_to_model [Const.get?, Equiv]
|
||||
simpa only [getValue?_eq_getValueCast?] using
|
||||
List.getValueCast?_ext h₁.ordered.distinctKeys h₂.ordered.distinctKeys
|
||||
|
||||
theorem of_forall_getKey?_unit_eq [TransOrd α] {t₁ t₂ : Impl α fun _ => Unit}
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) : (∀ k, t₁.getKey? k = t₂.getKey? k) → t₁ ~m t₂ := by
|
||||
simp_to_model [getKey?, Equiv] using List.getKey?_ext
|
||||
|
||||
theorem of_forall_contains_unit_eq [TransOrd α] [LawfulEqOrd α]
|
||||
{t₁ t₂ : Impl α fun _ => Unit} (h₁ : t₁.WF) (h₂ : t₂.WF) :
|
||||
(∀ k, t₁.contains k = t₂.contains k) → t₁ ~m t₂ := by
|
||||
simp_to_model [contains, Equiv] using List.containsKey_ext
|
||||
|
||||
theorem of_forall_mem_unit_iff [TransOrd α] [LawfulEqOrd α]
|
||||
{t₁ t₂ : Impl α Unit} (h₁ : t₁.WF) (h₂ : t₂.WF) :
|
||||
(∀ k, k ∈ t₁ ↔ k ∈ t₂) → t₁ ~m t₂ := by
|
||||
simpa [mem_iff_contains] using of_forall_contains_unit_eq h₁ h₂
|
||||
|
||||
end Const
|
||||
|
||||
end Equiv
|
||||
|
||||
section Equiv
|
||||
|
||||
variable {t₁ t₂ : Impl α β}
|
||||
|
||||
theorem equiv_empty_iff_isEmpty : t ~m empty ↔ t.isEmpty := by
|
||||
simp [equiv_iff_toListModel_perm, isEmpty_eq_isEmpty]
|
||||
|
||||
theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
|
||||
Equiv.comm.trans equiv_empty_iff_isEmpty
|
||||
|
||||
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList := by
|
||||
simp_to_model [toList, Equiv]
|
||||
|
||||
theorem Equiv.of_toList_perm : t₁.toList.Perm t₂.toList → t₁ ~m t₂ :=
|
||||
equiv_iff_toList_perm.mpr
|
||||
|
||||
theorem equiv_iff_toList_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) :
|
||||
t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
|
||||
⟨Equiv.toList_eq h₁ h₂, .of_toList_perm ∘ .of_eq⟩
|
||||
|
||||
section Const
|
||||
|
||||
variable {β : Type v} {t₁ t₂ : Impl α β}
|
||||
|
||||
theorem Const.equiv_iff_toList_perm : t₁ ~m t₂ ↔ (Const.toList t₁).Perm (Const.toList t₂) := by
|
||||
simp_to_model [Const.toList, Equiv]
|
||||
constructor
|
||||
· exact List.Perm.map _
|
||||
· intro h
|
||||
have := h.map (fun (x, y) => (⟨x, y⟩ : (_ : α) × β))
|
||||
simpa only [List.map_map, Function.comp_def, List.map_id'] using this
|
||||
|
||||
theorem Const.equiv_iff_toList_eq [TransOrd α] (h₁ : t₁.WF) (h₂ : t₂.WF) :
|
||||
t₁ ~m t₂ ↔ Const.toList t₁ = Const.toList t₂ := by
|
||||
simp_to_model [Const.toList]
|
||||
rw [List.map_inj_right fun _ _ => congrArg fun x : α × β => (⟨x.1, x.2⟩ : (_ : α) × β)]
|
||||
exact ⟨(·.toListModel_eq h₁.ordered h₂.ordered), .mk ∘ .of_eq⟩
|
||||
|
||||
theorem Const.equiv_iff_keys_perm {t₁ t₂ : Impl α Unit} :
|
||||
t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys := by
|
||||
simp_to_model [keys, Equiv]
|
||||
simp only [List.keys_eq_map]
|
||||
constructor
|
||||
· exact List.Perm.map _
|
||||
· intro h
|
||||
have := h.map (fun x => (⟨x, ()⟩ : (_ : α) × Unit))
|
||||
simpa only [List.map_map, Function.comp_def, List.map_id'] using this
|
||||
|
||||
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
|
||||
simp_to_model [keys]
|
||||
simp only [List.keys_eq_map]
|
||||
rw [List.map_inj_right fun _ _ => congrArg fun x : α => (⟨x, ()⟩ : (_ : α) × Unit)]
|
||||
exact ⟨(·.toListModel_eq h₁.ordered h₂.ordered), .mk ∘ .of_eq⟩
|
||||
|
||||
end Const
|
||||
|
||||
end Equiv
|
||||
|
||||
end Std.DTreeMap.Internal.Impl
|
||||
|
|
|
|||
|
|
@ -116,6 +116,100 @@ def explore {γ : Type w} [Ord α] (k : α → Ordering) (init : γ)
|
|||
| .eq => inner init <| .eq l.toListModel (Cell.ofEq ky y h) r.toListModel
|
||||
| .gt => explore k (inner init <| .gt l.toListModel ky h y) inner r
|
||||
|
||||
/-
|
||||
Note: these congruence lemmas are proven manually because `simp` currently can't handle
|
||||
matches with hypotheses on discriminants properly.
|
||||
-/
|
||||
|
||||
@[congr]
|
||||
theorem applyPartition.go.match_1.congr {α : Sort u} {o o' : Ordering}
|
||||
{lt : o = .lt → α} {eq : o = .eq → α} {gt : o = .gt → α}
|
||||
{lt' : o' = .lt → α} {eq' : o' = .eq → α} {gt' : o' = .gt → α}
|
||||
(ho : o = o')
|
||||
(hlt : ∀ h, lt (ho.trans h) = lt' h)
|
||||
(heq : ∀ h, eq (ho.trans h) = eq' h)
|
||||
(hgt : ∀ h, gt (ho.trans h) = gt' h) :
|
||||
(match (generalizing := false) h : o with | .lt => lt h | .eq => eq h | .gt => gt h) =
|
||||
(match (generalizing := false) h : o' with | .lt => lt' h | .eq => eq' h | .gt => gt' h) := by
|
||||
induction ho; induction funext hlt; induction funext heq; induction funext hgt
|
||||
rfl
|
||||
|
||||
@[congr]
|
||||
theorem entryAtIdx.match_1.congr {α : Sort u} {o o' : Ordering}
|
||||
{lt : o = .lt → α} {eq : o = .eq → α} {gt : o = .gt → α}
|
||||
{lt' : o' = .lt → α} {eq' : o' = .eq → α} {gt' : o' = .gt → α}
|
||||
(ho : o = o')
|
||||
(hlt : ∀ h, lt (ho.trans h) = lt' h)
|
||||
(heq : ∀ h, eq (ho.trans h) = eq' h)
|
||||
(hgt : ∀ h, gt (ho.trans h) = gt' h) :
|
||||
entryAtIdx.match_1 (fun _ => α) o lt eq gt = entryAtIdx.match_1 (fun _ => α) o' lt' eq' gt' := by
|
||||
induction ho; induction funext hlt; induction funext heq; induction funext hgt
|
||||
rfl
|
||||
|
||||
@[congr]
|
||||
theorem getEntryLE.match_1.congr {α : Sort u} {o o' : Ordering}
|
||||
{lt : o = .lt → α} {eq : o = .eq → α} {gt : o = .gt → α}
|
||||
{lt' : o' = .lt → α} {eq' : o' = .eq → α} {gt' : o' = .gt → α}
|
||||
(ho : o = o')
|
||||
(hlt : ∀ h, lt (ho.trans h) = lt' h)
|
||||
(heq : ∀ h, eq (ho.trans h) = eq' h)
|
||||
(hgt : ∀ h, gt (ho.trans h) = gt' h) :
|
||||
getEntryLE.match_1 (fun _ => α) o gt eq lt = getEntryLE.match_1 (fun _ => α) o' gt' eq' lt' := by
|
||||
induction ho; induction funext hlt; induction funext heq; induction funext hgt
|
||||
rfl
|
||||
|
||||
@[congr]
|
||||
theorem get?.match_1.congr {α : Sort u} {o o' : Ordering}
|
||||
{lt : o = .lt → α} {eq : o = .eq → α} {gt : o = .gt → α}
|
||||
{lt' : o' = .lt → α} {eq' : o' = .eq → α} {gt' : o' = .gt → α}
|
||||
(ho : o = o')
|
||||
(hlt : ∀ h, lt (ho.trans h) = lt' h)
|
||||
(heq : ∀ h, eq (ho.trans h) = eq' h)
|
||||
(hgt : ∀ h, gt (ho.trans h) = gt' h) :
|
||||
get?.match_1 (fun _ => α) o lt gt eq = get?.match_1 (fun _ => α) o' lt' gt' eq' := by
|
||||
induction ho; induction funext hlt; induction funext heq; induction funext hgt
|
||||
rfl
|
||||
|
||||
/--
|
||||
Induction principle on `Impl` with an additional case split on `k ky` for
|
||||
`Impl.inner _ ky _ _ _` without generalization.
|
||||
-/
|
||||
@[elab_as_elim]
|
||||
theorem tree_split_ind_no_gen [Ord α] (k : α → Ordering)
|
||||
{motive : (l : Impl α β) → Prop}
|
||||
(leaf : motive .leaf)
|
||||
(lt : ∀ n ky y l r, (h : k ky = .lt) →
|
||||
motive l → motive (.inner n ky y l r))
|
||||
(eq : ∀ n ky y l r, (h : k ky = .eq) →
|
||||
motive l → motive r → motive (.inner n ky y l r))
|
||||
(gt : ∀ n ky y l r, (h : k ky = .gt) →
|
||||
motive r → motive (.inner n ky y l r))
|
||||
(t : Impl α β) : motive t := by
|
||||
induction t with
|
||||
| leaf => exact leaf
|
||||
| inner n ky v l r ih ih' =>
|
||||
cases h : k ky
|
||||
· exact lt n ky v l r h ih
|
||||
· exact eq n ky v l r h ih ih'
|
||||
· exact gt n ky v l r h ih'
|
||||
|
||||
/--
|
||||
Induction principle on `Impl` with an additional case split on `k ky` for
|
||||
`Impl.inner _ ky _ _ _` and a generalization built in for convenience.
|
||||
-/
|
||||
@[elab_as_elim]
|
||||
theorem tree_split_ind {γ : Sort w} [Ord α] (k : α → Ordering)
|
||||
{motive : (l : Impl α β) → γ → Prop}
|
||||
(leaf : ∀ x, motive .leaf x)
|
||||
(lt : ∀ n ky y l r, (h : k ky = .lt) →
|
||||
(∀ x, motive l x) → ∀ x, motive (.inner n ky y l r) x)
|
||||
(eq : ∀ n ky y l r, (h : k ky = .eq) →
|
||||
(∀ x, motive l x) → (∀ x, motive r x) → ∀ x, motive (.inner n ky y l r) x)
|
||||
(gt : ∀ n ky y l r, (h : k ky = .gt) →
|
||||
(∀ x, motive r x) → ∀ x, motive (.inner n ky y l r) x)
|
||||
(t : Impl α β) : (x : γ) → motive t x :=
|
||||
tree_split_ind_no_gen k leaf lt eq gt t
|
||||
|
||||
open ExplorationStep
|
||||
|
||||
theorem applyPartition_go_step [Ord α] {k : α → Ordering} {init : δ} (l₁ l₂) (l l' : Impl α β) (h)
|
||||
|
|
@ -376,7 +470,7 @@ theorem contains_eq_containsₘ [Ord α] (k : α) (l : Impl α β) :
|
|||
simp only [containsₘ]
|
||||
induction l
|
||||
· simp only [contains, applyCell]
|
||||
split <;> split <;> simp_all
|
||||
split <;> simp_all
|
||||
· simp [contains, applyCell]
|
||||
|
||||
theorem get?_eq_get?ₘ [Ord α] [OrientedOrd α] [LawfulEqOrd α] (k : α) (l : Impl α β) :
|
||||
|
|
@ -384,15 +478,14 @@ theorem get?_eq_get?ₘ [Ord α] [OrientedOrd α] [LawfulEqOrd α] (k : α) (l :
|
|||
simp only [get?ₘ]
|
||||
induction l
|
||||
· simp only [applyCell, get?]
|
||||
split <;> rename_i hcmp₁ <;> split <;> rename_i hcmp₂ <;> try (simp [hcmp₁] at hcmp₂; done)
|
||||
all_goals simp_all [Cell.get?, Cell.ofEq]
|
||||
split <;> simp_all [Cell.get?, Cell.ofEq]
|
||||
· simp [get?, applyCell]
|
||||
|
||||
theorem get_eq_get? [Ord α] [OrientedOrd α] [LawfulEqOrd α] (k : α) (l : Impl α β) {h} :
|
||||
some (l.get k h) = l.get? k := by
|
||||
induction l
|
||||
· simp only [applyCell, get, get?]
|
||||
split <;> rename_i ihl ihr hcmp <;> simp_all
|
||||
split <;> simp_all
|
||||
· contradiction
|
||||
|
||||
theorem get_eq_getₘ [Ord α] [OrientedOrd α] [LawfulEqOrd α] (k : α) (l : Impl α β) {h} (h') :
|
||||
|
|
@ -405,8 +498,7 @@ theorem get!_eq_get!ₘ [Ord α] [OrientedOrd α] [LawfulEqOrd α] (k : α) [Inh
|
|||
simp only [get!ₘ, get?ₘ]
|
||||
induction l
|
||||
· simp only [applyCell, get!]
|
||||
split <;> rename_i hcmp₁ <;> split <;> rename_i hcmp₂ <;> try (simp [hcmp₁] at hcmp₂; done)
|
||||
all_goals simp_all [Cell.get?, Cell.ofEq]
|
||||
split <;> simp_all [Cell.get?, Cell.ofEq]
|
||||
· simp only [get!, applyCell, Cell.get?_empty, Option.get!_none]; rfl
|
||||
|
||||
theorem getD_eq_getDₘ [Ord α] [OrientedOrd α] [LawfulEqOrd α] (k : α) (l : Impl α β)
|
||||
|
|
@ -414,8 +506,7 @@ theorem getD_eq_getDₘ [Ord α] [OrientedOrd α] [LawfulEqOrd α] (k : α) (l :
|
|||
simp only [getDₘ, get?ₘ]
|
||||
induction l
|
||||
· simp only [applyCell, getD]
|
||||
split <;> rename_i hcmp₁ <;> split <;> rename_i hcmp₂ <;> try (simp [hcmp₁] at hcmp₂; done)
|
||||
all_goals simp_all [Cell.get?, Cell.ofEq]
|
||||
split <;> simp_all [Cell.get?, Cell.ofEq]
|
||||
· simp only [getD, applyCell, Cell.get?_empty, Option.getD_none]
|
||||
|
||||
theorem getKey?_eq_getKey?ₘ [Ord α] (k : α) (l : Impl α β) :
|
||||
|
|
@ -423,15 +514,14 @@ theorem getKey?_eq_getKey?ₘ [Ord α] (k : α) (l : Impl α β) :
|
|||
simp only [getKey?ₘ]
|
||||
induction l
|
||||
· simp only [applyCell, getKey?]
|
||||
split <;> rename_i hcmp₁ <;> split <;> rename_i hcmp₂ <;> try (simp [hcmp₁] at hcmp₂; done)
|
||||
all_goals simp_all [Cell.getKey?, Cell.ofEq]
|
||||
split <;> simp_all [Cell.getKey?, Cell.ofEq]
|
||||
· simp [getKey?, applyCell]
|
||||
|
||||
theorem getKey_eq_getKey? [Ord α] (k : α) (l : Impl α β) {h} :
|
||||
some (l.getKey k h) = l.getKey? k := by
|
||||
induction l
|
||||
· simp only [applyCell, getKey, getKey?]
|
||||
split <;> rename_i ihl ihr hcmp <;> simp_all
|
||||
split <;> simp_all
|
||||
· contradiction
|
||||
|
||||
theorem getKey_eq_getKeyₘ [Ord α] (k : α) (l : Impl α β) {h} (h') :
|
||||
|
|
@ -444,8 +534,7 @@ theorem getKey!_eq_getKey!ₘ [Ord α] (k : α) [Inhabited α] (l : Impl α β)
|
|||
simp only [getKey!ₘ, getKey?ₘ]
|
||||
induction l
|
||||
· simp only [applyCell, getKey!]
|
||||
split <;> rename_i hcmp₁ <;> split <;> rename_i hcmp₂ <;> try (simp [hcmp₁] at hcmp₂; done)
|
||||
all_goals simp_all [Cell.getKey?, Cell.ofEq]
|
||||
split <;> simp_all [Cell.getKey?, Cell.ofEq]
|
||||
· simp only [getKey!, applyCell, Cell.getKey?_empty, Option.get!_none]; rfl
|
||||
|
||||
theorem getKeyD_eq_getKeyDₘ [Ord α] (k : α) (l : Impl α β)
|
||||
|
|
@ -453,8 +542,7 @@ theorem getKeyD_eq_getKeyDₘ [Ord α] (k : α) (l : Impl α β)
|
|||
simp only [getKeyDₘ, getKey?ₘ]
|
||||
induction l
|
||||
· simp only [applyCell, getKeyD]
|
||||
split <;> rename_i hcmp₁ <;> split <;> rename_i hcmp₂ <;> try (simp [hcmp₁] at hcmp₂; done)
|
||||
all_goals simp_all [Cell.getKey?, Cell.ofEq]
|
||||
split <;> simp_all [Cell.getKey?, Cell.ofEq]
|
||||
· simp only [getKeyD, applyCell, Cell.getKey?_empty, Option.getD_none]
|
||||
|
||||
theorem minEntry?_eq_minEntry?ₘ' [Ord α] {l : Impl α β} : l.minEntry? = l.minEntry?ₘ' := by
|
||||
|
|
@ -467,47 +555,105 @@ theorem minEntry?ₘ'_eq_minEntry?ₘ [Ord α] {l : Impl α β} : l.minEntry?ₘ
|
|||
theorem minEntry?_eq_minEntry?ₘ [Ord α] {l : Impl α β} : l.minEntry? = l.minEntry?ₘ := by
|
||||
rw [minEntry?_eq_minEntry?ₘ', minEntry?ₘ'_eq_minEntry?ₘ]
|
||||
|
||||
theorem minKey?_eq_minEntry?_map_fst [Ord α] {l : Impl α β} : l.minKey? = l.minEntry?.map Sigma.fst := by
|
||||
induction l using minKey?.induct <;> simp only [minKey?, minEntry?] <;> trivial
|
||||
theorem minEntry!_eq_get!_minEntry? [Inhabited ((a : α) × β a)] {l : Impl α β} :
|
||||
l.minEntry! = l.minEntry?.get! := by
|
||||
induction l using minEntry?.induct_unfolding <;> simp only [minEntry!] <;> trivial
|
||||
|
||||
theorem some_minEntry_eq_minEntry? [Ord α] {l : Impl α β} {he} :
|
||||
theorem minEntryD_eq_getD_minEntry? {l : Impl α β} {fallback : (a : α) × β a} :
|
||||
l.minEntryD fallback = l.minEntry?.getD fallback := by
|
||||
induction l using minEntry?.induct_unfolding <;> simp only [minEntryD] <;> trivial
|
||||
|
||||
theorem some_minEntry_eq_minEntry? {l : Impl α β} {he} :
|
||||
some (l.minEntry he) = l.minEntry? := by
|
||||
induction l, he using minEntry.induct <;> simp_all [minEntry, minEntry?]
|
||||
induction l, he using minEntry.induct_unfolding <;> simp only [minEntry?] <;> assumption
|
||||
|
||||
theorem minEntry_eq_get_minEntry? [Ord α] {l : Impl α β} {he} :
|
||||
theorem minEntry_eq_get_minEntry? {l : Impl α β} {he} :
|
||||
l.minEntry he = l.minEntry?.get (by simp [← some_minEntry_eq_minEntry? (he := he)]) := by
|
||||
simp [← some_minEntry_eq_minEntry? (he := he)]
|
||||
|
||||
theorem minKey_eq_minEntry_fst [Ord α] {l : Impl α β} {he} : l.minKey he = (l.minEntry he).fst := by
|
||||
induction l, he using minKey.induct <;> simp only [minKey, minEntry] <;> trivial
|
||||
theorem maxEntry?_eq_minEntry?_reverse {l : Impl α β} : l.maxEntry? = l.reverse.minEntry? := by
|
||||
induction l using maxEntry?.induct_unfolding <;> simp only [minEntry?, reverse] <;> assumption
|
||||
|
||||
theorem minKey!_eq_get!_minKey? [Ord α] [Inhabited α] {l : Impl α β} :
|
||||
theorem maxEntry!_eq_get!_maxEntry? [Inhabited ((a : α) × β a)] {l : Impl α β} :
|
||||
l.maxEntry! = l.maxEntry?.get! := by
|
||||
induction l using maxEntry?.induct_unfolding <;> simp only [maxEntry!] <;> trivial
|
||||
|
||||
theorem maxEntryD_eq_getD_maxEntry? {l : Impl α β} {fallback : (a : α) × β a} :
|
||||
l.maxEntryD fallback = l.maxEntry?.getD fallback := by
|
||||
induction l using maxEntry?.induct_unfolding <;> simp only [maxEntryD] <;> trivial
|
||||
|
||||
theorem some_maxEntry_eq_maxEntry? {l : Impl α β} {he} : some (l.maxEntry he) = l.maxEntry? := by
|
||||
induction l, he using maxEntry.induct_unfolding <;> simp only [maxEntry?] <;> assumption
|
||||
|
||||
theorem minKey?_eq_minEntry?_map_fst {l : Impl α β} : l.minKey? = l.minEntry?.map Sigma.fst := by
|
||||
induction l using minKey?.induct_unfolding <;> simp only [minEntry?] <;> trivial
|
||||
|
||||
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
|
||||
|
||||
theorem minKey!_eq_get!_minKey? [Inhabited α] {l : Impl α β} :
|
||||
l.minKey! = l.minKey?.get! := by
|
||||
induction l using minKey!.induct <;> simp_all only [minKey!, minKey?] <;> rfl
|
||||
induction l using minKey!.induct_unfolding <;> simp only [minKey?] <;> trivial
|
||||
|
||||
theorem minKeyD_eq_getD_minKey? [Ord α] {l : Impl α β} {fallback} :
|
||||
theorem minKeyD_eq_getD_minKey? {l : Impl α β} {fallback} :
|
||||
l.minKeyD fallback = l.minKey?.getD fallback := by
|
||||
induction l, fallback using minKeyD.induct <;> simp_all only [minKeyD, minKey?] <;> rfl
|
||||
induction l, fallback using minKeyD.induct_unfolding <;> simp only [minKey?] <;> trivial
|
||||
|
||||
theorem maxKey?_eq_minKey?_reverse [Ord α] {l : Impl α β} :
|
||||
l.maxKey? = (letI : Ord α := .opposite inferInstance; (reverse l).minKey?) := by
|
||||
induction l using maxKey?.induct <;> simp_all only [minKey?, maxKey?, reverse]
|
||||
theorem maxKey?_eq_minKey?_reverse {l : Impl α β} : l.maxKey? = l.reverse.minKey? := by
|
||||
induction l using maxKey?.induct_unfolding <;> simp only [minKey?, reverse] <;> assumption
|
||||
|
||||
theorem some_maxKey_eq_maxKey? [Ord α] {l : Impl α β} {he} :
|
||||
some (l.maxKey he) = l.maxKey? := by
|
||||
induction l, he using maxKey.induct <;> simp_all [maxKey, maxKey?]
|
||||
theorem some_maxKey_eq_maxKey? {l : Impl α β} {he} : some (l.maxKey he) = l.maxKey? := by
|
||||
induction l, he using maxKey.induct_unfolding <;> simp only [maxKey?] <;> assumption
|
||||
|
||||
theorem maxKey_eq_get_maxKey? [Ord α] {l : Impl α β} {he} :
|
||||
theorem maxKey_eq_get_maxKey? {l : Impl α β} {he} :
|
||||
l.maxKey he = l.maxKey?.get (by simp [← some_maxKey_eq_maxKey? (he := he)]) := by
|
||||
simp [← some_maxKey_eq_maxKey? (he := he)]
|
||||
|
||||
theorem maxKey!_eq_get!_maxKey? [Ord α] [Inhabited α] {l : Impl α β} :
|
||||
theorem maxKey!_eq_get!_maxKey? [Inhabited α] {l : Impl α β} :
|
||||
l.maxKey! = l.maxKey?.get! := by
|
||||
induction l using maxKey!.induct <;> simp_all only [maxKey!, maxKey?] <;> rfl
|
||||
induction l using maxKey!.induct_unfolding <;> simp only [maxKey?] <;> trivial
|
||||
|
||||
theorem maxKeyD_eq_getD_maxKey? [Ord α] {l : Impl α β} {fallback} :
|
||||
theorem maxKeyD_eq_getD_maxKey? {l : Impl α β} {fallback} :
|
||||
l.maxKeyD fallback = l.maxKey?.getD fallback := by
|
||||
induction l, fallback using maxKeyD.induct <;> simp_all only [maxKeyD, maxKey?] <;> rfl
|
||||
induction l using maxKey?.induct_unfolding <;> simp only [maxKeyD] <;> trivial
|
||||
|
||||
namespace Const
|
||||
|
||||
variable {β : Type v}
|
||||
|
||||
theorem minEntry?_eq_minEntry? [Ord α] {l : Impl α fun _ => β} :
|
||||
minEntry? l = l.minEntry?.map (fun x => (x.1, x.2)) := by
|
||||
induction l using minEntry?.induct_unfolding <;> simp only [Impl.minEntry?] <;> trivial
|
||||
|
||||
theorem minEntry!_eq_get!_minEntry? [Ord α] {l : Impl α fun _ => β} [Inhabited (α × β)] :
|
||||
minEntry! l = (minEntry? l).get! := by
|
||||
induction l using minEntry?.induct_unfolding <;> simp only [minEntry!] <;> trivial
|
||||
|
||||
theorem minEntryD_eq_getD_minEntry? [Ord α] {l : Impl α fun _ => β} {fallback : α × β} :
|
||||
minEntryD l fallback = (minEntry? l).getD fallback := by
|
||||
induction l using minEntry?.induct_unfolding <;> simp only [minEntryD] <;> trivial
|
||||
|
||||
theorem some_minEntry_eq_minEntry? [Ord α] {l : Impl α fun _ => β} {he} :
|
||||
some (minEntry l he) = minEntry? l := by
|
||||
induction l, he using minEntry.induct_unfolding <;> simp only [minEntry?] <;> trivial
|
||||
|
||||
theorem maxEntry?_eq_maxEntry? [Ord α] {l : Impl α fun _ => β} :
|
||||
maxEntry? l = l.maxEntry?.map (fun x => (x.1, x.2)) := by
|
||||
induction l using maxEntry?.induct_unfolding <;> simp only [Impl.maxEntry?] <;> trivial
|
||||
|
||||
theorem maxEntry!_eq_get!_maxEntry? [Ord α] {l : Impl α fun _ => β} [Inhabited (α × β)] :
|
||||
maxEntry! l = (maxEntry? l).get! := by
|
||||
induction l using maxEntry?.induct_unfolding <;> simp only [maxEntry!] <;> trivial
|
||||
|
||||
theorem maxEntryD_eq_getD_maxEntry? [Ord α] {l : Impl α fun _ => β} {fallback : α × β} :
|
||||
maxEntryD l fallback = (maxEntry? l).getD fallback := by
|
||||
induction l using maxEntry?.induct_unfolding <;> simp only [maxEntryD] <;> trivial
|
||||
|
||||
theorem some_maxEntry_eq_maxEntry? [Ord α] {l : Impl α fun _ => β} {he} :
|
||||
some (maxEntry l he) = maxEntry? l := by
|
||||
induction l, he using maxEntry.induct_unfolding <;> simp only [maxEntry?] <;> trivial
|
||||
|
||||
end Const
|
||||
|
||||
theorem balanceL_eq_balance {k : α} {v : β k} {l r : Impl α β} {hlb hrb hlr} :
|
||||
balanceL k v l r hlb hrb hlr = balance k v l r hlb hrb (Or.inl hlr.erase) := by
|
||||
|
|
@ -606,10 +752,8 @@ theorem erase_eq_erase! [Ord α] {k : α} {t : Impl α β} {h} :
|
|||
theorem erase_eq_eraseₘ [Ord α] {k : α} {t : Impl α β} {h} :
|
||||
(erase k t h).impl = eraseₘ k t h := by
|
||||
simp only [eraseₘ]
|
||||
induction t
|
||||
· simp only [erase, updateCell]
|
||||
split <;> split <;> simp_all [balanceLErase_eq_balance, balanceRErase_eq_balance]
|
||||
· simp [erase, eraseₘ, updateCell]
|
||||
induction t using tree_split_ind_no_gen (compare k) <;>
|
||||
simp only [erase, updateCell, *, Cell.empty_inner, balanceRErase_eq_balance, balanceLErase_eq_balance]
|
||||
|
||||
theorem erase!_eq_eraseₘ [Ord α] {k : α} {t : Impl α β} (h : t.Balanced) :
|
||||
erase! k t = eraseₘ k t h := by
|
||||
|
|
@ -701,18 +845,12 @@ variable {β : Type v}
|
|||
theorem get?_eq_get?ₘ [Ord α] (k : α) (l : Impl α (fun _ => β)) :
|
||||
Const.get? l k = Const.get?ₘ l k := by
|
||||
simp only [Const.get?ₘ]
|
||||
induction l
|
||||
· simp only [applyCell, Const.get?]
|
||||
split <;> rename_i hcmp₁ <;> split <;> rename_i hcmp₂ <;> try (simp [hcmp₁] at hcmp₂; done)
|
||||
all_goals simp_all [Cell.Const.get?, Cell.ofEq]
|
||||
· simp [Const.get?, applyCell]
|
||||
induction l using tree_split_ind_no_gen (compare k) <;>
|
||||
simp only [*, get?, applyCell, Cell.Const.get?, Cell.empty_inner, Cell.ofEq_inner]
|
||||
|
||||
theorem get_eq_get? [Ord α] (k : α) (l : Impl α (fun _ => β)) {h} :
|
||||
some (get l k h) = get? l k := by
|
||||
induction l
|
||||
· simp only [applyCell, get, get?]
|
||||
split <;> rename_i ihl ihr hcmp <;> simp_all
|
||||
· contradiction
|
||||
induction l using tree_split_ind_no_gen (compare k) <;> simp only [*, get, get?] <;> contradiction
|
||||
|
||||
theorem get_eq_getₘ [Ord α] (k : α) (l : Impl α (fun _ => β)) {h} (h') :
|
||||
get l k h = getₘ l k h' := by
|
||||
|
|
@ -721,21 +859,361 @@ theorem get_eq_getₘ [Ord α] (k : α) (l : Impl α (fun _ => β)) {h} (h') :
|
|||
|
||||
theorem get!_eq_get!ₘ [Ord α] (k : α) [Inhabited β] (l : Impl α (fun _ => β)) :
|
||||
get! l k = get!ₘ l k := by
|
||||
simp only [get!ₘ, get?ₘ]
|
||||
induction l
|
||||
· simp only [applyCell, get!]
|
||||
split <;> rename_i hcmp₁ <;> split <;> rename_i hcmp₂ <;> try (simp [hcmp₁] at hcmp₂; done)
|
||||
all_goals simp_all [Cell.Const.get?, Cell.ofEq]
|
||||
· simp only [get!, applyCell, Option.get!_none]; rfl
|
||||
rw [get!ₘ, get?ₘ]
|
||||
induction l using tree_split_ind_no_gen (compare k) <;>
|
||||
simp only [*, get!, applyCell, Cell.Const.get?, Cell.ofEq, Option.get!_some]
|
||||
· rfl
|
||||
|
||||
theorem getD_eq_getDₘ [Ord α] (k : α) (l : Impl α (fun _ => β))
|
||||
(fallback : β) : getD l k fallback = getDₘ l k fallback := by
|
||||
simp only [getDₘ, get?ₘ]
|
||||
induction l
|
||||
· simp only [applyCell, getD]
|
||||
split <;> rename_i hcmp₁ <;> split <;> rename_i hcmp₂ <;> try (simp [hcmp₁] at hcmp₂; done)
|
||||
all_goals simp_all [Cell.Const.get?, Cell.ofEq]
|
||||
· simp only [getD, applyCell, Cell.Const.get?_empty, Option.getD_none]
|
||||
rw [getDₘ, get?ₘ]
|
||||
induction l using tree_split_ind_no_gen (compare k) <;>
|
||||
simp only [*, getD, applyCell, Cell.Const.get?, Cell.ofEq, Option.getD_some]
|
||||
· rfl
|
||||
|
||||
end Const
|
||||
|
||||
theorem entryAtIdx?_eq_some_entryAtIdx {t : Impl α β} (htb : t.Balanced) {i : Nat} (h) :
|
||||
t.entryAtIdx? i = some (t.entryAtIdx htb i h) := by
|
||||
induction t, htb, i, h using entryAtIdx.induct_unfolding <;> simp only [entryAtIdx?, *]
|
||||
|
||||
theorem entryAtIdx!_eq_get!_entryAtIdx? {t : Impl α β} {i : Nat} [Inhabited ((a : α) × β a)] :
|
||||
t.entryAtIdx! i = (t.entryAtIdx? i).get! := by
|
||||
induction t, i using entryAtIdx?.induct_unfolding <;> simp only [entryAtIdx!, *] <;> trivial
|
||||
|
||||
theorem entryAtIdxD_eq_getD_entryAtIdx? {t : Impl α β} {i : Nat} {fallback : (a : α) × β a} :
|
||||
t.entryAtIdxD i fallback = (t.entryAtIdx? i).getD fallback := by
|
||||
induction t, i using entryAtIdx?.induct_unfolding <;> simp only [entryAtIdxD, *] <;> trivial
|
||||
|
||||
theorem keyAtIdx?_eq_entryAtIdx? {t : Impl α β} {i : Nat} :
|
||||
t.keyAtIdx? i = (t.entryAtIdx? i).map (·.1) := by
|
||||
induction t, i using entryAtIdx?.induct_unfolding <;> simp only [keyAtIdx?, *] <;> trivial
|
||||
|
||||
theorem keyAtIdx_eq_entryAtIdx_fst {t : Impl α β} (htb : t.Balanced) {i : Nat} {h} :
|
||||
t.keyAtIdx htb i h = (t.entryAtIdx htb i h).1 := by
|
||||
induction t, htb, i, h using keyAtIdx.induct_unfolding <;> simp only [entryAtIdx, *]
|
||||
|
||||
theorem keyAtIdx!_eq_get!_keyAtIdx? [Inhabited α] {t : Impl α β} {i : Nat} :
|
||||
t.keyAtIdx! i = (t.keyAtIdx? i).get! := by
|
||||
induction t, i using keyAtIdx?.induct_unfolding <;> simp only [keyAtIdx!, *] <;> trivial
|
||||
|
||||
theorem keyAtIdxD_eq_getD_keyAtIdx? {t : Impl α β} {i : Nat} {fallback : α} :
|
||||
t.keyAtIdxD i fallback = (t.keyAtIdx? i).getD fallback := by
|
||||
induction t, i using keyAtIdx?.induct_unfolding <;> simp only [keyAtIdxD, *] <;> trivial
|
||||
|
||||
/-- Implementation detail of the tree map -/
|
||||
def getEntryGE?ₘ [Ord α] (k : α) (t : Impl α β) : Option ((a : α) × β a) :=
|
||||
applyPartition (compare k) t fun _ c _ r => c.inner.or r.head?
|
||||
|
||||
/-- Implementation detail of the tree map -/
|
||||
def getEntryGE?ₘ' [Ord α] (k : α) (t : Impl α β) : Option ((a : α) × β a) :=
|
||||
t.explore (compare k) none fun
|
||||
| _, .lt k' _ v _ => some ⟨k', v⟩
|
||||
| base, .eq _ c r => (c.inner.or r.head?).or base
|
||||
| base, .gt _ _ _ _ => base
|
||||
|
||||
theorem getEntryGE?_eq_getEntryGE?ₘ' [Ord α] (k : α) (t : Impl α β) :
|
||||
getEntryGE? k t = getEntryGE?ₘ' k t := by
|
||||
rw [getEntryGE?ₘ', getEntryGE?]
|
||||
induction t, none using tree_split_ind (compare k) <;> simp [*, getEntryGE?.go, explore]
|
||||
|
||||
theorem getEntryGE?_eq_getEntryGE?ₘ [Ord α] (k : α) (t : Impl α β) :
|
||||
getEntryGE? k t = getEntryGE?ₘ k t := by
|
||||
rw [getEntryGE?_eq_getEntryGE?ₘ', getEntryGE?ₘ', getEntryGE?ₘ, explore_eq_applyPartition] <;> simp
|
||||
|
||||
/-- Implementation detail of the tree map -/
|
||||
def getEntryGT?ₘ [Ord α] (k : α) (t : Impl α β) : Option ((a : α) × β a) :=
|
||||
applyPartition (fun k' => (compare k k').then .gt) t fun _ _ _ r => r.head?
|
||||
|
||||
/-- Implementation detail of the tree map -/
|
||||
def getEntryGT?ₘ' [Ord α] (k : α) (t : Impl α β) : Option ((a : α) × β a) :=
|
||||
t.explore (fun k' => (compare k k').then .gt) none fun
|
||||
| _, .lt k' _ v _ => some ⟨k', v⟩
|
||||
| base, .eq _ _ r => r.head?.or base
|
||||
| base, .gt _ _ _ _ => base
|
||||
|
||||
theorem getEntryGT?_eq_getEntryGT?ₘ' [Ord α] (k : α) (t : Impl α β) :
|
||||
getEntryGT? k t = getEntryGT?ₘ' k t := by
|
||||
rw [getEntryGT?ₘ', getEntryGT?]
|
||||
induction t, none using tree_split_ind (compare k) <;> simp [*, getEntryGT?.go, explore]
|
||||
|
||||
theorem getEntryGT?_eq_getEntryGT?ₘ [Ord α] (k : α) (t : Impl α β) :
|
||||
getEntryGT? k t = getEntryGT?ₘ k t := by
|
||||
rw [getEntryGT?_eq_getEntryGT?ₘ', getEntryGT?ₘ', getEntryGT?ₘ, explore_eq_applyPartition] <;> simp
|
||||
|
||||
theorem getEntryLT?_eq_getEntryGT?_reverse [o : Ord α] [TransOrd α] {t : Impl α β} {k : α} :
|
||||
getEntryLT? k t = @getEntryGT? α β o.opposite k t.reverse := by
|
||||
rw [getEntryLT?, @getEntryGT?.eq_def, Ord.opposite]
|
||||
induction t, none using tree_split_ind (compare k) <;>
|
||||
simp only [*, getEntryLT?.go, reverse, getEntryGT?.go, OrientedCmp.eq_swap (b := k),
|
||||
Ordering.swap]
|
||||
|
||||
theorem getEntryLE?_eq_getEntryGE?_reverse [o : Ord α] [TransOrd α] {t : Impl α β} {k : α} :
|
||||
getEntryLE? k t = @getEntryGE? α β o.opposite k t.reverse := by
|
||||
rw [getEntryLE?, @getEntryGE?.eq_def, Ord.opposite]
|
||||
induction t, none using tree_split_ind (compare k) <;>
|
||||
simp only [*, getEntryLE?.go, reverse, getEntryGE?.go, OrientedCmp.eq_swap (b := k),
|
||||
Ordering.swap]
|
||||
|
||||
theorem getEntryGE!_eq_get!_getEntryGE? [Ord α] {t : Impl α β} {k : α} [Inhabited ((a : α) × β a)] :
|
||||
t.getEntryGE! k = (t.getEntryGE? k).get! := rfl
|
||||
|
||||
theorem getEntryGT!_eq_get!_getEntryGT? [Ord α] {t : Impl α β} {k : α} [Inhabited ((a : α) × β a)] :
|
||||
t.getEntryGT! k = (t.getEntryGT? k).get! := rfl
|
||||
|
||||
theorem getEntryLE!_eq_get!_getEntryLE? [Ord α] {t : Impl α β} {k : α} [Inhabited ((a : α) × β a)] :
|
||||
t.getEntryLE! k = (t.getEntryLE? k).get! := rfl
|
||||
|
||||
theorem getEntryLT!_eq_get!_getEntryLT? [Ord α] {t : Impl α β} {k : α} [Inhabited ((a : α) × β a)] :
|
||||
t.getEntryLT! k = (t.getEntryLT? k).get! := rfl
|
||||
|
||||
theorem getEntryGED_eq_getD_getEntryGE? [Ord α] {t : Impl α β} {k : α} {fallback : (a : α) × β a} :
|
||||
t.getEntryGED k fallback = (t.getEntryGE? k).getD fallback := rfl
|
||||
|
||||
theorem getEntryGTD_eq_getD_getEntryGT? [Ord α] {t : Impl α β} {k : α} {fallback : (a : α) × β a} :
|
||||
t.getEntryGTD k fallback = (t.getEntryGT? k).getD fallback := rfl
|
||||
|
||||
theorem getEntryLED_eq_getD_getEntryLE? [Ord α] {t : Impl α β} {k : α} {fallback : (a : α) × β a} :
|
||||
t.getEntryLED k fallback = (t.getEntryLE? k).getD fallback := rfl
|
||||
|
||||
theorem getEntryLTD_eq_getD_getEntryLT? [Ord α] {t : Impl α β} {k : α} {fallback : (a : α) × β a} :
|
||||
t.getEntryLTD k fallback = (t.getEntryLT? k).getD fallback := rfl
|
||||
|
||||
theorem getEntryGE?.eq_go [Ord α] (k : α) (x) (t : Impl α β) :
|
||||
(getEntryGE? k t).or x = getEntryGE?.go k x t := by
|
||||
rw [getEntryGE?]
|
||||
induction t, x using tree_split_ind (compare k) <;>
|
||||
simp only [go, Option.none_or, Option.some_or, *]
|
||||
case _ ih _ => rw [← ih, Option.or_assoc, Option.some_or]
|
||||
|
||||
theorem getEntryGT?.eq_go [Ord α] (k : α) (x) (t : Impl α β) :
|
||||
(getEntryGT? k t).or x = getEntryGT?.go k x t := by
|
||||
rw [getEntryGT?]
|
||||
induction t, x using tree_split_ind (compare k) <;>
|
||||
simp only [go, Option.none_or, Option.some_or, *]
|
||||
case _ ih _ => rw [← ih, Option.or_assoc, Option.some_or]
|
||||
|
||||
theorem getEntryLE?.eq_go [Ord α] (k : α) (x) (t : Impl α β) :
|
||||
(getEntryLE? k t).or x = getEntryLE?.go k x t := by
|
||||
rw [getEntryLE?]
|
||||
induction t, x using tree_split_ind (compare k) <;>
|
||||
simp only [go, Option.none_or, Option.some_or, *]
|
||||
case _ ih _ => rw [← ih, Option.or_assoc, Option.some_or]
|
||||
|
||||
theorem getEntryLT?.eq_go [Ord α] (k : α) (x) (t : Impl α β) :
|
||||
(getEntryLT? k t).or x = getEntryLT?.go k x t := by
|
||||
rw [getEntryLT?]
|
||||
induction t, x using tree_split_ind (compare k) <;>
|
||||
simp only [go, Option.none_or, Option.some_or, *]
|
||||
case _ ih _ => rw [← ih, Option.or_assoc, Option.some_or]
|
||||
|
||||
theorem some_getEntryGE_eq_getEntryGE? [Ord α] [TransOrd α] (k : α) (t : Impl α β) {ho he} :
|
||||
some (getEntryGE k t ho he) = getEntryGE? k t := by
|
||||
rw [getEntryGE?]; apply of_eq_true
|
||||
induction t, none using tree_split_ind (compare k) <;>
|
||||
simp only [*, getEntryGE?.go, getEntryGE, getEntryGED, ← Option.or_some,
|
||||
getEntryGE?.eq_go] <;> contradiction
|
||||
|
||||
theorem some_getEntryGT_eq_getEntryGT? [Ord α] [TransOrd α] (k : α) (t : Impl α β) {ho he} :
|
||||
some (getEntryGT k t ho he) = getEntryGT? k t := by
|
||||
rw [getEntryGT?]; apply of_eq_true
|
||||
induction t, none using tree_split_ind (compare k) <;>
|
||||
simp only [*, getEntryGT?.go, getEntryGT, getEntryGTD, ← Option.or_some,
|
||||
getEntryGT?.eq_go, ↓reduceDIte, reduceCtorEq] <;> contradiction
|
||||
|
||||
theorem some_getEntryLE_eq_getEntryLE? [Ord α] [TransOrd α] (k : α) (t : Impl α β) {ho he} :
|
||||
some (getEntryLE k t ho he) = getEntryLE? k t := by
|
||||
rw [getEntryLE?]; apply of_eq_true
|
||||
induction t, none using tree_split_ind (compare k) <;>
|
||||
simp only [*, getEntryLE?.go, getEntryLE, getEntryLED, ← Option.or_some,
|
||||
getEntryLE?.eq_go] <;> contradiction
|
||||
|
||||
theorem some_getEntryLT_eq_getEntryLT? [Ord α] [TransOrd α] (k : α) (t : Impl α β) {ho he} :
|
||||
some (getEntryLT k t ho he) = getEntryLT? k t := by
|
||||
rw [getEntryLT?]; apply of_eq_true
|
||||
induction t, none using tree_split_ind (compare k) <;>
|
||||
simp only [*, getEntryLT?.go, getEntryLT, getEntryLTD, ← Option.or_some,
|
||||
getEntryLT?.eq_go, ↓reduceDIte, reduceCtorEq] <;> contradiction
|
||||
|
||||
theorem getKeyGE?_eq_getEntryGE? [Ord α] {t : Impl α β} {k : α} :
|
||||
getKeyGE? k t = (getEntryGE? k t).map (·.1) := by
|
||||
rw [getKeyGE?, getEntryGE?]; symm
|
||||
change _ = getKeyGE?.go k (Option.map (·.1) (none : Option ((a : α) × β a))) _
|
||||
induction t, none using tree_split_ind (compare k) <;> simp [getKeyGE?.go, getEntryGE?.go, *]
|
||||
|
||||
theorem getKeyGT?_eq_getEntryGT? [Ord α] {t : Impl α β} {k : α} :
|
||||
getKeyGT? k t = (getEntryGT? k t).map (·.1) := by
|
||||
rw [getKeyGT?, getEntryGT?]; symm
|
||||
change _ = getKeyGT?.go k (Option.map (·.1) (none : Option ((a : α) × β a))) _
|
||||
induction t, none using tree_split_ind (compare k) <;> simp [getKeyGT?.go, getEntryGT?.go, *]
|
||||
|
||||
theorem getKeyLE?_eq_getEntryLE? [Ord α] {t : Impl α β} {k : α} :
|
||||
getKeyLE? k t = (getEntryLE? k t).map (·.1) := by
|
||||
rw [getKeyLE?, getEntryLE?]; symm
|
||||
change _ = getKeyLE?.go k (Option.map (·.1) (none : Option ((a : α) × β a))) _
|
||||
induction t, none using tree_split_ind (compare k) <;> simp [getKeyLE?.go, getEntryLE?.go, *]
|
||||
|
||||
theorem getKeyLT?_eq_getEntryLT? [Ord α] {t : Impl α β} {k : α} :
|
||||
getKeyLT? k t = (getEntryLT? k t).map (·.1) := by
|
||||
rw [getKeyLT?, getEntryLT?]; symm
|
||||
change _ = getKeyLT?.go k (Option.map (·.1) (none : Option ((a : α) × β a))) _
|
||||
induction t, none using tree_split_ind (compare k) <;> simp [getKeyLT?.go, getEntryLT?.go, *]
|
||||
|
||||
theorem getKeyGE!_eq_get!_getKeyGE? [Ord α] {t : Impl α β} {k : α} [Inhabited α] :
|
||||
t.getKeyGE! k = (t.getKeyGE? k).get! := rfl
|
||||
|
||||
theorem getKeyGT!_eq_get!_getKeyGT? [Ord α] {t : Impl α β} {k : α} [Inhabited α] :
|
||||
t.getKeyGT! k = (t.getKeyGT? k).get! := rfl
|
||||
|
||||
theorem getKeyLE!_eq_get!_getKeyLE? [Ord α] {t : Impl α β} {k : α} [Inhabited α] :
|
||||
t.getKeyLE! k = (t.getKeyLE? k).get! := rfl
|
||||
|
||||
theorem getKeyLT!_eq_get!_getKeyLT? [Ord α] {t : Impl α β} {k : α} [Inhabited α] :
|
||||
t.getKeyLT! k = (t.getKeyLT? k).get! := rfl
|
||||
|
||||
theorem getKeyGED_eq_getD_getKeyGE? [Ord α] {t : Impl α β} {k fallback : α} :
|
||||
t.getKeyGED k fallback = (t.getKeyGE? k).getD fallback := rfl
|
||||
|
||||
theorem getKeyGTD_eq_getD_getKeyGT? [Ord α] {t : Impl α β} {k fallback : α} :
|
||||
t.getKeyGTD k fallback = (t.getKeyGT? k).getD fallback := rfl
|
||||
|
||||
theorem getKeyLED_eq_getD_getKeyLE? [Ord α] {t : Impl α β} {k fallback : α} :
|
||||
t.getKeyLED k fallback = (t.getKeyLE? k).getD fallback := rfl
|
||||
|
||||
theorem getKeyLTD_eq_getD_getKeyLT? [Ord α] {t : Impl α β} {k fallback : α} :
|
||||
t.getKeyLTD k fallback = (t.getKeyLT? k).getD fallback := rfl
|
||||
|
||||
theorem getKeyGE_eq_getEntryGE [Ord α] [TransOrd α] {t : Impl α β} {k : α} {hto he} :
|
||||
getKeyGE k t hto he = (getEntryGE k t hto he).1 := by
|
||||
induction t using tree_split_ind_no_gen (compare k) <;> simp only [getKeyGE, getEntryGE, *]
|
||||
· contradiction
|
||||
· rw [getKeyGED, getEntryGED, getKeyGE?_eq_getEntryGE?]; symm
|
||||
exact (Option.getD_map _ _ _).symm
|
||||
|
||||
theorem getKeyGT_eq_getEntryGT [Ord α] [TransOrd α] {t : Impl α β} {k : α} {hto he} :
|
||||
getKeyGT k t hto he = (getEntryGT k t hto he).1 := by
|
||||
induction t using tree_split_ind_no_gen (compare k) <;>
|
||||
simp only [getKeyGT, getEntryGT, *, ↓reduceDIte, reduceCtorEq]
|
||||
· contradiction
|
||||
· rw [getKeyGTD, getEntryGTD, getKeyGT?_eq_getEntryGT?]; symm
|
||||
exact (Option.getD_map _ _ _).symm
|
||||
|
||||
theorem getKeyLE_eq_getEntryLE [Ord α] [TransOrd α] {t : Impl α β} {k : α} {hto he} :
|
||||
getKeyLE k t hto he = (getEntryLE k t hto he).1 := by
|
||||
induction t using tree_split_ind_no_gen (compare k) <;> simp only [getKeyLE, getEntryLE, *]
|
||||
· contradiction
|
||||
· rw [getKeyLED, getEntryLED, getKeyLE?_eq_getEntryLE?]; symm
|
||||
exact (Option.getD_map _ _ _).symm
|
||||
|
||||
theorem getKeyLT_eq_getEntryLT [Ord α] [TransOrd α] {t : Impl α β} {k : α} {hto he} :
|
||||
getKeyLT k t hto he = (getEntryLT k t hto he).1 := by
|
||||
induction t using tree_split_ind_no_gen (compare k) <;>
|
||||
simp only [getKeyLT, getEntryLT, *, ↓reduceDIte, reduceCtorEq]
|
||||
· contradiction
|
||||
· rw [getKeyLTD, getEntryLTD, getKeyLT?_eq_getEntryLT?]; symm
|
||||
exact (Option.getD_map _ _ _).symm
|
||||
|
||||
namespace Const
|
||||
|
||||
variable {β : Type v}
|
||||
|
||||
theorem entryAtIdx?_eq_map {t : Impl α fun _ => β} {i : Nat} :
|
||||
entryAtIdx? t i = (t.entryAtIdx? i).map (fun x => (x.1, x.2)) := by
|
||||
induction t, i using entryAtIdx?.induct_unfolding <;> simp only [Impl.entryAtIdx?, *] <;> rfl
|
||||
|
||||
theorem entryAtIdx_eq {t : Impl α fun _ => β} (htb : t.Balanced) {i : Nat} {h} :
|
||||
entryAtIdx t htb i h = ((t.entryAtIdx htb i h).1, (t.entryAtIdx htb i h).2) := by
|
||||
induction t, htb, i, h using entryAtIdx.induct_unfolding <;> simp only [Impl.entryAtIdx, *]
|
||||
|
||||
theorem entryAtIdx!_eq_get!_entryAtIdx? {t : Impl α fun _ => β} {i : Nat} [Inhabited (α × β)] :
|
||||
entryAtIdx! t i = (entryAtIdx? t i).get! := by
|
||||
induction t, i using entryAtIdx?.induct_unfolding <;> simp only [entryAtIdx!, *] <;> rfl
|
||||
|
||||
theorem entryAtIdxD_eq_getD_entryAtIdx? {t : Impl α fun _ => β} {i : Nat} {fallback : α × β} :
|
||||
entryAtIdxD t i fallback = (entryAtIdx? t i).getD fallback := by
|
||||
induction t, i using entryAtIdx?.induct_unfolding <;> simp only [entryAtIdxD, *] <;> rfl
|
||||
|
||||
theorem getEntryGE?_eq_map [Ord α] {t : Impl α fun _ => β} {k : α} :
|
||||
getEntryGE? k t = (Impl.getEntryGE? k t).map (fun x => (x.1, x.2)) := by
|
||||
rw [getEntryGE?, Impl.getEntryGE?]; symm
|
||||
change _ = getEntryGE?.go k (Option.map (fun x => (x.1, x.2)) (none : Option ((_ : α) × β))) _
|
||||
induction t, none using tree_split_ind (compare k) <;> simp [getEntryGE?.go, Impl.getEntryGE?.go, *]
|
||||
|
||||
theorem getEntryGT?_eq_map [Ord α] {t : Impl α fun _ => β} {k : α} :
|
||||
getEntryGT? k t = (Impl.getEntryGT? k t).map (fun x => (x.1, x.2)) := by
|
||||
rw [getEntryGT?, Impl.getEntryGT?]; symm
|
||||
change _ = getEntryGT?.go k (Option.map (fun x => (x.1, x.2)) (none : Option ((_ : α) × β))) _
|
||||
induction t, none using tree_split_ind (compare k) <;> simp [getEntryGT?.go, Impl.getEntryGT?.go, *]
|
||||
|
||||
theorem getEntryLE?_eq_map [Ord α] {t : Impl α fun _ => β} {k : α} :
|
||||
getEntryLE? k t = (Impl.getEntryLE? k t).map (fun x => (x.1, x.2)) := by
|
||||
rw [getEntryLE?, Impl.getEntryLE?]; symm
|
||||
change _ = getEntryLE?.go k (Option.map (fun x => (x.1, x.2)) (none : Option ((_ : α) × β))) _
|
||||
induction t, none using tree_split_ind (compare k) <;> simp [getEntryLE?.go, Impl.getEntryLE?.go, *]
|
||||
|
||||
theorem getEntryLT?_eq_map [Ord α] {t : Impl α fun _ => β} {k : α} :
|
||||
getEntryLT? k t = (Impl.getEntryLT? k t).map (fun x => (x.1, x.2)) := by
|
||||
rw [getEntryLT?, Impl.getEntryLT?]; symm
|
||||
change _ = getEntryLT?.go k (Option.map (fun x => (x.1, x.2)) (none : Option ((_ : α) × β))) _
|
||||
induction t, none using tree_split_ind (compare k) <;> simp [getEntryLT?.go, Impl.getEntryLT?.go, *]
|
||||
|
||||
theorem getEntryGE!_eq_get!_getEntryGE? [Ord α] {t : Impl α fun _ => β} {k : α} [Inhabited (α × β)] :
|
||||
getEntryGE! k t = (getEntryGE? k t).get! := rfl
|
||||
|
||||
theorem getEntryGT!_eq_get!_getEntryGT? [Ord α] {t : Impl α fun _ => β} {k : α} [Inhabited (α × β)] :
|
||||
getEntryGT! k t = (getEntryGT? k t).get! := rfl
|
||||
|
||||
theorem getEntryLE!_eq_get!_getEntryLE? [Ord α] {t : Impl α fun _ => β} {k : α} [Inhabited (α × β)] :
|
||||
getEntryLE! k t = (getEntryLE? k t).get! := rfl
|
||||
|
||||
theorem getEntryLT!_eq_get!_getEntryLT? [Ord α] {t : Impl α fun _ => β} {k : α} [Inhabited (α × β)] :
|
||||
getEntryLT! k t = (getEntryLT? k t).get! := rfl
|
||||
|
||||
theorem getEntryGED_eq_getD_getEntryGE? [Ord α] {t : Impl α fun _ => β} {k : α} {fallback : α × β} :
|
||||
getEntryGED k t fallback = (getEntryGE? k t).getD fallback := rfl
|
||||
|
||||
theorem getEntryGTD_eq_getD_getEntryGT? [Ord α] {t : Impl α fun _ => β} {k : α} {fallback : α × β} :
|
||||
getEntryGTD k t fallback = (getEntryGT? k t).getD fallback := rfl
|
||||
|
||||
theorem getEntryLED_eq_getD_getEntryLE? [Ord α] {t : Impl α fun _ => β} {k : α} {fallback : α × β} :
|
||||
getEntryLED k t fallback = (getEntryLE? k t).getD fallback := rfl
|
||||
|
||||
theorem getEntryLTD_eq_getD_getEntryLT? [Ord α] {t : Impl α fun _ => β} {k : α} {fallback : α × β} :
|
||||
getEntryLTD k t fallback = (getEntryLT? k t).getD fallback := rfl
|
||||
|
||||
theorem getEntryGE_eq [Ord α] [TransOrd α] {t : Impl α fun _ => β} (hto : t.Ordered) {k : α} (he) :
|
||||
getEntryGE k t hto he = (letI e := Impl.getEntryGE k t hto he; (e.1, e.2)) := by
|
||||
induction t using tree_split_ind_no_gen (compare k) <;> simp only [getEntryGE, Impl.getEntryGE, *]
|
||||
· contradiction
|
||||
· rename_i l _ _ _
|
||||
rw [getEntryGED, Impl.getEntryGED, getEntryGE?_eq_map]
|
||||
exact Option.getD_map (fun x => (x.1, x.2)) ⟨_, _⟩ (Impl.getEntryGE? k l)
|
||||
|
||||
theorem getEntryGT_eq [Ord α] [TransOrd α] {t : Impl α fun _ => β} (hto : t.Ordered) {k : α} (he) :
|
||||
getEntryGT k t hto he = (letI e := Impl.getEntryGT k t hto he; (e.1, e.2)) := by
|
||||
induction t using tree_split_ind_no_gen (compare k) <;>
|
||||
simp only [getEntryGT, Impl.getEntryGT, *, ↓reduceDIte, reduceCtorEq]
|
||||
· contradiction
|
||||
· rename_i l _ _ _
|
||||
rw [getEntryGTD, Impl.getEntryGTD, getEntryGT?_eq_map]
|
||||
exact Option.getD_map (fun x => (x.1, x.2)) ⟨_, _⟩ (Impl.getEntryGT? k l)
|
||||
|
||||
theorem getEntryLE_eq [Ord α] [TransOrd α] {t : Impl α fun _ => β} (hto : t.Ordered) {k : α} (he) :
|
||||
getEntryLE k t hto he = (letI e := Impl.getEntryLE k t hto he; (e.1, e.2)) := by
|
||||
induction t using tree_split_ind_no_gen (compare k) <;> simp only [getEntryLE, Impl.getEntryLE, *]
|
||||
· contradiction
|
||||
· rename_i r _ _
|
||||
rw [getEntryLED, Impl.getEntryLED, getEntryLE?_eq_map]
|
||||
exact Option.getD_map (fun x => (x.1, x.2)) ⟨_, _⟩ (Impl.getEntryLE? k r)
|
||||
|
||||
theorem getEntryLT_eq [Ord α] [TransOrd α] {t : Impl α fun _ => β} (hto : t.Ordered) {k : α} (he) :
|
||||
getEntryLT k t hto he = (letI e := Impl.getEntryLT k t hto he; (e.1, e.2)) := by
|
||||
induction t using tree_split_ind_no_gen (compare k) <;>
|
||||
simp only [getEntryLT, Impl.getEntryLT, *, ↓reduceDIte, reduceCtorEq]
|
||||
· contradiction
|
||||
· rename_i r _ _
|
||||
rw [getEntryLTD, Impl.getEntryLTD, getEntryLT?_eq_map]
|
||||
exact Option.getD_map (fun x => (x.1, x.2)) ⟨_, _⟩ (Impl.getEntryLT? k r)
|
||||
|
||||
end Const
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,13 @@ private local instance : Coe (Type v) (α → Type v) where coe γ := fun _ =>
|
|||
|
||||
namespace Std.DTreeMap.Internal.Impl
|
||||
|
||||
/-- Two tree maps are equivalent in the sense of Equiv iff all the keys and values are equal. -/
|
||||
structure Equiv (t t' : Impl α β) where
|
||||
/-- Implementation detail of the tree map -/
|
||||
impl : t.toListModel.Perm t'.toListModel
|
||||
|
||||
@[inherit_doc] scoped infix:50 " ~m " => Equiv
|
||||
|
||||
/-- Returns `true` if the given key is contained in the map. -/
|
||||
def contains [Ord α] (k : α) (t : Impl α β) : Bool :=
|
||||
match t with
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ can be found in `Std.Data.Internal.Lemmas`.
|
|||
set_option autoImplicit false
|
||||
set_option linter.all true
|
||||
|
||||
universe u v w
|
||||
universe u v w w'
|
||||
|
||||
variable {α : Type u} {β : α → Type v} {γ : α → Type w} {δ : Type w}
|
||||
private local instance : Coe (Type v) (α → Type v) where coe γ := fun _ => γ
|
||||
|
|
@ -255,12 +255,6 @@ theorem toListModel_filter_lt_of_lt [Ord α] [TransOrd α] {k : α → Ordering}
|
|||
List.append_cancel_left_eq, List.cons.injEq, List.filter_eq_self, beq_iff_eq, true_and]
|
||||
exact fun p hp => IsCut.lt hcmp (ho.compare_right hp)
|
||||
|
||||
instance [Ord α] [TransOrd α] {k : α} : IsStrictCut compare (compare k) where
|
||||
lt := TransCmp.lt_trans
|
||||
gt h₁ h₂ := OrientedCmp.gt_of_lt (TransCmp.lt_trans (OrientedCmp.lt_of_gt h₂)
|
||||
(OrientedCmp.lt_of_gt h₁))
|
||||
eq _ _ := TransCmp.congr_left
|
||||
|
||||
theorem findCell_of_gt [Ord α] [TransOrd α] {k : α → Ordering} [IsStrictCut compare k]
|
||||
{sz k' v' l r} (hcmp : k k' = .gt) (ho : (inner sz k' v' l r : Impl α β).Ordered) :
|
||||
List.findCell (inner sz k' v' l r).toListModel k = List.findCell r.toListModel k :=
|
||||
|
|
@ -287,25 +281,21 @@ theorem toListModel_updateCell [Ord α] [TransOrd α] {k : α}
|
|||
· simp_all [updateCell]
|
||||
· rename_i sz k' v' l r hb hcmp l' hl'₁ hl'₂ hl'₃ hup ih
|
||||
simp only [updateCell, hcmp]
|
||||
split <;> rename_i hcmp' <;> try (simp [hcmp] at hcmp'; done)
|
||||
rw [toListModel_balance, toListModel_filter_gt_of_lt hcmp hlo,
|
||||
toListModel_filter_lt_of_lt hcmp hlo, findCell_of_lt hcmp hlo, ih hlo.left]
|
||||
simp
|
||||
· rename_i sz k' v' l r hl hcmp hf
|
||||
simp only [updateCell, hcmp, hf]
|
||||
split <;> rename_i hcmp' <;> try (simp [hcmp] at hcmp'; done)
|
||||
rw [toListModel_glue, toListModel_filter_gt_of_eq hcmp hlo, findCell_of_eq hcmp hlo,
|
||||
hf, toListModel_filter_lt_of_eq hcmp hlo]
|
||||
simp
|
||||
· rename_i sz k' v' l r hl hcmp k'' v'' hf
|
||||
simp only [updateCell, hcmp, hf]
|
||||
split <;> rename_i hcmp' <;> try (simp [hcmp] at hcmp'; done)
|
||||
rw [toListModel_inner, toListModel_filter_gt_of_eq hcmp hlo, findCell_of_eq hcmp hlo,
|
||||
toListModel_filter_lt_of_eq hcmp hlo, hf]
|
||||
simp
|
||||
· rename_i sz k' v' l r hb hcmp l' hl'₁ hl'₂ hl'₃ hup ih
|
||||
simp only [updateCell, hcmp]
|
||||
split <;> rename_i hcmp' <;> try (simp [hcmp] at hcmp'; done)
|
||||
rw [toListModel_filter_gt_of_gt hcmp hlo, findCell_of_gt hcmp hlo,
|
||||
toListModel_filter_lt_of_gt hcmp hlo, toListModel_balance, ih hlo.right]
|
||||
simp
|
||||
|
|
@ -545,6 +535,22 @@ theorem applyCell_eq_apply_toListModel [Ord α] [TransOrd α] [BEq α] [LawfulBE
|
|||
## Verification of access operations
|
||||
-/
|
||||
|
||||
/-!
|
||||
### Equiv
|
||||
-/
|
||||
|
||||
theorem equiv_iff_toListModel_perm {t t' : Impl α β} :
|
||||
t.Equiv t' ↔ t.toListModel.Perm t'.toListModel :=
|
||||
⟨Equiv.impl, Equiv.mk⟩
|
||||
|
||||
theorem Equiv.toListModel_eq [Ord α] [OrientedOrd α]
|
||||
{t t' : Impl α β} (h : t.Equiv t') (htb : t.Ordered) (htb' : t'.Ordered) :
|
||||
t.toListModel = t'.toListModel := by
|
||||
refine List.Perm.eq_of_sorted ?_ htb htb' h.1
|
||||
intro a b ha hb hlt hgt
|
||||
rw [OrientedOrd.eq_swap, hlt] at hgt
|
||||
contradiction
|
||||
|
||||
/-!
|
||||
### `isEmpty`
|
||||
-/
|
||||
|
|
@ -1018,7 +1024,7 @@ theorem toListModel_filterMap [Ord α] {t : Impl α β} {h} {f : (a : α) → β
|
|||
induction t with
|
||||
| leaf => rfl
|
||||
| inner sz k v _ _ ihl ihr =>
|
||||
simp [filterMap]
|
||||
simp only [filterMap, toListModel_inner, List.filterMap_append]
|
||||
cases h : f k v
|
||||
all_goals simp [h, ihl, ihr]
|
||||
|
||||
|
|
@ -1047,6 +1053,11 @@ theorem filter_eq_filterMap [Ord α] {t : Impl α β} {h} {f : (a : α) → β a
|
|||
simp [filter, filterMap]
|
||||
cases hf : f k v <;> rw [ihl, ihr] <;> rfl
|
||||
|
||||
theorem toListModel_filter [Ord α] {t : Impl α β} {h} {f : (a : α) → β a → Bool} :
|
||||
(t.filter f h).impl.toListModel = t.toListModel.filter (fun e => f e.1 e.2) := by
|
||||
rw [filter_eq_filterMap, toListModel_filterMap, ← List.filterMap_eq_filter]
|
||||
congr; simp only [Option.map_if, Option.guard_def]
|
||||
|
||||
theorem ordered_filter [Ord α] {t : Impl α β} {h} {f : (a : α) → β a → Bool} (hto : t.Ordered) :
|
||||
(t.filter f h).impl.Ordered := by
|
||||
simpa only [filter_eq_filterMap] using ordered_filterMap hto
|
||||
|
|
@ -1085,11 +1096,8 @@ theorem alter_eq_alterₘ [Ord α] [TransOrd α] [LawfulEqOrd α] {t : Impl α
|
|||
rw [alter, updateCell]
|
||||
split <;> rename_i heq <;> simp only [heq]
|
||||
· simp [ihl htb.left hto.left]
|
||||
split <;> simp_all
|
||||
· simp [ihr htb.right hto.right]
|
||||
split <;> simp_all
|
||||
· apply Eq.symm
|
||||
split <;> (try simp_all; done)
|
||||
simp [Cell.alter, Cell.ofOption, cast]
|
||||
cases h₁ : f _ <;> rfl
|
||||
|
||||
|
|
@ -1217,10 +1225,15 @@ theorem foldr_eq_foldr {t : Impl α β} {δ} {f : (a : α) → β a → δ →
|
|||
|
||||
theorem toList_eq_toListModel {t : Impl α β} :
|
||||
t.toList = t.toListModel := by
|
||||
rw [toList, foldr_eq_foldr]
|
||||
induction t with
|
||||
| leaf => rfl
|
||||
| inner sz k v l r ihl ihr => simp
|
||||
simp [toList, foldr_eq_foldr]
|
||||
|
||||
/-!
|
||||
### toArray
|
||||
-/
|
||||
|
||||
theorem toArray_eq_toArray {t : Impl α β} :
|
||||
t.toArray = t.toListModel.toArray := by
|
||||
simp [toArray, foldl_eq_foldl]
|
||||
|
||||
/-!
|
||||
### keys
|
||||
|
|
@ -1228,19 +1241,37 @@ theorem toList_eq_toListModel {t : Impl α β} :
|
|||
|
||||
theorem keys_eq_keys {t : Impl α β} :
|
||||
t.keys = t.toListModel.keys := by
|
||||
rw [keys, foldr_eq_foldr, List.keys.eq_def]
|
||||
simp
|
||||
induction t.toListModel with
|
||||
| nil => rfl
|
||||
| cons e es ih =>
|
||||
simp [ih]
|
||||
rw [List.keys.eq_def]
|
||||
simp [keys, foldr_eq_foldr, List.keys_eq_map]
|
||||
|
||||
/-!
|
||||
### keysArray
|
||||
-/
|
||||
|
||||
theorem keysArray_eq_toArray_keys {t : Impl α β} :
|
||||
t.keysArray = t.toListModel.keys.toArray := by
|
||||
simp [keysArray, foldl_eq_foldl, List.keys_eq_map]
|
||||
|
||||
/-!
|
||||
### values
|
||||
-/
|
||||
|
||||
theorem values_eq_map_snd {β : Type v} {t : Impl α β} :
|
||||
t.values = t.toListModel.map (·.2) := by
|
||||
simp [values, foldr_eq_foldr]
|
||||
|
||||
/-!
|
||||
### valuesArray
|
||||
-/
|
||||
|
||||
theorem valuesArray_eq_toArray_map {β : Type v} {t : Impl α β} :
|
||||
t.valuesArray = (t.toListModel.map (·.2)).toArray := by
|
||||
simp [valuesArray, foldl_eq_foldl]
|
||||
|
||||
/-!
|
||||
### forM
|
||||
-/
|
||||
|
||||
theorem forM_eq_forM {t: Impl α β} {m : Type w → Type w} [Monad m] [LawfulMonad m]
|
||||
theorem forM_eq_forM {t : Impl α β} {m : Type w → Type w'} [Monad m] [LawfulMonad m]
|
||||
{f : (a : α) → β a → m PUnit} :
|
||||
t.forM f = t.toListModel.forM (fun a => f a.1 a.2) := by
|
||||
simp only [Impl.forM, foldlM_eq_foldlM_toListModel]
|
||||
|
|
@ -1252,7 +1283,7 @@ theorem forM_eq_forM {t: Impl α β} {m : Type w → Type w} [Monad m] [LawfulMo
|
|||
### forIn
|
||||
-/
|
||||
|
||||
theorem forInStep_eq_foldlM {δ : Type w} {t : Impl α β} {m : Type w → Type w} [Monad m] [LawfulMonad m]
|
||||
theorem forInStep_eq_foldlM {δ : Type w} {t : Impl α β} {m : Type w → Type w'} [Monad m] [LawfulMonad m]
|
||||
{f : (a : α) → β a → δ → m (ForInStep δ)} {init : δ} :
|
||||
t.forInStep f init = t.foldlM (init := .yield init) fun
|
||||
| .yield d => fun k v => f k v d
|
||||
|
|
@ -1279,7 +1310,7 @@ theorem forInStep_eq_foldlM {δ : Type w} {t : Impl α β} {m : Type w → Type
|
|||
induction r <;> simp [foldlM, *]
|
||||
|
||||
|
||||
theorem forIn_eq_forIn_toListModel {δ : Type w} {t : Impl α β} {m : Type w → Type w} [Monad m] [LawfulMonad m]
|
||||
theorem forIn_eq_forIn_toListModel {δ : Type w} {t : Impl α β} {m : Type w → Type w'} [Monad m] [LawfulMonad m]
|
||||
{f : (a : α) → β a → δ → m (ForInStep δ)} {init : δ} :
|
||||
t.forIn f init = ForIn.forIn t.toListModel init (fun a d => f a.1 a.2 d) := by
|
||||
rw [Impl.forIn, forInStep_eq_foldlM, List.forIn_eq_foldlM, foldlM_eq_foldlM_toListModel]
|
||||
|
|
@ -1339,11 +1370,8 @@ theorem alter_eq_alterₘ [Ord α] [TransOrd α] {t : Impl α β} {a f}
|
|||
rw [alter, updateCell]
|
||||
split <;> rename_i heq <;> simp only [heq]
|
||||
· simp [ihl htb.left hto.left]
|
||||
split <;> simp_all
|
||||
· simp [ihr htb.right hto.right]
|
||||
split <;> simp_all
|
||||
· apply Eq.symm
|
||||
split <;> (try simp_all; done)
|
||||
simp [Cell.Const.alter, Cell.ofOption, cast]
|
||||
cases h₁ : f _ <;> rfl
|
||||
|
||||
|
|
@ -1424,11 +1452,16 @@ theorem ordered_mergeWith [Ord α] [TransOrd α] {t₁ t₂ : Impl α β} {f}
|
|||
-/
|
||||
|
||||
theorem toList_eq_toListModel_map {t : Impl α β} :
|
||||
Const.toList t = t.toListModel.map fun ⟨k, v⟩ => (k, v) := by
|
||||
rw [toList, foldr_eq_foldr]
|
||||
induction t with
|
||||
| leaf => rfl
|
||||
| inner sz k v l r ihl ihr => simp
|
||||
Const.toList t = t.toListModel.map fun e => (e.1, e.2) := by
|
||||
simp [toList, foldr_eq_foldr]
|
||||
|
||||
/-!
|
||||
### toArray
|
||||
-/
|
||||
|
||||
theorem toArray_eq_toArray_map {t : Impl α β} :
|
||||
Const.toArray t = (t.toListModel.map fun e => (e.1, e.2)).toArray := by
|
||||
simp [toArray, foldl_eq_foldl]
|
||||
|
||||
end Const
|
||||
|
||||
|
|
@ -1460,11 +1493,11 @@ theorem WF.ordered [Ord α] [TransOrd α] {l : Impl α β} (h : WF l) : l.Ordere
|
|||
variable {β'} in
|
||||
/-- Internal implementation detail of the tree map -/
|
||||
inductive SameKeys : Impl α β → Impl α β' → Prop where
|
||||
/-- Internal implementation detail of the tree map -/
|
||||
| leaf : SameKeys .leaf .leaf
|
||||
/-- Internal implementation detail of the tree map -/
|
||||
| inner (sz k v v' r r' l l') : SameKeys r r' → SameKeys l l' →
|
||||
SameKeys (.inner sz k v l r) (.inner sz k v' l' r')
|
||||
/-- Internal implementation detail of the tree map -/
|
||||
| leaf : SameKeys .leaf .leaf
|
||||
/-- Internal implementation detail of the tree map -/
|
||||
| inner (sz k v v' r r' l l') : SameKeys r r' → SameKeys l l' →
|
||||
SameKeys (.inner sz k v l r) (.inner sz k v' l' r')
|
||||
|
||||
namespace SameKeys
|
||||
|
||||
|
|
@ -1793,11 +1826,6 @@ theorem WF.map [Ord α] {t : Impl α β} {f : (a : α) → β a → γ a} (h : t
|
|||
### `minEntry?`
|
||||
-/
|
||||
|
||||
instance [Ord α] : IsStrictCut (compare : α → α → Ordering) (fun _ => .lt) where
|
||||
lt := by simp
|
||||
gt := by simp
|
||||
eq := by simp
|
||||
|
||||
theorem minEntry?ₘ_eq_minEntry? [Ord α] [TransOrd α] {l : Impl α β} (hlo : l.Ordered) :
|
||||
l.minEntry?ₘ = List.minEntry? l.toListModel := by
|
||||
rw [minEntry?ₘ, applyPartition_eq_apply_toListModel' hlo]
|
||||
|
|
@ -1844,6 +1872,14 @@ theorem Ordered.reverse [Ord α] {t : Impl α β} (h : t.Ordered) :
|
|||
simp only [Ordered, toListModel_reverse]
|
||||
exact List.pairwise_reverse.mpr h
|
||||
|
||||
theorem maxEntry?_eq_minEntry? [o : Ord α] [to : TransOrd α] {t : Impl α β} (hlo : t.Ordered) :
|
||||
t.maxEntry? = (letI := o.opposite; List.minEntry? t.toListModel) := by
|
||||
rw [maxEntry?_eq_minEntry?_reverse, @minEntry?_eq_minEntry? _ _ (_) _ _ hlo.reverse]
|
||||
apply @List.minEntry?_of_perm _ _ o.opposite to.opposite (@beqOfOrd _ o.opposite)
|
||||
· exact @hlo.reverse.distinctKeys _ _ (@beqOfOrd _ o.opposite) (_) _
|
||||
· rw [toListModel_reverse]
|
||||
exact List.reverse_perm t.toListModel
|
||||
|
||||
theorem maxKey?_eq_maxKey? [Ord α] [TransOrd α] [BEq α] [LawfulBEqOrd α] {t : Impl α β}
|
||||
(hlo : t.Ordered) :
|
||||
t.maxKey? = List.maxKey? t.toListModel := by
|
||||
|
|
@ -1865,4 +1901,131 @@ theorem maxKeyD_eq_maxKeyD [Ord α] [TransOrd α] [BEq α] [LawfulBEqOrd α] {t
|
|||
t.maxKeyD fallback = List.maxKeyD t.toListModel fallback := by
|
||||
simp only [List.maxKeyD_eq_getD_maxKey?, maxKeyD_eq_getD_maxKey?, maxKey?_eq_maxKey? hlo]
|
||||
|
||||
/-!
|
||||
### `entryAtIdx?` / `keyAtIdx?`
|
||||
-/
|
||||
|
||||
theorem entryAtIdx?_eq_getElem? {t : Impl α β} (htb : t.Balanced) {i : Nat} :
|
||||
t.entryAtIdx? i = t.toListModel[i]? := by
|
||||
induction t, i using entryAtIdx?.induct_unfolding with
|
||||
| case1 => rfl
|
||||
| case2 _ _ _ _ _ _ h ih =>
|
||||
simp only [toListModel_inner, *, htb.left]
|
||||
simp_all only [toListModel_inner, Nat.compare_eq_lt, ← size_eq_length,
|
||||
List.getElem?_append_left, htb.left]
|
||||
| case3 =>
|
||||
simp only [toListModel_inner, *]
|
||||
simp_all only [Nat.compare_eq_eq, List.getElem?_append_right, Nat.le_refl, htb.left,
|
||||
← size_eq_length, Nat.sub_self, List.getElem?_cons_zero]
|
||||
| case4 =>
|
||||
simp only [toListModel_inner, *, htb.right]
|
||||
simp_all only [Nat.compare_eq_gt, List.getElem?_append_right, Nat.le_of_lt,
|
||||
← size_eq_length, htb.left, List.getElem?_cons, Nat.sub_eq_zero_iff_le,
|
||||
← Nat.not_lt, not_true, ↓reduceIte]
|
||||
|
||||
theorem entryAtIdx_eq_getElem {t : Impl α β} (htb : t.Balanced) {i : Nat} {h} :
|
||||
t.entryAtIdx htb i h = t.toListModel[i]'(size_eq_length t htb ▸ h) := by
|
||||
simp only [List.getElem_eq_getElem?_get, ← entryAtIdx?_eq_getElem? htb,
|
||||
entryAtIdx?_eq_some_entryAtIdx htb h, Option.get_some]
|
||||
|
||||
theorem entryAtIdx!_eq_getElem! {t : Impl α β} (htb : t.Balanced) {i : Nat}
|
||||
[Inhabited ((a : α) × β a)] : t.entryAtIdx! i = t.toListModel[i]! := by
|
||||
simp only [entryAtIdx!_eq_get!_entryAtIdx?, entryAtIdx?_eq_getElem? htb,
|
||||
List.getElem!_eq_getElem?_getD, Option.get!_eq_getD]
|
||||
|
||||
theorem entryAtIdxD_eq_getD {t : Impl α β} (htb : t.Balanced) {i : Nat} {fallback : (a : α) × β a} :
|
||||
t.entryAtIdxD i fallback = t.toListModel.getD i fallback := by
|
||||
simp only [entryAtIdxD_eq_getD_entryAtIdx?, entryAtIdx?_eq_getElem? htb,
|
||||
List.getD_eq_getElem?_getD]
|
||||
|
||||
theorem keyAtIdx?_eq_getElem? {t : Impl α β} (htb : t.Balanced) {i : Nat} :
|
||||
t.keyAtIdx? i = t.toListModel[i]?.map (·.1) := by
|
||||
rw [keyAtIdx?_eq_entryAtIdx?, entryAtIdx?_eq_getElem? htb]
|
||||
|
||||
theorem keyAtIdx_eq_getElem_fst {t : Impl α β} (htb : t.Balanced) {i : Nat} {h} :
|
||||
t.keyAtIdx htb i h = (t.toListModel[i]'(size_eq_length t htb ▸ h)).1 := by
|
||||
rw [keyAtIdx_eq_entryAtIdx_fst, entryAtIdx_eq_getElem htb]
|
||||
|
||||
theorem keyAtIdx!_eq_get!_map_getElem? [Inhabited α] {t : Impl α β} (htb : t.Balanced) {i : Nat} :
|
||||
t.keyAtIdx! i = (t.toListModel[i]?.map (·.1)).get! := by
|
||||
rw [keyAtIdx!_eq_get!_keyAtIdx?, keyAtIdx?_eq_getElem? htb]
|
||||
|
||||
theorem keyAtIdxD_eq_getD_map_getElem? {t : Impl α β} (htb : t.Balanced) {i : Nat} {fallback : α} :
|
||||
t.keyAtIdxD i fallback = (t.toListModel[i]?.map (·.1)).getD fallback := by
|
||||
rw [keyAtIdxD_eq_getD_keyAtIdx?, keyAtIdx?_eq_getElem? htb]
|
||||
|
||||
namespace Const
|
||||
|
||||
variable {β : Type v}
|
||||
|
||||
theorem entryAtIdx?_eq_getElem? {t : Impl α β} (htb : t.Balanced) {i : Nat} :
|
||||
entryAtIdx? t i = t.toListModel[i]?.map (fun x => (x.1, x.2)) := by
|
||||
rw [entryAtIdx?_eq_map, Impl.entryAtIdx?_eq_getElem? htb]
|
||||
|
||||
theorem entryAtIdx_eq_getElem {t : Impl α β} (htb : t.Balanced) {i : Nat} {h} :
|
||||
entryAtIdx t htb i h = (letI x := t.toListModel[i]'(size_eq_length t htb ▸ h); (x.1, x.2)) := by
|
||||
rw [entryAtIdx_eq, Impl.entryAtIdx_eq_getElem htb]
|
||||
|
||||
theorem entryAtIdx!_eq_get!_map_getElem? {t : Impl α β} (htb : t.Balanced) {i : Nat}
|
||||
[Inhabited (α × β)] :
|
||||
entryAtIdx! t i = (t.toListModel[i]?.map (fun x => (x.1, x.2))).get! := by
|
||||
rw [entryAtIdx!_eq_get!_entryAtIdx?, entryAtIdx?_eq_getElem? htb]
|
||||
|
||||
theorem entryAtIdxD_eq_getD_map_getElem? {t : Impl α β} (htb : t.Balanced) {i : Nat}
|
||||
{fallback : α × β} :
|
||||
entryAtIdxD t i fallback = (t.toListModel[i]?.map (fun x => (x.1, x.2))).getD fallback := by
|
||||
rw [entryAtIdxD_eq_getD_entryAtIdx?, entryAtIdx?_eq_getElem? htb]
|
||||
|
||||
end Const
|
||||
|
||||
/-!
|
||||
### `getEntryLE?` / `getKeyLE?` / ...
|
||||
-/
|
||||
|
||||
theorem getEntryGE?_eq_find? [Ord α] [TransOrd α] {t : Impl α β} (hto : t.Ordered) {k : α} :
|
||||
t.getEntryGE? k = t.toListModel.find? (fun e => (compare e.1 k).isGE) := by
|
||||
rw [getEntryGE?_eq_getEntryGE?ₘ, getEntryGE?ₘ, applyPartition_eq hto, List.head?_filter,
|
||||
List.findCell_inner]
|
||||
simp only [OrientedCmp.eq_swap (b := k), Ordering.isGE_swap, ← Ordering.isEq_eq_beq_eq,
|
||||
← Ordering.isLT_eq_beq_lt]
|
||||
change t.toListModel.Pairwise _ at hto
|
||||
revert hto
|
||||
induction t.toListModel using List.assoc_induction with
|
||||
| nil => intro hto; rfl
|
||||
| cons k' v t ih =>
|
||||
intro hto
|
||||
simp only [List.find?_cons]
|
||||
rw [List.pairwise_cons] at hto
|
||||
cases h : compare k k'
|
||||
· simp only [Option.or_some, Ordering.isLE_lt, Option.some.injEq,
|
||||
Ordering.isLT_lt, Ordering.isEq_lt]
|
||||
rw [List.find?_eq_none.mpr, Option.getD_none]
|
||||
intro x hx hkx; have := hto.1 x hx
|
||||
simp [TransCmp.lt_trans h this] at hkx
|
||||
· rfl
|
||||
· exact ih hto.2
|
||||
|
||||
theorem getEntryGT?_eq_find? [Ord α] [TransOrd α] {t : Impl α β} (hto : t.Ordered) {k : α} :
|
||||
t.getEntryGT? k = t.toListModel.find? (fun e => (compare e.1 k).isGT) := by
|
||||
rw [getEntryGT?_eq_getEntryGT?ₘ, getEntryGT?ₘ, applyPartition_eq hto, List.head?_filter]
|
||||
congr; funext x; rw [Bool.eq_iff_iff, beq_iff_eq, Ordering.isGT_iff_eq_gt]
|
||||
simp [OrientedCmp.eq_swap (a := k), Ordering.then_eq_lt]
|
||||
|
||||
theorem getEntryLE?_eq_findRev? [Ord α] [TransOrd α] {t : Impl α β} (hto : t.Ordered) {k : α} :
|
||||
getEntryLE? k t = t.toListModel.findRev? (fun e => (compare e.1 k).isLE) := by
|
||||
rw [getEntryLE?_eq_getEntryGE?_reverse, @getEntryGE?_eq_find?, List.findRev?_eq_find?_reverse,
|
||||
toListModel_reverse]
|
||||
· simp only [Ord.opposite, Bool.coe_iff_coe.mp OrientedCmp.isGE_iff_isLE]
|
||||
· exact hto.reverse
|
||||
|
||||
theorem getEntryLT?_eq_findRev? [Ord α] [TransOrd α] {t : Impl α β} (hto : t.Ordered) {k : α} :
|
||||
getEntryLT? k t = t.toListModel.findRev? (fun e => (compare e.1 k).isLT) := by
|
||||
rw [getEntryLT?_eq_getEntryGT?_reverse, @getEntryGT?_eq_find?, List.findRev?_eq_find?_reverse,
|
||||
toListModel_reverse]
|
||||
· congr; funext e
|
||||
rw [← Bool.coe_iff_coe]
|
||||
simp only [Ord.opposite, Ordering.isGT_iff_eq_gt, Ordering.isLT_iff_eq_lt]
|
||||
exact OrientedCmp.gt_iff_lt
|
||||
· exact hto.reverse
|
||||
|
||||
end Std.DTreeMap.Internal.Impl
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ Authors: Markus Himmel, Paul Reichert
|
|||
prelude
|
||||
import Std.Data.DTreeMap.Internal.Lemmas
|
||||
import Std.Data.DTreeMap.Basic
|
||||
import Std.Data.DTreeMap.AdditionalOperations
|
||||
|
||||
/-!
|
||||
# Dependent tree map lemmas
|
||||
|
|
@ -19,11 +20,11 @@ open Std.DTreeMap.Internal
|
|||
set_option linter.missingDocs true
|
||||
set_option autoImplicit false
|
||||
|
||||
universe u v w
|
||||
universe u v w w'
|
||||
|
||||
namespace Std.DTreeMap
|
||||
|
||||
variable {α : Type u} {β : α → Type v} {cmp : α → α → Ordering} {t : DTreeMap α β cmp}
|
||||
variable {α : Type u} {β : α → Type v} {γ : α → Type w} {cmp : α → α → Ordering} {t : DTreeMap α β cmp}
|
||||
private local instance : Coe (Type v) (α → Type v) where coe γ := fun _ => γ
|
||||
|
||||
private theorem ext {t t' : DTreeMap α β cmp} : t.inner = t'.inner → t = t' := by
|
||||
|
|
@ -1153,7 +1154,7 @@ end Const
|
|||
|
||||
section monadic
|
||||
|
||||
variable {δ : Type w} {m : Type w → Type w}
|
||||
variable {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m]
|
||||
{f : δ → (a : α) → β a → m δ} {init : δ} :
|
||||
|
|
@ -2206,7 +2207,7 @@ theorem mem_alter [TransCmp cmp] [LawfulEqCmp cmp] {k k' : α}
|
|||
if cmp k k' = .eq then (f (t.get? k)).isSome = true else k' ∈ t :=
|
||||
Impl.mem_alter t.wf
|
||||
|
||||
theorem mem_alter_of_compare_eq [TransCmp cmp] [LawfulEqCmp cmp] {k k': α}
|
||||
theorem mem_alter_of_compare_eq [TransCmp cmp] [LawfulEqCmp cmp] {k k' : α}
|
||||
{f : Option (β k) → Option (β k)}
|
||||
(he : cmp k k' = .eq) :
|
||||
k' ∈ t.alter k f ↔ (f (t.get? k)).isSome :=
|
||||
|
|
@ -2432,7 +2433,7 @@ theorem mem_alter [TransCmp cmp] {k k' : α} {f : Option β → Option β} :
|
|||
if cmp k k' = .eq then (f (get? t k)).isSome = true else k' ∈ t :=
|
||||
Impl.Const.mem_alter t.wf
|
||||
|
||||
theorem mem_alter_of_compare_eq [TransCmp cmp] {k k': α} {f : Option β → Option β}
|
||||
theorem mem_alter_of_compare_eq [TransCmp cmp] {k k' : α} {f : Option β → Option β}
|
||||
(he : cmp k k' = .eq) :
|
||||
k' ∈ alter t k f ↔ (f (get? t k)).isSome :=
|
||||
Impl.Const.mem_alter_of_compare_eq t.wf he
|
||||
|
|
@ -4193,4 +4194,628 @@ end Const
|
|||
|
||||
end Max
|
||||
|
||||
namespace Equiv
|
||||
|
||||
variable {t₁ t₂ t₃ t₄ : DTreeMap α β cmp} {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
@[refl, simp] theorem rfl : Equiv t t := ⟨.rfl⟩
|
||||
|
||||
@[symm] theorem symm : Equiv t₁ t₂ → Equiv t₂ t₁
|
||||
| ⟨h⟩ => ⟨h.symm⟩
|
||||
|
||||
theorem trans : Equiv t₁ t₂ → Equiv t₂ t₃ → Equiv t₁ t₃
|
||||
| ⟨h⟩, ⟨h'⟩ => ⟨h.trans h'⟩
|
||||
|
||||
instance instTrans : @Trans (DTreeMap α β cmp) _ _ Equiv Equiv Equiv := ⟨trans⟩
|
||||
|
||||
theorem comm : t₁ ~m t₂ ↔ t₂ ~m t₁ := ⟨symm, symm⟩
|
||||
theorem congr_left (h : t₁ ~m t₂) : t₁ ~m t₃ ↔ t₂ ~m t₃ := ⟨h.symm.trans, h.trans⟩
|
||||
theorem congr_right (h : t₁ ~m t₂) : t₃ ~m t₁ ↔ t₃ ~m t₂ :=
|
||||
⟨fun h' => h'.trans h, fun h' => h'.trans h.symm⟩
|
||||
|
||||
-- congruence lemmas
|
||||
|
||||
theorem isEmpty_eq (h : t₁ ~m t₂) : t₁.isEmpty = t₂.isEmpty :=
|
||||
h.1.isEmpty_eq
|
||||
|
||||
theorem contains_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.contains k = t₂.contains k :=
|
||||
h.1.contains_eq t₁.2 t₂.2
|
||||
|
||||
theorem mem_iff [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
k ∈ t₁ ↔ k ∈ t₂ :=
|
||||
h.1.mem_iff t₁.2 t₂.2
|
||||
|
||||
theorem size_eq (h : t₁ ~m t₂) : t₁.size = t₂.size :=
|
||||
h.1.size_eq t₁.2 t₂.2
|
||||
|
||||
theorem get?_eq [TransCmp cmp] [LawfulEqCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.get? k = t₂.get? k :=
|
||||
h.1.get?_eq t₁.2 t₂.2
|
||||
|
||||
theorem get_eq [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {hk : k ∈ t₁} (h : t₁ ~m t₂) :
|
||||
t₁.get k hk = t₂.get k (h.mem_iff.mp hk) :=
|
||||
h.1.get_eq t₁.2 t₂.2 hk
|
||||
|
||||
theorem get!_eq [TransCmp cmp] [LawfulEqCmp cmp] {k : α} [Inhabited (β k)] (h : t₁ ~m t₂) :
|
||||
t₁.get! k = t₂.get! k :=
|
||||
h.1.get!_eq t₁.2 t₂.2
|
||||
|
||||
theorem getD_eq [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {fallback : β k} (h : t₁ ~m t₂) :
|
||||
t₁.getD k fallback = t₂.getD k fallback :=
|
||||
h.1.getD_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKey?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKey? k = t₂.getKey? k :=
|
||||
h.1.getKey?_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKey_eq [TransCmp cmp] {k : α} {hk : k ∈ t₁} (h : t₁ ~m t₂) :
|
||||
t₁.getKey k hk = t₂.getKey k (h.mem_iff.mp hk) :=
|
||||
h.1.getKey_eq t₁.2 t₂.2 hk
|
||||
|
||||
theorem getKey!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKey! k = t₂.getKey! k :=
|
||||
h.1.getKey!_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyD_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyD k fallback = t₂.getKeyD k fallback :=
|
||||
h.1.getKeyD_eq t₁.2 t₂.2
|
||||
|
||||
theorem toList_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.toList = t₂.toList :=
|
||||
h.1.toList_eq t₁.2 t₂.2
|
||||
|
||||
theorem toArray_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.toArray = t₂.toArray :=
|
||||
h.1.toArray_eq t₁.2 t₂.2
|
||||
|
||||
theorem keys_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.keys = t₂.keys :=
|
||||
h.1.keys_eq t₁.2 t₂.2
|
||||
|
||||
theorem keysArray_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.keysArray = t₂.keysArray :=
|
||||
h.1.keysArray_eq t₁.2 t₂.2
|
||||
|
||||
theorem foldlM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : δ → (a : α) → β a → m δ}
|
||||
{init : δ} (h : t₁ ~m t₂) :
|
||||
t₁.foldlM f init = t₂.foldlM f init :=
|
||||
h.1.foldlM_eq t₁.2 t₂.2
|
||||
|
||||
theorem foldl_eq [TransCmp cmp] {f : δ → (a : α) → β a → δ} {init : δ} (h : t₁ ~m t₂) :
|
||||
t₁.foldl f init = t₂.foldl f init :=
|
||||
h.1.foldl_eq t₁.2 t₂.2
|
||||
|
||||
theorem foldrM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : (a : α) → β a → δ → m δ}
|
||||
{init : δ} (h : t₁ ~m t₂) :
|
||||
t₁.foldrM f init = t₂.foldrM f init :=
|
||||
h.1.foldrM_eq t₁.2 t₂.2
|
||||
|
||||
theorem foldr_eq [TransCmp cmp] {f : (a : α) → β a → δ → δ} {init : δ} (h : t₁ ~m t₂) :
|
||||
t₁.foldr f init = t₂.foldr f init :=
|
||||
h.1.foldr_eq t₁.2 t₂.2
|
||||
|
||||
theorem forIn_eq [TransCmp cmp] [Monad m] [LawfulMonad m]
|
||||
{b : δ} {f : (a : α) × β a → δ → m (ForInStep δ)} (h : t₁ ~m t₂) :
|
||||
ForIn.forIn t₁ b f = ForIn.forIn t₂ b f :=
|
||||
h.1.forIn_eq t₁.2 t₂.2
|
||||
|
||||
theorem forM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : (a : α) × β a → m PUnit}
|
||||
(h : t₁ ~m t₂) :
|
||||
ForM.forM t₁ f = ForM.forM t₂ f :=
|
||||
h.1.forM_eq t₁.2 t₂.2
|
||||
|
||||
theorem any_eq [TransCmp cmp] {p : (a : α) → β a → Bool} (h : t₁ ~m t₂) : t₁.any p = t₂.any p := by
|
||||
simp only [any, h.forIn_eq]
|
||||
|
||||
theorem all_eq [TransCmp cmp] {p : (a : α) → β a → Bool} (h : t₁ ~m t₂) : t₁.all p = t₂.all p := by
|
||||
simp only [all, h.forIn_eq]
|
||||
|
||||
theorem minKey?_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.minKey? = t₂.minKey? :=
|
||||
h.1.minKey?_eq t₁.2 t₂.2
|
||||
|
||||
theorem minKey_eq [TransCmp cmp] {h' : t₁.isEmpty = false} (h : t₁ ~m t₂) :
|
||||
t₁.minKey h' = t₂.minKey (h.isEmpty_eq.symm.trans h') :=
|
||||
h.1.minKey_eq t₁.2 t₂.2 h'
|
||||
|
||||
theorem minKey!_eq [TransCmp cmp] [Inhabited α] (h : t₁ ~m t₂) :
|
||||
t₁.minKey! = t₂.minKey! :=
|
||||
h.1.minKey!_eq t₁.2 t₂.2
|
||||
|
||||
theorem minKeyD_eq [TransCmp cmp] {fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.minKeyD fallback = t₂.minKeyD fallback :=
|
||||
h.1.minKeyD_eq t₁.2 t₂.2
|
||||
|
||||
theorem maxKey?_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.maxKey? = t₂.maxKey? :=
|
||||
h.1.maxKey?_eq t₁.2 t₂.2
|
||||
|
||||
theorem maxKey_eq [TransCmp cmp] {h' : t₁.isEmpty = false} (h : t₁ ~m t₂) :
|
||||
t₁.maxKey h' = t₂.maxKey (h.isEmpty_eq.symm.trans h') :=
|
||||
h.1.maxKey_eq t₁.2 t₂.2 h'
|
||||
|
||||
theorem maxKey!_eq [TransCmp cmp] [Inhabited α] (h : t₁ ~m t₂) :
|
||||
t₁.maxKey! = t₂.maxKey! :=
|
||||
h.1.maxKey!_eq t₁.2 t₂.2
|
||||
|
||||
theorem maxKeyD_eq [TransCmp cmp] {fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.maxKeyD fallback = t₂.maxKeyD fallback :=
|
||||
h.1.maxKeyD_eq t₁.2 t₂.2
|
||||
|
||||
theorem minEntry?_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.minEntry? = t₂.minEntry? :=
|
||||
h.1.minEntry?_eq t₁.2 t₂.2
|
||||
|
||||
theorem minEntry_eq [TransCmp cmp] {he : t₁.isEmpty = false} (h : t₁ ~m t₂) :
|
||||
t₁.minEntry he = t₂.minEntry (h.isEmpty_eq.symm.trans he) :=
|
||||
h.1.minEntry_eq t₁.2 t₂.2
|
||||
|
||||
theorem minEntry!_eq [TransCmp cmp] [Inhabited ((a : α) × β a)] (h : t₁ ~m t₂) :
|
||||
t₁.minEntry! = t₂.minEntry! :=
|
||||
h.1.minEntry!_eq t₁.2 t₂.2
|
||||
|
||||
theorem minEntryD_eq [TransCmp cmp] {fallback : (a : α) × β a} (h : t₁ ~m t₂) :
|
||||
t₁.minEntryD fallback = t₂.minEntryD fallback :=
|
||||
h.1.minEntryD_eq t₁.2 t₂.2
|
||||
|
||||
theorem maxEntry?_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.maxEntry? = t₂.maxEntry? :=
|
||||
h.1.maxEntry?_eq t₁.2 t₂.2
|
||||
|
||||
theorem maxEntry_eq [TransCmp cmp] {he : t₁.isEmpty = false} (h : t₁ ~m t₂) :
|
||||
t₁.maxEntry he = t₂.maxEntry (h.isEmpty_eq.symm.trans he) :=
|
||||
h.1.maxEntry_eq t₁.2 t₂.2
|
||||
|
||||
theorem maxEntry!_eq [TransCmp cmp] [Inhabited ((a : α) × β a)] (h : t₁ ~m t₂) :
|
||||
t₁.maxEntry! = t₂.maxEntry! :=
|
||||
h.1.maxEntry!_eq t₁.2 t₂.2
|
||||
|
||||
theorem maxEntryD_eq [TransCmp cmp] {fallback : (a : α) × β a} (h : t₁ ~m t₂) :
|
||||
t₁.maxEntryD fallback = t₂.maxEntryD fallback :=
|
||||
h.1.maxEntryD_eq t₁.2 t₂.2
|
||||
|
||||
theorem entryAtIdx?_eq [TransCmp cmp] {i : Nat} (h : t₁ ~m t₂) :
|
||||
t₁.entryAtIdx? i = t₂.entryAtIdx? i :=
|
||||
h.1.entryAtIdx?_eq t₁.2 t₂.2
|
||||
|
||||
theorem entryAtIdx_eq [TransCmp cmp] {i : Nat} {h' : i < t₁.size} (h : t₁ ~m t₂) :
|
||||
t₁.entryAtIdx i h' = t₂.entryAtIdx i (h.size_eq ▸ h') :=
|
||||
h.1.entryAtIdx_eq t₁.2 t₂.2
|
||||
|
||||
theorem entryAtIdx!_eq [TransCmp cmp] [Inhabited ((a : α) × β a)] {i : Nat} (h : t₁ ~m t₂) :
|
||||
t₁.entryAtIdx! i = t₂.entryAtIdx! i :=
|
||||
h.1.entryAtIdx!_eq t₁.2 t₂.2
|
||||
|
||||
theorem entryAtIdxD_eq [TransCmp cmp] {i : Nat} {fallback : (a : α) × β a} (h : t₁ ~m t₂) :
|
||||
t₁.entryAtIdxD i fallback = t₂.entryAtIdxD i fallback :=
|
||||
h.1.entryAtIdxD_eq t₁.2 t₂.2
|
||||
|
||||
theorem keyAtIdx?_eq [TransCmp cmp] {i : Nat} (h : t₁ ~m t₂) :
|
||||
t₁.keyAtIdx? i = t₂.keyAtIdx? i :=
|
||||
h.1.keyAtIdx?_eq t₁.2 t₂.2
|
||||
|
||||
theorem keyAtIdx_eq [TransCmp cmp] {i : Nat} {h' : i < t₁.size} (h : t₁ ~m t₂) :
|
||||
t₁.keyAtIdx i h' = t₂.keyAtIdx i (h.size_eq ▸ h') :=
|
||||
h.1.keyAtIdx_eq t₁.2 t₂.2
|
||||
|
||||
theorem keyAtIdx!_eq [TransCmp cmp] [Inhabited α] {i : Nat} (h : t₁ ~m t₂) :
|
||||
t₁.keyAtIdx! i = t₂.keyAtIdx! i :=
|
||||
h.1.keyAtIdx!_eq t₁.2 t₂.2
|
||||
|
||||
theorem keyAtIdxD_eq [TransCmp cmp] {i : Nat} {fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.keyAtIdxD i fallback = t₂.keyAtIdxD i fallback :=
|
||||
h.1.keyAtIdxD_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryGE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGE? k = t₂.getEntryGE? k :=
|
||||
h.1.getEntryGE?_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryGE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGE k h' = t₂.getEntryGE k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getEntryGE_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryGE!_eq [TransCmp cmp] [Inhabited ((a : α) × β a)] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGE! k = t₂.getEntryGE! k :=
|
||||
h.1.getEntryGE!_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryGED_eq [TransCmp cmp] {k : α} {fallback : (a : α) × β a} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGED k fallback = t₂.getEntryGED k fallback :=
|
||||
h.1.getEntryGED_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryGT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGT? k = t₂.getEntryGT? k :=
|
||||
h.1.getEntryGT?_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryGT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGT k h' = t₂.getEntryGT k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getEntryGT_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryGT!_eq [TransCmp cmp] [Inhabited ((a : α) × β a)] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGT! k = t₂.getEntryGT! k :=
|
||||
h.1.getEntryGT!_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryGTD_eq [TransCmp cmp] {k : α} {fallback : (a : α) × β a} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGTD k fallback = t₂.getEntryGTD k fallback :=
|
||||
h.1.getEntryGTD_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryLE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLE? k = t₂.getEntryLE? k :=
|
||||
h.1.getEntryLE?_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryLE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLE k h' = t₂.getEntryLE k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getEntryLE_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryLE!_eq [TransCmp cmp] [Inhabited ((a : α) × β a)] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLE! k = t₂.getEntryLE! k :=
|
||||
h.1.getEntryLE!_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryLED_eq [TransCmp cmp] {k : α} {fallback : (a : α) × β a} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLED k fallback = t₂.getEntryLED k fallback :=
|
||||
h.1.getEntryLED_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryLT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLT? k = t₂.getEntryLT? k :=
|
||||
h.1.getEntryLT?_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryLT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLT k h' = t₂.getEntryLT k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getEntryLT_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryLT!_eq [TransCmp cmp] [Inhabited ((a : α) × β a)] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLT! k = t₂.getEntryLT! k :=
|
||||
h.1.getEntryLT!_eq t₁.2 t₂.2
|
||||
|
||||
theorem getEntryLTD_eq [TransCmp cmp] {k : α} {fallback : (a : α) × β a} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLTD k fallback = t₂.getEntryLTD k fallback :=
|
||||
h.1.getEntryLTD_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyGE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGE? k = t₂.getKeyGE? k :=
|
||||
h.1.getKeyGE?_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyGE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGE k h' = t₂.getKeyGE k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getKeyGE_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyGE!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGE! k = t₂.getKeyGE! k :=
|
||||
h.1.getKeyGE!_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyGED_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGED k fallback = t₂.getKeyGED k fallback :=
|
||||
h.1.getKeyGED_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyGT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGT? k = t₂.getKeyGT? k :=
|
||||
h.1.getKeyGT?_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyGT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGT k h' = t₂.getKeyGT k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getKeyGT_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyGT!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGT! k = t₂.getKeyGT! k :=
|
||||
h.1.getKeyGT!_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyGTD_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGTD k fallback = t₂.getKeyGTD k fallback :=
|
||||
h.1.getKeyGTD_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyLE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLE? k = t₂.getKeyLE? k :=
|
||||
h.1.getKeyLE?_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyLE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLE k h' = t₂.getKeyLE k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getKeyLE_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyLE!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLE! k = t₂.getKeyLE! k :=
|
||||
h.1.getKeyLE!_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyLED_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLED k fallback = t₂.getKeyLED k fallback :=
|
||||
h.1.getKeyLED_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyLT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLT? k = t₂.getKeyLT? k :=
|
||||
h.1.getKeyLT?_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyLT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLT k h' = t₂.getKeyLT k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getKeyLT_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyLT!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLT! k = t₂.getKeyLT! k :=
|
||||
h.1.getKeyLT!_eq t₁.2 t₂.2
|
||||
|
||||
theorem getKeyLTD_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLTD k fallback = t₂.getKeyLTD k fallback :=
|
||||
h.1.getKeyLTD_eq t₁.2 t₂.2
|
||||
|
||||
theorem insert [TransCmp cmp] (h : t₁ ~m t₂) (k : α) (v : β k) : t₁.insert k v ~m t₂.insert k v :=
|
||||
⟨h.1.insert t₁.2 t₂.2⟩
|
||||
|
||||
theorem erase [TransCmp cmp] (h : t₁ ~m t₂) (k : α) : t₁.erase k ~m t₂.erase k :=
|
||||
⟨h.1.erase t₁.2 t₂.2⟩
|
||||
|
||||
theorem insertIfNew [TransCmp cmp] (h : t₁ ~m t₂) (k : α) (v : β k) :
|
||||
t₁.insertIfNew k v ~m t₂.insertIfNew k v :=
|
||||
⟨h.1.insertIfNew t₁.2 t₂.2⟩
|
||||
|
||||
theorem alter [TransCmp cmp] [LawfulEqCmp cmp] (h : t₁ ~m t₂)
|
||||
(k : α) (f : Option (β k) → Option (β k)) : t₁.alter k f ~m t₂.alter k f :=
|
||||
⟨h.1.alter t₁.2 t₂.2⟩
|
||||
|
||||
theorem modify [TransCmp cmp] [LawfulEqCmp cmp] (h : t₁ ~m t₂)
|
||||
(k : α) (f : β k → β k) : t₁.modify k f ~m t₂.modify k f :=
|
||||
⟨h.1.modify t₁.2 t₂.2⟩
|
||||
|
||||
theorem filter (h : t₁ ~m t₂) (f : (a : α) → β a → Bool) : t₁.filter f ~m t₂.filter f :=
|
||||
⟨h.1.filter t₁.2 t₂.2⟩
|
||||
|
||||
theorem map (h : t₁ ~m t₂) (f : (a : α) → β a → γ a) : t₁.map f ~m t₂.map f :=
|
||||
⟨h.1.map⟩
|
||||
|
||||
theorem filterMap (h : t₁ ~m t₂) (f : (a : α) → β a → Option (γ a)) :
|
||||
t₁.filterMap f ~m t₂.filterMap f :=
|
||||
⟨h.1.filterMap t₁.2 t₂.2⟩
|
||||
|
||||
theorem insertMany_list [TransCmp cmp] (h : t₁ ~m t₂) (l : List ((a : α) × β a)) :
|
||||
t₁.insertMany l ~m t₂.insertMany l :=
|
||||
⟨h.1.insertMany_list t₁.2 t₂.2⟩
|
||||
|
||||
theorem eraseMany_list [TransCmp cmp] (h : t₁ ~m t₂) (l : List α) :
|
||||
t₁.eraseMany l ~m t₂.eraseMany l :=
|
||||
⟨h.1.eraseMany_list t₁.2 t₂.2⟩
|
||||
|
||||
theorem mergeWith [TransCmp cmp] [LawfulEqCmp cmp] (f : (a : α) → β a → β a → β a)
|
||||
(h : t₁ ~m t₂) (h' : t₃ ~m t₄) : t₁.mergeWith f t₃ ~m t₂.mergeWith f t₄ :=
|
||||
⟨h.1.mergeWith h'.1 t₁.2 t₂.2 t₃.2 t₄.2⟩
|
||||
|
||||
section Const
|
||||
|
||||
variable {β : Type v} {t₁ t₂ t₃ t₄ : DTreeMap α β cmp} {δ : Type w} {m : Type w → Type w}
|
||||
|
||||
theorem constGet?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) : Const.get? t₁ k = Const.get? t₂ k :=
|
||||
h.1.constGet?_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGet_eq [TransCmp cmp] {k : α} {hk : k ∈ t₁} (h : t₁ ~m t₂) :
|
||||
Const.get t₁ k hk = Const.get t₂ k (h.mem_iff.mp hk) :=
|
||||
h.1.constGet_eq t₁.2 t₂.2 hk
|
||||
|
||||
theorem constGet!_eq [TransCmp cmp] [Inhabited β] {k : α} (h : t₁ ~m t₂) :
|
||||
Const.get! t₁ k = Const.get! t₂ k :=
|
||||
h.1.constGet!_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetD_eq [TransCmp cmp] {k : α} {fallback : β} (h : t₁ ~m t₂) :
|
||||
Const.getD t₁ k fallback = Const.getD t₂ k fallback :=
|
||||
h.1.constGetD_eq t₁.2 t₂.2
|
||||
|
||||
theorem constToList_eq [TransCmp cmp] (h : t₁ ~m t₂) : Const.toList t₁ = Const.toList t₂ :=
|
||||
h.1.constToList_eq t₁.2 t₂.2
|
||||
|
||||
theorem constToArray_eq [TransCmp cmp] (h : t₁ ~m t₂) : Const.toArray t₁ = Const.toArray t₂ :=
|
||||
h.1.constToArray_eq t₁.2 t₂.2
|
||||
|
||||
theorem values_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.values = t₂.values :=
|
||||
h.1.values_eq t₁.2 t₂.2
|
||||
|
||||
theorem valuesArray_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.valuesArray = t₂.valuesArray :=
|
||||
h.1.valuesArray_eq t₁.2 t₂.2
|
||||
|
||||
theorem constMinEntry?_eq [TransCmp cmp] (h : t₁ ~m t₂) :
|
||||
Const.minEntry? t₁ = Const.minEntry? t₂ :=
|
||||
h.1.constMinEntry?_eq t₁.2 t₂.2
|
||||
|
||||
theorem constMinEntry_eq [TransCmp cmp] {he : t₁.isEmpty = false} (h : t₁ ~m t₂) :
|
||||
Const.minEntry t₁ he = Const.minEntry t₂ (h.isEmpty_eq.symm.trans he) :=
|
||||
h.1.constMinEntry_eq t₁.2 t₂.2
|
||||
|
||||
theorem constMinEntry!_eq [TransCmp cmp] [Inhabited (α × β)] (h : t₁ ~m t₂) :
|
||||
Const.minEntry! t₁ = Const.minEntry! t₂ :=
|
||||
h.1.constMinEntry!_eq t₁.2 t₂.2
|
||||
|
||||
theorem constMinEntryD_eq [TransCmp cmp] {fallback : α × β} (h : t₁ ~m t₂) :
|
||||
Const.minEntryD t₁ fallback = Const.minEntryD t₂ fallback :=
|
||||
h.1.constMinEntryD_eq t₁.2 t₂.2
|
||||
|
||||
theorem constMaxEntry?_eq [TransCmp cmp] (h : t₁ ~m t₂) :
|
||||
Const.maxEntry? t₁ = Const.maxEntry? t₂ :=
|
||||
h.1.constMaxEntry?_eq t₁.2 t₂.2
|
||||
|
||||
theorem constMaxEntry_eq [TransCmp cmp] {he : t₁.isEmpty = false} (h : t₁ ~m t₂) :
|
||||
Const.maxEntry t₁ he = Const.maxEntry t₂ (h.isEmpty_eq.symm.trans he) :=
|
||||
h.1.constMaxEntry_eq t₁.2 t₂.2
|
||||
|
||||
theorem constMaxEntry!_eq [TransCmp cmp] [Inhabited (α × β)] (h : t₁ ~m t₂) :
|
||||
Const.maxEntry! t₁ = Const.maxEntry! t₂ :=
|
||||
h.1.constMaxEntry!_eq t₁.2 t₂.2
|
||||
|
||||
theorem constMaxEntryD_eq [TransCmp cmp] {fallback : α × β} (h : t₁ ~m t₂) :
|
||||
Const.maxEntryD t₁ fallback = Const.maxEntryD t₂ fallback :=
|
||||
h.1.constMaxEntryD_eq t₁.2 t₂.2
|
||||
|
||||
theorem constEntryAtIdx?_eq [TransCmp cmp] {i : Nat} (h : t₁ ~m t₂) :
|
||||
Const.entryAtIdx? t₁ i = Const.entryAtIdx? t₂ i :=
|
||||
h.1.constEntryAtIdx?_eq t₁.2 t₂.2
|
||||
|
||||
theorem constEntryAtIdx_eq [TransCmp cmp] {i : Nat} {h' : i < t₁.size} (h : t₁ ~m t₂) :
|
||||
Const.entryAtIdx t₁ i h' = Const.entryAtIdx t₂ i (h.size_eq ▸ h') :=
|
||||
h.1.constEntryAtIdx_eq t₁.2 t₂.2
|
||||
|
||||
theorem constEntryAtIdx!_eq [TransCmp cmp] [Inhabited (α × β)] {i : Nat} (h : t₁ ~m t₂) :
|
||||
Const.entryAtIdx! t₁ i = Const.entryAtIdx! t₂ i :=
|
||||
h.1.constEntryAtIdx!_eq t₁.2 t₂.2
|
||||
|
||||
theorem constEntryAtIdxD_eq [TransCmp cmp] {i : Nat} {fallback : α × β} (h : t₁ ~m t₂) :
|
||||
Const.entryAtIdxD t₁ i fallback = Const.entryAtIdxD t₂ i fallback :=
|
||||
h.1.constEntryAtIdxD_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryGE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
Const.getEntryGE? t₁ k = Const.getEntryGE? t₂ k :=
|
||||
h.1.constGetEntryGE?_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryGE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
Const.getEntryGE t₁ k h' = Const.getEntryGE t₂ k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.constGetEntryGE_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryGE!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h : t₁ ~m t₂) :
|
||||
Const.getEntryGE! t₁ k = Const.getEntryGE! t₂ k :=
|
||||
h.1.constGetEntryGE!_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryGED_eq [TransCmp cmp] {k : α} {fallback : α × β} (h : t₁ ~m t₂) :
|
||||
Const.getEntryGED t₁ k fallback = Const.getEntryGED t₂ k fallback :=
|
||||
h.1.constGetEntryGED_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryGT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
Const.getEntryGT? t₁ k = Const.getEntryGT? t₂ k :=
|
||||
h.1.constGetEntryGT?_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryGT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
Const.getEntryGT t₁ k h' = Const.getEntryGT t₂ k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.constGetEntryGT_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryGT!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h : t₁ ~m t₂) :
|
||||
Const.getEntryGT! t₁ k = Const.getEntryGT! t₂ k :=
|
||||
h.1.constGetEntryGT!_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryGTD_eq [TransCmp cmp] {k : α} {fallback : α × β} (h : t₁ ~m t₂) :
|
||||
Const.getEntryGTD t₁ k fallback = Const.getEntryGTD t₂ k fallback :=
|
||||
h.1.constGetEntryGTD_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryLE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
Const.getEntryLE? t₁ k = Const.getEntryLE? t₂ k :=
|
||||
h.1.constGetEntryLE?_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryLE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
Const.getEntryLE t₁ k h' = Const.getEntryLE t₂ k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.constGetEntryLE_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryLE!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h : t₁ ~m t₂) :
|
||||
Const.getEntryLE! t₁ k = Const.getEntryLE! t₂ k :=
|
||||
h.1.constGetEntryLE!_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryLED_eq [TransCmp cmp] {k : α} {fallback : α × β} (h : t₁ ~m t₂) :
|
||||
Const.getEntryLED t₁ k fallback = Const.getEntryLED t₂ k fallback :=
|
||||
h.1.constGetEntryLED_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryLT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
Const.getEntryLT? t₁ k = Const.getEntryLT? t₂ k :=
|
||||
h.1.constGetEntryLT?_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryLT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
Const.getEntryLT t₁ k h' = Const.getEntryLT t₂ k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.constGetEntryLT_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryLT!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h : t₁ ~m t₂) :
|
||||
Const.getEntryLT! t₁ k = Const.getEntryLT! t₂ k :=
|
||||
h.1.constGetEntryLT!_eq t₁.2 t₂.2
|
||||
|
||||
theorem constGetEntryLTD_eq [TransCmp cmp] {k : α} {fallback : α × β} (h : t₁ ~m t₂) :
|
||||
Const.getEntryLTD t₁ k fallback = Const.getEntryLTD t₂ k fallback :=
|
||||
h.1.constGetEntryLTD_eq t₁.2 t₂.2
|
||||
|
||||
theorem constAlter [TransCmp cmp] (h : t₁ ~m t₂) (k : α) (f : Option β → Option β) :
|
||||
Const.alter t₁ k f ~m Const.alter t₂ k f :=
|
||||
⟨h.1.constAlter t₁.2 t₂.2⟩
|
||||
|
||||
theorem constModify [TransCmp cmp] (h : t₁ ~m t₂) (k : α) (f : β → β) :
|
||||
Const.modify t₁ k f ~m Const.modify t₂ k f :=
|
||||
⟨h.1.constModify t₁.2 t₂.2⟩
|
||||
|
||||
theorem constInsertMany_list [TransCmp cmp] (h : t₁ ~m t₂) (l : List (α × β)) :
|
||||
Const.insertMany t₁ l ~m Const.insertMany t₂ l :=
|
||||
⟨h.1.constInsertMany_list t₁.2 t₂.2⟩
|
||||
|
||||
theorem constInsertManyIfNewUnit_list [TransCmp cmp] {t₁ t₂ : DTreeMap α Unit cmp}
|
||||
(h : t₁ ~m t₂) (l : List α) :
|
||||
Const.insertManyIfNewUnit t₁ l ~m Const.insertManyIfNewUnit t₂ l :=
|
||||
⟨h.1.constInsertManyIfNewUnit_list t₁.2 t₂.2⟩
|
||||
|
||||
theorem constMergeWith [TransCmp cmp] (f : α → β → β → β) (h : t₁ ~m t₂) (h' : t₃ ~m t₄) :
|
||||
Const.mergeWith f t₁ t₃ ~m Const.mergeWith f t₂ t₄ :=
|
||||
⟨h.1.constMergeWith h'.1 t₁.2 t₂.2 t₃.2 t₄.2⟩
|
||||
|
||||
end Const
|
||||
|
||||
-- extensionalities
|
||||
|
||||
theorem of_forall_get?_eq [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
(h : ∀ k, t₁.get? k = t₂.get? k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_get?_eq t₁.2 t₂.2 h⟩
|
||||
|
||||
section Const
|
||||
|
||||
variable {β : Type v} {t₁ t₂ : DTreeMap α β cmp}
|
||||
|
||||
theorem of_forall_getKey_eq_of_forall_constGet?_eq [TransCmp cmp]
|
||||
(hk : ∀ k hk hk', t₁.getKey k hk = t₂.getKey k hk')
|
||||
(hv : ∀ k, Const.get? t₁ k = Const.get? t₂ k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_getKey_eq_of_forall_constGet?_eq t₁.2 t₂.2 hk hv⟩
|
||||
|
||||
theorem of_forall_constGet?_eq [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
(h : ∀ k, Const.get? t₁ k = Const.get? t₂ k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_constGet?_eq t₁.2 t₂.2 h⟩
|
||||
|
||||
theorem of_forall_getKey?_unit_eq [TransCmp cmp] {t₁ t₂ : DTreeMap α Unit cmp}
|
||||
(h : ∀ k, t₁.getKey? k = t₂.getKey? k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_getKey?_unit_eq t₁.2 t₂.2 h⟩
|
||||
|
||||
theorem of_forall_contains_unit_eq [TransCmp cmp] [LawfulEqCmp cmp] {t₁ t₂ : DTreeMap α Unit cmp}
|
||||
(h : ∀ k, t₁.contains k = t₂.contains k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_contains_unit_eq t₁.2 t₂.2 h⟩
|
||||
|
||||
theorem of_forall_mem_unit_iff [TransCmp cmp] [LawfulEqCmp cmp] {t₁ t₂ : DTreeMap α Unit cmp}
|
||||
(h : ∀ k, k ∈ t₁ ↔ k ∈ t₂) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_mem_unit_iff t₁.2 t₂.2 h⟩
|
||||
|
||||
end Const
|
||||
|
||||
end Equiv
|
||||
|
||||
section Equiv
|
||||
|
||||
variable {t₁ t₂ : DTreeMap α β cmp}
|
||||
|
||||
private theorem equiv_iff_equiv : t₁ ~m t₂ ↔ t₁.1.Equiv t₂.1 :=
|
||||
⟨fun ⟨h⟩ => h, fun h => ⟨h⟩⟩
|
||||
|
||||
theorem equiv_empty_iff_isEmpty : t ~m empty ↔ t.isEmpty :=
|
||||
equiv_iff_equiv.trans Impl.equiv_empty_iff_isEmpty
|
||||
|
||||
theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
|
||||
Equiv.comm.trans equiv_empty_iff_isEmpty
|
||||
|
||||
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList :=
|
||||
equiv_iff_equiv.trans Impl.equiv_iff_toList_perm
|
||||
|
||||
theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ :=
|
||||
⟨.of_toList_perm h⟩
|
||||
|
||||
theorem equiv_iff_toList_eq [TransCmp cmp] :
|
||||
t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
|
||||
equiv_iff_equiv.trans (Impl.equiv_iff_toList_eq t₁.2 t₂.2)
|
||||
|
||||
section Const
|
||||
|
||||
variable {β : Type v} {t₁ t₂ : DTreeMap α β cmp}
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
theorem Const.equiv_iff_keys_unit_eq [TransCmp cmp] {t₁ t₂ : DTreeMap α Unit cmp} :
|
||||
t₁ ~m t₂ ↔ t₁.keys = t₂.keys :=
|
||||
equiv_iff_equiv.trans (Impl.Const.equiv_iff_keys_eq t₁.2 t₂.2)
|
||||
|
||||
theorem Equiv.of_constToList_perm : (Const.toList t₁).Perm (Const.toList t₂) → t₁ ~m t₂ :=
|
||||
Const.equiv_iff_toList_perm.mpr
|
||||
|
||||
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
|
||||
|
||||
end Const
|
||||
|
||||
end Equiv
|
||||
|
||||
end Std.DTreeMap
|
||||
|
|
|
|||
|
|
@ -92,6 +92,13 @@ instance : EmptyCollection (Raw α β cmp) := ⟨empty⟩
|
|||
|
||||
instance : Inhabited (Raw α β cmp) := ⟨∅⟩
|
||||
|
||||
@[inherit_doc Impl.Equiv]
|
||||
structure Equiv (m₁ m₂ : Raw α β cmp) where
|
||||
/-- Internal implementation detail of the tree map -/
|
||||
inner : m₁.1.Equiv m₂.1
|
||||
|
||||
@[inherit_doc] scoped infix:50 " ~m " => Equiv
|
||||
|
||||
@[simp]
|
||||
theorem empty_eq_emptyc : (empty : Raw α β cmp) = ∅ :=
|
||||
rfl
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ Authors: Markus Himmel, Paul Reichert
|
|||
prelude
|
||||
import Std.Data.DTreeMap.Internal.Lemmas
|
||||
import Std.Data.DTreeMap.Raw.Basic
|
||||
import Std.Data.DTreeMap.Raw.AdditionalOperations
|
||||
|
||||
/-!
|
||||
# Dependent tree map lemmas
|
||||
|
|
@ -20,11 +21,11 @@ set_option autoImplicit false
|
|||
|
||||
open Std.DTreeMap.Internal
|
||||
|
||||
universe u v w
|
||||
universe u v w w'
|
||||
|
||||
namespace Std.DTreeMap.Raw
|
||||
|
||||
variable {α : Type u} {β : α → Type v} {cmp : α → α → Ordering} {t : DTreeMap.Raw α β cmp}
|
||||
variable {α : Type u} {β : α → Type v} {γ : α → Type w} {cmp : α → α → Ordering} {t : DTreeMap.Raw α β cmp}
|
||||
private local instance : Coe (Type v) (α → Type v) where coe γ := fun _ => γ
|
||||
|
||||
private theorem ext {t t' : Raw α β cmp} : t.inner = t'.inner → t = t' := by
|
||||
|
|
@ -1164,7 +1165,7 @@ end Const
|
|||
|
||||
section monadic
|
||||
|
||||
variable {δ : Type w} {m : Type w → Type w}
|
||||
variable {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m] {f : δ → (a : α) → β a → m δ} {init : δ} :
|
||||
t.foldlM f init = t.toList.foldlM (fun a b => f a b.1 b.2) init :=
|
||||
|
|
@ -2241,7 +2242,7 @@ theorem mem_alter [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k k' : α}
|
|||
k' ∈ t.alter k f ↔ if cmp k k' = .eq then (f (t.get? k)).isSome = true else k' ∈ t :=
|
||||
Impl.mem_alter! h
|
||||
|
||||
theorem mem_alter_of_compare_eq [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k k': α}
|
||||
theorem mem_alter_of_compare_eq [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k k' : α}
|
||||
{f : Option (β k) → Option (β k)}
|
||||
(he : cmp k k' = .eq) :
|
||||
k' ∈ t.alter k f ↔ (f (t.get? k)).isSome :=
|
||||
|
|
@ -2467,7 +2468,7 @@ theorem mem_alter [TransCmp cmp] (h : t.WF) {k k' : α} {f : Option β → Optio
|
|||
if cmp k k' = .eq then (f (get? t k)).isSome = true else k' ∈ t :=
|
||||
Impl.Const.mem_alter! h
|
||||
|
||||
theorem mem_alter_of_compare_eq [TransCmp cmp] (h : t.WF) {k k': α} {f : Option β → Option β}
|
||||
theorem mem_alter_of_compare_eq [TransCmp cmp] (h : t.WF) {k k' : α} {f : Option β → Option β}
|
||||
(he : cmp k k' = .eq) :
|
||||
k' ∈ alter t k f ↔ (f (get? t k)).isSome :=
|
||||
Impl.Const.mem_alter!_of_compare_eq h he
|
||||
|
|
@ -3130,7 +3131,7 @@ theorem minKey?_modify_eq_minKey? [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k
|
|||
Impl.Const.minKey?_modify_eq_minKey? h
|
||||
|
||||
@[grind =]
|
||||
theorem isSome_minKey?_modify [TransCmp cmp] {k f} (h : t.WF) :
|
||||
theorem isSome_minKey?_modify [TransCmp cmp] {k f} (h : t.WF) :
|
||||
(Const.modify t k f).minKey?.isSome = !t.isEmpty :=
|
||||
Impl.Const.isSome_minKey?_modify h
|
||||
|
||||
|
|
@ -3627,7 +3628,7 @@ theorem maxKey?_modify_eq_maxKey? [TransCmp cmp] [LawfulEqCmp cmp] (h : t.WF) {k
|
|||
(Const.modify t k f).maxKey? = t.maxKey? :=
|
||||
Impl.Const.maxKey?_modify_eq_maxKey? h
|
||||
|
||||
theorem isSome_maxKey?_modify [TransCmp cmp] {k f} (h : t.WF) :
|
||||
theorem isSome_maxKey?_modify [TransCmp cmp] {k f} (h : t.WF) :
|
||||
(Const.modify t k f).maxKey?.isSome = !t.isEmpty :=
|
||||
Impl.Const.isSome_maxKey?_modify h
|
||||
|
||||
|
|
@ -3941,4 +3942,576 @@ end Const
|
|||
|
||||
end Max
|
||||
|
||||
namespace Equiv
|
||||
|
||||
variable {t₁ t₂ t₃ t₄ : Raw α β cmp} {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
@[refl, simp] theorem rfl : Equiv t t := ⟨.rfl⟩
|
||||
|
||||
@[symm] theorem symm : Equiv t₁ t₂ → Equiv t₂ t₁
|
||||
| ⟨h⟩ => ⟨h.symm⟩
|
||||
|
||||
theorem trans : Equiv t₁ t₂ → Equiv t₂ t₃ → Equiv t₁ t₃
|
||||
| ⟨h⟩, ⟨h'⟩ => ⟨h.trans h'⟩
|
||||
|
||||
instance instTrans : @Trans (Raw α β cmp) _ _ Equiv Equiv Equiv := ⟨trans⟩
|
||||
|
||||
theorem comm : t₁ ~m t₂ ↔ t₂ ~m t₁ := ⟨symm, symm⟩
|
||||
theorem congr_left (h : t₁ ~m t₂) : t₁ ~m t₃ ↔ t₂ ~m t₃ := ⟨h.symm.trans, h.trans⟩
|
||||
theorem congr_right (h : t₁ ~m t₂) : t₃ ~m t₁ ↔ t₃ ~m t₂ :=
|
||||
⟨fun h' => h'.trans h, fun h' => h'.trans h.symm⟩
|
||||
|
||||
-- congruence lemmas
|
||||
|
||||
theorem isEmpty_eq (h : t₁ ~m t₂) : t₁.isEmpty = t₂.isEmpty :=
|
||||
h.1.isEmpty_eq
|
||||
|
||||
theorem contains_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.contains k = t₂.contains k :=
|
||||
h.1.contains_eq h₁.1 h₂.1
|
||||
|
||||
theorem mem_iff [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
k ∈ t₁ ↔ k ∈ t₂ :=
|
||||
h.1.mem_iff h₁.1 h₂.1
|
||||
|
||||
theorem size_eq (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.size = t₂.size :=
|
||||
h.1.size_eq h₁.1 h₂.1
|
||||
|
||||
theorem get?_eq [TransCmp cmp] [LawfulEqCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.get? k = t₂.get? k :=
|
||||
h.1.get?_eq h₁.1 h₂.1
|
||||
|
||||
theorem get_eq [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {hk : k ∈ t₁} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.get k hk = t₂.get k ((h.mem_iff h₁ h₂).mp hk) :=
|
||||
h.1.get_eq h₁.1 h₂.1 hk
|
||||
|
||||
theorem get!_eq [TransCmp cmp] [LawfulEqCmp cmp] {k : α} [Inhabited (β k)] (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.get! k = t₂.get! k :=
|
||||
h.1.get!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getD_eq [TransCmp cmp] [LawfulEqCmp cmp] {k : α} {fallback : β k} (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.getD k fallback = t₂.getD k fallback :=
|
||||
h.1.getD_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKey?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKey? k = t₂.getKey? k :=
|
||||
h.1.getKey?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKey_eq [TransCmp cmp] {k : α} {hk : k ∈ t₁} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKey k hk = t₂.getKey k ((h.mem_iff h₁ h₂).mp hk) :=
|
||||
h.1.getKey_eq h₁.1 h₂.1 hk
|
||||
|
||||
theorem getKey!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKey! k = t₂.getKey! k :=
|
||||
h.1.getKey!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyD_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyD k fallback = t₂.getKeyD k fallback :=
|
||||
h.1.getKeyD_eq h₁.1 h₂.1
|
||||
|
||||
theorem toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.toList = t₂.toList :=
|
||||
h.1.toList_eq h₁.1 h₂.1
|
||||
|
||||
theorem toArray_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.toArray = t₂.toArray :=
|
||||
h.1.toArray_eq h₁.1 h₂.1
|
||||
|
||||
theorem keys_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.keys = t₂.keys :=
|
||||
h.1.keys_eq h₁.1 h₂.1
|
||||
|
||||
theorem keysArray_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.keysArray = t₂.keysArray :=
|
||||
h.1.keysArray_eq h₁.1 h₂.1
|
||||
|
||||
theorem foldlM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : δ → (a : α) → β a → m δ}
|
||||
{init : δ} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.foldlM f init = t₂.foldlM f init :=
|
||||
h.1.foldlM_eq h₁.1 h₂.1
|
||||
|
||||
theorem foldl_eq [TransCmp cmp] {f : δ → (a : α) → β a → δ} {init : δ} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) :
|
||||
t₁.foldl f init = t₂.foldl f init :=
|
||||
h.1.foldl_eq h₁.1 h₂.1
|
||||
|
||||
theorem foldrM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : (a : α) → β a → δ → m δ}
|
||||
{init : δ} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.foldrM f init = t₂.foldrM f init :=
|
||||
h.1.foldrM_eq h₁.1 h₂.1
|
||||
|
||||
theorem foldr_eq [TransCmp cmp] {f : (a : α) → β a → δ → δ} {init : δ} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) :
|
||||
t₁.foldr f init = t₂.foldr f init :=
|
||||
h.1.foldr_eq h₁.1 h₂.1
|
||||
|
||||
theorem forIn_eq [TransCmp cmp] [Monad m] [LawfulMonad m]
|
||||
{b : δ} {f : (a : α) × β a → δ → m (ForInStep δ)} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
ForIn.forIn t₁ b f = ForIn.forIn t₂ b f :=
|
||||
h.1.forIn_eq h₁.1 h₂.1
|
||||
|
||||
theorem forM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : (a : α) × β a → m PUnit}
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
ForM.forM t₁ f = ForM.forM t₂ f :=
|
||||
h.1.forM_eq h₁.1 h₂.1
|
||||
|
||||
theorem any_eq [TransCmp cmp] {p : (a : α) → β a → Bool} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.any p = t₂.any p := by
|
||||
simp only [any, h.forIn_eq h₁ h₂]
|
||||
|
||||
theorem all_eq [TransCmp cmp] {p : (a : α) → β a → Bool} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.all p = t₂.all p := by
|
||||
simp only [all, h.forIn_eq h₁ h₂]
|
||||
|
||||
theorem minKey?_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.minKey? = t₂.minKey? :=
|
||||
h.1.minKey?_eq h₁.1 h₂.1
|
||||
|
||||
theorem minKey!_eq [TransCmp cmp] [Inhabited α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.minKey! = t₂.minKey! :=
|
||||
h.1.minKey!_eq h₁.1 h₂.1
|
||||
|
||||
theorem minKeyD_eq [TransCmp cmp] {fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.minKeyD fallback = t₂.minKeyD fallback :=
|
||||
h.1.minKeyD_eq h₁.1 h₂.1
|
||||
|
||||
theorem maxKey?_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.maxKey? = t₂.maxKey? :=
|
||||
h.1.maxKey?_eq h₁.1 h₂.1
|
||||
|
||||
theorem maxKey!_eq [TransCmp cmp] [Inhabited α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.maxKey! = t₂.maxKey! :=
|
||||
h.1.maxKey!_eq h₁.1 h₂.1
|
||||
|
||||
theorem maxKeyD_eq [TransCmp cmp] {fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.maxKeyD fallback = t₂.maxKeyD fallback :=
|
||||
h.1.maxKeyD_eq h₁.1 h₂.1
|
||||
|
||||
theorem minEntry?_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.minEntry? = t₂.minEntry? :=
|
||||
h.1.minEntry?_eq h₁.1 h₂.1
|
||||
|
||||
theorem minEntry!_eq [TransCmp cmp] [Inhabited ((a : α) × β a)] (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.minEntry! = t₂.minEntry! :=
|
||||
h.1.minEntry!_eq h₁.1 h₂.1
|
||||
|
||||
theorem minEntryD_eq [TransCmp cmp] {fallback : (a : α) × β a} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.minEntryD fallback = t₂.minEntryD fallback :=
|
||||
h.1.minEntryD_eq h₁.1 h₂.1
|
||||
|
||||
theorem maxEntry?_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.maxEntry? = t₂.maxEntry? :=
|
||||
h.1.maxEntry?_eq h₁.1 h₂.1
|
||||
|
||||
theorem maxEntry!_eq [TransCmp cmp] [Inhabited ((a : α) × β a)] (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.maxEntry! = t₂.maxEntry! :=
|
||||
h.1.maxEntry!_eq h₁.1 h₂.1
|
||||
|
||||
theorem maxEntryD_eq [TransCmp cmp] {fallback : (a : α) × β a} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.maxEntryD fallback = t₂.maxEntryD fallback :=
|
||||
h.1.maxEntryD_eq h₁.1 h₂.1
|
||||
|
||||
theorem entryAtIdx?_eq [TransCmp cmp] {i : Nat} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.entryAtIdx? i = t₂.entryAtIdx? i :=
|
||||
h.1.entryAtIdx?_eq h₁.1 h₂.1
|
||||
|
||||
theorem entryAtIdx!_eq [TransCmp cmp] [Inhabited ((a : α) × β a)] {i : Nat} (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.entryAtIdx! i = t₂.entryAtIdx! i :=
|
||||
h.1.entryAtIdx!_eq h₁.1 h₂.1
|
||||
|
||||
theorem entryAtIdxD_eq [TransCmp cmp] {i : Nat} {fallback : (a : α) × β a} (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.entryAtIdxD i fallback = t₂.entryAtIdxD i fallback :=
|
||||
h.1.entryAtIdxD_eq h₁.1 h₂.1
|
||||
|
||||
theorem keyAtIdx?_eq [TransCmp cmp] {i : Nat} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.keyAtIdx? i = t₂.keyAtIdx? i :=
|
||||
h.1.keyAtIdx?_eq h₁.1 h₂.1
|
||||
|
||||
theorem keyAtIdx!_eq [TransCmp cmp] [Inhabited α] {i : Nat} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.keyAtIdx! i = t₂.keyAtIdx! i :=
|
||||
h.1.keyAtIdx!_eq h₁.1 h₂.1
|
||||
|
||||
theorem keyAtIdxD_eq [TransCmp cmp] {i : Nat} {fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.keyAtIdxD i fallback = t₂.keyAtIdxD i fallback :=
|
||||
h.1.keyAtIdxD_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryGE?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGE? k = t₂.getEntryGE? k :=
|
||||
h.1.getEntryGE?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryGE!_eq [TransCmp cmp] [Inhabited ((a : α) × β a)] {k : α} (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.getEntryGE! k = t₂.getEntryGE! k :=
|
||||
h.1.getEntryGE!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryGED_eq [TransCmp cmp] {k : α} {fallback : (a : α) × β a} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.getEntryGED k fallback = t₂.getEntryGED k fallback :=
|
||||
h.1.getEntryGED_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryGT?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGT? k = t₂.getEntryGT? k :=
|
||||
h.1.getEntryGT?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryGT!_eq [TransCmp cmp] [Inhabited ((a : α) × β a)] {k : α} (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.getEntryGT! k = t₂.getEntryGT! k :=
|
||||
h.1.getEntryGT!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryGTD_eq [TransCmp cmp] {k : α} {fallback : (a : α) × β a} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.getEntryGTD k fallback = t₂.getEntryGTD k fallback :=
|
||||
h.1.getEntryGTD_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryLE?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLE? k = t₂.getEntryLE? k :=
|
||||
h.1.getEntryLE?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryLE!_eq [TransCmp cmp] [Inhabited ((a : α) × β a)] {k : α} (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.getEntryLE! k = t₂.getEntryLE! k :=
|
||||
h.1.getEntryLE!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryLED_eq [TransCmp cmp] {k : α} {fallback : (a : α) × β a} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.getEntryLED k fallback = t₂.getEntryLED k fallback :=
|
||||
h.1.getEntryLED_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryLT?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLT? k = t₂.getEntryLT? k :=
|
||||
h.1.getEntryLT?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryLT!_eq [TransCmp cmp] [Inhabited ((a : α) × β a)] {k : α} (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.getEntryLT! k = t₂.getEntryLT! k :=
|
||||
h.1.getEntryLT!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryLTD_eq [TransCmp cmp] {k : α} {fallback : (a : α) × β a} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.getEntryLTD k fallback = t₂.getEntryLTD k fallback :=
|
||||
h.1.getEntryLTD_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyGE?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGE? k = t₂.getKeyGE? k :=
|
||||
h.1.getKeyGE?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyGE!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGE! k = t₂.getKeyGE! k :=
|
||||
h.1.getKeyGE!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyGED_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGED k fallback = t₂.getKeyGED k fallback :=
|
||||
h.1.getKeyGED_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyGT?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGT? k = t₂.getKeyGT? k :=
|
||||
h.1.getKeyGT?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyGT!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGT! k = t₂.getKeyGT! k :=
|
||||
h.1.getKeyGT!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyGTD_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGTD k fallback = t₂.getKeyGTD k fallback :=
|
||||
h.1.getKeyGTD_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyLE?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLE? k = t₂.getKeyLE? k :=
|
||||
h.1.getKeyLE?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyLE!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLE! k = t₂.getKeyLE! k :=
|
||||
h.1.getKeyLE!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyLED_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLED k fallback = t₂.getKeyLED k fallback :=
|
||||
h.1.getKeyLED_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyLT?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLT? k = t₂.getKeyLT? k :=
|
||||
h.1.getKeyLT?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyLT!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLT! k = t₂.getKeyLT! k :=
|
||||
h.1.getKeyLT!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyLTD_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLTD k fallback = t₂.getKeyLTD k fallback :=
|
||||
h.1.getKeyLTD_eq h₁.1 h₂.1
|
||||
|
||||
theorem insert [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(k : α) (v : β k) : t₁.insert k v ~m t₂.insert k v :=
|
||||
⟨h.1.insert! h₁.1 h₂.1⟩
|
||||
|
||||
theorem erase [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(k : α) : t₁.erase k ~m t₂.erase k :=
|
||||
⟨h.1.erase! h₁.1 h₂.1⟩
|
||||
|
||||
theorem insertIfNew [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(k : α) (v : β k) : t₁.insertIfNew k v ~m t₂.insertIfNew k v :=
|
||||
⟨h.1.insertIfNew! h₁.1 h₂.1⟩
|
||||
|
||||
theorem alter [TransCmp cmp] [LawfulEqCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(k : α) (f : Option (β k) → Option (β k)) :
|
||||
t₁.alter k f ~m t₂.alter k f :=
|
||||
⟨h.1.alter! h₁.1 h₂.1⟩
|
||||
|
||||
theorem modify [TransCmp cmp] [LawfulEqCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(k : α) (f : β k → β k) : t₁.modify k f ~m t₂.modify k f :=
|
||||
⟨h.1.modify h₁.1 h₂.1⟩
|
||||
|
||||
theorem filter (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (f : (a : α) → β a → Bool) :
|
||||
t₁.filter f ~m t₂.filter f :=
|
||||
⟨h.1.filter! h₁.1 h₂.1⟩
|
||||
|
||||
theorem map (h : t₁ ~m t₂) (f : (a : α) → β a → γ a) :
|
||||
t₁.map f ~m t₂.map f :=
|
||||
⟨h.1.map⟩
|
||||
|
||||
theorem filterMap (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (f : (a : α) → β a → Option (γ a)) :
|
||||
t₁.filterMap f ~m t₂.filterMap f :=
|
||||
⟨h.1.filterMap! h₁.1 h₂.1⟩
|
||||
|
||||
theorem insertMany_list [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(l : List ((a : α) × β a)) : t₁.insertMany l ~m t₂.insertMany l :=
|
||||
⟨h.1.insertMany!_list h₁.1 h₂.1⟩
|
||||
|
||||
theorem eraseMany_list [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (l : List α) :
|
||||
t₁.eraseMany l ~m t₂.eraseMany l :=
|
||||
⟨h.1.eraseMany!_list h₁.1 h₂.1⟩
|
||||
|
||||
theorem mergeWith [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h₃ : t₃.WF) (h₄ : t₄.WF)
|
||||
(f : (a : α) → β a → β a → β a)
|
||||
(h : t₁ ~m t₂) (h' : t₃ ~m t₄) :
|
||||
t₁.mergeWith f t₃ ~m t₂.mergeWith f t₄ :=
|
||||
⟨h.1.mergeWith! h'.1 h₁.1 h₂.1 h₃.1 h₄.1⟩
|
||||
|
||||
section Const
|
||||
|
||||
variable {β : Type v} {t₁ t₂ t₃ t₄ : Raw α β cmp} (δ : Type w) (m : Type w → Type w)
|
||||
|
||||
theorem constGet?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.get? t₁ k = Const.get? t₂ k :=
|
||||
h.1.constGet?_eq h₁.1 h₂.1
|
||||
|
||||
theorem constGet_eq [TransCmp cmp] {k : α} {hk : k ∈ t₁} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.get t₁ k hk = Const.get t₂ k ((h.mem_iff h₁ h₂).mp hk) :=
|
||||
h.1.constGet_eq h₁.1 h₂.1 hk
|
||||
|
||||
theorem constGet!_eq [TransCmp cmp] [Inhabited β] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.get! t₁ k = Const.get! t₂ k :=
|
||||
h.1.constGet!_eq h₁.1 h₂.1
|
||||
|
||||
theorem constGetD_eq [TransCmp cmp] {k : α} {fallback : β} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.getD t₁ k fallback = Const.getD t₂ k fallback :=
|
||||
h.1.constGetD_eq h₁.1 h₂.1
|
||||
|
||||
theorem constToList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.toList t₁ = Const.toList t₂ :=
|
||||
h.1.constToList_eq h₁.1 h₂.1
|
||||
|
||||
theorem constToArray_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.toArray t₁ = Const.toArray t₂ :=
|
||||
h.1.constToArray_eq h₁.1 h₂.1
|
||||
|
||||
theorem values_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.values = t₂.values :=
|
||||
h.1.values_eq h₁.1 h₂.1
|
||||
|
||||
theorem valuesArray_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.valuesArray = t₂.valuesArray :=
|
||||
h.1.valuesArray_eq h₁.1 h₂.1
|
||||
|
||||
theorem constMinEntry?_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.minEntry? t₁ = Const.minEntry? t₂ :=
|
||||
h.1.constMinEntry?_eq h₁.1 h₂.1
|
||||
|
||||
theorem constMinEntry!_eq [TransCmp cmp] [Inhabited (α × β)] (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.minEntry! t₁ = Const.minEntry! t₂ :=
|
||||
h.1.constMinEntry!_eq h₁.1 h₂.1
|
||||
|
||||
theorem constMinEntryD_eq [TransCmp cmp] {fallback : α × β} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.minEntryD t₁ fallback = Const.minEntryD t₂ fallback :=
|
||||
h.1.constMinEntryD_eq h₁.1 h₂.1
|
||||
|
||||
theorem constMaxEntry?_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.maxEntry? t₁ = Const.maxEntry? t₂ :=
|
||||
h.1.constMaxEntry?_eq h₁.1 h₂.1
|
||||
|
||||
theorem constMaxEntry!_eq [TransCmp cmp] [Inhabited (α × β)] (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.maxEntry! t₁ = Const.maxEntry! t₂ :=
|
||||
h.1.constMaxEntry!_eq h₁.1 h₂.1
|
||||
|
||||
theorem constMaxEntryD_eq [TransCmp cmp] {fallback : α × β} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.maxEntryD t₁ fallback = Const.maxEntryD t₂ fallback :=
|
||||
h.1.constMaxEntryD_eq h₁.1 h₂.1
|
||||
|
||||
theorem constEntryAtIdx?_eq [TransCmp cmp] {i : Nat} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.entryAtIdx? t₁ i = Const.entryAtIdx? t₂ i :=
|
||||
h.1.constEntryAtIdx?_eq h₁.1 h₂.1
|
||||
|
||||
theorem constEntryAtIdx!_eq [TransCmp cmp] [Inhabited (α × β)] {i : Nat} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.entryAtIdx! t₁ i = Const.entryAtIdx! t₂ i :=
|
||||
h.1.constEntryAtIdx!_eq h₁.1 h₂.1
|
||||
|
||||
theorem constEntryAtIdxD_eq [TransCmp cmp] {i : Nat} {fallback : α × β} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.entryAtIdxD t₁ i fallback = Const.entryAtIdxD t₂ i fallback :=
|
||||
h.1.constEntryAtIdxD_eq h₁.1 h₂.1
|
||||
|
||||
theorem constGetEntryGE?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.getEntryGE? t₁ k = Const.getEntryGE? t₂ k :=
|
||||
h.1.constGetEntryGE?_eq h₁.1 h₂.1
|
||||
|
||||
theorem constGetEntryGE!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.getEntryGE! t₁ k = Const.getEntryGE! t₂ k :=
|
||||
h.1.constGetEntryGE!_eq h₁.1 h₂.1
|
||||
|
||||
theorem constGetEntryGED_eq [TransCmp cmp] {k : α} {fallback : α × β} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.getEntryGED t₁ k fallback = Const.getEntryGED t₂ k fallback :=
|
||||
h.1.constGetEntryGED_eq h₁.1 h₂.1
|
||||
|
||||
theorem constGetEntryGT?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.getEntryGT? t₁ k = Const.getEntryGT? t₂ k :=
|
||||
h.1.constGetEntryGT?_eq h₁.1 h₂.1
|
||||
|
||||
theorem constGetEntryGT!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.getEntryGT! t₁ k = Const.getEntryGT! t₂ k :=
|
||||
h.1.constGetEntryGT!_eq h₁.1 h₂.1
|
||||
|
||||
theorem constGetEntryGTD_eq [TransCmp cmp] {k : α} {fallback : α × β} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.getEntryGTD t₁ k fallback = Const.getEntryGTD t₂ k fallback :=
|
||||
h.1.constGetEntryGTD_eq h₁.1 h₂.1
|
||||
|
||||
theorem constGetEntryLE?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.getEntryLE? t₁ k = Const.getEntryLE? t₂ k :=
|
||||
h.1.constGetEntryLE?_eq h₁.1 h₂.1
|
||||
|
||||
theorem constGetEntryLE!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.getEntryLE! t₁ k = Const.getEntryLE! t₂ k :=
|
||||
h.1.constGetEntryLE!_eq h₁.1 h₂.1
|
||||
|
||||
theorem constGetEntryLED_eq [TransCmp cmp] {k : α} {fallback : α × β} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.getEntryLED t₁ k fallback = Const.getEntryLED t₂ k fallback :=
|
||||
h.1.constGetEntryLED_eq h₁.1 h₂.1
|
||||
|
||||
theorem constGetEntryLT?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
Const.getEntryLT? t₁ k = Const.getEntryLT? t₂ k :=
|
||||
h.1.constGetEntryLT?_eq h₁.1 h₂.1
|
||||
|
||||
theorem constGetEntryLT!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.getEntryLT! t₁ k = Const.getEntryLT! t₂ k :=
|
||||
h.1.constGetEntryLT!_eq h₁.1 h₂.1
|
||||
|
||||
theorem constGetEntryLTD_eq [TransCmp cmp] {k : α} {fallback : α × β} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : Const.getEntryLTD t₁ k fallback = Const.getEntryLTD t₂ k fallback :=
|
||||
h.1.constGetEntryLTD_eq h₁.1 h₂.1
|
||||
|
||||
theorem constAlter [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(k : α) (f : Option β → Option β) :
|
||||
Const.alter t₁ k f ~m Const.alter t₂ k f :=
|
||||
⟨h.1.constAlter! h₁.1 h₂.1⟩
|
||||
|
||||
theorem constModify [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(k : α) (f : β → β) : Const.modify t₁ k f ~m Const.modify t₂ k f :=
|
||||
⟨h.1.constModify h₁.1 h₂.1⟩
|
||||
|
||||
theorem constInsertMany_list [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(l : List (α × β)) : Const.insertMany t₁ l ~m Const.insertMany t₂ l :=
|
||||
⟨h.1.constInsertMany!_list h₁.1 h₂.1⟩
|
||||
|
||||
theorem constInsertManyIfNewUnit_list [TransCmp cmp] {t₁ t₂ : Raw α Unit cmp}
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (l : List α) :
|
||||
Const.insertManyIfNewUnit t₁ l ~m Const.insertManyIfNewUnit t₂ l :=
|
||||
⟨h.1.constInsertManyIfNewUnit!_list h₁.1 h₂.1⟩
|
||||
|
||||
theorem constMergeWith [TransCmp cmp]
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h₃ : t₃.WF) (h₄ : t₄.WF)
|
||||
(f : α → β → β → β)
|
||||
(h : t₁ ~m t₂) (h' : t₃ ~m t₄) :
|
||||
Const.mergeWith f t₁ t₃ ~m Const.mergeWith f t₂ t₄ :=
|
||||
⟨h.1.constMergeWith! h'.1 h₁.1 h₂.1 h₃.1 h₄.1⟩
|
||||
|
||||
end Const
|
||||
|
||||
-- extensionalities
|
||||
|
||||
theorem of_forall_get?_eq [TransCmp cmp] [LawfulEqCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : ∀ k, t₁.get? k = t₂.get? k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_get?_eq h₁.1 h₂.1 h⟩
|
||||
|
||||
section Const
|
||||
|
||||
variable {β : Type v} {t₁ t₂ : Raw α β cmp}
|
||||
|
||||
theorem of_forall_getKey_eq_of_forall_constGet?_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(hk : ∀ k hk hk', t₁.getKey k hk = t₂.getKey k hk')
|
||||
(hv : ∀ k, Const.get? t₁ k = Const.get? t₂ k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_getKey_eq_of_forall_constGet?_eq h₁.1 h₂.1 hk hv⟩
|
||||
|
||||
theorem of_forall_constGet?_eq [TransCmp cmp] [LawfulEqCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : ∀ k, Const.get? t₁ k = Const.get? t₂ k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_constGet?_eq h₁.1 h₂.1 h⟩
|
||||
|
||||
theorem of_forall_getKey?_unit_eq [TransCmp cmp] {t₁ t₂ : Raw α Unit cmp}
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) (h : ∀ k, t₁.getKey? k = t₂.getKey? k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_getKey?_unit_eq h₁.1 h₂.1 h⟩
|
||||
|
||||
theorem of_forall_contains_unit_eq [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
{t₁ t₂ : Raw α Unit cmp} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : ∀ k, t₁.contains k = t₂.contains k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_contains_unit_eq h₁.1 h₂.1 h⟩
|
||||
|
||||
theorem of_forall_mem_unit_iff [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
{t₁ t₂ : Raw α Unit cmp} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : ∀ k, k ∈ t₁ ↔ k ∈ t₂) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_mem_unit_iff h₁.1 h₂.1 h⟩
|
||||
|
||||
end Const
|
||||
|
||||
end Equiv
|
||||
|
||||
section Equiv
|
||||
|
||||
variable {t₁ t₂ : Raw α β cmp}
|
||||
|
||||
private theorem equiv_iff : t₁ ~m t₂ ↔ t₁.1.Equiv t₂.1 :=
|
||||
⟨fun ⟨h⟩ => h, fun h => ⟨h⟩⟩
|
||||
|
||||
theorem equiv_empty_iff_isEmpty : t ~m empty ↔ t.isEmpty :=
|
||||
equiv_iff.trans Impl.equiv_empty_iff_isEmpty
|
||||
|
||||
theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
|
||||
equiv_iff.trans Impl.empty_equiv_iff_isEmpty
|
||||
|
||||
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList :=
|
||||
equiv_iff.trans Impl.equiv_iff_toList_perm
|
||||
|
||||
theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ :=
|
||||
⟨.of_toList_perm h⟩
|
||||
|
||||
theorem equiv_iff_toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
|
||||
t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
|
||||
equiv_iff.trans (Impl.equiv_iff_toList_eq h₁.1 h₂.1)
|
||||
|
||||
section Const
|
||||
|
||||
variable {β : Type v} {t₁ t₂ : Raw α β cmp}
|
||||
|
||||
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
|
||||
|
||||
theorem Const.equiv_iff_toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
|
||||
t₁ ~m t₂ ↔ Const.toList t₁ = Const.toList t₂ :=
|
||||
equiv_iff.trans (Impl.Const.equiv_iff_toList_eq h₁.1 h₂.1)
|
||||
|
||||
theorem Const.equiv_iff_keys_unit_perm {t₁ t₂ : Raw α Unit cmp} :
|
||||
t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys :=
|
||||
equiv_iff.trans Impl.Const.equiv_iff_keys_perm
|
||||
|
||||
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 :=
|
||||
equiv_iff.trans (Impl.Const.equiv_iff_keys_eq h₁.1 h₂.1)
|
||||
|
||||
theorem Equiv.of_constToList_perm : (Const.toList t₁).Perm (Const.toList t₂) → t₁ ~m t₂ :=
|
||||
Const.equiv_iff_toList_perm.mpr
|
||||
|
||||
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
|
||||
|
||||
end Const
|
||||
|
||||
end Equiv
|
||||
|
||||
end Std.DTreeMap.Raw
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Markus Himmel
|
||||
-/
|
||||
prelude
|
||||
import Init.Data.Ord
|
||||
import Std.Classes.Ord.Basic
|
||||
|
||||
set_option autoImplicit false
|
||||
|
||||
|
|
@ -35,4 +35,24 @@ theorem IsStrictCut.lt_of_isLE_of_lt [IsStrictCut cmp cut] {k k' : α} :
|
|||
| lt => exact fun _ => IsCut.lt h₁
|
||||
| eq => exact fun h₂ h₃ => by rw [← h₃, IsStrictCut.eq (cmp := cmp) k h₁]
|
||||
|
||||
instance [Ord α] [TransOrd α] {k : α} : IsStrictCut compare (compare k) where
|
||||
lt := TransCmp.lt_trans
|
||||
gt h₁ h₂ := OrientedCmp.gt_of_lt (TransCmp.lt_trans (OrientedCmp.lt_of_gt h₂)
|
||||
(OrientedCmp.lt_of_gt h₁))
|
||||
eq _ _ := TransCmp.congr_left
|
||||
|
||||
instance [Ord α] : IsStrictCut (compare : α → α → Ordering) (fun _ => .lt) where
|
||||
lt := by simp
|
||||
gt := by simp
|
||||
eq := by simp
|
||||
|
||||
instance [Ord α] [TransOrd α] {k : α} : IsStrictCut compare fun k' => (compare k k').then .gt where
|
||||
lt {_ _} := by simpa [Ordering.then_eq_lt] using TransCmp.lt_trans
|
||||
eq {_ _} := by simp [Ordering.then_eq_eq]
|
||||
gt h h' := by
|
||||
simp only [Ordering.then_eq_gt, and_true] at h ⊢
|
||||
rcases h with (h | h)
|
||||
· exact .inl (TransCmp.gt_trans h h')
|
||||
· exact .inl (TransCmp.gt_of_eq_of_gt h h')
|
||||
|
||||
end Std.Internal
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ set_option linter.missingDocs true
|
|||
set_option autoImplicit false
|
||||
set_option Elab.async false
|
||||
|
||||
universe u v w
|
||||
universe u v w w'
|
||||
|
||||
variable {α : Type u} {β : α → Type v} {γ : α → Type w}
|
||||
|
||||
|
|
@ -2529,7 +2529,7 @@ theorem pairwise_fst_eq_false_map_toProd [BEq α] {β : Type v}
|
|||
simp [List.pairwise_map]
|
||||
assumption
|
||||
|
||||
theorem foldlM_eq_foldlM_toProd {β : Type v} {δ : Type w} {m' : Type w → Type w} [Monad m']
|
||||
theorem foldlM_eq_foldlM_toProd {β : Type v} {δ : Type w} {m' : Type w → Type w'} [Monad m']
|
||||
[LawfulMonad m'] {l : List ((_ : α) × β)} {f : δ → (a : α) → β → m' δ} {init : δ} :
|
||||
l.foldlM (fun a b => f a b.fst b.snd) init =
|
||||
(l.map fun x => (x.1, x.2)).foldlM (fun a b => f a b.fst b.snd) init := by
|
||||
|
|
@ -2545,7 +2545,7 @@ theorem foldl_eq_foldl_toProd {β : Type v} {δ : Type w}
|
|||
| nil => simp
|
||||
| cons hd tl ih => simp [ih]
|
||||
|
||||
theorem foldrM_eq_foldrM_toProd {β : Type v} {δ : Type w} {m' : Type w → Type w} [Monad m']
|
||||
theorem foldrM_eq_foldrM_toProd {β : Type v} {δ : Type w} {m' : Type w → Type w'} [Monad m']
|
||||
[LawfulMonad m'] {l : List ((_ : α) × β)} {f : (a : α) → β → δ → m' δ} {init : δ} :
|
||||
l.foldrM (fun a b => f a.1 a.2 b) init =
|
||||
(l.map fun x => (x.1, x.2)).foldrM (fun a b => f a.1 a.2 b) init := by
|
||||
|
|
@ -2553,7 +2553,7 @@ theorem foldrM_eq_foldrM_toProd {β : Type v} {δ : Type w} {m' : Type w → Typ
|
|||
| nil => simp
|
||||
| cons hd tl ih => simp [ih]
|
||||
|
||||
theorem foldrM_eq_foldrM_toProd' {β : Type v} {δ : Type w} {m' : Type w → Type w} [Monad m']
|
||||
theorem foldrM_eq_foldrM_toProd' {β : Type v} {δ : Type w} {m' : Type w → Type w'} [Monad m']
|
||||
[LawfulMonad m'] {l : List ((_ : α) × β)} {f : δ → (a : α) → β → m' δ} {init : δ} :
|
||||
l.foldrM (fun a b => f b a.1 a.2) init =
|
||||
(l.map fun x => (x.1, x.2)).foldrM (fun a b => f b a.1 a.2) init := by
|
||||
|
|
@ -2577,14 +2577,14 @@ theorem foldr_eq_foldr_toProd' {β : Type v} {δ : Type w}
|
|||
| nil => simp
|
||||
| cons hd tl ih => simp [ih]
|
||||
|
||||
theorem forM_eq_forM_toProd {β : Type v} {m' : Type w → Type w} [Monad m']
|
||||
theorem forM_eq_forM_toProd {β : Type v} {m' : Type w → Type w'} [Monad m']
|
||||
[LawfulMonad m'] {l : List ((_ : α) × β)} {f : (a : α) → β → m' PUnit} :
|
||||
forM l (fun a => f a.1 a.2) = forM (l.map (fun x => (x.1, x.2))) fun a => f a.1 a.2 := by
|
||||
cases l with
|
||||
| nil => simp
|
||||
| cons hd tl => simp
|
||||
|
||||
theorem forIn_eq_forIn_toProd {β : Type v} {δ : Type w} {m' : Type w → Type w} [Monad m']
|
||||
theorem forIn_eq_forIn_toProd {β : Type v} {δ : Type w} {m' : Type w → Type w'} [Monad m']
|
||||
[LawfulMonad m'] {l : List ((_ : α) × β)} {f : (a : α) → β → δ → m' (ForInStep δ)} {init : δ} :
|
||||
ForIn.forIn l init (fun a d => f a.1 a.2 d) =
|
||||
ForIn.forIn (l.map (fun x => (x.1, x.2))) init fun a d => f a.1 a.2 d := by
|
||||
|
|
@ -2592,7 +2592,7 @@ theorem forIn_eq_forIn_toProd {β : Type v} {δ : Type w} {m' : Type w → Type
|
|||
| nil => simp
|
||||
| cons hd tl => simp
|
||||
|
||||
theorem foldlM_eq_foldlM_keys {δ : Type w} {m' : Type w → Type w} [Monad m'] [LawfulMonad m']
|
||||
theorem foldlM_eq_foldlM_keys {δ : Type w} {m' : Type w → Type w'} [Monad m'] [LawfulMonad m']
|
||||
{l : List ((a : α) × β a)} {f : δ → α → m' δ} {init : δ} :
|
||||
l.foldlM (fun a b => f a b.1) init = (keys l).foldlM f init := by
|
||||
induction l generalizing init with
|
||||
|
|
@ -2609,7 +2609,7 @@ theorem foldl_eq_foldl_keys {δ : Type w}
|
|||
| nil => simp
|
||||
| cons hd tl ih => simp [List.foldlM_cons, keys, ih]
|
||||
|
||||
theorem foldrM_eq_foldrM_keys {δ : Type w} {m' : Type w → Type w} [Monad m'] [LawfulMonad m']
|
||||
theorem foldrM_eq_foldrM_keys {δ : Type w} {m' : Type w → Type w'} [Monad m'] [LawfulMonad m']
|
||||
{l : List ((a : α) × β a)} {f : α → δ → m' δ} {init : δ} :
|
||||
l.foldrM (fun a b => f a.1 b) init = (keys l).foldrM f init := by
|
||||
induction l generalizing init with
|
||||
|
|
@ -2617,7 +2617,7 @@ theorem foldrM_eq_foldrM_keys {δ : Type w} {m' : Type w → Type w} [Monad m']
|
|||
| cons hd tl ih =>
|
||||
simp [keys, ih]
|
||||
|
||||
theorem foldrM_eq_foldrM_keys' {δ : Type w} {m' : Type w → Type w} [Monad m'] [LawfulMonad m']
|
||||
theorem foldrM_eq_foldrM_keys' {δ : Type w} {m' : Type w → Type w'} [Monad m'] [LawfulMonad m']
|
||||
{l : List ((a : α) × β a)} {f : δ → α → m' δ} {init : δ} :
|
||||
l.foldrM (fun a b => f b a.1) init = (keys l).foldrM (fun a b => f b a) init := by
|
||||
induction l generalizing init with
|
||||
|
|
@ -2639,7 +2639,7 @@ theorem foldr_eq_foldr_keys' {δ : Type w}
|
|||
| nil => simp
|
||||
| cons hd tl ih => simp [keys, ih]
|
||||
|
||||
theorem forM_eq_forM_keys {m' : Type w → Type w} [Monad m'] [LawfulMonad m']
|
||||
theorem forM_eq_forM_keys {m' : Type w → Type w'} [Monad m'] [LawfulMonad m']
|
||||
{l : List ((a : α) × β a)} {f : α → m' PUnit} :
|
||||
l.forM (fun a => f a.1) = (keys l).forM f := by
|
||||
induction l with
|
||||
|
|
@ -2650,7 +2650,7 @@ theorem forM_eq_forM_keys {m' : Type w → Type w} [Monad m'] [LawfulMonad m']
|
|||
funext x
|
||||
apply ih
|
||||
|
||||
theorem forIn_eq_forIn_keys {δ : Type w} {m' : Type w → Type w} [Monad m'] [LawfulMonad m']
|
||||
theorem forIn_eq_forIn_keys {δ : Type w} {m' : Type w → Type w'} [Monad m'] [LawfulMonad m']
|
||||
{f : α → δ → m' (ForInStep δ)} {init : δ} {l : List ((a : α) × β a)} :
|
||||
ForIn.forIn l init (fun a d => f a.fst d) = ForIn.forIn (keys l) init f := by
|
||||
induction l generalizing init with
|
||||
|
|
|
|||
|
|
@ -71,6 +71,13 @@ instance : EmptyCollection (TreeMap α β cmp) where
|
|||
|
||||
instance : Inhabited (TreeMap α β cmp) := ⟨∅⟩
|
||||
|
||||
@[inherit_doc DTreeMap.Equiv]
|
||||
structure Equiv (m₁ m₂ : TreeMap α β cmp) where
|
||||
/-- Internal implementation detail of the tree map -/
|
||||
inner : m₁.1.Equiv m₂.1
|
||||
|
||||
@[inherit_doc] scoped infix:50 " ~m " => Equiv
|
||||
|
||||
@[simp]
|
||||
theorem empty_eq_emptyc : (empty : TreeMap α β cmp) = ∅ :=
|
||||
rfl
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ Authors: Markus Himmel, Paul Reichert
|
|||
prelude
|
||||
import Std.Data.DTreeMap.Lemmas
|
||||
import Std.Data.TreeMap.Basic
|
||||
import Std.Data.TreeMap.AdditionalOperations
|
||||
|
||||
/-!
|
||||
# Tree map lemmas
|
||||
|
|
@ -17,11 +18,11 @@ This file contains lemmas about `Std.Data.TreeMap`. Most of the lemmas require
|
|||
set_option linter.missingDocs true
|
||||
set_option autoImplicit false
|
||||
|
||||
universe u v w
|
||||
universe u v w w'
|
||||
|
||||
namespace Std.TreeMap
|
||||
|
||||
variable {α : Type u} {β : Type v} {cmp : α → α → Ordering} {t : TreeMap α β cmp}
|
||||
variable {α : Type u} {β : Type v} {γ : Type w} {cmp : α → α → Ordering} {t : TreeMap α β cmp}
|
||||
|
||||
private theorem ext {t t' : TreeMap α β cmp} : t.inner = t'.inner → t = t' := by
|
||||
cases t; cases t'; rintro rfl; rfl
|
||||
|
|
@ -849,7 +850,7 @@ theorem ordered_keys_toList [TransCmp cmp] :
|
|||
|
||||
section monadic
|
||||
|
||||
variable {δ : Type w} {m : Type w → Type w}
|
||||
variable {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m] {f : δ → α → β → m δ} {init : δ} :
|
||||
t.foldlM f init = t.toList.foldlM (fun a b => f a b.1 b.2) init :=
|
||||
|
|
@ -1176,7 +1177,7 @@ theorem getKey!_insertManyIfNewUnit_list_of_not_mem_of_mem [TransCmp cmp]
|
|||
DTreeMap.Const.getKey!_insertManyIfNewUnit_list_of_not_mem_of_mem k_eq not_mem distinct mem
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_mem [TransCmp cmp]
|
||||
[Inhabited α] {l : List α} {k : α} (mem : k ∈ t):
|
||||
[Inhabited α] {l : List α} {k : α} (mem : k ∈ t) :
|
||||
getKey! (insertManyIfNewUnit t l) k = getKey! t k :=
|
||||
DTreeMap.Const.getKey!_insertManyIfNewUnit_list_of_mem mem
|
||||
|
||||
|
|
@ -1516,7 +1517,7 @@ theorem mem_alter [TransCmp cmp] {k k' : α} {f : Option β → Option β} :
|
|||
if cmp k k' = .eq then (f t[k]?).isSome = true else k' ∈ t :=
|
||||
DTreeMap.Const.mem_alter
|
||||
|
||||
theorem mem_alter_of_compare_eq [TransCmp cmp] {k k': α} {f : Option β → Option β}
|
||||
theorem mem_alter_of_compare_eq [TransCmp cmp] {k k' : α} {f : Option β → Option β}
|
||||
(he : cmp k k' = .eq) :
|
||||
k' ∈ alter t k f ↔ (f t[k]?).isSome :=
|
||||
DTreeMap.Const.mem_alter_of_compare_eq he
|
||||
|
|
@ -2997,4 +2998,446 @@ theorem maxKeyD_alter_eq_self [TransCmp cmp] {k f}
|
|||
|
||||
end Max
|
||||
|
||||
namespace Equiv
|
||||
|
||||
variable {t₁ t₂ t₃ t₄ : TreeMap α β cmp} {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
@[refl, simp] theorem rfl : Equiv t t := ⟨.rfl⟩
|
||||
|
||||
@[symm] theorem symm : Equiv t₁ t₂ → Equiv t₂ t₁
|
||||
| ⟨h⟩ => ⟨h.symm⟩
|
||||
|
||||
theorem trans : Equiv t₁ t₂ → Equiv t₂ t₃ → Equiv t₁ t₃
|
||||
| ⟨h⟩, ⟨h'⟩ => ⟨h.trans h'⟩
|
||||
|
||||
instance instTrans : @Trans (TreeMap α β cmp) _ _ Equiv Equiv Equiv := ⟨trans⟩
|
||||
|
||||
theorem comm : t₁ ~m t₂ ↔ t₂ ~m t₁ := ⟨symm, symm⟩
|
||||
theorem congr_left (h : t₁ ~m t₂) : t₁ ~m t₃ ↔ t₂ ~m t₃ := ⟨h.symm.trans, h.trans⟩
|
||||
theorem congr_right (h : t₁ ~m t₂) : t₃ ~m t₁ ↔ t₃ ~m t₂ :=
|
||||
⟨fun h' => h'.trans h, fun h' => h'.trans h.symm⟩
|
||||
|
||||
-- congruence lemmas
|
||||
|
||||
theorem isEmpty_eq (h : t₁ ~m t₂) : t₁.isEmpty = t₂.isEmpty :=
|
||||
h.1.isEmpty_eq
|
||||
|
||||
theorem contains_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.contains k = t₂.contains k :=
|
||||
h.1.contains_eq
|
||||
|
||||
theorem mem_iff [TransCmp cmp] (h : t₁ ~m t₂) {k : α} :
|
||||
k ∈ t₁ ↔ k ∈ t₂ :=
|
||||
h.1.mem_iff
|
||||
|
||||
theorem size_eq (h : t₁ ~m t₂) : t₁.size = t₂.size :=
|
||||
h.1.size_eq
|
||||
|
||||
theorem getElem?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) : t₁[k]? = t₂[k]? :=
|
||||
h.1.constGet?_eq
|
||||
|
||||
theorem getElem_eq [TransCmp cmp] {k : α} {hk : k ∈ t₁} (h : t₁ ~m t₂) :
|
||||
t₁[k] = t₂[k]'(h.mem_iff.mp hk) :=
|
||||
h.1.constGet_eq
|
||||
|
||||
theorem getElem!_eq [TransCmp cmp] [Inhabited β] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁[k]! = t₂[k]! :=
|
||||
h.1.constGet!_eq
|
||||
|
||||
theorem getD_eq [TransCmp cmp] {k : α} {fallback : β} (h : t₁ ~m t₂) :
|
||||
t₁.getD k fallback = t₂.getD k fallback :=
|
||||
h.1.constGetD_eq
|
||||
|
||||
theorem getKey?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKey? k = t₂.getKey? k :=
|
||||
h.1.getKey?_eq
|
||||
|
||||
theorem getKey_eq [TransCmp cmp] {k : α} {hk : k ∈ t₁} (h : t₁ ~m t₂) :
|
||||
t₁.getKey k hk = t₂.getKey k (h.mem_iff.mp hk) :=
|
||||
h.1.getKey_eq
|
||||
|
||||
theorem getKey!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKey! k = t₂.getKey! k :=
|
||||
h.1.getKey!_eq
|
||||
|
||||
theorem getKeyD_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyD k fallback = t₂.getKeyD k fallback :=
|
||||
h.1.getKeyD_eq
|
||||
|
||||
theorem toList_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.toList = t₂.toList :=
|
||||
h.1.constToList_eq
|
||||
|
||||
theorem toArray_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.toArray = t₂.toArray :=
|
||||
h.1.constToArray_eq
|
||||
|
||||
theorem keys_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.keys = t₂.keys :=
|
||||
h.1.keys_eq
|
||||
|
||||
theorem keysArray_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.keysArray = t₂.keysArray :=
|
||||
h.1.keysArray_eq
|
||||
|
||||
theorem foldlM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : δ → α → β → m δ} {init : δ}
|
||||
(h : t₁ ~m t₂) :
|
||||
t₁.foldlM f init = t₂.foldlM f init :=
|
||||
h.1.foldlM_eq
|
||||
|
||||
theorem foldl_eq [TransCmp cmp] {f : δ → α → β → δ} {init : δ} (h : t₁ ~m t₂) :
|
||||
t₁.foldl f init = t₂.foldl f init :=
|
||||
h.1.foldl_eq
|
||||
|
||||
theorem foldrM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : α → β → δ → m δ} {init : δ}
|
||||
(h : t₁ ~m t₂) :
|
||||
t₁.foldrM f init = t₂.foldrM f init :=
|
||||
h.1.foldrM_eq
|
||||
|
||||
theorem foldr_eq [TransCmp cmp] {f : α → β → δ → δ} {init : δ} (h : t₁ ~m t₂) :
|
||||
t₁.foldr f init = t₂.foldr f init :=
|
||||
h.1.foldr_eq
|
||||
|
||||
theorem forIn_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {b : δ} {f : α × β → δ → m (ForInStep δ)}
|
||||
(h : t₁ ~m t₂) : ForIn.forIn t₁ b f = ForIn.forIn t₂ b f :=
|
||||
h.1.forIn_eq (f := fun ⟨a, b⟩ => f ⟨a, b⟩)
|
||||
|
||||
theorem forM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : α × β → m PUnit} (h : t₁ ~m t₂) :
|
||||
ForM.forM t₁ f = ForM.forM t₂ f :=
|
||||
h.1.forM_eq (f := fun x : (_ : α) × β => f (x.1, x.2))
|
||||
|
||||
theorem any_eq [TransCmp cmp] {p : α → β → Bool} (h : t₁ ~m t₂) : t₁.any p = t₂.any p :=
|
||||
h.1.any_eq
|
||||
|
||||
theorem all_eq [TransCmp cmp] {p : α → β → Bool} (h : t₁ ~m t₂) : t₁.all p = t₂.all p :=
|
||||
h.1.all_eq
|
||||
|
||||
theorem minKey?_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.minKey? = t₂.minKey? :=
|
||||
h.1.minKey?_eq
|
||||
|
||||
theorem minKey_eq [TransCmp cmp] {h' : t₁.isEmpty = false} (h : t₁ ~m t₂) :
|
||||
t₁.minKey h' = t₂.minKey (h.isEmpty_eq.symm.trans h') :=
|
||||
h.1.minKey_eq
|
||||
|
||||
theorem minKey!_eq [TransCmp cmp] [Inhabited α] (h : t₁ ~m t₂) :
|
||||
t₁.minKey! = t₂.minKey! :=
|
||||
h.1.minKey!_eq
|
||||
|
||||
theorem minKeyD_eq [TransCmp cmp] {fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.minKeyD fallback = t₂.minKeyD fallback :=
|
||||
h.1.minKeyD_eq
|
||||
|
||||
theorem maxKey?_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.maxKey? = t₂.maxKey? :=
|
||||
h.1.maxKey?_eq
|
||||
|
||||
theorem maxKey_eq [TransCmp cmp] {h' : t₁.isEmpty = false} (h : t₁ ~m t₂) :
|
||||
t₁.maxKey h' = t₂.maxKey (h.isEmpty_eq.symm.trans h') :=
|
||||
h.1.maxKey_eq
|
||||
|
||||
theorem maxKey!_eq [TransCmp cmp] [Inhabited α] (h : t₁ ~m t₂) :
|
||||
t₁.maxKey! = t₂.maxKey! :=
|
||||
h.1.maxKey!_eq
|
||||
|
||||
theorem maxKeyD_eq [TransCmp cmp] {fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.maxKeyD fallback = t₂.maxKeyD fallback :=
|
||||
h.1.maxKeyD_eq
|
||||
|
||||
theorem minEntry?_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.minEntry? = t₂.minEntry? :=
|
||||
h.1.constMinEntry?_eq
|
||||
|
||||
theorem minEntry_eq [TransCmp cmp] {he : t₁.isEmpty = false} (h : t₁ ~m t₂) :
|
||||
t₁.minEntry he = t₂.minEntry (h.isEmpty_eq.symm.trans he) :=
|
||||
h.1.constMinEntry_eq
|
||||
|
||||
theorem minEntry!_eq [TransCmp cmp] [Inhabited (α × β)] (h : t₁ ~m t₂) :
|
||||
t₁.minEntry! = t₂.minEntry! :=
|
||||
h.1.constMinEntry!_eq
|
||||
|
||||
theorem minEntryD_eq [TransCmp cmp] {fallback : α × β} (h : t₁ ~m t₂) :
|
||||
t₁.minEntryD fallback = t₂.minEntryD fallback :=
|
||||
h.1.constMinEntryD_eq
|
||||
|
||||
theorem maxEntry?_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.maxEntry? = t₂.maxEntry? :=
|
||||
h.1.constMaxEntry?_eq
|
||||
|
||||
theorem maxEntry_eq [TransCmp cmp] {he : t₁.isEmpty = false} (h : t₁ ~m t₂) :
|
||||
t₁.maxEntry he = t₂.maxEntry (h.isEmpty_eq.symm.trans he) :=
|
||||
h.1.constMaxEntry_eq
|
||||
|
||||
theorem maxEntry!_eq [TransCmp cmp] [Inhabited (α × β)] (h : t₁ ~m t₂) :
|
||||
t₁.maxEntry! = t₂.maxEntry! :=
|
||||
h.1.constMaxEntry!_eq
|
||||
|
||||
theorem maxEntryD_eq [TransCmp cmp] {fallback : α × β} (h : t₁ ~m t₂) :
|
||||
t₁.maxEntryD fallback = t₂.maxEntryD fallback :=
|
||||
h.1.constMaxEntryD_eq
|
||||
|
||||
theorem entryAtIdx?_eq [TransCmp cmp] {i : Nat} (h : t₁ ~m t₂) :
|
||||
t₁.entryAtIdx? i = t₂.entryAtIdx? i :=
|
||||
h.1.constEntryAtIdx?_eq
|
||||
|
||||
theorem entryAtIdx_eq [TransCmp cmp] {i : Nat} {h' : i < t₁.size} (h : t₁ ~m t₂) :
|
||||
t₁.entryAtIdx i h' = t₂.entryAtIdx i (h.size_eq ▸ h') :=
|
||||
h.1.constEntryAtIdx_eq
|
||||
|
||||
theorem entryAtIdx!_eq [TransCmp cmp] [Inhabited (α × β)] {i : Nat} (h : t₁ ~m t₂) :
|
||||
t₁.entryAtIdx! i = t₂.entryAtIdx! i :=
|
||||
h.1.constEntryAtIdx!_eq
|
||||
|
||||
theorem entryAtIdxD_eq [TransCmp cmp] {i : Nat} {fallback : α × β} (h : t₁ ~m t₂) :
|
||||
t₁.entryAtIdxD i fallback = t₂.entryAtIdxD i fallback :=
|
||||
h.1.constEntryAtIdxD_eq
|
||||
|
||||
theorem keyAtIdx?_eq [TransCmp cmp] {i : Nat} (h : t₁ ~m t₂) :
|
||||
t₁.keyAtIdx? i = t₂.keyAtIdx? i :=
|
||||
h.1.keyAtIdx?_eq
|
||||
|
||||
theorem keyAtIdx_eq [TransCmp cmp] {i : Nat} {h' : i < t₁.size} (h : t₁ ~m t₂) :
|
||||
t₁.keyAtIdx i h' = t₂.keyAtIdx i (h.size_eq ▸ h') :=
|
||||
h.1.keyAtIdx_eq
|
||||
|
||||
theorem keyAtIdx!_eq [TransCmp cmp] [Inhabited α] {i : Nat} (h : t₁ ~m t₂) :
|
||||
t₁.keyAtIdx! i = t₂.keyAtIdx! i :=
|
||||
h.1.keyAtIdx!_eq
|
||||
|
||||
theorem keyAtIdxD_eq [TransCmp cmp] {i : Nat} {fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.keyAtIdxD i fallback = t₂.keyAtIdxD i fallback :=
|
||||
h.1.keyAtIdxD_eq
|
||||
|
||||
theorem getEntryGE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGE? k = t₂.getEntryGE? k :=
|
||||
h.1.constGetEntryGE?_eq
|
||||
|
||||
theorem getEntryGE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGE k h' = t₂.getEntryGE k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.constGetEntryGE_eq
|
||||
|
||||
theorem getEntryGE!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGE! k = t₂.getEntryGE! k :=
|
||||
h.1.constGetEntryGE!_eq
|
||||
|
||||
theorem getEntryGED_eq [TransCmp cmp] {k : α} {fallback : α × β} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGED k fallback = t₂.getEntryGED k fallback :=
|
||||
h.1.constGetEntryGED_eq
|
||||
|
||||
theorem getEntryGT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGT? k = t₂.getEntryGT? k :=
|
||||
h.1.constGetEntryGT?_eq
|
||||
|
||||
theorem getEntryGT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGT k h' = t₂.getEntryGT k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.constGetEntryGT_eq
|
||||
|
||||
theorem getEntryGT!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGT! k = t₂.getEntryGT! k :=
|
||||
h.1.constGetEntryGT!_eq
|
||||
|
||||
theorem getEntryGTD_eq [TransCmp cmp] {k : α} {fallback : α × β} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGTD k fallback = t₂.getEntryGTD k fallback :=
|
||||
h.1.constGetEntryGTD_eq
|
||||
|
||||
theorem getEntryLE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLE? k = t₂.getEntryLE? k :=
|
||||
h.1.constGetEntryLE?_eq
|
||||
|
||||
theorem getEntryLE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLE k h' = t₂.getEntryLE k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.constGetEntryLE_eq
|
||||
|
||||
theorem getEntryLE!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLE! k = t₂.getEntryLE! k :=
|
||||
h.1.constGetEntryLE!_eq
|
||||
|
||||
theorem getEntryLED_eq [TransCmp cmp] {k : α} {fallback : α × β} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLED k fallback = t₂.getEntryLED k fallback :=
|
||||
h.1.constGetEntryLED_eq
|
||||
|
||||
theorem getEntryLT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLT? k = t₂.getEntryLT? k :=
|
||||
h.1.constGetEntryLT?_eq
|
||||
|
||||
theorem getEntryLT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLT k h' = t₂.getEntryLT k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.constGetEntryLT_eq
|
||||
|
||||
theorem getEntryLT!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLT! k = t₂.getEntryLT! k :=
|
||||
h.1.constGetEntryLT!_eq
|
||||
|
||||
theorem getEntryLTD_eq [TransCmp cmp] {k : α} {fallback : α × β} (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLTD k fallback = t₂.getEntryLTD k fallback :=
|
||||
h.1.constGetEntryLTD_eq
|
||||
|
||||
theorem getKeyGE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGE? k = t₂.getKeyGE? k :=
|
||||
h.1.getKeyGE?_eq
|
||||
|
||||
theorem getKeyGE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGE k h' = t₂.getKeyGE k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getKeyGE_eq
|
||||
|
||||
theorem getKeyGE!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGE! k = t₂.getKeyGE! k :=
|
||||
h.1.getKeyGE!_eq
|
||||
|
||||
theorem getKeyGED_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGED k fallback = t₂.getKeyGED k fallback :=
|
||||
h.1.getKeyGED_eq
|
||||
|
||||
theorem getKeyGT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGT? k = t₂.getKeyGT? k :=
|
||||
h.1.getKeyGT?_eq
|
||||
|
||||
theorem getKeyGT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGT k h' = t₂.getKeyGT k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getKeyGT_eq
|
||||
|
||||
theorem getKeyGT!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGT! k = t₂.getKeyGT! k :=
|
||||
h.1.getKeyGT!_eq
|
||||
|
||||
theorem getKeyGTD_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGTD k fallback = t₂.getKeyGTD k fallback :=
|
||||
h.1.getKeyGTD_eq
|
||||
|
||||
theorem getKeyLE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLE? k = t₂.getKeyLE? k :=
|
||||
h.1.getKeyLE?_eq
|
||||
|
||||
theorem getKeyLE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLE k h' = t₂.getKeyLE k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getKeyLE_eq
|
||||
|
||||
theorem getKeyLE!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLE! k = t₂.getKeyLE! k :=
|
||||
h.1.getKeyLE!_eq
|
||||
|
||||
theorem getKeyLED_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLED k fallback = t₂.getKeyLED k fallback :=
|
||||
h.1.getKeyLED_eq
|
||||
|
||||
theorem getKeyLT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLT? k = t₂.getKeyLT? k :=
|
||||
h.1.getKeyLT?_eq
|
||||
|
||||
theorem getKeyLT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLT k h' = t₂.getKeyLT k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getKeyLT_eq
|
||||
|
||||
theorem getKeyLT!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLT! k = t₂.getKeyLT! k :=
|
||||
h.1.getKeyLT!_eq
|
||||
|
||||
theorem getKeyLTD_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLTD k fallback = t₂.getKeyLTD k fallback :=
|
||||
h.1.getKeyLTD_eq
|
||||
|
||||
theorem insert [TransCmp cmp] (h : t₁ ~m t₂) (k : α) (v : β) : t₁.insert k v ~m t₂.insert k v :=
|
||||
⟨h.1.insert k v⟩
|
||||
|
||||
theorem erase [TransCmp cmp] (h : t₁ ~m t₂) (k : α) : t₁.erase k ~m t₂.erase k :=
|
||||
⟨h.1.erase k⟩
|
||||
|
||||
theorem insertIfNew [TransCmp cmp] (h : t₁ ~m t₂) (k : α) (v : β) :
|
||||
t₁.insertIfNew k v ~m t₂.insertIfNew k v :=
|
||||
⟨h.1.insertIfNew k v⟩
|
||||
|
||||
theorem alter [TransCmp cmp] [LawfulEqCmp cmp] (h : t₁ ~m t₂)
|
||||
(k : α) (f : Option β → Option β) : t₁.alter k f ~m t₂.alter k f :=
|
||||
⟨h.1.constAlter k f⟩
|
||||
|
||||
theorem modify [TransCmp cmp] [LawfulEqCmp cmp] (h : t₁ ~m t₂)
|
||||
(k : α) (f : β → β) : t₁.modify k f ~m t₂.modify k f :=
|
||||
⟨h.1.constModify k f⟩
|
||||
|
||||
theorem filter (h : t₁ ~m t₂) (f : α → β → Bool) : t₁.filter f ~m t₂.filter f :=
|
||||
⟨h.1.filter f⟩
|
||||
|
||||
theorem map (h : t₁ ~m t₂) (f : α → β → γ) : t₁.map f ~m t₂.map f :=
|
||||
⟨h.1.map f⟩
|
||||
|
||||
theorem filterMap (h : t₁ ~m t₂) (f : α → β → Option γ) : t₁.filterMap f ~m t₂.filterMap f :=
|
||||
⟨h.1.filterMap f⟩
|
||||
|
||||
theorem insertMany_list [TransCmp cmp] (h : t₁ ~m t₂) (l : List (α × β)) :
|
||||
t₁.insertMany l ~m t₂.insertMany l :=
|
||||
⟨h.1.constInsertMany_list l⟩
|
||||
|
||||
theorem insertManyIfNewUnit_list [TransCmp cmp] {t₁ t₂ : TreeMap α Unit cmp}
|
||||
(h : t₁ ~m t₂) (l : List α) :
|
||||
t₁.insertManyIfNewUnit l ~m t₂.insertManyIfNewUnit l :=
|
||||
⟨h.1.constInsertManyIfNewUnit_list l⟩
|
||||
|
||||
theorem eraseMany_list [TransCmp cmp] (h : t₁ ~m t₂) (l : List α) :
|
||||
t₁.eraseMany l ~m t₂.eraseMany l :=
|
||||
⟨h.1.eraseMany_list l⟩
|
||||
|
||||
theorem mergeWith [TransCmp cmp] [LawfulEqCmp cmp] (f : α → β → β → β)
|
||||
(h : t₁ ~m t₂) (h' : t₃ ~m t₄) : t₁.mergeWith f t₃ ~m t₂.mergeWith f t₄ :=
|
||||
⟨h.1.constMergeWith f h'.1⟩
|
||||
|
||||
theorem values_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.values = t₂.values :=
|
||||
h.1.values_eq
|
||||
|
||||
theorem valuesArray_eq [TransCmp cmp] (h : t₁ ~m t₂) :
|
||||
t₁.valuesArray = t₂.valuesArray :=
|
||||
h.1.valuesArray_eq
|
||||
|
||||
-- extensionalities
|
||||
|
||||
theorem of_forall_getKey_eq_of_forall_constGet?_eq [TransCmp cmp]
|
||||
(hk : ∀ k hk hk', t₁.getKey k hk = t₂.getKey k hk')
|
||||
(hv : ∀ k : α, t₁[k]? = t₂[k]?) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_getKey_eq_of_forall_constGet?_eq hk hv⟩
|
||||
|
||||
theorem of_forall_constGet?_eq [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
(h : ∀ k : α, t₁[k]? = t₂[k]?) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_constGet?_eq h⟩
|
||||
|
||||
theorem of_forall_getKey?_unit_eq [TransCmp cmp] {t₁ t₂ : TreeMap α Unit cmp}
|
||||
(h : ∀ k, t₁.getKey? k = t₂.getKey? k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_getKey?_unit_eq h⟩
|
||||
|
||||
theorem of_forall_contains_unit_eq [TransCmp cmp] [LawfulEqCmp cmp] {t₁ t₂ : TreeMap α Unit cmp}
|
||||
(h : ∀ k, t₁.contains k = t₂.contains k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_contains_unit_eq h⟩
|
||||
|
||||
theorem of_forall_mem_unit_iff [TransCmp cmp] [LawfulEqCmp cmp] {t₁ t₂ : TreeMap α Unit cmp}
|
||||
(h : ∀ k, k ∈ t₁ ↔ k ∈ t₂) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_mem_unit_iff h⟩
|
||||
|
||||
end Equiv
|
||||
|
||||
section Equiv
|
||||
|
||||
variable {t₁ t₂ : TreeMap α β cmp}
|
||||
|
||||
private theorem equiv_iff_equiv : t₁ ~m t₂ ↔ t₁.1.Equiv t₂.1 :=
|
||||
⟨fun ⟨h⟩ => h, fun h => ⟨h⟩⟩
|
||||
|
||||
theorem equiv_empty_iff_isEmpty : t ~m empty ↔ t.isEmpty :=
|
||||
equiv_iff_equiv.trans DTreeMap.equiv_empty_iff_isEmpty
|
||||
|
||||
theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
|
||||
Equiv.comm.trans equiv_empty_iff_isEmpty
|
||||
|
||||
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList :=
|
||||
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_toList_perm
|
||||
|
||||
theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ :=
|
||||
⟨.of_constToList_perm h⟩
|
||||
|
||||
theorem equiv_iff_toList_eq [TransCmp cmp] :
|
||||
t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
|
||||
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_toList_eq
|
||||
|
||||
theorem equiv_iff_keys_unit_perm {t₁ t₂ : TreeMap α Unit cmp} :
|
||||
t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys :=
|
||||
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_keys_unit_perm
|
||||
|
||||
theorem equiv_iff_keys_unit_eq [TransCmp cmp] {t₁ t₂ : TreeMap α Unit cmp} :
|
||||
t₁ ~m t₂ ↔ t₁.keys = t₂.keys :=
|
||||
equiv_iff_equiv.trans DTreeMap.Const.equiv_iff_keys_unit_eq
|
||||
|
||||
theorem Equiv.of_keys_unit_perm {t₁ t₂ : TreeMap α Unit cmp} : t₁.keys.Perm t₂.keys → t₁ ~m t₂ :=
|
||||
equiv_iff_keys_unit_perm.mpr
|
||||
|
||||
end Equiv
|
||||
|
||||
end Std.TreeMap
|
||||
|
|
|
|||
|
|
@ -88,6 +88,13 @@ instance : EmptyCollection (Raw α β cmp) where
|
|||
instance : Inhabited (Raw α β cmp) where
|
||||
default := ∅
|
||||
|
||||
@[inherit_doc DTreeMap.Equiv]
|
||||
structure Equiv (m₁ m₂ : Raw α β cmp) where
|
||||
/-- Internal implementation detail of the tree map -/
|
||||
inner : m₁.1.Equiv m₂.1
|
||||
|
||||
@[inherit_doc] scoped infix:50 " ~m " => Equiv
|
||||
|
||||
@[simp]
|
||||
theorem empty_eq_emptyc : (empty : Raw α β cmp) = ∅ :=
|
||||
rfl
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ Authors: Markus Himmel, Paul Reichert
|
|||
prelude
|
||||
import Std.Data.DTreeMap.Raw.Lemmas
|
||||
import Std.Data.TreeMap.Raw.Basic
|
||||
import Std.Data.TreeMap.Raw.AdditionalOperations
|
||||
|
||||
/-!
|
||||
# Tree map lemmas
|
||||
|
|
@ -18,11 +19,11 @@ These proofs can be obtained from `Std.Data.TreeMap.Raw.WF`.
|
|||
set_option linter.missingDocs true
|
||||
set_option autoImplicit false
|
||||
|
||||
universe u v w
|
||||
universe u v w w'
|
||||
|
||||
namespace Std.TreeMap.Raw
|
||||
|
||||
variable {α : Type u} {β : Type v} {cmp : α → α → Ordering} {t : TreeMap.Raw α β cmp}
|
||||
variable {α : Type u} {β : Type v} {γ : Type w} {cmp : α → α → Ordering} {t : TreeMap.Raw α β cmp}
|
||||
|
||||
private theorem ext {t t' : Raw α β cmp} : t.inner = t'.inner → t = t' := by
|
||||
cases t; cases t'; rintro rfl; rfl
|
||||
|
|
@ -844,7 +845,7 @@ theorem ordered_keys_toList [TransCmp cmp] (h : t.WF) :
|
|||
|
||||
section monadic
|
||||
|
||||
variable {δ : Type w} {m : Type w → Type w}
|
||||
variable {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m] {f : δ → α → β → m δ} {init : δ} :
|
||||
t.foldlM f init = t.toList.foldlM (fun a b => f a b.1 b.2) init :=
|
||||
|
|
@ -2735,4 +2736,414 @@ theorem maxKeyD_alter_eq_self [TransCmp cmp] (h : t.WF) {k f}
|
|||
|
||||
end Max
|
||||
|
||||
namespace Equiv
|
||||
|
||||
variable {t₁ t₂ t₃ t₄ : Raw α β cmp} {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
@[refl, simp] theorem rfl : Equiv t t := ⟨.rfl⟩
|
||||
|
||||
@[symm] theorem symm : Equiv t₁ t₂ → Equiv t₂ t₁
|
||||
| ⟨h⟩ => ⟨h.symm⟩
|
||||
|
||||
theorem trans : Equiv t₁ t₂ → Equiv t₂ t₃ → Equiv t₁ t₃
|
||||
| ⟨h⟩, ⟨h'⟩ => ⟨h.trans h'⟩
|
||||
|
||||
instance instTrans : @Trans (Raw α β cmp) _ _ Equiv Equiv Equiv := ⟨trans⟩
|
||||
|
||||
theorem comm : t₁ ~m t₂ ↔ t₂ ~m t₁ := ⟨symm, symm⟩
|
||||
theorem congr_left (h : t₁ ~m t₂) : t₁ ~m t₃ ↔ t₂ ~m t₃ := ⟨h.symm.trans, h.trans⟩
|
||||
theorem congr_right (h : t₁ ~m t₂) : t₃ ~m t₁ ↔ t₃ ~m t₂ :=
|
||||
⟨fun h' => h'.trans h, fun h' => h'.trans h.symm⟩
|
||||
|
||||
-- congruence lemmas
|
||||
|
||||
theorem isEmpty_eq (h : t₁ ~m t₂) : t₁.isEmpty = t₂.isEmpty :=
|
||||
h.1.isEmpty_eq
|
||||
|
||||
theorem contains_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.contains k = t₂.contains k :=
|
||||
h.1.contains_eq h₁.1 h₂.1
|
||||
|
||||
theorem mem_iff [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
k ∈ t₁ ↔ k ∈ t₂ :=
|
||||
h.1.mem_iff h₁.1 h₂.1
|
||||
|
||||
theorem size_eq (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.size = t₂.size :=
|
||||
h.1.size_eq h₁.1 h₂.1
|
||||
|
||||
theorem getElem?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁[k]? = t₂[k]? :=
|
||||
h.1.constGet?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getElem_eq [TransCmp cmp] {k : α} {hk : k ∈ t₁} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁[k] = t₂[k]'((h.mem_iff h₁ h₂).mp hk) :=
|
||||
h.1.constGet_eq h₁.1 h₂.1
|
||||
|
||||
theorem getElem!_eq [TransCmp cmp] [Inhabited β] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁[k]! = t₂[k]! :=
|
||||
h.1.constGet!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getD_eq [TransCmp cmp] {k : α} {fallback : β} (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.getD k fallback = t₂.getD k fallback :=
|
||||
h.1.constGetD_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKey?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKey? k = t₂.getKey? k :=
|
||||
h.1.getKey?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKey_eq [TransCmp cmp] {k : α} {hk : k ∈ t₁} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKey k hk = t₂.getKey k ((h.mem_iff h₁ h₂).mp hk) :=
|
||||
h.1.getKey_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKey!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKey! k = t₂.getKey! k :=
|
||||
h.1.getKey!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyD_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyD k fallback = t₂.getKeyD k fallback :=
|
||||
h.1.getKeyD_eq h₁.1 h₂.1
|
||||
|
||||
theorem toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.toList = t₂.toList :=
|
||||
h.1.constToList_eq h₁.1 h₂.1
|
||||
|
||||
theorem toArray_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.toArray = t₂.toArray :=
|
||||
h.1.constToArray_eq h₁.1 h₂.1
|
||||
|
||||
theorem keys_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.keys = t₂.keys :=
|
||||
h.1.keys_eq h₁.1 h₂.1
|
||||
|
||||
theorem keysArray_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.keysArray = t₂.keysArray :=
|
||||
h.1.keysArray_eq h₁.1 h₂.1
|
||||
|
||||
theorem foldlM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : δ → α → β → m δ}
|
||||
{init : δ} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.foldlM f init = t₂.foldlM f init :=
|
||||
h.1.foldlM_eq h₁.1 h₂.1
|
||||
|
||||
theorem foldl_eq [TransCmp cmp] {f : δ → α → β → δ} {init : δ} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) :
|
||||
t₁.foldl f init = t₂.foldl f init :=
|
||||
h.1.foldl_eq h₁.1 h₂.1
|
||||
|
||||
theorem foldrM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : α → β → δ → m δ}
|
||||
{init : δ} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.foldrM f init = t₂.foldrM f init :=
|
||||
h.1.foldrM_eq h₁.1 h₂.1
|
||||
|
||||
theorem foldr_eq [TransCmp cmp] {f : α → β → δ → δ} {init : δ} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) :
|
||||
t₁.foldr f init = t₂.foldr f init :=
|
||||
h.1.foldr_eq h₁.1 h₂.1
|
||||
|
||||
theorem forIn_eq [TransCmp cmp] [Monad m] [LawfulMonad m]
|
||||
{b : δ} {f : α × β → δ → m (ForInStep δ)} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
ForIn.forIn t₁ b f = ForIn.forIn t₂ b f :=
|
||||
h.1.forIn_eq h₁.1 h₂.1 (f := fun ⟨a, b⟩ => f ⟨a, b⟩)
|
||||
|
||||
theorem forM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : α × β → m PUnit}
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
ForM.forM t₁ f = ForM.forM t₂ f :=
|
||||
h.1.forM_eq h₁.1 h₂.1 (f := fun x : (_ : α) × β => f (x.1, x.2))
|
||||
|
||||
theorem any_eq [TransCmp cmp] {p : α → β → Bool} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.any p = t₂.any p :=
|
||||
h.1.any_eq h₁.1 h₂.1
|
||||
|
||||
theorem all_eq [TransCmp cmp] {p : α → β → Bool} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.all p = t₂.all p :=
|
||||
h.1.all_eq h₁.1 h₂.1
|
||||
|
||||
theorem minKey?_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.minKey? = t₂.minKey? :=
|
||||
h.1.minKey?_eq h₁.1 h₂.1
|
||||
|
||||
theorem minKey!_eq [TransCmp cmp] [Inhabited α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.minKey! = t₂.minKey! :=
|
||||
h.1.minKey!_eq h₁.1 h₂.1
|
||||
|
||||
theorem minKeyD_eq [TransCmp cmp] {fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.minKeyD fallback = t₂.minKeyD fallback :=
|
||||
h.1.minKeyD_eq h₁.1 h₂.1
|
||||
|
||||
theorem maxKey?_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.maxKey? = t₂.maxKey? :=
|
||||
h.1.maxKey?_eq h₁.1 h₂.1
|
||||
|
||||
theorem maxKey!_eq [TransCmp cmp] [Inhabited α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.maxKey! = t₂.maxKey! :=
|
||||
h.1.maxKey!_eq h₁.1 h₂.1
|
||||
|
||||
theorem maxKeyD_eq [TransCmp cmp] {fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.maxKeyD fallback = t₂.maxKeyD fallback :=
|
||||
h.1.maxKeyD_eq h₁.1 h₂.1
|
||||
|
||||
theorem minEntry?_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.minEntry? = t₂.minEntry? :=
|
||||
h.1.constMinEntry?_eq h₁.1 h₂.1
|
||||
|
||||
theorem minEntry!_eq [TransCmp cmp] [Inhabited (α × β)] (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.minEntry! = t₂.minEntry! :=
|
||||
h.1.constMinEntry!_eq h₁.1 h₂.1
|
||||
|
||||
theorem minEntryD_eq [TransCmp cmp] {fallback : α × β} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.minEntryD fallback = t₂.minEntryD fallback :=
|
||||
h.1.constMinEntryD_eq h₁.1 h₂.1
|
||||
|
||||
theorem maxEntry?_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.maxEntry? = t₂.maxEntry? :=
|
||||
h.1.constMaxEntry?_eq h₁.1 h₂.1
|
||||
|
||||
theorem maxEntry!_eq [TransCmp cmp] [Inhabited (α × β)] (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.maxEntry! = t₂.maxEntry! :=
|
||||
h.1.constMaxEntry!_eq h₁.1 h₂.1
|
||||
|
||||
theorem maxEntryD_eq [TransCmp cmp] {fallback : α × β} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.maxEntryD fallback = t₂.maxEntryD fallback :=
|
||||
h.1.constMaxEntryD_eq h₁.1 h₂.1
|
||||
|
||||
theorem entryAtIdx?_eq [TransCmp cmp] {i : Nat} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.entryAtIdx? i = t₂.entryAtIdx? i :=
|
||||
h.1.constEntryAtIdx?_eq h₁.1 h₂.1
|
||||
|
||||
theorem entryAtIdx!_eq [TransCmp cmp] [Inhabited (α × β)] {i : Nat} (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.entryAtIdx! i = t₂.entryAtIdx! i :=
|
||||
h.1.constEntryAtIdx!_eq h₁.1 h₂.1
|
||||
|
||||
theorem entryAtIdxD_eq [TransCmp cmp] {i : Nat} {fallback : α × β} (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.entryAtIdxD i fallback = t₂.entryAtIdxD i fallback :=
|
||||
h.1.constEntryAtIdxD_eq h₁.1 h₂.1
|
||||
|
||||
theorem keyAtIdx?_eq [TransCmp cmp] {i : Nat} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.keyAtIdx? i = t₂.keyAtIdx? i :=
|
||||
h.1.keyAtIdx?_eq h₁.1 h₂.1
|
||||
|
||||
theorem keyAtIdx!_eq [TransCmp cmp] [Inhabited α] {i : Nat} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.keyAtIdx! i = t₂.keyAtIdx! i :=
|
||||
h.1.keyAtIdx!_eq h₁.1 h₂.1
|
||||
|
||||
theorem keyAtIdxD_eq [TransCmp cmp] {i : Nat} {fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.keyAtIdxD i fallback = t₂.keyAtIdxD i fallback :=
|
||||
h.1.keyAtIdxD_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryGE?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGE? k = t₂.getEntryGE? k :=
|
||||
h.1.constGetEntryGE?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryGE!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.getEntryGE! k = t₂.getEntryGE! k :=
|
||||
h.1.constGetEntryGE!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryGED_eq [TransCmp cmp] {k : α} {fallback : α × β} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.getEntryGED k fallback = t₂.getEntryGED k fallback :=
|
||||
h.1.constGetEntryGED_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryGT?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getEntryGT? k = t₂.getEntryGT? k :=
|
||||
h.1.constGetEntryGT?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryGT!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.getEntryGT! k = t₂.getEntryGT! k :=
|
||||
h.1.constGetEntryGT!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryGTD_eq [TransCmp cmp] {k : α} {fallback : α × β} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.getEntryGTD k fallback = t₂.getEntryGTD k fallback :=
|
||||
h.1.constGetEntryGTD_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryLE?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLE? k = t₂.getEntryLE? k :=
|
||||
h.1.constGetEntryLE?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryLE!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.getEntryLE! k = t₂.getEntryLE! k :=
|
||||
h.1.constGetEntryLE!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryLED_eq [TransCmp cmp] {k : α} {fallback : α × β} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.getEntryLED k fallback = t₂.getEntryLED k fallback :=
|
||||
h.1.constGetEntryLED_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryLT?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getEntryLT? k = t₂.getEntryLT? k :=
|
||||
h.1.constGetEntryLT?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryLT!_eq [TransCmp cmp] [Inhabited (α × β)] {k : α} (h₁ : t₁.WF)
|
||||
(h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.getEntryLT! k = t₂.getEntryLT! k :=
|
||||
h.1.constGetEntryLT!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getEntryLTD_eq [TransCmp cmp] {k : α} {fallback : α × β} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.getEntryLTD k fallback = t₂.getEntryLTD k fallback :=
|
||||
h.1.constGetEntryLTD_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyGE?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGE? k = t₂.getKeyGE? k :=
|
||||
h.1.getKeyGE?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyGE!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGE! k = t₂.getKeyGE! k :=
|
||||
h.1.getKeyGE!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyGED_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGED k fallback = t₂.getKeyGED k fallback :=
|
||||
h.1.getKeyGED_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyGT?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGT? k = t₂.getKeyGT? k :=
|
||||
h.1.getKeyGT?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyGT!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGT! k = t₂.getKeyGT! k :=
|
||||
h.1.getKeyGT!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyGTD_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyGTD k fallback = t₂.getKeyGTD k fallback :=
|
||||
h.1.getKeyGTD_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyLE?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLE? k = t₂.getKeyLE? k :=
|
||||
h.1.getKeyLE?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyLE!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLE! k = t₂.getKeyLE! k :=
|
||||
h.1.getKeyLE!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyLED_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLED k fallback = t₂.getKeyLED k fallback :=
|
||||
h.1.getKeyLED_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyLT?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLT? k = t₂.getKeyLT? k :=
|
||||
h.1.getKeyLT?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyLT!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLT! k = t₂.getKeyLT! k :=
|
||||
h.1.getKeyLT!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyLTD_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getKeyLTD k fallback = t₂.getKeyLTD k fallback :=
|
||||
h.1.getKeyLTD_eq h₁.1 h₂.1
|
||||
|
||||
theorem insert [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(k : α) (v : β) : t₁.insert k v ~m t₂.insert k v :=
|
||||
⟨h.1.insert h₁.1 h₂.1 k v⟩
|
||||
|
||||
theorem erase [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(k : α) : t₁.erase k ~m t₂.erase k :=
|
||||
⟨h.1.erase h₁.1 h₂.1 k⟩
|
||||
|
||||
theorem insertIfNew [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(k : α) (v : β) : t₁.insertIfNew k v ~m t₂.insertIfNew k v :=
|
||||
⟨h.1.insertIfNew h₁.1 h₂.1 k v⟩
|
||||
|
||||
theorem alter [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(k : α) (f : Option β → Option β) :
|
||||
t₁.alter k f ~m t₂.alter k f :=
|
||||
⟨h.1.constAlter h₁.1 h₂.1 k f⟩
|
||||
|
||||
theorem modify [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(k : α) (f : β → β) : t₁.modify k f ~m t₂.modify k f :=
|
||||
⟨h.1.constModify h₁.1 h₂.1 k f⟩
|
||||
|
||||
theorem filter (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (f : α → β → Bool) :
|
||||
t₁.filter f ~m t₂.filter f :=
|
||||
⟨h.1.filter h₁.1 h₂.1 f⟩
|
||||
|
||||
theorem map (h : t₁ ~m t₂) (f : α → β → γ) : t₁.map f ~m t₂.map f :=
|
||||
⟨h.1.map f⟩
|
||||
|
||||
theorem filterMap (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (f : α → β → Option γ) :
|
||||
t₁.filterMap f ~m t₂.filterMap f :=
|
||||
⟨h.1.filterMap h₁.1 h₂.1 f⟩
|
||||
|
||||
theorem insertMany_list [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(l : List (α × β)) : t₁.insertMany l ~m t₂.insertMany l :=
|
||||
⟨h.1.constInsertMany_list h₁.1 h₂.1 l⟩
|
||||
|
||||
theorem insertManyIfNewUnit_list [TransCmp cmp] {t₁ t₂ : Raw α Unit cmp}
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (l : List α) :
|
||||
t₁.insertManyIfNewUnit l ~m t₂.insertManyIfNewUnit l :=
|
||||
⟨h.1.constInsertManyIfNewUnit_list h₁.1 h₂.1 l⟩
|
||||
|
||||
theorem eraseMany_list [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (l : List α) :
|
||||
t₁.eraseMany l ~m t₂.eraseMany l :=
|
||||
⟨h.1.eraseMany_list h₁.1 h₂.1 l⟩
|
||||
|
||||
theorem mergeWith [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h₃ : t₃.WF) (h₄ : t₄.WF)
|
||||
(f : α → β → β → β)
|
||||
(h : t₁ ~m t₂) (h' : t₃ ~m t₄) :
|
||||
t₁.mergeWith f t₃ ~m t₂.mergeWith f t₄ :=
|
||||
⟨h.1.constMergeWith h₁.1 h₂.1 h₃.1 h₄.1 f h'.1⟩
|
||||
|
||||
theorem values_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.values = t₂.values :=
|
||||
h.1.values_eq h₁.1 h₂.1
|
||||
|
||||
theorem valuesArray_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.valuesArray = t₂.valuesArray :=
|
||||
h.1.valuesArray_eq h₁.1 h₂.1
|
||||
|
||||
-- extensionalities
|
||||
|
||||
theorem of_forall_getKey_eq_of_forall_getElem?_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(hk : ∀ k hk hk', t₁.getKey k hk = t₂.getKey k hk')
|
||||
(hv : ∀ k : α, t₁[k]? = t₂[k]?) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_getKey_eq_of_forall_constGet?_eq h₁.1 h₂.1 hk hv⟩
|
||||
|
||||
theorem of_forall_getElem?_eq [TransCmp cmp] [LawfulEqCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : ∀ k : α, t₁[k]? = t₂[k]?) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_constGet?_eq h₁.1 h₂.1 h⟩
|
||||
|
||||
theorem of_forall_getKey?_unit_eq [TransCmp cmp] {t₁ t₂ : Raw α Unit cmp}
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) (h : ∀ k, t₁.getKey? k = t₂.getKey? k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_getKey?_unit_eq h₁.1 h₂.1 h⟩
|
||||
|
||||
theorem of_forall_contains_unit_eq [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
{t₁ t₂ : Raw α Unit cmp} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : ∀ k, t₁.contains k = t₂.contains k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_contains_unit_eq h₁.1 h₂.1 h⟩
|
||||
|
||||
theorem of_forall_mem_unit_iff [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
{t₁ t₂ : Raw α Unit cmp} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : ∀ k, k ∈ t₁ ↔ k ∈ t₂) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_mem_unit_iff h₁.1 h₂.1 h⟩
|
||||
|
||||
end Equiv
|
||||
|
||||
section Equiv
|
||||
|
||||
variable {t₁ t₂ : Raw α β cmp}
|
||||
|
||||
private theorem equiv_iff : t₁ ~m t₂ ↔ t₁.1.Equiv t₂.1 :=
|
||||
⟨fun ⟨h⟩ => h, fun h => ⟨h⟩⟩
|
||||
|
||||
theorem equiv_empty_iff_isEmpty : t ~m empty ↔ t.isEmpty :=
|
||||
equiv_iff.trans DTreeMap.Raw.equiv_empty_iff_isEmpty
|
||||
|
||||
theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
|
||||
equiv_iff.trans DTreeMap.Raw.empty_equiv_iff_isEmpty
|
||||
|
||||
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList :=
|
||||
equiv_iff.trans DTreeMap.Raw.Const.equiv_iff_toList_perm
|
||||
|
||||
theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ :=
|
||||
⟨.of_constToList_perm h⟩
|
||||
|
||||
theorem equiv_iff_toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
|
||||
t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
|
||||
equiv_iff.trans (DTreeMap.Raw.Const.equiv_iff_toList_eq h₁.1 h₂.1)
|
||||
|
||||
theorem equiv_iff_keys_unit_perm {t₁ t₂ : Raw α Unit cmp} :
|
||||
t₁ ~m t₂ ↔ t₁.keys.Perm t₂.keys :=
|
||||
equiv_iff.trans DTreeMap.Raw.Const.equiv_iff_keys_unit_perm
|
||||
|
||||
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 :=
|
||||
equiv_iff.trans (DTreeMap.Raw.Const.equiv_iff_keys_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₂ :=
|
||||
equiv_iff_keys_unit_perm.mpr
|
||||
|
||||
end Equiv
|
||||
|
||||
end Std.TreeMap.Raw
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ universe u v w
|
|||
|
||||
variable {α : Type u} {β : Type v} {cmp : α → α → Ordering}
|
||||
|
||||
namespace Std.TreeMap
|
||||
namespace Std.TreeSet
|
||||
|
||||
/-!
|
||||
We do not provide `get*GE`, `get*GT`, `get*LE` and `get*LT` functions for the raw trees.
|
||||
|
|
@ -60,4 +60,4 @@ less than the given element.
|
|||
def getLT [TransCmp cmp] (t : TreeSet α cmp) (k : α) (h : ∃ a ∈ t, cmp a k = .lt) : α :=
|
||||
TreeMap.getKeyLT t.inner k h
|
||||
|
||||
end Std.TreeMap
|
||||
end Std.TreeSet
|
||||
|
|
|
|||
|
|
@ -76,6 +76,13 @@ instance : EmptyCollection (TreeSet α cmp) where
|
|||
instance : Inhabited (TreeSet α cmp) where
|
||||
default := ∅
|
||||
|
||||
/-- Two tree sets are equivalent in the sense of Equiv iff all the values are equal. -/
|
||||
structure Equiv (m₁ m₂ : TreeSet α cmp) where
|
||||
/-- Internal implementation detail of the tree map -/
|
||||
inner : m₁.1.Equiv m₂.1
|
||||
|
||||
@[inherit_doc] scoped infix:50 " ~m " => Equiv
|
||||
|
||||
@[simp]
|
||||
theorem empty_eq_emptyc : (empty : TreeSet α cmp) = ∅ :=
|
||||
rfl
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ Authors: Markus Himmel, Paul Reichert
|
|||
prelude
|
||||
import Std.Data.TreeMap.Lemmas
|
||||
import Std.Data.TreeSet.Basic
|
||||
import Std.Data.TreeSet.AdditionalOperations
|
||||
|
||||
/-!
|
||||
# Tree set lemmas
|
||||
|
|
@ -17,7 +18,7 @@ This file contains lemmas about `Std.Data.TreeSet`. Most of the lemmas require
|
|||
set_option linter.missingDocs true
|
||||
set_option autoImplicit false
|
||||
|
||||
universe u v w
|
||||
universe u v w w'
|
||||
|
||||
namespace Std.TreeSet
|
||||
|
||||
|
|
@ -442,7 +443,7 @@ theorem ordered_toList [TransCmp cmp] :
|
|||
|
||||
section monadic
|
||||
|
||||
variable {δ : Type w} {m : Type w → Type w}
|
||||
variable {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ} :
|
||||
t.foldlM f init = t.toList.foldlM f init :=
|
||||
|
|
@ -1511,4 +1512,264 @@ theorem maxD_eq_getLastD_toList [TransCmp cmp] {fallback} :
|
|||
|
||||
end Max
|
||||
|
||||
namespace Equiv
|
||||
|
||||
variable {t₁ t₂ t₃ t₄ : TreeSet α cmp} {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
@[refl, simp] theorem rfl : Equiv t t := ⟨.rfl⟩
|
||||
|
||||
@[symm] theorem symm : Equiv t₁ t₂ → Equiv t₂ t₁
|
||||
| ⟨h⟩ => ⟨h.symm⟩
|
||||
|
||||
theorem trans : Equiv t₁ t₂ → Equiv t₂ t₃ → Equiv t₁ t₃
|
||||
| ⟨h⟩, ⟨h'⟩ => ⟨h.trans h'⟩
|
||||
|
||||
instance instTrans : @Trans (TreeSet α cmp) _ _ Equiv Equiv Equiv := ⟨trans⟩
|
||||
|
||||
theorem comm : t₁ ~m t₂ ↔ t₂ ~m t₁ := ⟨symm, symm⟩
|
||||
theorem congr_left (h : t₁ ~m t₂) : t₁ ~m t₃ ↔ t₂ ~m t₃ := ⟨h.symm.trans, h.trans⟩
|
||||
theorem congr_right (h : t₁ ~m t₂) : t₃ ~m t₁ ↔ t₃ ~m t₂ :=
|
||||
⟨fun h' => h'.trans h, fun h' => h'.trans h.symm⟩
|
||||
|
||||
-- congruence lemmas
|
||||
|
||||
theorem isEmpty_eq (h : t₁ ~m t₂) : t₁.isEmpty = t₂.isEmpty :=
|
||||
h.1.isEmpty_eq
|
||||
|
||||
theorem contains_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.contains k = t₂.contains k :=
|
||||
h.1.contains_eq
|
||||
|
||||
theorem mem_iff [TransCmp cmp] (h : t₁ ~m t₂) {k : α} :
|
||||
k ∈ t₁ ↔ k ∈ t₂ :=
|
||||
h.1.mem_iff
|
||||
|
||||
theorem size_eq (h : t₁ ~m t₂) : t₁.size = t₂.size :=
|
||||
h.1.size_eq
|
||||
|
||||
theorem get?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.get? k = t₂.get? k :=
|
||||
h.1.getKey?_eq
|
||||
|
||||
theorem get_eq [TransCmp cmp] {k : α} {hk : k ∈ t₁} (h : t₁ ~m t₂) :
|
||||
t₁.get k hk = t₂.get k (h.mem_iff.mp hk) :=
|
||||
h.1.getKey_eq
|
||||
|
||||
theorem get!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.get! k = t₂.get! k :=
|
||||
h.1.getKey!_eq
|
||||
|
||||
theorem getD_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getD k fallback = t₂.getD k fallback :=
|
||||
h.1.getKeyD_eq
|
||||
|
||||
theorem toList_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.toList = t₂.toList :=
|
||||
h.1.keys_eq
|
||||
|
||||
theorem toArray_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.toArray = t₂.toArray :=
|
||||
h.1.keysArray_eq
|
||||
|
||||
theorem foldlM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : δ → α → m δ} {init : δ}
|
||||
(h : t₁ ~m t₂) : t₁.foldlM f init = t₂.foldlM f init :=
|
||||
h.1.foldlM_eq
|
||||
|
||||
theorem foldl_eq [TransCmp cmp] {f : δ → α → δ} {init : δ} (h : t₁ ~m t₂) :
|
||||
t₁.foldl f init = t₂.foldl f init :=
|
||||
h.1.foldl_eq
|
||||
|
||||
theorem foldrM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : α → δ → m δ} {init : δ}
|
||||
(h : t₁ ~m t₂) :
|
||||
t₁.foldrM f init = t₂.foldrM f init :=
|
||||
h.1.foldrM_eq
|
||||
|
||||
theorem foldr_eq [TransCmp cmp] {f : α → δ → δ} {init : δ} (h : t₁ ~m t₂) :
|
||||
t₁.foldr f init = t₂.foldr f init :=
|
||||
h.1.foldr_eq
|
||||
|
||||
theorem forIn_eq [TransCmp cmp] [Monad m] [LawfulMonad m]
|
||||
{b : δ} {f : α → δ → m (ForInStep δ)} (h : t₁ ~m t₂) :
|
||||
ForIn.forIn t₁ b f = ForIn.forIn t₂ b f :=
|
||||
h.1.forIn_eq (f := fun x => f x.1)
|
||||
|
||||
theorem forM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : α → m PUnit} (h : t₁ ~m t₂) :
|
||||
ForM.forM t₁ f = ForM.forM t₂ f :=
|
||||
h.1.forM_eq (f := fun x => f x.1)
|
||||
|
||||
theorem any_eq [TransCmp cmp] {p : α → Bool} (h : t₁ ~m t₂) : t₁.any p = t₂.any p :=
|
||||
h.1.any_eq
|
||||
|
||||
theorem all_eq [TransCmp cmp] {p : α → Bool} (h : t₁ ~m t₂) : t₁.all p = t₂.all p :=
|
||||
h.1.all_eq
|
||||
|
||||
theorem min?_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.min? = t₂.min? :=
|
||||
h.1.minKey?_eq
|
||||
|
||||
theorem min_eq [TransCmp cmp] {h' : t₁.isEmpty = false} (h : t₁ ~m t₂) :
|
||||
t₁.min h' = t₂.min (h.isEmpty_eq.symm.trans h') :=
|
||||
h.1.minKey_eq
|
||||
|
||||
theorem min!_eq [TransCmp cmp] [Inhabited α] (h : t₁ ~m t₂) :
|
||||
t₁.min! = t₂.min! :=
|
||||
h.1.minKey!_eq
|
||||
|
||||
theorem minD_eq [TransCmp cmp] {fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.minD fallback = t₂.minD fallback :=
|
||||
h.1.minKeyD_eq
|
||||
|
||||
theorem max?_eq [TransCmp cmp] (h : t₁ ~m t₂) : t₁.max? = t₂.max? :=
|
||||
h.1.maxKey?_eq
|
||||
|
||||
theorem max_eq [TransCmp cmp] {h' : t₁.isEmpty = false} (h : t₁ ~m t₂) :
|
||||
t₁.max h' = t₂.max (h.isEmpty_eq.symm.trans h') :=
|
||||
h.1.maxKey_eq
|
||||
|
||||
theorem max!_eq [TransCmp cmp] [Inhabited α] (h : t₁ ~m t₂) :
|
||||
t₁.max! = t₂.max! :=
|
||||
h.1.maxKey!_eq
|
||||
|
||||
theorem maxD_eq [TransCmp cmp] {fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.maxD fallback = t₂.maxD fallback :=
|
||||
h.1.maxKeyD_eq
|
||||
|
||||
theorem atIdx?_eq [TransCmp cmp] {i : Nat} (h : t₁ ~m t₂) :
|
||||
t₁.atIdx? i = t₂.atIdx? i :=
|
||||
h.1.keyAtIdx?_eq
|
||||
|
||||
theorem atIdx_eq [TransCmp cmp] {i : Nat} {h' : i < t₁.size} (h : t₁ ~m t₂) :
|
||||
t₁.atIdx i h' = t₂.atIdx i (h.size_eq ▸ h') :=
|
||||
h.1.keyAtIdx_eq
|
||||
|
||||
theorem atIdx!_eq [TransCmp cmp] [Inhabited α] {i : Nat} (h : t₁ ~m t₂) :
|
||||
t₁.atIdx! i = t₂.atIdx! i :=
|
||||
h.1.keyAtIdx!_eq
|
||||
|
||||
theorem atIdxD_eq [TransCmp cmp] {i : Nat} {fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.atIdxD i fallback = t₂.atIdxD i fallback :=
|
||||
h.1.keyAtIdxD_eq
|
||||
|
||||
theorem getGE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getGE? k = t₂.getGE? k :=
|
||||
h.1.getKeyGE?_eq
|
||||
|
||||
theorem getGE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getGE k h' = t₂.getGE k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getKeyGE_eq
|
||||
|
||||
theorem getGE!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getGE! k = t₂.getGE! k :=
|
||||
h.1.getKeyGE!_eq
|
||||
|
||||
theorem getGED_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getGED k fallback = t₂.getGED k fallback :=
|
||||
h.1.getKeyGED_eq
|
||||
|
||||
theorem getGT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getGT? k = t₂.getGT? k :=
|
||||
h.1.getKeyGT?_eq
|
||||
|
||||
theorem getGT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getGT k h' = t₂.getGT k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getKeyGT_eq
|
||||
|
||||
theorem getGT!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getGT! k = t₂.getGT! k :=
|
||||
h.1.getKeyGT!_eq
|
||||
|
||||
theorem getGTD_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getGTD k fallback = t₂.getGTD k fallback :=
|
||||
h.1.getKeyGTD_eq
|
||||
|
||||
theorem getLE?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getLE? k = t₂.getLE? k :=
|
||||
h.1.getKeyLE?_eq
|
||||
|
||||
theorem getLE_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getLE k h' = t₂.getLE k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getKeyLE_eq
|
||||
|
||||
theorem getLE!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getLE! k = t₂.getLE! k :=
|
||||
h.1.getKeyLE!_eq
|
||||
|
||||
theorem getLED_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getLED k fallback = t₂.getLED k fallback :=
|
||||
h.1.getKeyLED_eq
|
||||
|
||||
theorem getLT?_eq [TransCmp cmp] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getLT? k = t₂.getLT? k :=
|
||||
h.1.getKeyLT?_eq
|
||||
|
||||
theorem getLT_eq [TransCmp cmp] {k : α} {h'} (h : t₁ ~m t₂) :
|
||||
t₁.getLT k h' = t₂.getLT k (h'.imp fun _ ⟨h₁, h₂⟩ => ⟨h.mem_iff.mp h₁, h₂⟩) :=
|
||||
h.1.getKeyLT_eq
|
||||
|
||||
theorem getLT!_eq [TransCmp cmp] [Inhabited α] {k : α} (h : t₁ ~m t₂) :
|
||||
t₁.getLT! k = t₂.getLT! k :=
|
||||
h.1.getKeyLT!_eq
|
||||
|
||||
theorem getLTD_eq [TransCmp cmp] {k fallback : α} (h : t₁ ~m t₂) :
|
||||
t₁.getLTD k fallback = t₂.getLTD k fallback :=
|
||||
h.1.getKeyLTD_eq
|
||||
|
||||
theorem insert [TransCmp cmp] (h : t₁ ~m t₂) (k : α) : t₁.insert k ~m t₂.insert k :=
|
||||
⟨h.1.insertIfNew k ()⟩
|
||||
|
||||
theorem erase [TransCmp cmp] (h : t₁ ~m t₂) (k : α) : t₁.erase k ~m t₂.erase k :=
|
||||
⟨h.1.erase k⟩
|
||||
|
||||
theorem filter (h : t₁ ~m t₂) (f : α → Bool) : t₁.filter f ~m t₂.filter f :=
|
||||
⟨h.1.filter _⟩
|
||||
|
||||
theorem insertMany_list [TransCmp cmp] (h : t₁ ~m t₂) (l : List α) :
|
||||
t₁.insertMany l ~m t₂.insertMany l :=
|
||||
⟨h.1.insertManyIfNewUnit_list l⟩
|
||||
|
||||
theorem eraseMany_list [TransCmp cmp] (h : t₁ ~m t₂) (l : List α) :
|
||||
t₁.eraseMany l ~m t₂.eraseMany l :=
|
||||
⟨h.1.eraseMany_list l⟩
|
||||
|
||||
theorem merge [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
(h : t₁ ~m t₂) (h' : t₃ ~m t₄) : t₁.merge t₃ ~m t₂.merge t₄ :=
|
||||
⟨h.1.mergeWith _ h'.1⟩
|
||||
|
||||
-- extensionalities
|
||||
|
||||
theorem of_forall_get?_eq [TransCmp cmp] (h : ∀ k, t₁.get? k = t₂.get? k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_getKey?_unit_eq h⟩
|
||||
|
||||
theorem of_forall_contains_eq [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
(h : ∀ k, t₁.contains k = t₂.contains k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_contains_unit_eq h⟩
|
||||
|
||||
theorem of_forall_mem_iff [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
(h : ∀ k, k ∈ t₁ ↔ k ∈ t₂) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_mem_unit_iff h⟩
|
||||
|
||||
end Equiv
|
||||
|
||||
section Equiv
|
||||
|
||||
variable {t₁ t₂ : TreeSet α cmp}
|
||||
|
||||
private theorem equiv_iff_equiv : t₁ ~m t₂ ↔ t₁.1.Equiv t₂.1 :=
|
||||
⟨fun ⟨h⟩ => h, fun h => ⟨h⟩⟩
|
||||
|
||||
theorem equiv_empty_iff_isEmpty : t ~m empty ↔ t.isEmpty :=
|
||||
equiv_iff_equiv.trans TreeMap.equiv_empty_iff_isEmpty
|
||||
|
||||
theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
|
||||
Equiv.comm.trans equiv_empty_iff_isEmpty
|
||||
|
||||
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList :=
|
||||
equiv_iff_equiv.trans TreeMap.equiv_iff_keys_unit_perm
|
||||
|
||||
theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ :=
|
||||
⟨.of_keys_unit_perm h⟩
|
||||
|
||||
theorem equiv_iff_toList_eq [TransCmp cmp] :
|
||||
t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
|
||||
equiv_iff_equiv.trans TreeMap.equiv_iff_keys_unit_eq
|
||||
|
||||
end Equiv
|
||||
|
||||
end Std.TreeSet
|
||||
|
|
|
|||
|
|
@ -88,6 +88,13 @@ instance : EmptyCollection (Raw α cmp) where
|
|||
instance : Inhabited (Raw α cmp) where
|
||||
default := ∅
|
||||
|
||||
/-- Two tree sets are equivalent in the sense of Equiv iff all the values are equal. -/
|
||||
structure Equiv (m₁ m₂ : Raw α cmp) where
|
||||
/-- Internal implementation detail of the tree map -/
|
||||
inner : m₁.1.Equiv m₂.1
|
||||
|
||||
@[inherit_doc] scoped infix:50 " ~m " => Equiv
|
||||
|
||||
@[simp]
|
||||
theorem empty_eq_emptyc : (empty : Raw α cmp) = ∅ :=
|
||||
rfl
|
||||
|
|
@ -298,7 +305,7 @@ def forIn (f : α → δ → m (ForInStep δ)) (init : δ) (t : Raw α cmp) : m
|
|||
instance : ForM m (Raw α cmp) α where
|
||||
forM t f := t.forM f
|
||||
|
||||
instance {t : Type w → Type w} : ForIn t (Raw α cmp) α where
|
||||
instance : ForIn m (Raw α cmp) α where
|
||||
forIn t init f := t.forIn (fun a acc => f a acc) init
|
||||
|
||||
@[inline, inherit_doc TreeSet.empty]
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ These proofs can be obtained from `Std.Data.TreeSet.Raw.WF`.
|
|||
set_option linter.missingDocs true
|
||||
set_option autoImplicit false
|
||||
|
||||
universe u v w
|
||||
universe u v w w'
|
||||
|
||||
namespace Std.TreeSet.Raw
|
||||
|
||||
|
|
@ -444,7 +444,7 @@ theorem ordered_toList [TransCmp cmp] (h : t.WF) :
|
|||
|
||||
section monadic
|
||||
|
||||
variable {δ : Type w} {m : Type w → Type w}
|
||||
variable {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
theorem foldlM_eq_foldlM_toList [Monad m] [LawfulMonad m]
|
||||
{f : δ → α → m δ} {init : δ} :
|
||||
|
|
@ -1317,4 +1317,254 @@ theorem maxD_eq_getLastD_toList [TransCmp cmp] (h : t.WF) {fallback} :
|
|||
|
||||
end Max
|
||||
|
||||
namespace Equiv
|
||||
|
||||
variable {t₁ t₂ t₃ t₄ : Raw α cmp} {δ : Type w} {m : Type w → Type w'}
|
||||
|
||||
@[refl, simp] theorem rfl : Equiv t t := ⟨.rfl⟩
|
||||
|
||||
@[symm] theorem symm : Equiv t₁ t₂ → Equiv t₂ t₁
|
||||
| ⟨h⟩ => ⟨h.symm⟩
|
||||
|
||||
theorem trans : Equiv t₁ t₂ → Equiv t₂ t₃ → Equiv t₁ t₃
|
||||
| ⟨h⟩, ⟨h'⟩ => ⟨h.trans h'⟩
|
||||
|
||||
instance instTrans : @Trans (Raw α cmp) _ _ Equiv Equiv Equiv := ⟨trans⟩
|
||||
|
||||
theorem comm : t₁ ~m t₂ ↔ t₂ ~m t₁ := ⟨symm, symm⟩
|
||||
theorem congr_left (h : t₁ ~m t₂) : t₁ ~m t₃ ↔ t₂ ~m t₃ := ⟨h.symm.trans, h.trans⟩
|
||||
theorem congr_right (h : t₁ ~m t₂) : t₃ ~m t₁ ↔ t₃ ~m t₂ :=
|
||||
⟨fun h' => h'.trans h, fun h' => h'.trans h.symm⟩
|
||||
|
||||
-- congruence lemmas
|
||||
|
||||
theorem isEmpty_eq (h : t₁ ~m t₂) : t₁.isEmpty = t₂.isEmpty :=
|
||||
h.1.isEmpty_eq
|
||||
|
||||
theorem contains_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.contains k = t₂.contains k :=
|
||||
h.1.contains_eq h₁.1 h₂.1
|
||||
|
||||
theorem mem_iff [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
k ∈ t₁ ↔ k ∈ t₂ :=
|
||||
h.1.mem_iff h₁.1 h₂.1
|
||||
|
||||
theorem size_eq (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.size = t₂.size :=
|
||||
h.1.size_eq h₁.1 h₂.1
|
||||
|
||||
theorem get?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.get? k = t₂.get? k :=
|
||||
h.1.getKey?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKey_eq [TransCmp cmp] {k : α} {hk : k ∈ t₁} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.get k hk = t₂.get k ((h.mem_iff h₁ h₂).mp hk) :=
|
||||
h.1.getKey_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKey!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.get! k = t₂.get! k :=
|
||||
h.1.getKey!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getKeyD_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getD k fallback = t₂.getD k fallback :=
|
||||
h.1.getKeyD_eq h₁.1 h₂.1
|
||||
|
||||
theorem toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) : t₁.toList = t₂.toList :=
|
||||
h.1.keys_eq h₁.1 h₂.1
|
||||
|
||||
theorem toArray_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.toArray = t₂.toArray :=
|
||||
h.1.keysArray_eq h₁.1 h₂.1
|
||||
|
||||
theorem foldlM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : δ → α → m δ}
|
||||
{init : δ} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.foldlM f init = t₂.foldlM f init :=
|
||||
h.1.foldlM_eq h₁.1 h₂.1
|
||||
|
||||
theorem foldl_eq [TransCmp cmp] {f : δ → α → δ} {init : δ} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) :
|
||||
t₁.foldl f init = t₂.foldl f init :=
|
||||
h.1.foldl_eq h₁.1 h₂.1
|
||||
|
||||
theorem foldrM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : α → δ → m δ}
|
||||
{init : δ} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.foldrM f init = t₂.foldrM f init :=
|
||||
h.1.foldrM_eq h₁.1 h₂.1
|
||||
|
||||
theorem foldr_eq [TransCmp cmp] {f : α → δ → δ} {init : δ} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) :
|
||||
t₁.foldr f init = t₂.foldr f init :=
|
||||
h.1.foldr_eq h₁.1 h₂.1
|
||||
|
||||
theorem forIn_eq [TransCmp cmp] [Monad m] [LawfulMonad m]
|
||||
{b : δ} {f : α → δ → m (ForInStep δ)} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
ForIn.forIn t₁ b f = ForIn.forIn t₂ b f :=
|
||||
h.1.forIn_eq h₁.1 h₂.1 (f := fun x => f x.1)
|
||||
|
||||
theorem forM_eq [TransCmp cmp] [Monad m] [LawfulMonad m] {f : α → m PUnit}
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
ForM.forM t₁ f = ForM.forM t₂ f :=
|
||||
h.1.forM_eq h₁.1 h₂.1 (f := fun x => f x.1)
|
||||
|
||||
theorem any_eq [TransCmp cmp] {p : α → Bool} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.any p = t₂.any p :=
|
||||
h.1.any_eq h₁.1 h₂.1
|
||||
|
||||
theorem all_eq [TransCmp cmp] {p : α → Bool} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.all p = t₂.all p :=
|
||||
h.1.all_eq h₁.1 h₂.1
|
||||
|
||||
theorem min?_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.min? = t₂.min? :=
|
||||
h.1.minKey?_eq h₁.1 h₂.1
|
||||
|
||||
theorem min!_eq [TransCmp cmp] [Inhabited α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.min! = t₂.min! :=
|
||||
h.1.minKey!_eq h₁.1 h₂.1
|
||||
|
||||
theorem minD_eq [TransCmp cmp] {fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.minD fallback = t₂.minD fallback :=
|
||||
h.1.minKeyD_eq h₁.1 h₂.1
|
||||
|
||||
theorem max?_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.max? = t₂.max? :=
|
||||
h.1.maxKey?_eq h₁.1 h₂.1
|
||||
|
||||
theorem max!_eq [TransCmp cmp] [Inhabited α] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.max! = t₂.max! :=
|
||||
h.1.maxKey!_eq h₁.1 h₂.1
|
||||
|
||||
theorem maxD_eq [TransCmp cmp] {fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.maxD fallback = t₂.maxD fallback :=
|
||||
h.1.maxKeyD_eq h₁.1 h₂.1
|
||||
|
||||
theorem atIdx?_eq [TransCmp cmp] {i : Nat} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.atIdx? i = t₂.atIdx? i :=
|
||||
h.1.keyAtIdx?_eq h₁.1 h₂.1
|
||||
|
||||
theorem atIdx!_eq [TransCmp cmp] [Inhabited α] {i : Nat} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.atIdx! i = t₂.atIdx! i :=
|
||||
h.1.keyAtIdx!_eq h₁.1 h₂.1
|
||||
|
||||
theorem atIdxD_eq [TransCmp cmp] {i : Nat} {fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : t₁ ~m t₂) : t₁.atIdxD i fallback = t₂.atIdxD i fallback :=
|
||||
h.1.keyAtIdxD_eq h₁.1 h₂.1
|
||||
|
||||
theorem getGE?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getGE? k = t₂.getGE? k :=
|
||||
h.1.getKeyGE?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getGE!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getGE! k = t₂.getGE! k :=
|
||||
h.1.getKeyGE!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getGED_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getGED k fallback = t₂.getGED k fallback :=
|
||||
h.1.getKeyGED_eq h₁.1 h₂.1
|
||||
|
||||
theorem getGT?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getGT? k = t₂.getGT? k :=
|
||||
h.1.getKeyGT?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getGT!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getGT! k = t₂.getGT! k :=
|
||||
h.1.getKeyGT!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getGTD_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getGTD k fallback = t₂.getGTD k fallback :=
|
||||
h.1.getKeyGTD_eq h₁.1 h₂.1
|
||||
|
||||
theorem getLE?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getLE? k = t₂.getLE? k :=
|
||||
h.1.getKeyLE?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getLE!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getLE! k = t₂.getLE! k :=
|
||||
h.1.getKeyLE!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getLED_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getLED k fallback = t₂.getLED k fallback :=
|
||||
h.1.getKeyLED_eq h₁.1 h₂.1
|
||||
|
||||
theorem getLT?_eq [TransCmp cmp] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getLT? k = t₂.getLT? k :=
|
||||
h.1.getKeyLT?_eq h₁.1 h₂.1
|
||||
|
||||
theorem getLT!_eq [TransCmp cmp] [Inhabited α] {k : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getLT! k = t₂.getLT! k :=
|
||||
h.1.getKeyLT!_eq h₁.1 h₂.1
|
||||
|
||||
theorem getLTD_eq [TransCmp cmp] {k fallback : α} (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) :
|
||||
t₁.getLTD k fallback = t₂.getLTD k fallback :=
|
||||
h.1.getKeyLTD_eq h₁.1 h₂.1
|
||||
|
||||
theorem insert [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (k : α) :
|
||||
t₁.insert k ~m t₂.insert k :=
|
||||
⟨h.1.insertIfNew h₁.1 h₂.1 k ()⟩
|
||||
|
||||
theorem erase [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (k : α) :
|
||||
t₁.erase k ~m t₂.erase k :=
|
||||
⟨h.1.erase h₁.1 h₂.1 k⟩
|
||||
|
||||
theorem filter (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (f : α → Bool) :
|
||||
t₁.filter f ~m t₂.filter f :=
|
||||
⟨h.1.filter h₁.1 h₂.1 _⟩
|
||||
|
||||
theorem insertMany_list [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂)
|
||||
(l : List α) : t₁.insertMany l ~m t₂.insertMany l :=
|
||||
⟨h.1.insertManyIfNewUnit_list h₁.1 h₂.1 l⟩
|
||||
|
||||
theorem eraseMany_list [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) (h : t₁ ~m t₂) (l : List α) :
|
||||
t₁.eraseMany l ~m t₂.eraseMany l :=
|
||||
⟨h.1.eraseMany_list h₁.1 h₂.1 l⟩
|
||||
|
||||
theorem merge [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h₃ : t₃.WF) (h₄ : t₄.WF)
|
||||
(h : t₁ ~m t₂) (h' : t₃ ~m t₄) :
|
||||
t₁.merge t₃ ~m t₂.merge t₄ :=
|
||||
⟨h.1.mergeWith h₁.1 h₂.1 h₃.1 h₄.1 _ h'.1⟩
|
||||
|
||||
-- extensionalities
|
||||
|
||||
theorem of_forall_get?_eq [TransCmp cmp]
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF) (h : ∀ k, t₁.get? k = t₂.get? k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_getKey?_unit_eq h₁.1 h₂.1 h⟩
|
||||
|
||||
theorem of_forall_contains_eq [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : ∀ k, t₁.contains k = t₂.contains k) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_contains_unit_eq h₁.1 h₂.1 h⟩
|
||||
|
||||
theorem of_forall_mem_iff [TransCmp cmp] [LawfulEqCmp cmp]
|
||||
(h₁ : t₁.WF) (h₂ : t₂.WF)
|
||||
(h : ∀ k, k ∈ t₁ ↔ k ∈ t₂) : t₁ ~m t₂ :=
|
||||
⟨.of_forall_mem_unit_iff h₁.1 h₂.1 h⟩
|
||||
|
||||
end Equiv
|
||||
|
||||
section Equiv
|
||||
|
||||
variable {t₁ t₂ : Raw α cmp}
|
||||
|
||||
private theorem equiv_iff : t₁ ~m t₂ ↔ t₁.1.Equiv t₂.1 :=
|
||||
⟨fun ⟨h⟩ => h, fun h => ⟨h⟩⟩
|
||||
|
||||
theorem equiv_empty_iff_isEmpty : t ~m empty ↔ t.isEmpty :=
|
||||
equiv_iff.trans TreeMap.Raw.equiv_empty_iff_isEmpty
|
||||
|
||||
theorem empty_equiv_iff_isEmpty : empty ~m t ↔ t.isEmpty :=
|
||||
equiv_iff.trans TreeMap.Raw.empty_equiv_iff_isEmpty
|
||||
|
||||
theorem equiv_iff_toList_perm : t₁ ~m t₂ ↔ t₁.toList.Perm t₂.toList :=
|
||||
equiv_iff.trans TreeMap.Raw.equiv_iff_keys_unit_perm
|
||||
|
||||
theorem Equiv.of_toList_perm (h : t₁.toList.Perm t₂.toList) : t₁ ~m t₂ :=
|
||||
⟨.of_keys_unit_perm h⟩
|
||||
|
||||
theorem equiv_iff_toList_eq [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) :
|
||||
t₁ ~m t₂ ↔ t₁.toList = t₂.toList :=
|
||||
equiv_iff.trans (TreeMap.Raw.equiv_iff_keys_unit_eq h₁.1 h₂.1)
|
||||
|
||||
end Equiv
|
||||
|
||||
end Std.TreeSet.Raw
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue