"""Independently reconstruct the note's matrices from its displayed polynomials/Gram row."""
from pathlib import Path
import json
import sympy as s

x=s.Symbol('x');n=13;eye=s.eye(n)
p=s.Poly((x+1)*(x**12-x**6+1),x)
q=s.Poly((x-1)**3*(x**2+x+1)*(x**2-x+1)*(x**6-x**3+1),x)

def companion(poly):
    return s.Matrix.hstack(eye[:,1:],s.Matrix([-poly.nth(j) for j in range(n)]))

a,b=companion(p),companion(q)
assert a.charpoly(x).as_expr()==p.as_expr() and b.charpoly(x).as_expr()==q.as_expr()
c=a.inv()*b;u=(c-eye)[:,-1]
assert c*c==eye and (c-eye).rank()==1 and u[-1]==-2
assert c-eye == u*eye[-1,:]
o=s.Matrix.hstack(*[b**j*u for j in range(n)])
obs=s.Matrix.vstack(*[eye[-1,:]*b**j for j in range(n)])
assert o.det()==-4608 and obs.det()==1
row=[-2,-4,-8,-13,-20,-28,-36,-44,-52,-59,-64,-68,-72]
k=s.Matrix(n,n,lambda i,j:row[abs(i-j)])
oi=o.inv();f=oi.T*k*oi
assert a.T*f*a==b.T*f*b==f
assert all(v.q==1 for v in 72*f)
minors=[k[:j,:j].det() for j in range(1,n+1)]
expected=[-2,-12,-72,-324,-1458,-3645,-8748,-16848,-31680,-34752,-38080,-41408,-4608]
assert minors==expected and all(v<0 for v in minors)
assert s.gcd(p,q).degree()==0 and a.trace()==-1 and b.trace()==3
assert s.div(q,s.Poly((x-1)**3,x))[1].is_zero
assert not s.div(q,s.Poly((x-1)**4,x))[1].is_zero
assert all(s.gcd(s.Poly(x**r-1,x),s.Poly(s.cyclotomic_poly(36,x),x)).degree()==0 for r in range(1,27))
# Negating a primitive 36th root permutes the same complete root set.
assert s.Poly(s.cyclotomic_poly(36,x).subs(x,-x),x)==s.Poly(s.cyclotomic_poly(36,x),x)
result={'arithmetic':'exact integer/rational','degree':n,'form_integer_scale':72,
        'gram_first_row':row,'leading_principal_determinants':[int(v) for v in minors],
        'inertia_positive_negative_zero':[12,1,0],'orbit_determinant':-4608,
        'dual_orbit_determinant':1,'matrix_invariance':'both zero residuals',
        'complete_cyclotomic_root_order_exclusions_1_through_26':'passed',
        'primitive_36_half_shift_invariance':'passed'}
Path(__file__).with_name('note-math-verification.json').write_text(json.dumps(result,indent=2)+'\n')
print('All independently reconstructed note identities and determinants pass exactly.')
