feat: add intersection on ExtDTreeMap/ExtTreeMap/ExtTreeSet (#11292)

This PR adds intersection operation on
`ExtDTreeMap`/`ExtTreeMap`/`ExtTreeSet` and proves several lemmas about
it.
This commit is contained in:
Wojciech Różowski 2025-11-21 11:25:58 +00:00 committed by GitHub
parent e7ece45e3c
commit 2e22c854cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 871 additions and 0 deletions

View file

@ -4147,6 +4147,57 @@ theorem contains_inter!_eq_false_of_contains_eq_false_right [TransOrd α]
apply contains_inter_eq_false_of_contains_eq_false_right h₁ h₂
all_goals wf_trivial
/- Equiv -/
theorem Equiv.inter_left {m₃ : Impl α β} [TransOrd α]
(h₁ : m₁.WF) (h₂ : m₂.WF) (h₃ : m₃.WF) (equiv : m₁.Equiv m₂) :
(m₁.inter m₃ h₁.balanced).Equiv (m₂.inter m₃ h₂.balanced) := by
revert equiv
simp_to_model [Equiv, inter]
intro equiv
apply List.Perm.filter
wf_trivial
theorem Equiv.inter!_left {m₃ : Impl α β} [TransOrd α]
(h₁ : m₁.WF) (h₂ : m₂.WF) (h₃ : m₃.WF) (equiv : m₁.Equiv m₂) :
(m₁.inter! m₃).Equiv (m₂.inter! m₃) := by
rw [← inter_eq_inter!, ← inter_eq_inter!]
apply Equiv.inter_left
all_goals wf_trivial
theorem Equiv.inter_right {m₃ : Impl α β} [TransOrd α]
(h₁ : m₁.WF) (h₂ : m₂.WF) (h₃ : m₃.WF) (equiv : m₂.Equiv m₃) :
(m₁.inter m₂ h₁.balanced).Equiv (m₁.inter m₃ h₁.balanced) := by
revert equiv
simp_to_model [Equiv, inter]
intro equiv
apply List.perm_filter_containsKey_of_perm equiv
all_goals wf_trivial
theorem Equiv.inter!_right {m₃ : Impl α β} [TransOrd α]
(h₁ : m₁.WF) (h₂ : m₂.WF) (h₃ : m₃.WF) (equiv : m₂.Equiv m₃) :
(m₁.inter! m₂).Equiv (m₁.inter! m₃) := by
rw [← inter_eq_inter!, ← inter_eq_inter!]
apply Equiv.inter_right
all_goals wf_trivial
theorem Equiv.inter_congr {m₃ m₄ : Impl α β} [TransOrd α]
(h₁ : m₁.WF) (h₂ : m₂.WF) (h₃ : m₃.WF) (h₄ : m₄.WF)
(equiv₁ : m₁.Equiv m₃) (equiv₂ : m₂.Equiv m₄) :
(m₁.inter m₂ h₁.balanced).Equiv (m₃.inter m₄ h₃.balanced) := by
revert equiv₁ equiv₂
simp_to_model [Equiv, inter]
intro equiv₁ equiv₂
apply List.congr_filter_containsKey_of_perm
all_goals wf_trivial
theorem Equiv.inter!_congr {m₃ m₄ : Impl α β} [TransOrd α]
(h₁ : m₁.WF) (h₂ : m₂.WF) (h₃ : m₃.WF) (h₄ : m₄.WF)
(equiv₁ : m₁.Equiv m₃) (equiv₂ : m₂.Equiv m₄) :
(m₁.inter! m₂).Equiv (m₃.inter! m₄) := by
rw [← inter_eq_inter!, ← inter_eq_inter!]
apply Equiv.inter_congr
all_goals wf_trivial
/- get? -/
theorem get?_inter [TransOrd α] [LawfulEqOrd α] (h₁ : m₁.WF) (h₂ : m₂.WF) {k : α} :
(m₁.inter m₂ h₁.balanced).get? k =

View file

@ -2567,6 +2567,22 @@ theorem not_mem_inter_of_not_mem_right [TransCmp cmp]
rw [← contains_eq_false_iff_not_mem] at h ⊢
exact Impl.contains_inter_eq_false_of_contains_eq_false_right t₁.wf t₂.wf h
/- Equiv -/
theorem Equiv.inter_left {t₃ : DTreeMap α β cmp} [TransCmp cmp]
(equiv : t₁ ~m t₂) :
(t₁ ∩ t₃).Equiv (t₂ ∩ t₃) :=
⟨Impl.Equiv.inter_left t₁.wf t₂.wf t₃.wf equiv.1⟩
theorem Equiv.inter_right {t₃ : DTreeMap α β cmp} [TransCmp cmp]
(equiv : t₂ ~m t₃) :
(t₁ ∩ t₂).Equiv (t₁ ∩ t₃) :=
⟨Impl.Equiv.inter_right t₁.wf t₂.wf t₃.wf equiv.1⟩
theorem Equiv.inter_congr {t₃ t₄ : DTreeMap α β cmp} [TransCmp cmp]
(equiv₁ : t₁ ~m t₃) (equiv₂ : t₂ ~m t₄) :
(t₁ ∩ t₂).Equiv (t₃ ∩ t₄) :=
⟨Impl.Equiv.inter_congr t₁.wf t₂.wf t₃.wf t₄.wf equiv₁.1 equiv₂.1⟩
/- get? -/
theorem get?_inter [TransCmp cmp] [LawfulEqCmp cmp] {k : α} :
(t₁ ∩ t₂).get? k =

View file

@ -2691,6 +2691,25 @@ theorem not_mem_inter_of_not_mem_right [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t
simp only [Inter.inter]
exact Impl.contains_inter!_eq_false_of_contains_eq_false_right h₁ h₂ h
theorem Equiv.inter_left [TransCmp cmp] {t₃ : Raw α β cmp}
(h₁ : t₁.WF) (h₂ : t₂.WF) (h₃ : t₃.WF) (equiv : t₁ ~m t₂) :
(t₁ ∩ t₃).Equiv (t₂ ∩ t₃) := by
simp only [Inter.inter]
exact ⟨@Impl.Equiv.inter!_left _ _ ⟨cmp⟩ t₁.inner t₂.inner t₃.inner _ h₁.out h₂.out h₃.out equiv.1⟩
theorem Equiv.inter_right [TransCmp cmp] {t₃ : Raw α β cmp}
(h₁ : t₁.WF) (h₂ : t₂.WF) (h₃ : t₃.WF) (equiv : t₂ ~m t₃) :
(t₁ ∩ t₂).Equiv (t₁ ∩ t₃) := by
simp only [Inter.inter]
exact ⟨@Impl.Equiv.inter!_right _ _ ⟨cmp⟩ t₁.inner t₂.inner t₃.inner _ h₁.out h₂.out h₃.out equiv.1⟩
theorem Equiv.inter_congr [TransCmp cmp] {t₃ t₄ : Raw α β cmp}
(h₁ : t₁.WF) (h₂ : t₂.WF) (h₃ : t₃.WF) (h₄ : t₄.WF)
(equiv₁ : t₁ ~m t₃) (equiv₂ : t₂ ~m t₄) :
(t₁ ∩ t₂).Equiv (t₃ ∩ t₄) := by
simp only [Inter.inter]
exact ⟨@Impl.Equiv.inter!_congr _ _ ⟨cmp⟩ t₁.inner t₂.inner t₃.inner t₄.inner _ h₁.out h₂.out h₃.out h₄.out equiv₁.1 equiv₂.1⟩
/- get? -/
theorem get?_inter [TransCmp cmp] [LawfulEqCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF)
{k : α} :

View file

@ -918,6 +918,17 @@ def union [TransCmp cmp] (m₁ m₂ : ExtDTreeMap α β cmp) : ExtDTreeMap α β
instance [TransCmp cmp] : Union (ExtDTreeMap α β cmp) := ⟨union⟩
@[inline, inherit_doc DTreeMap.union]
def inter [TransCmp cmp] (m₁ m₂ : ExtDTreeMap α β cmp) : ExtDTreeMap α β cmp := lift₂ (fun x y : DTreeMap α β cmp => mk (x.inter y))
(fun a b c d equiv₁ equiv₂ => by
simp only [DTreeMap.inter_eq, mk'.injEq]
apply Quotient.sound
apply DTreeMap.Equiv.inter_congr
. exact equiv₁
. exact equiv₂) m₁ m₂
instance [TransCmp cmp] : Inter (ExtDTreeMap α β cmp) := ⟨inter⟩
instance [TransCmp cmp] [Repr α] [(a : α) → Repr (β a)] : Repr (ExtDTreeMap α β cmp) where
reprPrec m prec := Repr.addAppParen ("Std.ExtDTreeMap.ofList " ++ repr m.toList) prec

View file

@ -2642,6 +2642,341 @@ theorem get!_union_of_not_mem_right [TransCmp cmp] [Inhabited β]
end Const
section Inter
variable {t₁ t₂ : ExtDTreeMap α β cmp}
@[simp]
theorem inter_eq [TransCmp cmp] : t₁.inter t₂ = t₁ ∩ t₂ := by
simp only [Inter.inter]
/- contains -/
@[simp]
theorem contains_inter [TransCmp cmp] {k : α} :
(t₁ ∩ t₂).contains k = (t₁.contains k && t₂.contains k) :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.contains_inter
/- mem -/
@[simp]
theorem mem_inter_iff [TransCmp cmp] {k : α} :
k ∈ t₁ ∩ t₂ ↔ k ∈ t₁ ∧ k ∈ t₂ :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.mem_inter_iff
theorem not_mem_inter_of_not_mem_left [TransCmp cmp]
{k : α} (h : ¬k ∈ t₁) :
¬k ∈ t₁ ∩ t₂ := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.not_mem_inter_of_not_mem_left h
theorem not_mem_inter_of_not_mem_right [TransCmp cmp]
{k : α} (h : ¬k ∈ t₂) :
¬k ∈ t₁ ∩ t₂ := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.not_mem_inter_of_not_mem_right h
/- get? -/
theorem get?_inter [TransCmp cmp] [LawfulEqCmp cmp] {k : α} :
(t₁ ∩ t₂).get? k =
if k ∈ t₂ then t₁.get? k else none :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.get?_inter
theorem get?_inter_of_mem_right [TransCmp cmp] [LawfulEqCmp cmp]
{k : α} (h : k ∈ t₂) :
(t₁ ∩ t₂).get? k = t₁.get? k := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.get?_inter_of_mem_right h
theorem get?_inter_of_not_mem_left [TransCmp cmp] [LawfulEqCmp cmp]
{k : α} (h : ¬k ∈ t₁) :
(t₁ ∩ t₂).get? k = none := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.get?_inter_of_not_mem_left h
theorem get?_inter_of_not_mem_right [TransCmp cmp] [LawfulEqCmp cmp]
{k : α} (h : ¬k ∈ t₂) :
(t₁ ∩ t₂).get? k = none := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.get?_inter_of_not_mem_right h
/- get -/
@[simp]
theorem get_inter [TransCmp cmp] [LawfulEqCmp cmp]
{k : α} {h_mem : k ∈ t₁ ∩ t₂} :
(t₁ ∩ t₂).get k h_mem =
t₁.get k (mem_inter_iff.1 h_mem).1 := by
induction t₁ with
| mk a =>
induction t₂ with
| mk b =>
apply DTreeMap.get_inter
/- getD -/
theorem getD_inter [TransCmp cmp] [LawfulEqCmp cmp]
{k : α} {fallback : β k} :
(t₁ ∩ t₂).getD k fallback =
if k ∈ t₂ then t₁.getD k fallback else fallback :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.getD_inter
theorem getD_inter_of_mem_right [TransCmp cmp] [LawfulEqCmp cmp]
{k : α} {fallback : β k} (h : k ∈ t₂) :
(t₁ ∩ t₂).getD k fallback = t₁.getD k fallback := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.getD_inter_of_mem_right h
theorem getD_inter_of_not_mem_right [TransCmp cmp] [LawfulEqCmp cmp]
{k : α} {fallback : β k} (h : ¬k ∈ t₂) :
(t₁ ∩ t₂).getD k fallback = fallback := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.getD_inter_of_not_mem_right h
theorem getD_inter_of_not_mem_left [TransCmp cmp] [LawfulEqCmp cmp]
{k : α} {fallback : β k} (h : ¬k ∈ t₁) :
(t₁ ∩ t₂).getD k fallback = fallback := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.getD_inter_of_not_mem_left h
/- get! -/
theorem get!_inter [TransCmp cmp] [LawfulEqCmp cmp]
{k : α} [Inhabited (β k)] :
(t₁ ∩ t₂).get! k =
if k ∈ t₂ then t₁.get! k else default :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.get!_inter
theorem get!_inter_of_mem_right [TransCmp cmp] [LawfulEqCmp cmp]
{k : α} [Inhabited (β k)] (h : k ∈ t₂) :
(t₁ ∩ t₂).get! k = t₁.get! k := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.get!_inter_of_mem_right h
theorem get!_inter_of_not_mem_right [TransCmp cmp] [LawfulEqCmp cmp]
{k : α} [Inhabited (β k)] (h : ¬k ∈ t₂) :
(t₁ ∩ t₂).get! k = default := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.get!_inter_of_not_mem_right h
theorem get!_inter_of_not_mem_left [TransCmp cmp] [LawfulEqCmp cmp]
{k : α} [Inhabited (β k)] (h : ¬k ∈ t₁) :
(t₁ ∩ t₂).get! k = default := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.get!_inter_of_not_mem_left h
/- getKey? -/
theorem getKey?_inter [TransCmp cmp] {k : α} :
(t₁ ∩ t₂).getKey? k =
if k ∈ t₂ then t₁.getKey? k else none :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.getKey?_inter
theorem getKey?_inter_of_mem_right [TransCmp cmp]
{k : α} (h : k ∈ t₂) :
(t₁ ∩ t₂).getKey? k = t₁.getKey? k := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.getKey?_inter_of_mem_right h
theorem getKey?_inter_of_not_mem_right [TransCmp cmp]
{k : α} (h : ¬k ∈ t₂) :
(t₁ ∩ t₂).getKey? k = none := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.getKey?_inter_of_not_mem_right h
theorem getKey?_inter_of_not_mem_left [TransCmp cmp]
{k : α} (h : ¬k ∈ t₁) :
(t₁ ∩ t₂).getKey? k = none := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.getKey?_inter_of_not_mem_left h
/- getKey -/
@[simp]
theorem getKey_inter [TransCmp cmp]
{k : α} {h_mem : k ∈ t₁ ∩ t₂} :
(t₁ ∩ t₂).getKey k h_mem =
t₁.getKey k (mem_inter_iff.1 h_mem).1 := by
induction t₁ with
| mk a =>
induction t₂ with
| mk b =>
apply DTreeMap.getKey_inter
/- getKeyD -/
theorem getKeyD_inter [TransCmp cmp] {k fallback : α} :
(t₁ ∩ t₂).getKeyD k fallback =
if k ∈ t₂ then t₁.getKeyD k fallback else fallback :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.getKeyD_inter
theorem getKeyD_inter_of_mem_right [TransCmp cmp] {k fallback : α} (h : k ∈ t₂) :
(t₁ ∩ t₂).getKeyD k fallback = t₁.getKeyD k fallback := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.getKeyD_inter_of_mem_right h
theorem getKeyD_inter_of_not_mem_right [TransCmp cmp] {k fallback : α} (h : ¬k ∈ t₂) :
(t₁ ∩ t₂).getKeyD k fallback = fallback := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.getKeyD_inter_of_not_mem_right h
theorem getKeyD_inter_of_not_mem_left [TransCmp cmp] {k fallback : α} (h : ¬k ∈ t₁) :
(t₁ ∩ t₂).getKeyD k fallback = fallback := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.getKeyD_inter_of_not_mem_left h
/- getKey! -/
theorem getKey!_inter [Inhabited α] [TransCmp cmp] {k : α} :
(t₁ ∩ t₂).getKey! k =
if k ∈ t₂ then t₁.getKey! k else default :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.getKey!_inter
theorem getKey!_inter_of_mem_right [Inhabited α] [TransCmp cmp]
{k : α} (h : k ∈ t₂) :
(t₁ ∩ t₂).getKey! k = t₁.getKey! k := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.getKey!_inter_of_mem_right h
theorem getKey!_inter_of_not_mem_right [Inhabited α] [TransCmp cmp]
{k : α} (h : ¬k ∈ t₂) :
(t₁ ∩ t₂).getKey! k = default := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.getKey!_inter_of_not_mem_right h
theorem getKey!_inter_of_not_mem_left [Inhabited α] [TransCmp cmp]
{k : α} (h : ¬k ∈ t₁) :
(t₁ ∩ t₂).getKey! k = default := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.getKey!_inter_of_not_mem_left h
/- size -/
theorem size_inter_le_size_left [TransCmp cmp] :
(t₁ ∩ t₂).size ≤ t₁.size :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.size_inter_le_size_left
theorem size_inter_le_size_right [TransCmp cmp] :
(t₁ ∩ t₂).size ≤ t₂.size :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.size_inter_le_size_right
theorem size_inter_eq_size_left [TransCmp cmp]
(h : ∀ (a : α), a ∈ t₁ → a ∈ t₂) :
(t₁ ∩ t₂).size = t₁.size := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.size_inter_eq_size_left h
theorem size_inter_eq_size_right [TransCmp cmp]
(h : ∀ (a : α), a ∈ t₂ → a ∈ t₁) :
(t₁ ∩ t₂).size = t₂.size := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.size_inter_eq_size_right h
theorem size_add_size_eq_size_union_add_size_inter [TransCmp cmp] :
t₁.size + t₂.size = (t₁ t₂).size + (t₁ ∩ t₂).size :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.size_add_size_eq_size_union_add_size_inter
/- isEmpty -/
@[simp]
theorem isEmpty_inter_left [TransCmp cmp] (h : t₁.isEmpty) :
(t₁ ∩ t₂).isEmpty = true := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.isEmpty_inter_left h
@[simp]
theorem isEmpty_inter_right [TransCmp cmp] (h : t₂.isEmpty) :
(t₁ ∩ t₂).isEmpty = true := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.isEmpty_inter_right h
theorem isEmpty_inter_iff [TransCmp cmp] :
(t₁ ∩ t₂).isEmpty ↔ ∀ k, k ∈ t₁ → ¬k ∈ t₂ :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.isEmpty_inter_iff
end Inter
namespace Const
variable {β : Type v} {t₁ t₂ : ExtDTreeMap α (fun _ => β) cmp}
/- get? -/
theorem get?_inter [TransCmp cmp] {k : α} :
Const.get? (t₁ ∩ t₂) k =
if k ∈ t₂ then Const.get? t₁ k else none :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.Const.get?_inter
theorem get?_inter_of_mem_right [TransCmp cmp]
{k : α} (h : k ∈ t₂) :
Const.get? (t₁ ∩ t₂) k = Const.get? t₁ k := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.Const.get?_inter_of_mem_right h
theorem get?_inter_of_not_mem_left [TransCmp cmp]
{k : α} (h : ¬k ∈ t₁) :
Const.get? (t₁ ∩ t₂) k = none := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.Const.get?_inter_of_not_mem_left h
theorem get?_inter_of_not_mem_right [TransCmp cmp]
{k : α} (h : ¬k ∈ t₂) :
Const.get? (t₁ ∩ t₂) k = none := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.Const.get?_inter_of_not_mem_right h
/- get -/
@[simp]
theorem get_inter [TransCmp cmp]
{k : α} {h_mem : k ∈ t₁ ∩ t₂} :
Const.get (t₁ ∩ t₂) k h_mem =
Const.get t₁ k (mem_inter_iff.1 h_mem).1 := by
induction t₁ with
| mk a =>
induction t₂ with
| mk b =>
apply DTreeMap.Const.get_inter
/- getD -/
theorem getD_inter [TransCmp cmp]
{k : α} {fallback : β} :
Const.getD (t₁ ∩ t₂) k fallback =
if k ∈ t₂ then Const.getD t₁ k fallback else fallback :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.Const.getD_inter
theorem getD_inter_of_mem_right [TransCmp cmp]
{k : α} {fallback : β} (h : k ∈ t₂) :
Const.getD (t₁ ∩ t₂) k fallback = Const.getD t₁ k fallback := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.Const.getD_inter_of_mem_right h
theorem getD_inter_of_not_mem_right [TransCmp cmp]
{k : α} {fallback : β} (h : ¬k ∈ t₂) :
Const.getD (t₁ ∩ t₂) k fallback = fallback := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.Const.getD_inter_of_not_mem_right h
theorem getD_inter_of_not_mem_left [TransCmp cmp]
{k : α} {fallback : β} (h : ¬k ∈ t₁) :
Const.getD (t₁ ∩ t₂) k fallback = fallback := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.Const.getD_inter_of_not_mem_left h
/- get! -/
theorem get!_inter [TransCmp cmp] [Inhabited β]
{k : α} :
Const.get! (t₁ ∩ t₂) k =
if k ∈ t₂ then Const.get! t₁ k else default :=
t₁.inductionOn₂ t₂ fun _ _ => DTreeMap.Const.get!_inter
theorem get!_inter_of_mem_right [TransCmp cmp] [Inhabited β]
{k : α} (h : k ∈ t₂) :
Const.get! (t₁ ∩ t₂) k = Const.get! t₁ k := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.Const.get!_inter_of_mem_right h
theorem get!_inter_of_not_mem_right [TransCmp cmp] [Inhabited β]
{k : α} (h : ¬k ∈ t₂) :
Const.get! (t₁ ∩ t₂) k = default := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.Const.get!_inter_of_not_mem_right h
theorem get!_inter_of_not_mem_left [TransCmp cmp] [Inhabited β]
{k : α} (h : ¬k ∈ t₁) :
Const.get! (t₁ ∩ t₂) k = default := by
revert h
exact t₁.inductionOn₂ t₂ fun _ _ h => DTreeMap.Const.get!_inter_of_not_mem_left h
end Const
section Alter
theorem alter_eq_empty_iff_erase_eq_empty [TransCmp cmp] [LawfulEqCmp cmp] {k : α}

View file

@ -535,6 +535,10 @@ def union [TransCmp cmp] (t₁ t₂ : ExtTreeMap α β cmp) : ExtTreeMap α β c
instance [TransCmp cmp] : Union (ExtTreeMap α β cmp) := ⟨union⟩
@[inline, inherit_doc ExtDTreeMap.inter]
def inter [TransCmp cmp] (t₁ t₂ : ExtTreeMap α β cmp) : ExtTreeMap α β cmp := ⟨ExtDTreeMap.inter t₁.inner t₂.inner⟩
instance [TransCmp cmp] : Inter (ExtTreeMap α β cmp) := ⟨inter⟩
@[inline, inherit_doc ExtDTreeMap.eraseMany]
def eraseMany [TransCmp cmp] {ρ} [ForIn Id ρ α] (t : ExtTreeMap α β cmp) (l : ρ) : ExtTreeMap α β cmp :=

View file

@ -1690,6 +1690,218 @@ theorem isEmpty_union [TransCmp cmp] :
end Union
section Inter
variable {t₁ t₂ : ExtTreeMap α β cmp}
@[simp]
theorem inter_eq [TransCmp cmp] : t₁.inter t₂ = t₁ ∩ t₂ := by
simp only [Inter.inter]
/- contains -/
@[simp]
theorem contains_inter [TransCmp cmp] {k : α} :
(t₁ ∩ t₂).contains k = (t₁.contains k && t₂.contains k) :=
ExtDTreeMap.contains_inter
/- mem -/
@[simp]
theorem mem_inter_iff [TransCmp cmp] {k : α} :
k ∈ t₁ ∩ t₂ ↔ k ∈ t₁ ∧ k ∈ t₂ :=
ExtDTreeMap.mem_inter_iff
theorem not_mem_inter_of_not_mem_left [TransCmp cmp] {k : α}
(not_mem : k ∉ t₁) :
k ∉ t₁ ∩ t₂ :=
ExtDTreeMap.not_mem_inter_of_not_mem_left not_mem
theorem not_mem_inter_of_not_mem_right [TransCmp cmp] {k : α}
(not_mem : k ∉ t₂) :
k ∉ t₁ ∩ t₂ :=
ExtDTreeMap.not_mem_inter_of_not_mem_right not_mem
/- get? -/
theorem get?_inter [TransCmp cmp] {k : α} :
(t₁ ∩ t₂).get? k =
if k ∈ t₂ then t₁.get? k else none :=
ExtDTreeMap.Const.get?_inter
theorem get?_inter_of_mem_right [TransCmp cmp]
{k : α} (mem : k ∈ t₂) :
(t₁ ∩ t₂).get? k = t₁.get? k :=
ExtDTreeMap.Const.get?_inter_of_mem_right mem
theorem get?_inter_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).get? k = none :=
ExtDTreeMap.Const.get?_inter_of_not_mem_left not_mem
theorem get?_inter_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).get? k = none :=
ExtDTreeMap.Const.get?_inter_of_not_mem_right not_mem
/- get -/
@[simp]
theorem get_inter [TransCmp cmp]
{k : α} {h_mem : k ∈ t₁ ∩ t₂} :
(t₁ ∩ t₂).get k h_mem =
t₁.get k (mem_inter_iff.1 h_mem).1 :=
ExtDTreeMap.Const.get_inter
/- getD -/
theorem getD_inter [TransCmp cmp] {k : α} {fallback : β} :
(t₁ ∩ t₂).getD k fallback =
if k ∈ t₂ then t₁.getD k fallback else fallback :=
ExtDTreeMap.Const.getD_inter
theorem getD_inter_of_mem_right [TransCmp cmp]
{k : α} {fallback : β} (mem : k ∈ t₂) :
(t₁ ∩ t₂).getD k fallback = t₁.getD k fallback :=
ExtDTreeMap.Const.getD_inter_of_mem_right mem
theorem getD_inter_of_not_mem_right [TransCmp cmp]
{k : α} {fallback : β} (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).getD k fallback = fallback :=
ExtDTreeMap.Const.getD_inter_of_not_mem_right not_mem
theorem getD_inter_of_not_mem_left [TransCmp cmp]
{k : α} {fallback : β} (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).getD k fallback = fallback :=
ExtDTreeMap.Const.getD_inter_of_not_mem_left not_mem
/- get! -/
theorem get!_inter [TransCmp cmp] {k : α} [Inhabited β] :
(t₁ ∩ t₂).get! k =
if k ∈ t₂ then t₁.get! k else default :=
ExtDTreeMap.Const.get!_inter
theorem get!_inter_of_mem_right [TransCmp cmp]
{k : α} [Inhabited β] (mem : k ∈ t₂) :
(t₁ ∩ t₂).get! k = t₁.get! k :=
ExtDTreeMap.Const.get!_inter_of_mem_right mem
theorem get!_inter_of_not_mem_right [TransCmp cmp]
{k : α} [Inhabited β] (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).get! k = default :=
ExtDTreeMap.Const.get!_inter_of_not_mem_right not_mem
theorem get!_inter_of_not_mem_left [TransCmp cmp]
{k : α} [Inhabited β] (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).get! k = default :=
ExtDTreeMap.Const.get!_inter_of_not_mem_left not_mem
/- getKey? -/
theorem getKey?_inter [TransCmp cmp] {k : α} :
(t₁ ∩ t₂).getKey? k =
if k ∈ t₂ then t₁.getKey? k else none :=
ExtDTreeMap.getKey?_inter
theorem getKey?_inter_of_mem_right [TransCmp cmp]
{k : α} (mem : k ∈ t₂) :
(t₁ ∩ t₂).getKey? k = t₁.getKey? k :=
ExtDTreeMap.getKey?_inter_of_mem_right mem
theorem getKey?_inter_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).getKey? k = none :=
ExtDTreeMap.getKey?_inter_of_not_mem_right not_mem
theorem getKey?_inter_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).getKey? k = none :=
ExtDTreeMap.getKey?_inter_of_not_mem_left not_mem
/- getKey -/
@[simp]
theorem getKey_inter [TransCmp cmp]
{k : α} {h_mem : k ∈ t₁ ∩ t₂} :
(t₁ ∩ t₂).getKey k h_mem =
t₁.getKey k (mem_inter_iff.1 h_mem).1 :=
ExtDTreeMap.getKey_inter
/- getKeyD -/
theorem getKeyD_inter [TransCmp cmp] {k fallback : α} :
(t₁ ∩ t₂).getKeyD k fallback =
if k ∈ t₂ then t₁.getKeyD k fallback else fallback :=
ExtDTreeMap.getKeyD_inter
theorem getKeyD_inter_of_mem_right [TransCmp cmp]
{k fallback : α} (mem : k ∈ t₂) :
(t₁ ∩ t₂).getKeyD k fallback = t₁.getKeyD k fallback :=
ExtDTreeMap.getKeyD_inter_of_mem_right mem
theorem getKeyD_inter_of_not_mem_right [TransCmp cmp]
{k fallback : α} (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).getKeyD k fallback = fallback :=
ExtDTreeMap.getKeyD_inter_of_not_mem_right not_mem
theorem getKeyD_inter_of_not_mem_left [TransCmp cmp]
{k fallback : α} (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).getKeyD k fallback = fallback :=
ExtDTreeMap.getKeyD_inter_of_not_mem_left not_mem
/- getKey! -/
theorem getKey!_inter [TransCmp cmp] [Inhabited α] {k : α} :
(t₁ ∩ t₂).getKey! k =
if k ∈ t₂ then t₁.getKey! k else default :=
ExtDTreeMap.getKey!_inter
theorem getKey!_inter_of_mem_right [TransCmp cmp] [Inhabited α]
{k : α} (mem : k ∈ t₂) :
(t₁ ∩ t₂).getKey! k = t₁.getKey! k :=
ExtDTreeMap.getKey!_inter_of_mem_right mem
theorem getKey!_inter_of_not_mem_right [TransCmp cmp] [Inhabited α]
{k : α} (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).getKey! k = default :=
ExtDTreeMap.getKey!_inter_of_not_mem_right not_mem
theorem getKey!_inter_of_not_mem_left [TransCmp cmp] [Inhabited α]
{k : α} (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).getKey! k = default :=
ExtDTreeMap.getKey!_inter_of_not_mem_left not_mem
/- size -/
theorem size_inter_le_size_left [TransCmp cmp] :
(t₁ ∩ t₂).size ≤ t₁.size :=
ExtDTreeMap.size_inter_le_size_left
theorem size_inter_le_size_right [TransCmp cmp] :
(t₁ ∩ t₂).size ≤ t₂.size :=
ExtDTreeMap.size_inter_le_size_right
theorem size_inter_eq_size_left [TransCmp cmp]
(h : ∀ (a : α), a ∈ t₁ → a ∈ t₂) :
(t₁ ∩ t₂).size = t₁.size :=
ExtDTreeMap.size_inter_eq_size_left h
theorem size_inter_eq_size_right [TransCmp cmp]
(h : ∀ (a : α), a ∈ t₂ → a ∈ t₁) :
(t₁ ∩ t₂).size = t₂.size :=
ExtDTreeMap.size_inter_eq_size_right h
theorem size_add_size_eq_size_union_add_size_inter [TransCmp cmp] :
t₁.size + t₂.size = (t₁ t₂).size + (t₁ ∩ t₂).size :=
ExtDTreeMap.size_add_size_eq_size_union_add_size_inter
/- isEmpty -/
@[simp]
theorem isEmpty_inter_left [TransCmp cmp] (h : t₁.isEmpty) :
(t₁ ∩ t₂).isEmpty = true :=
ExtDTreeMap.isEmpty_inter_left h
@[simp]
theorem isEmpty_inter_right [TransCmp cmp] (h : t₂.isEmpty) :
(t₁ ∩ t₂).isEmpty = true :=
ExtDTreeMap.isEmpty_inter_right h
theorem isEmpty_inter_iff [TransCmp cmp] :
(t₁ ∩ t₂).isEmpty ↔ ∀ k, k ∈ t₁ → k ∉ t₂ :=
ExtDTreeMap.isEmpty_inter_iff
end Inter
section Alter
theorem alter_eq_empty_iff_erase_eq_empty [TransCmp cmp] {k : α}

View file

@ -523,6 +523,17 @@ def union [TransCmp cmp] (t₁ t₂ : ExtTreeSet α cmp) : ExtTreeSet α cmp :=
instance [TransCmp cmp] : Union (ExtTreeSet α cmp) := ⟨union⟩
/--
Computes the intersection of the given tree sets.
This function always iterates through the smaller set.
-/
@[inline]
def inter [TransCmp cmp] (t₁ t₂ : ExtTreeSet α cmp) : ExtTreeSet α cmp := ⟨ExtTreeMap.inter t₁.inner t₂.inner⟩
instance [TransCmp cmp] : Inter (ExtTreeSet α cmp) := ⟨inter⟩
/--
Erases multiple items from the tree set by iterating over the given collection and calling erase.
-/

View file

@ -574,6 +574,146 @@ theorem isEmpty_union [TransCmp cmp] :
end Union
section Inter
variable {t₁ t₂ : ExtTreeSet α cmp}
@[simp]
theorem inter_eq [TransCmp cmp] : t₁.inter t₂ = t₁ ∩ t₂ := by
simp only [Inter.inter]
/- contains -/
@[simp]
theorem contains_inter [TransCmp cmp] {k : α} :
(t₁ ∩ t₂).contains k = (t₁.contains k && t₂.contains k) :=
ExtTreeMap.contains_inter
/- mem -/
@[simp]
theorem mem_inter_iff [TransCmp cmp] {k : α} :
k ∈ t₁ ∩ t₂ ↔ k ∈ t₁ ∧ k ∈ t₂ :=
ExtTreeMap.mem_inter_iff
theorem not_mem_inter_of_not_mem_left [TransCmp cmp] {k : α}
(not_mem : k ∉ t₁) :
k ∉ t₁ ∩ t₂ :=
ExtTreeMap.not_mem_inter_of_not_mem_left not_mem
theorem not_mem_inter_of_not_mem_right [TransCmp cmp] {k : α}
(not_mem : k ∉ t₂) :
k ∉ t₁ ∩ t₂ :=
ExtTreeMap.not_mem_inter_of_not_mem_right not_mem
/- get? -/
theorem get?_inter [TransCmp cmp] {k : α} :
(t₁ ∩ t₂).get? k =
if k ∈ t₂ then t₁.get? k else none :=
ExtTreeMap.getKey?_inter
theorem get?_inter_of_mem_right [TransCmp cmp]
{k : α} (mem : k ∈ t₂) :
(t₁ ∩ t₂).get? k = t₁.get? k :=
ExtTreeMap.getKey?_inter_of_mem_right mem
theorem get?_inter_of_not_mem_left [TransCmp cmp]
{k : α} (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).get? k = none :=
ExtTreeMap.getKey?_inter_of_not_mem_left not_mem
theorem get?_inter_of_not_mem_right [TransCmp cmp]
{k : α} (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).get? k = none :=
ExtTreeMap.getKey?_inter_of_not_mem_right not_mem
/- get -/
@[simp]
theorem get_inter [TransCmp cmp]
{k : α} {h_mem : k ∈ t₁ ∩ t₂} :
(t₁ ∩ t₂).get k h_mem =
t₁.get k (mem_inter_iff.1 h_mem).1 :=
ExtTreeMap.getKey_inter
/- getD -/
theorem getD_inter [TransCmp cmp] {k fallback : α} :
(t₁ ∩ t₂).getD k fallback =
if k ∈ t₂ then t₁.getD k fallback else fallback :=
ExtTreeMap.getKeyD_inter
theorem getD_inter_of_mem_right [TransCmp cmp]
{k fallback : α} (mem : k ∈ t₂) :
(t₁ ∩ t₂).getD k fallback = t₁.getD k fallback :=
ExtTreeMap.getKeyD_inter_of_mem_right mem
theorem getD_inter_of_not_mem_right [TransCmp cmp]
{k fallback : α} (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).getD k fallback = fallback :=
ExtTreeMap.getKeyD_inter_of_not_mem_right not_mem
theorem getD_inter_of_not_mem_left [TransCmp cmp]
{k fallback : α} (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).getD k fallback = fallback :=
ExtTreeMap.getKeyD_inter_of_not_mem_left not_mem
/- get! -/
theorem get!_inter [TransCmp cmp] [Inhabited α] {k : α} :
(t₁ ∩ t₂).get! k =
if k ∈ t₂ then t₁.get! k else default :=
ExtTreeMap.getKey!_inter
theorem get!_inter_of_mem_right [TransCmp cmp] [Inhabited α]
{k : α} (mem : k ∈ t₂) :
(t₁ ∩ t₂).get! k = t₁.get! k :=
ExtTreeMap.getKey!_inter_of_mem_right mem
theorem get!_inter_of_not_mem_right [TransCmp cmp] [Inhabited α]
{k : α} (not_mem : k ∉ t₂) :
(t₁ ∩ t₂).get! k = default :=
ExtTreeMap.getKey!_inter_of_not_mem_right not_mem
theorem get!_inter_of_not_mem_left [TransCmp cmp] [Inhabited α]
{k : α} (not_mem : k ∉ t₁) :
(t₁ ∩ t₂).get! k = default :=
ExtTreeMap.getKey!_inter_of_not_mem_left not_mem
/- size -/
theorem size_inter_le_size_left [TransCmp cmp] :
(t₁ ∩ t₂).size ≤ t₁.size :=
ExtTreeMap.size_inter_le_size_left
theorem size_inter_le_size_right [TransCmp cmp] :
(t₁ ∩ t₂).size ≤ t₂.size :=
ExtTreeMap.size_inter_le_size_right
theorem size_inter_eq_size_left [TransCmp cmp]
(h : ∀ (a : α), a ∈ t₁ → a ∈ t₂) :
(t₁ ∩ t₂).size = t₁.size :=
ExtTreeMap.size_inter_eq_size_left h
theorem size_inter_eq_size_right [TransCmp cmp]
(h : ∀ (a : α), a ∈ t₂ → a ∈ t₁) :
(t₁ ∩ t₂).size = t₂.size :=
ExtTreeMap.size_inter_eq_size_right h
theorem size_add_size_eq_size_union_add_size_inter [TransCmp cmp] :
t₁.size + t₂.size = (t₁ t₂).size + (t₁ ∩ t₂).size :=
ExtTreeMap.size_add_size_eq_size_union_add_size_inter
/- isEmpty -/
@[simp]
theorem isEmpty_inter_left [TransCmp cmp] (h : t₁.isEmpty) :
(t₁ ∩ t₂).isEmpty = true :=
ExtTreeMap.isEmpty_inter_left h
@[simp]
theorem isEmpty_inter_right [TransCmp cmp] (h : t₂.isEmpty) :
(t₁ ∩ t₂).isEmpty = true :=
ExtTreeMap.isEmpty_inter_right h
theorem isEmpty_inter_iff [TransCmp cmp] :
(t₁ ∩ t₂).isEmpty ↔ ∀ k, k ∈ t₁ → k ∉ t₂ :=
ExtTreeMap.isEmpty_inter_iff
end Inter
section monadic

View file

@ -1760,6 +1760,25 @@ theorem not_mem_inter_of_not_mem_right [TransCmp cmp] {k : α}
k ∉ t₁ ∩ t₂ :=
DTreeMap.not_mem_inter_of_not_mem_right not_mem
/- Equiv -/
theorem Equiv.inter_left {t₃ : TreeMap α β cmp} [TransCmp cmp]
(equiv : t₁ ~m t₂) :
(t₁ ∩ t₃).Equiv (t₂ ∩ t₃) := by
constructor
apply DTreeMap.Equiv.inter_left equiv.1
theorem Equiv.inter_right {t₃ : TreeMap α β cmp} [TransCmp cmp]
(equiv : t₂ ~m t₃) :
(t₁ ∩ t₂).Equiv (t₁ ∩ t₃) := by
constructor
apply DTreeMap.Equiv.inter_right equiv.1
theorem Equiv.inter_congr {t₃ t₄ : TreeMap α β cmp} [TransCmp cmp]
(equiv₁ : t₁ ~m t₃) (equiv₂ : t₂ ~m t₄) :
(t₁ ∩ t₂).Equiv (t₃ ∩ t₄) := by
constructor
apply DTreeMap.Equiv.inter_congr equiv₁.1 equiv₂.1
/- get? -/
theorem get?_inter [TransCmp cmp] {k : α} :
(t₁ ∩ t₂).get? k =

View file

@ -1803,6 +1803,24 @@ theorem not_mem_inter_of_not_mem_right [TransCmp cmp]
k ∉ t₁ ∩ t₂ :=
DTreeMap.Raw.not_mem_inter_of_not_mem_right h₁ h₂ not_mem
/- Equiv -/
theorem Equiv.inter_left [TransCmp cmp] {t₃ : Raw α β cmp}
(h₁ : t₁.WF) (h₂ : t₂.WF) (h₃ : t₃.WF) (equiv : t₁ ~m t₂) :
(t₁ ∩ t₃).Equiv (t₂ ∩ t₃) :=
⟨DTreeMap.Raw.Equiv.inter_left h₁ h₂ h₃ equiv.1⟩
theorem Equiv.inter_right [TransCmp cmp] {t₃ : Raw α β cmp}
(h₁ : t₁.WF) (h₂ : t₂.WF) (h₃ : t₃.WF) (equiv : t₂ ~m t₃) :
(t₁ ∩ t₂).Equiv (t₁ ∩ t₃) :=
⟨DTreeMap.Raw.Equiv.inter_right h₁ h₂ h₃ equiv.1⟩
theorem Equiv.inter_congr [TransCmp cmp] {t₃ t₄ : Raw α β cmp}
(h₁ : t₁.WF) (h₂ : t₂.WF) (h₃ : t₃.WF) (h₄ : t₄.WF)
(equiv₁ : t₁ ~m t₃) (equiv₂ : t₂ ~m t₄) :
(t₁ ∩ t₂).Equiv (t₃ ∩ t₄) :=
⟨DTreeMap.Raw.Equiv.inter_congr h₁ h₂ h₃ h₄ equiv₁.1 equiv₂.1⟩
/- get? -/
theorem get?_inter [TransCmp cmp] (h₁ : t₁.WF) (h₂ : t₂.WF) {k : α} :
(t₁ ∩ t₂).get? k =

View file

@ -642,6 +642,25 @@ theorem not_mem_inter_of_not_mem_right [TransCmp cmp] {k : α}
k ∉ t₁ ∩ t₂ :=
TreeMap.not_mem_inter_of_not_mem_right not_mem
/- Equiv -/
theorem Equiv.inter_left {t₃ : TreeSet α cmp} [TransCmp cmp]
(equiv : t₁ ~m t₂) :
(t₁ ∩ t₃).Equiv (t₂ ∩ t₃) := by
constructor
apply TreeMap.Equiv.inter_left equiv.1
theorem Equiv.inter_right {t₃ : TreeSet α cmp} [TransCmp cmp]
(equiv : t₂ ~m t₃) :
(t₁ ∩ t₂).Equiv (t₁ ∩ t₃) := by
constructor
apply TreeMap.Equiv.inter_right equiv.1
theorem Equiv.inter_congr {t₃ t₄ : TreeSet α cmp} [TransCmp cmp]
(equiv₁ : t₁ ~m t₃) (equiv₂ : t₂ ~m t₄) :
(t₁ ∩ t₂).Equiv (t₃ ∩ t₄) := by
constructor
apply TreeMap.Equiv.inter_congr equiv₁.1 equiv₂.1
/- get? -/
theorem get?_inter [TransCmp cmp] {k : α} :
(t₁ ∩ t₂).get? k =

View file

@ -668,6 +668,22 @@ theorem not_mem_inter_of_not_mem_right [TransCmp cmp]
k ∉ t₁ ∩ t₂ :=
TreeMap.Raw.not_mem_inter_of_not_mem_right h₁ h₂ not_mem
theorem Equiv.inter_left [TransCmp cmp] {t₃ : Raw α cmp}
(h₁ : t₁.WF) (h₂ : t₂.WF) (h₃ : t₃.WF) (equiv : t₁ ~m t₂) :
(t₁ ∩ t₃).Equiv (t₂ ∩ t₃) :=
⟨TreeMap.Raw.Equiv.inter_left h₁ h₂ h₃ equiv.1⟩
theorem Equiv.inter_right [TransCmp cmp] {t₃ : Raw α cmp}
(h₁ : t₁.WF) (h₂ : t₂.WF) (h₃ : t₃.WF) (equiv : t₂ ~m t₃) :
(t₁ ∩ t₂).Equiv (t₁ ∩ t₃) :=
⟨TreeMap.Raw.Equiv.inter_right h₁ h₂ h₃ equiv.1⟩
theorem Equiv.inter_congr [TransCmp cmp] {t₃ t₄ : Raw α cmp}
(h₁ : t₁.WF) (h₂ : t₂.WF) (h₃ : t₃.WF) (h₄ : t₄.WF)
(equiv₁ : t₁ ~m t₃) (equiv₂ : t₂ ~m t₄) :
(t₁ ∩ t₂).Equiv (t₃ ∩ t₄) :=
⟨TreeMap.Raw.Equiv.inter_congr h₁ h₂ h₃ h₄ equiv₁.1 equiv₂.1⟩
/- get? -/
theorem get?_inter [TransCmp cmp]
(h₁ : t₁.WF) (h₂ : t₂.WF)