back to table · edit · history · where entries came from · files · download
3548 bytes, as of the version from 2026-10-16 10:14 (current). Recorded here, not run.
"""Verify the editorial repair of numberdb.org/T461 without writing.
Run with SageMath after downloading generate.py, checks.py and check.py from
T461 into this directory:
sage -pip install numberdb
sage -python repair_checks.py > repair-checks.json
The draft requires its author's NUMBERDB_API_KEY. Alternatively set
NUMBERDB_KEY_FROM_STDIN=1 and pipe the key to stdin. An optional positional
JSON snapshot path avoids a network read. The exact formal-series inversion
checks the Bernoulli convention independently of the attached generator.
"""
import json
import os
import sys
from fractions import Fraction
from math import factorial
from pathlib import Path
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.arith.misc import bernoulli
from generate import OrbifoldEulerCharacteristics
from checks import check_values
def main():
if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
numberdb.configure(api_key=sys.stdin.read().strip())
doc = (json.loads(Path(sys.argv[1]).read_text()) if len(sys.argv) > 1
else numberdb.table('T461'))
values = {(int(g), int(n)): QQ(e['number'] if isinstance(e, dict) else e)
for g, group in doc['Numbers'].items() for n, e in group.items()}
# Invert (exp(t)-1)/t coefficient by coefficient over the rationals.
coeff = [Fraction(1)]
for k in range(1, 25):
coeff.append(-sum((coeff[k-j] / factorial(j+1)
for j in range(1, k+1)), Fraction(0)))
bernoullis = [c * factorial(k) for k, c in enumerate(coeff)]
assert bernoullis[:5] == [1, Fraction(-1, 2), Fraction(1, 6),
0, Fraction(-1, 30)]
assert all(QQ(b) == bernoulli(k) for k, b in enumerate(bernoullis))
for (g, n), stored in values.items():
independent = (Fraction((-1)**n * (2*g-1) * factorial(2*g+n-3),
factorial(2*g)) * bernoullis[2*g])
assert QQ(independent) == stored, (g, n)
assert values[1, 1] != QQ(1)/12 # reject a deliberately wrong sign
generator = OrbifoldEulerCharacteristics()
generated = {(int(p['g']), int(p['n'])): generator.value(p, 100)['number']
for p in generator.enumerate()}
assert generated == values
namespace = {}
exec(compile(doc['Programs']['sage']['code'], '<T461 Sage program>', 'exec'), namespace)
program = namespace['orbifold_chi']
for (g, n), stored in values.items():
assert program(g, n) == stored
for n in range(3, 13):
assert program(0, n) == (-1)**(n-3) * factorial(n-3)
for g, n in [(0, 0), (0, 2), (1, 0), (-1, 5), (2, -1)]:
try:
program(g, n)
except ValueError:
pass
else:
raise AssertionError('The program accepted an invalid pair')
# Re-run the downloaded independent Stirling-sum and 512-bit Arb checks.
result = check_values(values)
result.update({
'table': 'T461',
'source': 'live authenticated API' if len(sys.argv) == 1 else 'JSON snapshot',
'bernoulli_series_coefficients_checked': 25,
'series_closed_formula_matches': len(values),
'attached_generator_matches': len(values),
'displayed_program_matches': len(values),
'genus_zero_program_controls': 10,
'invalid_program_inputs_rejected': 5,
'bernoulli_controls': {'B0': '1', 'B1': '-1/2', 'B2': '1/6', 'B4': '-1/30'},
})
print(json.dumps(result, indent=2))
if __name__ == '__main__':
main()