-
Notifications
You must be signed in to change notification settings - Fork 232
Expand file tree
/
Copy pathSection_5_epilogue.lean
More file actions
253 lines (180 loc) · 8.84 KB
/
Section_5_epilogue.lean
File metadata and controls
253 lines (180 loc) · 8.84 KB
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
import Mathlib.Tactic
import Analysis.Section_5_6
/-!
# Analysis I, Chapter 5 epilogue: Isomorphism with the Mathlib real numbers
In this (technical) epilogue, we show that the "Chapter 5" real numbers {name}`Chapter5.Real` are
isomorphic in various standard senses to the standard real numbers {lean}`ℝ`. This we do by matching
both structures with Dedekind cuts of the (Mathlib) rational numbers {lean}`ℚ`.
From this point onwards, {name}`Chapter5.Real` will be deprecated, and we will use the standard real
numbers {lean}`ℝ` instead. In particular, one should use the full Mathlib API for {lean}`ℝ` for all
subsequent chapters, in lieu of the {name}`Chapter5.Real` API.
Filling the {syntax term}`sorry`s here requires both the {name}`Chapter5.Real` API and the Mathlib API for the standard
real numbers {lean}`ℝ`. As such, they are excellent exercises to prepare you for the aforementioned
transition.
## Tips from past users
Users of the companion who have completed the exercises in this section are welcome to send their tips for future users in this section as PRs.
- (Add tip here)
-/
namespace Chapter5
@[ext]
structure DedekindCut where
E : Set ℚ
nonempty : E.Nonempty
bounded : BddAbove E
lower: IsLowerSet E
nomax : ∀ q ∈ E, ∃ r ∈ E, r > q
theorem isLowerSet_iff (E: Set ℚ) : IsLowerSet E ↔ ∀ q r, r < q → q ∈ E → r ∈ E :=
isLowerSet_iff_forall_lt
abbrev Real.toSet_Rat (x:Real) : Set ℚ := { q | (q:Real) < x }
lemma Real.toSet_Rat_nonempty (x:Real) : x.toSet_Rat.Nonempty := by sorry
lemma Real.toSet_Rat_bounded (x:Real) : BddAbove x.toSet_Rat := by sorry
lemma Real.toSet_Rat_lower (x:Real) : IsLowerSet x.toSet_Rat := by sorry
lemma Real.toSet_Rat_nomax {x:Real} : ∀ q ∈ x.toSet_Rat, ∃ r ∈ x.toSet_Rat, r > q := by sorry
abbrev Real.toCut (x:Real) : DedekindCut :=
{
E := x.toSet_Rat
nonempty := x.toSet_Rat_nonempty
bounded := x.toSet_Rat_bounded
lower := x.toSet_Rat_lower
nomax := x.toSet_Rat_nomax
}
abbrev DedekindCut.toSet_Real (c: DedekindCut) : Set Real := (fun (q:ℚ) ↦ (q:Real)) '' c.E
lemma DedekindCut.toSet_Real_nonempty (c: DedekindCut) : c.toSet_Real.Nonempty := by sorry
lemma DedekindCut.toSet_Real_bounded (c: DedekindCut) : BddAbove c.toSet_Real := by sorry
noncomputable abbrev DedekindCut.toReal (c: DedekindCut) : Real := sSup c.toSet_Real
lemma DedekindCut.toReal_isLUB (c: DedekindCut) : IsLUB c.toSet_Real c.toReal :=
ExtendedReal.sSup_of_bounded c.toSet_Real_nonempty c.toSet_Real_bounded
noncomputable abbrev Real.equivCut : Real ≃ DedekindCut where
toFun := toCut
invFun := DedekindCut.toReal
left_inv x := by
sorry
right_inv c := by
sorry
end Chapter5
/-- Now to develop analogous results for the Mathlib reals. -/
abbrev Real.toSet_Rat (x:ℝ) : Set ℚ := { q | (q:ℝ) < x }
lemma Real.toSet_Rat_nonempty (x:ℝ) : x.toSet_Rat.Nonempty := by sorry
lemma Real.toSet_Rat_bounded (x:ℝ) : BddAbove x.toSet_Rat := by sorry
lemma Real.toSet_Rat_lower (x:ℝ) : IsLowerSet x.toSet_Rat := by sorry
lemma Real.toSet_Rat_nomax (x:ℝ) : ∀ q ∈ x.toSet_Rat, ∃ r ∈ x.toSet_Rat, r > q := by sorry
abbrev Real.toCut (x:ℝ) : Chapter5.DedekindCut :=
{
E := x.toSet_Rat
nonempty := x.toSet_Rat_nonempty
bounded := x.toSet_Rat_bounded
lower := x.toSet_Rat_lower
nomax := x.toSet_Rat_nomax
}
namespace Chapter5
abbrev DedekindCut.toSet_R (c: DedekindCut) : Set ℝ := (fun (q:ℚ) ↦ (q:ℝ)) '' c.E
lemma DedekindCut.toSet_R_nonempty (c: DedekindCut) : c.toSet_R.Nonempty := by sorry
lemma DedekindCut.toSet_R_bounded (c: DedekindCut) : BddAbove c.toSet_R := by sorry
noncomputable abbrev DedekindCut.toR (c: DedekindCut) : ℝ := sSup c.toSet_R
lemma DedekindCut.toR_isLUB (c: DedekindCut) : IsLUB c.toSet_R c.toR :=
isLUB_csSup c.toSet_R_nonempty c.toSet_R_bounded
end Chapter5
noncomputable abbrev Real.equivCut : ℝ ≃ Chapter5.DedekindCut where
toFun := _root_.Real.toCut
invFun := Chapter5.DedekindCut.toR
left_inv x := by
sorry
right_inv c := by
sorry
namespace Chapter5
/-- The isomorphism between the {name}`Chapter5.Real` numbers and the Mathlib reals. -/
noncomputable abbrev Real.equivR : Real ≃ ℝ := Real.equivCut.trans _root_.Real.equivCut.symm
lemma Real.equivR_iff (x : Real) (y : ℝ) : y = Real.equivR x ↔ y.toCut = x.toCut := by
simp only [equivR, Equiv.trans_apply, ←Equiv.apply_eq_iff_eq_symm_apply]
rfl
-- In order to use this definition, we need some machinery
-----
-- We start by showing it works for ratCasts
theorem Real.equivR_ratCast {q: ℚ} : equivR q = (q: ℝ) := by
sorry
lemma Real.equivR_nat {n: ℕ} : equivR n = (n: ℝ) := equivR_ratCast
lemma Real.equivR_int {n: ℤ} : equivR n = (n: ℝ) := equivR_ratCast
----
-- We then want to set up a way to convert from the Real `LIM` to the ℝ `Real.mk`
-- To do this we need a few things:
-- Convertion between the notions of Cauchy Sequences
theorem Sequence.IsCauchy.to_IsCauSeq {a: ℕ → ℚ} (ha: IsCauchy a) : IsCauSeq _root_.abs a := by
sorry
-- Convertion of an `IsCauchy` to a `CauSeq`
abbrev Sequence.IsCauchy.CauSeq {a: ℕ → ℚ} : (ha: IsCauchy a) → CauSeq ℚ _root_.abs :=
(⟨a, ·.to_IsCauSeq⟩)
-- We then set up the conversion from Sequence.Equiv to CauSeq.LimZero because
-- it is the equivalence relation
example {a b: CauSeq ℚ abs} : a ≈ b ↔ CauSeq.LimZero (a - b) := by rfl
theorem Sequence.Equiv.LimZero {a b: ℕ → ℚ} (ha: IsCauchy a) (hb: IsCauchy b) (h:Equiv a b)
: CauSeq.LimZero (ha.CauSeq - hb.CauSeq) := by
sorry
-- We can now use it to convert between different functions in Real.mk
theorem Real.mk_eq_mk {a b: ℕ → ℚ} (ha : Sequence.IsCauchy a) (hb : Sequence.IsCauchy b) (hab: Sequence.Equiv a b)
: Real.mk ha.CauSeq = Real.mk hb.CauSeq := Real.mk_eq.mpr (hab.LimZero ha hb)
-- Both directions of the equivalence
theorem Sequence.Equiv_iff_LimZero {a b: ℕ → ℚ} (ha: IsCauchy a) (hb: IsCauchy b)
: Equiv a b ↔ CauSeq.LimZero (ha.CauSeq - hb.CauSeq) := by
refine ⟨(·.LimZero ha hb), ?_⟩
sorry
----
-- We create some cauchy sequences with useful properties
-- We show that for any sequence, it will eventually be arbitrarily close to its LIM
open Real in
theorem Sequence.difference_approaches_zero {a: ℕ → ℚ} (ha: Sequence.IsCauchy a) :
∀ε > 0, ∃N, ∀n ≥ N, |LIM a - a n| ≤ (ε: ℚ) := by
sorry
-- There exists a Cauchy sequence entirely above the LIM
theorem Real.exists_equiv_above {a: ℕ → ℚ} (ha: Sequence.IsCauchy a)
: ∃(b: ℕ → ℚ), Sequence.IsCauchy b ∧ Sequence.Equiv a b ∧ ∀n, LIM a ≤ b n := by
sorry
-- There exists a Cauchy sequence entirely below the LIM
theorem Real.exists_equiv_below {a: ℕ → ℚ} (ha: Sequence.IsCauchy a)
: ∃(b: ℕ → ℚ), Sequence.IsCauchy b ∧ Sequence.Equiv a b ∧ ∀n, b n ≤ LIM a := by
sorry
----
-- useful theorems for the following proof
#check Real.mk_le
#check Real.mk_le_of_forall_le
#check Real.mk_const
-- Transform a `Real` to an `ℝ` by going through Cauchy Sequences
-- we can use the conversion of Real.mk_eq to use different sequences to show different parts
theorem Real.equivR_eq' {a: ℕ → ℚ} (ha: Sequence.IsCauchy a)
: (LIM a).equivR = Real.mk ha.CauSeq := by
by_cases hq: ∃(q: ℚ), q = LIM a
· sorry
show sSup (Rat.cast '' (LIM a).toSet_Rat) = _
refine IsLUB.csSup_eq ⟨?_, ?_⟩ (Set.Nonempty.image _ <| Real.toSet_Rat_nonempty _)
· -- show that `Real.mk ha.CauSeq` is an upper bound
intro _ hy
obtain ⟨y, hy, h⟩ := Set.mem_image _ _ _ |>.mp hy
rw [← h, show (y: ℝ) = Real.mk (CauSeq.const _ y) from rfl]
sorry
-- show that for any other upper bound, `Real.mk ha.CauSeq` is smaller
intro M hM
sorry
lemma Real.equivR_eq (x: Real) : ∃(a : ℕ → ℚ) (ha: Sequence.IsCauchy a),
x = LIM a ∧ x.equivR = Real.mk ha.CauSeq := by
obtain ⟨a, ha, rfl⟩ := x.eq_lim
exact ⟨a, ha, rfl, equivR_eq' ha⟩
/-- The isomorphism preserves order and ring operations. -/
noncomputable abbrev Real.equivR_ordered_ring : Real ≃+*o ℝ where
toEquiv := equivR
map_add' := by sorry
map_mul' := by sorry
map_le_map_iff' := by sorry
-- helpers for converting properties between Real and ℝ
lemma Real.equivR_map_mul {x y : Real} : equivR (x * y) = equivR x * equivR y :=
equivR_ordered_ring.map_mul _ _
lemma Real.equivR_map_inv {x: Real} : equivR (x⁻¹) = (equivR x)⁻¹ :=
map_inv₀ equivR_ordered_ring _
theorem Real.equivR_map_pos {x: Real} : 0 < x ↔ 0 < equivR x := by sorry
theorem Real.equivR_map_nonneg {x: Real} : 0 ≤ x ↔ 0 ≤ equivR x := by sorry
-- Showing equivalence of the different pows
theorem Real.pow_of_equivR (x:Real) (n:ℕ) : equivR (x^n) = (equivR x)^n := by
sorry
theorem Real.zpow_of_equivR (x:Real) (n:ℤ) : equivR (x^n) = (equivR x)^n := by
sorry
theorem Real.ratPow_of_equivR (x:Real) (q:ℚ) : equivR (x^q) = (equivR x)^(q:ℝ) := by
sorry
end Chapter5