mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
fix(lharness): Improve proof extraction to handle LLM response formatting variations
- Extract markdown code blocks first, fallback to manual stripping - Handle multiple 'by' keyword case variations (:= by, by line starts, etc.) - Avoid duplicate 'by by' syntax errors on insertion - Strip trailing whitespace in proof positions
This commit is contained in:
parent
5bca8fe5e3
commit
551df86e1d
1 changed files with 38 additions and 10 deletions
|
|
@ -315,21 +315,35 @@ def extract_errors(log: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
def extract_proof_code(response: str) -> str:
|
def extract_proof_code(response: str) -> str:
|
||||||
text = re.sub(r"^\s*```(?:lean)?\s*\n?", "", response, flags=re.MULTILINE)
|
# 1. Try to extract content inside markdown code blocks first to ignore explanations
|
||||||
text = re.sub(r"\n\s*```\s*$", "", text, flags=re.MULTILINE)
|
blocks = re.findall(r"```(?:lean)?\n(.*?)\n```", response, re.DOTALL | re.IGNORECASE)
|
||||||
text = text.strip()
|
if blocks:
|
||||||
|
text = blocks[-1].strip()
|
||||||
if text.startswith(":= by"):
|
else:
|
||||||
return text
|
# Fallback to manual stripping if markdown block is unclosed or malformed
|
||||||
|
text = re.sub(r"^\s*```(?:lean)?\s*\n?", "", response, flags=re.MULTILINE)
|
||||||
|
text = re.sub(r"\n\s*```\s*$", "", text, flags=re.MULTILINE)
|
||||||
|
text = text.strip()
|
||||||
|
|
||||||
|
# 2. Extract proof body matching case variations to prevent formatting drift failures:
|
||||||
|
# Case A: Contains ":= by"
|
||||||
idx = text.find(":= by")
|
idx = text.find(":= by")
|
||||||
if idx >= 0:
|
if idx >= 0:
|
||||||
return text[idx:]
|
return text[idx:]
|
||||||
|
|
||||||
idx = text.find("\nby ")
|
# Case B: Contains ":=" followed by optional space/newline and then "by"
|
||||||
if idx >= 0:
|
m = re.search(r":=\s*(by\b.*)", text, re.DOTALL)
|
||||||
prev_newline = text.rfind("\n", 0, idx)
|
if m:
|
||||||
return text[prev_newline + 1:].strip()
|
return ":= " + m.group(1)
|
||||||
|
|
||||||
|
# Case C: Starts with "by"
|
||||||
|
if text.startswith("by\n") or text.startswith("by "):
|
||||||
|
return text
|
||||||
|
|
||||||
|
# Case D: Contains a line starting with "by "
|
||||||
|
m = re.search(r"(?:\n|^)\s*(by\b.*)", text, re.DOTALL)
|
||||||
|
if m:
|
||||||
|
return m.group(1)
|
||||||
|
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
@ -371,6 +385,20 @@ def insert_proof(lean_path: Path, sorry_line: int, proof_code: str) -> bool:
|
||||||
if code.startswith(":= by"):
|
if code.startswith(":= by"):
|
||||||
code = code[5:].strip()
|
code = code[5:].strip()
|
||||||
|
|
||||||
|
# Avoid duplicate "by by" syntax errors if insertion point already has "by"
|
||||||
|
insertion_line = lines[insert_idx]
|
||||||
|
has_by = "by" in insertion_line or (insert_idx > 0 and "by" in lines[insert_idx - 1])
|
||||||
|
|
||||||
|
if has_by:
|
||||||
|
if code.startswith("by "):
|
||||||
|
code = code[3:].strip()
|
||||||
|
elif code.startswith("by\n"):
|
||||||
|
code = code[2:].strip()
|
||||||
|
else:
|
||||||
|
# Ensure code starts with "by" if insertion point is missing it
|
||||||
|
if not code.startswith("by\n") and not code.startswith("by "):
|
||||||
|
code = "by\n " + code
|
||||||
|
|
||||||
# Build indented proof lines (preserve blank lines).
|
# Build indented proof lines (preserve blank lines).
|
||||||
proof_lines: list[str] = []
|
proof_lines: list[str] = []
|
||||||
for pl in code.split("\n"):
|
for pl in code.split("\n"):
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue