Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 04e80bb

Browse files
committed
refactor(number_theory/liouville/liouville_number): review API, golf (#19126)
* Protect `liouville.irrational` and `liouville.transcendental`. * Sync file name with definition name (Liouville constant vs Liouville number). * Move auxiliary definitions and lemmas about Liouville number to `liouville_number` namespace. * Rename auxiliary definitions, golf proofs (where it doesn't affect readability).
1 parent cca4078 commit 04e80bb

3 files changed

Lines changed: 73 additions & 72 deletions

File tree

docs/overview.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ General algebra:
137137
ring of Witt vectors: 'witt_vector'
138138
perfection of a ring: 'ring.perfection'
139139
Transcendental numbers:
140-
Liouville's theorem on existence of transcendental numbers: liouville.is_transcendental
140+
Liouville's theorem on existence of transcendental numbers: 'transcendental_liouville_number'
141141

142142
Representation theory:
143143
representation : 'representation'

src/number_theory/liouville/basic.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def liouville (x : ℝ) := ∀ n : ℕ, ∃ a b : ℤ, 1 < b ∧ x ≠ a / b ∧
2929

3030
namespace liouville
3131

32-
@[protected] lemma irrational {x : ℝ} (h : liouville x) : irrational x :=
32+
protected lemma irrational {x : ℝ} (h : liouville x) : irrational x :=
3333
begin
3434
-- By contradiction, `x = a / b`, with `a ∈ ℤ`, `0 < b ∈ ℕ` is a Liouville number,
3535
rintros ⟨⟨a, b, bN0, cop⟩, rfl⟩,
@@ -169,7 +169,7 @@ begin
169169
end
170170

171171
/-- **Liouville's Theorem** -/
172-
theorem transcendental {x : ℝ} (lx : liouville x) :
172+
protected theorem transcendental {x : ℝ} (lx : liouville x) :
173173
transcendental ℤ x :=
174174
begin
175175
-- Proceed by contradiction: if `x` is algebraic, then `x` is the root (`ef0`) of a

src/number_theory/liouville/liouville_constant.lean renamed to src/number_theory/liouville/liouville_number.lean

Lines changed: 70 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import number_theory.liouville.basic
1010
1111
This file contains a construction of a family of Liouville numbers, indexed by a natural number $m$.
1212
The most important property is that they are examples of transcendental real numbers.
13-
This fact is recorded in `liouville.is_transcendental`.
13+
This fact is recorded in `transcendental_liouville_number`.
1414
1515
More precisely, for a real number $m$, Liouville's constant is
1616
$$
@@ -33,8 +33,6 @@ noncomputable theory
3333
open_locale nat big_operators
3434
open real finset
3535

36-
namespace liouville
37-
3836
/--
3937
For a real number `m`, Liouville's constant is
4038
$$
@@ -45,78 +43,80 @@ if the series does not converge, then the sum of the series is defined to be zer
4543
-/
4644
def liouville_number (m : ℝ) : ℝ := ∑' (i : ℕ), 1 / m ^ i!
4745

46+
namespace liouville_number
47+
4848
/--
49-
`liouville_number_initial_terms` is the sum of the first `k + 1` terms of Liouville's constant,
49+
`liouville_number.partial_sum` is the sum of the first `k + 1` terms of Liouville's constant,
5050
i.e.
5151
$$
5252
\sum_{i=0}^k\frac{1}{m^{i!}}.
5353
$$
5454
-/
55-
def liouville_number_initial_terms (m : ℝ) (k : ℕ) : ℝ := ∑ i in range (k+1), 1 / m ^ i!
55+
def partial_sum (m : ℝ) (k : ℕ) : ℝ := ∑ i in range (k+1), 1 / m ^ i!
5656

5757
/--
58-
`liouville_number_tail` is the sum of the series of the terms in `liouville_number m`
58+
`liouville_number.remainder` is the sum of the series of the terms in `liouville_number m`
5959
starting from `k+1`, i.e
6060
$$
6161
\sum_{i=k+1}^\infty\frac{1}{m^{i!}}.
6262
$$
6363
-/
64-
def liouville_number_tail (m : ℝ) (k : ℕ) : ℝ := ∑' i, 1 / m ^ (i + (k+1))!
65-
66-
lemma liouville_number_tail_pos {m : ℝ} (hm : 1 < m) (k : ℕ) :
67-
0 < liouville_number_tail m k :=
68-
-- replace `0` with the constantly zero series `∑ i : ℕ, 0`
69-
calc (0 : ℝ) = ∑' i : ℕ, 0 : tsum_zero.symm
70-
... < liouville_number_tail m k :
71-
-- to show that a series with non-negative terms has strictly positive sum it suffices
72-
-- to prove that
73-
tsum_lt_tsum_of_nonneg
74-
-- 1. the terms of the zero series are indeed non-negative
75-
(λ _, rfl.le)
76-
-- 2. the terms of our series are non-negative
77-
(λ i, one_div_nonneg.mpr (pow_nonneg (zero_le_one.trans hm.le) _))
78-
-- 3. one term of our series is strictly positive -- they all are, we use the first term
79-
(one_div_pos.mpr (pow_pos (zero_lt_one.trans hm) (0 + (k + 1))!)) $
80-
-- 4. our series converges -- it does since it is the tail of a converging series, though
81-
-- this is not the argument here.
82-
summable_one_div_pow_of_le hm (λ i, trans le_self_add (nat.self_le_factorial _))
64+
def remainder (m : ℝ) (k : ℕ) : ℝ := ∑' i, 1 / m ^ (i + (k+1))!
65+
66+
/-!
67+
We start with simple observations.
68+
-/
69+
70+
protected lemma summable {m : ℝ} (hm : 1 < m) : summable (λ i : ℕ, 1 / m ^ i!) :=
71+
summable_one_div_pow_of_le hm nat.self_le_factorial
72+
73+
lemma remainder_summable {m : ℝ} (hm : 1 < m) (k : ℕ) :
74+
summable (λ i : ℕ, 1 / m ^ (i + (k + 1))!) :=
75+
by convert (summable_nat_add_iff (k + 1)).2 (liouville_number.summable hm)
76+
77+
lemma remainder_pos {m : ℝ} (hm : 1 < m) (k : ℕ) : 0 < remainder m k :=
78+
tsum_pos (remainder_summable hm k) (λ _, by positivity) 0 (by positivity)
79+
80+
lemma partial_sum_succ (m : ℝ) (n : ℕ) :
81+
partial_sum m (n + 1) = partial_sum m n + 1 / m ^ (n + 1)! :=
82+
sum_range_succ _ _
8383

8484
/-- Split the sum definining a Liouville number into the first `k` term and the rest. -/
85-
lemma liouville_number_eq_initial_terms_add_tail {m : ℝ} (hm : 1 < m) (k : ℕ) :
86-
liouville_number m = liouville_number_initial_terms m k +
87-
liouville_number_tail m k :=
88-
(sum_add_tsum_nat_add _ (summable_one_div_pow_of_le hm (λ i, i.self_le_factorial))).symm
85+
lemma partial_sum_add_remainder {m : ℝ} (hm : 1 < m) (k : ℕ) :
86+
partial_sum m k + remainder m k = liouville_number m :=
87+
sum_add_tsum_nat_add _ (liouville_number.summable hm)
8988

9089
/-! We now prove two useful inequalities, before collecting everything together. -/
9190

92-
/-- Partial inequality, works with `m ∈ ℝ` satisfying `1 < m`. -/
93-
lemma tsum_one_div_pow_factorial_lt (n : ℕ) {m : ℝ} (m1 : 1 < m) :
94-
∑' (i : ℕ), 1 / m ^ (i + (n + 1))! < (1 - 1 / m)⁻¹ * (1 / m ^ (n + 1)!) :=
91+
/-- An upper estimate on the remainder. This estimate works with `m ∈ ℝ` satisfying `1 < m` and is
92+
stronger than the estimate `liouville_number.remainder_lt` below. However, the latter estimate is
93+
more useful for the proof. -/
94+
lemma remainder_lt' (n : ℕ) {m : ℝ} (m1 : 1 < m) :
95+
remainder m n < (1 - 1 / m)⁻¹ * (1 / m ^ (n + 1)!) :=
9596
-- two useful inequalities
96-
have m0 : 0 < m := (zero_lt_one.trans m1),
97-
have mi : |1 / m| < 1 :=
98-
(le_of_eq (abs_of_pos (one_div_pos.mpr m0))).trans_lt ((div_lt_one m0).mpr m1),
97+
have m0 : 0 < m := zero_lt_one.trans m1,
98+
have mi : 1 / m < 1 := (div_lt_one m0).mpr m1,
9999
calc (∑' i, 1 / m ^ (i + (n + 1))!)
100100
< ∑' i, 1 / m ^ (i + (n + 1)!) :
101101
-- to show the strict inequality between these series, we prove that:
102-
tsum_lt_tsum_of_nonneg
103-
-- 1. the first series has non-negative terms
104-
(λ b, one_div_nonneg.mpr (pow_nonneg m0.le _))
105-
-- 2. the second series dominates the first
102+
tsum_lt_tsum
103+
-- 1. the second series dominates the first
106104
(λ b, one_div_pow_le_one_div_pow_of_le m1.le (b.add_factorial_succ_le_factorial_add_succ n))
107-
-- 3. the term with index `i = 2` of the first series is strictly smaller than
105+
-- 2. the term with index `i = 2` of the first series is strictly smaller than
108106
-- the corresponding term of the second series
109-
(one_div_pow_strict_anti m1 (n.add_factorial_succ_lt_factorial_add_succ rfl.le))
107+
(one_div_pow_strict_anti m1 (n.add_factorial_succ_lt_factorial_add_succ le_rfl))
108+
-- 3. the first series is summable
109+
(remainder_summable m1 n)
110110
-- 4. the second series is summable, since its terms grow quickly
111-
(summable_one_div_pow_of_le m1 (λ j, nat.le.intro rfl))
112-
... = ∑' i, (1 / m) ^ i * (1 / m ^ (n + 1)!) :
111+
(summable_one_div_pow_of_le m1 (λ j, le_self_add))
112+
... = ∑' i : ℕ, (1 / m) ^ i * (1 / m ^ (n + 1)!) :
113113
-- split the sum in the exponent and massage
114-
by { congr, ext i, rw [pow_add, ← div_div, div_eq_mul_one_div, one_div_pow] }
114+
by simp only [pow_add, one_div, mul_inv, inv_pow]
115115
-- factor the constant `(1 / m ^ (n + 1)!)` out of the series
116116
... = (∑' i, (1 / m) ^ i) * (1 / m ^ (n + 1)!) : tsum_mul_right
117117
... = (1 - 1 / m)⁻¹ * (1 / m ^ (n + 1)!) :
118118
-- the series if the geometric series
119-
mul_eq_mul_right_iff.mpr (or.inl (tsum_geometric_of_abs_lt_1 mi))
119+
by rw [tsum_geometric_of_lt_1 (by positivity) mi]
120120

121121
lemma aux_calc (n : ℕ) {m : ℝ} (hm : 2 ≤ m) :
122122
(1 - 1 / m)⁻¹ * (1 / m ^ (n + 1)!) ≤ 1 / (m ^ n!) ^ n :=
@@ -142,51 +142,52 @@ calc (1 - 1 / m)⁻¹ * (1 / m ^ (n + 1)!) ≤ 2 * (1 / m ^ (n + 1)!) :
142142
end
143143
... = 1 / (m ^ n!) ^ n : congr_arg ((/) 1) (pow_mul m n! n)
144144

145+
/-- An upper estimate on the remainder. This estimate works with `m ∈ ℝ` satisfying `2 ≤ m` and is
146+
weaker than the estimate `liouville_number.remainder_lt'` above. However, this estimate is
147+
more useful for the proof. -/
148+
lemma remainder_lt (n : ℕ) {m : ℝ} (m2 : 2 ≤ m) :
149+
remainder m n < 1 / (m ^ n!) ^ n :=
150+
(remainder_lt' n $ one_lt_two.trans_le m2).trans_le (aux_calc _ m2)
151+
145152
/-! Starting from here, we specialize to the case in which `m` is a natural number. -/
146153

147154
/-- The sum of the `k` initial terms of the Liouville number to base `m` is a ratio of natural
148155
numbers where the denominator is `m ^ k!`. -/
149-
lemma liouville_number_rat_initial_terms {m : ℕ} (hm : 0 < m) (k : ℕ) :
150-
∃ p : ℕ, liouville_number_initial_terms m k = p / m ^ k! :=
156+
lemma partial_sum_eq_rat {m : ℕ} (hm : 0 < m) (k : ℕ) :
157+
∃ p : ℕ, partial_sum m k = p / m ^ k! :=
151158
begin
152159
induction k with k h,
153-
{ exact ⟨1, by rw [liouville_number_initial_terms, range_one, sum_singleton, nat.cast_one]⟩ },
160+
{ exact ⟨1, by rw [partial_sum, range_one, sum_singleton, nat.cast_one]⟩ },
154161
{ rcases h with ⟨p_k, h_k⟩,
155162
use p_k * (m ^ ((k + 1)! - k!)) + 1,
156-
unfold liouville_number_initial_terms at h_k ⊢,
157-
rw [sum_range_succ, h_k, div_add_div, div_eq_div_iff, add_mul],
163+
rw [partial_sum_succ, h_k, div_add_div, div_eq_div_iff, add_mul],
158164
{ norm_cast,
159-
rw [add_mul, one_mul, nat.factorial_succ,
160-
show k.succ * k! - k! = (k.succ - 1) * k!, by rw [tsub_mul, one_mul],
161-
nat.succ_sub_one, add_mul, one_mul, pow_add],
165+
rw [add_mul, one_mul, nat.factorial_succ, add_mul, one_mul, add_tsub_cancel_right, pow_add],
162166
simp [mul_assoc] },
163-
refine mul_ne_zero_iff.mpr ⟨_, _⟩,
164-
all_goals { exact pow_ne_zero _ (nat.cast_ne_zero.mpr hm.ne.symm) } }
167+
all_goals { positivity } }
165168
end
166169

167-
theorem is_liouville {m : ℕ} (hm : 2 ≤ m) :
170+
end liouville_number
171+
172+
open liouville_number
173+
174+
theorem liouville_liouville_number {m : ℕ} (hm : 2 ≤ m) :
168175
liouville (liouville_number m) :=
169176
begin
170177
-- two useful inequalities
171178
have mZ1 : 1 < (m : ℤ), { norm_cast, exact one_lt_two.trans_le hm },
172179
have m1 : 1 < (m : ℝ), { norm_cast, exact one_lt_two.trans_le hm },
173180
intro n,
174181
-- the first `n` terms sum to `p / m ^ k!`
175-
rcases liouville_number_rat_initial_terms (zero_lt_two.trans_le hm) n with ⟨p, hp⟩,
182+
rcases partial_sum_eq_rat (zero_lt_two.trans_le hm) n with ⟨p, hp⟩,
176183
refine ⟨p, m ^ n!, one_lt_pow mZ1 n.factorial_ne_zero, _⟩,
177184
push_cast,
178185
-- separate out the sum of the first `n` terms and the rest
179-
rw [liouville_number_eq_initial_terms_add_tail m1 n,
180-
← hp, add_sub_cancel', abs_of_nonneg (liouville_number_tail_pos m1 _).le],
181-
exact ⟨((lt_add_iff_pos_right _).mpr (liouville_number_tail_pos m1 n)).ne.symm,
182-
(tsum_one_div_pow_factorial_lt n m1).trans_le
183-
(aux_calc _ (nat.cast_two.symm.le.trans (nat.cast_le.mpr hm)))⟩
186+
rw [← partial_sum_add_remainder m1 n, ← hp],
187+
have hpos := remainder_pos m1 n,
188+
simpa [abs_of_pos hpos, hpos.ne'] using @remainder_lt n m (by assumption_mod_cast)
184189
end
185190

186-
/- Placing this lemma outside of the `open/closed liouville`-namespace would allow to remove
187-
`_root_.`, at the cost of some other small weirdness. -/
188-
lemma is_transcendental {m : ℕ} (hm : 2 ≤ m) :
189-
_root_.transcendental ℤ (liouville_number m) :=
190-
transcendental (is_liouville hm)
191-
192-
end liouville
191+
lemma transcendental_liouville_number {m : ℕ} (hm : 2 ≤ m) :
192+
transcendental ℤ (liouville_number m) :=
193+
(liouville_liouville_number hm).transcendental

0 commit comments

Comments
 (0)