A proof language

Specifications and proofs, independently checked

Metamath Zero is designed so that a reader can see exactly what a theorem claims, and a small, independent verifier can confirm its proof.

verified
-- the language of propositional logic, and its rules
sort wff;
term im (p q: wff): wff;   infixr im: $->$ prec 25;
term not (p: wff): wff;    prefix not: $~$ prec 41;

axiom ax_1 (a b: wff): $ a -> b -> a $;
axiom ax_2 (a b c: wff): $ (a -> b -> c) -> (a -> b) -> a -> c $;
axiom ax_mp (a b: wff): $ a -> b $ > $ a $ > $ b $;

-- a claim, with no proof attached: this file only states it
theorem id (a: wff): $ a -> a $;

A specification states what is true; a proof establishes it; a program can itself be the subject of a theorem — and the same verifier checks all three. Colours carry the ecosystem's meanings: terms, axioms, theorems, hypotheses.

How it works

One step you have to trust

Everything that produces a proof is untrusted. Only the verifier has to be believed — and it is small enough to read.

untrusted — anything may produce these MM1 you write MM0 the spec MMB the proof

A trusted core you can audit

The reference verifier, mm0-c, is under 3,000 lines of C. You don't have to trust the tools that wrote a proof — only the small program that checks it, and you can read all of it.

No built-in foundation

MM0 fixes no logic of its own. You supply the axioms — set theory, higher-order logic, type theory, Peano arithmetic — and it checks proofs in the system you defined.

Proof, not proof-script

A finished proof is a file, not a session in someone's editor. The untrusted MM1 compiler produces it; the verifier re-checks every step from scratch, knowing nothing about how it was found.

Fast verification

Checking is close to the cost of reading the file. A full library verifies in seconds rather than minutes, so re-checking an entire development is routine rather than a bottleneck.

Verified down to the machine

The project's goal theorem is a verifier for MM0, proved correct in MM0 itself, down to the x86 instructions it runs on — so the trust base terminates in a verified artifact rather than an assumption.

A root of trust

A small trusted kernel matters for what is built on it. MM0 is intended as a common substrate: other proof systems can translate their results into it and have them re-checked, terminating in a verifier that is itself proved correct.

Tools

The tools run in the browser

The verifier is small enough to compile to WebAssembly. Nothing is uploaded; every file is checked in the tab it's opened in.

Install

Build the toolchain

  1. Get the compiler and language server (needs Rust):
    # clone and build mm0-rs
    git clone https://github.com/digama0/mm0
    cd mm0/mm0-rs
    cargo build --release
  2. Add the editor integration:
    # the "Metamath Zero" VS Code extension
    code --install-extension digama0.metamath-zero
  3. Want the smallest possible checker? The reference verifier is a single C file:
    # build mm0-c and check a proof
    gcc mm0-c/main.c -O2 -o mm0-c
    ./mm0-c proof.mmb < spec.mm0

Trust

No single point of trust

Because the format is small and precisely specified, more than one program can play the role of "the verifier" — so no single implementation has to be believed.

Independent verifiers

What has been built in it

  • Peano arithmetic — the base library, formalized for real use.
  • The x86 architecture — a machine-code semantics, the MMC compiler's target.
  • The MMC compiler — producing MM0 proofs about the programs it compiles.
  • MM0 itself — a full formal spec of the format and its verification.

The endpoint: verifier.mm1, a proof that an MM0 verifier is correct — checked by an MM0 verifier.