Files
lean-bench/textbook
claude-bot caedf2e6f4 Add textbook formalization pipeline (extract -> LLM formalize -> elaboration check -> library assembly)
- extract_section.py: slice a book section out of a pdftotext -layout dump and
  list its labeled Theorem/Proposition/Lemma/Corollary/Definition items.
- formalize.py: LLM-formalize a section into Lean 4 candidate statements
  (preferring Mathlib vocabulary) plus a definitions manifest.
- check_statements.py: elaboration-only sanity check against a real
  Mathlib-backed Lean project (must run outside the Cowork sandbox, which has
  no Lean toolchain and can't run macOS binaries anyway).
- build_library.py: assemble solved lean-bench results into a reusable .lean
  file, reusing each winning proof verbatim.
- llm.py: standalone OpenAI-compatible chat client + .env loader, kept
  independent of lean_agent so this pipeline works without it installed.
- Source PDFs and raw/layout text dumps are gitignored (copyrighted material);
  only code and the final short Lean statement datasets are tracked.
2026-09-17 17:04:19 +00:00
..

Textbook formalization pipeline

把一本教科书(目前是 Goodman, Algebra: Abstract and Concrete)里正文的 Theorem/Proposition/Lemma/Corollary 转成 lean-bench 能跑的任务 JSONL,配套 Definition 清单(优先复用 Mathlib,Mathlib 没有的才手写),再由 lean-agent 在 一个真正带 Mathlib 的 Lean 项目里验证/证明。这条流水线本身不跑 Lean,也不联网 以外没有第三方依赖。

这条流水线不做什么

  • 不产出证明。生成的只是待证命题(statement 字段),证明留给 lean-agent/lean-bench 去跑。
  • 不在 Cowork 沙盒里验证 Lean 语句能不能通过类型检查——沙盒里没有装 Lean/Lake/Mathlib(架构也不兼容:本机 ~/.elan 下是 macOS 二进制,沙盒是 Linux VM,跑不了),所以 check_statements.py 必须在你本机、且是一个已经 lake exe cache get 过的 Mathlib 项目里跑,见下面"本机环境准备"。
  • 不会把教科书 PDF 或者大段原文提取结果提交进 git——.gitignore 里已经排除 了 *.pdf 和 textbook/*.txt,这些是版权内容,只应该留在你本机。只有代码、 生成的最终数据集(短的 Lean 语句 + 自己改写的简短英文释义)会进仓库。

用法

1. 从 PDF 提取一章的版式文本

pdftotext -layout -f <起始pdf页码> -l <结束pdf页码> uiowa-algebra.pdf textbook/chapterNN_layout.txt

页码用 pdfinfo/pypdf 先核对——书里印的页码和 PDF 物理页码不是一回事(前 面有目录、序言)。

2. 切出一个 section,列出带编号的条目清单

python3 textbook/extract_section.py textbook/chapterNN_layout.txt \
  --start-heading "1.6. Divisibility in the Integers" \
  --end-heading "1.7. Modular Arithmetic" \
  --section-prefix "1.6." \
  --out-text textbook/section_1_6.txt \
  --out-index textbook/section_1_6.index.json

--start-heading/--end-heading 必须和版式文本里独占一行的章节标题逐字 一致(提取时打印出的书本身的标题行);--end-heading 留空就切到文件末尾。 输出的 index JSON 是这个 section 里所有 Theorem/Proposition/Lemma/ Corollary/Definition N.N.N 开头的条目清单(自动去重了跨页重复的标签),用来 让下一步的 LLM 不漏项、不编项目。

3. 用 LLM 把 section 形式化成候选 Lean 语句

export DASHSCOPE_API_KEY=...            # 或者写进 lean-bench/.env(已 gitignore)
python3 textbook/formalize.py \
  textbook/section_1_6.txt textbook/section_1_6.index.json \
  --model qwen-max --base-url https://dashscope.aliyuncs.com/compatible-mode/v1 \
  --out-dataset datasets/goodman-1.6.jsonl \
  --out-definitions textbook/goodman-1.6.definitions.json \
  --out-excluded textbook/goodman-1.6.excluded.jsonl

模型会为每条 Theorem/Proposition/Lemma/Corollary 产出一个 Lean 4 命题 (statement)、需要的 prelude(通常就是 import Mathlib)、一句自己改写 的英文释义,以及用到的 Mathlib 标识符列表;为每条相关的 Definition 产出一个 清单条目——如果 Mathlib 已经有对应概念(mathlib_ref 非空)就不写 Lean 代 码,只有 Mathlib 没有的概念才会给出手写的 def。判断这条目根本没法形式化 (纯计算题、内容太模糊/被 PDF 提取污染到读不出原意)的条目,会带着 include_in_bench: false 和原因单独写进 --out-excluded,不会进真正的数据 集,但也不会被静默丢弃——都留痕方便你复核。

源 PDF 的数学符号提取质量很差(≡、∈、上下标经常丢失或乱码),这一步依赖模 型自己对标准教材内容的知识去猜测/还原真实含义,不是逐字翻译提取出来的文 本。所以生成的候选语句必须经过下一步验证,不能直接信。

4. 在你本机验证候选语句能不能通过类型检查

见下面"本机环境准备"先搭好一个带 Mathlib 的 Lake 项目,然后:

python3 textbook/check_statements.py datasets/goodman-1.6.jsonl \
  --lean-project /path/to/your/mathlib-project \
  --lean-command '["lake","env","lean"]' \
  --report textbook/goodman-1.6.elab-report.jsonl

这一步只检查"这句 Lean 能不能通过类型检查"(用 sorry 占位),不检查证明 是否存在、也不检查是否忠实于原书——分别对应两件不同的事:语法/引用是否正 确,跟数学内容是否正确。失败的条目(FAIL)要么是模型编造了不存在的 Mathlib 标识符,要么是语句本身写错了,需要你告诉我具体哪条、Lean 报的什么 错,我再改。

5. 用 lean-agent/lean-bench 真正证明

lean-bench datasets/goodman-1.6.jsonl --output results/goodman-1.6-001 \
  --lean-project /path/to/your/mathlib-project --lean-command '["lake","env","lean"]' \
  --model ... --base-url ...

6. 把证出来的定理组装成一份可复用的库文件

python3 textbook/build_library.py datasets/goodman-1.6.jsonl \
  results/goodman-1.6-001/results.jsonl --out lib/Chapter01Section06.lean

只有这次跑真的证出来的定理(results.jsonl 里 success: true)才会被收进 去,直接复用验证时确认过的那个证明,不会引入新的证明风险。后续章节要用这些 已证定理时,import 这份文件——注意这只是把已证结果攒成一个文件,不是一个真 正的 Lake 包/模块边界。

本机环境准备:一个带 Mathlib 的 Lake 项目

Cowork 这边的沙盒没有 Lean,check_statements.py 和真正跑 lean-agent/ lean-bench 都需要在你本机(或者别的有 Lean 的环境)完成。如果还没有这样一 个项目:

cd ~/ProjectResearch   # 随便一个地方
lake +leanprover/lean4:v4.33.1 new mathlib-bench math
cd mathlib-bench
lake exe cache get     # 下载 Mathlib 预编译缓存,比从源码编译快得多
lake build

之后 --lean-project 就指到 mathlib-bench 这个目录,--lean-command 用 '["lake","env","lean"]'。

反馈循环

我(claude-bot)在 ProjectResearch 里生成/修改数据集和代码 → 提交并 push 到 Zayden-Jung/lean-bench(用 claude-bot 的 token) → 你在本机 git pull → 跑 check_statements.py / lean-bench → 把失败的条目 id 和 Lean 报的错发 给我 → 我改完再 push。不需要额外工具,就是正常的 git 往返。