Prime Counting Function π(n)

lean4-proofnumber-theoryvisualization
π(n)=#{pn:p prime}\pi(n) = \#\{p \le n : p \text{ prime}\}

Statement

The prime counting function π(n)\pi(n) counts the number of primes up to nn:

π(n)=#{pn:p is prime}.\pi(n) = \#\{p \le n : p \text{ is prime}\}.

The Prime Number Theorem (Hadamard and de la Vallée-Poussin, 1896) gives the asymptotic:

π(n)nlnn(n),\pi(n) \sim \frac{n}{\ln n} \quad (n \to \infty),

meaning π(n)/(n/lnn)1\pi(n) / (n / \ln n) \to 1. Equivalently, π(n)Li(n)\pi(n) \sim \mathrm{Li}(n) where Li(n)=2ndt/lnt\mathrm{Li}(n) = \int_2^n dt/\ln t is the logarithmic integral.

Mathlib defines Nat.primeCounting n as the number of primes n\le n, with notation π\pi (scoped to Nat.Prime).

Visualization

Exact values of π(n)\pi(n) and comparison with the approximation n/lnnn/\ln n:

nnπ(n)\pi(n)n/lnn\lfloor n/\ln n \rfloorπ(n)n/lnn\pi(n) - \lfloor n/\ln n \rfloor
10440
5015114
10025214
500958015
100016814424
500066959178
1000012291085144

The logarithmic integral Li(n)\mathrm{Li}(n) is a better approximation (within O(nlnn)O(\sqrt{n}\ln n) assuming the Riemann Hypothesis):

nnπ(n)\pi(n)Li(n)\mathrm{Li}(n) (approx)error
100016817810-10
100001229124617-17
1000009592963038-38

Note Li(n)>π(n)\mathrm{Li}(n) > \pi(n) for all computed values, though Skewes showed the inequality reverses for some astronomically large nn.

Proof Sketch

  1. Elementary lower bound. By Bertrand's PostulateBertrand's Postulaten1,  p prime,  n<p2n\forall n \ge 1,\; \exists p \text{ prime},\; n < p \le 2nFor every positive integer n there is always a prime p with n < p ≤ 2nRead more →, π(2n)π(n)+1\pi(2n) \ge \pi(n) + 1, giving π(n)log2n\pi(n) \ge \lfloor \log_2 n \rfloor.
  2. Chebyshev bounds. (ln2)n/lnnπ(n)(2ln2)n/lnn(\ln 2)\, n/\ln n \le \pi(n) \le (2\ln 2)\, n/\ln n for large nn (see Chebyshev's Bounds for π(n)Chebyshev's Bounds for π(n)n2lnn<π(n)<2nlnn\frac{n}{2\ln n} < \pi(n) < \frac{2n}{\ln n}The prime counting function satisfies c₁·n/ln(n) ≤ π(n) ≤ c₂·n/ln(n) for explicit constantsRead more →).
  3. Prime Number Theorem. The full asymptotics use complex analysis: ζ(s)0\zeta(s) \ne 0 on (s)=1\Re(s) = 1 (zero-free region) implies π(n)n/lnn\pi(n) \sim n/\ln n.
  4. Equivalent forms. π(n)n/lnn    ψ(n)n\pi(n) \sim n/\ln n \iff \psi(n) \sim n (von Mangoldt function)     \iff ϑ(n)n\vartheta(n) \sim n (Chebyshev ϑ\vartheta).

Connections

π(n)\pi(n) is the primary object of study in analytic number theory, shaped by Chebyshev's Bounds for π(n)Chebyshev's Bounds for π(n)n2lnn<π(n)<2nlnn\frac{n}{2\ln n} < \pi(n) < \frac{2n}{\ln n}The prime counting function satisfies c₁·n/ln(n) ≤ π(n) ≤ c₂·n/ln(n) for explicit constantsRead more → and Mertens' TheoremsMertens' Theoremspn1p=lnlnn+M+O ⁣(1lnn)\sum_{p \le n} \frac{1}{p} = \ln \ln n + M + O\!\left(\frac{1}{\ln n}\right)The sum of reciprocals of primes diverges, with precise logarithmic asymptoticsRead more →. The Infinitude of PrimesInfinitude of PrimesnN,  p>n  such that  p  is prime\forall\, n \in \mathbb{N},\; \exists\, p > n \;\text{such that}\; p \;\text{is prime}Euclid's classic proof that there are infinitely many prime numbersRead more → shows π(n)\pi(n) \to \infty; the Prime Number Theorem quantifies the rate. The Multiplicative FunctionsMultiplicative Functionsgcd(m,n)=1f(mn)=f(m)f(n)\gcd(m,n)=1 \Rightarrow f(mn)=f(m)f(n)Arithmetic functions that split over coprime inputs: f(mn) = f(m)f(n) when gcd(m,n) = 1Read more → Dirichlet series generating function is ζ(s)/ζ(s)=n1Λ(n)ns-\zeta'(s)/\zeta(s) = \sum_{n\ge1} \Lambda(n) n^{-s}, linking π\pi to the Riemann zeta function.

Lean4 Proof

import Mathlib.NumberTheory.PrimeCounting
import Mathlib.Data.Nat.Prime.Basic

/-- π(10) = 4: there are exactly 4 primes ≤ 10 (namely 2, 3, 5, 7). -/
theorem pi_10 : Nat.primeCounting 10 = 4 := by decide

/-- π is monotone: if m ≤ n then π(m) ≤ π(n). -/
theorem pi_monotone : Monotone Nat.primeCounting :=
  Nat.monotone_primeCounting

/-- π(n) is unbounded: Nat.tendsto_primeCounting' shows it diverges to infinity. -/
theorem pi_tendsto : Filter.Tendsto Nat.primeCounting' Filter.atTop Filter.atTop :=
  Nat.tendsto_primeCounting'