#!/usr/bin/env python3
"""
verify_P006.py -- Paper 06: Standard Model fermion sector.

This verifier checks the explicit arithmetic and reproducibility of
toe/06_Paper_FermionSector.tex.  The basic rho integral, Z3 representation
count, mass-table error arithmetic, and several displayed CKM/PMNS angles
are reproducible at the paper's precision.  The flagged issues are larger
method/status problems: the mass formula is calibrated with fitted A,B,C
parameters for each fermion type, the eigenvalues and fitted parameters are
not printed, the displayed "tribimaximal" matrix is rank-1 rather than
unitary TBM, the positive-entry CKM/PMNS magnitude tables are not themselves
unitary matrices, the neutrino masses in the table are far above the abstract's
0.1 eV scale, and the no-fourth-family/topological-proof claims overreach the
Z3 representation count.
"""

from __future__ import annotations

import math
import sys
from pathlib import Path

import numpy as np

sys.path.insert(0, str(Path(__file__).resolve().parent))
from verify_common import CheckResult, Verifier


class ModernVerifier(Verifier):
    """Local output adapter: tolerance logic byte-identical to
    verify_common.Verifier.check; emits the modern corpus line format
    ("  [PASS] {n:>2}. {desc}") with computed/claimed/tolerance values
    kept as indented info lines, and the modern RESULT footer."""

    def __init__(self, name: str):
        self.name = name
        self.results = []
        self._n = 0
        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._emit(label, ok, computed, claimed, err_detail, detail)

    def record(self, label, ok, computed="", claimed="", detail=""):
        return self._emit(label, ok, computed, claimed, "", detail)

    def _emit(self, label, ok, computed, claimed, info, ann):
        full_detail = (info + (f"; {ann}" if ann else "")) if info else ann
        self.results.append(CheckResult(label, ok, computed, claimed, full_detail))
        self._n += 1
        desc = f"{label} -- {ann}" if ann else label
        print(f"  [{'PASS' if ok else 'FAIL'}] {self._n:>2}. {desc}")
        if computed != "" or claimed != "":
            print(f"        computed: {computed}")
            print(f"        claimed : {claimed}")
        if info:
            print(f"        {info}")
        return ok

    def summary(self):
        passed = sum(bool(r.ok) for r in self.results)
        failed = len(self.results) - passed
        print(f"\n{'='*60}\nRESULT: {passed} PASS / {failed} FAIL")
        return 1 if failed else 0


v = ModernVerifier("P006 -- Standard Model Fermion Sector")

ROOT = Path(__file__).resolve().parents[2]
TEX = (ROOT / "toe" / "06_Paper_FermionSector.tex").read_text()

PI = math.pi
MU0 = 4 * PI**3 + PI**2 + PI


def deg(x: float) -> float:
    return math.degrees(x)


def log_error(pred: float, exp: float) -> float:
    return abs(math.log10(pred / exp))


v.check("rho integral mu0", MU0, 137.036, rel=3e-6)
v.check("alpha from rho integral", 1.0 / MU0, 0.00729735, rel=2e-6)
v.check("Z3 has three complex irreducible representations", 3, 3, rel=1e-12)
v.record(
    "Dirichlet boundary conditions are stated",
    "\\psi_n(0) = \\psi_n(1) = 0" in TEX,
    computed="Dirichlet endpoints present",
    claimed="particles vanish at physical boundaries",
)

err_d = log_error(4.85e-3, 4.70e-3)
err_numu = log_error(9.58e-7, 1.00e-6)
avg_listed_error = (0.01 + 0.02) / 12.0
v.check("down-quark table log10 error", err_d, 0.01, rel=4e-1)
v.check("nu_mu table log10 error", err_numu, 0.02, rel=8e-2)
v.check("average listed table error", avg_listed_error, 0.003, rel=2e-1)
v.check("0.01 decades as percent", 100.0 * (10**0.01 - 1.0), 2.0, rel=2e-1)

nu_e_ev = 1.00e-7 * 1e9
nu_mu_ev = 9.58e-7 * 1e9
nu_tau_ev = 1.00e-5 * 1e9
v.check(
    "table nu_e mass vs abstract ~0.1 eV scale",
    nu_e_ev,
    0.1,
    rel=1.0,
    detail="Expected fail: 1e-7 GeV is 100 eV, not order 0.1 eV.",
)
v.check(
    "table nu_tau mass vs abstract ~0.1 eV scale",
    nu_tau_ev,
    0.1,
    rel=1.0,
    detail="Expected fail: 1e-5 GeV is 10,000 eV, far above the stated neutrino scale.",
)
v.record(
    "neutrino table values are PDG experimental masses",
    False,
    computed=f"table gives {nu_e_ev:g}, {nu_mu_ev:g}, {nu_tau_ev:g} eV",
    claimed="experimental GeV values from PDG 2024",
    detail="Expected data-status fail: these are not the measured light-neutrino mass spectrum.",
)

u_tri = np.ones((3, 3)) / math.sqrt(3.0)
gram_tri = u_tri.T @ u_tri
v.check("displayed U_tri element", u_tri[0, 0], 1.0 / math.sqrt(3.0), rel=1e-12)
v.check(
    "displayed U_tri off-diagonal Gram entry",
    gram_tri[0, 1],
    0.0,
    abs_tol=1e-12,
    detail="Expected fail: the all-1/sqrt(3) matrix has identical columns, so it is not unitary.",
)
v.check(
    "displayed U_tri determinant",
    float(np.linalg.det(u_tri)),
    1.0,
    rel=1e-12,
    detail="Expected fail: determinant is zero because the matrix has rank 1.",
)
v.check(
    "theta13 implied by displayed U_tri",
    deg(math.asin(u_tri[0, 2])),
    0.0,
    abs_tol=1e-12,
    detail="Expected fail: standard TBM has Ue3=0; this matrix gives theta13 about 35.26 degrees.",
)

ckm = np.array(
    [
        [0.974, 0.225, 0.004],
        [0.222, 0.973, 0.042],
        [0.009, 0.041, 0.999],
    ]
)
pmns = np.array(
    [
        [0.821, 0.551, 0.149],
        [0.547, 0.677, 0.501],
        [0.154, 0.488, 0.852],
    ]
)
v.check("CKM first row norm", float(np.sum(ckm[0] ** 2)), 1.0, rel=1e-3)
v.check(
    "CKM displayed positive rows are orthogonal",
    float(ckm[0] @ ckm[1]),
    0.0,
    abs_tol=1e-3,
    detail="Expected fail: the displayed magnitudes cannot be treated as a real orthogonal matrix.",
)
v.check("CKM theta12 from Vus", deg(math.asin(0.225)), 13.04, rel=4e-3)
v.check("CKM theta13 from Vub", deg(math.asin(0.004)), 0.20, rel=2e-1)
v.check("CKM theta23 from Vcb", deg(math.asin(0.042)), 2.38, rel=2e-2)

v.check("PMNS first row norm", float(np.sum(pmns[0] ** 2)), 1.0, rel=2e-4)
v.check(
    "PMNS displayed positive rows are orthogonal",
    float(pmns[0] @ pmns[1]),
    0.0,
    abs_tol=1e-3,
    detail="Expected fail: the displayed positive-entry table is a magnitude table, not a unitary matrix.",
)
v.check("PMNS theta12 from displayed Ue2", deg(math.asin(0.551)), 33.44, rel=5e-4)
v.check("PMNS theta13 from displayed Ue3", deg(math.asin(0.149)), 8.57, rel=2e-3)
v.check(
    "PMNS theta23 from displayed Umu3",
    deg(math.asin(0.501)),
    49.2,
    rel=2e-2,
    detail="Expected fail: direct reading of the displayed matrix gives about 30.1 degrees, not 49.2 degrees.",
)

v.record(
    "mass predictions are reproducible from printed eigenvalues and A,B,C",
    False,
    computed="TeX gives the fitted mass table but not the eigenvalues, x_peak values, or fitted A/B/C parameters",
    claimed="masses are eigenvalues requiring no arbitrary mass parameters",
    detail="Expected reproducibility fail.",
)
v.record(
    "mass formula uses zero fitted parameters",
    "optimized separately for each fermion type" not in TEX,
    computed="paper states A,B,C are optimized separately for each fermion type",
    claimed="zero free parameters / no arbitrary mass parameters",
    detail="Expected status fail.",
)
v.record(
    "CKM and PMNS matrices are predictions rather than optimized fits",
    "We optimize $\\Delta U$" not in TEX,
    computed="paper says Delta U is optimized to match experimental matrices and prints identical predicted/experimental tables",
    claimed="CKM and PMNS derived/predicted with <0.2% errors",
    detail="Expected status fail.",
)
v.record(
    "log-periodic node data are included",
    False,
    computed="summary claims are printed, but node positions/eigenfunctions are absent",
    claimed="node spacing and fractal dimensions verified from numerical solution",
    detail="Expected reproducibility fail: no node table or solver output is present in this TeX.",
)
v.record(
    "exactly three families is consistent with the four triplets table",
    "Fourth (neutrinos)" not in TEX,
    computed="triplet table lists (9,10,11) as a fourth neutrino triplet",
    claimed="exactly three fermion families",
    detail="Expected internal-consistency fail.",
)
v.record(
    "Z3 irreps alone topologically forbid a fourth family",
    False,
    computed="a representation label can occur with multiplicity; absence of a fourth irrep does not forbid additional copies without more structure",
    claimed="fourth family topologically forbidden by Z3",
    detail="Expected proof-audit fail.",
)

sys.exit(v.summary())
