prepare-conformance.py (2776B)
1 #!/usr/bin/env python3 2 """Capture Haskell runtime goldens for exact raw normal trees (no compiler build).""" 3 import hashlib 4 import json 5 from pathlib import Path 6 import subprocess 7 import sys 8 import tempfile 9 10 HERE = Path(__file__).resolve().parent 11 host = Path(sys.argv[1]).resolve() 12 13 def digest(kind, payload): 14 return hashlib.sha256(kind.encode() + b'\0' + payload).hexdigest() 15 16 by_size = {1: ['0']} 17 for size in range(2, 6): 18 terms = ['1' + child for child in by_size[size - 1]] 19 for left_size in range(1, size - 1): 20 terms += ['2' + a + b for a in by_size[left_size] for b in by_size[size - 1 - left_size]] 21 by_size[size] = terms 22 terms = sum(by_size.values(), []) 23 cases = [] 24 with tempfile.TemporaryDirectory(prefix='arboricx-browser-conformance-') as temporary: 25 temp = Path(temporary) 26 store = temp / 'store' 27 def put(kind, payload): 28 pin = digest(kind, payload) 29 path = store / 'objects' / pin[:3] / pin 30 path.parent.mkdir(parents=True, exist_ok=True) 31 path.write_bytes(payload) 32 return pin 33 def run(program, arguments): 34 tree = put('arboricx.tree-term.v1', bytes(map(int, program))) 35 manifest = put('arboricx.module-manifest.v1', 36 ('arboricx.module-manifest.v1\nexport\tmain\tarboricx.tree-term.v1\t' 37 + tree + '\tarboricx.abi.tree.v1\n').encode()) 38 args = [] 39 for i, arg in enumerate(arguments): 40 path = temp / f'arg{i}.tree' 41 path.write_bytes(bytes(map(int, arg))) 42 args += ['--arg-tree-file', str(path)] 43 reply = subprocess.run([str(host), 'arboricx', 'run', '--store', str(store), 44 '--module', manifest, '--name', 'main', '--format', 'ternary', *args], 45 capture_output=True, timeout=3) 46 if reply.returncode: 47 raise RuntimeError(reply.stderr.decode()) 48 result = reply.stdout.decode() 49 assert len(result) < 200000 50 return dict(program=program, arguments=arguments, result=result) 51 for program in terms: 52 for arg in terms: 53 cases.append(run(program, [arg])) 54 cases.append(run('2120200212110021100', ['212110021100'])) 55 # Multiple arguments and partial application with selected triage demand. 56 for program in ('0', '10', '200', '21100', '22000'): 57 cases.append(run(program, ['10', '200'])) 58 cases.append(run(program, [])) 59 60 payload = dict(hostSha256=hashlib.sha256(host.read_bytes()).hexdigest(), 61 description='All normal trees <=5 nodes, every ordered application pair; lazy regression and partial/multiple applications.', 62 cases=cases) 63 (HERE / 'conformance.json').write_text(json.dumps(payload, indent=2) + '\n') 64 print(f'Captured {len(cases)} independent Haskell runtime results')