Writing verifiers and solutions
A verifier decides, by machine, whether a solution is correct. Pick the language you want to work in.
The verifier
A verifier is one Python module that defines
def verify(solution: str, rng: numpy.random.Generator) -> bool:
It gets the candidate solution as a string and must return the literal True if and only if it is correct. Anything else -- False, an exception, a timeout, 1, printing "ACCEPTED" -- is a rejection. Put the solution format you expect in the module docstring so solvers know what to submit.
- Parse defensively: strip whitespace, reject wrong arity, empty or malformed input, trivial answers. Never let bad input raise -- return
False. - Check the whole claim, not a heuristic. No prints, no side effects, no global state.
- Need randomness (random test cases)? Draw from
rngonly, so every verdict is reproducible from its seed.
What a verifier can use
Python 3.12, the standard library, and numpy, scipy, sympy, mpmath -- nothing else can be imported. It runs in a sandbox with no network, a read-only filesystem and no writable directory: do not read or write files or spawn processes. It must finish, imports included, within the time and memory budget the author declares when publishing; design for a small one (10 s / 256 MB is typical).
The solution
Plain text, in whatever format the verifier's docstring asks for (at most 64 KB). Paste it or upload a file on the problem page, pick the verifier, and the verdict arrives within that verifier's time budget. Only an ACCEPTED solution can be listed for sale.
Try it: the Python demo problems
Nothing on a demo problem involves money: every bid, ask and trade on it is fake, and a practice bot already holds a standing bid on each one. Post a solution, get your verdict, list an ask and watch it trade -- the whole loop, with no stakes.
- Python demo: 5 + 4 DEMO
A solution that passes
9
A solution that passes
17 23
The verifier
In Lean the verifier is a type, and the checker is the Lean kernel -- there is no function to write. A verifier is a module named Verifier defining one root-level constant:
abbrev Spec : Prop := 2 + 2 = 4 -- a statement to prove, or
def Spec : Type := { p : Nat × Nat // p.1 * p.2 = 391 ∧ 1 < p.1 ∧ 1 < p.2 } -- an object to produce
Spec : Propasks for a proof;Spec : Type(typically a subtype) asks for a witness together with the proof it qualifies.- Write
Specwithabbrevwhen tactics such asdecideornorm_nummust see through it; a plaindefleaves the goal opaque to them. - Helper definitions and lemmas can live in the same file, above
Spec. The verifier is held to the same axiom rules as solutions: asorryin a helper lemma fails the build.
The solution
A module named Solution defining a root-level constant answer : Spec:
import Verifier
theorem answer : Spec := by decide -- Prop
def answer : Spec := ⟨(17, 23), by decide⟩ -- Type
import Verifier brings Spec into scope (you may also restate the type verbatim; the kernel compares types, not text). Accepted iff the module elaborates, the kernel accepts answer : Spec, and the proof's axioms are within the allowlist -- propext, Classical.choice, Quot.sound. So sorry, your own axioms and native_decide are all rejected (a verifier may widen the list with a first-line comment such as -- judge: allow Lean.ofReduceBool). Every elaboration-time trick -- run_cmd, debug.skipKernelTC, redefining Spec -- is caught by an independent kernel replay.
What is available
Core Lean, and Mathlib: import Mathlib.Tactic.NormNum.Prime (or any other Mathlib module) works in both the verifier and the solution, from a pinned Mathlib build inside the sandbox. Importing Mathlib costs real time and memory, so a verifier that needs it should be published with a larger budget (a few minutes, a few GB) than a core-only one. No network, no files, no randomness: a verdict depends only on the two modules and the pinned image. Solutions are at most 64 KB.
Try it: the Lean demo problems
Nothing on a demo problem involves money: every bid, ask and trade on it is fake, and a practice bot already holds a standing bid on each one. Post a solution, get your verdict, list an ask and watch it trade -- the whole loop, with no stakes.
A solution that passes
import Verifier def answer : Spec := ⟨(17, 23), by decide⟩
A solution that passes
import Verifier theorem answer : Spec := by norm_num
- Lean demo: 2 + 2 = 4 DEMO
A solution that passes
import Verifier theorem answer : Spec := by decide