#!/usr/bin/env python3
"""
verify_P100.py -- Addendum 100: Complete Standard Model synthesis table.

This verifier checks the numerical consistency of the summary table in
100_Addendum_CompleteSM.tex.  Most table entries reproduce if one uses the
older corpus mass slope MU = (16*pi^3/5 + 3*pi^2/4 + 2*pi/3)/mu0.  The paper's
displayed P100 formula for MU, however, is a different expression and gives
about 113, not 0.79334.
"""

import math
import sys
from pathlib import Path

PASS = FAIL = 0
_N = 0


def check(desc, cond):
    global PASS, FAIL, _N
    _N += 1
    ok = bool(cond)
    PASS += ok
    FAIL += not ok
    print(f"  [{'PASS' if ok else 'FAIL'}] {_N:>2}. {desc}")
    return ok


class Verifier:
    """Same check semantics as verify_common.Verifier; modern output style."""

    def __init__(self, name):
        print(name)

    def check(self, label, computed, claimed, *, rel=1e-3, abs_tol=None, detail=""):
        if abs_tol is not None:
            ok = abs(computed - claimed) <= abs_tol
            err = abs(computed - claimed)
            err_detail = f"abs err={err:.6g}, tol={abs_tol:.6g}"
        else:
            if claimed == 0:
                ok = abs(computed) <= (rel or 1e-12)
                err_detail = f"abs value={abs(computed):.6g}, tol={rel:.6g}"
            else:
                err = (computed - claimed) / abs(claimed)
                ok = abs(err) <= (rel or 0)
                err_detail = f"rel err={100 * err:+.6g}%, tol={100 * (rel or 0):.6g}%"
        return self.record(label, ok, computed, claimed, err_detail + (f"; {detail}" if detail else ""))

    def record(self, label, ok, computed="", claimed="", detail=""):
        check(label + (f" -- {detail}" if detail else ""), ok)
        if computed != "" or claimed != "":
            print(f"        computed: {computed}")
            print(f"        claimed : {claimed}")
        return ok

    def summary(self):
        print(f"\n{'='*60}\nRESULT: {PASS} PASS / {FAIL} FAIL")
        return 1 if FAIL else 0


v = Verifier("P100 -- Complete Standard Model Synthesis")

PI = math.pi
M_E = 0.51100
MU0 = PI + PI**2 + 4 * PI**3
MU_DISPLAY = (PI**2 + PI**4 + 16 * PI**6) / MU0
MU_CORPUS = (16 * PI**3 / 5 + 3 * PI**2 / 4 + 2 * PI / 3) / MU0
LAM = math.sin(PI / 14)
C_NLO = 1 - 4 * LAM**2 / 5
PHI_GOLDEN = (1 + math.sqrt(5)) / 2
SIN2_LO = 1 / (1 + PI)
SIN2_NLO = SIN2_LO * C_NLO
PHI_CKM = math.cos(PI / 14) * math.cos(2 * PI / 14) * math.cos(5 * PI / 28)
A_LO = math.cos(PI / 14) ** 2 * math.cos(2 * PI / 14)
A_NLO = A_LO * C_NLO
DELTA = 31 * PI / 84
RHO = 0.5 * PHI_CKM * math.cos(DELTA)
ETA = 0.5 * PHI_CKM * math.sin(DELTA)
J_LO = A_LO**2 * LAM**6 * ETA
J_NLO = J_LO * (1 - 48 * LAM**4 / 25)


def mass_from_e(energy: float) -> float:
    return M_E * math.exp(MU_CORPUS * (energy - PI))


def residual(value: float, target: float) -> float:
    return 100 * (value - target) / target


v.check("mu0 sector trace", MU0, 137.03630, rel=5e-8)
v.check(
    "displayed MU formula equals stated 0.79334",
    MU_DISPLAY,
    0.79334,
    rel=1e-3,
    detail="Expected fail: (pi^2 + pi^4 + 16*pi^6)/mu0 is about 113.03, not the mass slope.",
)
v.check("corpus MU mass slope", MU_CORPUS, 0.79334, rel=5e-6)
v.check("lambda = sin(pi/14)", LAM, 0.22252, rel=5e-6)
v.check("4 lambda^2 / 5", 4 * LAM**2 / 5, 0.039612, rel=2e-5)
v.check("C_NLO = 1 - 4lambda^2/5", C_NLO, 0.96039, rel=3e-6)
v.check("Phi CKM calibration", PHI_CKM, 0.7437, rel=7e-5)
v.check("A_LO", A_LO, 0.8564, rel=6e-5)
v.check("A_NLO", A_NLO, 0.82243, rel=6e-6)

v.check("sin^2 theta_W LO", SIN2_LO, 0.24145, rel=2e-5)
v.check("sin^2 theta_W NLO", SIN2_NLO, 0.23189, rel=1e-5)
v.check("sin^2 theta_W NLO residual percent", residual(SIN2_NLO, 0.23122), 0.29, rel=5e-3)
v.check("sin^2 theta_W NLO / (3/8)", SIN2_NLO / (3 / 8), 0.61837, rel=3e-6)
v.check("golden-ratio near-miss percent", abs(residual(SIN2_NLO / (3 / 8), 1 / PHI_GOLDEN)), 0.05, rel=1e-1)

v.check("m_mu from pi^2", mass_from_e(PI**2), 106.30, rel=5e-5)
v.check("m_mu residual percent", residual(mass_from_e(PI**2), 105.66), 0.60, rel=1e-2)
v.check("m_tau from pi^2 + pi + 2/5", mass_from_e(PI**2 + PI + 2 / 5), 1765.0, rel=5e-5)
v.check("m_tau residual percent", residual(mass_from_e(PI**2 + PI + 2 / 5), 1776.86), -0.67, rel=1e-2)

v.check("m_u table", mass_from_e(PI ** (7 / 5)), 2.173, rel=1e-4)
v.check("m_d table", mass_from_e(PI ** (14 / 9)), 4.683, rel=5e-5)
v.check("m_s table", mass_from_e(PI**2 - 1 / 7), 94.9, rel=1e-4)
v.check("m_b table", mass_from_e(PI ** (7 / 3)), 4039.8, rel=5e-5)
v.check("m_t table", mass_from_e(PI**2 + PI + math.log(MU0) / MU_CORPUS), 176101, rel=5e-5)
v.check("m_t residual percent", residual(mass_from_e(PI**2 + PI + math.log(MU0) / MU_CORPUS), 172690), 1.98, rel=2e-2)

v.check("lambda_CKM table", LAM, 0.22252, rel=5e-6)
v.check("lambda_CKM residual percent", residual(LAM, 0.22500), -1.10, rel=5e-3)
v.check("A_NLO table", A_NLO, 0.82243, rel=6e-6)
v.check("A_NLO residual percent", residual(A_NLO, 0.826), -0.43, rel=1e-2)
v.check("rho_bar table", RHO, 0.14871, rel=1e-5)
v.check("rho_bar residual percent", residual(RHO, 0.1472), 1.03, rel=1e-2)
v.check("eta_bar table", ETA, 0.34084, rel=2e-5)
v.check("eta_bar residual percent", residual(ETA, 0.3441), -0.95, rel=1e-2)
v.check("J_LO", J_LO, 3.035e-5, rel=2e-4)
v.check("J_NLO", J_NLO, 3.020e-5, rel=1e-4)
v.check("J_NLO residual percent", residual(J_NLO, 3.08e-5), -1.94, rel=2e-2)

theta12 = math.degrees(5 * PI / 28)
theta23_ckm = A_NLO * LAM**2
theta23 = 45 - math.degrees(LAM**2 / 2) - math.degrees(theta23_ckm)
theta13 = math.degrees(math.asin(LAM / math.sqrt(2) * (1 - 3 * LAM**2 / 4)))
delta_pmns = -math.degrees(PI / 3 + PI / 28)
v.check("theta12 PMNS", theta12, 32.14, rel=1e-4)
v.check("theta12 residual percent", residual(theta12, 33.41), -3.79, rel=5e-3)
v.check("theta23 PMNS", theta23, 41.25, rel=5e-5)
v.check("theta23 residual percent", residual(theta23, 42.2), -2.26, rel=5e-3)
v.record(
    "theta23 marked closed under <=2.1 percent criterion",
    abs(residual(theta23, 42.2)) <= 2.1,
    f"{residual(theta23, 42.2):+.4f}%",
    "<=2.1%",
    "Expected fail: table marks theta23 closed, but its listed residual is about 2.26%.",
)
v.check("theta13 PMNS", theta13, 8.71, rel=5e-4)
v.check("theta13 residual percent", residual(theta13, 8.57), 1.68, rel=5e-3)
v.check("delta_CP PMNS magnitude residual percent", abs(residual(abs(delta_pmns), 66.0)), 0.65, rel=5e-3)

m_h_nlo = 246.22 / 2 * math.sqrt(1 + 4 * LAM**2 / 5)
v.check("m_H NLO", m_h_nlo, 125.52, rel=5e-5)
v.check("m_H residual percent", residual(m_h_nlo, 125.20), 0.26, rel=1e-2)
v.check("v = 2 * 123.11 GeV", 2 * 123.11, 246.22, rel=1e-12)
v.check(
    "literal v = 2*m_H_NLO",
    246.22,
    2 * m_h_nlo,
    rel=1e-3,
    detail="Expected fail if the abstract's 'v = 2 m_H at all orders' is read literally; the theorem later uses m_H^LO.",
)

mw_mz_ratio = math.sqrt(1 - SIN2_NLO)
mw_from_displayed_expr = 91.1876 * mw_mz_ratio
v.check("M_W/M_Z table ratio", mw_mz_ratio, 0.87642, rel=5e-6)
v.check("M_W/M_Z residual percent", residual(mw_mz_ratio, 0.8815), -0.58, rel=2e-2)
v.check(
    "M_W from displayed expression M_Z sqrt(1-sin^2 theta_W)",
    mw_from_displayed_expr,
    77.42,
    rel=5e-4,
    detail="Expected fail: the displayed expression with PDG M_Z gives about 79.92 GeV; 77.42 is the separate P93 absolute tree value.",
)
v.check("P93 absolute tree M_W residual percent", residual(77.42, 80.38), -3.68, rel=5e-3)

listed_closed_residuals = [
    residual(SIN2_NLO, 0.23122),
    residual(mass_from_e(PI**2), 105.66),
    residual(mass_from_e(PI**2 + PI + 2 / 5), 1776.86),
    residual(mass_from_e(PI ** (7 / 5)), 2.2),
    residual(mass_from_e(PI ** (14 / 9)), 4.7),
    residual(mass_from_e(PI**2 - 1 / 7), 93.0),
    residual(mass_from_e(PI**2 + PI + math.log(MU0) / MU_CORPUS), 172690),
    residual(LAM, 0.22500),
    residual(A_NLO, 0.826),
    residual(RHO, 0.1472),
    residual(ETA, 0.3441),
    residual(J_NLO, 3.08e-5),
    residual(theta12, 33.41),
    residual(theta23, 42.2),
    residual(theta13, 8.57),
    residual(abs(delta_pmns), 66.0),
    residual(m_h_nlo, 125.20),
]
rms = math.sqrt(sum(x * x for x in listed_closed_residuals) / len(listed_closed_residuals))
v.check("RMS over reproducible listed residuals", rms, 1.54, rel=1e-2)
v.record(
    "reproducible closed-observable count equals claimed 20",
    len(listed_closed_residuals) == 20,
    len(listed_closed_residuals),
    20,
    "Expected fail/ambiguity: the 1.54% RMS reproduces over 17 listed central predictions, not an unambiguous set of 20.",
)

sys.exit(v.summary())
