axiom-verify
Original:🇺🇸 English
Translated
Verify, check, transform, and repair Lean 4 proofs using the Axiom (Axle) CLI and API. Supports proof verification, syntax checking, theorem extraction, code transformation (rename, merge, simplify), proof repair, and disproving. Use this skill whenever the user works with Lean 4 code, formal mathematics, Mathlib theorems, or mentions axiom, axle, lean verify, proof verification, formal proof, or theorem checking -- even if they don't explicitly say "axiom" but are clearly working with Lean proofs that need machine verification.
21installs
Sourceworkersio/spec
Added on
NPX Install
npx skill4agent add workersio/spec axiom-verifyTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Axiom Lean 4 Proof Verification
Axiom provides cloud-based Lean 4 proof verification through the Axle API. It compiles and checks Lean code against a full Mathlib environment without requiring a local Lean installation -- verification results come back in seconds rather than the minutes it takes to build locally.
Reference Files
Read these as needed based on the task:
- references/axiom-configuration.md -- Setup, authentication, environment selection. Read this first if the user hasn't configured Axiom yet.
- references/axiom-api-reference.md -- All 14 API endpoints with parameters and response formats. Read when you need exact parameter names or response fields.
- references/axiom-cli-reference.md -- CLI commands and options. Read for exact flags and usage details when working with local files.
- references/axiom-best-practices.md -- Workflow guidance, scope limitations, and tips. Read when planning a multi-step workflow or hitting unexpected behavior.
Workflow
Step 1: Select the Right Tool
Match the user's intent to the appropriate endpoint:
| User wants to... | Endpoint | Notes |
|---|---|---|
| Verify a proof is correct | | Checks candidate proof against a formal statement |
| Check if code compiles | | Quick syntax and type checking |
| Understand proof structure | | Splits file into self-contained theorem units |
| Rename declarations | | Automatic reference updates throughout |
| Convert theorem/lemma | | Switch between |
| Stub out proofs | | Replace proofs with |
| Combine files | | Intelligent deduplication across files |
| Remove no-op tactics/haves | | Tactics that don't change proof state, unused haves |
| Remove post-completion tactics | | Tactics after proof is done, replace sorry, fix unsafe tactics |
| Extract have statements | | Promote inline |
| Stub have bodies | | Replace |
| Extract sorry placeholders | | Turn |
| Test if statement is false | | Attempts counterexample via Plausible |
| Standardize formatting | | Clean up sections, namespaces, comments |
When unsure which tool to use:
- Start with to see if the code compiles at all
check - Use to understand what's in the file
extract_theorems - Use first if the file uses
normalize/sectionblocks (these can cause issues with other tools)namespace
Step 2: Execute
When working with local files, prefer the CLI -- it reads files directly from disk, has simpler syntax, and can write output to files with . The CLI reads from the environment automatically. Note: CLI commands use hyphens (e.g., ), while the HTTP API uses underscores (). All code is sent to for compilation against a full Mathlib environment -- the CLI is not local verification.
axle-oAXLE_API_KEYverify-proofverify_proofaxle.axiommath.aiWhen constructing Lean code dynamically (generating content in scripts, CI/CD pipelines, or building code strings programmatically), use the HTTP API via curl or the Python client (). The API accepts content as JSON strings, which is better suited for generated or in-memory code.
pip install axiom-axleCheck code compiles:
bash
axle check file.lean --environment lean-4.28.0 --ignore-importsVerify a proof:
bash
axle verify-proof formal_statement.lean proof.lean \
--environment lean-4.28.0 --ignore-importsRepair broken proofs:
bash
axle repair-proofs file.lean --environment lean-4.28.0 --ignore-imports \
--repairs remove_extraneous_tactics,apply_terminal_tacticsDisprove a conjecture:
bash
axle disprove file.lean --environment lean-4.28.0 --ignore-importsNormalize a file (flatten sections/namespaces):
bash
axle normalize file.lean -o normalized.lean --environment lean-4.28.0 --ignore-importsExtract theorems:
bash
axle extract-theorems file.lean --environment lean-4.28.0 --ignore-importsSimplify theorems:
bash
axle simplify-theorems file.lean --environment lean-4.28.0 --ignore-importsRename declarations:
bash
axle rename file.lean --declarations '{"old_name": "new_name"}' \
--environment lean-4.28.0 --ignore-importsStub proofs with sorry:
bash
axle theorem2sorry file.lean --environment lean-4.28.0 --ignore-importsWrite transformation output to a file (works with normalize, repair-proofs, simplify-theorems, rename, etc.):
bash
axle normalize file.lean -o output.lean -f --environment lean-4.28.0 --ignore-importsAPI example (for dynamically constructed code):
bash
curl -s -X POST https://axle.axiommath.ai/api/v1/check \
-H "Authorization: Bearer $AXLE_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--arg content "$LEAN_CODE" \
'{content: $content, environment: "lean-4.28.0", ignore_imports: true}')" \
| jq '{okay, failed_declarations, lean_errors: .lean_messages.errors, tool_errors: .tool_messages.errors}'For the full CLI command reference, see references/axiom-cli-reference.md. For the full API parameter reference for all 14 endpoints, see references/axiom-api-reference.md.
Step 3: Interpret Results
Every response includes two types of messages -- understanding both is key to helping the user:
- : Direct Lean compiler output. Errors here mean the Lean code itself has problems (type mismatches, tactic failures, unknown identifiers).
lean_messages - : Axle-specific diagnostics. Errors here mean the tool couldn't process the request (import mismatches, unsupported constructs, timeouts). The
tool_messagesfield often contains unsolved goals when a proof fails -- always check this for debugging context.tool_messages.infos
Severity levels:
- Errors: Result may be unusable
- Warnings: Suspicious but non-fatal
- Infos: Timing/debug output, unsolved goals
For : Returns (boolean) and (list). The flag reflects compilation success only -- if the code compiles without errors (warnings like don't affect it). is empty when is . The endpoint does not detect sorry usage or other verification-level issues -- it only checks that code compiles. Use to validate that proofs are complete.
checkokayfailed_declarationsokaytruesorryfailed_declarationsokaytruecheckverify_proofFor : Returns (boolean) and (list). The flag reflects proof validity -- only if the code compiles and passes all verification checks (no sorry, signatures match, no disallowed axioms). Note the distinction:
verify_proofokayfailed_declarationsokaytrue- Compilation errors (tactic failures, syntax errors, name collisions): is
okay,falseis empty. The errors appear infailed_declarations.lean_messages.errors - Verification failures (sorry usage, signature mismatch, disallowed axioms): is
okay, and the offending names appear infalsewith details infailed_declarations.tool_messages.errors - Fully valid proof: is
okayandtrueis empty. This is the only state that means the proof is both compilable and complete.failed_declarations
For transformation tools (, , , etc.): These do not return or . Check that is empty and inspect the field for the transformed result.
repair_proofssimplify_theoremsnormalizeokayfailed_declarationslean_messages.errorscontentFor : Check (list of refuted names) and (dict mapping each theorem name to a human-readable outcome string). If a counterexample is found, the name appears in and the entry contains the counterexample. If disprove fails (the theorem may be true), is empty and the entry describes why the negation could not be proven.
disprovedisproved_theoremsresultsdisproved_theoremsresultsdisproved_theoremsresultsImport handling: Always use (CLI) or (API) unless you have a specific reason not to (e.g., testing that exact imports are correct). Without this flag, import mismatches return a string instead of the standard response format, which breaks JSON parsing and hides the actual verification result. Code snippets, code from different Lean/Mathlib versions, and proof-logic checks all require this flag.
--ignore-imports"ignore_imports": trueuser_erroruser_error{"user_error": "...", "info": {...}}ignore_importsrenameuser_errorlean_messagestool_messagesCommon Multi-Step Workflows
Verify and fix a proof:
- -- see if it compiles
check - If errors: -- attempt automatic fix
repair_proofs - again -- verify the repair worked
check - -- confirm it proves the intended statement
verify_proof
Analyze and clean a file:
- -- standardize formatting first (flatten sections/namespaces)
normalize - -- understand the structure
extract_theorems - with
repair_proofs-- remove tactics after proof is already completeremove_extraneous_tactics - -- remove unused haves and no-op tactics
simplify_theorems - -- verify nothing broke
check
Scaffold a proof development:
- Write formal statements
- -- stub out proofs with
theorem2sorry(usesorryparameter to target specific theorems)names - Fill in proofs incrementally
- after each proof to verify progress
check - -- track remaining obligations (generates
sorry2lemmalemma stubs inserted before each sorry'd theorem){name}.sorried - for final verification
verify_proof
Test a conjecture:
- -- look for counterexamples first
disprove - If no counterexample found, attempt the proof
- incrementally as you build the proof
check - when complete
verify_proof
Common Pitfalls
- Custom project attributes and constructs. Files from Lean projects often define custom attributes (e.g., ) and helper constructs (e.g.,
@[category research open, AMS 11]) via project-specific imports. Whenanswer(sorry)replaces those imports with standard Mathlib, these custom constructs become unresolvable and produce compilation errors. Before submitting, strip custom attributes and project-specific constructs using sed or similar:ignore_imports: trueremovessed 's/@\[category [^]]*\]//' file.leanblocks; replace@[category ...]withanswer(sorry)or remove it entirely. Note:Truetriggers a misleading "Candidate uses banned 'open private' command" tool error because the parser misinterprets the word@[category ... open ...]inside the attribute as theopencommand -- this is a false positive that disappears once the attribute is stripped.open private - is off in Mathlib environments. Always declare type variables explicitly (e.g.,
autoImplicitorvariable {α : Type*}). Implicit variables like(α : Type*)without declaringList αwill fail.α - Mathlib name shadowing. If your theorem names match existing Mathlib declarations (e.g., ,
add_zero,add_comm), you'll get "already declared" errors and all transformation tools will silently return unchanged content with zero stats. The error appears only inmul_comm, notlean_messages.errors-- you must inspecttool_messagesto notice the problem. Uselean_messagesto give theorems unique names, or prefix with a namespace.rename - cannot see through opaque definitions. The
omegatactic works on linear arithmetic overomegaandNat, but it treats user-defined functions as opaque. If you defineIntand try to provedef my_double (n : Nat) := n + nwithmy_double n = 2 * n, it will fail becauseomegadoesn't know whatomegacomputes. Usemy_double(orunfold my_double) beforesimp [my_double]to expose the definition.omega - vs
simplify_theoremsfor cleanup. These serve different purposes:repair_proofs- with
simplify_theorems: removes tactics that are no-ops (don't change the proof state at all)remove_unused_tactics - with
repair_proofs: removes tactics that appear after the proof is already completeremove_extraneous_tactics - For cleaning up redundant tactics, you usually want first, then
repair_proofs.simplify_theorems
- Sections and namespaces. ,
extract_theorems, and other transformation tools may produce non-compilable output when sections/namespaces are present because extracted names won't be fully qualified. Always runtheorem2sorryfirst to flatten these constructs. Note thatnormalizepreserves the original indentation from inside flattened blocks -- the output may look oddly indented but still compiles correctly. Caveat:normalizemay not update all references inside theorem bodies when flattening namespaces (e.g.,normalizemay not becomep k). AlwaysNamespace.p kthe normalized output and fix any unresolved references manually.check - requires fully-qualified names. The
renameparameter must use fully-qualified names including namespace prefixes. For example, ifdeclarationsis insidemy_thm, usenamespace Foo, not{"Foo.my_thm": "Foo.new_name"}. Using an unqualified name returns a{"my_thm": "new_name"}("Source name not found").user_error - Non-theorem commands in . The
extract_theoremstool warns about any non-theorem command it encounters withextract_theorems. This includes"Unsupported command kind ...",variable,open,notation, and other non-declaration commands. These warnings are informational -- the tool still correctly extracts all theorem declarations and includes dependencies (includingset_optionbindings,variablestatements, etc.) in each theorem's standaloneopenblock.content - Always check both message types. Transformation tools can "succeed" (return content with zero errors) while the underlying code has compilation errors visible only in
tool_messages. Always inspectlean_messages.errorseven whenlean_messages.errorsis clean. This silent failure mode applies broadly: any compilation error (custom attributes, missing imports, syntax issues, name shadowing) causes transformation tools to return unchanged content with zero stats. The only signal is non-emptytool_messages.lean_messages.errors - The environments endpoint uses (no
/v1/environmentsprefix), while all tool endpoints use/api/./api/v1/{tool_name}