-
Notifications
You must be signed in to change notification settings - Fork 251
/
AdicTopology.lean
270 lines (222 loc) · 10.1 KB
/
AdicTopology.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
/-
Copyright (c) 2021 Patrick Massot. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Patrick Massot
-/
import Mathlib.RingTheory.Ideal.Maps
import Mathlib.Topology.Algebra.Nonarchimedean.Bases
import Mathlib.Topology.Algebra.UniformRing
#align_import topology.algebra.nonarchimedean.adic_topology from "leanprover-community/mathlib"@"f0c8bf9245297a541f468be517f1bde6195105e9"
/-!
# Adic topology
Given a commutative ring `R` and an ideal `I` in `R`, this file constructs the unique
topology on `R` which is compatible with the ring structure and such that a set is a neighborhood
of zero if and only if it contains a power of `I`. This topology is non-archimedean: every
neighborhood of zero contains an open subgroup, namely a power of `I`.
It also studies the predicate `IsAdic` which states that a given topological ring structure is
adic, proving a characterization and showing that raising an ideal to a positive power does not
change the associated topology.
Finally, it defines `WithIdeal`, a class registering an ideal in a ring and providing the
corresponding adic topology to the type class inference system.
## Main definitions and results
* `Ideal.adic_basis`: the basis of submodules given by powers of an ideal.
* `Ideal.adicTopology`: the adic topology associated to an ideal. It has the above basis
for neighborhoods of zero.
* `Ideal.nonarchimedean`: the adic topology is non-archimedean
* `isAdic_iff`: A topological ring is `J`-adic if and only if it admits the powers of `J` as
a basis of open neighborhoods of zero.
* `WithIdeal`: a class registering an ideal in a ring.
## Implementation notes
The `I`-adic topology on a ring `R` has a contrived definition using `I^n • ⊤` instead of `I`
to make sure it is definitionally equal to the `I`-topology on `R` seen as an `R`-module.
-/
variable {R : Type*} [CommRing R]
open Set TopologicalAddGroup Submodule Filter
open Topology Pointwise
namespace Ideal
theorem adic_basis (I : Ideal R) : SubmodulesRingBasis fun n : ℕ => (I ^ n • ⊤ : Ideal R) :=
{ inter := by
suffices ∀ i j : ℕ, ∃ k, I ^ k ≤ I ^ i ∧ I ^ k ≤ I ^ j by
simpa only [smul_eq_mul, mul_top, Algebra.id.map_eq_id, map_id, le_inf_iff] using this
intro i j
exact ⟨max i j, pow_le_pow_right (le_max_left i j), pow_le_pow_right (le_max_right i j)⟩
leftMul := by
suffices ∀ (a : R) (i : ℕ), ∃ j : ℕ, a • I ^ j ≤ I ^ i by
simpa only [smul_top_eq_map, Algebra.id.map_eq_id, map_id] using this
intro r n
use n
rintro a ⟨x, hx, rfl⟩
exact (I ^ n).smul_mem r hx
mul := by
suffices ∀ i : ℕ, ∃ j : ℕ, (↑(I ^ j) * ↑(I ^ j) : Set R) ⊆ (↑(I ^ i) : Set R) by
simpa only [smul_top_eq_map, Algebra.id.map_eq_id, map_id] using this
intro n
use n
rintro a ⟨x, _hx, b, hb, rfl⟩
exact (I ^ n).smul_mem x hb }
#align ideal.adic_basis Ideal.adic_basis
/-- The adic ring filter basis associated to an ideal `I` is made of powers of `I`. -/
def ringFilterBasis (I : Ideal R) :=
I.adic_basis.toRing_subgroups_basis.toRingFilterBasis
#align ideal.ring_filter_basis Ideal.ringFilterBasis
/-- The adic topology associated to an ideal `I`. This topology admits powers of `I` as a basis of
neighborhoods of zero. It is compatible with the ring structure and is non-archimedean. -/
def adicTopology (I : Ideal R) : TopologicalSpace R :=
(adic_basis I).topology
#align ideal.adic_topology Ideal.adicTopology
theorem nonarchimedean (I : Ideal R) : @NonarchimedeanRing R _ I.adicTopology :=
I.adic_basis.toRing_subgroups_basis.nonarchimedean
#align ideal.nonarchimedean Ideal.nonarchimedean
/-- For the `I`-adic topology, the neighborhoods of zero has basis given by the powers of `I`. -/
theorem hasBasis_nhds_zero_adic (I : Ideal R) :
HasBasis (@nhds R I.adicTopology (0 : R)) (fun _n : ℕ => True) fun n =>
((I ^ n : Ideal R) : Set R) :=
⟨by
intro U
rw [I.ringFilterBasis.toAddGroupFilterBasis.nhds_zero_hasBasis.mem_iff]
constructor
· rintro ⟨-, ⟨i, rfl⟩, h⟩
replace h : ↑(I ^ i) ⊆ U := by simpa using h
exact ⟨i, trivial, h⟩
· rintro ⟨i, -, h⟩
exact ⟨(I ^ i : Ideal R), ⟨i, by simp⟩, h⟩⟩
#align ideal.has_basis_nhds_zero_adic Ideal.hasBasis_nhds_zero_adic
theorem hasBasis_nhds_adic (I : Ideal R) (x : R) :
HasBasis (@nhds R I.adicTopology x) (fun _n : ℕ => True) fun n =>
(fun y => x + y) '' (I ^ n : Ideal R) := by
letI := I.adicTopology
have := I.hasBasis_nhds_zero_adic.map fun y => x + y
rwa [map_add_left_nhds_zero x] at this
#align ideal.has_basis_nhds_adic Ideal.hasBasis_nhds_adic
variable (I : Ideal R) (M : Type*) [AddCommGroup M] [Module R M]
theorem adic_module_basis :
I.ringFilterBasis.SubmodulesBasis fun n : ℕ => I ^ n • (⊤ : Submodule R M) :=
{ inter := fun i j =>
⟨max i j,
le_inf_iff.mpr
⟨smul_mono_left <| pow_le_pow_right (le_max_left i j),
smul_mono_left <| pow_le_pow_right (le_max_right i j)⟩⟩
smul := fun m i =>
⟨(I ^ i • ⊤ : Ideal R), ⟨i, by simp⟩, fun a a_in => by
replace a_in : a ∈ I ^ i := by simpa [(I ^ i).mul_top] using a_in
exact smul_mem_smul a_in mem_top⟩ }
#align ideal.adic_module_basis Ideal.adic_module_basis
/-- The topology on an `R`-module `M` associated to an ideal `M`. Submodules $I^n M$,
written `I^n • ⊤` form a basis of neighborhoods of zero. -/
def adicModuleTopology : TopologicalSpace M :=
@ModuleFilterBasis.topology R M _ I.adic_basis.topology _ _
(I.ringFilterBasis.moduleFilterBasis (I.adic_module_basis M))
#align ideal.adic_module_topology Ideal.adicModuleTopology
/-- The elements of the basis of neighborhoods of zero for the `I`-adic topology
on an `R`-module `M`, seen as open additive subgroups of `M`. -/
def openAddSubgroup (n : ℕ) : @OpenAddSubgroup R _ I.adicTopology := by
letI := I.adicTopology
refine ⟨(I ^ n).toAddSubgroup, ?_⟩
convert (I.adic_basis.toRing_subgroups_basis.openAddSubgroup n).isOpen
change (↑(I ^ n) : Set R) = ↑(I ^ n • (⊤ : Ideal R))
simp [smul_top_eq_map, Algebra.id.map_eq_id, map_id, restrictScalars_self]
#align ideal.open_add_subgroup Ideal.openAddSubgroup
end Ideal
section IsAdic
/-- Given a topology on a ring `R` and an ideal `J`, `IsAdic J` means the topology is the
`J`-adic one. -/
def IsAdic [H : TopologicalSpace R] (J : Ideal R) : Prop :=
H = J.adicTopology
#align is_adic IsAdic
/-- A topological ring is `J`-adic if and only if it admits the powers of `J` as a basis of
open neighborhoods of zero. -/
theorem isAdic_iff [top : TopologicalSpace R] [TopologicalRing R] {J : Ideal R} :
IsAdic J ↔
(∀ n : ℕ, IsOpen ((J ^ n : Ideal R) : Set R)) ∧
∀ s ∈ 𝓝 (0 : R), ∃ n : ℕ, ((J ^ n : Ideal R) : Set R) ⊆ s := by
constructor
· intro H
change _ = _ at H
rw [H]
letI := J.adicTopology
constructor
· intro n
exact (J.openAddSubgroup n).isOpen'
· intro s hs
simpa using J.hasBasis_nhds_zero_adic.mem_iff.mp hs
· rintro ⟨H₁, H₂⟩
apply TopologicalAddGroup.ext
· apply @TopologicalRing.to_topologicalAddGroup
· apply (RingSubgroupsBasis.toRingFilterBasis _).toAddGroupFilterBasis.isTopologicalAddGroup
· ext s
letI := Ideal.adic_basis J
rw [J.hasBasis_nhds_zero_adic.mem_iff]
constructor <;> intro H
· rcases H₂ s H with ⟨n, h⟩
exact ⟨n, trivial, h⟩
· rcases H with ⟨n, -, hn⟩
rw [mem_nhds_iff]
exact ⟨_, hn, H₁ n, (J ^ n).zero_mem⟩
#align is_adic_iff isAdic_iff
variable [TopologicalSpace R] [TopologicalRing R]
theorem is_ideal_adic_pow {J : Ideal R} (h : IsAdic J) {n : ℕ} (hn : 0 < n) : IsAdic (J ^ n) := by
rw [isAdic_iff] at h ⊢
constructor
· intro m
rw [← pow_mul]
apply h.left
· intro V hV
cases' h.right V hV with m hm
use m
refine Set.Subset.trans ?_ hm
cases n
· exfalso
exact Nat.not_succ_le_zero 0 hn
rw [← pow_mul, Nat.succ_mul]
apply Ideal.pow_le_pow_right
apply Nat.le_add_left
#align is_ideal_adic_pow is_ideal_adic_pow
theorem is_bot_adic_iff {A : Type*} [CommRing A] [TopologicalSpace A] [TopologicalRing A] :
IsAdic (⊥ : Ideal A) ↔ DiscreteTopology A := by
rw [isAdic_iff]
constructor
· rintro ⟨h, _h'⟩
rw [discreteTopology_iff_isOpen_singleton_zero]
simpa using h 1
· intros
constructor
· simp
· intro U U_nhds
use 1
simp [mem_of_mem_nhds U_nhds]
#align is_bot_adic_iff is_bot_adic_iff
end IsAdic
/-- The ring `R` is equipped with a preferred ideal. -/
class WithIdeal (R : Type*) [CommRing R] where
i : Ideal R
#align with_ideal WithIdeal
namespace WithIdeal
variable (R)
variable [WithIdeal R]
instance (priority := 100) : TopologicalSpace R :=
i.adicTopology
instance (priority := 100) : NonarchimedeanRing R :=
RingSubgroupsBasis.nonarchimedean _
instance (priority := 100) : UniformSpace R :=
TopologicalAddGroup.toUniformSpace R
instance (priority := 100) : UniformAddGroup R :=
comm_topologicalAddGroup_is_uniform
/-- The adic topology on an `R` module coming from the ideal `WithIdeal.I`.
This cannot be an instance because `R` cannot be inferred from `M`. -/
def topologicalSpaceModule (M : Type*) [AddCommGroup M] [Module R M] : TopologicalSpace M :=
(i : Ideal R).adicModuleTopology M
#align with_ideal.topological_space_module WithIdeal.topologicalSpaceModule
/-
The next examples are kept to make sure potential future refactors won't break the instance
chaining.
-/
example : NonarchimedeanRing R := by infer_instance
example : TopologicalRing (UniformSpace.Completion R) := by infer_instance
example (M : Type*) [AddCommGroup M] [Module R M] :
@TopologicalAddGroup M (WithIdeal.topologicalSpaceModule R M) _ := by infer_instance
example (M : Type*) [AddCommGroup M] [Module R M] :
@ContinuousSMul R M _ _ (WithIdeal.topologicalSpaceModule R M) := by infer_instance
example (M : Type*) [AddCommGroup M] [Module R M] :
@NonarchimedeanAddGroup M _ (WithIdeal.topologicalSpaceModule R M) :=
SubmodulesBasis.nonarchimedean _
end WithIdeal