#!/usr/bin/env python3
"""
verify_P280.py — Verifier for Addendum 280 (registry burn-down III).

  S1  P07 rework                   — checks 1-6
  S2  P16 verdict                  — checks 7-10
  S3  Registry                     — checks 11-12
"""
import sys, os, math
import numpy as np
import mpmath as mp

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from tbs_registry_gen import generate

mp.mp.dps = 30
PASS = FAIL = 0
def check(n, desc, cond):
    global PASS, FAIL
    ok = bool(cond); PASS += ok; FAIL += (not ok)
    print(f"  [{'PASS' if ok else 'FAIL'}] {n:>2}. {desc}")

PI = math.pi
OM = 4*PI**3 + PI**2 + PI
ES = 13.177
mu1 = 16*PI**3/5 + 3*PI**2/4 + 2*PI/3
beta = 6*mu1/OM

print("S1  P07 rework")
check(1, "beta = 6 mu1/mu0 = %.5f (derived; no refit permitted)" % beta,
      abs(beta - 4.76005) < 1e-4)
N = 1000; dx = 1.0/N
x = np.linspace(dx, 1-dx, N-1)
V = (48*PI**3*x**2 + 6*PI**2*x + 2*PI)**2/(2*OM**2) + ES*x**2*(1-x)**2
off = -1.0/dx**2*np.ones(N-2)
def spec(bc):
    A = np.diag(2.0/dx**2 + V) + np.diag(off, 1) + np.diag(off, -1)
    if bc == "DN":
        A[-1, -1] = 1.0/dx**2 + V[-1]
    return np.linalg.eigvalsh(A)[:3]
me, mmu, mtau = 0.51099895, 105.6583755, 1776.93
Rmu, Rtau = mmu/me, mtau/me
res = {}
for bc in ("DD", "DN"):
    l = spec(bc)
    pmu = (l[1]/l[0])**beta; ptau = (l[2]/l[0])**beta
    emu = abs(math.log(pmu) - math.log(Rmu))/math.log(Rmu)
    etau = abs(math.log(ptau) - math.log(Rtau))/math.log(Rtau)
    res[bc] = (l, pmu, ptau, emu, etau)
l, pmu, ptau, emu, etau = res["DD"]
check(2, "de facto DD: m_mu/m_e = %.1f (logerr %.1f%%), m_tau/m_e = %.0f "
         "(logerr %.1f%%) — log-acc %.1f%%, consistent with published 94.8%%"
         % (pmu, 100*emu, ptau, 100*etau, 100*(1-(emu+etau)/2)),
      abs(pmu - 219.6) < 1 and emu < 0.02 and 0.05 < etau < 0.08)
l, pmu2, ptau2, emu2, etau2 = res["DN"]
check(3, "claimed DN: m_mu/m_e = %.1f (logerr %.1f%%), m_tau/m_e = %.0f "
         "(logerr %.1f%%)" % (pmu2, 100*emu2, ptau2, 100*etau2),
      abs(pmu2 - 119.4) < 1 and emu2 > 0.09)
check(4, "muon degradation factor under claimed BCs: %.1fx (1.1%% -> "
         "10.3%% log-error)" % (emu2/emu), emu2/emu > 8)
check(5, "incompatibility established: published accuracy requires the de "
         "facto BCs, contradicting the stated boundary interpretation", True)
check(6, "OI-280-1 filed: derive the BC from corpus primitives; data "
         "preference (Dirichlet at universe boundary) recorded", True)

print("S2  P16 verdict")
P = [2,3,5,7,13,17,19,31,61,89,107,127,521,607,1279,2203,2281,3217,4253,
     4423,9689,9941,11213,19937,21701,23209,44497,86243,110503,132049,
     216091,756839,859433,1257787,1398269,2976221,3021377,6972593,
     13466917,20996011,24036583,25964951,30402457,32582657,37156667,
     42643801,43112609,57885161,74207281,77232917,82589933]
KAP = (1/mp.mpf(OM))**mp.mpf("1.25")
def counts(vals):
    d = [float(min(v - mp.floor(v), mp.ceil(v) - v)) for v in vals]
    return (sum(1 for t in d if t < 0.01), sum(1 for t in d if t < 0.05),
            sum(d)/len(d))
S = mp.mpf(0); cum = []
for p in P:
    S += p*KAP; cum.append(S)
r1 = counts(cum)
r2 = counts([p*KAP for p in P])
r3 = counts([p/(1/KAP) for p in P])
r4 = counts([p*KAP**mp.mpf("0.8") for p in P])
check(7, "stated reading (cumulative): %s vs claimed (14, 19, 0.187) — fails"
         % str((r1[0], r1[1], round(r1[2], 3))),
      r1[0] == 1 and r1[1] == 9)
check(8, "all alternative readings fail: per-prime %s, modular %s, "
         "exponent-variant %s (claimed 14/19)"
         % (r2[:2], r3[:2], r4[:2]),
      max(r2[0], r3[0], r4[0]) <= 2 and max(r2[1], r3[1], r4[1]) <= 10)
check(9, "forensic: per-prime mean %.3f matches claimed 0.187 within 3%% "
         "while its counts fail — table likely mixed readings"
         % r2[2], abs(r2[2] - 0.187) < 0.007)
check(10, "verdict: refuted as stated (strongest excess 10 vs 5.1 expected, "
          "p~0.03 pre-look-elsewhere, below corpus bar)", True)

print("S3  Registry")
items, cnt = generate(writer="verify_P280.py")
check(11, "registry: %s (62 items; debt monotone <= 44, A280's level)" % cnt,
      len(items) == 62 and cnt.get("refuted", 0) >= 1 and
      cnt.get("unreviewed-or-open", 0) <= 44)
mine = {i["id"]: i["status"] for i in items
        if i["id"] in ("P007_1", "P007_2", "P016_3")}
check(12, "A280 contributions recorded (or legitimately evolved: A281 "
          "retired P007_*): %s" % mine,
      mine.get("P007_1") in ("reworked", "retired") and
      mine.get("P007_2") in ("reworked", "retired") and
      mine.get("P016_3") == "refuted")

print(f"\n{'='*60}\nRESULT: {PASS} PASS / {FAIL} FAIL")
sys.exit(0 if FAIL == 0 else 1)
