mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
## Lean fixes - RRCLogogramProjection.lean: replace `native_decide` → `decide` in 5 compiler-surface theorem witnesses (semantic_tear_projects_after_repair, semantic_tear_does_not_merge, semantic_tear_uses_quarantine_lane, unrepaired_tear_does_not_project, ordinary_logogram_projects_and_merges). All 5 pass under `decide`; no logic change. - PistSimulation.lean: add `-- expect: <value>` to every `#eval`/`#eval!` block across §6–§11 (~104 annotation lines). Document 8 undocumented `ofRawInt` magic integers in fixtureSpectralWindow (10.0, 20.0, 100.0, 40.0, 20.0, 10.0, 5.0, 5.0 × 65536). - DynamicCanal.lean: add `-- expect:` to all 15 #eval witness blocks in §17 (fixed-point constructors, DIAT encoding, coarse-graining tests). - MISignal.lean: add `-- expect: 131072` to both #eval witnesses. - Functions/BracketedCalculus.lean: add `-- expect: 327680` to #eval. - AVMIsa/Emit.lean, RRC/Emit.lean, RRC/ReceiptDensity.lean, ReceiptCore.lean: previously-staged `-- expect:` additions (from prior session) carried forward in this commit. ## Python shim fixes - Add `# PARTIAL BOUNDARY: contains domain logic; not a provable surface. Port to Lean/RRC before treating as authoritative.` to 9 shim files: pist_trace_classify_mcp.py, genus0_sphere_shell_demo.py, routing_benchmark.py, route_repair_v14a.py, pist_prove_and_classify.py, label_canary_theorems.py, validate_rrc_predictions.py, pist_receipt_density_injector.py, rrc_pist_shape_alignment.py. ## Build baseline lake build Compiler → 3311 jobs, 0 errors lake build → 3567 jobs, 0 errors Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
260 lines
9 KiB
Python
260 lines
9 KiB
Python
#!/usr/bin/env python3
|
||
"""Generate ground-truth multi-labels for the 42 canary theorems.
|
||
|
||
Reads canary receipts + results, infers labels from Lean code and proof output.
|
||
Outputs shared-data/pist_canary_ground_truth_labels.jsonl
|
||
"""
|
||
# PARTIAL BOUNDARY: contains domain logic; not a provable surface. Port to Lean/RRC before treating as authoritative.
|
||
|
||
import json
|
||
import os
|
||
import re
|
||
import sys
|
||
from collections import Counter, defaultdict
|
||
|
||
RESULTS_PATH = os.path.join(os.path.dirname(__file__), "../..",
|
||
"shared-data/pist_canary_results.jsonl")
|
||
RECEIPTS_PATH = os.path.join(os.path.dirname(__file__), "../..",
|
||
"shared-data/pist_canary_receipts.jsonl")
|
||
LABELS_PATH = os.path.join(os.path.dirname(__file__), "../..",
|
||
"shared-data/pist_canary_ground_truth_labels.jsonl")
|
||
|
||
|
||
def parse_domain(code: str) -> str:
|
||
"""Infer theorem domain from Lean code."""
|
||
code_lower = code.lower()
|
||
if "list" in code_lower and ("map" in code_lower or "reverse" in code_lower or "length" in code_lower):
|
||
return "list"
|
||
if "set" in code_lower and ("union" in code_lower or "inter" in code_lower):
|
||
return "set"
|
||
if "prop" in code_lower and ("∧" in code or "∨" in code or "→" in code or "¬" in code):
|
||
return "logic"
|
||
if "≤" in code or "≥" in code or "order" in code_lower or "le_refl" in code or "le_trans" in code:
|
||
return "order"
|
||
if "ring" in code_lower or "mul_comm" in code or "*" in code:
|
||
return "algebra"
|
||
if "gcd" in code_lower or "nat." in code_lower or "+" in code or "omega" in code_lower:
|
||
return "arithmetic"
|
||
if "def " in code:
|
||
return "fixed_point"
|
||
if "induction" in code_lower:
|
||
return "induction"
|
||
return "other"
|
||
|
||
|
||
def parse_proof_method(code: str) -> str:
|
||
"""Infer primary proof method from proof script.
|
||
|
||
Handles both full theorem statements and bare by-blocks.
|
||
"""
|
||
# Extract the by-block if present
|
||
m = re.search(r'by\s+(.+?)$', code)
|
||
if m:
|
||
proof = m.group(1).strip()
|
||
else:
|
||
proof = code.strip()
|
||
|
||
if not proof:
|
||
return "unknown"
|
||
|
||
if "omega" in proof:
|
||
return "omega"
|
||
if "nlinarith" in proof:
|
||
return "nlinarith"
|
||
if "ring" in proof:
|
||
return "ring"
|
||
if "simp" in proof and "induction" not in proof:
|
||
return "simp"
|
||
if "induction" in proof:
|
||
return "induction"
|
||
if "rw " in proof or "rewrite" in proof:
|
||
return "rewrite"
|
||
if "rfl" in proof:
|
||
return "rfl"
|
||
if "cases" in proof:
|
||
return "cases"
|
||
if "apply" in proof or "exact" in proof:
|
||
return "apply"
|
||
if "intro" in proof:
|
||
return "intro"
|
||
if "calc" in proof:
|
||
return "calc"
|
||
if "native_decide" in proof:
|
||
return "native_decide"
|
||
if "sorry" in proof:
|
||
return "incomplete"
|
||
return "unknown"
|
||
|
||
|
||
def parse_obstruction(stdout: str, stderr: str, status: str, code: str) -> str | None:
|
||
"""Infer obstruction type from proof output."""
|
||
if status == "verified" or "verified" in status:
|
||
return None
|
||
combined = (stdout + " " + stderr).lower()
|
||
if "timeout" in status or "timeout" in combined:
|
||
return "timeout"
|
||
if "type mismatch" in combined or "typeMismatch" in combined:
|
||
return "type_mismatch"
|
||
if "failed to synthesize" in combined or "synthInstance" in combined:
|
||
return "missing_instance"
|
||
if "unknown identifier" in combined or "unknownConstant" in combined:
|
||
return "missing_lemma"
|
||
if "unsat" in combined or "contradiction" in combined:
|
||
return "unsatisfiable_goal"
|
||
if "omega" in combined and "could not prove" in combined:
|
||
return "nonlinear_arithmetic"
|
||
if "coercion" in combined:
|
||
return "coercion_gap"
|
||
if "simp" in combined and "did not simplify" in combined:
|
||
return "simplifier_gap"
|
||
if "stack overflow" in combined or "recursion" in combined:
|
||
return "recursion_limit"
|
||
if "no applicable" in combined:
|
||
return "no_applicable_tactic"
|
||
return "other"
|
||
|
||
|
||
def infer_joint_label(domain: str, proof_method: str, obstruction: str | None, code: str) -> str:
|
||
"""Infer the type of proof joint from domain + method."""
|
||
if obstruction:
|
||
return f"{domain}_{obstruction}"
|
||
if proof_method == "rfl":
|
||
return "definitional_equality"
|
||
if proof_method == "simp":
|
||
return "rewrite_normalization"
|
||
if proof_method == "omega":
|
||
return "linear_constraint_closure"
|
||
if proof_method == "nlinarith":
|
||
return "nonlinear_constraint_closure"
|
||
if proof_method == "induction":
|
||
return "inductive_step"
|
||
if proof_method == "rewrite":
|
||
return "equality_chaining"
|
||
if proof_method == "apply":
|
||
return "rule_application"
|
||
if proof_method == "cases":
|
||
return "case_analysis"
|
||
if proof_method == "intro":
|
||
return "implication_introduction"
|
||
if proof_method == "calc":
|
||
return "calculational_proof"
|
||
if proof_method == "incomplete":
|
||
return "incomplete_proof"
|
||
return f"{domain}_{proof_method}"
|
||
|
||
|
||
def infer_rrc_shape(domain: str, proof_method: str, obstruction: str | None, code: str) -> str:
|
||
"""Map domain + proof method to RRCShape."""
|
||
if obstruction:
|
||
return "HoldForUnlawfulOrUnderspecifiedShape"
|
||
if proof_method in ("rfl", "simp"):
|
||
return "CognitiveLoadField"
|
||
if proof_method in ("omega", "nlinarith", "ring"):
|
||
return "SignalShapedRouteCompiler"
|
||
if proof_method == "induction":
|
||
return "ProjectableGeometryTopology"
|
||
if proof_method in ("rewrite", "calc"):
|
||
return "CadForceProbeReceipt"
|
||
if proof_method in ("apply", "cases", "intro"):
|
||
return "LogogramProjection"
|
||
if domain in ("logic", "order"):
|
||
return "LogogramProjection"
|
||
return "HoldForUnlawfulOrUnderspecifiedShape"
|
||
|
||
|
||
def find_in_receipt(receipts: list[dict], name: str) -> dict | None:
|
||
for r in receipts:
|
||
if r.get("theorem_name") == name:
|
||
return r
|
||
return None
|
||
|
||
|
||
def main():
|
||
# Load results
|
||
results = []
|
||
with open(RESULTS_PATH) as f:
|
||
for line in f:
|
||
results.append(json.loads(line))
|
||
|
||
# Load receipts
|
||
receipts = []
|
||
with open(RECEIPTS_PATH) as f:
|
||
for line in f:
|
||
receipts.append(json.loads(line))
|
||
|
||
print(f"Loaded {len(results)} results, {len(receipts)} receipts", flush=True)
|
||
|
||
labels = []
|
||
for r in results:
|
||
name = r["name"]
|
||
receipt = find_in_receipt(receipts, name)
|
||
code = receipt.get("theorem_statement", "") if receipt else ""
|
||
stdout = receipt.get("theorem_statement", "") if receipt else ""
|
||
|
||
status = r["status"]
|
||
proof_method = parse_proof_method(code)
|
||
domain = parse_domain(code)
|
||
obstruction = parse_obstruction(
|
||
r.get("stdout", ""),
|
||
r.get("stderr", ""),
|
||
status,
|
||
code,
|
||
)
|
||
joint = infer_joint_label(domain, proof_method, obstruction, code)
|
||
rrc = infer_rrc_shape(domain, proof_method, obstruction, code)
|
||
|
||
labels.append({
|
||
"theorem_name": name,
|
||
"canonical_hash": r.get("canonical_hash", ""),
|
||
"proof_status": "verified" if "verified" in status else status,
|
||
"domain_label": domain,
|
||
"proof_method_label": proof_method,
|
||
"obstruction_label": obstruction,
|
||
"joint_label": joint,
|
||
"manual_rrc_shape": rrc,
|
||
"label_confidence": "auto",
|
||
"notes": code[:80] if code else "",
|
||
})
|
||
|
||
# Print distribution
|
||
print(f"\nGround-truth labels generated: {len(labels)}", flush=True)
|
||
|
||
print("\nDomain distribution:")
|
||
for label, count in sorted(Counter(l["domain_label"] for l in labels).items()):
|
||
print(f" {label:20s}: {count:3d}")
|
||
|
||
print("\nProof method distribution:")
|
||
for label, count in sorted(Counter(l["proof_method_label"] for l in labels).items()):
|
||
print(f" {label:20s}: {count:3d}")
|
||
print("\nObstruction distribution:")
|
||
for label, count in sorted(Counter(l["obstruction_label"] or "none" for l in labels).items()):
|
||
print(f" {label:30s}: {count:3d}")
|
||
|
||
print("\nManual RRCShape distribution:")
|
||
for label, count in sorted(Counter(l["manual_rrc_shape"] for l in labels).items()):
|
||
print(f" {label:35s}: {count:3d}")
|
||
|
||
# Write labels
|
||
with open(LABELS_PATH, "w") as f:
|
||
for lbl in labels:
|
||
f.write(json.dumps(lbl) + "\n")
|
||
print(f"\nLabels: {LABELS_PATH}", flush=True)
|
||
|
||
# Cross-tab: domain × proof method
|
||
print("\nCross-tab: domain × proof method")
|
||
domains = sorted(set(l["domain_label"] for l in labels))
|
||
methods = sorted(set(l["proof_method_label"] for l in labels))
|
||
header = " " + "".join(f"{m:18s}" for m in methods)
|
||
print(header)
|
||
for dom in domains:
|
||
row = f" {dom:12s}"
|
||
for meth in methods:
|
||
c = sum(1 for l in labels if l["domain_label"] == dom and l["proof_method_label"] == meth)
|
||
row += f"{c:>18d}"
|
||
print(row)
|
||
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|