diff --git a/src/Std/Data/DTreeMap/Internal/Lemmas.lean b/src/Std/Data/DTreeMap/Internal/Lemmas.lean index 9d7c66eb2d..2dba4e7ee7 100644 --- a/src/Std/Data/DTreeMap/Internal/Lemmas.lean +++ b/src/Std/Data/DTreeMap/Internal/Lemmas.lean @@ -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 = diff --git a/src/Std/Data/DTreeMap/Lemmas.lean b/src/Std/Data/DTreeMap/Lemmas.lean index ebeb028e66..b871d6117c 100644 --- a/src/Std/Data/DTreeMap/Lemmas.lean +++ b/src/Std/Data/DTreeMap/Lemmas.lean @@ -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 = diff --git a/src/Std/Data/DTreeMap/Raw/Lemmas.lean b/src/Std/Data/DTreeMap/Raw/Lemmas.lean index f710b44bcb..761ecdbfe7 100644 --- a/src/Std/Data/DTreeMap/Raw/Lemmas.lean +++ b/src/Std/Data/DTreeMap/Raw/Lemmas.lean @@ -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 : α} : diff --git a/src/Std/Data/ExtDTreeMap/Basic.lean b/src/Std/Data/ExtDTreeMap/Basic.lean index 18d4027ae0..6e23a4c09f 100644 --- a/src/Std/Data/ExtDTreeMap/Basic.lean +++ b/src/Std/Data/ExtDTreeMap/Basic.lean @@ -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 diff --git a/src/Std/Data/ExtDTreeMap/Lemmas.lean b/src/Std/Data/ExtDTreeMap/Lemmas.lean index cae44acbf3..0eaabe5210 100644 --- a/src/Std/Data/ExtDTreeMap/Lemmas.lean +++ b/src/Std/Data/ExtDTreeMap/Lemmas.lean @@ -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 : α} diff --git a/src/Std/Data/ExtTreeMap/Basic.lean b/src/Std/Data/ExtTreeMap/Basic.lean index 4af9a618e3..65e1288641 100644 --- a/src/Std/Data/ExtTreeMap/Basic.lean +++ b/src/Std/Data/ExtTreeMap/Basic.lean @@ -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 := diff --git a/src/Std/Data/ExtTreeMap/Lemmas.lean b/src/Std/Data/ExtTreeMap/Lemmas.lean index 2a712ebf05..0625190406 100644 --- a/src/Std/Data/ExtTreeMap/Lemmas.lean +++ b/src/Std/Data/ExtTreeMap/Lemmas.lean @@ -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 : α} diff --git a/src/Std/Data/ExtTreeSet/Basic.lean b/src/Std/Data/ExtTreeSet/Basic.lean index cb039559a9..8f455ec7e5 100644 --- a/src/Std/Data/ExtTreeSet/Basic.lean +++ b/src/Std/Data/ExtTreeSet/Basic.lean @@ -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. -/ diff --git a/src/Std/Data/ExtTreeSet/Lemmas.lean b/src/Std/Data/ExtTreeSet/Lemmas.lean index 518d9d608b..f835605b93 100644 --- a/src/Std/Data/ExtTreeSet/Lemmas.lean +++ b/src/Std/Data/ExtTreeSet/Lemmas.lean @@ -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 diff --git a/src/Std/Data/TreeMap/Lemmas.lean b/src/Std/Data/TreeMap/Lemmas.lean index d087909cd0..50738d31b5 100644 --- a/src/Std/Data/TreeMap/Lemmas.lean +++ b/src/Std/Data/TreeMap/Lemmas.lean @@ -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 = diff --git a/src/Std/Data/TreeMap/Raw/Lemmas.lean b/src/Std/Data/TreeMap/Raw/Lemmas.lean index b977572e57..81d84eac40 100644 --- a/src/Std/Data/TreeMap/Raw/Lemmas.lean +++ b/src/Std/Data/TreeMap/Raw/Lemmas.lean @@ -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 = diff --git a/src/Std/Data/TreeSet/Lemmas.lean b/src/Std/Data/TreeSet/Lemmas.lean index 065d11d01b..55fe1c5686 100644 --- a/src/Std/Data/TreeSet/Lemmas.lean +++ b/src/Std/Data/TreeSet/Lemmas.lean @@ -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 = diff --git a/src/Std/Data/TreeSet/Raw/Lemmas.lean b/src/Std/Data/TreeSet/Raw/Lemmas.lean index 18ac93002e..1eb2ea122f 100644 --- a/src/Std/Data/TreeSet/Raw/Lemmas.lean +++ b/src/Std/Data/TreeSet/Raw/Lemmas.lean @@ -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)