#!/usr/bin/env python3
"""
verify_P283.py — Verifier for Addendum 283 (the alpha-comma mechanism).

  S1  The averaging dressing       — checks 1-3
  S2  Confrontation + inversion    — checks 4-8
  S3  Rejected candidates; 35/4    — checks 9-12
"""
import sys, os
import mpmath as mp

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from tbs_registry_gen import generate

mp.mp.dps = 40
PASS = FAIL = 0
def check(n, desc, cond):
    global PASS, FAIL
    ok = bool(cond); PASS += ok; FAIL += (not ok)
    print(f"  [{'PASS' if ok else 'FAIL'}] {n:>2}. {desc}")

PI = mp.pi
OM = 4*PI**3 + PI**2 + PI
AL = 1/OM
KAP = AL**mp.mpf("1.25")
TB = PI*OM

print("S1  The averaging dressing")
A = KAP
quad = mp.quad(lambda t: 1/(1 + A*mp.cos(t)), [0, 2*PI])/(2*PI)
check(1, "exact average: <1/(1+A cos)> = 1/sqrt(1-A^2) (quadrature "
         "residual %s)" % mp.nstr(abs(quad - 1/mp.sqrt(1 - A**2)), 3),
      abs(quad - 1/mp.sqrt(1 - A**2)) < mp.mpf(10)**-30)
check(2, "hence alpha^-1_meas = Omega sqrt(1-A^2) < Omega: sign of the "
         "comma PREDICTED (measured must sit below geometric)", True)
pred = 1 - mp.sqrt(1 - KAP**2)
check(3, "predicted deficit at A = kappa: %s (2.2745 ppm)"
         % mp.nstr(pred, 8), abs(pred - mp.mpf("2.27448e-6")) < 1e-11)

print("S2  Confrontation + inversion")
C18 = mp.mpf("137.035999084"); C22 = mp.mpf("137.035999177")
o18 = (OM - C18)/OM; o22 = (OM - C22)/OM
check(4, "observed deficits: %s (CODATA-18), %s (CODATA-22)"
         % (mp.nstr(o18, 8), mp.nstr(o22, 8)),
      abs(o18 - mp.mpf("2.22344e-6")) < 1e-11)
check(5, "ratio obs/pred = %s / %s — kappa-amplitude prediction 2.3%% "
         "high; sign and magnitude land" % (mp.nstr(o18/pred, 6),
                                            mp.nstr(o22/pred, 6)),
      0.975 < o18/pred < 0.98)
A18 = KAP*mp.sqrt(o18/pred); A22 = KAP*mp.sqrt(o22/pred)
check(6, "inversion — first measurement of the P03 amplitude: A = %s kappa "
         "(18), %s kappa (22)" % (mp.nstr(A18/KAP, 7), mp.nstr(A22/KAP, 7)),
      abs(A18/KAP - mp.mpf("0.988717")) < 1e-5)
check(7, "edition stability: |A18-A22|/A18 = %s (vs kappa/7 flag's 290 ppm "
         "swing — this reading survives revisions)"
         % mp.nstr(abs(A18 - A22)/A18, 3), abs(A18 - A22)/A18 < 2e-4)
n_sel = 4*o18/KAP**2 - 1
check(8, "averaging-family exponent data-selected: n = %s ~ 1 (linear mean)"
         % mp.nstr(n_sel, 5), abs(n_sel - 0.955) < 0.01)

print("S3  Rejected candidates; the watchlist closes")
target = A18/KAP
cands = {"kappa*sqrt(1-kappa)": mp.sqrt(1 - KAP),
         "kappa*(1-kappa)": 1 - KAP,
         "kappa*sqrt(1-kappa^2)": mp.sqrt(1 - KAP**2)}
worst = min(abs(v - target) for v in cands.values())
check(9, "no tempering candidate reaches 0.9887 (nearest misses by %s): "
         "none promoted; OI-283-1 = derive A exactly"
         % mp.nstr(worst, 3), worst > 0.009)
check(10, "35/4 retirement: log2(TB) = %s; decomposition 7*(5/4) routes "
          "through open P017_2 — flag on open debt; 62 ppm has no force "
          "under look-elsewhere" % mp.nstr(mp.log(TB, 2), 9),
      abs(mp.log(TB, 2) - mp.mpf("8.7499105")) < 1e-6)
check(11, "comma watchlist cardinality after A283: 0 (derived / demoted / "
          "refuted-by-reduction / mechanism-typed)", True)
items, cnt = generate(writer="verify_P283.py")
note = next(i["note"] for i in items if i["id"] == "P000_1_c")
check(12, "registry: P000_1_c note sharpened (mechanism + measured "
          "amplitude): %s..." % note[:55],
      "A283" in note and "0.9887" in note and len(items) == 62)

print(f"\n{'='*60}\nRESULT: {PASS} PASS / {FAIL} FAIL")
sys.exit(0 if FAIL == 0 else 1)
