back to table · edit · history · where entries came from · files · download
8554 bytes, as of the version from 2026-10-28 22:35 (current). Recorded here, not run.
"""Independent counting and numerical checks for numberdb.org/T592.
Run: sage -python checks.py. Requires adjacent generate.py and the campaign's
unmodified check.py. Set CHECK_STORED=1 to check an authenticated database read.
The counting checks are independent of row transfer: direct subsets for small
rectangles and an edge-parity transfer for the zero-field specialization.
"""
import sys,os,json,time
from collections import defaultdict
from math import comb
import numberdb.sage as numberdb
from sage.rings.integer_ring import ZZ
from sage.rings.rational_field import QQ
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.rings.complex_interval_field import ComplexIntervalField
from sage.rings.complex_arb import ComplexBallField
from numberdb._write import to_text
from numberdb._compare import _claim, _complex_parts
from fractions import Fraction
from sage.rings.real_mpfi import RealIntervalField
import generate as g
import check
def edges(m,n):
# Vertex order is column-major; independent from the generator's row masks.
return [(r*n+c,(r+1)*n+c) for r in range(m-1) for c in range(n)] + [(r*n+c,r*n+c+1) for r in range(m) for c in range(n-1)]
def brute(m,n):
es=edges(m,n);result=defaultdict(int)
for mask in range(1 << (m*n)):
d=sum(((mask>>u)^(mask>>v))&1 for u,v in es)
result[(mask.bit_count(),d)] += 1
return dict(result)
def even_counts(m,n):
"""Edge-subset expansion with parity states, forgetting finished vertices."""
es=sorted((min(u,v),max(u,v)) for u,v in edges(m,n))
last={v:i for i,e in enumerate(es) for v in e}
dp={(0,0):1}
for i,(u,v) in enumerate(es):
nxt=defaultdict(int);flip=(1<<u)|(1<<v)
forget=sum(1<<w for w in (u,v) if last[w]==i)
for (parity,k),count in dp.items():
if parity & forget == 0:
nxt[(parity,k)] += count
other=parity ^ flip
if other & forget == 0:
nxt[(other,k+1)] += count
dp=nxt
assert all(parity==0 for parity,k in dp)
return {k:c for (parity,k),c in dp.items()}
def product_roots(values,cb):
coefficients=[cb(1)]
for value,mult in values:
for _ in range(mult):
nxt=[cb(0)]*(len(coefficients)+1)
for k,c in enumerate(coefficients):
nxt[k] -= value*c
nxt[k+1] += c
coefficients=nxt
return coefficients
def exact_written_contains(text,raw):
parts=_complex_parts(text) or (text,'0')
cb=ComplexBallField(700);r=cb(raw)
rf=RealIntervalField(700)
for part,component in zip(parts,(r.real(),r.imag())):
centre,radius=_claim(part)
centre=QQ(Fraction(centre));radius=QQ(Fraction(radius))
lo,hi=map(QQ,rf(component).endpoints())
assert centre-radius <= lo <= hi <= centre+radius
def written_ball(text,cb):
parts=_complex_parts(text) or (text,'0')
rf=RealIntervalField(cb.prec())
components=[]
for part in parts:
centre,radius=_claim(part)
centre=QQ(Fraction(centre));radius=QQ(Fraction(radius))
components.append(rf(centre-radius,centre+radius))
return cb(components[0],components[1])
def run(stored=None):
t0=time.time();report={'rectangles':[]};allvalues={};data={}; min_bits=None;max_rad=0
# Known-answer control for the independent even-subgraph algorithm.
assert even_counts(2,2)=={0:1,4:1}
assert brute(2,2)=={(0,0):1,(1,2):4,(2,2):4,(2,4):2,(3,2):4,(4,0):1}
print('Controls: C4 cut counts and even-subgraph counts passed',flush=True)
B=PolynomialRing(QQ,'b');b=B.gen()
cb=ComplexBallField(700)
exact_written_contains('1.00 + i * 0.00', cb(1))
try:
exact_written_contains('1.00 + i * 0.00', cb(2))
except AssertionError:
pass
else:
raise AssertionError('Containment control accepted 2 as 1.00')
for m in range(2,7):
for n in range(m,7):
N=m*n;E=2*N-m-n;c=g.counts(m,n)
data[f'{m},{n}']=[[k,d,v] for (k,d),v in sorted(c.items())]
assert sum(c.values())==2**N
assert all(sum(v for (kk,d),v in c.items() if kk==k)==comb(N,k) for k in range(N+1))
assert {(k,d):v for (k,d),v in c.items() if d==0}=={(0,0):1,(N,0):1}
assert all(c.get((N-k,d),0)==v for (k,d),v in c.items())
if N<=16:
assert not check.agrees_with({(m,n):c},lambda _: brute(m,n))
# Independent even-subgraph expansion over all fifteen geometries.
ec=even_counts(m,n)
assert sum(ec.values())==2**(E-N+1)
high=QQ(2)**(N-E)*sum((ZZ(v)*(1-b)**k*(1+b)**(E-k) for k,v in ec.items()),B(0))
low=sum((ZZ(v)*b**d for (k,d),v in c.items()),B(0))
assert high==low
p=g.field_polynomial(m,n)
assert p(1)==g.F(low(g.BC)) and p(0)==1
roots=g.root_data(m,n); vals=[]
for j,(x,y,mult) in enumerate(roots,1):
raw=g.enclosed_root(m,n,j,100)[0]
entry=g.LeeYangZeros().value({'m':m,'n':n,'j':j},100)
allvalues[f'{m},{n},{j}']=entry
text=to_text(raw,100)
if stored is not None:
text=stored[(m,n,j)]
# Parse the intervals actually written, not their midpoints.
exact_written_contains(text,raw)
value=written_ball(text,cb)
assert value.real().is_finite() and value.imag().is_finite()
assert cb(raw) in value
assert 0 in p.change_ring(cb)(value)
assert 1 in (value*value.conjugate()).real()
vals.append((value,mult))
if raw != -1:
for part in (raw.real(),raw.imag()):
assert part.is_finite() and part.rad() < QQ(1)/10**120
# A conservative relative accuracy bound, computed from
# the enclosing interval with exact rational endpoints.
iv=RealIntervalField(part.parent().prec())(part)
lo,hi=map(QQ,iv.endpoints())
if lo != hi and lo*hi>0:
relative=(hi-lo)/min(abs(lo),abs(hi))
bits=0
while relative < QQ(1)/(ZZ(2)**bits): bits+=1
min_bits=bits-1 if min_bits is None else min(min_bits,bits-1)
assert sum(e for _,e in vals)==N
assert all((roots[k][0],roots[k][1]) < (roots[k+1][0],roots[k+1][1]) for k in range(len(roots)-1))
assert all(any(v.conjugate().overlaps(w) and e==f for w,f in vals) for v,e in vals)
recon=product_roots(vals,cb)
assert len(recon)==len(p.list())
assert all(cb(exact) in enclosure for enclosure,exact in zip(recon,p.list()))
assert all(enclosure.real().is_finite() and enclosure.imag().is_finite() and enclosure.real().rad() < QQ(1)/10**75 and enclosure.imag().rad() < QQ(1)/10**75 for enclosure in recon)
report['rectangles'].append({'m':m,'n':n,'degree':N,'distinct_roots':len(roots),'multiplicities':[int(e) for _,_,e in roots],'brute_force':N<=16,'even_subgraph_check':True,'reconstruction':True})
print('PASS',m,n,'roots',len(roots),'seconds',round(time.time()-t0,2),flush=True)
assert not check.exactness(allvalues)
assert not check.names_its_rings(g.__file__)
report['minimum_relative_accuracy_bits']=min_bits
report['minimum_relative_decimal_digits']=int(min_bits*0.301029995663981)
report['measure_raw_balls']=check.measure(allvalues)
written={k:{**v,'number':to_text(v['number'],100)} for k,v in allvalues.items()}
report['measure_serialized']=check.measure(written)
report['seconds']=time.time()-t0
report['skill_manifest']='agents/runs/20261028T215936Z-build-skills/manifest.json'
report['skill_sha256']='28ecbeeccb0c5e5d6eb541b5a5b0f88aec47b154374d909085116d34f5629199'
print('REPORT_JSON '+json.dumps(report),flush=True)
print('COUNT_DATA_JSON '+json.dumps(data),flush=True)
print('VALUES_JSON '+json.dumps(written),flush=True)
return report
if __name__=='__main__':
stored=None
if '--stored' in sys.argv:
from numberdb._generate import _current_entries
entries=_current_entries('T592',None)
stored={tuple(map(int,key.split(','))): value for key,value in entries.items()}
assert len(stored)==245
run(stored)