"""Checks for the layout-only repair of numberdb.org/T631.

Download this file, generate.py and the table document as document-before.json.
Run: sage -python reflow-check.py
The generator is read unchanged. No writes or credentials are used.
"""
import hashlib,json,pathlib,platform
from decimal import Decimal
import generate as g
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField
from sage.env import SAGE_VERSION
W=pathlib.Path(__file__).resolve().parent
D=json.loads((W/'document-before.json').read_text())
def direct(p,q,u,m):
    return sum((a*(1+q)+b*(1-q)-2*u)%(2*p)==0
               for n,k in ((m,m-2),(m-2,m))
               for a in range(-n,n+1,2) for b in range(-k,k+1,2))
# Known sphere-cover dimension: summing all characters counts both full weight products.
assert sum(direct(5,2,u,4) for u in range(5))==2*(4*4-1)
count=symmetries=0
for p,q,u in g.cases():
    for m in range(2,2*p+4):
        assert direct(p,q,u,m)==g.multiplicity(p,q,u,m)
        count+=1
    r=pow(q,-1,p)
    for m in range(2,10):
        base=direct(p,q,u,m)
        assert base==direct(p,q,(-u)%p,m)==direct(p,p-q,u,m)==direct(p,r,u*r%p,m)
        symmetries+=3
stored=[]
for p,qs in D['Numbers'].items():
    for q,us in qs.items():
        for u,cs in us.items():
            for convention in cs:
                stored.append({'p':p,'q':q,'u':u,'convention':convention})
assert stored==list(g.CoexactLensDeterminants().enumerate())
R=RealBallField(600)
controls={0:4*R(3).zeta()/R.pi()**2-2*R.pi().log(),1:-3*R(3).zeta()/R.pi()**2-2*R(2).log()}
accuracy=[]
for u in (0,1):
    logdet=g.logdet(2,1,u,digits=100)
    control=controls[u]
    assert control.is_finite() and logdet.is_finite() and logdet.overlaps(control)
    assert logdet.accuracy()>450 and control.accuracy()>550
    for convention,value in [('logdet',logdet),('det',logdet.exp())]:
        text=D['Numbers']['2']['1'][str(u)][convention]
        if isinstance(text,dict):text=text['number']
        d=Decimal(text); n,den=d.as_integer_ratio()
        center=QQ(n)/QQ(den); radius=QQ(10)**int(d.as_tuple().exponent)
        assert value.is_finite() and bool(value>R(center-radius)) and bool(value<R(center+radius))
        assert not value.overlaps(R(center+10*radius))
        accuracy.append(int(value.accuracy()))
report={'table':'T631','purpose':'Verify preserved formulas for a layout-only repair; no new values',
        'skill_manifest':'agents/runs/20261030T210745Z-repair-skills/manifest.json',
        'skill_sha256_local':'10c1d8bd62d6ddfa2c016375ad82879151f0ab7a9516c2f371432108a85be009',
        'skill_sha256_live':'10c1d8bd62d6ddfa2c016375ad82879151f0ab7a9516c2f371432108a85be009',
        'generator_sha256':hashlib.sha256((W/'generate.py').read_bytes()).hexdigest(),
        'sage':SAGE_VERSION,'python':platform.python_version(),
        'ordered_enumeration_matches':len(stored),'direct_weight_multiplicities_checked':count,
        'symmetry_equalities_checked':symmetries,'closed_form_logarithm_controls':2,
        'stored_decimal_enclosures_checked':4,'ten_ulp_perturbations_rejected':4,
        'minimum_relative_accuracy_bits':min(accuracy),
        'scope':'Finite exact multiplicity checks and two projective-space controls corroborate preserved formulas; this is not a fresh independent argument-selection critique or a full numerical recomputation.'}
print(json.dumps(report,indent=2))
