Skip to content

Commit 3a0fa9d

Browse files
committed
feat(ArithmeticFunction): lemmas about positivity (#28789)
Add lemmas like `σ k n = 0 ↔ n = 0`. Also add `positivity` extensions for `zeta` and `sigma`.
1 parent 31e27b3 commit 3a0fa9d

File tree

2 files changed

+62
-4
lines changed

2 files changed

+62
-4
lines changed

Mathlib/NumberTheory/ArithmeticFunction.lean

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,10 @@ theorem zeta_apply {x : ℕ} : ζ x = if x = 0 then 0 else 1 :=
393393
theorem zeta_apply_ne {x : ℕ} (h : x ≠ 0) : ζ x = 1 :=
394394
if_neg h
395395

396+
theorem zeta_eq_zero {x : ℕ} : ζ x = 0 ↔ x = 0 := by simp [zeta]
397+
398+
theorem zeta_pos {x : ℕ} : 0 < ζ x ↔ 0 < x := by simp [Nat.pos_iff_ne_zero]
399+
396400
theorem coe_zeta_smul_apply {M} [Semiring R] [AddCommMonoid M] [MulAction R M]
397401
{f : ArithmeticFunction M} {x : ℕ} :
398402
((↑ζ : ArithmeticFunction R) • f) x = ∑ i ∈ divisors x, f i := by
@@ -821,6 +825,19 @@ scoped[ArithmeticFunction.sigma] notation "σ" => ArithmeticFunction.sigma
821825
theorem sigma_apply {k n : ℕ} : σ k n = ∑ d ∈ divisors n, d ^ k :=
822826
rfl
823827

828+
@[simp]
829+
theorem sigma_eq_zero {k n : ℕ} : σ k n = 0 ↔ n = 0 := by
830+
rcases eq_or_ne n 0 with rfl | hn
831+
· simp
832+
· refine iff_of_false ?_ hn
833+
simp_rw [ArithmeticFunction.sigma_apply, Finset.sum_eq_zero_iff, not_forall]
834+
use 1
835+
simp [hn]
836+
837+
@[simp]
838+
theorem sigma_pos_iff {k n} : 0 < σ k n ↔ 0 < n := by
839+
simp [pos_iff_ne_zero]
840+
824841
theorem sigma_apply_prime_pow {k p i : ℕ} (hp : p.Prime) :
825842
σ k (p ^ i) = ∑ j ∈ .range (i + 1), p ^ (j * k) := by
826843
simp [sigma_apply, divisors_prime_pow hp, Nat.pow_mul]
@@ -844,13 +861,12 @@ theorem sigma_one (k : ℕ) : σ k 1 = 1 := by
844861
simp only [sigma_apply, divisors_one, sum_singleton, one_pow]
845862

846863
theorem sigma_pos (k n : ℕ) (hn0 : n ≠ 0) : 0 < σ k n := by
847-
rw [sigma_apply]
848-
exact sum_pos (fun d hd ↦ pow_pos (pos_of_mem_divisors hd) k) (nonempty_divisors.mpr hn0)
864+
rwa [sigma_pos_iff, pos_iff_ne_zero]
849865

850866
theorem sigma_mono (k k' n : ℕ) (hk : k ≤ k') : σ k n ≤ σ k' n := by
851867
simp_rw [sigma_apply]
852-
apply Finset.sum_le_sum
853-
exact fun d hd ↦ Nat.pow_le_pow_right (Nat.pos_of_mem_divisors hd) hk
868+
gcongr with d hd
869+
exact Nat.pos_of_mem_divisors hd
854870

855871
theorem zeta_mul_pow_eq_sigma {k : ℕ} : ζ * pow k = σ k := by
856872
ext
@@ -1018,6 +1034,13 @@ theorem cardDistinctFactors_one : ω 1 = 0 := by simp [cardDistinctFactors]
10181034
theorem cardDistinctFactors_apply {n : ℕ} : ω n = n.primeFactorsList.dedup.length :=
10191035
rfl
10201036

1037+
@[simp]
1038+
theorem cardDistinctFactors_eq_zero {n : ℕ} : ω n = 0 ↔ n ≤ 1 := by
1039+
simp [cardDistinctFactors_apply, Nat.le_one_iff_eq_zero_or_eq_one]
1040+
1041+
@[simp]
1042+
theorem cardDistinctFactors_pos {n : ℕ} : 0 < ω n ↔ 1 < n := by simp [pos_iff_ne_zero]
1043+
10211044
theorem cardDistinctFactors_eq_cardFactors_iff_squarefree {n : ℕ} (h0 : n ≠ 0) :
10221045
ω n = Ω n ↔ Squarefree n := by
10231046
rw [squarefree_iff_nodup_primeFactorsList h0, cardDistinctFactors_apply]
@@ -1379,3 +1402,32 @@ theorem sum_divisors_mul {m n : ℕ} (hmn : m.Coprime n) :
13791402
simp only [← sigma_one_apply, isMultiplicative_sigma.map_mul_of_coprime hmn]
13801403

13811404
end Nat.Coprime
1405+
1406+
namespace Mathlib.Meta.Positivity
1407+
open Lean Meta Qq
1408+
1409+
/-- Extension for `ArithmeticFunction.sigma`. -/
1410+
@[positivity ArithmeticFunction.sigma _ _]
1411+
def evalArithmeticFunctionSigma : PositivityExt where eval {u α} z p e := do
1412+
match u, α, e with
1413+
| 0, ~q(ℕ), ~q(ArithmeticFunction.sigma $k $n) =>
1414+
let rn ← core z p n
1415+
assumeInstancesCommute
1416+
match rn with
1417+
| .positive pn => return .positive q(Iff.mpr ArithmeticFunction.sigma_pos_iff $pn)
1418+
| _ => return .nonnegative q(Nat.zero_le _)
1419+
| _, _, _ => throwError "not ArithmeticFunction.sigma"
1420+
1421+
/-- Extension for `ArithmeticFunction.zeta`. -/
1422+
@[positivity ArithmeticFunction.zeta _]
1423+
def evalArithmeticFunctionZeta : PositivityExt where eval {u α} z p e := do
1424+
match u, α, e with
1425+
| 0, ~q(ℕ), ~q(ArithmeticFunction.zeta $n) =>
1426+
let rn ← core z p n
1427+
assumeInstancesCommute
1428+
match rn with
1429+
| .positive pn => return .positive q(Iff.mpr ArithmeticFunction.zeta_pos $pn)
1430+
| _ => return .nonnegative q(Nat.zero_le _)
1431+
| _, _, _ => throwError "not ArithmeticFunction.zeta"
1432+
1433+
end Mathlib.Meta.Positivity

MathlibTest/positivity.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Mathlib.Analysis.SpecialFunctions.Pow.Real
77
import Mathlib.Analysis.SpecialFunctions.Log.Basic
88
import Mathlib.Analysis.SpecialFunctions.Trigonometric.Arctan
99
import Mathlib.MeasureTheory.Integral.Bochner.Basic
10+
import Mathlib.NumberTheory.ArithmeticFunction
1011
import Mathlib.Topology.Algebra.InfiniteSum.Order
1112

1213
/-! # Tests for the `positivity` tactic
@@ -108,6 +109,11 @@ example : (1/4 - 2/3 : α) ≠ 0 := by positivity
108109

109110
end
110111

112+
/- ### `ArithmeticFunction.sigma` and `ArithmeticFunction.zeta` -/
113+
114+
example (a b : ℕ) (hb : 0 < b) : 0 < ArithmeticFunction.sigma a b := by positivity
115+
example (a : ℕ) (ha : 0 < a) : 0 < ArithmeticFunction.zeta a := by positivity
116+
111117
/-
112118
## Test for meta-variable instantiation
113119

0 commit comments

Comments
 (0)