"""
verify_P215.py — Verification for Addendum P215
OP-G2A2-lattice: Lattice Path Derivation of T_k from the A₂ Lepton Face.

Sections verified:
  §1  T_k formula for k=1..5
  §2  Ratios T_{k+1}/T_k = −r for k=1..4
  §3  A₂ adjacency matrix Trace(A^{2k}) for k=1,2,3
  §4  Seed factorisation T_k = (−1)^{k+1} · r^k · σ
  §5  Resolvent comparison (mismatch documented)
  §6  Partial sums converging to R∞ from P213
  §7  Sanity checks on constants and loop-weight

All assertions run at mp.dps = 60.
© Léon Fernando Vlegels. MIT License.
"""

from mpmath import mp, mpf, pi, fabs, nstr, sqrt as mpsqrt
import sys
mp.dps = 60

PASS = FAIL = 0
_N = 0

def check(desc, cond):
    global PASS, FAIL, _N
    _N += 1
    ok = bool(cond)
    PASS += ok
    FAIL += (not ok)
    print(f"  [{'PASS' if ok else 'FAIL'}] {_N:>2}. {desc}")
    return ok

# ─────────────────────────────────────────────────────────────────────────────
# Constants
# ─────────────────────────────────────────────────────────────────────────────
ALPHA_INV  = 4*pi**3 + pi**2 + pi      # μ  = ALPHA_INV ≈ 137.036
OMEGA_0    = pi**3 / 4                  # ω  = OMEGA_0
E_e        = pi                          # e  = electron sector energy = π
E_mu       = pi**2                       # E_μ = e² = muon energy insertion
TARGET     = mpf('206.7682830')          # CODATA-2018 muon/electron mass ratio
h          = mpf(3)                      # h∨(A₂) = 3
alpha      = 1 / ALPHA_INV               # fine-structure constant

# Seed and loop weight
sigma      = ALPHA_INV / E_e**5         # σ = μ/e⁵  (bare propagator seed)
r          = h * E_e**2 / ALPHA_INV**2  # r = h·e²/μ² (one-loop weight)

# T₀ correction (candidate-8 base)
T0 = -OMEGA_0 / (E_e**3 * ALPHA_INV)

# ─────────────────────────────────────────────────────────────────────────────
# §1: Constants sanity
# ─────────────────────────────────────────────────────────────────────────────

# A1: h∨(A₂) = 3
check("A1: h∨(A₂) = 3", int(h) == 3)
# A2: μ ≈ 137.036
check("A2: μ ≈ 137.036", fabs(ALPHA_INV - mpf('137.036')) < mpf('0.001'))
# A3: ω = π³/4
check("A3: ω = π³/4", fabs(OMEGA_0 - E_e**3/4) < mpf('1e-58'))
# A4: μ = 4e³+e²+e
check("A4: μ = 4e³+e²+e", fabs(ALPHA_INV - (4*E_e**3 + E_e**2 + E_e)) < mpf('1e-58'))
# A5: E_μ = e²
check("A5: E_μ = e²", fabs(E_mu - E_e**2) < mpf('1e-58'))
# A6: r = h·E_μ/μ² = h·e²/μ²
check("A6: r = h·E_μ/μ²", fabs(r - h*E_mu/ALPHA_INV**2) < mpf('1e-58'))
# A7: r ≈ 0.001577
check("A7: r ≈ 0.001577", fabs(r - mpf('0.001577')) < mpf('0.00001'))
# A8: σ = μ/e⁵ = 4/e²+1/e³+1/e⁴
sigma_check = 4/E_e**2 + 1/E_e**3 + 1/E_e**4
check("A8: σ = 4/e²+1/e³+1/e⁴", fabs(sigma - sigma_check) < mpf('1e-58'))
# A9: r = h∨(A₂)·α²·e²
check("A9: r = h·α²·e²", fabs(r - h*alpha**2*E_e**2) < mpf('1e-55'))
# ─────────────────────────────────────────────────────────────────────────────
# §2: T_k formula — direct definition
# ─────────────────────────────────────────────────────────────────────────────

def T_k_def(k):
    """T_k = (-1)^{k+1} · h^k · e^{2k-5} / μ^{2k-1}"""
    return ((-1)**(k+1)) * h**k * E_e**(2*k-5) / ALPHA_INV**(2*k-1)

T1 = T_k_def(1)
T2 = T_k_def(2)
T3 = T_k_def(3)
T4 = T_k_def(4)
T5 = T_k_def(5)

# A10: T1 = h/(e³μ) > 0
check("A10: T1 = h/(e³μ)", fabs(T1 - h/(E_e**3 * ALPHA_INV)) < mpf('1e-58'))
check("A10b: T1 > 0", T1 > 0)
# A11: T2 = −h²/(e·μ³) < 0
check("A11: T2 = −h²/(eμ³)", fabs(T2 - (-h**2/(E_e * ALPHA_INV**3))) < mpf('1e-58'))
check("A11b: T2 < 0", T2 < 0)
# A12: T3 = h³·e/μ⁵ > 0
check("A12: T3 = h³e/μ⁵", fabs(T3 - h**3*E_e/ALPHA_INV**5) < mpf('1e-58'))
check("A12b: T3 > 0", T3 > 0)
# A13: T4 = −h⁴·e³/μ⁷ < 0
check("A13: T4 = −h⁴e³/μ⁷", fabs(T4 - (-h**4*E_e**3/ALPHA_INV**7)) < mpf('1e-58'))
check("A13b: T4 < 0", T4 < 0)
# A14: T5 = h⁵·e⁵/μ⁹ > 0
check("A14: T5 = h⁵e⁵/μ⁹", fabs(T5 - h**5*E_e**5/ALPHA_INV**9) < mpf('1e-58'))
check("A14b: T5 > 0", T5 > 0)
# A15: magnitudes decrease monotonically
check("A15: |T1|>|T2|>|T3|>|T4|>|T5|", fabs(T1) > fabs(T2) > fabs(T3) > fabs(T4) > fabs(T5))
# ─────────────────────────────────────────────────────────────────────────────
# §3: Geometric ratio T_{k+1}/T_k = −r
# ─────────────────────────────────────────────────────────────────────────────

# A16: T2/T1 = −r
check("A16: T2/T1 = −r", fabs(T2/T1 - (-r)) < mpf('1e-55'))
# A17: T3/T2 = −r
check("A17: T3/T2 = −r", fabs(T3/T2 - (-r)) < mpf('1e-55'))
# A18: T4/T3 = −r
check("A18: T4/T3 = −r", fabs(T4/T3 - (-r)) < mpf('1e-55'))
# A19: T5/T4 = −r
check("A19: T5/T4 = −r", fabs(T5/T4 - (-r)) < mpf('1e-55'))
# A20: ratios are identical (constant common ratio)
check("A20: T2/T1 = T3/T2", fabs(T2/T1 - T3/T2) < mpf('1e-60'))
check("A21: T3/T2 = T4/T3", fabs(T3/T2 - T4/T3) < mpf('1e-60'))
# ─────────────────────────────────────────────────────────────────────────────
# §4: A₂ adjacency matrix — trace formula Tr(A^{2k}) = 4^k + 2
# ─────────────────────────────────────────────────────────────────────────────
# A (K₃) has eigenvalues 2, -1, -1
# Tr(A^{2k}) = 2^{2k} + 2·(-1)^{2k} = 4^k + 2

# A22: k=1: Tr(A²) = 6 = 4¹+2
Tr_A2  = 4**1 + 2
check("A22: Tr(A²) = 6", Tr_A2 == 6)
# A23: k=2: Tr(A⁴) = 18 = 4²+2
Tr_A4  = 4**2 + 2
check("A23: Tr(A⁴) = 18", Tr_A4 == 18)
# A24: k=3: Tr(A⁶) = 66 = 4³+2
Tr_A6  = 4**3 + 2
check("A24: Tr(A⁶) = 66", Tr_A6 == 66)
# A25: Tr(A²)/2 = 3 = h∨(A₂)  ✓ (k=1 matches)
check("A25: Tr(A²)/2 = h∨(A₂)", Tr_A2//2 == int(h))
# A26: Tr(A⁴)/2 = 9 = h∨(A₂)²  ✓ (k=2 matches)
check("A26: Tr(A⁴)/2 = h∨(A₂)²", Tr_A4//2 == int(h)**2)
# A27: Tr(A⁶)/2 = 33 ≠ 27 = h∨(A₂)³  ✗ (k=3 fails)
check("A27: Tr(A⁶)/2 = 33", Tr_A6//2 == 33)
check("A28: 33 ≠ 27 = h∨(A₂)³ (pattern breaks at k=3)", 33 != int(h)**3)
# A29: General formula: Tr(A^{2k}) = 4^k + 2 (verified for k=1,2,3,4,5)
for k in range(1, 6):
    formula_val = 4**k + 2
    # Verify by expansion: eigenvalues 2,-1,-1 → Tr = 2^{2k}+2·(-1)^{2k} = 4^k+2
    eigen_trace = 2**(2*k) + 2*(-1)**(2*k)
    check(f"A29k{k}: eigenvalue formula at k={k}", formula_val == eigen_trace)
# A30: Trace-half matches h^k only for k=1,2
for k in [1, 2]:
    check(f"A30: Tr(A^{{2k}})/2 = h^k at k={k}", (4**k + 2)//2 == 3**k)
for k in [3, 4, 5]:
    check(f"A31: Tr(A^{{2k}})/2 ≠ h^k at k={k} (pattern breaks)", (4**k + 2)//2 != 3**k)
# ─────────────────────────────────────────────────────────────────────────────
# §5: Seed factorisation T_k = (−1)^{k+1} · r^k · σ
# ─────────────────────────────────────────────────────────────────────────────

def T_k_seed(k):
    """T_k = (−1)^{k+1} · r^k · σ  (Lemma 3.1)"""
    return ((-1)**(k+1)) * r**k * sigma

# A32: Seed form matches definition for k=1,2,3,4,5
for k in range(1, 6):
    T_def  = T_k_def(k)
    T_seed = T_k_seed(k)
    check(f"A32k{k}: seed form = def at k={k}", fabs(T_def - T_seed) < mpf('1e-55'))
# A33: σ = μ/e⁵
check("A33: σ = μ/e⁵", fabs(sigma - ALPHA_INV/E_e**5) < mpf('1e-58'))
# A34: r = h·e²/μ²  (r already verified; reconfirm link to seed)
check("A34: r·σ = T1", fabs(r**1 * sigma - T1) < mpf('1e-58'))
check("A35: r²·σ = -T2", fabs(r**2 * sigma - (-T2)) < mpf('1e-58'))
# A36: T_k/σ = (−r)^k × (−1) ... actually (−1)^{k+1}·r^k, verified:
for k in range(1, 5):
    ratio = T_k_def(k) / sigma
    expected = ((-1)**(k+1)) * r**k
    check(f"A36k{k}: T_k/σ = (−1)^{{k+1}}·r^k", fabs(ratio - expected) < mpf('1e-55'))
# ─────────────────────────────────────────────────────────────────────────────
# §6: Resolvent comparison (mismatch documented)
# ─────────────────────────────────────────────────────────────────────────────
# A₂ adjacency resolvent at λ = μ/e:
# G(λ) = 1/(λ-2) + 2/(λ+1) = 3(λ-1)/((λ-2)(λ+1))
lam = ALPHA_INV / E_e
G_lam = 1/(lam - 2) + 2/(lam + 1)

# Closed-form sum S = T1/(1+r) = hμ/(e³(μ²+he²))
S_closed = h * ALPHA_INV / (E_e**3 * (ALPHA_INV**2 + h*E_e**2))

# A37: Resolvent at λ=μ/e is computed correctly
G_check = 3*(lam - 1)/((lam - 2)*(lam + 1))
check("A37: resolvent formula consistent", fabs(G_lam - G_check) < mpf('1e-55'))
# A38: G(μ/e) ≠ S_closed (mismatch documented)
mismatch = fabs(G_lam - S_closed)
check("A38: G(μ/e) ≠ S_closed (mismatch > 0.06)", mismatch > mpf('0.06'))
# A39: Mismatch factor ≈ 97.7 (not a simple integer ratio)
factor = G_lam / S_closed
check("A39: mismatch factor ≈ 97.7", factor > mpf('90') and factor < mpf('105'))
# A40: S_closed = σ·r/(1+r) exactly (Lemma + geometric series)
S_seed_form = sigma * r / (1 + r)
check("A40: S_closed = σ·r/(1+r)", fabs(S_closed - S_seed_form) < mpf('1e-55'))
# A41: S_closed = T1/(1+r)  (from geometric series)
check("A41: S_closed = T1/(1+r)", fabs(S_closed - T1/(1+r)) < mpf('1e-55'))
# ─────────────────────────────────────────────────────────────────────────────
# §7: Partial sums converging to R∞
# ─────────────────────────────────────────────────────────────────────────────
R_closed = 207 * (1 + T0 + S_closed)
gap_closed = fabs(R_closed - TARGET)/TARGET * 1e6

# A42: R∞ computed from closed form
check("A42: R∞ = 207(1+T0+T1/(1+r))", fabs(R_closed - 207*(1 + T0 + T1/(1+r))) < mpf('1e-50'))
# A43: R∞ gap ≈ 0.01113 ppm
check("A43: R∞ gap ≈ 0.01113 ppm", fabs(gap_closed - mpf('0.01113')) < mpf('0.0001'))
# A44: R∞ > TARGET
check("A44: R∞ > TARGET", R_closed > TARGET)
# A45: Partial sum k=1 (R_star)
S_partial1 = T1
R_star = 207*(1 + T0 + S_partial1)
gap_star = fabs(R_star - TARGET)/TARGET * 1e6
check("A45: R_star gap ∈ [1.1, 1.2] ppm", gap_star > mpf('1.1') and gap_star < mpf('1.2'))
# A46: Partial sum k=2 (R3)
S_partial2 = T1 + T2
R3 = 207*(1 + T0 + S_partial2)
gap_R3 = fabs(R3 - TARGET)/TARGET * 1e6
check("A46: R3 gap ≈ 0.009373 ppm", fabs(gap_R3 - mpf('0.009373')) < mpf('0.0001'))
# A47: Partial sum k=3 increases gap (R3 closest to TARGET among partial sums)
S_partial3 = T1 + T2 + T3
R4 = 207*(1 + T0 + S_partial3)
gap_R4 = fabs(R4 - TARGET)/TARGET * 1e6
check("A47: k=3 partial sum gap > k=2 (R3 is optimal truncation)", gap_R4 > gap_R3)
# A48: Convergence: by k=4 the sum is within 10⁻¹⁰ ppm of R∞
S_partial4 = T1 + T2 + T3 + T4
R5 = 207*(1 + T0 + S_partial4)
gap_to_Rinf = fabs(R5 - R_closed)
check("A48: partial sum k=4 within 10⁻⁹ of R∞", gap_to_Rinf < mpf('1e-9'))
# A49: The series converges — |r| < 1
check("A49: r < 1 (series converges)", r < mpf('1'))
check("A50: r < 0.002 (rapid convergence)", r < mpf('0.002'))
# ─────────────────────────────────────────────────────────────────────────────
# §8: Loop-weight structure checks
# ─────────────────────────────────────────────────────────────────────────────

# A51: r = h∨(A₂) · α² · E_μ  (loop-weight decomposition)
check("A51: r = h∨·α²·E_μ", fabs(r - h*alpha**2*E_mu) < mpf('1e-55'))
# A52: T1 = r·σ  (first loop = seed × loop-weight)
check("A52: T1 = r·σ", fabs(T1 - r*sigma) < mpf('1e-58'))
# A53: normalised ratio T_k·e³·μ/h = (−1)^{k+1}·(−r)^{k−1}
for k in range(1, 5):
    lhs = T_k_def(k) * E_e**3 * ALPHA_INV / h
    rhs = ((-1)**(k+1)) * ((-r)**(k-1)) * ((-1)**(k-1))  # = (-1)^{k+1}·r^{k-1}
    # Actually: T_k·e³μ/h = (-1)^{k+1}·r^{k-1}·r·σ·e³μ/h ... simplify:
    # T_k = (-1)^{k+1}·r^k·σ; T_k·e³μ/h = (-1)^{k+1}·r^k·(μ/e⁵)·e³μ/h
    #      = (-1)^{k+1}·r^k·μ²/(h·e²) = (-1)^{k+1}·r^{k-1}·(r·μ²/(h·e²))
    # and r·μ²/(h·e²) = h·e²/μ²·μ²/(h·e²) = 1
    simple_lhs = T_k_def(k) * E_e**3 * ALPHA_INV / h
    simple_rhs = ((-1)**(k+1)) * r**(k-1)
    check(f"A53k{k}: T_k·e³μ/h = (−1)^{{k+1}}·r^{{k−1}}", fabs(simple_lhs - simple_rhs) < mpf('1e-55'))
# A54: The resolvent two-solution quadratic has no natural TOE solution
# (just verify the mismatch is large — detailed root computation in §3)
check("A54: resolvent mismatch is large (>0.015)", mismatch > mpf('0.015'))
# ─────────────────────────────────────────────────────────────────────────────
# Final report
# ─────────────────────────────────────────────────────────────────────────────
print()
print(f"  ALPHA_INV (μ)  = {nstr(ALPHA_INV, 20)}")
print(f"  h = h∨(A₂)    = {h}")
print(f"  r = h·e²/μ²   = {nstr(r, 20)}")
print(f"  σ = μ/e⁵       = {nstr(sigma, 20)}")
print()
print(f"  T1 = {nstr(T1, 15)}")
print(f"  T2 = {nstr(T2, 15)}")
print(f"  T3 = {nstr(T3, 15)}")
print(f"  T4 = {nstr(T4, 15)}")
print(f"  T5 = {nstr(T5, 15)}")
print()
print(f"  Ratio T2/T1 = {nstr(T2/T1, 15)}   (should be −r = {nstr(-r, 15)})")
print(f"  Ratio T3/T2 = {nstr(T3/T2, 15)}   (should be −r)")
print(f"  Ratio T4/T3 = {nstr(T4/T3, 15)}   (should be −r)")
print()
print(f"  Tr(A²)  = {4**1+2} = 4¹+2;   /2 = {(4**1+2)//2} = h∨  ✓")
print(f"  Tr(A⁴)  = {4**2+2} = 4²+2;   /2 = {(4**2+2)//2} = h∨²  ✓")
print(f"  Tr(A⁶)  = {4**3+2} = 4³+2;   /2 = {(4**3+2)//2} ≠ {3**3} = h∨³  ✗ (pattern breaks)")
print()
print(f"  Resolvent G(μ/e) = {nstr(G_lam, 15)}")
print(f"  S_closed         = {nstr(S_closed, 15)}")
print(f"  Mismatch factor  = {nstr(G_lam/S_closed, 10)}")
print(f"  → Resolvent interpretation: MISMATCH (status: CONJECTURED)")
print()
print(f"  R_star  gap = {nstr(fabs(R_star-TARGET)/TARGET*1e6, 8)} ppm")
print(f"  R3      gap = {nstr(gap_R3, 8)} ppm")
print(f"  R4      gap = {nstr(gap_R4, 8)} ppm  (k=3 term worsens)")
print(f"  R∞      gap = {nstr(gap_closed, 8)} ppm  (closed form)")
print()
print("Programme status: CONJECTURED")
print("  Loop-order factorisation T_k = (−1)^{k+1}·r^k·σ proved.")
print("  h∨(A₂)^k from A₂ adjacency matrix holds for k=1,2 only.")
print("  Full G₂ holonomy derivation remains open (OP-G2A2-lattice).")

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