back to table · edit · history · where entries came from · files · download
3757 bytes, as of the version from 2026-10-30 02:01 (current). Recorded here, not run.
"""Check every stored T614 mass interval and companion radius after readback.
Run: sage -python readback_checks.py, with NUMBERDB_API_KEY for the draft.
The campaign may pipe the key with NUMBERDB_KEY_FROM_STDIN=1.
Requires generate.py, solver.py, numerical-evidence.json,
independent-evidence.json and skills-evidence.json beside this script.
"""
import os,sys,json,pathlib
from decimal import Decimal,localcontext
import numberdb.sage as numberdb
from sage.rings.real_arb import RealBallField
from generate import INDICES
def decimal_interval(s):
d=Decimal(s);ulp=Decimal(10)**d.as_tuple().exponent
return d-ulp,d+ulp,ulp
def main():
if os.environ.get('NUMBERDB_KEY_FROM_STDIN')=='1':
token=sys.stdin.read().strip()
if '=' in token and token.split('=',1)[0].replace('_','').isalnum():
token=token.split('=',1)[1].strip().strip('\"\'')
os.environ['NUMBERDB_API_KEY']=token
d=numberdb.table('T614');radii=numberdb.table('T613')
assert d['Title']=='Mass constants of Lane–Emden polytropes'
assert d['Display properties']['number-header']==r'$\mu_n$'
assert d['Parameters']['n']['type']=='Q'
assert list(d['Numbers'])==list(INDICES)
p=pathlib.Path(__file__).parent
computed=json.loads((p/'numerical-evidence.json').read_text())['values']
independent=json.loads((p/'independent-evidence.json').read_text())
assert json.loads((p/'skills-evidence.json').read_text())['versions'][0]['sha256']=='28ecbeeccb0c5e5d6eb541b5a5b0f88aec47b154374d909085116d34f5629199'
report={'table':'T614','skill_manifest':'agents/runs/20261030T013608Z-build-skills/manifest.json','rows':{}}
B=RealBallField(700)
with localcontext() as ctx:
ctx.prec=250
for n,item in d['Numbers'].items():
s=item['number'] if isinstance(item,dict) else item
lo,hi,ulp=decimal_interval(s);center=Decimal(s)
assert len(center.as_tuple().digits)>=100,(n,'too few digits')
if n in ('0','1','5'):
target=2*B(6).sqrt() if n=='0' else (B.pi() if n=='1' else B(3).sqrt())
assert target.is_finite() and B(target.rad())<B('1e-190')
assert B(str(lo))<target and target<B(str(hi)),n
else:
for precision in ('150','210'):
assert lo<Decimal(computed[n][precision]['mass'])<hi,(n,precision)
independent_error=abs(Decimal(independent[n]['value'])-center)/abs(center)
assert independent_error<Decimal('1e-40'),(n,independent_error)
row={'stored_interval_pass':True,'significant_digits':len(center.as_tuple().digits),'independent_relative_difference':str(independent_error)}
if n!='5':
rr=radii['Numbers'][n];rs=rr['number'] if isinstance(rr,dict) else rr
rlo,rhi,_=decimal_interval(rs)
assert rlo<Decimal(computed[n]['210']['radius'])<rhi,('companion',n)
xi=Decimal(independent[n]['radius']);J=Decimal(independent[n]['pressure_integral'])
nn=Decimal(n.split('/')[0])/(Decimal(n.split('/')[1]) if '/' in n else 1)
virial=(nn+1)*center*center/((5-nn)*xi)
error=abs(J-virial)/abs(virial)
assert error<Decimal('1e-40'),('stored virial',n,error)
row['companion_radius_interval_pass']=True
row['stored_virial_relative_error']=str(error)
report['rows'][n]=row
# Deliberately shifted mass fails the decimal-interval predicate.
anchor=Decimal(d['Numbers']['1']['number'])
lo,hi,ulp=decimal_interval(str(anchor))
assert not lo<anchor+100*ulp<hi
print('DATA '+json.dumps(report))
if __name__=='__main__':main()