Skip to content

Commit d62493a

Browse files
committed
feat: port Order.Filter.Partial (#2059)
Co-authored-by: Moritz Firsching <firsching@google.com>
1 parent adaaf29 commit d62493a

File tree

2 files changed

+292
-0
lines changed

2 files changed

+292
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,7 @@ import Mathlib.Order.Filter.Interval
795795
import Mathlib.Order.Filter.Lift
796796
import Mathlib.Order.Filter.ModEq
797797
import Mathlib.Order.Filter.NAry
798+
import Mathlib.Order.Filter.Partial
798799
import Mathlib.Order.Filter.Pi
799800
import Mathlib.Order.Filter.Pointwise
800801
import Mathlib.Order.Filter.Prod

Mathlib/Order/Filter/Partial.lean

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
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

Comments
 (0)