"""D1256: exact split-octonion checks; no banked physics arrays are imported."""
from itertools import product
from pathlib import Path
import json
import random
import sys
import hashlib
import platform
import sympy as S

if not __debug__:
    raise SystemExit('Run without -O: this verifier uses assertions.')

NAMES = ('1', 'e1', 'e2', 'e3', 'f1', 'f2', 'f3', 'l')
B = [tuple(int(i == j) for i in range(len(NAMES))) for j in range(len(NAMES))]
ZERO = (0,) * len(NAMES)

def add(x, y): return tuple(a + b for a, b in zip(x, y))
def neg(x): return tuple(-a for a in x)
def sub(x, y): return add(x, neg(y))
def scale(k, x): return tuple(k * a for a in x)
def dot(x, y): return sum(a * b for a, b in zip(x, y))
def cross(x, y):
    return (x[1]*y[2]-x[2]*y[1], x[2]*y[0]-x[0]*y[2],
            x[0]*y[1]-x[1]*y[0])
def half(a):
    if isinstance(a, int):
        assert a % 2 == 0, 'Integer carrier conversion lost parity'
        return a // 2
    return S.expand(a) / 2

def zorn(x):
    """Coordinates -> (a,u,v,b), with u=E+F, v=F-E."""
    return (x[0]+x[7], add(x[1:4], x[4:7]),
            sub(x[4:7], x[1:4]), x[0]-x[7])
def unzorn(a, u, v, b):
    return (half(a+b),) + tuple(half(t) for t in sub(u, v)) + \
        tuple(half(t) for t in add(u, v)) + (half(a-b),)
def mul(x, y):
    a,u,v,b = zorn(x); c,U,V,d = zorn(y)
    return unzorn(a*c+dot(u,V),
                  add(add(scale(a,U),scale(d,u)),cross(v,V)),
                  sub(add(scale(c,v),scale(b,V)),cross(u,U)),
                  dot(v,U)+b*d)
def bar(x): return (x[0],) + neg(x[1:])
def norm(x):
    a,u,v,b = zorn(x)
    return a*b-dot(u,v)

def qm(p, r):
    """Quaternion multiplication implemented separately from Zorn."""
    a,b,c,d = p; e,f,g,h = r
    return (a*e-b*f-c*g-d*h, a*f+b*e+c*h-d*g,
            a*g-b*h+c*e+d*f, a*h+b*g-c*f+d*e)
def qb(p): return (p[0],-p[1],-p[2],-p[3])
def cd(x, y):
    # In this basis f_i = -e_i*l; q = (l coefficient, -F).
    p = x[:4]; q = (x[7],) + neg(x[4:7])
    r = y[:4]; s = (y[7],) + neg(y[4:7])
    first = add(qm(p,r),qm(qb(s),q))
    second = add(qm(s,p),qm(q,qb(r)))
    return first + neg(second[1:]) + (second[0],)

def assoc(x, y, z, op=mul): return sub(op(op(x,y),z),op(x,op(y,z)))
def pretty(x):
    terms=[]
    for a,n in zip(x,NAMES):
        if a:
            terms.append(('-' if a < 0 else '+') +
                         (str(abs(a)) if n=='1' or abs(a)!=1 else '') +
                         ('' if n=='1' else n))
    return ''.join(terms).lstrip('+') or '0'

table = [[mul(x,y) for y in B] for x in B]
sign_checks = negative = 0
for i,j in product(range(len(B)), repeat=2):
    z = table[i][j]
    assert sum(t != 0 for t in z) == 1 and all(t in (-1,0,1) for t in z)
    assert z == cd(B[i],B[j])
    sign_checks += 1
    negative += int(-1 in z)
unit_checks = sum(mul(B[0],x)==x and mul(x,B[0])==x for x in B)
assert unit_checks == len(B)
anti_checks = 0
for i in range(1,len(B)):
    for j in range(i+1,len(B)):
        assert add(table[i][j],table[j][i]) == ZERO
        anti_checks += 1
basis_alternative_checks = 0
for x,y in product(B,repeat=2):
    assert assoc(x,x,y) == ZERO and assoc(y,x,x) == ZERO
    basis_alternative_checks += 2
polarized_checks = 0
for x,y,z in product(B,repeat=3):
    a = assoc(x,y,z)
    assert add(a,assoc(y,x,z)) == ZERO
    assert add(a,assoc(x,z,y)) == ZERO
    polarized_checks += 2

x = S.symbols('s E1 E2 E3 F1 F2 F3 t')
y = S.symbols('r A1 A2 A3 B1 B2 B3 w')
xy = mul(x,y)
composition_residual = S.expand(norm(xy)-norm(x)*norm(y))
assert composition_residual == 0
norm_left = [S.expand(z) for z in sub(mul(x,bar(x)),scale(norm(x),B[0]))]
norm_right = [S.expand(z) for z in sub(mul(bar(x),x),scale(norm(x),B[0]))]
conjugation = [S.expand(z) for z in sub(bar(xy),mul(bar(y),bar(x)))]
assert all(z == 0 for z in norm_left + norm_right + conjugation)
cd_coeff_residual = [S.expand(a-b) for a,b in zip(xy,cd(x,y))]
assert all(v==0 for v in cd_coeff_residual)
metric = S.hessian(norm(x),x)/2
metric_diagonal = list(metric.diagonal())
inertia = [sum(int(bool(v>0)) for v in metric_diagonal),sum(int(bool(v<0)) for v in metric_diagonal),
           sum(int(bool(v==0)) for v in metric_diagonal)]
np = add(B[0],B[7]); nm = sub(B[0],B[7]); nil = add(B[1],B[4])
null_data = {'N(1+l)':norm(np), 'N(1-l)':norm(nm), '(1+l)(1-l)':pretty(mul(np,nm)),
             'N((1+l)+(1-l))':norm(add(np,nm)),
             'N(e1+f1)':norm(nil), '(e1+f1)^2':pretty(mul(nil,nil))}
# A totally null four-plane in Zorn coordinates: b=v=0.
a,U1,U2,U3 = S.symbols('a U1 U2 U3')
null_plane_norm = S.expand(norm(unzorn(a,(U1,U2,U3),(0,0,0),0)))
assert null_plane_norm == 0
seed, requested_pairs, radius = 1256, 64, 2
rng = random.Random(seed)
sample_checks = 0
for _ in range(requested_pairs):
    u=tuple(rng.randint(-radius,radius) for _ in B); v=tuple(rng.randint(-radius,radius) for _ in B)
    assert norm(mul(u,v))==norm(u)*norm(v)
    assert mul(u,v)==cd(u,v)
    assert assoc(u,u,v)==ZERO and assoc(v,u,u)==ZERO
    sample_checks += 1
example = assoc(B[1],B[2],B[4])
assert example != ZERO

# Negative control: parse, do not repair, the supplied March table.
legacy_path = Path(sys.argv[1] if len(sys.argv) > 1 else
                   '03_L1_MARCH_PRODUCTION_SAMPLE_REJECT.md')
if not legacy_path.is_file():
    raise SystemExit('Pass the supplied March negative-control Markdown as argv[1].')
legacy_bytes = legacy_path.read_bytes()
legacy_text = legacy_bytes.decode('utf-8')
legacy = json.JSONDecoder().raw_decode(legacy_text[legacy_text.index('{'):])[0]
latex = legacy['content']['RESULT']['multiplication_table']['latex_matrix']
rows = latex.replace('\\begin{pmatrix}','').replace('\\end{pmatrix}','').strip().split('\\\\')
legacy_table = []
for row in rows:
    out=[]
    for item in row.split('&'):
        item=item.strip(); sign=-1 if item.startswith('-') else 1
        token=item.lstrip('+-'); out.append(scale(sign,B[NAMES.index(token)]))
    legacy_table.append(out)
assert len(legacy_table)==len(B) and all(len(r)==len(B) for r in legacy_table)
def oldmul(u,v):
    out=ZERO
    for i,j in product(range(len(B)),repeat=2):
        out=add(out,scale(u[i]*v[j],legacy_table[i][j]))
    return out
old_left_failures = sum(assoc(u,u,v,oldmul)!=ZERO for u,v in product(B,repeat=2))
old_right_failures = sum(assoc(v,u,u,oldmul)!=ZERO for u,v in product(B,repeat=2))
old_diag=[oldmul(u,bar(u))[0] for u in B]
old_inertia=[sum(v>0 for v in old_diag),sum(v<0 for v in old_diag),sum(v==0 for v in old_diag)]
old_witness = assoc(B[1],B[1],B[2],oldmul)
assert old_witness!=ZERO

print('python =',platform.python_version(),'; sympy =',S.__version__)
print('negative_control_input_sha256 =',hashlib.sha256(legacy_bytes).hexdigest())
print('basis_dimension =',len(B),'; quaternion_half_dimension =',len(x[:4]),
      '; quaternion_pair_dimension =',2*len(x[:4]),
      '; compact_octonion_pair_dimension =',2*len(B))
print('basis_order =',','.join(NAMES))
print('| x*y | '+' | '.join(NAMES)+' |')
print('|---|'+'---|'*len(B))
for name,row in zip(NAMES,table): print('| '+name+' | '+' | '.join(pretty(z) for z in row)+' |')
print('zorn_cd_signed_unit_checks =',sign_checks, '; negative_products =',negative)
print('two_sided_unit_basis_checks =',unit_checks)
print('unordered_imaginary_anticommutation_checks =',anti_checks)
print('basis_left_right_alternative_checks =',basis_alternative_checks)
print('polarized_alternative_vector_checks =',polarized_checks)
print('polarized_alternative_scalar_coefficients =',polarized_checks*len(B))
print('symbolic_zorn_cd_coordinate_residuals =',cd_coeff_residual)
print('symbolic_norm_composition_residual =',composition_residual)
print('symbolic_norm_and_conjugation_residuals =',norm_left,norm_right,conjugation)
print('norm_polynomial =',S.expand(norm(x)))
print('norm_matrix_diagonal =',metric_diagonal,'; inertia(+,-,0) =',inertia)
print('basis_norms =',[norm(u) for u in B])
print('null_controls =',null_data)
print('totally_null_plane b=v=0: free_coordinates =',len((a,U1,U2,U3)),'; norm =',null_plane_norm)
print('nonassociative_witness [e1,e2,f1] =',pretty(example))
print('sample_integer_pairs =',sample_checks,'; seed =',seed,
      '; coefficient_range =',[-radius,radius],'; all_assertions_passed =',sample_checks==requested_pairs)
print('legacy_left_alternative_failures =',old_left_failures,'of',len(B)**2)
print('legacy_right_alternative_failures =',old_right_failures,'of',len(B)**2)
print('legacy_witness [e1,e1,e2] =',pretty(old_witness))
print('legacy_conjugation_candidate_diagonal =',old_diag,'; inertia(+,-,0) =',old_inertia)
def old_norm(u): return sum(d*a*a for d,a in zip(old_diag,u))
old_conj_residual = [S.expand(t) for t in sub(oldmul(x,bar(x)),scale(old_norm(x),B[0]))]
assert all(t == 0 for t in old_conj_residual)
print('legacy_N(e1*e2), N(e1)*N(e2) =',old_norm(oldmul(B[1],B[2])),
      old_norm(B[1])*old_norm(B[2]))
print('legacy_conjugation_candidate_residual =',old_conj_residual)
print('SUITE_BANKED_ARRAY_ALIGNMENT = NOT VERIFIED')
