back to table · edit · history · where entries came from · files · download
3611 bytes, as of the version from 2026-10-27 07:39 (current). Recorded here, not run.
"""Check T541's integer-domain repair and independent control values.
Run: sage -python repair-check.py
Download live-before.json and the unchanged generate.py alongside this file.
No key is needed. This script reads files and writes its evidence to stdout.
"""
from pathlib import Path
import ast
import json
import hashlib
import importlib.metadata
import numberdb.sage as numberdb
from sage.rings.integer_ring import ZZ
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField
here = Path(__file__).resolve().parent
doc = json.loads((here / 'live-before.json').read_text())
source = (here / 'generate.py').read_text()
node = next(node for node in ast.walk(ast.parse(source))
if isinstance(node, ast.FunctionDef) and node.name == 'enumerate')
namespace = {}
exec(compile(ast.Module(body=[node], type_ignores=[]), 'generate.py:enumerate', 'exec'), namespace)
actual = [(str(row['N']), str(row['n'])) for row in namespace['enumerate'](None)]
stored = [(N, n) for N, orders in doc['Numbers'].items() for n in orders]
assert actual == stored
expected = [(str(N), str(n)) for N in range(1, 13)
for n in (1, 2) if QQ(n) > QQ(N+2)/(2*N)]
assert stored == expected
for N, n in stored:
assert str(ZZ(N)) == N and str(ZZ(n)) == n
assert ZZ(N) >= 1 and QQ(n) > (QQ(N)+2)/(2*QQ(N))
assert all(QQ(1) <= QQ(N+2)/(2*N) for N in (1, 2))
R = RealBallField(512)
checks = []
def decimal(text):
digits = len(text.split('.')[1])
return QQ(ZZ(text.replace('.', ''))) / (10**digits), QQ(1)/(10**digits)
def check(N, n, value, method):
assert value.is_finite()
assert R(value.rad()) < abs(value)*R(2)**(-400)
center, ulp = decimal(doc['Numbers'][str(N)][str(n)])
assert R(center-ulp) < value < R(center+ulp)
assert not (R(center+9*ulp) < value < R(center+11*ulp))
checks.append({'N':N, 'n':n, 'method':method,
'relative_accuracy_exceeds_bits':400,
'enclosed_in_stored_last_place_interval':True,
'ten_ulp_perturbation_rejected':True,
'computed_ball':str(value)})
k = R(3)**(R(QQ(1)/3))*R(QQ(2)/3).gamma()/R(QQ(1)/3).gamma()
check(1, 2, k*k+1/k, 'Airy initial values: kappa^2+1/kappa')
check(2, 2, R.pi()**2/8, 'Odd-integer harmonic spectrum: pi^2/8')
for N in range(3, 13):
v = R(QQ(1)/(N+2))
A = (R.pi()*v).sin()/(2*R.pi().sqrt())*(2*v)**(2-4*v)
A *= v.gamma()*(2*v).gamma()*(3*v).gamma()/(2*v+R(QQ(1)/2)).gamma()
check(N, 1, A*(2*R.pi()*v).tan()/(R.pi()*v).tan(), 'Voros equation (140), full trace')
result = {'table':'T541', 'selection_matches_generator_and_completeness':True,
'all_22_parameter_pairs_integral_and_convergent':True,
'first_moments_at_N_1_2_excluded':True,
'checks':checks,
'scope':'No values changed. Twelve control values rigorously enclosed; ten nonlinear second moments were not recomputed in this repair.',
'argument_uncertainty':'Exact rational inputs converted directly to Arb balls; all operations propagate their uncertainty at 512 bits.',
'skill_manifest':'agents/runs/20261027T073238Z-repair-skills/manifest.json',
'skill_sha256':{'local':'e37efb7e2ededf6c1d7134c673f152f648f26e0267c556aebdf3ec65765d8b4c','live':'e37efb7e2ededf6c1d7134c673f152f648f26e0267c556aebdf3ec65765d8b4c'},
'input_sha256':{name:hashlib.sha256((here/name).read_bytes()).hexdigest() for name in ('generate.py','live-before.json')},
'versions':{name:importlib.metadata.version(name) for name in ('numberdb','mpmath')}}
print(json.dumps(result,indent=2))