satp-policy-v4.27

A 0.2B ByT5 policy that reads a Lean 4 goal state and emits a per-problem aesop configuration — search budget, rule-set options, and extra tactic and lemma rules. This repository is a self-contained inference bundle: checkpoint plus a standalone infer.py (no training-repo dependencies), forward-equivalent to the training policy. Everything runs in a Lean 4 v4.27.0 environment.

Interim checkpoint (uploaded 2026-07-27). This is the validation-best of a 40-epoch run that is still training, not a final release. It will be replaced if a later checkpoint sets a new validation best.

Results

miniF2F, greedy decode, all 244 problems of each split, Lean 4 v4.27.0. Statements are submitted raw, at Lean's default maxHeartbeats 200000. The dataset is ChristianZ97/minif2f-satp-v4.27, pinned by infer.py at revision 94424f13 and overridable with SATP_DATASET_REVISION.

split solved
test 41.0% (100/244)
validation 42.2% (103/244)
configuration (test) solved
satp 41.0% (100/244)
w/ default search budget 41.0% (100/244)
w/o additional tactic 38.1% (93/244)
w/o additional lemma 32.0% (78/244)
distilled static configuration (tactic only) 30.7% (75/244)
aesop 12.7% (31/244)
Expert-tuned aesop (from DSP+, w/o BFS) 34.0% (83/244)

The first four rows are one greedy decode per problem through infer.py, verified on Kimina; validation reproduces the training-time best, 103/244. The rest use no policy: the static configuration is distilled from the validation decodes and measured on test, and aesop and Expert-tuned aesop are baselines. Every Kimina count was re-checked under lake env lean and matched; the expert-tuned row is lake env lean only.

Checkpoint

run mv53kefx (wandb), seed 1827 — validation-best at ~epoch 5 of a 40-epoch run; the run had reached ~epoch 24 when this was uploaded
verifier Kimina-Lean Server, Lean 4 v4.27.0
training data ChristianZ97/NuminaMath-LEAN-satp-v4.27 (75,008 problems; 5,000 subsampled per epoch)
architecture ReProver's Retrieval Encoder+LoRA(r16,α32,q/k/v/o) mean-pool → shared MLP → 69-head joint action (28 tactic ×10-way + 32 lemma ×172-way + 4 config_level + 5 config_binary) + dense premise retrieval

The 172-way lemma decision is off + 19 hosts × 3 type × 3 priority. positivity appears as a tactic rule and has no lemma host.

Distilled static configuration

One constant configuration for every problem, lemma rules off. Each value is the per-head mode over the 244 validation decodes; -- % is how often that mode was chosen (joint 10-way: off | type×priority).

  aesop (config := {
    maxRuleApplications := 2400            -- 55%
    maxRuleApplicationDepth := 60          -- 64%
    maxNormIterations := 800               -- 45%
    maxGoals := 32                         -- 64%
    enableSimp := false                    -- 70%
  })
    (add norm 100 (by ring))               -- 70%
    (add norm 100 (by field_simp))         -- 50%
    (add norm 100 (by norm_cast))          -- 65%
    (add norm 1 (by linarith))             -- 100%
    (add norm 0 (by nlinarith))            -- 100%
    (add norm 100 (by abel))               -- 54%
    (add norm 0 (by bound))                -- 100%
    (add norm 100 (by exfalso))            -- 100%
    (add norm 0 (by simp_all))             -- 84%
    (add norm 1 (by field_simp [*] at *))  -- 50%
    (add norm 100 (by norm_cast at *))     -- 100%
    (add norm 0 (by decide))               -- 96%
    (add norm 100 (by push_cast))          -- 100%
    (add safe 0 (by positivity))           -- 98%
    (add safe 0 (by push_neg))             -- 97%
    (add safe 100 (by zify))               -- 98%
    (add safe 0 (by interval_cases))       -- 100%
    (add safe 0 (by ext))                  -- 100%
    (add safe 1 (by split))                -- 100%
    (add safe 0 (by simp))                 -- 82%
    (add safe 0 (by norm_num [*] at *))    -- 100%
    (add unsafe 10% (by norm_num))         -- 100%

Modes that came out off: gcongr 100%, rfl 100%, assumption_mod_cast 100%, ring_nf at * 94%, ring_nf 88%, omega 59%. Binary options: enableSimp F 70%, useSimpAll T 79%, enableUnfold T 97%, useDefaultSimpSet T 74%, enableBuiltin T 84%. Priorities are integers, smaller = higher (0 first, 100 last); unsafe = success %.

Expert-tuned aesop (from DSP+, w/o BFS)

DSP+'s hand-tuned aesop configuration, taken verbatim from microsoft/DSP-Plus@eb98320: the two model-free attempts of bfsaesopLoop plus its 16 add_aesop_rules. Its third attempt, bfsaesop, runs a 7B prover inside the search and is excluded.

Same 244 test problems, same Lean 4.27 toolchain, lake env lean (rc 0, no sorryAx).

configuration solved
aesop 12.7% (31/244)
Expert-tuned aesop, this card's protocol (300 s, maxRecDepth 512) 34.0% (83/244)
Expert-tuned aesop, DSP+ source limits (1200 s, maxRecDepth 1024) 34.8% (85/244)
satp 41.0% (100/244)

Both limits are given; only maxRecDepth separates them. DSP+ reports 35.2% for this configuration on its own Lean 4 v4.17-rc1 snapshot.

Files

best_checkpoint.pt            # 1.07 GB — infer.py reads model_state_dict only
infer.py                      # load → retrieve → greedy-decode → Kimina verify
reproduce.py                  # test-split repro, kimina | lake verifier (imports infer.py)
cache/premise_embeddings.npy  # 1.0 GB — 180,957 × 1472 premise embeddings
cache/mathlib4_premises.txt   # 38 MB — premise names, index-aligned

Premise corpus = LeanDojo Benchmark-4 v10; embeddings come from the frozen retriever → verifier-version independent. ByT5 base auto-downloads on first run.

Run

pip install torch transformers numpy requests huggingface_hub datasets
hf download ChristianZ97/satp-policy-v4.27 --local-dir satp-policy-v4.27
cd satp-policy-v4.27
KIMINA_URL=http://localhost:8000 python infer.py

The Kimina server must run a Lean 4 v4.27.0 workspace.

var default meaning
KIMINA_URL http://localhost:8000 Kimina /verify endpoint
SATP_SPLIT validation or test
SATP_DATASET_REVISION 94424f13… dataset commit infer.py resolves (pinned)
SATP_LIMIT 0 >0 → first N problems only
SATP_CKPT ./best_checkpoint.pt checkpoint path
SATP_CACHE ./cache premise files dir
SATP_HEARTBEATS0 unset 1 removes the heartbeat cap; reported numbers use the default
SATP_LEAN_TIMEOUT 300 server-side Lean timeout (s); HTTP timeout = +60

Verification is sequential (one POST per problem, retried with backoff). Header-less statements get the training header prepended.

Reproduce

reproduce.py re-runs the miniF2F test split end-to-end over the same greedy decode and checks the result against 100/244 (SATP_SPLIT=validation targets 103/244), with either verifier:

KIMINA_URL=http://localhost:8000 python reproduce.py kimina
SATP_LAKE_DIR=/path/to/lean-v4.27-project python reproduce.py lake   # no server

lake runs one lake env lean per problem (300 s timeout) inside any Lean 4 v4.27 project with Mathlib built; writes reproduce_<backend>.jsonl ({name, success, tactic, code} per problem). Greedy decode is deterministic.

Downloads last month

-

Downloads are not tracked for this model. How to track
Video Preview
loading

Paper for ChristianZ97/satp-policy-v4.27