Skip to content

Commit 55dfeba

Browse files
mo271qawbecrdteyAntoine Chambert-Loirkim-em
committed
feat: port NumberTheory.Bertrand (leanprover-community#4777)
Co-authored-by: Moritz Firsching <firsching@google.com> Co-authored-by: qawbecrdtey <qawbecrdtey@naver.com> Co-authored-by: Antoine Chambert-Loir <antoine.chambert-loir@math.univ-paris-diderot.fr> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
1 parent b4ae732 commit 55dfeba

File tree

2 files changed

+261
-0
lines changed

2 files changed

+261
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2312,6 +2312,7 @@ import Mathlib.NumberTheory.ArithmeticFunction
23122312
import Mathlib.NumberTheory.Basic
23132313
import Mathlib.NumberTheory.Bernoulli
23142314
import Mathlib.NumberTheory.BernoulliPolynomials
2315+
import Mathlib.NumberTheory.Bertrand
23152316
import Mathlib.NumberTheory.ClassNumber.AdmissibleAbs
23162317
import Mathlib.NumberTheory.ClassNumber.AdmissibleAbsoluteValue
23172318
import Mathlib.NumberTheory.ClassNumber.AdmissibleCardPowDegree

Mathlib/NumberTheory/Bertrand.lean

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
/-
2+
Copyright (c) 2020 Patrick Stevens. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Patrick Stevens, Bolton Bailey
5+
6+
! This file was ported from Lean 3 source module number_theory.bertrand
7+
! leanprover-community/mathlib commit a16665637b378379689c566204817ae792ac8b39
8+
! Please do not edit these lines, except to modify the commit id
9+
! if you have ported upstream changes.
10+
-/
11+
import Mathlib.Data.Nat.Choose.Factorization
12+
import Mathlib.Data.Nat.PrimeNormNum
13+
import Mathlib.NumberTheory.Primorial
14+
import Mathlib.Analysis.Convex.SpecificFunctions.Basic
15+
import Mathlib.Analysis.Convex.SpecificFunctions.Deriv
16+
17+
/-!
18+
# Bertrand's Postulate
19+
20+
This file contains a proof of Bertrand's postulate: That between any positive number and its
21+
double there is a prime.
22+
23+
The proof follows the outline of the Erdős proof presented in "Proofs from THE BOOK": One considers
24+
the prime factorization of `(2 * n).choose n`, and splits the constituent primes up into various
25+
groups, then upper bounds the contribution of each group. This upper bounds the central binomial
26+
coefficient, and if the postulate does not hold, this upper bound conflicts with a simple lower
27+
bound for large enough `n`. This proves the result holds for large enough `n`, and for smaller `n`
28+
an explicit list of primes is provided which covers the remaining cases.
29+
30+
As in the [Metamath implementation](carneiro2015arithmetic), we rely on some optimizations from
31+
[Shigenori Tochiori](tochiori_bertrand). In particular we use the cleaner bound on the central
32+
binomial coefficient given in `Nat.four_pow_lt_mul_centralBinom`.
33+
34+
## References
35+
36+
* [M. Aigner and G. M. Ziegler _Proofs from THE BOOK_][aigner1999proofs]
37+
* [S. Tochiori, _Considering the Proof of “There is a Prime between n and 2n”_][tochiori_bertrand]
38+
* [M. Carneiro, _Arithmetic in Metamath, Case Study: Bertrand's Postulate_][carneiro2015arithmetic]
39+
40+
## Tags
41+
42+
Bertrand, prime, binomial coefficients
43+
-/
44+
45+
46+
open scoped BigOperators
47+
48+
section Real
49+
50+
open Real
51+
52+
namespace Bertrand
53+
54+
/-- A reified version of the `Bertrand.main_inequality` below.
55+
This is not best possible: it actually holds for 464 ≤ x.
56+
-/
57+
theorem real_main_inequality {x : ℝ} (n_large : (512 : ℝ) ≤ x) :
58+
x * (2 * x) ^ sqrt (2 * x) * 4 ^ (2 * x / 3) ≤ 4 ^ x := by
59+
let f : ℝ → ℝ := fun x => log x + sqrt (2 * x) * log (2 * x) - log 4 / 3 * x
60+
have hf' : ∀ x, 0 < x → 0 < x * (2 * x) ^ sqrt (2 * x) / 4 ^ (x / 3) := fun x h =>
61+
div_pos (mul_pos h (rpow_pos_of_pos (mul_pos two_pos h) _)) (rpow_pos_of_pos four_pos _)
62+
have hf : ∀ x, 0 < x → f x = log (x * (2 * x) ^ sqrt (2 * x) / 4 ^ (x / 3)) := by
63+
intro x h5
64+
have h6 := mul_pos (zero_lt_two' ℝ) h5
65+
have h7 := rpow_pos_of_pos h6 (sqrt (2 * x))
66+
rw [log_div (mul_pos h5 h7).ne' (rpow_pos_of_pos four_pos _).ne', log_mul h5.ne' h7.ne',
67+
log_rpow h6, log_rpow zero_lt_four, ← mul_div_right_comm, ← mul_div, mul_comm x]
68+
have h5 : 0 < x := lt_of_lt_of_le (by norm_num1) n_large
69+
rw [← div_le_one (rpow_pos_of_pos four_pos x), ← div_div_eq_mul_div, ← rpow_sub four_pos, ←
70+
mul_div 2 x, mul_div_left_comm, ← mul_one_sub, (by norm_num1 : (1 : ℝ) - 2 / 3 = 1 / 3),
71+
mul_one_div, ← log_nonpos_iff (hf' x h5), ← hf x h5]
72+
-- porting note: the proof was rewritten, because it was too slow
73+
have h : ConcaveOn ℝ (Set.Ioi 0.5) f := by
74+
apply ConcaveOn.sub
75+
apply ConcaveOn.add
76+
exact strictConcaveOn_log_Ioi.concaveOn.subset
77+
(Set.Ioi_subset_Ioi (by norm_num)) (convex_Ioi 0.5)
78+
convert ((strictConcaveOn_sqrt_mul_log_Ioi.concaveOn.comp_linearMap
79+
((2 : ℝ) • LinearMap.id))) using 1
80+
. ext x
81+
simp only [Set.mem_Ioi, Set.mem_preimage, LinearMap.smul_apply,
82+
LinearMap.id_coe, id_eq, smul_eq_mul]
83+
rw [← mul_lt_mul_left (two_pos)]
84+
norm_num1
85+
rfl
86+
apply ConvexOn.smul
87+
refine div_nonneg (log_nonneg (by norm_num1)) (by norm_num1)
88+
exact convexOn_id (convex_Ioi (0.5 : ℝ))
89+
suffices ∃ x1 x2, 0.5 < x1 ∧ x1 < x2 ∧ x2 ≤ x ∧ 0 ≤ f x1 ∧ f x2 ≤ 0 by
90+
obtain ⟨x1, x2, h1, h2, h0, h3, h4⟩ := this
91+
exact (h.right_le_of_le_left'' h1 ((h1.trans h2).trans_le h0) h2 h0 (h4.trans h3)).trans h4
92+
refine' ⟨18, 512, by norm_num1, by norm_num1, n_large, _, _⟩
93+
. have : sqrt (2 * 18) = 6 := (sqrt_eq_iff_mul_self_eq_of_pos (by norm_num1)).mpr (by norm_num1)
94+
rw [hf, log_nonneg_iff, this]
95+
rw [one_le_div] <;> norm_num1
96+
apply le_trans _ (le_mul_of_one_le_left _ _) <;> norm_num1
97+
apply Real.rpow_le_rpow <;> norm_num1
98+
apply rpow_nonneg_of_nonneg ; norm_num1
99+
apply rpow_pos_of_pos ; norm_num1
100+
apply hf' 18 ; norm_num1
101+
norm_num1
102+
. have : sqrt (2 * 512) = 32 :=
103+
(sqrt_eq_iff_mul_self_eq_of_pos (by norm_num1)).mpr (by norm_num1)
104+
rw [hf, log_nonpos_iff (hf' _ _), this, div_le_one] <;> norm_num1
105+
have : (512 : ℝ) = 2 ^ (9 : ℕ)
106+
. rw [rpow_nat_cast 2 9] ; norm_num1
107+
conv_lhs => rw [this]
108+
have : (1024 : ℝ) = 2 ^ (10 : ℕ)
109+
. rw [rpow_nat_cast 2 10] ; norm_num1
110+
rw [this, ← rpow_mul, ← rpow_add] <;> norm_num1
111+
have : (4 : ℝ) = 2 ^ (2 : ℕ)
112+
. rw [rpow_nat_cast 2 2] ; norm_num1
113+
rw [this, ← rpow_mul] <;> norm_num1
114+
apply rpow_le_rpow_of_exponent_le <;> norm_num1
115+
apply rpow_pos_of_pos four_pos
116+
#align bertrand.real_main_inequality Bertrand.real_main_inequality
117+
118+
end Bertrand
119+
120+
end Real
121+
122+
section Nat
123+
124+
open Nat
125+
126+
/-- The inequality which contradicts Bertrand's postulate, for large enough `n`.
127+
-/
128+
theorem bertrand_main_inequality {n : ℕ} (n_large : 512 ≤ n) :
129+
n * (2 * n) ^ sqrt (2 * n) * 4 ^ (2 * n / 3) ≤ 4 ^ n := by
130+
rw [← @cast_le ℝ]
131+
simp only [cast_add, cast_one, cast_mul, cast_pow, ← Real.rpow_nat_cast]
132+
have n_pos : 0 < n := (by decide : 0 < 512).trans_le n_large
133+
have n2_pos : 12 * n := mul_pos (by decide) n_pos
134+
refine' _root_.trans (mul_le_mul _ _ _ _)
135+
(Bertrand.real_main_inequality (by exact_mod_cast n_large))
136+
· refine' mul_le_mul_of_nonneg_left _ (Nat.cast_nonneg _)
137+
refine' Real.rpow_le_rpow_of_exponent_le (by exact_mod_cast n2_pos) _
138+
exact_mod_cast Real.nat_sqrt_le_real_sqrt
139+
· exact Real.rpow_le_rpow_of_exponent_le (by norm_num1) (cast_div_le.trans (by norm_cast))
140+
· exact Real.rpow_nonneg_of_nonneg (by norm_num1) _
141+
· refine' mul_nonneg (Nat.cast_nonneg _) _
142+
exact Real.rpow_nonneg_of_nonneg (mul_nonneg zero_le_two (Nat.cast_nonneg _)) _
143+
#align bertrand_main_inequality bertrand_main_inequality
144+
145+
/-- A lemma that tells us that, in the case where Bertrand's postulate does not hold, the prime
146+
factorization of the central binomial coefficent only has factors at most `2 * n / 3 + 1`.
147+
-/
148+
theorem centralBinom_factorization_small (n : ℕ) (n_large : 2 < n)
149+
(no_prime : ¬∃ p : ℕ, p.Prime ∧ n < p ∧ p ≤ 2 * n) :
150+
centralBinom n = ∏ p in Finset.range (2 * n / 3 + 1), p ^ (centralBinom n).factorization p := by
151+
refine' (Eq.trans _ n.prod_pow_factorization_centralBinom).symm
152+
apply Finset.prod_subset
153+
· exact Finset.range_subset.2 (add_le_add_right (Nat.div_le_self _ _) _)
154+
intro x hx h2x
155+
rw [Finset.mem_range, lt_succ_iff] at hx h2x
156+
rw [not_le, div_lt_iff_lt_mul' three_pos, mul_comm x] at h2x
157+
replace no_prime := not_exists.mp no_prime x
158+
rw [← and_assoc, not_and', not_and_or, not_lt] at no_prime
159+
cases' no_prime hx with h h
160+
· rw [factorization_eq_zero_of_non_prime n.centralBinom h, Nat.pow_zero]
161+
· rw [factorization_centralBinom_of_two_mul_self_lt_three_mul n_large h h2x, Nat.pow_zero]
162+
#align central_binom_factorization_small centralBinom_factorization_small
163+
164+
/-- An upper bound on the central binomial coefficient used in the proof of Bertrand's postulate.
165+
The bound splits the prime factors of `centralBinom n` into those
166+
1. At most `sqrt (2 * n)`, which contribute at most `2 * n` for each such prime.
167+
2. Between `sqrt (2 * n)` and `2 * n / 3`, which contribute at most `4^(2 * n / 3)` in total.
168+
3. Between `2 * n / 3` and `n`, which do not exist.
169+
4. Between `n` and `2 * n`, which would not exist in the case where Bertrand's postulate is false.
170+
5. Above `2 * n`, which do not exist.
171+
-/
172+
theorem centralBinom_le_of_no_bertrand_prime (n : ℕ) (n_big : 2 < n)
173+
(no_prime : ¬∃ p : ℕ, Nat.Prime p ∧ n < p ∧ p ≤ 2 * n) :
174+
centralBinom n ≤ (2 * n) ^ sqrt (2 * n) * 4 ^ (2 * n / 3) := by
175+
have n_pos : 0 < n := (Nat.zero_le _).trans_lt n_big
176+
have n2_pos : 12 * n := mul_pos (zero_lt_two' ℕ) n_pos
177+
let S := (Finset.range (2 * n / 3 + 1)).filter Nat.Prime
178+
let f x := x ^ n.centralBinom.factorization x
179+
have : (∏ x : ℕ in S, f x) = ∏ x : ℕ in Finset.range (2 * n / 3 + 1), f x := by
180+
refine' Finset.prod_filter_of_ne fun p _ h => _
181+
contrapose! h; dsimp only
182+
rw [factorization_eq_zero_of_non_prime n.centralBinom h, _root_.pow_zero]
183+
rw [centralBinom_factorization_small n n_big no_prime, ← this, ←
184+
Finset.prod_filter_mul_prod_filter_not S (· ≤ sqrt (2 * n))]
185+
apply mul_le_mul'
186+
· refine' (Finset.prod_le_prod' fun p _ => (_ : f p ≤ 2 * n)).trans _
187+
· exact pow_factorization_choose_le (mul_pos two_pos n_pos)
188+
have : (Finset.Icc 1 (sqrt (2 * n))).card = sqrt (2 * n) := by rw [card_Icc, Nat.add_sub_cancel]
189+
rw [Finset.prod_const]
190+
refine' pow_le_pow n2_pos ((Finset.card_le_of_subset fun x hx => _).trans this.le)
191+
obtain ⟨h1, h2⟩ := Finset.mem_filter.1 hx
192+
exact Finset.mem_Icc.mpr ⟨(Finset.mem_filter.1 h1).2.one_lt.le, h2⟩
193+
· refine' le_trans _ (primorial_le_4_pow (2 * n / 3))
194+
refine' (Finset.prod_le_prod' fun p hp => (_ : f p ≤ p)).trans _
195+
· obtain ⟨h1, h2⟩ := Finset.mem_filter.1 hp
196+
refine' (pow_le_pow (Finset.mem_filter.1 h1).2.one_lt.le _).trans (pow_one p).le
197+
exact Nat.factorization_choose_le_one (sqrt_lt'.mp <| not_le.1 h2)
198+
refine' Finset.prod_le_prod_of_subset_of_one_le' (Finset.filter_subset _ _) _
199+
exact fun p hp _ => (Finset.mem_filter.1 hp).2.one_lt.le
200+
#align central_binom_le_of_no_bertrand_prime centralBinom_le_of_no_bertrand_prime
201+
202+
namespace Nat
203+
204+
/-- Proves that Bertrand's postulate holds for all sufficiently large `n`.
205+
-/
206+
theorem exists_prime_lt_and_le_two_mul_eventually (n : ℕ) (n_big : 512 ≤ n) :
207+
∃ p : ℕ, p.Prime ∧ n < p ∧ p ≤ 2 * n := by
208+
-- Assume there is no prime in the range.
209+
by_contra no_prime
210+
-- Then we have the above sub-exponential bound on the size of this central binomial coefficient.
211+
-- We now couple this bound with an exponential lower bound on the central binomial coefficient,
212+
-- yielding an inequality which we have seen is false for large enough n.
213+
have H1 : n * (2 * n) ^ sqrt (2 * n) * 4 ^ (2 * n / 3) ≤ 4 ^ n := bertrand_main_inequality n_big
214+
have H2 : 4 ^ n < n * n.centralBinom :=
215+
Nat.four_pow_lt_mul_centralBinom n (le_trans (by norm_num1) n_big)
216+
have H3 : n.centralBinom ≤ (2 * n) ^ sqrt (2 * n) * 4 ^ (2 * n / 3) :=
217+
centralBinom_le_of_no_bertrand_prime n (lt_of_lt_of_le (by norm_num1) n_big) no_prime
218+
rw [mul_assoc] at H1 ; exact not_le.2 H2 ((mul_le_mul_left' H3 n).trans H1)
219+
#align nat.exists_prime_lt_and_le_two_mul_eventually Nat.exists_prime_lt_and_le_two_mul_eventually
220+
221+
/-- Proves that Bertrand's postulate holds over all positive naturals less than n by identifying a
222+
descending list of primes, each no more than twice the next, such that the list contains a witness
223+
for each number ≤ n.
224+
-/
225+
theorem exists_prime_lt_and_le_two_mul_succ {n} (q) {p : ℕ} (prime_p : Nat.Prime p)
226+
(covering : p ≤ 2 * q) (H : n < q → ∃ p : ℕ, p.Prime ∧ n < p ∧ p ≤ 2 * n) (hn : n < p) :
227+
∃ p : ℕ, p.Prime ∧ n < p ∧ p ≤ 2 * n := by
228+
by_cases p ≤ 2 * n; · exact ⟨p, prime_p, hn, h⟩
229+
exact H (lt_of_mul_lt_mul_left' (lt_of_lt_of_le (not_le.1 h) covering))
230+
#align nat.exists_prime_lt_and_le_two_mul_succ Nat.exists_prime_lt_and_le_two_mul_succ
231+
232+
/--
233+
**Bertrand's Postulate**: For any positive natural number, there is a prime which is greater than
234+
it, but no more than twice as large.
235+
-/
236+
theorem exists_prime_lt_and_le_two_mul (n : ℕ) (hn0 : n ≠ 0) :
237+
∃ p, Nat.Prime p ∧ n < p ∧ p ≤ 2 * n := by
238+
-- Split into cases whether `n` is large or small
239+
cases' lt_or_le 511 n with h h
240+
-- If `n` is large, apply the lemma derived from the inequalities on the central binomial
241+
-- coefficient.
242+
· exact exists_prime_lt_and_le_two_mul_eventually n h
243+
replace h : n < 521 := h.trans_lt (by norm_num1)
244+
revert h
245+
-- For small `n`, supply a list of primes to cover the initial cases.
246+
open Lean Elab Tactic in
247+
run_tac do
248+
for i in [317, 163, 83, 43, 23, 13, 7, 5, 3, 2] do
249+
let i : Term := quote i
250+
evalTactic
251+
(← `(tactic| refine' exists_prime_lt_and_le_two_mul_succ $i (by norm_num) (by norm_num) _))
252+
exact fun h2 => ⟨2, prime_two, h2, Nat.mul_le_mul_left 2 (Nat.pos_of_ne_zero hn0)⟩
253+
#align nat.exists_prime_lt_and_le_two_mul Nat.exists_prime_lt_and_le_two_mul
254+
255+
alias Nat.exists_prime_lt_and_le_two_mul ← bertrand
256+
#align nat.bertrand Nat.bertrand
257+
258+
end Nat
259+
260+
end Nat

0 commit comments

Comments
 (0)