素数計算OSのための数理基盤
解析的明示公式と証明可能計算の実装

GhostDrift Mathematical Institute
(Authored by Manny)

本稿では、Riemann ゼータ関数 $\zeta(s)$ の解析的性質に基づき、素数計数関数 $\pi(x)$ の明示的な評価式を導出する過程を概観する。 さらに、導出された「誤差項付き素数定理 (Prime Number Theorem with Error Term)」を基礎とし、証明可能計算 (Provable Computation) を指向したアルゴリズムの実装モデルを示す。

1. 定義および基本等式

まず、本稿で用いる基本的な関数群を定義する。

定義 1.1 (Riemann ゼータ関数).
複素変数 $s = \sigma + it$ ($\sigma > 1$) に対して、以下のように定義する。 $$ \zeta(s) := \sum_{n=1}^\infty \frac{1}{n^s} = \prod_{p} \left(1 - \frac{1}{p^s}\right)^{-1}. $$
定義 1.2 (Von Mangoldt 関数).
$$ \Lambda(n) := \begin{cases} \log p & n = p^k \text{ ($p$: 素数, $k \ge 1$) のとき}, \\ 0 & \text{それ以外のとき}. \end{cases} $$ この関数を用いると、$\zeta(s)$ の対数微分は以下のように表される。 $$ -\frac{\zeta'}{\zeta}(s) = \sum_{n=1}^\infty \frac{\Lambda(n)}{n^s}, \quad \sigma > 1. $$
定義 1.3 (Chebyshev 関数).
$$ \psi(x) := \sum_{n \le x} \Lambda(n). $$

2. Perron の公式と複素積分

Dirichlet 級数の係数和を抽出するために、Perron の公式を用いる。積分路を適切に選ぶことで、$\psi(x)$ を複素積分として表現できる。

補題 2.1 (打ち切り型 Perron 公式).
$x \ge 2, T \ge 2$ とし、$c = 1 + \frac{1}{\log x}$ とおく。このとき、 $$ \psi(x) = \frac{1}{2\pi i} \int_{c-iT}^{c+iT} \left( -\frac{\zeta'}{\zeta}(s) \right) \frac{x^s}{s} \, ds + R(x, T), $$ が成り立つ。ここで剰余項 $R(x, T)$ は次のように評価される。 $$ R(x, T) \ll \frac{x \log^2 x}{T}. $$

積分路を左方(臨界領域 $0 < \sigma < 1$)へ移動させ、Cauchy の留数定理を適用することで、被積分関数の極における留数の寄与を抽出する。

3. 明示公式 (Explicit Formula)

$\zeta(s)$ は全平面 $\mathbb{C}$ に有理型に解析接続され、$s=1$ に単純極を持つ。非自明零点を $\rho = \beta + i\gamma$ とし、自明な零点を $s = -2k$ ($k \in \mathbb{N}$) とする。

定理 3.1 ($\psi(x)$ の明示公式).
$x \ge 2$ および $T \ge 2$ に対して、次式が成り立つ。 $$ \psi(x) = x - \sum_{|\gamma| \le T} \frac{x^\rho}{\rho} - \frac{\zeta'}{\zeta}(0) - \frac{1}{2}\log(1-x^{-2}) + R_{explicit}(x, T), $$ ここで誤差項は以下を満たす。 $$ R_{explicit}(x, T) \ll \frac{x \log^2(xT)}{T} + \log x. $$

4. 零点自由領域と誤差評価

定理 3.1 における零点和を評価するため、解析数論における標準的な外部知見を用いる。 具体的には、古典的な零点自由領域 (Zero-Free Region) および Riemann–von Mangoldt の零点個数公式の 「有効版 (effective version)」を想定する。 すなわち、そこでは具体的な定数 $c_0, A, B,\dots$ を伴う形で $$ \sigma \ge 1 - \frac{c_0}{\log(|t|+2)}, \qquad N(T) = \frac{T}{2\pi}\log\frac{T}{2\pi} - \frac{T}{2\pi} + O(\log T) $$ といった評価が与えられていると仮定する。 本デモにおいて、これらは新たな貢献ではなく、外部モジュールから供給される 「解析的定数付き外部定理 (External Explicit Theorem)」として扱う。 後述の Safe モードでは、この種の定数がすべて $(K_\psi, K_\pi, c, x_0)$ に吸収される。

古典的知見 4.1 (零点自由領域; 外部定理).
ある明示的な定数 $c_0 > 0$ が存在し、領域 $$ \sigma \ge 1 - \frac{c_0}{\log(|t| + 2)} \qquad (|t| \ge 2) $$ において $\zeta(\sigma + it) \neq 0$ が成り立つ。
歴史的には de la Vallée Poussin に遡るこの領域は、現代においては Kadiri や Mossinghoff らによる研究で、$c_0$ の具体的な数値計算値が与えられている。
古典的知見 4.2 (零点個数公式; 外部定理).
$N(T)$ を $0 < \gamma \le T$ なる $\zeta(s)$ の零点 $\rho = \beta + i\gamma$ の個数とする。古典的な Riemann–von Mangoldt 公式によれば、 $$ N(T) = \frac{T}{2\pi} \log \frac{T}{2\pi} - \frac{T}{2\pi} + O(\log T). $$ 文献(Titchmarsh, Davenport 等)には、暗黙の定数を含む形での有効な (effective) 評価式が標準的に記載されている。 本デモではこの公式の「形式 (shape)」のみを用い、暗黙の定数は外部からの解析的入力の一部として扱う。

古典的な議論(例えば Titchmarsh や Davenport の教科書に見られるもの)により、 零点自由領域 4.1 と零点個数公式 4.2 から、次のような誤差項付き素数定理が得られることが知られている。

定理 4.3 (誤差項付き素数定理).
ある明示的な定数 $c > 0$ および $x_0 \ge 2$ が存在し、 すべての $x \ge x_0$ に対して $$ \psi(x) = x + O\left( x \exp(-c\sqrt{\log x}) \right) $$ が成り立つ。
実際には、古典的な零点自由領域および零点個数公式の有効版 (例えば Titchmarsh や Davenport の教科書に記載されているもの)を組み合わせることで、 具体的な $c$ と $x_0$ を与えることができる。 本デモでは、それらの数値の導出過程をブラックボックス化し、 後続のアルゴリズム層では $(K_\psi, K_\pi, c, x_0)$ という「解析的プロファイル」として受け取る。

5. $\psi(x)$ から $\pi(x)$ への帰着

$\theta(x) = \sum_{p \le x} \log p$ と定義する。関係式 $\psi(x) = \theta(x) + \theta(x^{1/2}) + \dots$ より、 $$ \psi(x) - \theta(x) \ll \sqrt{x} $$ である。したがって、$\theta(x)$ の漸近挙動は誤差項の範囲内で $\psi(x)$ と一致する。 Stieltjes 積分による部分積分公式を用いれば、 $$ \pi(x) = \int_{2}^{x} \frac{d\theta(t)}{\log t} = \int_{2}^{x} \frac{dt}{\log t} + O\left( x \exp(-c\sqrt{\log x}) \right) $$ を得る。ここで、素数定理の文脈では $$ \Li(x) := \int_{2}^{x} \frac{dt}{\log t} $$ と定義する。

なお解析数論の文献では、主値積分 $$ \operatorname{li}(x) := \mathrm{pv}\!\!\int_0^x \frac{dt}{\log t} $$ を用いる記法も一般的だが、本稿では一貫して $$ \Li(x) = \int_2^x \frac{dt}{\log t} $$ の意味で $\Li$ を用いる。

系 5.1.
$$ \pi(x) = \Li(x) + O\left( x \exp(-c\sqrt{\log x}) \right). $$

6. アルゴリズム実装とライブデモ

以上の解析的評価に基づき、素数計算OSの核となるロジックを示す。 本実装では、解析数論的な「理論的定数(Explicit Constants)」と、計算機による「数値的評価」を厳密に分離する設計を採用している。

注意 (Safe vs Pragmatic Modes).

本デモコードでは、以下の2つの利用モードを明確に区別する:

⚡ Interactive OS Kernel (Pragmatic Mode)

以下のフォームで、Pythonコードのロジックをブラウザ上で実行し、$\pi(x)$ の推定値と誤差項の評価を行います。

ここに計算結果が表示されます...
Reference Implementation (Python) : クリックして展開
import math
from typing import Tuple

# ==========================================
# Explicit PNT constants: sample "Safe profile"
#   Based on Platt–Trudgian, *The error term in the prime number theorem*
#   (Math. Comp. 90 (2021)), Corollary 2, which improves Dusart (2010, Thm 1.12).
#   Cor. 2 states:
#       |π(x) - Li(x)| ≤ 235 * x * (log x)**0.52 * exp(-0.8 * sqrt(log x))
#   for log x ≥ 2000.
#   We treat this as an external analytic input.
# ==========================================
PI_SAFE_PROFILE_PT2020 = {
    "name": "Platt–Trudgian 2021, Cor. 2 (improves Dusart 2010, Thm 1.12)",
    "K_pi": 235.0,
    "c": 0.8,
    # The theorem assumes log x ≥ 2000 (natural logarithm).
    # We store that threshold as `log_x0` rather than `x0 = exp(2000)`,
    # since exp(2000) is astronomically large and cannot be represented as a float.
    "log_x0": 2000.0,
}

# ==============================================================================
# 素数定理に基づく推定のための数理コア
# ==============================================================================

# ========================================
# 1. Li(x) 評価レイヤ
# ========================================

def li_bounds_interval(x: float) -> Tuple[float, float]:
    """
    Li(x) の厳密な区間評価のためのスケルトン。
    証明可能計算 (ADIC) コンテキストでの想定インターフェイスは次の通り。

      - 入力: 実数 x ≥ 2 (OS 側からは float で渡される)
      - 出力: (Li_low, Li_high) のタプル。
        実際の ADIC 実装では、有理数対 (q_low, q_high) を outward rounding したものを
        台帳に保持し、この関数はその値を浮動小数点に写像して返すことを想定する。
      - 性質: つねに Li_low ≤ Li(x) ≤ Li_high を満たす。
        この性質の証明責任は Explicit-PNT / ADIC レイヤにあり、
        本ファイルの OS ロジックはその前提の下でのみ Safe モードを名乗る。

    デモ実装では、解析レイヤがまだ接続されていないことを明示するために、
    呼び出されると例外を送出する。
    """
    raise NotImplementedError(
        "Li(x) の厳密な区間評価は未接続です: "
        "Explicit-PNT / ADIC レイヤからの提供が必要です。"
    )

def li_numeric(x: float, n_steps: int = 10000) -> float:
    """
    対数積分 Li(x) = ∫_2^x dt / log t の数値近似(Simpson則を使用)。

    モードの意味論:
      - 実用モード (Pragmatic Mode):
          対話的な探索用。戻り値 Li(x) に厳密な誤差保証はない。
      - 安全/証明モード (Safe / Certificate Mode):
          使用禁止。`li_bounds_interval(x)` に置換されなければならない。
    """
    if x <= 2.0:
        return 0.0

    a, b = 2.0, float(x)
    h = (b - a) / n_steps
    s = 0.0

    for k in range(n_steps + 1):
        t = a + k * h
        weight = 1 if (k == 0 or k == n_steps) else (4 if k % 2 == 1 else 2)
        s += weight / math.log(t)

    # Note: Correct Simpson's rule factor is h/3.
    # The previous 0.5 * h was trapezoidal-like, adjusted here for consistency.
    return (h / 3.0) * s


# ========================================
# 2. 新素数定理型 誤差カーネル
# ========================================

def new_pnt_error_kernel(x: float, c: float) -> float:
    """
    一般的な誤差カーネル: E(x,c) = x * exp(-c * sqrt(log x))
    定理 4.3 参照。
    """
    if x <= 1.0:
        return 0.0
    L = math.log(x)
    return x * math.exp(-c * math.sqrt(L))

def new_pnt_error_kernel_pt2020(x: float, c: float) -> float:
    """
    Platt–Trudgian (2021), Corollary 2 に対応する誤差カーネル:

        |π(x) - Li(x)|
          ≤ 235 * x * (log x)**0.52 * exp(-0.8 * sqrt(log x))
          for log x ≥ 2000.

    これは一般的なカーネル `new_pnt_error_kernel` に、追加の因子 (log x)**0.52 を乗じたもの。
    """
    if x <= 0.0:
        raise ValueError("x must be positive in new_pnt_error_kernel_pt2020")

    log_x = math.log(x)
    if log_x < PI_SAFE_PROFILE_PT2020["log_x0"]:
        # Safeモードでは定理の適用範囲外なら例外を送出
        raise ValueError(
            f"x = {x} is outside the provable range: "
            f"log x = {log_x:.3f} < {PI_SAFE_PROFILE_PT2020['log_x0']}"
        )

    base = new_pnt_error_kernel(x, c)
    return (log_x ** 0.52) * base


# ========================================
# 3. 理論レイヤ (補題のコード化)
# ========================================

def psi_bounds_new_pnt(x: float, K_psi: float, c: float) -> Tuple[float, float]:
    """
    ψ(x) の明示公式評価: |ψ(x) - x| ≤ K_psi * x * exp(-c * sqrt(log x))
    """
    E = K_psi * new_pnt_error_kernel(x, c)
    return x - E, x + E

def theta_bounds_from_psi(psi_lower: float, psi_upper: float,
                          x: float, C_theta: float) -> Tuple[float, float]:
    """
    ψ(x) から θ(x) への境界伝播。
    """
    shift = C_theta * math.sqrt(x)
    return psi_lower - shift, psi_upper + shift


# ========================================
# 4. π(x) の境界評価と OS 推定
# ========================================

def pi_bounds_new_pnt(x: float,
                      K_pi: float,
                      c: float) -> Tuple[float, float]:
    """
    汎用的な明示的素数定理形式に基づく π(x) の境界計算。
    (K_pi, c, x0) は外部から供給される前提。
    """
    li_x = li_numeric(x)
    E_pi = K_pi * new_pnt_error_kernel(x, c)
    return li_x - E_pi, li_x + E_pi

def pi_bounds_new_pnt_safe_sample(x: float) -> Tuple[float, float]:
    """
    固定された「Safe プロファイル」を用いた π(x) の境界計算サンプル。

        |π(x) - Li(x)|
          ≤ 235 * x * (log x)**0.52 * exp(-0.8 * sqrt(log x))
          for log x ≥ 2000,

    出典: Platt–Trudgian, Math. Comp. 90 (2021), Corollary 2.

    【重要】
      真に厳密な証明書を得るには、`li_numeric(x)` を
      `li_bounds_interval(x)` に置き換える必要がある。
    """
    # 定理の適用範囲チェック: log x ≥ 2000
    if x <= 0.0:
        raise ValueError("x must be positive")

    log_x = math.log(x)
    if log_x < PI_SAFE_PROFILE_PT2020["log_x0"]:
        raise ValueError(
            f"x = {x} is outside the provable range for the fixed profile "
            f"(log x = {log_x:.3f} < {PI_SAFE_PROFILE_PT2020['log_x0']})."
        )

    # デモ用: 浮動小数点 Li(x) を使用
    li_x = li_numeric(x)

    E_pi = PI_SAFE_PROFILE_PT2020["K_pi"] * \
        new_pnt_error_kernel_pt2020(x, PI_SAFE_PROFILE_PT2020["c"])

    return li_x - E_pi, li_x + E_pi

def pi_estimate_new_pnt(x: float,
                        K_pi: float = 1.0, 
                        c: float = 0.2) -> int:
    """
    OS API 用の π(x) 点推定(丸め値)。
    安全性重視の用途では使用せず、上記 `pi_bounds_...` 関数を使用すること。
    """
    li_x = li_numeric(x)
    return int(round(li_x))

# 使用例
if __name__ == "__main__":
    # Platt-Trudgian の適用範囲外でのデモ用ターゲット
    target = 10**6
    est = pi_estimate_new_pnt(target, K_pi=0.5, c=0.2)
    print(f"pi({target}) estimate (Pragmatic Mode): {est}")