#!/usr/bin/env python3
"""verify_P174.py -- Addendum 174: G2 -> A2 branching and Cabibbo angle."""

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 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("P174 -- G2/A2 Branching")
ROOT = Path(__file__).resolve().parents[1]
TEX = (ROOT / "174_Addendum_U3G2_Branching.tex").read_text()

PI = math.pi
SQRT3 = math.sqrt(3.0)
alpha1 = (1.0, 0.0)
alpha2 = (-1.5, SQRT3 / 2.0)


def add(a: tuple[float, float], b: tuple[float, float]) -> tuple[float, float]:
    return (a[0] + b[0], a[1] + b[1])


def scale(c: float, a: tuple[float, float]) -> tuple[float, float]:
    return (c * a[0], c * a[1])


def dot(a: tuple[float, float], b: tuple[float, float]) -> float:
    return a[0] * b[0] + a[1] * b[1]


def norm2(a: tuple[float, float]) -> float:
    return dot(a, a)


def angle_deg(a: tuple[float, float]) -> float:
    return math.degrees(math.atan2(a[1], a[0])) % 360.0


positive_roots = [
    alpha1,
    alpha2,
    add(alpha1, alpha2),
    add(scale(2.0, alpha1), alpha2),
    add(scale(3.0, alpha1), alpha2),
    add(scale(3.0, alpha1), scale(2.0, alpha2)),
]
short_pos = [r for r in positive_roots if abs(norm2(r) - 1.0) < 1e-12]
long_pos = [r for r in positive_roots if abs(norm2(r) - 3.0) < 1e-12]
all_angles = sorted([angle_deg(r) for r in positive_roots] + [(angle_deg(r) + 180.0) % 360.0 for r in positive_roots])
angle_gaps = [((all_angles[(i + 1) % 12] - all_angles[i]) % 360.0) for i in range(12)]
beta1 = alpha2
beta2 = add(scale(3.0, alpha1), alpha2)

v.record("TeX source is present", "Cabibbo Holonomy Angle" in TEX and "G_2" in TEX)
v.check("Cartan determinant", 2 * 2 - (-1) * (-3), 1, rel=0)
v.check("Cartan eigenvalue low", 2.0 - SQRT3, 2.0 - SQRT3, rel=0)
v.check("Cartan eigenvalue high", 2.0 + SQRT3, 2.0 + SQRT3, rel=0)
v.check("short simple root length squared", norm2(alpha1), 1.0, rel=1e-12)
v.check("long simple root length squared", norm2(alpha2), 3.0, rel=1e-12)
v.check("simple-root angle degrees", math.degrees(math.acos(dot(alpha1, alpha2) / math.sqrt(norm2(alpha1) * norm2(alpha2)))), 150.0, rel=1e-12)
v.check("positive root count", len(positive_roots), 6, rel=0)
v.check("short root count", 2 * len(short_pos), 6, rel=0)
v.check("long root count", 2 * len(long_pos), 6, rel=0)
v.record(
    "combined G2 root fan has pi/6 spacing",
    all(abs(g - 30.0) < 1e-10 for g in angle_gaps),
    computed=angle_gaps,
    claimed="12 roots uniformly spaced by 30 degrees",
)
v.check("A2 long-root Cartan off-diagonal", 2.0 * dot(beta1, beta2) / norm2(beta2), -1.0, rel=1e-12)
v.check("G2 Lie algebra dimension", 12 + 2, 14, rel=0)
v.check("7 -> 1+3+3bar dimension check", 1 + 3 + 3, 7, rel=0)
v.check("root-fan identity", (PI / 6.0) * (3.0 / 7.0), PI / 14.0, rel=1e-15)
v.check("Lie-dimension identity", PI / 14.0, PI / 14.0, rel=0)
v.check("Wolfenstein lambda from sin(pi/14)", math.sin(PI / 14.0), 0.222520934, rel=2e-9)
v.record(
    "boundary of derivation is stated",
    "Conditional on P94" in TEX and "Not yet proved" in TEX,
    computed="conditional-status caveat found",
    claimed="holonomy angle imported from P94",
)

v.record(
    "P174 independently derives theta_C=pi/14",
    False,
    computed="the paper states that the specific value pi/14 requires the P94 holonomy computation",
    claimed="Cabibbo angle theta_C=pi/14 is established here from weight geometry alone",
    detail="Expected dependency/status fail.",
)
v.record(
    "pi/dim(G2) is a holonomy derivation",
    False,
    computed="pi/14=pi/dim(G2) is an exact identity after choosing 14; no connection curvature or holonomy calculation is supplied here",
    claimed="the Lie algebra identity explains theta_C",
    detail="Expected numerology/proof gap.",
)
v.record(
    "root-fan dimension-ratio identity proves physical Cabibbo mixing",
    False,
    computed="(pi/6)*(3/7)=pi/14 is arithmetic consistency; it does not construct a CKM rotation or identify a physical mixing operator",
    claimed="weight geometry makes the Cabibbo angle natural with no new physical parameters",
    detail="Expected physics-bridge gap.",
)
v.record(
    "sin(pi/14) equals the measured Wolfenstein parameter exactly",
    False,
    computed="sin(pi/14)=0.222520934; current phenomenological lambda values are close but not an exact mathematical equality, and the paper uses an approximate six-figure criterion",
    claimed="sin(pi/14)=lambda_Wolfenstein",
    detail="Expected precision/status fail.",
)
v.record(
    "accompanying P174 script is present at the cited path",
    False,
    computed="this TOE workspace has TOE/verify/verify_P174_U3G2_branching.py, not Lumen/corpus/addenda/verify/verify_P174_U3G2_branching.py",
    claimed="run python Lumen/corpus/addenda/verify/verify_P174_U3G2_branching.py",
    detail="Expected reproducibility/path fail.",
)

sys.exit(v.summary())
