"""Assemble a standalone, importable Lean 4 file from a definitions manifest's hand-written lean_code entries. Only definitions with no Mathlib equivalent need one -- when a manifest entry's mathlib_ref is set, the theorems that use it just reference that Mathlib name directly, and there is nothing to assemble here. This exists because a definitions manifest is only JSON metadata by itself: Lean can't verify a proof that mentions a concept unless that concept is actual Lean code somewhere it can see, which is the point raised about definitions needing to be real, not just documented. Does not call Lean itself -- check_statements.py / lean-agent still has to actually verify that the resulting file, and anything that imports it, type-checks. """ import argparse import json from pathlib import Path def build(definitions_paths): entries = [] for path in definitions_paths: entries.extend(json.loads(path.read_text(encoding='utf-8'))) lines = ['-- Generated by textbook/build_definitions.py -- hand-written Lean', '-- definitions for concepts with no Mathlib equivalent. Regenerate', '-- from the definitions manifest(s) instead of hand-editing.', '', 'import Mathlib', ''] emitted = 0 for entry in entries: code = entry.get('lean_code') if not code: continue lines.append(f"-- {entry['label']}: {entry['concept']}") if entry.get('notes'): for note_line in entry['notes'].splitlines(): lines.append(f"-- {note_line}") lines.append(code.rstrip()) lines.append('') emitted += 1 return '\n'.join(lines), emitted def main(): parser = argparse.ArgumentParser(description='Assemble hand-written definitions into one importable Lean file') parser.add_argument('definitions', type=Path, nargs='+', help='one or more *.definitions.json manifests') parser.add_argument('--out', type=Path, required=True) args = parser.parse_args() text, emitted = build(args.definitions) args.out.write_text(text + '\n', encoding='utf-8') print(f'{emitted} hand-written definitions -> {args.out}') if __name__ == '__main__': main()