Skip to content

Commit 4e6f8fb

Browse files
urkudBergschaf
authored andcommitted
feat: define WithTopology structure (leanprover-community#39522)
`WithTopology X t` is a 1-field structure wrapper around `X` with topology coinduced from `t`. Define the structure, transfer some instances to it, and port `CofiniteTopology` to use it. ### AI usage disclosure First draft of `Topology/WithTopology.lean` was written by Gemini.
1 parent cadee3a commit 4e6f8fb

9 files changed

Lines changed: 243 additions & 26 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8038,6 +8038,7 @@ public import Mathlib.Topology.VectorBundle.ContinuousAlternatingMap
80388038
public import Mathlib.Topology.VectorBundle.FiniteDimensional
80398039
public import Mathlib.Topology.VectorBundle.Hom
80408040
public import Mathlib.Topology.VectorBundle.Riemannian
8041+
public import Mathlib.Topology.WithTopology
80418042
public import Mathlib.Util.AddRelatedDecl
80428043
public import Mathlib.Util.AliasIn
80438044
public import Mathlib.Util.AssertNoSorry

Mathlib/Topology/Compactification/OnePoint/Basic.lean

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module
88
public import Mathlib.Data.Fintype.Option
99
public import Mathlib.Topology.Homeomorph.Lemmas
1010
public import Mathlib.Topology.Sets.Opens
11+
import Mathlib.Topology.WithTopology
1112

1213
/-!
1314
# The one-point compactification
@@ -550,8 +551,8 @@ theorem not_continuous_cofiniteTopology_of_symm [Infinite X] [DiscreteTopology X
550551
inhabit X
551552
simp only [continuous_iff_continuousAt, ContinuousAt, not_forall]
552553
use CofiniteTopology.of ↑(default : X)
553-
simpa [nhds_coe_eq, nhds_discrete, CofiniteTopology.nhds_eq] using
554-
(finite_singleton ((default : X) : OnePoint X)).infinite_compl
554+
simpa [nhds_coe_eq, nhds_discrete, CofiniteTopology.nhds_eq, Equiv.symm_apply_eq]
555+
using (finite_singleton _).infinite_compl
555556

556557
instance (X : Type*) [TopologicalSpace X] [DiscreteTopology X] :
557558
TotallySeparatedSpace (OnePoint X) where

Mathlib/Topology/Constructions.lean

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public import Mathlib.Order.Filter.Cofinite
1313
public import Mathlib.Order.Filter.Curry
1414
public import Mathlib.Topology.Constructions.SumProd
1515
public import Mathlib.Topology.NhdsSet
16+
import Mathlib.Topology.WithTopology
1617

1718
/-!
1819
# Constructions of new topological spaces from old ones
@@ -272,19 +273,9 @@ lemma DiscreteTopology.isDiscrete [DiscreteTopology s] : IsDiscrete s := ⟨infe
272273

273274
end IsDiscrete
274275

275-
/-- A type synonym equipped with the topology whose open sets are the empty set and the sets with
276-
finite complements. -/
277-
def CofiniteTopology (X : Type*) := X
278-
279-
namespace CofiniteTopology
280-
281-
/-- The identity equivalence between `X` and `CofiniteTopology X`. -/
282-
def of : X ≃ CofiniteTopology X :=
283-
Equiv.refl X
284-
285-
instance [Inhabited X] : Inhabited (CofiniteTopology X) where default := of default
286-
287-
instance : TopologicalSpace (CofiniteTopology X) where
276+
/-- Cofinite topology. A set is open if it's empty or cofinite. -/
277+
@[implicit_reducible]
278+
protected def TopologicalSpace.cofinite {X : Type*} : TopologicalSpace X where
288279
IsOpen s := s.Nonempty → Set.Finite sᶜ
289280
isOpen_univ := by simp
290281
isOpen_inter s t := by
@@ -296,8 +287,22 @@ instance : TopologicalSpace (CofiniteTopology X) where
296287
rw [compl_sUnion]
297288
exact Finite.sInter (mem_image_of_mem _ hts) (h t hts ⟨x, hzt⟩)
298289

299-
theorem isOpen_iff {s : Set (CofiniteTopology X)} : IsOpen s ↔ s.Nonempty → sᶜ.Finite :=
300-
Iff.rfl
290+
/-- A type synonym equipped with the topology whose open sets are the empty set and the sets with
291+
finite complements. -/
292+
abbrev CofiniteTopology (X : Type*) :=
293+
WithTopology X .cofinite
294+
295+
namespace CofiniteTopology
296+
297+
/-- The identity equivalence between `X` and `CofiniteTopology X`. -/
298+
def of : X ≃ CofiniteTopology X := (WithTopology.equiv _ _).symm
299+
300+
instance [Inhabited X] : Inhabited (CofiniteTopology X) where default := of default
301+
302+
theorem isOpen_iff {s : Set (CofiniteTopology X)} : IsOpen s ↔ s.Nonempty → sᶜ.Finite := by
303+
simp_rw [isOpen_coinduced, TopologicalSpace.cofinite, isOpen_mk, ← Set.preimage_compl,
304+
WithTopology.preimage_toTopology, image_nonempty,
305+
finite_image_iff (WithTopology.ofTopology_injective _).injOn]
301306

302307
theorem isOpen_iff' {s : Set (CofiniteTopology X)} : IsOpen s ↔ s = ∅ ∨ sᶜ.Finite := by
303308
simp only [isOpen_iff, nonempty_iff_ne_empty, or_iff_not_imp_left]
@@ -307,7 +312,7 @@ theorem isClosed_iff {s : Set (CofiniteTopology X)} : IsClosed s ↔ s = univ
307312

308313
theorem nhds_eq (x : CofiniteTopology X) : 𝓝 x = pure x ⊔ cofinite := by
309314
ext U
310-
rw [mem_nhds_iff]
315+
simp_rw [mem_nhds_iff, isOpen_iff]
311316
constructor
312317
· rintro ⟨V, hVU, V_op, haV⟩
313318
exact mem_sup.mpr ⟨hVU haV, mem_of_superset (V_op ⟨_, haV⟩) hVU⟩

Mathlib/Topology/Defs/Basic.lean

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,22 @@ Formulated here when the source space is ℕ.
227227
Use `dense_iInter_of_isOpen` which works for any countable index type instead. -/
228228
class BaireSpace (X : Type*) [TopologicalSpace X] : Prop where
229229
baire_property : ∀ f : ℕ → Set X, (∀ n, IsOpen (f n)) → (∀ n, Dense (f n)) → Dense (⋂ n, f n)
230+
231+
/-- A one-field structure wrapper for `X` with the topology coinduced from `t`. -/
232+
@[ext]
233+
structure WithTopology (X : Type*) (t : TopologicalSpace X) where
234+
/-- Converts an element of `X` to an element of `WithTopology X t`. -/
235+
toTopology (t) ::
236+
/-- Converts an element of `WithTopology X t` to an element of `X`. -/
237+
ofTopology : X
238+
239+
section Notation
240+
241+
open Lean.PrettyPrinter.Delaborator
242+
243+
/-- This prevents `toTopology t x` being printed as `{ ofTopology := x }`
244+
by `delabStructureInstance`. -/
245+
@[app_delab WithTopology.toTopology]
246+
meta def WithTopology.delabToTopology : Delab := delabApp
247+
248+
end Notation

Mathlib/Topology/Defs/Induced.lean

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,26 @@ def coinduced (f : X → Y) (t : TopologicalSpace X) : TopologicalSpace Y where
9090

9191
end TopologicalSpace
9292

93+
namespace WithTopology
94+
95+
instance instTopologicalSpace (X : Type*) (t : TopologicalSpace X) :
96+
TopologicalSpace (WithTopology X t) :=
97+
.coinduced (WithTopology.toTopology t) t
98+
99+
lemma topology_eq_coinduced (X : Type*) (t : TopologicalSpace X) :
100+
instTopologicalSpace X t = .coinduced (.toTopology t) t :=
101+
rfl
102+
103+
/-- `WithTopology.ofTopology` and `WithTopology.toTopology` as an equivalence. -/
104+
@[simps]
105+
protected def equiv (X : Type*) (t : TopologicalSpace X) : WithTopology X t ≃ X where
106+
toFun := WithTopology.ofTopology
107+
invFun := WithTopology.toTopology t
108+
left_inv _ := rfl
109+
right_inv _ := rfl
110+
111+
end WithTopology
112+
93113
namespace Topology
94114
variable {X Y : Type*} [tX : TopologicalSpace X] [tY : TopologicalSpace Y]
95115

Mathlib/Topology/Irreducible.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public import Mathlib.Order.Zorn
1010
public import Mathlib.Topology.ContinuousOn
1111
public import Mathlib.Topology.DiscreteSubset
1212
public import Mathlib.Tactic.CrossRefAttribute
13+
import Mathlib.Topology.WithTopology
1314

1415
/-!
1516
# Irreducibility in topological spaces
@@ -264,11 +265,10 @@ instance (priority := 100) [IndiscreteTopology X] : PreirreducibleSpace X where
264265
/-- An infinite type with cofinite topology is an irreducible topological space. -/
265266
instance (priority := 100) {X} [Infinite X] : IrreducibleSpace (CofiniteTopology X) where
266267
isPreirreducible_univ u v := by
267-
haveI : Infinite (CofiniteTopology X) := ‹_›
268268
simp only [CofiniteTopology.isOpen_iff, univ_inter]
269269
intro hu hv hu' hv'
270270
simpa only [compl_union, compl_compl] using ((hu hu').union (hv hv')).infinite_compl.nonempty
271-
toNonempty := (inferInstance : Nonempty X)
271+
toNonempty := inferInstance
272272

273273
theorem irreducibleComponents_eq_singleton [IrreducibleSpace X] :
274274
irreducibleComponents X = {univ} :=

Mathlib/Topology/Order.lean

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,8 @@ theorem induced_id [t : TopologicalSpace α] : t.induced id = t :=
489489
TopologicalSpace.ext <|
490490
funext fun s => propext <| ⟨fun ⟨_, hs, h⟩ => h ▸ hs, fun hs => ⟨s, hs, rfl⟩⟩
491491

492+
theorem induced_fun_id {t : TopologicalSpace α} : t.induced (·) = t := induced_id
493+
492494
theorem induced_compose {tγ : TopologicalSpace γ} {f : α → β} {g : β → γ} :
493495
(tγ.induced g).induced f = tγ.induced (g ∘ f) :=
494496
TopologicalSpace.ext <|
@@ -516,6 +518,10 @@ theorem Equiv.coinduced_symm {α β : Type*} (e : α ≃ β) :
516518
TopologicalSpace.coinduced e.symm = TopologicalSpace.induced e :=
517519
e.symm.induced_symm.symm
518520

521+
lemma WithTopology.topology_eq_induced {X : Type*} (t : TopologicalSpace X) :
522+
instTopologicalSpace X t = .induced ofTopology t :=
523+
congrFun (WithTopology.equiv X t).coinduced_symm t
524+
519525
end GaloisConnection
520526

521527
-- constructions using the complete lattice structure
@@ -570,6 +576,20 @@ instance : DiscreteTopology ℤ := ⟨rfl⟩
570576
instance {n} : TopologicalSpace (Fin n) := ⊥
571577
instance {n} : DiscreteTopology (Fin n) := ⟨rfl⟩
572578

579+
instance : DiscreteTopology (WithTopology α ⊥) where
580+
eq_bot := coinduced_bot
581+
582+
instance : IndiscreteTopology (WithTopology α ⊤) where
583+
eq_top := by rw [WithTopology.topology_eq_induced, induced_top]
584+
585+
protected theorem WithTopology.nontrivialTopology_iff {t : TopologicalSpace α} :
586+
NontrivialTopology (WithTopology α t) ↔ t ≠ ⊤ := by
587+
simp_rw [nontrivialTopology_iff, topology_eq_induced, ne_eq, not_iff_not]
588+
constructor
589+
· intro h
590+
simpa [induced_compose, comp_def, induced_fun_id] using congr(induced (toTopology t) $h)
591+
· simp +contextual
592+
573593
lemma Nat.cast_continuous {R : Type*} [NatCast R] [TopologicalSpace R] :
574594
Continuous (Nat.cast (R := R)) :=
575595
continuous_of_discreteTopology

Mathlib/Topology/Separation/Basic.lean

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,9 @@ theorem TopologicalSpace.IsTopologicalBasis.exists_mem_of_ne [T1Space X] {b : Se
392392
protected theorem Finset.isClosed [T1Space X] (s : Finset X) : IsClosed (s : Set X) :=
393393
s.finite_toSet.isClosed
394394

395+
instance : T1Space (CofiniteTopology X) where
396+
t1 x := CofiniteTopology.isClosed_iff.mpr <| by simp
397+
395398
theorem t1Space_TFAE (X : Type u) [TopologicalSpace X] :
396399
List.TFAE [T1Space X,
397400
∀ x, IsClosed ({ x } : Set X),
@@ -421,9 +424,13 @@ theorem t1Space_TFAE (X : Type u) [TopologicalSpace X] :
421424
tfae_have 14 := by
422425
simp only [continuous_def, CofiniteTopology.isOpen_iff']
423426
rintro H s (rfl | hs)
424-
exacts [isOpen_empty, compl_compl s ▸ (@Set.Finite.isClosed _ _ H _ hs).isOpen_compl]
425-
tfae_have 42 :=
426-
fun h x => (CofiniteTopology.isClosed_iff.2 <| Or.inr (finite_singleton _)).preimage h
427+
· exact isOpen_empty
428+
· rw [← compl_compl s, preimage_compl]
429+
exact hs.preimage (Equiv.injective _).injOn |>.isClosed.isOpen_compl
430+
tfae_have 42 := by
431+
intro h x
432+
rw [← CofiniteTopology.of.preimage_image {x}]
433+
exact (Set.Finite.isClosed <| by simp) |>.preimage h
427434
tfae_have 210 := by
428435
simp only [← closure_subset_iff_isClosed, specializes_iff_mem_closure, subset_def,
429436
mem_singleton_iff, eq_comm]
@@ -480,9 +487,6 @@ theorem nhds_le_nhds_iff [T1Space X] {a b : X} : 𝓝 a ≤ 𝓝 b ↔ a = b :=
480487
instance (priority := 100) [T1Space X] : R0Space X :=
481488
(t1Space_iff_t0Space_and_r0Space.mp ‹T1Space X›).right
482489

483-
instance : T1Space (CofiniteTopology X) :=
484-
t1Space_iff_continuous_cofinite_of.mpr continuous_id
485-
486490
instance (priority := 80) [T0Space X] [R0Space X] : T1Space X :=
487491
t1Space_iff_t0Space_and_r0Space.mpr ⟨‹T0Space X›, ‹R0Space X›⟩
488492

Mathlib/Topology/WithTopology.lean

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/-
2+
Copyright (c) 2026 Yury Kudryashov. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Yury Kudryashov, Gemini CLI
5+
-/
6+
module
7+
8+
public import Mathlib.Topology.Defs.Induced
9+
10+
/-!
11+
# Basic lemmas and instances about the `WithTopology` type synonym
12+
13+
`WithTopology X t` is a copy of `X` equipped with the topology `t`.
14+
This is useful for providing multiple topologies on the same type
15+
without causing instance conflicts.
16+
17+
In this file we setup basic API about this type
18+
and transfer instances (basic, order) from `X` to `WithTopology X t`.
19+
20+
## Implementation notes
21+
22+
The pattern here is the same one as is used by `Lex` for order structures
23+
and `WithLp` for metric structures.
24+
-/
25+
26+
public section
27+
28+
variable {X : Type*} (t : TopologicalSpace X)
29+
30+
namespace WithTopology
31+
32+
lemma ofTopology_toTopology (x : X) : ofTopology (toTopology t x) = x := rfl
33+
34+
@[simp]
35+
lemma toTopology_ofTopology (x : WithTopology X t) :
36+
toTopology t (ofTopology x) = x := rfl
37+
38+
lemma ofTopology_surjective : Function.Surjective (ofTopology (t := t)) :=
39+
Function.RightInverse.surjective <| ofTopology_toTopology _
40+
41+
lemma toTopology_surjective : Function.Surjective (toTopology t) :=
42+
Function.RightInverse.surjective <| toTopology_ofTopology _
43+
44+
lemma ofTopology_injective : Function.Injective (ofTopology (t := t)) :=
45+
Function.LeftInverse.injective <| toTopology_ofTopology _
46+
47+
lemma toTopology_injective : Function.Injective (toTopology t) :=
48+
Function.LeftInverse.injective <| ofTopology_toTopology _
49+
50+
lemma ofTopology_bijective : Function.Bijective (ofTopology (t := t)) :=
51+
⟨ofTopology_injective t, ofTopology_surjective t⟩
52+
53+
lemma toTopology_bijective : Function.Bijective (toTopology t) :=
54+
⟨toTopology_injective t, toTopology_surjective t⟩
55+
56+
/-- Injectivity lemma for the constructor `toTopology t`.
57+
58+
It is not marked as `@[simp]`, because its autogenerated version
59+
is already in the default `simp` set. -/
60+
lemma toTopology_inj {x y : X} : toTopology t x = toTopology t y ↔ x = y :=
61+
(toTopology_injective t).eq_iff
62+
63+
@[simp] lemma ofTopology_inj {x y : WithTopology X t} : ofTopology x = ofTopology y ↔ x = y :=
64+
(ofTopology_injective t).eq_iff
65+
66+
/-! ### Set-theoretic lemmas -/
67+
68+
open Set
69+
70+
lemma image_ofTopology (s : Set (WithTopology X t)) : ofTopology '' s = toTopology t ⁻¹' s :=
71+
WithTopology.equiv X t |>.symm.image_symm_eq_preimage _
72+
73+
lemma preimage_toTopology (s : Set (WithTopology X t)) : toTopology t ⁻¹' s = ofTopology '' s :=
74+
(image_ofTopology t s).symm
75+
76+
lemma image_toTopology (s : Set X) : toTopology t '' s = ofTopology ⁻¹' s :=
77+
WithTopology.equiv X t |>.symm.image_eq_preimage_symm _
78+
79+
lemma preimage_ofTopology (s : Set X) : ofTopology ⁻¹' s = toTopology t '' s :=
80+
(image_toTopology t s).symm
81+
82+
/-!
83+
### Instance transfers
84+
85+
In this section we transfer some instances from `X` to `WithTopology X t`.
86+
-/
87+
88+
instance [Nonempty X] : Nonempty (WithTopology X t) :=
89+
(WithTopology.equiv X t).nonempty
90+
91+
instance [Inhabited X] : Inhabited (WithTopology X t) :=
92+
⟨toTopology t default⟩
93+
94+
instance [Subsingleton X] : Subsingleton (WithTopology X t) :=
95+
(WithTopology.equiv X t).subsingleton
96+
97+
instance [Unique X] : Unique (WithTopology X t) := .mk' _
98+
99+
instance [Finite X] : Finite (WithTopology X t) := .of_equiv _ (WithTopology.equiv X t).symm
100+
101+
instance [Infinite X] : Infinite (WithTopology X t) := .of_injective _ <| toTopology_injective _
102+
103+
instance [Fintype X] : Fintype (WithTopology X t) :=
104+
.ofBijective (.toTopology t) (toTopology_bijective t)
105+
106+
deriving instance DecidableEq for WithTopology
107+
108+
instance [LE X] : LE (WithTopology X t) where
109+
le x y := ofTopology x ≤ ofTopology y
110+
111+
instance [LT X] : LT (WithTopology X t) where
112+
lt x y := ofTopology x < ofTopology y
113+
114+
-- TODO: `inferInstance` works here, but it shouldn't
115+
instance [LE X] [DecidableLE X] : DecidableLE (WithTopology X t) := fun x y ↦
116+
inferInstanceAs (Decidable (x.ofTopology ≤ y.ofTopology))
117+
118+
-- TODO: `inferInstance` works here, but it shouldn't
119+
instance [LT X] [DecidableLT X] : DecidableLT (WithTopology X t) := fun x y ↦
120+
inferInstanceAs (Decidable (x.ofTopology < y.ofTopology))
121+
122+
instance [Preorder X] : Preorder (WithTopology X t) :=
123+
.lift ofTopology
124+
125+
instance [PartialOrder X] : PartialOrder (WithTopology X t) :=
126+
ofTopology_injective t |>.partialOrder _ .rfl .rfl
127+
128+
@[to_dual]
129+
instance [Max X] : Max (WithTopology X t) where
130+
max x y := toTopology t (max x.ofTopology y.ofTopology)
131+
132+
@[to_dual]
133+
instance [SemilatticeSup X] : SemilatticeSup (WithTopology X t) :=
134+
ofTopology_injective t |>.semilatticeSup _ .rfl .rfl fun _ _ ↦ rfl
135+
136+
instance [Lattice X] : Lattice (WithTopology X t) where
137+
138+
instance [DistribLattice X] : DistribLattice (WithTopology X t) where
139+
le_sup_inf _ _ _ := le_sup_inf (α := X)
140+
141+
instance [Ord X] : Ord (WithTopology X t) where
142+
compare x y := compare x.ofTopology y.ofTopology
143+
144+
instance [LinearOrder X] : LinearOrder (WithTopology X t) :=
145+
ofTopology_injective t |>.linearOrder _ .rfl .rfl (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl)
146+
147+
end WithTopology

0 commit comments

Comments
 (0)