Skip to content

Commit 9bb1071

Browse files
hyperpolymathclaude
andcommitted
feat(extract): unlock 7 more provers — Mercury/λProlog/Naproche/SAT trio/ABC
Vendored upstreams + extractor fixes for previously-empty provers: Mercury 0 → 13 173 (Mercury-Language/mercury, 2 794 .m files) Naproche 0 → 2 110 (naproche/naproche, sTeX .ftl.tex parser) λProlog 0 → 1 585 (teyjus/teyjus, 207 .mod files) CaDiCaL 0 → 313 (arminbiere/cadical + SAT-classical CNFs) Kissat 0 → 313 (same SAT corpus, mirrored) MiniSat 0 → 313 (same SAT corpus, mirrored) ABC 0 → 1 (placeholder — need proper benchmark source) Naproche extractor fix: prior pattern required bare `.ftl` files with `theorem NAME: ...` syntax. Real Naproche corpus ships as `.ftl.tex` / `.ftl.en.tex` (sTeX literate form) with theorems in \\begin{theorem}[forthel,title=...,name=...] blocks. Added both sTeX env and legacy bare-ftl patterns. SAT-benchmarks setup: consolidated 313 .cnf files from cadical + kissat + SAT-classical test suites under external_corpora/sat_benchmarks/, feeding the shared extract_sat_benchmarks.jl which emits per-prover records for all three SAT backends. Mercury + λProlog were pure vendoring — extractors already handled the formats. Three more provers past the 2K ML-useful threshold: Mercury, Naproche (along with Boogie/SeaHorn/Frama-C from the earlier wave). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent fc3f0f4 commit 9bb1071

1 file changed

Lines changed: 52 additions & 15 deletions

File tree

scripts/extract_naproche.jl

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,59 @@ function run_extract()
1111
ps, ts, pm = Dict{String,Any}[], Dict{String,Any}[], Dict{String,Any}[]; id = START_ID
1212
if !isdir(DIR); println("Naproche (ForTheL) corpus not found: $DIR"); println("Vendor source into $DIR and rerun."); return ps, ts, pm; end
1313
files = String[]
14-
for (root, _, fs) in walkdir(DIR); for f in fs; endswith(f, ".ftl") && push!(files, joinpath(root, f)); end; end
15-
println("Found $(length(files)) .ftl files")
16-
pat = r"theorem\s+([A-Za-z0-9_]+)\s*:\s*([^.]+)\."s
17-
for f in files
18-
try
19-
c = read(f, String)
20-
for m in eachmatch(pat, c)
21-
n = length(m.captures) >= 1 ? strip(String(m.captures[1])) : ""
22-
g = length(m.captures) >= 2 ? strip(String(m.captures[2])) : ""
23-
if !isempty(n)
24-
push!(ps, Dict{String,Any}("id"=>id, "prover"=>"naproche",
25-
"source_file"=>relpath(f, DIR), "theorem"=>n, "goal"=>g, "context"=>Any[]))
26-
id += 1
27-
end
14+
for (root, _, fs) in walkdir(DIR)
15+
for f in fs
16+
# Widening (2026-04-18): Naproche now publishes sources
17+
# as .ftl.tex (sTeX literate form) rather than bare .ftl.
18+
if endswith(f, ".ftl") || endswith(f, ".ftl.tex") ||
19+
endswith(f, ".ftl.en.tex")
20+
push!(files, joinpath(root, f))
2821
end
29-
catch e; println("Warning: $f: $e"); end
22+
end
23+
end
24+
println("Found $(length(files)) ForTheL files")
25+
26+
# sTeX/Naproche carries theorems in \begin{theorem}[forthel,
27+
# title=TITLE, name=NAME] ... \end{theorem} blocks.
28+
env_pat = r"\\begin\{(theorem|lemma|corollary|proposition|definition|axiom)\}(?:\[([^\]]*)\])?\s*(.*?)\\end\{\1\}"s
29+
# Older bare-ftl: `Theorem NAME. BODY Proof. ... Qed.`
30+
plain_pat = r"(Theorem|Lemma|Corollary|Proposition|Definition|Axiom)\s+([A-Za-z][A-Za-z0-9_ \-]*?)\.\s*(.*?)(?=\n\s*(?:Theorem|Lemma|Corollary|Proposition|Definition|Axiom|Proof|Qed)|\z)"s
31+
32+
for f in files
33+
c = try
34+
read(f, String)
35+
catch
36+
continue
37+
end
38+
rel = relpath(f, DIR)
39+
40+
matches = try collect(eachmatch(env_pat, c)) catch; Any[] end
41+
for (i, m) in enumerate(matches)
42+
kind = strip(m.captures[1])
43+
opts = m.captures[2] === nothing ? "" : strip(m.captures[2])
44+
body = first(strip(m.captures[3]), 2000)
45+
name_match = match(r"name=([A-Za-z0-9_\-]+)", opts)
46+
title_match = match(r"title=([^,\]]+)", opts)
47+
name = name_match !== nothing ? strip(name_match.captures[1]) :
48+
title_match !== nothing ? replace(strip(title_match.captures[1]), r"\s+" => "_") :
49+
"$(kind)_$(i)"
50+
push!(ps, Dict{String,Any}("id"=>id, "prover"=>"naproche",
51+
"source_file"=>rel, "theorem"=>name,
52+
"kind"=>kind, "goal"=>body, "context"=>Any[]))
53+
id += 1
54+
end
55+
56+
matches = try collect(eachmatch(plain_pat, c)) catch; Any[] end
57+
for m in matches
58+
kind = strip(String(m.captures[1]))
59+
name = replace(strip(String(m.captures[2])), r"\s+" => "_")
60+
body = first(strip(String(m.captures[3])), 2000)
61+
isempty(name) && continue
62+
push!(ps, Dict{String,Any}("id"=>id, "prover"=>"naproche",
63+
"source_file"=>rel, "theorem"=>name,
64+
"kind"=>kind, "goal"=>body, "context"=>Any[]))
65+
id += 1
66+
end
3067
end
3168
ps, ts, pm
3269
end

0 commit comments

Comments
 (0)