ragsolver / scripts /reverify_eval_v1.py
CamiloS1111's picture
Upload folder using huggingface_hub
81f30c1 verified
Raw History Blame Contribute Delete
4.78 kB
"""Fase 1, tarea 8 de docs/PLAN_CORRECCIONES.md — re-verificación offline de
`eval-v1` con el verificador endurecido (SEC-1, VER-1, BUG-2). 0 llamadas LLM:
sólo el REPL de Lean (~1 min de import + ~0.3 s por fila).
1. Validación de tácticas (`find_forbidden_tactic`) sobre el `lean_code`
final de las 300 filas: mide falsos positivos del denylist nuevo contra
tácticas reales ya producidas por el LLM.
2. Re-verificación completa (kernel + auditoría de axiomas) de las 27 filas
`done`, reconstruyendo el archivo con el `header` del problema (BUG-2),
que el `lean_code` original no incluía.
No modifica `results.jsonl`. Escribe `data/eval/runs/eval-v1/reverify.json`.
Uso: uv run python scripts/reverify_eval_v1.py
"""
from __future__ import annotations
import json
import re
from pathlib import Path
from ragsolver.agents.agents import load_agents_config
from ragsolver.agents.schemas import Problem
from ragsolver.lean.verify import LeanChecker, find_forbidden_tactic
RUN_DIR = Path("data/eval/runs/eval-v1")
PROBLEMS_PATH = Path("data/eval/problems/eval_v1.jsonl")
_TACTICS_SPLIT_RE = re.compile(r":=\s*by\n")
def extract_tactics(lean_code: str) -> str | None:
"""Tácticas ya indentadas a 2 espacios que dejó el `build_file` original
(formato antiguo, sin `#print axioms`): todo lo que sigue al primer
`:= by\\n` del archivo, de-indentado. None si no se encuentra el patrón."""
m = _TACTICS_SPLIT_RE.search(lean_code)
if not m:
return None
tail = lean_code[m.end() :]
lines = tail.split("\n")
while lines and lines[-1].strip() == "":
lines.pop()
return "\n".join(line[2:] if line.startswith(" ") else line for line in lines)
def main() -> None:
rows = [json.loads(l) for l in (RUN_DIR / "results.jsonl").read_text(encoding="utf-8").splitlines() if l.strip()]
problems = {p.problem_id: p for p in (Problem.model_validate_json(l) for l in PROBLEMS_PATH.read_text(encoding="utf-8").splitlines() if l.strip())}
lean_cfg = load_agents_config()["lean"]
# 1. Falsos positivos del denylist sobre las filas con lean_code -------------
false_positives = []
n_checked = 0
for r in rows:
code = r.get("lean_code") or ""
if not code:
continue
tactics = extract_tactics(code)
if tactics is None:
continue
n_checked += 1
hit = find_forbidden_tactic(tactics)
if hit:
false_positives.append({"config": r["config"], "problem_id": r["problem_id"], "status": r["status"], "denied_token": hit, "tactics": tactics[:300]})
# 2. Re-verificación completa de las filas `done` -----------------------------
done = [r for r in rows if r["status"] == "done" and r.get("lean_code")]
checker = LeanChecker(imports=lean_cfg["imports"], timeout_s=lean_cfg["timeout_s"])
checker.check("theorem _warmup : True := by sorry", "trivial") # precalienta fuera del cronómetro por fila
reverified = []
for r in done:
problem = problems.get(r["problem_id"])
if problem is None:
reverified.append({"config": r["config"], "problem_id": r["problem_id"], "skipped": "problema no encontrado en eval_v1.jsonl"})
continue
tactics = extract_tactics(r["lean_code"])
if tactics is None:
reverified.append({"config": r["config"], "problem_id": r["problem_id"], "skipped": "no se pudo extraer las tácticas del lean_code original"})
continue
v = checker.check(problem.formal_statement, tactics, problem.header, lean_cfg["max_heartbeats"])
reverified.append(
{
"config": r["config"],
"problem_id": r["problem_id"],
"ok_before": True,
"ok_now": v.ok,
"axioms": v.axioms,
"non_standard_axioms": [a for a in v.axioms if a not in ("propext", "Classical.choice", "Quot.sound")],
"errors": v.errors[:2] if not v.ok else [],
}
)
checker.close()
regressions = [x for x in reverified if x.get("ok_before") and not x.get("ok_now")]
out = {
"n_rows": len(rows),
"n_lean_code_checked_for_false_positives": n_checked,
"n_false_positives": len(false_positives),
"false_positives": false_positives,
"n_done_reverified": len(reverified),
"n_regressions": len(regressions),
"regressions": regressions,
"reverified": reverified,
}
(RUN_DIR / "reverify.json").write_text(json.dumps(out, indent=2, ensure_ascii=False), encoding="utf-8")
print(json.dumps({k: v for k, v in out.items() if k != "reverified"}, indent=2, ensure_ascii=False))
if __name__ == "__main__":
main()