Skip to content

Commit 4199e29

Browse files
committed
feat: add strictMono_mersenne and corollaries (#12687)
Incl. upgrade of `mersenne_pos` to an `Iff`. Also add a `positivity` extension and use it in a few lemmas.
1 parent 6a17032 commit 4199e29

File tree

2 files changed

+45
-14
lines changed

2 files changed

+45
-14
lines changed

Archive/Wiedijk100Theorems/PerfectNumbers.lean

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ theorem perfect_two_pow_mul_mersenne_of_prime (k : ℕ) (pr : (mersenne (k + 1))
5353
(Nat.prime_two.coprime_pow_of_not_dvd (odd_mersenne_succ _)),
5454
sigma_two_pow_eq_mersenne_succ]
5555
· simp [pr, Nat.prime_two, sigma_one_apply]
56-
· apply mul_pos (pow_pos _ k) (mersenne_pos (Nat.succ_pos k))
57-
norm_num
56+
· positivity
5857
#align theorems_100.nat.perfect_two_pow_mul_mersenne_of_prime Theorems100.Nat.perfect_two_pow_mul_mersenne_of_prime
5958

6059
theorem ne_zero_of_prime_mersenne (k : ℕ) (pr : (mersenne (k + 1)).Prime) : k ≠ 0 := by
@@ -94,7 +93,7 @@ theorem eq_two_pow_mul_prime_mersenne_of_even_perfect {n : ℕ} (ev : Even n) (p
9493
(Nat.prime_two.coprime_pow_of_not_dvd (odd_mersenne_succ _)) (Dvd.intro _ perf) with
9594
⟨j, rfl⟩
9695
rw [← mul_assoc, mul_comm _ (mersenne _), mul_assoc] at perf
97-
have h := mul_left_cancel₀ (ne_of_gt (mersenne_pos (Nat.succ_pos _))) perf
96+
have h := mul_left_cancel₀ (by positivity) perf
9897
rw [sigma_one_apply, Nat.sum_divisors_eq_sum_properDivisors_add_self, ← succ_mersenne, add_mul,
9998
one_mul, add_comm] at h
10099
have hj := add_left_cancel h

Mathlib/NumberTheory/LucasLehmer.lean

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,49 @@ def mersenne (p : ℕ) : ℕ :=
4343
2 ^ p - 1
4444
#align mersenne mersenne
4545

46-
theorem mersenne_pos {p : ℕ} (h : 0 < p) : 0 < mersenne p := by
47-
dsimp [mersenne]
48-
calc
49-
0 < 2 ^ 1 - 1 := by norm_num
50-
_ ≤ 2 ^ p - 1 := Nat.sub_le_sub_right (Nat.pow_le_pow_of_le_right (Nat.succ_pos 1) h) 1
46+
theorem strictMono_mersenne : StrictMono mersenne := fun m n h ↦
47+
(Nat.sub_lt_sub_iff_right <| Nat.one_le_pow _ _ two_pos).2 <| by gcongr; norm_num1
48+
49+
@[simp]
50+
theorem mersenne_lt_mersenne {p q : ℕ} : mersenne p < mersenne q ↔ p < q :=
51+
strictMono_mersenne.lt_iff_lt
52+
53+
@[gcongr] protected alias ⟨_, GCongr.mersenne_lt_mersenne⟩ := mersenne_lt_mersenne
54+
55+
@[simp]
56+
theorem mersenne_le_mersenne {p q : ℕ} : mersenne p ≤ mersenne q ↔ p ≤ q :=
57+
strictMono_mersenne.le_iff_le
58+
59+
@[gcongr] protected alias ⟨_, GCongr.mersenne_le_mersenne⟩ := mersenne_le_mersenne
60+
61+
@[simp] theorem mersenne_zero : mersenne 0 = 0 := rfl
62+
63+
@[simp] theorem mersenne_pos {p : ℕ} : 0 < mersenne p ↔ 0 < p := mersenne_lt_mersenne (p := 0)
5164
#align mersenne_pos mersenne_pos
5265

53-
theorem one_lt_mersenne {p : ℕ} (hp : 1 < p) : 1 < mersenne p :=
54-
lt_tsub_iff_right.2 <|
55-
calc 1 + 1 = 2 ^ 1 := by rw [one_add_one_eq_two, pow_one]
56-
_ < 2 ^ p := pow_lt_pow_right one_lt_two hp
66+
namespace Mathlib.Meta.Positivity
67+
68+
open Lean Meta Qq Function
69+
70+
alias ⟨_, mersenne_pos_of_pos⟩ := mersenne_pos
71+
72+
/-- Extension for the `positivity` tactic: `mersenne`. -/
73+
@[positivity mersenne _]
74+
def evalMersenne : PositivityExt where eval {u α} _zα _pα e := do
75+
match u, α, e with
76+
| 0, ~q(ℕ), ~q(mersenne $a) =>
77+
let ra ← core q(inferInstance) q(inferInstance) a
78+
assertInstancesCommute
79+
match ra with
80+
| .positive pa => pure (.positive q(mersenne_pos_of_pos $pa))
81+
| _ => pure (.nonnegative q(Nat.zero_le (mersenne $a)))
82+
| _, _, _ => throwError "not mersenne"
83+
84+
end Mathlib.Meta.Positivity
85+
86+
@[simp]
87+
theorem one_lt_mersenne {p : ℕ} : 1 < mersenne p ↔ 1 < p :=
88+
mersenne_lt_mersenne (p := 1)
5789

5890
@[simp]
5991
theorem succ_mersenne (k : ℕ) : mersenne k + 1 = 2 ^ k := by
@@ -415,7 +447,7 @@ Here and below, we introduce `p' = p - 2`, in order to avoid using subtraction i
415447

416448
/-- If `1 < p`, then `q p`, the smallest prime factor of `mersenne p`, is more than 2. -/
417449
theorem two_lt_q (p' : ℕ) : 2 < q (p' + 2) := by
418-
refine (minFac_prime (one_lt_mersenne ?_).ne').two_le.lt_of_ne' ?_
450+
refine (minFac_prime (one_lt_mersenne.2 ?_).ne').two_le.lt_of_ne' ?_
419451
· exact le_add_left _ _
420452
· rw [Ne, minFac_eq_two_iff, mersenne, Nat.pow_succ']
421453
exact Nat.two_not_dvd_two_mul_sub_one Nat.one_le_two_pow
@@ -527,7 +559,7 @@ theorem lucas_lehmer_sufficiency (p : ℕ) (w : 1 < p) : LucasLehmerTest p → (
527559
rw [z] at a
528560
rw [z] at t
529561
have h₁ := order_ineq p' t
530-
have h₂ := Nat.minFac_sq_le_self (mersenne_pos (Nat.lt_of_succ_lt w)) a
562+
have h₂ := Nat.minFac_sq_le_self (mersenne_pos.2 (Nat.lt_of_succ_lt w)) a
531563
have h := lt_of_lt_of_le h₁ h₂
532564
exact not_lt_of_ge (Nat.sub_le _ _) h
533565
#align lucas_lehmer_sufficiency lucas_lehmer_sufficiency

0 commit comments

Comments
 (0)