tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

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')