Zulip Chat Archive
Stream: Is there code for X?
Topic: congruence of filters for tendsto
Max Bobbin (Aug 23 2022 at 20:37):
I don't think this is possible, but I wanted to check. I'm trying to show that if a function tends to the same value along two different filters, then those filters are the same. Of course, under the requirement, the function only hits that value once. I'm not sure how to state that last part in Lean, though so its missing from the mwe. So, for instance, for the function f x =1/x
, if f approaches positive infinity along filter 1 and it approaches positive infinity along filter 2, then filter 1 and filter 2 must be the same. I have a feeling that this doesn't work, for a similar reason as to why we have to say an unbounded function has a local minimum, instead of calling it a global minimum.
mwe:
example
{f : ℝ → ℝ}
{l₁ l₂ : filter ℝ}
(h1 : filter.tendsto f l₁ filter.at_top)
(h2 : filter.tendsto f l₂ filter.at_top)
--a premise that f only appraoches filter.at_top once
: l₁ = l₂ :=
begin
end
Patrick Massot (Aug 23 2022 at 20:39):
This isn't true.
Jireh Loreaux (Aug 23 2022 at 20:40):
The function f x := 1 / x
approaches at_top
along many filters.
Patrick Massot (Aug 23 2022 at 20:41):
And I don't see any true statement that would look like this. Under assumption tendsto f l₁ at_top
, any filter l₂
such that l₂ ≤ l₁
will satisfy tendsto f l₂ at_top
.
Jireh Loreaux (Aug 23 2022 at 20:42):
e.g., 𝓝[s] 0
where s
is any set of positive numbers whose only limit point is 0
.
Patrick Massot (Aug 23 2022 at 20:43):
Max I think your intuition of filters isn't sufficiently good. Shameless self-advertisement: I think you should try to watch the beginning of https://icerm.brown.edu/video_archive/?play=2899
Max Bobbin (Aug 23 2022 at 20:43):
Ok, this is what I thought. I'm trying to replicate a derivation from a scientific paper, and they do something similar to this with limits. They want to say that since the function approaches infinity when you approach this, and, since we want the function to approach infinity when we approach this specific constant, these two constants are equal
Max Bobbin (Aug 23 2022 at 20:43):
It most definitely isn't. I'm just trying to convert filters to my knowledge of limits
Jireh Loreaux (Aug 23 2022 at 20:43):
that might be possible, just replace arbitrary filters with neighborhood filters.
Jireh Loreaux (Aug 23 2022 at 20:44):
example
{f : ℝ → ℝ}
{l₁ l₂ : filter ℝ}
(h1 : filter.tendsto f (𝓝 a) filter.at_top)
(h2 : filter.tendsto f (𝓝 b) filter.at_top)
--a premise that f only appraoches filter.at_top once
: a = b := sorry
Max Bobbin (Aug 23 2022 at 20:45):
I think thats what I mean. As pointed out above, my knowledge of filters is not good, so I just used general filter. However, yes that may be what I mean
Mario Carneiro (Aug 23 2022 at 20:46):
That theorem sounds false as well: what about something like sec x
? This approaches infinity at lots of different points
Max Bobbin (Aug 23 2022 at 20:47):
My assumption is that the premise I have in the comments would have to bound the function to require it approach the value only once. So for sec x
, it would have to be bounded
Mario Carneiro (Aug 23 2022 at 20:47):
it's bounded, and approaches infinity?
Max Bobbin (Aug 23 2022 at 20:48):
Would 1/x
bounded from (-1,1) still approach infinity at zero?
Jireh Loreaux (Aug 23 2022 at 20:48):
Mario, there is a premise missing in the code I wrote, it's in a comment.
Mario Carneiro (Aug 23 2022 at 20:48):
only from above
Reid Barton (Aug 23 2022 at 20:49):
I'm not sure how you would express that premise in a way that makes your theorem non-trivial (i.e., not just applying the hypotheses to each other)
Jireh Loreaux (Aug 23 2022 at 20:50):
I think Max want's something like: "this function has a limit of ∞ at a, and is bounded on a complement of a neighborhood of a"
Mario Carneiro (Aug 23 2022 at 20:51):
sec x
is also bounded on a complement of a neighborhood of any of its poles
Mario Carneiro (Aug 23 2022 at 20:52):
the neighborhood would just encompass both poles
Mario Carneiro (Aug 23 2022 at 20:52):
oh wait, sec x
isn't a good example, (sec x)^2
is better
Jireh Loreaux (Aug 23 2022 at 20:52):
Sorry, I should have said, "bounded on the complement of anything in a filter basis for 𝓝 a"
Jireh Loreaux (Aug 23 2022 at 20:53):
I think that makes it work (but I agree it's really messy and there are probably better ways to go about it).
Mario Carneiro (Aug 23 2022 at 20:53):
I think that has the same issue, you can just choose a weird filter base with a member that happens to span the other poles
Jireh Loreaux (Aug 23 2022 at 20:54):
not every element of that filter basis can contain the other pole if the filter in question is 𝓝 a
Jireh Loreaux (Aug 23 2022 at 20:54):
or am I being silly?
Mario Carneiro (Aug 23 2022 at 20:55):
sure, but you just said there exists one
Jireh Loreaux (Aug 23 2022 at 20:56):
No, I'm saying this: "there exists a filter basis for 𝓝 a
such that for every element in this basis f
is bounded on the complement of that set"
Mario Carneiro (Aug 23 2022 at 20:56):
oh I see, that's more plausible
Jireh Loreaux (Aug 23 2022 at 20:58):
The filter basis isn't really necessary I guess, you just want bounded on the complement of any neighborhood.
Mario Carneiro (Aug 23 2022 at 20:59):
That sounds like it should be a general filter definition, some kind of co-tendsto
Mario Carneiro (Aug 23 2022 at 21:03):
def co_tendsto {α β} (f : α → β) (l₁ : filter α) (l₂ : filter β) :=
∀ s ∈ l₁, (f '' sᶜ)ᶜ ∈ l₂
Jireh Loreaux (Aug 23 2022 at 21:05):
maybe it's that the comap of the cobounded filter along f
is contained in 𝓝 a
?
Mario Carneiro (Aug 23 2022 at 21:10):
oh nice, mem_comap_iff_compl
says exactly that s ∈ comap f l ↔ (f '' sᶜ)ᶜ ∈ l
Mario Carneiro (Aug 23 2022 at 21:11):
so this really is co-tendsto
Jireh Loreaux (Aug 23 2022 at 21:13):
Yeah, I think saying that f : α → β
is bounded on complements of neighborhoods of a
is equivalent to filter.comap f (cobounded β) ≤ 𝓝 a
.
Mario Carneiro (Aug 23 2022 at 21:13):
This isn't the cobounded filter though
Mario Carneiro (Aug 23 2022 at 21:14):
I think
Jireh Loreaux (Aug 23 2022 at 21:14):
what isn't the cobounded filter?
Mario Carneiro (Aug 23 2022 at 21:16):
the definition I gave is equivalent to l₂.comap f ≤ l₁
Jireh Loreaux (Aug 23 2022 at 21:18):
oh okay, we're talking about different things I think. You're talking about a "co-tendsto" and I'm still talking about the specific thing.
Mario Carneiro (Aug 23 2022 at 21:18):
To apply to the specific thing you would use co_tendsto f (N a) at_top
Mario Carneiro (Aug 23 2022 at 21:19):
I'm not sure exactly what cobounded means here, I found is_cobounded
which isn't what we want and cobounded
is a typeclass (I have no idea what bornology is)
Adam Topaz (Aug 23 2022 at 21:20):
docs#bornology.cobounded supposedly?
Mario Carneiro (Aug 23 2022 at 21:20):
yes, but that's a typeclass like I said, I don't know what the filter actually is
Adam Topaz (Aug 23 2022 at 21:21):
but the reals have the bornology from the metric.
Jireh Loreaux (Aug 23 2022 at 21:21):
in a metric space, the cobounded filter consists of exactly the complements of bounded sets.
Mario Carneiro (Aug 23 2022 at 21:23):
So these are not exactly the same thing, I'm interpreting it as co-bounded above (at_top
) and not just metrically co-bounded
Jireh Loreaux (Aug 23 2022 at 21:24):
Mario, a bornology is just an abstraction of boundedness. It's a collection of sets which is closed under finite unions, subsets and contains all singletons. But in mathlib we dualize it so that it's just a filter smaller than the cofinite filter.
Jireh Loreaux (Aug 23 2022 at 21:24):
No, I agree, they are not exactly the same thing.
Jireh Loreaux (Aug 23 2022 at 21:26):
My condition (bounded away from a
) seemed like what the OP as getting at (which implies your condition since the at_top
filter is smaller than the cobounded
filter), and I was just trying to formalize that.
Mario Carneiro (Aug 23 2022 at 21:30):
So the interesting theorem here is that co_tendsto f l₁ l₂
and tendsto f l₁' l₂
implies l₁ ≤ l₁'
:
import order.filter.basic
def co_tendsto {α β} (f : α → β) (l₁ : filter α) (l₂ : filter β) :=
l₂.comap f ≤ l₁
open filter
example {α β} (f : α → β) (l₁ l₁' : filter α) (l₂ : filter β)
(h1 : tendsto f l₁ l₂) (h2 : co_tendsto f l₁' l₂) : l₁ ≤ l₁' :=
(map_le_iff_le_comap.1 h1).trans h2
Jireh Loreaux (Aug 23 2022 at 21:31):
I mean, isn't this just something to do with the fact that map and comap are a Galois connection?
Mario Carneiro (Aug 23 2022 at 21:32):
yes, it's a quite trivial proof as you can see
Mario Carneiro (Aug 23 2022 at 21:32):
but it means that if co_tendsto f (𝓝 a) at_top
and tendsto f (𝓝 b) at_top
then 𝓝 a <= 𝓝 b
so a = b
if the top space is hausdorff
Jireh Loreaux (Aug 23 2022 at 21:32):
Right, but I mean, it's just a lemma about Galois connections that's already in the library, presumably.
Mario Carneiro (Aug 23 2022 at 21:32):
I don't think co_tendsto
is
Mario Carneiro (Aug 23 2022 at 21:32):
I mean I just made it up
Mario Carneiro (Aug 23 2022 at 21:33):
note that map_le_iff_le_comap
is the galois connection lemma
Jireh Loreaux (Aug 23 2022 at 21:34):
sorry, I didn't actually read the proof :sheep:
Max Bobbin (Aug 23 2022 at 21:40):
Thank you. This is really helpful. I will have to watch those videos linked and learn more so I can understand whats happening
Jireh Loreaux (Aug 23 2022 at 21:40):
So are you saying we should actually have a definition for co_tendsto
, as opposed to the expanded version? I thought we have tendsto
primarily because limits occur everywhere. Do we have a lot of use cases for co_tendsto
outside of the above lemma?
Mario Carneiro (Aug 23 2022 at 21:41):
it seems to be similarly "foundational" to tendsto
, but it's possible we don't have a lot of applications just like we don't have many uses for coinductive types
Mario Carneiro (Aug 23 2022 at 21:43):
I would defer to someone else who works with the topology / filter library more for whether this is actually a good idea for a library definition. @Patrick Massot , any thoughts?
Patrick Massot (Aug 23 2022 at 21:44):
I haven't read this conversation, I'm playing with semantic highlighting. I want to finish writing doc about that and then I'll come back here if I don't forget.
Mario Carneiro (Aug 23 2022 at 21:46):
The question is whether it would make sense to have a definition for "co-tendsto" (name TBD), which says something like "it is consistent that f converges to l2 at l1". It has a nice duality with tendsto:
tendsto f l₁ l₂ ↔ l₁ ≤ l₂.comap f
co_tendsto f l₁ l₂ ↔ l₂.comap f ≤ l₁
Mario Carneiro (Aug 23 2022 at 21:47):
it will have a ton of monotonicity and galois connection style theorems, so it would actually be some work to add
Jireh Loreaux (Aug 23 2022 at 21:50):
Mario Carneiro said:
... "it is consistent that f converges to l2 at l1".
That doesn't seem like the right description in English to me, but maybe I'm wrong.
Mario Carneiro (Aug 23 2022 at 21:55):
It's a bit abstract, not sure how best to gloss it. "f
definitely doesn't converge to l2 anywhere other than l1"
Eric Rodriguez (Aug 23 2022 at 21:58):
Patrick Massot said:
Max I think your intuition of filters isn't sufficiently good. Shameless self-advertisement: I think you should try to watch the beginning of https://icerm.brown.edu/video_archive/?play=2899
thanks for this talk, this was very interesting! just to check the exercises: they are the stuff in https://leanprover-community.github.io/mathematics_in_lean/01_Introduction.html#getting-started, right?
Jireh Loreaux (Aug 23 2022 at 21:59):
Mario, that reads more correct to me.
Anatole Dedecker (Aug 23 2022 at 22:09):
The only case I can think of is in the hypothesis of docs#cauchy.comap. I will read this conversation again tomorrow because I’m half sleeping right now
Patrick Massot (Aug 23 2022 at 22:20):
Now that I posted my semantic highlighting stuff I read that discussion. I'm not convinced the "cotendsto" definition is useful in mathlib.
Patrick Massot (Aug 23 2022 at 22:22):
Mario Carneiro said:
it seems to be similarly "foundational" to
tendsto
I disagree. The definition of tendsto f F G
is much nicer because you can phrase it both as map f F ≤ G
and F ≤ comap f G
. Your definition doesn't have this symmetry.
Mario Carneiro (Aug 23 2022 at 22:23):
That's true. You can make it higher order, like \forall l', l' <= l₂.comap f -> l' <= l₁
and this latter thing can be rewritten in terms of map
(since it's just a tendsto
)
Mario Carneiro (Aug 23 2022 at 22:24):
I suspect there is some name for this operation with adjunctions but I don't know
Mario Carneiro (Aug 23 2022 at 22:26):
there should also be a version of this on the other side: l₂ ≤ l₁.map f
Mario Carneiro (Aug 23 2022 at 22:26):
so perhaps it's not a "co-" thing exactly but more like a left adjunction or something like that
Patrick Massot (Aug 23 2022 at 22:30):
I don't understand what you're trying to say, but it's getting late here.
Junyan Xu (Aug 23 2022 at 22:32):
I looked into https://ncatlab.org/nlab/show/adjoint+string and https://mathoverflow.net/questions/46877/natural-examples-of-sequences-of-adjoint-functors but found no examples about filters.
Patrick Massot (Aug 23 2022 at 22:33):
Do you mean you hoped that map f
could be right adjoint or comap f
could be a left adjoint? This is simply wrong.
Patrick Massot (Aug 23 2022 at 22:34):
Remember that for maps between complete lattices the adjoint functor theorem is extremely simple to state (and prove): a map is a left (resp. right) adjoint iff it commutes with sup (resp. inf).
Mario Carneiro (Aug 23 2022 at 22:37):
Fair enough. I think the most I want to claim at this point is that for an arbitrary galois connection u b <= a
is a relation you can say, and it sometimes has uses
Mario Carneiro (Aug 23 2022 at 22:37):
I will certainly agree it's not nearly as well behaved as a <= u b
Junyan Xu (Aug 23 2022 at 22:39):
Patrick Massot said:
Remember that for maps between complete lattices the adjoint functor theorem is extremely simple to state (and prove): a map is a left (resp. right) adjoint iff it commutes with sup (resp. inf).
That's a nice theorem to know! But it seems we have both docs#filter.comap_infi and docs#filter.comap_supr ?
Patrick Massot (Aug 23 2022 at 22:41):
Oh yes, I wrote too fast for comap f
.
Patrick Massot (Aug 23 2022 at 22:41):
I never noticed that.
Junyan Xu (Aug 23 2022 at 22:42):
We only have docs#filter.map_infi_le so the adjunction chain can't be extended that way (at least for general m : α → β
).
Patrick Massot (Aug 23 2022 at 22:42):
Now we have a nice exercise to do: figure out a concrete description of the right-adjoint to comap f
Patrick Massot (Aug 23 2022 at 22:43):
I'm really tired because I should have remember that set.preimage f
is also a left adjoint.
Patrick Massot (Aug 23 2022 at 22:43):
So it's not surprising that its extension to filters is both a right and a left adjoint.
Mario Carneiro (Aug 23 2022 at 22:44):
IIRC we actually have the definition for sets
Mario Carneiro (Aug 23 2022 at 22:46):
Patrick Massot (Aug 23 2022 at 22:46):
I have difficulties switching at high frequency between Lean 4 meta-programming and adjunctions at 1am.
Patrick Massot (Aug 23 2022 at 22:47):
Maybe I just disproved the theory claiming that programming monads belong to category theory.
Junyan Xu (Aug 24 2022 at 03:54):
So set.image f
doesn't admit a left adjoint unless f
is a bijection, because it doesn't preserve intersections unless f
is injective and doesn't preserve nullary intersection unless f
is surjective, and similarly set.kern_image f
doesn't admit a right adjoint because it's just (f '' sᶜ)ᶜ
.
I've worked out the right adjoint to docs#filter.comap, which I call filter.kern_map
, and it also admits a simple description: for m : α → β
and f : filter α
, (f.kern_map m).sets
is exactly the image of f.sets
under set.kern_image m
. Compare this to (f.map m).sets
, which is exactly the preimage of f.sets
under set.preimage m
. The appearance of docs#set.kern_image is because docs#filter.mem_comap' says exactly (is defeq to) s ∈ g.comap m ↔ s.kern_image m ∈ g
.
import order.filter.basic
variables {α β : Type*} (m : α → β)
namespace set
lemma kern_image_eq_compl (s : set α) : s.kern_image m = (m '' sᶜ)ᶜ :=
begin
ext1,
simp only [kern_image, mem_set_of_eq, mem_compl_eq, mem_image, not_exists, not_and],
exact forall_congr (λ _, not_imp_not.symm),
end
variables {s : set α} {t : set β}
lemma image_downward_closed (h : t ⊆ m '' s) : m '' (s ∩ m ⁻¹' t) = t :=
by rwa [image_inter_preimage, inter_eq_right_iff_subset]
lemma kern_image_upward_closed (h : s.kern_image m ⊆ t) : (s ∪ m ⁻¹' t).kern_image m = t :=
begin
rw [kern_image_eq_compl, compl_subset_comm] at h,
rw [kern_image_eq_compl, compl_union, ← preimage_compl, image_downward_closed m h, compl_compl],
end
end set
namespace filter
open set
lemma mem_comap'' (s : set α) (g : filter β) : s ∈ g.comap m ↔ s.kern_image m ∈ g := mem_comap'
def kern_map (f : filter α) : filter β :=
{ sets := (kern_image m) '' f.sets,
univ_sets := ⟨univ, f.univ_sets, by simp [kern_image_eq_compl]⟩,
sets_of_superset := begin
rintro _ t ⟨s, hm, rfl⟩ hi,
use [s ∪ m ⁻¹' t, f.sets_of_superset hm (subset_union_left s _)],
exact kern_image_upward_closed m hi,
end,
inter_sets := begin
rintro _ _ ⟨s₁, h₁, rfl⟩ ⟨s₂, h₂, rfl⟩,
use [s₁ ∩ s₂, f.inter_sets h₁ h₂],
simp only [kern_image_eq_compl, compl_inter, image_union, compl_union],
end }
lemma comap_kern_map (m : α → β) : galois_connection (comap m) (kern_map m) :=
λ g f, begin
simp_rw [le_def, mem_comap''], split,
{ rintro h _ ⟨s, hs, rfl⟩, exact h s hs },
{ intros h s hs, exact h _ ⟨s, hs, rfl⟩ },
end
end filter
-- miscellaneous lemmas unnecessary for the Galois connection
namespace set
variables {s : set α} {t : set β}
lemma image_downward_closed' (h : t ⊆ m '' s) : t ∈ set.range (set.image m) :=
by { rw [← inter_eq_right_iff_subset, ← image_inter_preimage] at h, exact ⟨_, h⟩ }
lemma image_downward_closed'' (h : t ⊆ m '' s) : m '' (m ⁻¹' t) = t :=
begin
rw [← inter_eq_right_iff_subset, ← image_inter_preimage] at h,
apply subset_antisymm,
{ apply image_preimage_subset },
{ conv_lhs { rw ← h }, apply image_subset, apply inter_subset_right },
end
lemma kern_image_upward_closed' (h : s.kern_image m ⊆ t) : t ∈ set.range (set.kern_image m) :=
begin
rw [kern_image_eq_compl, compl_subset_comm] at h,
obtain ⟨s', h'⟩ := image_downward_closed' m h,
use s'ᶜ, simp only [kern_image_eq_compl, compl_compl, h'],
end
lemma kern_image_upward_closed'' (h : s.kern_image m ⊆ t) : (m ⁻¹' t).kern_image m = t :=
begin
rw [kern_image_eq_compl, compl_subset_comm] at h,
rw [kern_image_eq_compl, ← preimage_compl, image_downward_closed'' m h, compl_compl],
end
lemma kern_image_mono {s₁ s₂ : set α} (h : s₁ ⊆ s₂) : s₁.kern_image m ⊆ s₂.kern_image m :=
begin
simp only [kern_image_eq_compl, compl_subset_compl],
apply image_subset m (compl_subset_compl.2 h),
end
end set
Junyan Xu (Aug 24 2022 at 04:13):
Let me also mention
extension of scalars ⊣ restriction of scalars ⊣ coextension of scalars
(#15529, functors between module categories induced by a ring hom)
which is apparently analogous the example
(functors between derived categories of sheaves induced by a proper morphism between algebraic varieties, see https://mathoverflow.net/a/46928/3332)
Patrick Massot (Aug 24 2022 at 07:07):
Nice! It can be used at least to simplify the proof of docs#filter.comap_supr
Patrick Massot (Aug 24 2022 at 07:09):
But please stop using dot notation for the only purpose of reversing the order you would write things on paper. Once you open the relevant namespaces it's not longer to write map f F
than F.map f
and it makes it much clear that you are applying the function map f
to F
, and the same with kern_image m s
.
Junyan Xu (Aug 24 2022 at 07:50):
Haha, I think dot notation allows me to use the declaration name as an infix operator, just like in m '' s
; I don't care so much about the order. I used the same notations '', ^-1 and ^k for filters on the scratch paper.
Eric Rodriguez (Aug 24 2022 at 07:57):
also, there's 50 different map
s and now opening namespaces means you can get clashes with map_{xyz}
lemmas.
Patrick Massot (Aug 24 2022 at 09:18):
There are no serious name clashes. I always start Lean 3 files with open set function filter
before thinking.
Patrick Massot (Aug 24 2022 at 09:18):
Junyan, what you do is not the analogue of writing m '' s
with an infix ''
, it is the analogue of writing s '' m
to mean m '' s
.
Junyan Xu (Aug 24 2022 at 15:25):
It seems there's special support in pretty printer/doc-gen for this purpose? For example in docs#multiset.sum_map_mul_left, multiset.sum uses dot notation but multiset.map doesn't, even though in the source code dot notation is used everywhere. Or maybe the pretty printer doesn't use dot notation whenever it's not associated to the first argument?
Yaël Dillies (Aug 24 2022 at 15:29):
Is it pp nodot
by any chance?
Junyan Xu (Aug 24 2022 at 15:50):
The pp_nodot
attribute is not added to src#multiset.map at its definition or locally.
Anatole Dedecker (Oct 04 2022 at 11:23):
Junyan Xu said:
So
set.image f
doesn't admit a left adjoint unlessf
is a bijection, because it doesn't preserve intersections unlessf
is injective and doesn't preserve nullary intersection unlessf
is surjective, and similarlyset.kern_image f
doesn't admit a right adjoint because it's just(f '' sᶜ)ᶜ
.I've worked out the right adjoint to docs#filter.comap, which I call
filter.kern_map
, and it also admits a simple description: form : α → β
andf : filter α
,(f.kern_map m).sets
is exactly the image off.sets
underset.kern_image m
. Compare this to(f.map m).sets
, which is exactly the preimage off.sets
underset.preimage m
. The appearance of docs#set.kern_image is because docs#filter.mem_comap' says exactly (is defeq to)s ∈ g.comap m ↔ s.kern_image m ∈ g
.import order.filter.basic variables {α β : Type*} (m : α → β) namespace set lemma kern_image_eq_compl (s : set α) : s.kern_image m = (m '' sᶜ)ᶜ := begin ext1, simp only [kern_image, mem_set_of_eq, mem_compl_eq, mem_image, not_exists, not_and], exact forall_congr (λ _, not_imp_not.symm), end variables {s : set α} {t : set β} lemma image_downward_closed (h : t ⊆ m '' s) : m '' (s ∩ m ⁻¹' t) = t := by rwa [image_inter_preimage, inter_eq_right_iff_subset] lemma kern_image_upward_closed (h : s.kern_image m ⊆ t) : (s ∪ m ⁻¹' t).kern_image m = t := begin rw [kern_image_eq_compl, compl_subset_comm] at h, rw [kern_image_eq_compl, compl_union, ← preimage_compl, image_downward_closed m h, compl_compl], end end set namespace filter open set lemma mem_comap'' (s : set α) (g : filter β) : s ∈ g.comap m ↔ s.kern_image m ∈ g := mem_comap' def kern_map (f : filter α) : filter β := { sets := (kern_image m) '' f.sets, univ_sets := ⟨univ, f.univ_sets, by simp [kern_image_eq_compl]⟩, sets_of_superset := begin rintro _ t ⟨s, hm, rfl⟩ hi, use [s ∪ m ⁻¹' t, f.sets_of_superset hm (subset_union_left s _)], exact kern_image_upward_closed m hi, end, inter_sets := begin rintro _ _ ⟨s₁, h₁, rfl⟩ ⟨s₂, h₂, rfl⟩, use [s₁ ∩ s₂, f.inter_sets h₁ h₂], simp only [kern_image_eq_compl, compl_inter, image_union, compl_union], end } lemma comap_kern_map (m : α → β) : galois_connection (comap m) (kern_map m) := λ g f, begin simp_rw [le_def, mem_comap''], split, { rintro h _ ⟨s, hs, rfl⟩, exact h s hs }, { intros h s hs, exact h _ ⟨s, hs, rfl⟩ }, end end filter -- miscellaneous lemmas unnecessary for the Galois connection namespace set variables {s : set α} {t : set β} lemma image_downward_closed' (h : t ⊆ m '' s) : t ∈ set.range (set.image m) := by { rw [← inter_eq_right_iff_subset, ← image_inter_preimage] at h, exact ⟨_, h⟩ } lemma image_downward_closed'' (h : t ⊆ m '' s) : m '' (m ⁻¹' t) = t := begin rw [← inter_eq_right_iff_subset, ← image_inter_preimage] at h, apply subset_antisymm, { apply image_preimage_subset }, { conv_lhs { rw ← h }, apply image_subset, apply inter_subset_right }, end lemma kern_image_upward_closed' (h : s.kern_image m ⊆ t) : t ∈ set.range (set.kern_image m) := begin rw [kern_image_eq_compl, compl_subset_comm] at h, obtain ⟨s', h'⟩ := image_downward_closed' m h, use s'ᶜ, simp only [kern_image_eq_compl, compl_compl, h'], end lemma kern_image_upward_closed'' (h : s.kern_image m ⊆ t) : (m ⁻¹' t).kern_image m = t := begin rw [kern_image_eq_compl, compl_subset_comm] at h, rw [kern_image_eq_compl, ← preimage_compl, image_downward_closed'' m h, compl_compl], end lemma kern_image_mono {s₁ s₂ : set α} (h : s₁ ⊆ s₂) : s₁.kern_image m ⊆ s₂.kern_image m := begin simp only [kern_image_eq_compl, compl_subset_compl], apply image_subset m (compl_subset_compl.2 h), end end set
Has any of this been PR-ed? I know it sounds crazy, but I need this for defining the space of test functions on an open set of a finite dimensional vector space in a convenient way!
Because I don't want to have "extensions by zero" all the time, I want to be the type of smooth functions defined on all of and whose docs#tsupport is a compact subset of . The problem is to encode the last condition in a convenient way that doesn't involve duplicating the API of docs#has_compact_support for this relative case (for example, a naive combination of docs#has_compact_support and "support " makes proving the sum of two test functions is a test function annoying).
So I want to apply the same trick as docs#has_compact_support_iff_eventually_eq but with a different filter, namely ⨅ (s : set S) (h : is_compact s), 𝓟 (coe '' s : set α)ᶜ
(I am in a normed space so docs#cocompact = docs#coclosed_compact). I've long been wondering if this could be defined from docs#cocompact by pure filter-theoretic nonsense, and I just realized that this is exactly kern_map coe cocompact
, which is way more satisfying!
Junyan Xu (Oct 04 2022 at 18:35):
No I haven't PR'd. Glad that the definition finds some actual use! I doubt I have time for the PR, and I think it's better that someone more familiar with the filter library PRs it, especially since you are probably adding more APIs to it. As shown in the proof above, the Galois connection is essentially known, as docs#filter.mem_comap'' in mathlib, and the main content of my work was to show (kern_image m) '' f.sets
forms a filter. I also worked out some more relationships back then:
image.png
Junyan Xu (Oct 04 2022 at 18:37):
The diagonal inclusion/generation are essneitally known in mathlib, and the middle top two are used in induced/coinduced topology, but I can't think of what the bottom row is good for.
Last updated: Dec 20 2023 at 11:08 UTC