#!/usr/bin/env python3
"""
verify_P073.py -- Addendum 73: theta12 PMNS Closure.

This verifier checks the numerical claims in
73_Addendum_Theta12Closure.tex. The lower-level cubic corrections are mostly
arithmetic-consistent, but the paper's final "closure" argument mixes several
incompatible Jarlskog/back-reaction calculations.

The main intentional failures are:
  * cos(8.934 deg) and therefore K_TOE are miscomputed in the Jarlskog section.
  * Direct Jarlskog inversion gives a lower theta12, not 33.38 deg.
  * The closed-form theta12 formula as written evaluates to about 34.36 deg.
  * The final "definitive" U12 calculation uses y1^2*y2/8 = 0.006498, but the
    actual value is about 0.002685.
  * The paper explicitly derives Delta_J ~= -1.41 deg after claiming +0.44 deg.
"""

import math
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))
class Verifier:
    """Output shim: identical tolerance semantics to verify_common.Verifier,
    modern [PASS]/[FAIL] check-line output format."""

    def __init__(self, name):
        self.PASS = 0
        self.FAIL = 0
        self.n = 0
        print(name)

    def _mark(self, ok, desc):
        self.n += 1
        if ok:
            self.PASS += 1
        else:
            self.FAIL += 1
        print(f"  [{'PASS' if ok else 'FAIL'}] {self.n:>2}. {desc}")

    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_detail = f"abs err={abs(computed - claimed):.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}%"
        self._mark(ok, label + (f" -- {detail}" if detail else ""))
        print(f"        computed: {computed}   claimed: {claimed}   ({err_detail})")
        return ok

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

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


v = Verifier("P073 -- theta12 PMNS Closure")

DEG = math.pi / 180

LAM = math.sin(math.pi / 14)
THETA_C = math.pi / 14
Y2 = math.sin(2 * math.pi / 14)

TH12_2_DEG = 32.59
TH23_TOE_DEG = 41.245
TH13_TOE_DEG = 8.934
DELTA_TOE_DEG = 66.43  # absolute value; the paper drops the sign.

TH12_PDG_DEG = 33.44
TH23_PDG_DEG = 42.20
TH13_PDG_DEG = 8.620
DELTA_PDG_DEG = 67.0


def sind(x_deg):
    return math.sin(x_deg * DEG)


def cosd(x_deg):
    return math.cos(x_deg * DEG)


def asind(x):
    return math.asin(x) / DEG


theta12_2 = TH12_2_DEG * DEG
theta23_toe = TH23_TOE_DEG * DEG
theta13_toe = TH13_TOE_DEG * DEG
delta_toe = DELTA_TOE_DEG * DEG

v.check("lambda = sin(pi/14)", LAM, 0.22252, rel=5e-6)
v.check("lambda^2", LAM**2, 0.04952, rel=1e-4)
v.check("lambda^3", LAM**3, 0.011018, rel=5e-5)
v.check("lambda^3 in degrees", (LAM**3) / DEG, 0.63, rel=1e-2)
v.check("theta_C = pi/14 in degrees", THETA_C / DEG, 12.857, rel=5e-5)

theta12_lo = 45 - THETA_C / DEG
theta12_nlo = (math.pi / 4 - LAM * (1 - LAM**2 / 2)) / DEG
v.check("LO QLC theta12 = pi/4 - theta_C", theta12_lo, 32.14, rel=2e-3)
v.check("NLO theta12 = pi/4 - lambda*(1-lambda^2/2)", theta12_nlo, 32.59, rel=1e-3)
v.check("P72 theta12 residual", TH12_PDG_DEG - TH12_2_DEG, 0.85, rel=1e-2)

peirce_rad = LAM**2 * Y2 / (8 * math.cos(theta12_2))
qlc_rad = LAM**3 / 4
v.check("sin(2*pi/14)", Y2, 0.43388, rel=1e-4)
v.check("cos(32.59 deg)", math.cos(theta12_2), 0.8424, rel=5e-4)
v.check("Peirce angular correction rad", peirce_rad, 0.003189, rel=1e-3)
v.check("Peirce angular correction deg", peirce_rad / DEG, 0.183, rel=3e-3)
v.check("QLC cubic correction rad = lambda^3/4", qlc_rad, 0.002755, rel=5e-4)
v.check("QLC cubic correction deg", qlc_rad / DEG, 0.158, rel=3e-3)
v.check("Peirce + QLC correction", peirce_rad / DEG + qlc_rad / DEG, 0.341, rel=3e-3)

v.check(
    "cos(8.934 deg) used in Jarlskog section",
    cosd(TH13_TOE_DEG),
    0.99388,
    rel=2e-3,
    detail="Expected fail: cos(8.934 deg) is about 0.98787, not 0.99388.",
)
v.check("sin(2*41.245 deg)", sind(2 * TH23_TOE_DEG), 0.99133, rel=2e-4)
v.check("sin(2*8.934 deg)", sind(2 * TH13_TOE_DEG), 0.30704, rel=1e-3)
v.check("sin(66.43 deg)", sind(DELTA_TOE_DEG), 0.91626, rel=5e-4)

k_toe = (
    math.sin(2 * theta23_toe)
    * math.sin(2 * theta13_toe)
    * math.cos(theta13_toe)
    * math.sin(delta_toe)
)
v.check(
    "K_TOE Jarlskog product",
    k_toe,
    0.27761,
    rel=2e-3,
    detail="Expected fail: using the correct cos(8.934 deg) gives about 0.27543.",
)
v.check(
    "J_TOE coefficient K_TOE/8",
    k_toe / 8,
    0.034701,
    rel=2e-3,
    detail="Expected fail: follows from the K_TOE arithmetic error.",
)

j_toe_2 = math.sin(2 * theta12_2) * k_toe / 8
j_pdg = (
    sind(2 * TH12_PDG_DEG)
    * sind(2 * TH23_PDG_DEG)
    * sind(2 * TH13_PDG_DEG)
    * cosd(TH13_PDG_DEG)
    * sind(DELTA_PDG_DEG)
) / 8
v.check(
    "J_TOE at theta12=32.59 deg",
    j_toe_2,
    0.031500,
    rel=3e-3,
    detail="Expected fail at strict precision: corrected K_TOE gives about 0.03125.",
)
v.check("PDG absolute Jarlskog value", j_pdg, 0.030973, rel=5e-3)

theta_from_pdg_j_with_toe_k = 0.5 * asind(j_pdg / (k_toe / 8))
v.check(
    "Jarlskog inversion using PDG J and TOE K",
    theta_from_pdg_j_with_toe_k,
    33.38,
    abs_tol=0.1,
    detail="Expected fail: direct inversion gives about 31.8 deg, i.e. lower theta12.",
)
v.record(
    "Jarlskog section gives mutually incompatible theta12 values",
    False,
    "31.62 deg, 32.59 deg, 33.62 deg, 33.19 deg, and 33.38 deg all appear",
    "one independent determination",
    "Expected fail: this is a logical consistency check, not a numeric tolerance.",
)

delta_j_claim_deg = 0.44
j0_claim = 0.032220
k_claim = 0.27761
delta_j_from_paper_formula_deg = ((0.031500 - j0_claim) / ((k_claim / 4) * math.cos(2 * theta12_2))) / DEG
v.check(
    "Delta_J from the paper's explicit derivative formula",
    delta_j_from_paper_formula_deg,
    delta_j_claim_deg,
    abs_tol=0.1,
    detail="Expected fail: the explicit formula gives about -1.41 deg, not +0.44 deg.",
)

theta_full_as_written_deg = (
    math.pi / 4
    - THETA_C
    + LAM**2 / 2
    + peirce_rad
    + LAM**3 / (4 * math.sin(2 * theta12_2))
    + delta_j_claim_deg * DEG
) / DEG
v.check(
    "closed-form theta12 formula as written",
    theta_full_as_written_deg,
    33.38,
    abs_tol=0.1,
    detail="Expected fail: using +lambda^2/2 in radians evaluates near 34.36 deg.",
)

peirce_u12_scalar = LAM**2 * Y2 / 8
v.check(
    "final calculation scalar y1^2*y2/8",
    peirce_u12_scalar,
    0.006498,
    rel=1e-2,
    detail="Expected fail: y1^2*y2/8 is about 0.002685.",
)
v.check(
    "final Peirce delta |U12|",
    peirce_u12_scalar * sind(TH12_2_DEG),
    0.003502,
    rel=1e-2,
    detail="Expected fail: corrected scalar times sin(32.59 deg) is about 0.00145.",
)
d_u12_c = math.cos(theta12_2) * LAM**3 / 2
v.check("final Cabibbo delta |U12|", d_u12_c, 0.004641, rel=5e-4)

paper_u12_3 = 0.54689
theta_from_paper_u12_correct_cos = asind(paper_u12_3 / cosd(TH13_TOE_DEG))
v.check(
    "theta12 extracted from paper's |U12| with correct cos(theta13)",
    theta_from_paper_u12_correct_cos,
    33.38,
    abs_tol=0.1,
    detail="Expected fail: corrected cos(8.934 deg) gives about 33.6 deg.",
)

u12_corrected = sind(TH12_2_DEG) + peirce_u12_scalar * sind(TH12_2_DEG) + d_u12_c
theta_corrected_definitive = asind(u12_corrected / cosd(TH13_TOE_DEG))
v.record(
    "corrected definitive calculation still closes within 1 sigma",
    abs(theta_corrected_definitive - TH12_PDG_DEG) < 0.77,
    f"{theta_corrected_definitive:.4f} deg",
    "within 0.77 deg of 33.44 deg",
)

v.check("final stated residual 33.44 - 33.38", TH12_PDG_DEG - 33.38, 0.06, abs_tol=1e-12)
v.check("final stated sigma residual", (TH12_PDG_DEG - 33.38) / 0.77, 0.08, rel=3e-2)

sys.exit(v.summary())
