-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathLattice.lean
More file actions
182 lines (142 loc) · 7.45 KB
/
Lattice.lean
File metadata and controls
182 lines (142 loc) · 7.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/-
Copyright (c) 2017 Johannes Hölzl. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Johannes Hölzl
-/
import Mathlib.Data.Set.Lattice
import Mathlib.Data.Set.Pairwise.Basic
/-!
# Relations holding pairwise
In this file we prove many facts about `Pairwise` and the set lattice.
-/
open Function Set Order
variable {α ι ι' : Type*} {κ : Sort*} {r : α → α → Prop}
section Pairwise
variable {f : ι → α} {s : Set α}
namespace Set
theorem pairwise_iUnion {f : κ → Set α} (h : Directed (· ⊆ ·) f) :
(⋃ n, f n).Pairwise r ↔ ∀ n, (f n).Pairwise r := by
constructor
· intro H n
exact Pairwise.mono (subset_iUnion _ _) H
· intro H i hi j hj hij
rcases mem_iUnion.1 hi with ⟨m, hm⟩
rcases mem_iUnion.1 hj with ⟨n, hn⟩
rcases h m n with ⟨p, mp, np⟩
exact H p (mp hm) (np hn) hij
theorem pairwise_sUnion {r : α → α → Prop} {s : Set (Set α)} (h : DirectedOn (· ⊆ ·) s) :
(⋃₀ s).Pairwise r ↔ ∀ a ∈ s, Set.Pairwise a r := by
rw [sUnion_eq_iUnion, pairwise_iUnion h.directed_val, SetCoe.forall]
end Set
end Pairwise
namespace Set
section PartialOrderBot
variable [PartialOrder α] [OrderBot α] {s : Set ι} {f : ι → α}
theorem pairwiseDisjoint_iUnion {g : ι' → Set ι} (h : Directed (· ⊆ ·) g) :
(⋃ n, g n).PairwiseDisjoint f ↔ ∀ ⦃n⦄, (g n).PairwiseDisjoint f :=
pairwise_iUnion h
theorem pairwiseDisjoint_sUnion {s : Set (Set ι)} (h : DirectedOn (· ⊆ ·) s) :
(⋃₀ s).PairwiseDisjoint f ↔ ∀ ⦃a⦄, a ∈ s → Set.PairwiseDisjoint a f :=
pairwise_sUnion h
theorem pairwiseDisjoint_union_of_disjoint
{s t : Set (Set ι)} {f : Set ι → α} (hf : Monotone f)
(hs : PairwiseDisjoint s f) (ht : PairwiseDisjoint t f)
(hst : Disjoint (f (Set.sUnion s)) (f (sUnion t))) : PairwiseDisjoint (s ∪ t) f := by
apply pairwiseDisjoint_union.mpr ⟨hs, ht, ?_⟩
exact fun a ha b hb hab ↦ Disjoint.mono (hf (subset_sUnion_of_subset s a (subset_refl a) ha))
(hf (subset_sUnion_of_subset t b (subset_refl b) hb)) hst
end PartialOrderBot
section CompleteLattice
variable [CompleteLattice α] {s : Set ι} {t : Set ι'}
/-- Bind operation for `Set.PairwiseDisjoint`. If you want to only consider finsets of indices, you
can use `Set.PairwiseDisjoint.biUnion_finset`. -/
theorem PairwiseDisjoint.biUnion {s : Set ι'} {g : ι' → Set ι} {f : ι → α}
(hs : s.PairwiseDisjoint fun i' : ι' => ⨆ i ∈ g i', f i)
(hg : ∀ i ∈ s, (g i).PairwiseDisjoint f) : (⋃ i ∈ s, g i).PairwiseDisjoint f := by
rintro a ha b hb hab
simp_rw [Set.mem_iUnion] at ha hb
obtain ⟨c, hc, ha⟩ := ha
obtain ⟨d, hd, hb⟩ := hb
obtain hcd | hcd := eq_or_ne (g c) (g d)
· exact hg d hd (hcd ▸ ha) hb hab
-- Porting note: the elaborator couldn't figure out `f` here.
· exact (hs hc hd <| ne_of_apply_ne _ hcd).mono
(le_iSup₂ (f := fun i _ => f i) a ha)
(le_iSup₂ (f := fun i _ => f i) b hb)
/-- If the suprema of columns are pairwise disjoint and suprema of rows as well, then everything is
pairwise disjoint. Not to be confused with `Set.PairwiseDisjoint.prod`. -/
theorem PairwiseDisjoint.prod_left {f : ι × ι' → α}
(hs : s.PairwiseDisjoint fun i => ⨆ i' ∈ t, f (i, i'))
(ht : t.PairwiseDisjoint fun i' => ⨆ i ∈ s, f (i, i')) :
(s ×ˢ t : Set (ι × ι')).PairwiseDisjoint f := by
rintro ⟨i, i'⟩ hi ⟨j, j'⟩ hj h
rw [mem_prod] at hi hj
obtain rfl | hij := eq_or_ne i j
· refine (ht hi.2 hj.2 <| (Prod.mk_right_injective _).ne_iff.1 h).mono ?_ ?_
· convert le_iSup₂ (α := α) i hi.1; rfl
· convert le_iSup₂ (α := α) i hj.1; rfl
· refine (hs hi.1 hj.1 hij).mono ?_ ?_
· convert le_iSup₂ (α := α) i' hi.2; rfl
· convert le_iSup₂ (α := α) j' hj.2; rfl
end CompleteLattice
section Frame
variable [Frame α]
theorem pairwiseDisjoint_prod_left {s : Set ι} {t : Set ι'} {f : ι × ι' → α} :
(s ×ˢ t : Set (ι × ι')).PairwiseDisjoint f ↔
(s.PairwiseDisjoint fun i => ⨆ i' ∈ t, f (i, i')) ∧
t.PairwiseDisjoint fun i' => ⨆ i ∈ s, f (i, i') := by
refine
⟨fun h => ⟨fun i hi j hj hij => ?_, fun i hi j hj hij => ?_⟩, fun h => h.1.prod_left h.2⟩ <;>
simp_rw [Function.onFun, iSup_disjoint_iff, disjoint_iSup_iff] <;>
intro i' hi' j' hj'
· exact h (mk_mem_prod hi hi') (mk_mem_prod hj hj') (ne_of_apply_ne Prod.fst hij)
· exact h (mk_mem_prod hi' hi) (mk_mem_prod hj' hj) (ne_of_apply_ne Prod.snd hij)
end Frame
theorem biUnion_diff_biUnion_eq {s t : Set ι} {f : ι → Set α} (h : (s ∪ t).PairwiseDisjoint f) :
((⋃ i ∈ s, f i) \ ⋃ i ∈ t, f i) = ⋃ i ∈ s \ t, f i := by
refine
(biUnion_diff_biUnion_subset f s t).antisymm
(iUnion₂_subset fun i hi a ha => (mem_diff _).2 ⟨mem_biUnion hi.1 ha, ?_⟩)
rw [mem_iUnion₂]; rintro ⟨j, hj, haj⟩
exact (h (Or.inl hi.1) (Or.inr hj) (ne_of_mem_of_not_mem hj hi.2).symm).le_bot ⟨ha, haj⟩
/-- Equivalence between a disjoint bounded union and a dependent sum. -/
noncomputable def biUnionEqSigmaOfDisjoint {s : Set ι} {f : ι → Set α} (h : s.PairwiseDisjoint f) :
(⋃ i ∈ s, f i) ≃ Σi : s, f i :=
(Equiv.setCongr (biUnion_eq_iUnion _ _)).trans <|
unionEqSigmaOfDisjoint fun ⟨_i, hi⟩ ⟨_j, hj⟩ ne => h hi hj fun eq => ne <| Subtype.eq eq
end Set
section
variable {f : ι → Set α} {s t : Set ι}
lemma Set.pairwiseDisjoint_iff :
s.PairwiseDisjoint f ↔ ∀ ⦃i⦄, i ∈ s → ∀ ⦃j⦄, j ∈ s → (f i ∩ f j).Nonempty → i = j := by
simp [Set.PairwiseDisjoint, Set.Pairwise, Function.onFun, not_imp_comm (a := _ = _),
not_disjoint_iff_nonempty_inter]
lemma Set.pairwiseDisjoint_pair_insert {s : Set α} {a : α} (ha : a ∉ s) :
s.powerset.PairwiseDisjoint fun t ↦ ({t, insert a t} : Set (Set α)) := by
rw [pairwiseDisjoint_iff]
rintro i hi j hj
have := insert_erase_invOn.2.injOn (not_mem_subset hi ha) (not_mem_subset hj ha)
aesop (add simp [Set.Nonempty, Set.subset_def])
theorem Set.PairwiseDisjoint.subset_of_biUnion_subset_biUnion (h₀ : (s ∪ t).PairwiseDisjoint f)
(h₁ : ∀ i ∈ s, (f i).Nonempty) (h : ⋃ i ∈ s, f i ⊆ ⋃ i ∈ t, f i) : s ⊆ t := by
rintro i hi
obtain ⟨a, hai⟩ := h₁ i hi
obtain ⟨j, hj, haj⟩ := mem_iUnion₂.1 (h <| mem_iUnion₂_of_mem hi hai)
rwa [h₀.eq (subset_union_left hi) (subset_union_right hj)
(not_disjoint_iff.2 ⟨a, hai, haj⟩)]
theorem Pairwise.subset_of_biUnion_subset_biUnion (h₀ : Pairwise (Disjoint on f))
(h₁ : ∀ i ∈ s, (f i).Nonempty) (h : ⋃ i ∈ s, f i ⊆ ⋃ i ∈ t, f i) : s ⊆ t :=
Set.PairwiseDisjoint.subset_of_biUnion_subset_biUnion (h₀.set_pairwise _) h₁ h
theorem Pairwise.biUnion_injective (h₀ : Pairwise (Disjoint on f)) (h₁ : ∀ i, (f i).Nonempty) :
Injective fun s : Set ι => ⋃ i ∈ s, f i := fun _s _t h =>
((h₀.subset_of_biUnion_subset_biUnion fun _ _ => h₁ _) <| h.subset).antisymm <|
(h₀.subset_of_biUnion_subset_biUnion fun _ _ => h₁ _) <| h.superset
/-- In a disjoint union we can identify the unique set an element belongs to. -/
theorem pairwiseDisjoint_unique {y : α}
(h_disjoint : PairwiseDisjoint s f)
(hy : y ∈ (⋃ i ∈ s, f i)) : ∃! i, i ∈ s ∧ y ∈ f i := by
refine existsUnique_of_exists_of_unique ?ex ?unique
· simpa only [mem_iUnion, exists_prop] using hy
· rintro i j ⟨his, hi⟩ ⟨hjs, hj⟩
exact h_disjoint.elim his hjs <| not_disjoint_iff.mpr ⟨y, ⟨hi, hj⟩⟩
end