SPB Git

spb/wp34_uqo

Public
5.5 KB · 82 lines python
1"""Hypothesis registry: parses hypotheses/H*.md (YAML front matter), validates required fields, optionally executes the2linked verification commands, and emits research_log/discovery_log.jsonl + paper/tables/hypotheses.tex.34Front matter schema (all required):5  id, title, axis (A|B|C|D), kind (algebraic|algorithmic|sha256|methodology|formal), statement, motivation, assumptions,6  expected_contribution, related_work (list of bib keys), possible_counterexamples, verification_strategy,7  computational_budget, status (planned|running|evaluated), classification (new_verified|known_reproduced|conditional|8  empirical_observation|rejected|unresolved|pending), evidence (list of result files), verdict (one sentence).9"""10import argparse, datetime, json, pathlib, re, subprocess, sys11import yaml12ROOT = pathlib.Path(__file__).resolve().parents[2]13REQ = ["id", "title", "axis", "kind", "statement", "motivation", "assumptions", "expected_contribution", "related_work",14       "possible_counterexamples", "verification_strategy", "computational_budget", "status", "classification", "evidence", "verdict"]15CLASSES = {"new_verified", "known_reproduced", "conditional", "empirical_observation", "rejected", "unresolved", "pending"}16LABEL = {"new_verified": "New verified result", "known_reproduced": "Known result reproduced", "conditional": "Conditional result",17         "empirical_observation": "Empirical observation", "rejected": "Rejected conjecture", "unresolved": "Unresolved direction", "pending": "Pending"}181920def load():21    hyps = []22    for f in sorted((ROOT / "hypotheses").glob("H*.md")):23        txt = f.read_text()24        m = re.match(r"^---\n(.*?)\n---\n(.*)$", txt, re.S)25        if not m:26            raise SystemExit(f"{f}: missing front matter")27        meta = yaml.safe_load(m.group(1)); meta["body"] = m.group(2).strip(); meta["file"] = f.name28        missing = [k for k in REQ if k not in meta]29        if missing:30            raise SystemExit(f"{f}: missing fields {missing}")31        if meta["classification"] not in CLASSES:32            raise SystemExit(f"{f}: bad classification {meta['classification']}")33        for ev in meta["evidence"]:34            if not (ROOT / ev).exists():35                print(f"WARNING {f.name}: evidence file missing: {ev}")36        hyps.append(meta)37    return hyps383940def tex_escape(s: str) -> str:41    return s.replace("&", r"\&").replace("%", r"\%").replace("_", r"\_").replace("#", r"\#").replace("√", r"$\sqrt{\ }$").replace("≈", r"$\approx$").replace("≤", r"$\le$").replace("≥", r"$\ge$").replace("→", r"$\to$").replace("×", r"$\times$").replace("²", r"$^2$").replace("Ω", r"$\Omega$").replace("φ", r"$\varphi$").replace("λ", r"$\lambda$").replace("β", r"$\beta$").replace("Σ", r"$\Sigma$").replace("σ", r"$\sigma$").replace("δ", r"$\delta$").replace("π", r"$\pi$").replace("ω", r"$\omega$").replace("−", "--").replace("–", "--").replace("—", "---").replace("·", r"$\cdot$").replace("∈", r"$\in$").replace("⊕", r"$\oplus$").replace("≡", r"$\equiv$").replace("∞", r"$\infty$").replace("ℓ", r"$\ell$").replace("ε", r"$\varepsilon$")424344def main():45    ap = argparse.ArgumentParser(); ap.add_argument("--run", action="store_true", help="execute verification commands in front matter `commands`")46    a = ap.parse_args()47    hyps = load()48    counts = {}49    for h in hyps:50        counts[h["kind"]] = counts.get(h["kind"], 0) + 151    log = ROOT / "research_log/discovery_log.jsonl"52    with log.open("w") as fh:53        for h in hyps:54            if a.run and h.get("commands"):55                for cmd in h["commands"]:56                    print(f"[{h['id']}] $ {cmd}")57                    subprocess.run(cmd, shell=True, check=True, cwd=ROOT)58            fh.write(json.dumps({"id": h["id"], "title": h["title"], "axis": h["axis"], "kind": h["kind"], "status": h["status"],59                                 "classification": h["classification"], "verdict": h["verdict"], "evidence": h["evidence"],60                                 "logged_utc": datetime.datetime.now(datetime.timezone.utc).isoformat(timespec="seconds")}) + "\n")61    # LaTeX table (longtable) for the paper62    rows = []63    for h in hyps:64        rows.append(f"{h['id']} & {h['axis']} & {tex_escape(h['title'])} & {LABEL[h['classification']]} & {tex_escape(h['verdict'])} \\\\")65    tex = ["% generated by experiments/automated_discovery/registry.py — do not edit",66           r"\begin{longtable}{@{}p{0.8cm}p{0.5cm}p{4.2cm}p{2.6cm}p{6.4cm}@{}}",67           r"\caption{Hypothesis portfolio and evaluation outcome. Classification vocabulary follows the mandate (new verified result; known result independently reproduced; conditional result; empirical observation; rejected conjecture; unresolved direction).}\label{tab:hypotheses}\\",68           r"\toprule ID & Axis & Hypothesis & Classification & Verdict \\ \midrule \endfirsthead",69           r"\toprule ID & Axis & Hypothesis & Classification & Verdict \\ \midrule \endhead",70           r"\bottomrule \endfoot"] + rows + [r"\end{longtable}"]71    (ROOT / "paper/tables").mkdir(exist_ok=True, parents=True)72    (ROOT / "paper/tables/hypotheses.tex").write_text("\n".join(tex) + "\n")73    summary = {"n_hypotheses": len(hyps), "by_kind": counts,74               "by_classification": {c: sum(1 for h in hyps if h["classification"] == c) for c in CLASSES}}75    (ROOT / "results/automated_discovery").mkdir(exist_ok=True, parents=True)76    (ROOT / "results/automated_discovery/hypothesis_summary.json").write_text(json.dumps(summary, indent=1))77    print(json.dumps(summary, indent=1))787980if __name__ == "__main__":81    main()82
Files · 838777af38d0770ebe997649ab0bf1629f7324d5
Menu

Theme