`ml-hilbert`: The theorem prover that thinks in sketches first
How a recursive Python orchestrator turns informal reasoning, Lean 4 verification, and `sorry` placeholders into a divide-and-conquer system for formal mathematics.
- Hilbert treats proof as a staged reasoning workflow, not a single generation step.
- Its core trick is recursive decomposition, where long proofs become smaller claims that can be checked and reassembled.
- `sorry` is used as a controlled placeholder during partial verification, not as an excuse to skip rigor.
- The project is built for throughput and reproducibility, which makes it read like research infrastructure rather than a polished product.
Most theorem provers ask an LLM to jump straight from theorem statement to final proof. Hilbert takes the slower route on purpose. It asks for an informal sketch first, then breaks the problem into subgoals, then lets Lean 4 decide whether each piece really holds.
That matters because hard proofs are rarely linear. Human mathematicians do not start with the finished term. They sketch, prune, recurse, and only later clean up the formal details. Hilbert tries to encode that workflow instead of pretending it does not exist.
Why Hilbert feels different from a normal prover
The repo is a research framework for `ml-hilbert`, a Lean 4 system built around recursive informal reasoning. Its job is not just to produce proofs. Its job is to turn proof search into something closer to mathematical thinking.
That is why the system tolerates partial work. The model can draft an informal explanation, extract smaller claims, and leave holes behind while the rest of the tree keeps moving. The point is not to fake certainty. The point is to keep the search alive long enough to earn certainty.
The recursive proof loop
The central loop is simple to say and tricky to build. If a proof looks too long or too tangled, Hilbert cuts it apart. A worker generates an informal sketch, turns that sketch into subgoals, tries to formalize them, and recurses on the children until Lean accepts the pieces.
The important part is the feedback loop. Lean does not just bless or reject the whole attempt. It sends the worker back into correction mode, where the proof sketch gets revised and rechecked. That turns verification into an iterative search process instead of a one-shot gamble.
Why `sorry` is not cheating here
In ordinary Lean usage, `sorry` is a last resort. In Hilbert, it becomes a disciplined boundary marker. The system distinguishes between proofs that are correct with placeholders and proofs that are complete without them, which lets it keep partial structure while the missing pieces are still under construction.
That distinction is the key to the whole design. A theorem can be useful before it is finished, as long as the system knows which parts are real and which parts are provisional. Hilbert turns incompleteness into a tracked state, not a hidden flaw.
| Dimension | Direct prover | Hilbert |
|---|---|---|
| First move | Jump straight from theorem to proof text | Write an informal sketch first |
| Handling long proofs | Hope the model fits everything in one shot | Split into recursive subgoals |
| Error recovery | Regenerate or fail | Patch Lean syntax and retry |
| Context use | Prompt and current theorem only | Prompt plus retrieved similar informal problems |
| Throughput | Single path exploration | Parallel workers with async verification |
| Mental model | Generate the answer | Build the answer from steps |
| Failure mode | One bad generation can sink the run | A failed branch can be isolated and rerouted |
That is also why the project feels closer to software engineering than to magic. There is a state machine underneath the math. The system keeps track of what is proven, what is provisional, and what still needs a human-style explanation before Lean will accept it.
Async is the quiet superpower
The repo does not rely on a single proof attempt at a time. `AsyncJobPool`, `AsyncHILBERT`, and fresh client factories let the system fan out across multiple branches while Lean verification and model inference happen in parallel. In theorem proving, latency is the enemy. Async design is how the project keeps the search moving.
That matters because each branch can fail for a different reason. One may need syntax repair. Another may need a better sketch. A third may simply be a dead end. Parallelism lets Hilbert learn that faster.
You can see the throughput-first mindset in the architecture: one coordinator, many workers, separate verification clients, and telemetry that watches the proof tree evolve over time. This is not a monolithic prover. It is a distributed search process.
What the retrieval layer adds
Hilbert also tries to look things up before it reasons. The semantic search layer embeds informal problem descriptions and retrieves similar items from `mathlib_informal.jsonl`, which gives the model nearby examples instead of forcing it to start from scratch every time.
That is a strong fit for mathematics. Mathematicians do not invent all structure from first principles on every theorem. They remember analogues, patterns, and prior lemmas. Retrieval gives the model a rough version of that memory.
How Hilbert compares to a direct prover
| Dimension | Direct prompt-to-proof | Hilbert |
|---|---|---|
| Reasoning style | Single-pass generation | Informal sketch, then formalization |
| Search shape | Flat | Recursive tree |
| Verification | All-or-nothing | Partial first, complete later |
| Context strategy | Prompt engineering | Prompt plus retrieval plus subgoals |
| Engineering focus | Model quality | Orchestration quality |
| Best use case | Short, local proofs | Longer proofs that benefit from decomposition |
The contrast is not subtle. Direct provers treat the proof as an output artifact. Hilbert treats it as a process. That shift in framing is the whole project.
What kind of project this really is
This is a research artifact built for reproducibility, not a product with an aggressive roadmap. The original repository explicitly says it is not in active development and points readers toward the active fork at Rose-STL-Lab/ml-hilbert. That makes the codebase feel more like a published method than a platform.
The upside is clarity. The repo tells you what it is for, what it is not for, and where to look if you want to extend it. The project invites out-of-tree improvements, but it does not pretend to be a finished commercial system.





