#!/usr/bin/env python3
"""
verify_P046.py -- Addendum 46: Conjectures B/D as trace identities.

This verifier checks the trace identities, moment-log spectrum, top/charm
ratio arithmetic, first-moment/down-quark arithmetic, G0-G1 link, and the
Peirce center matrix formulas in 46_Addendum_ConjBD_Trace.tex.

The main trace identities reproduce. The flagged issues are narrower:
the Peirce-center eigenvalue rule is written as n/(n+1), but the displayed
2/3, 3/4, 4/5 factors come from (n+1)/(n+2) for sector powers n=1,2,3;
the related center-of-mass integral is miscomputed; the displayed current
top/charm inputs imply a +1.14% top-mass discrepancy rather than +2.0%;
and two proposed interpretation routes are not established formulas as
written (G2 Killing form on V1, and the unqualified Bregman-divergence label).
"""

from __future__ import annotations

import math
import sys
from pathlib import Path

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


class ModernVerifier(Verifier):
    """Local adapter: tolerance logic inherited byte-identical from
    verify_common.Verifier; only the output layer is modernised."""

    def __init__(self, name: str) -> None:
        self.name = name
        self.results = []
        print(name)

    def record(self, label, ok, computed="", claimed="", detail=""):
        self.results.append(CheckResult(label, ok, computed, claimed, detail))
        n = len(self.results)
        desc = f"{label} -- {detail}" if detail else label
        print(f"  [{'PASS' if ok else 'FAIL'}] {n:>2}. {desc}")
        if computed != "" or claimed != "":
            print(f"        computed: {computed}")
            print(f"        claimed : {claimed}")
        return ok

    def summary(self):
        passed = sum(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("P046 -- Conjectures B/D Trace Identities")

ROOT = Path(__file__).resolve().parents[1]
TEX = (ROOT / "46_Addendum_ConjBD_Trace.tex").read_text()

PI = math.pi
M_E = 0.51099895
M_TOP = 172_760.0
M_CHARM = 1_275.0
M_DOWN_REF = 4.7


def mu(k: int) -> float:
    return 16.0 * PI**3 / (k + 4.0) + 3.0 * PI**2 / (k + 3.0) + 2.0 * PI / (k + 2.0)


def pct(value: float, target: float) -> float:
    return 100.0 * (value - target) / abs(target)


MU0 = mu(0)
MU1 = mu(1)
MU = MU1 / MU0

XSEC = (PI, PI**2, 4.0 * PI**3)
XONE = (2.0 * PI / 3.0, 3.0 * PI**2 / 4.0, 16.0 * PI**3 / 5.0)
K = (2.0 / 3.0, 3.0 / 4.0, 4.0 / 5.0)

v.check("mu0", MU0, 137.036304, rel=2e-9)
v.check("mu1", MU1, 108.716684, rel=3e-9)
v.check("MU = mu1/mu0", MU, 0.793342, rel=3e-7)
v.check("Z3 dimensions add to dim J3(O)", 3 + 8 + 16, 27, rel=1e-12)

v.check("Tr(Xsec)", sum(XSEC), MU0, rel=1e-12)
v.check("Tr(Xone)", sum(XONE), MU1, rel=1e-12)
v.record(
    "Xone = Xsec circ K componentwise",
    all(abs(XSEC[i] * K[i] - XONE[i]) < 1e-12 for i in range(3)),
    computed=tuple(XSEC[i] * K[i] for i in range(3)),
    claimed=XONE,
)
v.check("Peirce compression ratio", sum(XONE) / sum(XSEC), MU, rel=1e-12)

for k, claimed_mu, claimed_g in [
    (0, 137.036, 6.2019),
    (1, 108.717, 5.9101),
    (2, 90.176, 5.6744),
    (3, 77.063, 5.4764),
    (4, 67.290, 5.3054),
    (5, 59.721, 5.1550),
]:
    muk = mu(k)
    gk = math.log(muk) / MU
    v.check(f"table mu_{k}", muk, claimed_mu, rel=8e-6)
    v.check(f"table G_{k}", gk, claimed_g, rel=9e-6)

g0 = math.log(MU0) / MU
g1 = math.log(MU1) / MU
v.check("G0-G1", g0 - g1, 0.2918, rel=2e-5)
v.check("-ln(MU)/MU", -math.log(MU) / MU, g0 - g1, rel=1e-12)
v.check("trace-ratio log link", math.log(sum(XSEC) / sum(XONE)) / MU, g0 - g1, rel=1e-12)
v.check("r ln r expression", (MU0 / MU1) * math.log(MU0 / MU1), g0 - g1, rel=1e-12)

ratio_pdg = M_TOP / M_CHARM
v.check("PDG top/charm ratio", ratio_pdg, 135.50, rel=2e-5)
v.check("mu0 vs PDG top/charm discrepancy percent", pct(MU0, ratio_pdg), 1.1, rel=4e-2)
mt_from_ratio = MU0 * M_CHARM
v.check(
    "top-mass discrepancy from displayed 172760/1275 inputs",
    pct(mt_from_ratio, M_TOP),
    2.0,
    rel=5e-2,
    detail="Expected fail: with the displayed current inputs the ratio route gives +1.14%, not +2.0%; the +2.0% appears to be inherited from a different Addendum 45 comparison.",
)

ed = math.log(MU1) / MU
md = M_E * math.exp(MU * (ed - PI))
v.check("E_d = ln(mu1)/MU", ed, 5.9101, rel=5e-6)
v.check("down mass from E_d", md, 4.595, rel=4e-5)
v.check("down mass residual percent", pct(md, M_DOWN_REF), -2.2, rel=2e-2)

char_pair_sum = PI**3 + 4.0 * PI**4 + 4.0 * PI**5
char_product = 4.0 * PI**6
v.check("Xsec characteristic trace coefficient", sum(XSEC), MU0, rel=1e-12)
v.check("Xsec characteristic pair coefficient", XSEC[0] * XSEC[1] + XSEC[0] * XSEC[2] + XSEC[1] * XSEC[2], char_pair_sum, rel=1e-12)
v.check("Xsec characteristic product", XSEC[0] * XSEC[1] * XSEC[2], char_product, rel=1e-12)

sector_powers = (1, 2, 3)
wrong_rule = tuple(n / (n + 1.0) for n in sector_powers)
right_rule = tuple((n + 1.0) / (n + 2.0) for n in sector_powers)
v.record(
    "K_i = n_i/(n_i+1) for sector powers n_i=1,2,3",
    all(abs(wrong_rule[i] - K[i]) < 1e-12 for i in range(3)),
    computed=wrong_rule,
    claimed=K,
    detail="Expected fail: the displayed K entries require (n+1)/(n+2), not n/(n+1), for density powers x^n.",
)
v.record(
    "center-of-mass integral equals n/(n+1)",
    all(abs(right_rule[i] - wrong_rule[i]) < 1e-12 for i in range(3)),
    computed=right_rule,
    claimed=wrong_rule,
    detail="Expected fail: integral_0^1 x*(n+1)x^n dx = (n+1)/(n+2).",
)

v.record(
    "Route 2 uses a well-defined G2 Killing form restricted to V1",
    False,
    computed="the Killing form is defined on the Lie algebra g2; V1 is a trivial/fixed subspace of the J3(O) representation",
    claimed="G2 Killing form restricted to V1 is proportional to the J3(O) trace form",
    detail="Expected proof-status fail: an invariant trace form on V1 may be chosen, but it is not literally the G2 Killing form restricted to V1.",
)
v.record(
    "r ln r is justified as a Bregman divergence without specifying a generator/baseline",
    False,
    computed="r ln r with r=mu0/mu1; standard Bregman divergences include a generator and affine subtraction term",
    claimed="-ln(MU)/MU is the Bregman divergence",
    detail="Expected wording/status fail: the identity is true, but the Bregman interpretation is not established by the displayed formula.",
)
v.record(
    "OP-B and OP-D are fully structurally closed in this paper",
    "Remaining input" not in TEX and "remaining open problem" not in TEX,
    computed="the paper lists remaining inputs: Z3 spectral normalization for OP-B and -ln(MU)/MU as a JO Casimir for OP-D",
    claimed="structurally targeted trace reformulation",
    detail="Expected status note: the trace identities are exact, but the structural derivations remain open by the paper's own checklist.",
)

sys.exit(v.summary())
