Syntax guide
- Status: active
- Audience: users, contributors
- Authority: user-facing syntax reference for current shipped input surface; subordinate to QED formal specification, current code/tests, and User manual
- Scope: current theorem-script surface syntax, CLI-facing file shape, supported proof steps, and known unsupported forms
- Last reviewed: 2026-04-20
This document is a quick reference for QED’s current shipped user input syntax.
It answers only one question: what kind of theorem script does src/cmd currently accept. For
capability boundaries, the support matrix, failure semantics, and the implementation contract,
User manual remains the main entry point.
Quick start
The current command-line entry point is:
moon run src/cmd <file>
moon run src/cmd -- -d <file>
moon run src/cmd -- --no-warn <file>
-d prints the full conclusion summary. --no-warn returns a success exit code when there are only
warnings and no errors. When launching through moon run, use -- to forward the remaining
arguments to the QED CLI; once compiled into a standalone executable, you can run
qed-cmd -d --no-warn <file> directly.
The input is a theorem-script file, for example:
theorem truth_file : ⊢ T := by exact truth
Runnable examples in the repository:
examples/truth_file.qedexamples/demo_and.qedexamples/and_comm.qedexamples/multi_theorems.qedexamples/multi_with_hole.qedexamples/bad_branch.qedexamples/unfinished_branch.qed
The repository root also has prelude/, which holds theorem asset files that can be run directly;
they are runnable scripts, not the public surface of the current theorem-name catalog.
File shape
The current shipped theorem script shape is:
theorem <name> [(binder...)] : <goal> := by <steps>
When a file contains several theorems, end each preceding theorem block with a lowercase qed:
theorem t1 : ⊢ T := by exact truth
qed
theorem t2 : ⊢ T := by exact truth
qed
Where:
<name>is the theorem name.[(binder...)]currently supports zero or more theorem-header binders.<goal>is a sequent.<steps>are the proof steps, written either in single-line sequential form or in newline-separated block form.
For compatibility with existing examples, a single-theorem file may omit the trailing qed. In a
multi-theorem file, each preceding theorem must be followed by qed before the next top-level
theorem.
Theorem header
Theorem name
Minimal example:
theorem truth_file : ⊢ T := by exact truth
Theorem-header binders
The current shipped binder form is:
(x : bool)
For example:
theorem id_bool (x : bool) : ⊢ x -> x := by
intro h
exact h
qed
The safest file-first usage in the current documentation and examples is to start with bool
binders.
Currently supported quantified goals
A raw forall theorem goal like the following is now accepted as goal-only sugar:
theorem quant_raw_intro_ok : ⊢ forall (x : bool), x -> x := by
intro h
exact h
qed
The parenthesized form is also accepted:
theorem quant_raw_intro_paren_ok : ⊢ (forall (x : bool), x -> x) := by
intro h
exact h
qed
In other words:
- Theorem-header binders
(x : bool)and rawforall/∀theorem goals are both part of the currently shipped quantifier-facing user syntax. - Raw
forall (x : A), body/∀ (x : A), bodyis accepted only at the theorem-script goal /parse_goalentry points; it is not term-level syntax. - The raw
forallpath is currently only goal sugar; it follows the same lowering / replay / CLI diagnostics contract and introduces no new kernel quantifier authority.
Goal shape
The current shipped surface uses sequent goals:
⊢ goal
A ⊢ B
A, B ⊢ goal
The minimal runnable examples in the README and examples/ mainly use:
⊢ T⊢ x -> x⊢ x -> x ∧ x⊢ x -> x ∨ x
For first-time CLI users, it is safest to start with state-free examples using T, F, and
theorem-header binders.
Proof steps
The current shipped steps are only these:
introexactapplyassumptionsplitleftrighthole
intro
intro h
When the current goal is A -> B, introduces a local hypothesis and continues by proving the
consequent.
exact
exact h
exact truth
Closes the current goal directly.
apply
apply and_elim_l
Applies an implication-backed theorem or a local implication hypothesis to the current goal, producing new subgoals.
assumption
assumption
Searches the current local hypotheses for evidence that matches the current goal.
split
Sequential form:
split
Structured branch form:
split { exact h } { exact h }
left / right
Sequential form:
left
right
Structured branch form:
left { exact h }
right { right { hole h1 } }
hole
hole
hole h1
hole does not fake success; it currently returns a structured unfinished result.
Sequential blocks and structured branch blocks
<steps> can currently be written on a single line:
theorem t1 (x : bool) : ⊢ x -> x := by intro h; exact h
or as a multi-line block:
theorem t1 (x : bool) : ⊢ x -> x := by
intro h
exact h
qed
When steps need explicit branching, a minimal structured branch block is currently supported:
theorem demo_and (x : bool) : ⊢ x -> x ∧ x := by
intro h
split { exact h } { exact h }
qed
An example closer to classical propositional logic:
theorem and_comm (p : bool) (q : bool) : ⊢ p ∧ q -> q ∧ p := by
intro h
split { exact and_elim_r } { exact and_elim_l }
qed
theorem bad_branch (x : bool) : ⊢ x -> x ∨ x := by
intro h
left { exact truth }
qed
Most important current limitations
- The current
src/cmdworkflow is file-first; a single-theorem file may omit the trailingqed, and a multi-theorem file usesqedas a separator. - Directly runnable public examples should preferably use the existing scripts in
examples/. - Theorem-header binders are shipped; raw
foralltheorem goals are supported as goal-only sugar, while term-level forms are still unsupported. - Unsupported paths must fail closed and never fake theorem success.
holereturns unfinished, not theorem success.
Output shape
Current CLI output falls into three categories:
- Success: by default, one line
ok <theorem_name>per theorem; with-d, the output isok <theorem_name>: <conclusion_summary> - Failure:
error[kind] ... - Unfinished:
warning[unfinished] ...; it produces no theorem authority, but checking continues with the following theorems.
The -- in moon run src/cmd -- -d --no-warn <file> belongs only to moon run argument
forwarding; a standalone executable does not need it, so run qed-cmd -d --no-warn <file> directly.
See User manual for the complete failure fields, unfinished fields, and stable examples.