# -*- coding: utf-8 -*- """ collatz_base_projective.py Generate base projective of 60 states (B12 mod 4096). Uses md_to_audit_json when audit MD exists, else outputs minimal structure. """ from __future__ import annotations import argparse import json from pathlib import Path from md_to_audit_json import ( parse_residues_by_state, parse_state_table, build_residue_to_state, ) def run(modulus: int, output_path: str, audit_md_path: str | None = None) -> None: """Generate base_projective JSON from audit MD or minimal structure.""" default_md = Path(__file__).parent / "audit_60_etats_B12_mod4096_horizon7.md" md_path = Path(audit_md_path) if audit_md_path else default_md if md_path.exists(): text = md_path.read_text(encoding="utf-8") state_table = parse_state_table(text) residue_by_state = parse_residues_by_state(text) residue_to_state = build_residue_to_state(residue_by_state) out = { "modulus": modulus, "residue_to_state": {k: v for k, v in residue_to_state.items()}, "state_table": state_table, } else: out = {"modulus": modulus, "residue_to_state": {}, "state_table": []} Path(output_path).write_text( json.dumps(out, indent=2, ensure_ascii=False), encoding="utf-8" ) print(f"Wrote {output_path}: modulus={modulus}") def main() -> None: ap = argparse.ArgumentParser(description="Generate base projective 60 states") ap.add_argument("--modulus", type=int, default=4096) ap.add_argument("--output", "-o", required=True) ap.add_argument("--audit-md", help="Path to audit MD (default: audit_60_etats_*.md)") args = ap.parse_args() run(args.modulus, args.output, args.audit_md) if __name__ == "__main__": main()