|
| 1 | +/- |
| 2 | +Copyright (c) 2019 Jeremy Avigad. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Jeremy Avigad |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module order.filter.partial |
| 7 | +! leanprover-community/mathlib commit b363547b3113d350d053abdf2884e9850a56b205 |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.Order.Filter.Basic |
| 12 | +import Mathlib.Data.PFun |
| 13 | + |
| 14 | +/-! |
| 15 | +# `Tendsto` for relations and partial functions |
| 16 | +
|
| 17 | +This file generalizes `Filter` definitions from functions to partial functions and relations. |
| 18 | +
|
| 19 | +## Considering functions and partial functions as relations |
| 20 | +
|
| 21 | +A function `f : α → β` can be considered as the relation `Rel α β` which relates `x` and `f x` for |
| 22 | +all `x`, and nothing else. This relation is called `Function.Graph f`. |
| 23 | +
|
| 24 | +A partial function `f : α →. β` can be considered as the relation `Rel α β` which relates `x` and |
| 25 | +`f x` for all `x` for which `f x` exists, and nothing else. This relation is called |
| 26 | +`PFun.Graph' f`. |
| 27 | +
|
| 28 | +In this regard, a function is a relation for which every element in `α` is related to exactly one |
| 29 | +element in `β` and a partial function is a relation for which every element in `α` is related to at |
| 30 | +most one element in `β`. |
| 31 | +
|
| 32 | +This file leverages this analogy to generalize `Filter` definitions from functions to partial |
| 33 | +functions and relations. |
| 34 | +
|
| 35 | +## Notes |
| 36 | +
|
| 37 | +`Set.preimage` can be generalized to relations in two ways: |
| 38 | +* `Rel.preimage` returns the image of the set under the inverse relation. |
| 39 | +* `Rel.core` returns the set of elements that are only related to those in the set. |
| 40 | +Both generalizations are sensible in the context of filters, so `Filter.comap` and `Filter.Tendsto` |
| 41 | +get two generalizations each. |
| 42 | +
|
| 43 | +We first take care of relations. Then the definitions for partial functions are taken as special |
| 44 | +cases of the definitions for relations. |
| 45 | +-/ |
| 46 | + |
| 47 | + |
| 48 | +universe u v w |
| 49 | + |
| 50 | +namespace Filter |
| 51 | + |
| 52 | +variable {α : Type u} {β : Type v} {γ : Type w} |
| 53 | + |
| 54 | +open Filter |
| 55 | + |
| 56 | +/-! ### Relations -/ |
| 57 | + |
| 58 | + |
| 59 | +/-- The forward map of a filter under a relation. Generalization of `Filter.map` to relations. Note |
| 60 | +that `Rel.core` generalizes `Set.preimage`. -/ |
| 61 | +def rmap (r : Rel α β) (l : Filter α) : Filter β |
| 62 | + where |
| 63 | + sets := { s | r.core s ∈ l } |
| 64 | + univ_sets := by simp |
| 65 | + sets_of_superset := @fun s t hs st => mem_of_superset hs (Rel.core_mono _ st) |
| 66 | + inter_sets := @fun s t hs ht => by |
| 67 | + simp only [Set.mem_setOf_eq] |
| 68 | + convert inter_mem hs ht |
| 69 | + rw [←Rel.core_inter] |
| 70 | +#align filter.rmap Filter.rmap |
| 71 | + |
| 72 | +theorem rmap_sets (r : Rel α β) (l : Filter α) : (l.rmap r).sets = r.core ⁻¹' l.sets := |
| 73 | + rfl |
| 74 | +#align filter.rmap_sets Filter.rmap_sets |
| 75 | + |
| 76 | +@[simp] |
| 77 | +theorem mem_rmap (r : Rel α β) (l : Filter α) (s : Set β) : s ∈ l.rmap r ↔ r.core s ∈ l := |
| 78 | + Iff.rfl |
| 79 | +#align filter.mem_rmap Filter.mem_rmap |
| 80 | + |
| 81 | +@[simp] |
| 82 | +theorem rmap_rmap (r : Rel α β) (s : Rel β γ) (l : Filter α) : |
| 83 | + rmap s (rmap r l) = rmap (r.comp s) l := |
| 84 | + filter_eq <| by simp [rmap_sets, Set.preimage, Rel.core_comp] |
| 85 | +#align filter.rmap_rmap Filter.rmap_rmap |
| 86 | + |
| 87 | +@[simp] |
| 88 | +theorem rmap_compose (r : Rel α β) (s : Rel β γ) : rmap s ∘ rmap r = rmap (r.comp s) := |
| 89 | + funext <| rmap_rmap _ _ |
| 90 | +#align filter.rmap_compose Filter.rmap_compose |
| 91 | + |
| 92 | +/-- Generic "limit of a relation" predicate. `Rtendsto r l₁ l₂` asserts that for every |
| 93 | +`l₂`-neighborhood `a`, the `r`-core of `a` is an `l₁`-neighborhood. One generalization of |
| 94 | +`filter.Tendsto` to relations. -/ |
| 95 | +def Rtendsto (r : Rel α β) (l₁ : Filter α) (l₂ : Filter β) := |
| 96 | + l₁.rmap r ≤ l₂ |
| 97 | +#align filter.rtendsto Filter.Rtendsto |
| 98 | + |
| 99 | +theorem rtendsto_def (r : Rel α β) (l₁ : Filter α) (l₂ : Filter β) : |
| 100 | + Rtendsto r l₁ l₂ ↔ ∀ s ∈ l₂, r.core s ∈ l₁ := |
| 101 | + Iff.rfl |
| 102 | +#align filter.rtendsto_def Filter.rtendsto_def |
| 103 | + |
| 104 | +/-- One way of taking the inverse map of a filter under a relation. One generalization of |
| 105 | +`Filter.comap` to relations. Note that `Rel.core` generalizes `Set.preimage`. -/ |
| 106 | +def rcomap (r : Rel α β) (f : Filter β) : Filter α |
| 107 | + where |
| 108 | + sets := Rel.image (fun s t => r.core s ⊆ t) f.sets |
| 109 | + univ_sets := ⟨Set.univ, univ_mem, Set.subset_univ _⟩ |
| 110 | + sets_of_superset := @fun _ _ ⟨a', ha', ma'a⟩ ab => ⟨a', ha', ma'a.trans ab⟩ |
| 111 | + inter_sets := @fun _ _ ⟨a', ha₁, ha₂⟩ ⟨b', hb₁, hb₂⟩ => |
| 112 | + ⟨a' ∩ b', inter_mem ha₁ hb₁, (r.core_inter a' b').subset.trans (Set.inter_subset_inter ha₂ hb₂)⟩ |
| 113 | +#align filter.rcomap Filter.rcomap |
| 114 | + |
| 115 | +theorem rcomap_sets (r : Rel α β) (f : Filter β) : |
| 116 | + (rcomap r f).sets = Rel.image (fun s t => r.core s ⊆ t) f.sets := |
| 117 | + rfl |
| 118 | +#align filter.rcomap_sets Filter.rcomap_sets |
| 119 | + |
| 120 | +theorem rcomap_rcomap (r : Rel α β) (s : Rel β γ) (l : Filter γ) : |
| 121 | + rcomap r (rcomap s l) = rcomap (r.comp s) l := |
| 122 | + filter_eq <| by |
| 123 | + ext t; simp [rcomap_sets, Rel.image, Rel.core_comp]; constructor |
| 124 | + · rintro ⟨u, ⟨v, vsets, hv⟩, h⟩ |
| 125 | + exact ⟨v, vsets, Set.Subset.trans (Rel.core_mono _ hv) h⟩ |
| 126 | + rintro ⟨t, tsets, ht⟩ |
| 127 | + exact ⟨Rel.core s t, ⟨t, tsets, Set.Subset.rfl⟩, ht⟩ |
| 128 | +#align filter.rcomap_rcomap Filter.rcomap_rcomap |
| 129 | + |
| 130 | +@[simp] |
| 131 | +theorem rcomap_compose (r : Rel α β) (s : Rel β γ) : rcomap r ∘ rcomap s = rcomap (r.comp s) := |
| 132 | + funext <| rcomap_rcomap _ _ |
| 133 | +#align filter.rcomap_compose Filter.rcomap_compose |
| 134 | + |
| 135 | +theorem rtendsto_iff_le_rcomap (r : Rel α β) (l₁ : Filter α) (l₂ : Filter β) : |
| 136 | + Rtendsto r l₁ l₂ ↔ l₁ ≤ l₂.rcomap r := by |
| 137 | + rw [rtendsto_def] |
| 138 | + change (∀ s : Set β, s ∈ l₂.sets → r.core s ∈ l₁) ↔ l₁ ≤ rcomap r l₂ |
| 139 | + simp [Filter.le_def, rcomap, Rel.mem_image]; constructor |
| 140 | + · exact fun h s t tl₂ => mem_of_superset (h t tl₂) |
| 141 | + · exact fun h t tl₂ => h _ t tl₂ Set.Subset.rfl |
| 142 | +#align filter.rtendsto_iff_le_rcomap Filter.rtendsto_iff_le_rcomap |
| 143 | + |
| 144 | +-- Interestingly, there does not seem to be a way to express this relation using a forward map. |
| 145 | +-- Given a filter `f` on `α`, we want a filter `f'` on `β` such that `r.preimage s ∈ f` if |
| 146 | +-- and only if `s ∈ f'`. But the intersection of two sets satisfying the lhs may be empty. |
| 147 | +/-- One way of taking the inverse map of a filter under a relation. Generalization of `Filter.comap` |
| 148 | +to relations. -/ |
| 149 | +def rcomap' (r : Rel α β) (f : Filter β) : Filter α |
| 150 | + where |
| 151 | + sets := Rel.image (fun s t => r.preimage s ⊆ t) f.sets |
| 152 | + univ_sets := ⟨Set.univ, univ_mem, Set.subset_univ _⟩ |
| 153 | + sets_of_superset := @fun _ _ ⟨a', ha', ma'a⟩ ab => ⟨a', ha', ma'a.trans ab⟩ |
| 154 | + inter_sets := @fun _ _ ⟨a', ha₁, ha₂⟩ ⟨b', hb₁, hb₂⟩ => |
| 155 | + ⟨a' ∩ b', inter_mem ha₁ hb₁, |
| 156 | + (@Rel.preimage_inter _ _ r _ _).trans (Set.inter_subset_inter ha₂ hb₂)⟩ |
| 157 | +#align filter.rcomap' Filter.rcomap' |
| 158 | + |
| 159 | +@[simp] |
| 160 | +theorem mem_rcomap' (r : Rel α β) (l : Filter β) (s : Set α) : |
| 161 | + s ∈ l.rcomap' r ↔ ∃ t ∈ l, r.preimage t ⊆ s := |
| 162 | + Iff.rfl |
| 163 | +#align filter.mem_rcomap' Filter.mem_rcomap' |
| 164 | + |
| 165 | +theorem rcomap'_sets (r : Rel α β) (f : Filter β) : |
| 166 | + (rcomap' r f).sets = Rel.image (fun s t => r.preimage s ⊆ t) f.sets := |
| 167 | + rfl |
| 168 | +#align filter.rcomap'_sets Filter.rcomap'_sets |
| 169 | + |
| 170 | +@[simp] |
| 171 | +theorem rcomap'_rcomap' (r : Rel α β) (s : Rel β γ) (l : Filter γ) : |
| 172 | + rcomap' r (rcomap' s l) = rcomap' (r.comp s) l := |
| 173 | + Filter.ext fun t => by |
| 174 | + simp [rcomap'_sets, Rel.image, Rel.preimage_comp]; constructor |
| 175 | + · rintro ⟨u, ⟨v, vsets, hv⟩, h⟩ |
| 176 | + exact ⟨v, vsets, (Rel.preimage_mono _ hv).trans h⟩ |
| 177 | + rintro ⟨t, tsets, ht⟩ |
| 178 | + exact ⟨s.preimage t, ⟨t, tsets, Set.Subset.rfl⟩, ht⟩ |
| 179 | +#align filter.rcomap'_rcomap' Filter.rcomap'_rcomap' |
| 180 | + |
| 181 | +@[simp] |
| 182 | +theorem rcomap'_compose (r : Rel α β) (s : Rel β γ) : rcomap' r ∘ rcomap' s = rcomap' (r.comp s) := |
| 183 | + funext <| rcomap'_rcomap' _ _ |
| 184 | +#align filter.rcomap'_compose Filter.rcomap'_compose |
| 185 | + |
| 186 | +/-- Generic "limit of a relation" predicate. `Rtendsto' r l₁ l₂` asserts that for every |
| 187 | +`l₂`-neighborhood `a`, the `r`-preimage of `a` is an `l₁`-neighborhood. One generalization of |
| 188 | +`Filter.Tendsto` to relations. -/ |
| 189 | +def Rtendsto' (r : Rel α β) (l₁ : Filter α) (l₂ : Filter β) := |
| 190 | + l₁ ≤ l₂.rcomap' r |
| 191 | +#align filter.rtendsto' Filter.Rtendsto' |
| 192 | + |
| 193 | +theorem rtendsto'_def (r : Rel α β) (l₁ : Filter α) (l₂ : Filter β) : |
| 194 | + Rtendsto' r l₁ l₂ ↔ ∀ s ∈ l₂, r.preimage s ∈ l₁ := by |
| 195 | + unfold Rtendsto' rcomap'; simp [le_def, Rel.mem_image]; constructor |
| 196 | + · exact fun h s hs => h _ _ hs Set.Subset.rfl |
| 197 | + · exact fun h s t ht => mem_of_superset (h t ht) |
| 198 | +#align filter.rtendsto'_def Filter.rtendsto'_def |
| 199 | + |
| 200 | +theorem tendsto_iff_rtendsto (l₁ : Filter α) (l₂ : Filter β) (f : α → β) : |
| 201 | + Tendsto f l₁ l₂ ↔ Rtendsto (Function.graph f) l₁ l₂ := by |
| 202 | + simp [tendsto_def, Function.graph, rtendsto_def, Rel.core, Set.preimage] |
| 203 | +#align filter.tendsto_iff_rtendsto Filter.tendsto_iff_rtendsto |
| 204 | + |
| 205 | +theorem tendsto_iff_rtendsto' (l₁ : Filter α) (l₂ : Filter β) (f : α → β) : |
| 206 | + Tendsto f l₁ l₂ ↔ Rtendsto' (Function.graph f) l₁ l₂ := by |
| 207 | + simp [tendsto_def, Function.graph, rtendsto'_def, Rel.preimage_def, Set.preimage] |
| 208 | +#align filter.tendsto_iff_rtendsto' Filter.tendsto_iff_rtendsto' |
| 209 | + |
| 210 | +/-! ### Partial functions -/ |
| 211 | + |
| 212 | + |
| 213 | +/-- The forward map of a filter under a partial function. Generalization of `Filter.map` to partial |
| 214 | +functions. -/ |
| 215 | +def pmap (f : α →. β) (l : Filter α) : Filter β := |
| 216 | + Filter.rmap f.graph' l |
| 217 | +#align filter.pmap Filter.pmap |
| 218 | + |
| 219 | +@[simp] |
| 220 | +theorem mem_pmap (f : α →. β) (l : Filter α) (s : Set β) : s ∈ l.pmap f ↔ f.core s ∈ l := |
| 221 | + Iff.rfl |
| 222 | +#align filter.mem_pmap Filter.mem_pmap |
| 223 | + |
| 224 | +/-- Generic "limit of a partial function" predicate. `Ptendsto r l₁ l₂` asserts that for every |
| 225 | +`l₂`-neighborhood `a`, the `p`-core of `a` is an `l₁`-neighborhood. One generalization of |
| 226 | +`Filter.Tendsto` to partial function. -/ |
| 227 | +def Ptendsto (f : α →. β) (l₁ : Filter α) (l₂ : Filter β) := |
| 228 | + l₁.pmap f ≤ l₂ |
| 229 | +#align filter.ptendsto Filter.Ptendsto |
| 230 | + |
| 231 | +theorem ptendsto_def (f : α →. β) (l₁ : Filter α) (l₂ : Filter β) : |
| 232 | + Ptendsto f l₁ l₂ ↔ ∀ s ∈ l₂, f.core s ∈ l₁ := |
| 233 | + Iff.rfl |
| 234 | +#align filter.ptendsto_def Filter.ptendsto_def |
| 235 | + |
| 236 | +theorem ptendsto_iff_rtendsto (l₁ : Filter α) (l₂ : Filter β) (f : α →. β) : |
| 237 | + Ptendsto f l₁ l₂ ↔ Rtendsto f.graph' l₁ l₂ := |
| 238 | + Iff.rfl |
| 239 | +#align filter.ptendsto_iff_rtendsto Filter.ptendsto_iff_rtendsto |
| 240 | + |
| 241 | +theorem pmap_res (l : Filter α) (s : Set α) (f : α → β) : pmap (PFun.res f s) l = map f (l ⊓ 𝓟 s) := |
| 242 | + by |
| 243 | + ext t |
| 244 | + simp only [PFun.core_res, mem_pmap, mem_map, mem_inf_principal, imp_iff_not_or] |
| 245 | + rfl |
| 246 | +#align filter.pmap_res Filter.pmap_res |
| 247 | + |
| 248 | +theorem tendsto_iff_ptendsto (l₁ : Filter α) (l₂ : Filter β) (s : Set α) (f : α → β) : |
| 249 | + Tendsto f (l₁ ⊓ 𝓟 s) l₂ ↔ Ptendsto (PFun.res f s) l₁ l₂ := by |
| 250 | + simp only [Tendsto, Ptendsto, pmap_res] |
| 251 | +#align filter.tendsto_iff_ptendsto Filter.tendsto_iff_ptendsto |
| 252 | + |
| 253 | +theorem tendsto_iff_ptendsto_univ (l₁ : Filter α) (l₂ : Filter β) (f : α → β) : |
| 254 | + Tendsto f l₁ l₂ ↔ Ptendsto (PFun.res f Set.univ) l₁ l₂ := by |
| 255 | + rw [← tendsto_iff_ptendsto] |
| 256 | + simp [principal_univ] |
| 257 | +#align filter.tendsto_iff_ptendsto_univ Filter.tendsto_iff_ptendsto_univ |
| 258 | + |
| 259 | +/-- Inverse map of a filter under a partial function. One generalization of `Filter.comap` to |
| 260 | +partial functions. -/ |
| 261 | +def pcomap' (f : α →. β) (l : Filter β) : Filter α := |
| 262 | + Filter.rcomap' f.graph' l |
| 263 | +#align filter.pcomap' Filter.pcomap' |
| 264 | + |
| 265 | +/-- Generic "limit of a partial function" predicate. `Ptendsto' r l₁ l₂` asserts that for every |
| 266 | +`l₂`-neighborhood `a`, the `p`-preimage of `a` is an `l₁`-neighborhood. One generalization of |
| 267 | +`Filter.Tendsto` to partial functions. -/ |
| 268 | +def Ptendsto' (f : α →. β) (l₁ : Filter α) (l₂ : Filter β) := |
| 269 | + l₁ ≤ l₂.rcomap' f.graph' |
| 270 | +#align filter.ptendsto' Filter.Ptendsto' |
| 271 | + |
| 272 | +theorem ptendsto'_def (f : α →. β) (l₁ : Filter α) (l₂ : Filter β) : |
| 273 | + Ptendsto' f l₁ l₂ ↔ ∀ s ∈ l₂, f.preimage s ∈ l₁ := |
| 274 | + rtendsto'_def _ _ _ |
| 275 | +#align filter.ptendsto'_def Filter.ptendsto'_def |
| 276 | + |
| 277 | +theorem ptendsto_of_ptendsto' {f : α →. β} {l₁ : Filter α} {l₂ : Filter β} : |
| 278 | + Ptendsto' f l₁ l₂ → Ptendsto f l₁ l₂ := by |
| 279 | + rw [ptendsto_def, ptendsto'_def] |
| 280 | + exact fun h s sl₂ => mem_of_superset (h s sl₂) (PFun.preimage_subset_core _ _) |
| 281 | +#align filter.ptendsto_of_ptendsto' Filter.ptendsto_of_ptendsto' |
| 282 | + |
| 283 | +theorem ptendsto'_of_ptendsto {f : α →. β} {l₁ : Filter α} {l₂ : Filter β} (h : f.Dom ∈ l₁) : |
| 284 | + Ptendsto f l₁ l₂ → Ptendsto' f l₁ l₂ := by |
| 285 | + rw [ptendsto_def, ptendsto'_def] |
| 286 | + intro h' s sl₂ |
| 287 | + rw [PFun.preimage_eq] |
| 288 | + exact inter_mem (h' s sl₂) h |
| 289 | +#align filter.ptendsto'_of_ptendsto Filter.ptendsto'_of_ptendsto |
| 290 | + |
| 291 | +end Filter |
0 commit comments