Skip to content

Commit

Permalink
feat: define HasCountableSeparatingOn (#5675)
Browse files Browse the repository at this point in the history
- Define a typeclass saying that a countable family of sets satisfying
  a given predicate separate points of a given set.
- Provide instances for open and closed sets in a T₀ space with second
  countable topology and for measurable sets in case of a countably
  generated σ-algebra.

See [Zulip](https://leanprover.zulipchat.com/#narrow/stream/116395-maths/topic/ae.20eq.20of.20preimages) for motivation.
  • Loading branch information
urkud committed Jul 8, 2023
1 parent ea84670 commit adca8e2
Show file tree
Hide file tree
Showing 6 changed files with 309 additions and 29 deletions.
2 changes: 2 additions & 0 deletions Mathlib.lean
Expand Up @@ -2523,6 +2523,7 @@ import Mathlib.Order.Filter.Bases
import Mathlib.Order.Filter.Basic
import Mathlib.Order.Filter.Cofinite
import Mathlib.Order.Filter.CountableInter
import Mathlib.Order.Filter.CountableSeparatingOn
import Mathlib.Order.Filter.Curry
import Mathlib.Order.Filter.ENNReal
import Mathlib.Order.Filter.EventuallyConst
Expand Down Expand Up @@ -3140,6 +3141,7 @@ import Mathlib.Topology.ContinuousFunction.Units
import Mathlib.Topology.ContinuousFunction.Weierstrass
import Mathlib.Topology.ContinuousFunction.ZeroAtInfty
import Mathlib.Topology.ContinuousOn
import Mathlib.Topology.CountableSeparatingOn
import Mathlib.Topology.Covering
import Mathlib.Topology.DenseEmbedding
import Mathlib.Topology.DiscreteQuotient
Expand Down
4 changes: 4 additions & 0 deletions Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean
Expand Up @@ -312,6 +312,10 @@ theorem IsOpen.measurableSet (h : IsOpen s) : MeasurableSet s :=
OpensMeasurableSpace.borel_le _ <| GenerateMeasurable.basic _ h
#align is_open.measurable_set IsOpen.measurableSet

instance (priority := 500) {s : Set α} [HasCountableSeparatingOn α IsOpen s] :
HasCountableSeparatingOn α MeasurableSet s :=
.mono (fun _ ↦ IsOpen.measurableSet) Subset.rfl

@[measurability]
theorem measurableSet_interior : MeasurableSet (interior s) :=
isOpen_interior.measurableSet
Expand Down
46 changes: 17 additions & 29 deletions Mathlib/MeasureTheory/MeasurableSpace.lean
Expand Up @@ -14,6 +14,7 @@ import Mathlib.GroupTheory.Coset
import Mathlib.Logic.Equiv.Fin
import Mathlib.MeasureTheory.MeasurableSpaceDef
import Mathlib.Order.Filter.SmallSets
import Mathlib.Order.Filter.CountableSeparatingOn
import Mathlib.Order.LiminfLimsup
import Mathlib.Data.Set.UnionLift

Expand Down Expand Up @@ -1664,42 +1665,29 @@ instance [MeasurableSpace α] [CountablyGenerated α] [MeasurableSpace β] [Coun
CountablyGenerated (α × β) :=
.sup (.comap Prod.fst) (.comap Prod.snd)

instance [MeasurableSpace α] {s : Set α} [h : CountablyGenerated s] [MeasurableSingletonClass s] :
HasCountableSeparatingOn α MeasurableSet s := by
suffices HasCountableSeparatingOn s MeasurableSet univ from this.of_subtype fun _ ↦ id
rcases h.1 with ⟨b, hbc, hb⟩
refine ⟨⟨b, hbc, fun t ht ↦ hb.symm ▸ .basic t ht, fun x _ y _ h ↦ ?_⟩⟩
rw [← forall_generateFrom_mem_iff_mem_iff, ← hb] at h
simpa using h {y}

variable (α)

open Classical

/-- If a measurable space is countably generated, it admits a measurable injection
into the Cantor space `ℕ → Bool` (equipped with the product sigma algebra). -/
/-- If a measurable space is countably generated and separates points, it admits a measurable
injection into the Cantor space `ℕ → Bool` (equipped with the product sigma algebra). -/
theorem measurable_injection_nat_bool_of_countablyGenerated [MeasurableSpace α]
[h : CountablyGenerated α] [MeasurableSingletonClass α] :
[HasCountableSeparatingOn α MeasurableSet univ] :
∃ f : α → ℕ → Bool, Measurable f ∧ Function.Injective f := by
obtain ⟨b, bct, hb⟩ := h.isCountablyGenerated
obtain ⟨e, he⟩ := Set.Countable.exists_eq_range (bct.insert ∅) (insert_nonempty _ _)
rw [← generateFrom_insert_empty, he] at hb
refine' ⟨fun x n => x ∈ e n, _, _⟩
rcases exists_seq_separating α MeasurableSet.empty univ with ⟨e, hem, he⟩
refine ⟨(· ∈ e ·), ?_, ?_⟩
· rw [measurable_pi_iff]
intro n
apply measurable_to_bool
simp only [preimage, mem_singleton_iff, Bool.decide_iff]
rw [hb]
apply measurableSet_generateFrom
exact ⟨n, rfl⟩
intro x y hxy
have : ∀ s : Set α, MeasurableSet s → (x ∈ s ↔ y ∈ s) := fun s => by
rw [hb]
apply generateFrom_induction
· rintro - ⟨n, rfl⟩
rw [← decide_eq_decide]
rw [funext_iff] at hxy
exact hxy n
· tauto
· intro t
tauto
intro t ht
simp_rw [mem_iUnion, ht]
specialize this {y} measurableSet_eq
simp only [mem_singleton, iff_true_iff] at this
exact this
refine fun n ↦ measurable_to_bool ?_
simpa only [preimage, mem_singleton_iff, Bool.decide_iff, setOf_mem_eq] using hem n
· exact fun x y h ↦ he x trivial y trivial fun n ↦ decide_eq_decide.1 <| congr_fun h _
#align measurable_space.measurable_injection_nat_bool_of_countably_generated MeasurableSpace.measurable_injection_nat_bool_of_countablyGenerated

end MeasurableSpace
Expand Down
10 changes: 10 additions & 0 deletions Mathlib/MeasureTheory/MeasurableSpaceDef.lean
Expand Up @@ -402,6 +402,16 @@ theorem generateFrom_measurableSet [MeasurableSpace α] :
le_antisymm (generateFrom_le fun _ => id) fun _ => measurableSet_generateFrom
#align measurable_space.generate_from_measurable_set MeasurableSpace.generateFrom_measurableSet

theorem forall_generateFrom_mem_iff_mem_iff {S : Set (Set α)} {x y : α} :
(∀ s, MeasurableSet[generateFrom S] s → (x ∈ s ↔ y ∈ s)) ↔ (∀ s ∈ S, x ∈ s ↔ y ∈ s) := by
refine ⟨fun H s hs ↦ H s (.basic s hs), fun H s ↦ ?_⟩
apply generateFrom_induction
· exact H
· rfl
· exact fun _ ↦ Iff.not
· intro f hf
simp only [mem_iUnion, hf]

/-- If `g` is a collection of subsets of `α` such that the `σ`-algebra generated from `g` contains
the same sets as `g`, then `g` was already a `σ`-algebra. -/
protected def mkOfClosure (g : Set (Set α)) (hg : { t | MeasurableSet[generateFrom g] t } = g) :
Expand Down
242 changes: 242 additions & 0 deletions Mathlib/Order/Filter/CountableSeparatingOn.lean
@@ -0,0 +1,242 @@
/-
Copyright (c) 2023 Yury Kudryashov All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yury Kudryashov
-/
import Mathlib.Order.Filter.CountableInter

/-!
# Filters with countable intersections and countable separating families
In this file we prove some facts about a filter with countable intersections property on a type with
a countable family of sets that separates points of the space. The main use case is the
`MeasureTheory.Measure.ae` filter and a space with countably generated σ-algebra but lemmas apply,
e.g., to the `residual` filter and a T₀ topological space with second countable topology.
To avoid repetition of lemmas for different families of separating sets (measurable sets, open sets,
closed sets), all theorems in this file take a predicate `p : Set α → Prop` as an argument and prove
existence of a countable separating family satisfying this predicate by searching for a
`HasCountableSeparatingOn` typeclass instance.
## Main definitions
- `HasCountableSeparatingOn α p t`: a typeclass saying that there exists a countable set family
`S : Set (Set α)` such that all `s ∈ S` satisfy the predicate `p` and any two distinct points
`x y ∈ t`, `x ≠ y`, can be separated by a set `s ∈ S`. For technical reasons, we formulate the
latter property as "for all `x y ∈ t`, if `x ∈ s ↔ y ∈ s` for all `s ∈ S`, then `x = y`".
This typeclass is used in all lemmas in this file to avoid repeating them for open sets, closed
sets, and measurable sets.
### Main results
#### Filters supported on a (sub)singleton
Let `l : Filter α` be a filter with countable intersections property. Let `p : Set α → Prop` be a
property such that there exists a countable family of sets satisfying `p` and separating points of
`α`. Then `l` is supported on a subsingleton: there exists a subsingleton `t` such that
`t ∈ l`.
We formalize various versions of this theorem in
`Filter.exists_subset_subsingleton_mem_of_forall_separating`,
`Filter.exists_mem_singleton_mem_of_mem_of_nonempty_of_forall_separating`,
`Filter.exists_singleton_mem_of_mem_of_forall_separating`,
`Filter.exists_subsingleton_mem_of_forall_separating`, and
`Filter.exists_singleton_mem_of_forall_separating`.
#### Eventually constant functions
Consider a function `f : α → β`, a filter `l` with countable intersections property, and a countable
separating family of sets of `β`. Suppose that for every `U` from the family, either
`∀ᶠ x in l, f x ∈ U` or `∀ᶠ x in l, f x ∉ U`. Then `f` is eventually constant along `l`.
We formalize three versions of this theorem in
`Filter.exists_mem_eventuallyEq_const_of_eventually_mem_of_forall_separating`,
`Filter.exists_eventuallyEq_const_of_eventually_mem_of_forall_separating`, and
`Filer.exists_eventuallyEq_const_of_forall_separating`.
#### Eventually equal functions
Two functions are equal along a filter with countable intersections property if the preimages of all
sets from a countable separating family of sets are equal along the filter.
We formalize several versions of this theorem in
`Filter.of_eventually_mem_of_forall_separating_mem_iff`, `Filter.of_forall_separating_mem_iff`,
`Filter.of_eventually_mem_of_forall_separating_preimage`, and
`Filter.of_forall_separating_preimage`.
## Keywords
filter, countable
-/

open Function Set Filter

/-- We say that a type `α` has a *countable separating family of sets* satisfying a predicate
`p : Set α → Prop` on a set `t` if there exists a countable family of sets `S : Set (Set α)` such
that all sets `s ∈ S` satisfy `p` and any two distinct points `x y ∈ t`, `x ≠ y`, can be separated
by `s ∈ S`: there exists `s ∈ S` such that exactly one of `x` and `y` belongs to `s`.
E.g., if `α` is a `T₀` topological space with second countable topology, then it has a countable
separating family of open sets and a countable separating family of closed sets.
-/
class HasCountableSeparatingOn (α : Type _) (p : Set α → Prop) (t : Set α) : Prop where
exists_countable_separating : ∃ S : Set (Set α), S.Countable ∧ (∀ s ∈ S, p s) ∧
∀ x ∈ t, ∀ y ∈ t, (∀ s ∈ S, x ∈ s ↔ y ∈ s) → x = y

theorem exists_countable_separating (α : Type _) (p : Set α → Prop) (t : Set α)
[h : HasCountableSeparatingOn α p t] :
∃ S : Set (Set α), S.Countable ∧ (∀ s ∈ S, p s) ∧
∀ x ∈ t, ∀ y ∈ t, (∀ s ∈ S, x ∈ s ↔ y ∈ s) → x = y :=
h.1

theorem exists_nonempty_countable_separating (α : Type _) {p : Set α → Prop} {s₀} (hp : p s₀)
(t : Set α) [HasCountableSeparatingOn α p t] :
∃ S : Set (Set α), S.Nonempty ∧ S.Countable ∧ (∀ s ∈ S, p s) ∧
∀ x ∈ t, ∀ y ∈ t, (∀ s ∈ S, x ∈ s ↔ y ∈ s) → x = y :=
let ⟨S, hSc, hSp, hSt⟩ := exists_countable_separating α p t
⟨insert s₀ S, insert_nonempty _ _, hSc.insert _, forall_insert_of_forall hSp hp,
fun x hx y hy hxy ↦ hSt x hx y hy <| forall_of_forall_insert hxy⟩

theorem exists_seq_separating (α : Type _) {p : Set α → Prop} {s₀} (hp : p s₀) (t : Set α)
[HasCountableSeparatingOn α p t] :
∃ S : ℕ → Set α, (∀ n, p (S n)) ∧ ∀ x ∈ t, ∀ y ∈ t, (∀ n, x ∈ S n ↔ y ∈ S n) → x = y := by
rcases exists_nonempty_countable_separating α hp t with ⟨S, hSne, hSc, hS⟩
rcases hSc.exists_eq_range hSne with ⟨S, rfl⟩
use S
simpa only [forall_range_iff] using hS

theorem HasCountableSeparatingOn.mono {α} {p₁ p₂ : Set α → Prop} {t₁ t₂ : Set α}
[h : HasCountableSeparatingOn α p₁ t₁] (hp : ∀ s, p₁ s → p₂ s) (ht : t₂ ⊆ t₁) :
HasCountableSeparatingOn α p₂ t₂ where
exists_countable_separating :=
let ⟨S, hSc, hSp, hSt⟩ := h.1
⟨S, hSc, fun s hs ↦ hp s (hSp s hs), fun x hx y hy ↦ hSt x (ht hx) y (ht hy)⟩

theorem HasCountableSeparatingOn.of_subtype {α : Type _} {p : Set α → Prop} {t : Set α}
{q : Set t → Prop} [h : HasCountableSeparatingOn t q univ]
(hpq : ∀ U, q U → ∃ V, p V ∧ (↑) ⁻¹' V = U) : HasCountableSeparatingOn α p t := by
rcases h.1 with ⟨S, hSc, hSq, hS⟩
choose! V hpV hV using fun s hs ↦ hpq s (hSq s hs)
refine ⟨⟨V '' S, hSc.image _, ball_image_iff.2 hpV, fun x hx y hy h ↦ ?_⟩⟩
refine congr_arg Subtype.val (hS ⟨x, hx⟩ trivial ⟨y, hy⟩ trivial fun U hU ↦ ?_)
rw [← hV U hU]
exact h _ (mem_image_of_mem _ hU)

namespace Filter

variable {l : Filter α} [CountableInterFilter l] {f g : α → β}

/-!
### Filters supported on a (sub)singleton
In this section we prove several versions of the following theorem. Let `l : Filter α` be a filter
with countable intersections property. Let `p : Set α → Prop` be a property such that there exists a
countable family of sets satisfying `p` and separating points of `α`. Then `l` is supported on
a subsingleton: there exists a subsingleton `t` such that `t ∈ l`.
With extra `Nonempty`/`Set.Nonempty` assumptions one can ensure that `t` is a singleton `{x}`.
If `s ∈ l`, then it suffices to assume that the countable family separates only points of `s`.
-/

theorem exists_subset_subsingleton_mem_of_forall_separating (p : Set α → Prop)
{s : Set α} [h : HasCountableSeparatingOn α p s] (hs : s ∈ l)
(hl : ∀ U, p U → U ∈ l ∨ Uᶜ ∈ l) : ∃ t, t ⊆ s ∧ t.Subsingleton ∧ t ∈ l := by
rcases h.1 with ⟨S, hSc, hSp, hS⟩
refine ⟨s ∩ ⋂₀ (S ∩ l.sets) ∩ ⋂ (U ∈ S) (_ : Uᶜ ∈ l), Uᶜ, ?_, ?_, ?_⟩
· exact fun _ h ↦ h.1.1
· intro x hx y hy
simp only [mem_sInter, mem_inter_iff, mem_iInter, mem_compl_iff] at hx hy
refine hS x hx.1.1 y hy.1.1 (fun s hsS ↦ ?_)
cases hl s (hSp s hsS) with
| inl hsl => simp only [hx.1.2 s ⟨hsS, hsl⟩, hy.1.2 s ⟨hsS, hsl⟩]
| inr hsl => simp only [hx.2 s hsS hsl, hy.2 s hsS hsl]
· exact inter_mem
(inter_mem hs ((countable_sInter_mem (hSc.mono (inter_subset_left _ _))).2 fun _ h ↦ h.2))
((countable_bInter_mem hSc).2 fun U hU ↦ iInter_mem.2 id)

theorem exists_mem_singleton_mem_of_mem_of_nonempty_of_forall_separating (p : Set α → Prop)
{s : Set α} [HasCountableSeparatingOn α p s] (hs : s ∈ l) (hne : s.Nonempty)
(hl : ∀ U, p U → U ∈ l ∨ Uᶜ ∈ l) : ∃ a ∈ s, {a} ∈ l := by
rcases exists_subset_subsingleton_mem_of_forall_separating p hs hl with ⟨t, hts, ht, htl⟩
rcases ht.eq_empty_or_singleton with rfl | ⟨x, rfl⟩
· exact hne.imp fun a ha ↦ ⟨ha, mem_of_superset htl (empty_subset _)⟩
· exact ⟨x, hts rfl, htl⟩

theorem exists_singleton_mem_of_mem_of_forall_separating [Nonempty α] (p : Set α → Prop)
{s : Set α} [HasCountableSeparatingOn α p s] (hs : s ∈ l) (hl : ∀ U, p U → U ∈ l ∨ Uᶜ ∈ l) :
∃ a, {a} ∈ l := by
rcases s.eq_empty_or_nonempty with rfl | hne
· exact ‹Nonempty α›.elim fun a ↦ ⟨a, mem_of_superset hs (empty_subset _)⟩
· exact (exists_mem_singleton_mem_of_mem_of_nonempty_of_forall_separating p hs hne hl).imp fun _ ↦
And.right

theorem exists_subsingleton_mem_of_forall_separating (p : Set α → Prop)
[HasCountableSeparatingOn α p univ] (hl : ∀ U, p U → U ∈ l ∨ Uᶜ ∈ l) :
∃ s : Set α, s.Subsingleton ∧ s ∈ l :=
let ⟨t, _, hts, htl⟩ := exists_subset_subsingleton_mem_of_forall_separating p univ_mem hl
⟨t, hts, htl⟩

theorem exists_singleton_mem_of_forall_separating [Nonempty α] (p : Set α → Prop)
[HasCountableSeparatingOn α p univ] (hl : ∀ U, p U → U ∈ l ∨ Uᶜ ∈ l) :
∃ x : α, {x} ∈ l :=
exists_singleton_mem_of_mem_of_forall_separating p univ_mem hl

/-!
### Eventually constant functions
In this section we apply theorems from the previous section to the filter `Filter.map f l` to show
that `f : α → β` is eventually constant along `l` if for every `U` from the separating family,
either `∀ᶠ x in l, f x ∈ U` or `∀ᶠ x in l, f x ∉ U`.
-/

theorem exists_mem_eventuallyEq_const_of_eventually_mem_of_forall_separating (p : Set β → Prop)
{s : Set β} [HasCountableSeparatingOn β p s] (hs : ∀ᶠ x in l, f x ∈ s) (hne : s.Nonempty)
(h : ∀ U, p U → (∀ᶠ x in l, f x ∈ U) ∨ (∀ᶠ x in l, f x ∉ U)) :
∃ a ∈ s, f =ᶠ[l] const α a :=
exists_mem_singleton_mem_of_mem_of_nonempty_of_forall_separating p (l := map f l) hs hne h

theorem exists_eventuallyEq_const_of_eventually_mem_of_forall_separating [Nonempty β]
(p : Set β → Prop) {s : Set β} [HasCountableSeparatingOn β p s] (hs : ∀ᶠ x in l, f x ∈ s)
(h : ∀ U, p U → (∀ᶠ x in l, f x ∈ U) ∨ (∀ᶠ x in l, f x ∉ U)) :
∃ a, f =ᶠ[l] const α a :=
exists_singleton_mem_of_mem_of_forall_separating (l := map f l) p hs h

theorem exists_eventuallyEq_const_of_forall_separating [Nonempty β] (p : Set β → Prop)
[HasCountableSeparatingOn β p univ]
(h : ∀ U, p U → (∀ᶠ x in l, f x ∈ U) ∨ (∀ᶠ x in l, f x ∉ U)) :
∃ a, f =ᶠ[l] const α a :=
exists_singleton_mem_of_forall_separating (l := map f l) p h

namespace EventuallyEq

/-!
### Eventually equal functions
In this section we show that two functions are equal along a filter with countable intersections
property if the preimages of all sets from a countable separating family of sets are equal along
the filter.
-/

theorem of_eventually_mem_of_forall_separating_mem_iff (p : Set β → Prop) {s : Set β}
[h' : HasCountableSeparatingOn β p s] (hf : ∀ᶠ x in l, f x ∈ s) (hg : ∀ᶠ x in l, g x ∈ s)
(h : ∀ U : Set β, p U → ∀ᶠ x in l, f x ∈ U ↔ g x ∈ U) : f =ᶠ[l] g := by
rcases h'.1 with ⟨S, hSc, hSp, hS⟩
have H : ∀ᶠ x in l, ∀ s ∈ S, f x ∈ s ↔ g x ∈ s :=
(eventually_countable_ball hSc).2 fun s hs ↦ (h _ (hSp _ hs))
filter_upwards [H, hf, hg] with x hx hxf hxg using hS _ hxf _ hxg hx

theorem of_forall_separating_mem_iff (p : Set β → Prop)
[HasCountableSeparatingOn β p univ] (h : ∀ U : Set β, p U → ∀ᶠ x in l, f x ∈ U ↔ g x ∈ U) :
f =ᶠ[l] g :=
of_eventually_mem_of_forall_separating_mem_iff p (s := univ) univ_mem univ_mem h

theorem of_eventually_mem_of_forall_separating_preimage (p : Set β → Prop) {s : Set β}
[HasCountableSeparatingOn β p s] (hf : ∀ᶠ x in l, f x ∈ s) (hg : ∀ᶠ x in l, g x ∈ s)
(h : ∀ U : Set β, p U → f ⁻¹' U =ᶠ[l] g ⁻¹' U) : f =ᶠ[l] g :=
of_eventually_mem_of_forall_separating_mem_iff p hf hg fun U hU ↦ (h U hU).mem_iff

theorem of_forall_separating_preimage (p : Set β → Prop) [HasCountableSeparatingOn β p univ]
(h : ∀ U : Set β, p U → f ⁻¹' U =ᶠ[l] g ⁻¹' U) : f =ᶠ[l] g :=
of_eventually_mem_of_forall_separating_preimage p (s := univ) univ_mem univ_mem h
34 changes: 34 additions & 0 deletions Mathlib/Topology/CountableSeparatingOn.lean
@@ -0,0 +1,34 @@
/-
Copyright (c) 2023 Yury Kudryashov. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yury Kudryashov
-/
import Mathlib.Topology.Separation
import Mathlib.Order.Filter.CountableSeparatingOn

/-!
# Countable separating families of sets in topological spaces
In this file we show that a T₀ topological space with second countable
topology has a countable family of open (or closed) sets separating the points.
-/

open Set TopologicalSpace

/-- If `X` is a topological space, `s` is a set in `X` such that the induced topology is T₀ and is
second countable, then there exists a countable family of open sets in `X` that separates points
of `s`. -/
instance [TopologicalSpace X] {s : Set X} [T0Space s] [SecondCountableTopology s] :
HasCountableSeparatingOn X IsOpen s := by
suffices HasCountableSeparatingOn s IsOpen univ from .of_subtype fun _ ↦ isOpen_induced_iff.1
refine ⟨⟨countableBasis s, countable_countableBasis _, fun _ ↦ isOpen_of_mem_countableBasis,
fun x _ y _ h ↦ ?_⟩⟩
exact ((isBasis_countableBasis _).inseparable_iff.2 h).eq

/-- If there exists a countable family of open sets separating points of `s`, then there exists
a countable family of closed sets separating points of `s`. -/
instance [TopologicalSpace X] {s : Set X} [h : HasCountableSeparatingOn X IsOpen s] :
HasCountableSeparatingOn X IsClosed s :=
let ⟨S, hSc, hSo, hS⟩ := h.1
⟨compl '' S, hSc.image _, ball_image_iff.2 fun U hU ↦ (hSo U hU).isClosed_compl,
fun x hx y hy h ↦ hS x hx y hy fun _U hU ↦ not_iff_not.1 <| h _ (mem_image_of_mem _ hU)⟩

0 comments on commit adca8e2

Please sign in to comment.