files / problems / riemann-hypothesis / compute / q2 / verify_finite.py

6.5 KB · on GitHub

#!/usr/bin/env python3
"""Stream-check complete outputs of both finite implementations.

This is a transcript check. run_all.sh first regenerates both streams.
Reading successful old logs alone is not a fresh numerical verification.
"""
import argparse
from fractions import Fraction
import gzip
import hashlib
import json
from pathlib import Path
import re
from regenerate import SEGMENTS, SOURCE_SHA, PIN
from run_independent import LEGS

ERROR=Fraction(233494905212337849,10**24)

def require(ok,message):
    if not ok: raise ValueError(message)

def digest(path):
    with (gzip.open(path.with_suffix(path.suffix+'.gz'),'rb')
          if not path.exists() else path.open('rb')) as f:
        return hashlib.file_digest(f,'sha256').hexdigest()

def transcript(path):
    return path.open() if path.exists() else gzip.open(path.with_suffix(path.suffix+'.gz'),'rt')

def c_rows(root):
    manifest=json.loads((root/'progress.json').read_text())
    require(manifest['pin']==PIN,'C upstream pin')
    require(manifest['source_sha256']==SOURCE_SHA,'C source pin')
    require(len(manifest['segments'])==len(SEGMENTS),'C segment count')
    for definition,entry in zip(SEGMENTS,manifest['segments']):
        lo,hi,k,bits,order,width=definition
        times=[16125,16125,100000] if k==6 else [161250000,161250001,1000000000]
        parameters=[str(lo),str(hi),*map(str,times),'350708','10000000',
                    str(k),str(bits),str(order),width,'t']
        require(entry['command'][1:]==parameters,'C exact invocation parameters')
        require((entry['first_N'],entry['last_N'],entry['rows'])==(lo,hi,hi-lo+1),'C manifest coverage')
        require(entry['reused'] is False,'C transcript must come from a fresh run')
        path=root/f'N{lo}-{hi}.txt'
        require(digest(path)==entry['sha256'],'C transcript hash')
        next_n=lo; minimum=10**12; finished=False
        with transcript(path) as f:
            tbox='16125/100000 16125/100000' if k==6 else '161250000/1000000000 161250001/1000000000'
            require(next(f)==f'TBOX {tbox}\n','C time box')
            require(next(f)=='WEIGHT TRIANGLE\n','C weight branch')
            for line in f:
                match=re.fullmatch(r'N (\d+) L12 0\.(\d{12}) GT089 ([01])\n',line)
                if match:
                    n,v=int(match[1]),int(match[2])
                    require(not finished and n==next_n and n<=hi,'C row order')
                    require(Fraction(v,10**12)>ERROR,'C finite positivity')
                    minimum=min(minimum,v); next_n+=1
                    yield n,v
                else:
                    match=re.fullmatch(r'TIMING [0-9.]+ (\d+)\n',line)
                    require(match is not None and not finished,'C unrecognized/extra record')
                    require(int(match[1])==hi-lo+1 and next_n==hi+1,'C completion count')
                    finished=True
        require(finished and minimum==entry['floor_1e12'],'C terminal/minimum')
    require(manifest['rows_regenerated']==3149013,'C total')

def rust_rows(root):
    manifest=json.loads((root/'manifest.json').read_text())
    here=Path(__file__).resolve().parent
    source_names={'direct.rs','interpolate.rs','ball.rs','arb_bridge.c','run_independent.py'}
    require(set(manifest['sources'])==source_names,'Rust numerical source set')
    for name in source_names:
        require(digest(here/name)==manifest['sources'][name],'Rust executed source hash')
    names=['direct-first']+[f'interpolation-{lo}-{hi}' for lo,hi,_ in LEGS]
    require([r['name'] for r in manifest['runs']]==names,'Rust run list')
    commands=[['690988','5','192']]+[[str(lo),str(hi),str(k),'8','192'] for lo,hi,k in LEGS]
    require([r['command'][1:] for r in manifest['runs']]==commands,'Rust exact invocation parameters')
    for entry in manifest['runs']:
        require(entry['returncode']==0,'Rust unsuccessful run')
        for suffix,key in [('.txt','stdout_sha256'),('.stderr.txt','stderr_sha256')]:
            require(digest(root/(entry['name']+suffix))==entry[key],'Rust transcript hash')
    for lo,hi,k in LEGS:
        name=f'interpolation-{lo}-{hi}'
        with transcript(root/(name+'.txt')) as f:
            require(next(f)==f'INTERPOLATION first={lo} last={hi} primes={k} nodes=8 bits=192 t=129/800 y2=87677/2500000\n','Rust parameters')
            minimum=10**12; at=lo; next_n=lo; finished=False
            for line in f:
                match=re.fullmatch(r'N (\d+) LOWER12 (-?\d+)\n',line)
                if match:
                    n,v=int(match[1]),int(match[2])
                    require(not finished and n==next_n and n<=hi,'Rust row coverage')
                    require(v>233495 and Fraction(v,10**12)>ERROR,'Rust finite positivity')
                    if v<minimum: minimum,at=v,n
                    next_n+=1
                    yield n,v
                else:
                    match=re.fullmatch(r'COMPLETE rows=(\d+) minimum12=(-?\d+) at=(\d+)\n',line)
                    require(match is not None and not finished,'Rust unrecognized/extra record')
                    require(tuple(map(int,match.groups()))==(hi-lo+1,minimum,at),'Rust terminal summary')
                    require(next_n==hi+1,'Rust incomplete range')
                    finished=True
        require(finished,'Rust missing completion')

def main():
    p=argparse.ArgumentParser(description=__doc__)
    p.add_argument('original',type=Path);p.add_argument('independent',type=Path)
    p.add_argument('--summary',type=Path)
    args=p.parse_args()
    c=iter(c_rows(args.original));r=iter(rust_rows(args.independent))
    cmin=rmin=10**12; rc=rr=0; count=0
    for n in range(690988,3840001):
        cn,cv=next(c);rn,rv=next(r)
        require(cn==rn==n,'implementation coverage agreement')
        if cv<cmin: cmin,rc=cv,n
        if rv<rmin: rmin,rr=rv,n
        count+=1
    require(next(c,None) is None and next(r,None) is None,'extra finite rows')
    require(cmin==791366 and rc==690988,'original global floor')
    report={'rows_per_implementation':count,'first_N':690988,'last_N':3840000,
            'original_minimum12':cmin,'original_at':rc,'independent_minimum12':rmin,
            'independent_at':rr,'uniform_error_upper':str(ERROR),
            'original_margin_lower':str(Fraction(cmin,10**12)-ERROR),
            'independent_margin_lower':str(Fraction(rmin,10**12)-ERROR)}
    if args.summary: args.summary.write_text(json.dumps(report,indent=2)+'\n')
    print(json.dumps(report,indent=2))
    print('PASS: two complete finite implementations; analytic assembly is separate')

if __name__=='__main__': main()