repair-check.py

back to table · edit · history · where entries came from · files · download

4149 bytes, as of the version from 2026-11-01 21:32 (current). Recorded here, not run.

"""Check the Programs example for numberdb.org/T652 using exact arithmetic.

Save this file, generate.py, seeds.json and class-data.json in one directory.
With SageMath and numberdb installed, run:
    sage -python repair-check.py
For a private draft, pipe its authorized API key on stdin and set
NUMBERDB_KEY_FROM_STDIN=1. To check a saved candidate without network access,
place document-proposed.json beside this script; it is read preferentially.
This check writes nothing to the website. It checks the displayed example
against the stored entry and reproduces every stored value with the attached
generator; the latter is reproduction, not an independent mathematical check.

Skill manifest: agents/runs/20261101T143334Z-repair-skills/manifest.json
Both skill copies SHA-256: a2b28d9953264d7b0ca62663785c2952190c5be6d6d3597fd695d9a54d606278
"""
import ast
import hashlib
import json
import os
from pathlib import Path
import sys
import numberdb.sage as numberdb
from sage.rings.integer_ring import ZZ
from sage.version import version as sage_version
from generate import McKayThompsonCoefficients
HERE=Path(__file__).resolve().parent
if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
    key=sys.stdin.read().strip()
    if '=' in key and key.split('=',1)[0].strip().replace('_','').isalnum():
        key=key.split('=',1)[1].strip().strip('"\'')
    numberdb.configure(api_key=key)
local=HERE/'document-proposed.json'
doc=json.loads(local.read_text()) if local.exists() else numberdb.table('T652')
code=doc['Programs']['program-generator']['code']
expected="from generate import McKayThompsonCoefficients\ngenerator = McKayThompsonCoefficients()\ngenerator.value({'g': '2A', 'n': 30}, digits=100)"
assert ast.dump(ast.parse(code))==ast.dump(ast.parse(expected)), 'Unexpected executable snippet'
assert 'Save generate.py, seeds.json and class-data.json from the attachments' in code
assert 'The output is an exact integer; the digits argument does not round it.' in code
parsed=ast.parse(code)
namespace={}
exec(compile(ast.Module(body=parsed.body[:-1],type_ignores=[]),'<table snippet>','exec'),namespace)
value=eval(compile(ast.Expression(parsed.body[-1].value),'<table snippet>','eval'),namespace)
assert value.parent() is ZZ
# The value return path does not use digits; check the advertised behavior.
assert namespace['generator'].value({'g':'2A','n':30},digits=1)==value
numbers=doc['Numbers']
if isinstance(numbers,list):
    records=[(r['params'],r['number']) for r in numbers if 'number' in r]
else:
    records=[]
    for g,block in numbers.items():
        if isinstance(block,dict) and 'equals' in block and 'number' not in block:
            continue
        for n,entry in block.items():
            records.append(({'g':str(g),'n':int(n)},entry['number'] if isinstance(entry,dict) else entry))
gen=McKayThompsonCoefficients()
identities=[{'g':str(p['g']),'n':int(p['n'])} for p,v in records]
assert list(gen.enumerate())==identities
matches=0
for params,stored in records:
    actual=gen.value(params,digits=100)
    assert actual.parent() is ZZ
    assert actual==ZZ(stored),(params,str(actual),stored)
    if str(params['g'])=='2A' and int(params['n'])==30:
        assert value==ZZ(stored)
    matches+=1
result={'table':'T652','snippet_value':str(value),'exact_sage_integer':True,
 'digits_1_equals_digits_100':True,'generator_reproduction_matches':matches,
 'ordered_enumeration_matches':True,'independent_numerical_check':False,
 'scope':'Executed the proposed Programs example and reproduced every stored integer with its unchanged attached generator. No new mathematical or numerical claims added.',
 'versions':{'Sage':sage_version,'Python':sys.version.split()[0],'numberdb':numberdb.__version__},
 'skill_manifest':'agents/runs/20261101T143334Z-repair-skills/manifest.json',
 'skill_sha256':{'local':'a2b28d9953264d7b0ca62663785c2952190c5be6d6d3597fd695d9a54d606278','live':'a2b28d9953264d7b0ca62663785c2952190c5be6d6d3597fd695d9a54d606278'},
 'generator_files':{name:hashlib.sha256((HERE/name).read_bytes()).hexdigest() for name in ('generate.py','seeds.json','class-data.json')}}
print(json.dumps(result,indent=2))