--- title: Lean 4 Proof Assistant emoji: 🔮 colorFrom: yellow colorTo: red sdk: docker app_file: app.py pinned: false --- # Lean 4 Proof Assistant An AI agent that completes formal mathematical proofs in **Lean 4**. Paste a theorem containing `sorry`, and the agent retrieves relevant Mathlib lemmas, drafts a proof with an LLM, and verifies it with the Lean compiler — retrying with error feedback until the proof checks or retries run out. The core guarantee: **only Lean decides correctness.** Every accepted proof is formally verified by the Lean 4 REPL, so the system structurally cannot return a hallucinated proof. **[Try it on Hugging Face Spaces →](https://huggingface.co/spaces/Ray5th/lean4-helper)** ## How it works ```mermaid flowchart LR UI[Gradio UI] --> V[Verify
Lean 4 REPL] V -->|errors / goals| R[Retrieve
LeanDojo ByT5 + FAISS] R -->|top-5 premises| G[Generate
LLM] G -->|candidate proof| V V -->|no goals left| OK([Verified proof]) ``` A LangGraph state machine drives a `verify → retrieve → generate` loop: 1. **Verify** — the file is checked by the Lean 4 REPL (via [lean-interact](https://github.com/augustepoiroux/LeanInteract)) with Mathlib available. Open goals and errors are extracted. 2. **Retrieve** — the current proof state (goals only, canonical `h : T ⊢ goal` form) is embedded with **LeanDojo's pretrained ByT5 premise retriever** and searched against a FAISS index of **180,973 Mathlib premises**. The index is IVFPQ-compressed, so 1.06 GB of raw embeddings ship as a 17 MB file via Git LFS. 3. **Generate** — retrieved premises are passed to the LLM as *optional hints* (RAFT-style distractor-aware framing), and the model must cite which lemmas it actually used (`-- used: Nat.add_comm`). The generated proof goes back to step 1. Lean error messages feed the LLM prompt on retry but are kept out of the retrieval query — the encoder was trained on clean proof states, and error text degrades the embedding. ## Supported models | Provider | Models | Notes | |---|---|---| | **Groq** (default) | `openai/gpt-oss-120b`, `openai/gpt-oss-20b`, `qwen/qwen3-32b`, `meta-llama/llama-4-scout-17b-16e-instruct` | Needs `GROQ_API_KEY` (Space secret / env var) | | **Anthropic** | Claude Opus 4.7 · Sonnet 4.6 · Haiku 4.5 | Bring-your-own key in the UI; never stored | | **Claude CLI** | `claude-cli-opus` etc. | Local `claude -p` subprocess — bills a Claude Pro subscription instead of API credits | ## Running locally ```bash git clone https://github.com/ray5th/lean4-helper && cd lean4-helper pip install -r requirements.txt git lfs pull # fetch the FAISS index python scripts/setup_lean.py # one-time Lean + Mathlib warmup (slow first run) export GROQ_API_KEY=... # or use a Claude key / CLI in the UI python app.py # Gradio UI on :7860 ``` CLI instead of UI: ```bash python scripts/run_agent.py problems/simple_add.lean --model openai/gpt-oss-120b ``` Benchmark on local problem files or MiniF2F: ```bash python scripts/benchmark.py --problems-dir problems --retries 3 --verbose python scripts/benchmark.py --subset 20 --model claude-cli-opus # MiniF2F via HF datasets ``` ## Benchmarks (small-sample, honest numbers) | Set | Result | Notes | |---|---|---| | 16 intro lecture problems (calc / linarith / ring) | 16/16 | 15 solved on first generation | | 6 harder problems (named-lemma, induction, divisibility) | 6/6 | retrieved-lemma citations fired on 4/6 | | MiniF2F sample (5 AMC/AIME problems) | 3/5 | competition-grade; n far too small to quote as a pass rate | ## Project structure ``` app.py Gradio UI (two-pane editor, model picker, logs) src/ langgraph_agent.py verify→retrieve→generate state machine lean_verifier.py Lean 4 REPL wrapper (lean-interact) retriever.py FAISS retrieval over Mathlib premises byt5_embedder.py LeanDojo ByT5 encoder wrapper rag_chain.py prompts + LLM provider routing (Groq/Anthropic/CLI) mathlib_corpus.py Mathlib source → premise extraction scripts/ build_leandojo_index.py build the IVFPQ FAISS index from LeanDojo embeddings benchmark.py pass@k benchmark (local files or MiniF2F) run_agent.py CLI entry point setup_lean.py one-time Lean + Mathlib warmup problems/ sample .lean problems tests/ ~110 unit/fuzz tests (mocked LLM + Lean) ``` ## Testing & CI ```bash python -m unittest discover -s tests # full suite, no API keys or Lean needed ruff check . ``` GitHub Actions runs lint + tests on every push and auto-deploys to the Space on merge to `main` (when `HF_TOKEN` is configured).