Form Language Specification
The Form language is a domain-specific language for defining verified state machines that compile to WebAssembly. A Form consists of three components: state declarations that define the typed variables of the machine, invariant declarations that define predicates which must hold after every transition, and transition declarations that define the named state mutations with preconditions and updates. The compiler proves that every transition preserves every invariant, then emits minimal WASM where proven properties are erased from the output.
Structure of a Form
Every Form definition follows a fixed structure. The form keyword introduces the name. Within the body, three declaration blocks appear: state for typed variable declarations, invariant for named predicates over the state, and transition for named state mutations. The compiler processes these blocks in order: it first builds the type environment from the state block, then registers invariants as proof obligations, then analyzes each transition to discharge those obligations.
form Token { state { balance : Nat per Address supply : Nat owner : Address } invariant conservation : sum(balance) == supply transition transfer(from, to, amount) { require balance[from] >= amount balance[from] -= amount balance[to] += amount } -- conservation proven by arithmetic identity -- sum(balance') = sum(balance) - amount + amount = supply transition mint(to, amount) { require msg.sender == owner balance[to] += amount supply += amount } -- sum(balance') = sum(balance) + amount = supply + amount = supply' transition burn(from, amount) { require balance[from] >= amount balance[from] -= amount supply -= amount } -- sum(balance') = sum(balance) - amount = supply - amount = supply' }
Table of Contents
- Type System base types, parameterized types, per-address quantification, typing rules
- Invariant Algebra conservation, monotonicity, access control, boundedness, state machine
- Transition Semantics preconditions, updates, proof obligation generation
- Verification Rules proof methods, counterexamples, complete verification traces
- WASM Compilation lowering, erasure, target adaptation, annotated output
Core Definitions
per Address creates an implicit Map(Address, T).require preconditions, and a sequence of state updates. The compiler generates a proof obligation for every (transition, invariant) pair, requiring that if the invariant holds before the transition and the preconditions hold, then the invariant holds after.require clauses that depend on runtime values (caller identity, message value, block time) survive as WASM instructions.Compilation Pipeline
The compiler processes a Form in five sequential phases:
1. Parsing. The Form source text is parsed into an abstract syntax tree. State fields, invariants, and transitions are extracted as structured declarations.
2. Type checking. Each state field is assigned its declared type. Transition parameters are typed by inference from their usage. Type rules enforce closure of arithmetic operations and compatibility of comparisons. See Type System.
3. Invariant classification. Each invariant is classified by its algebraic structure (conservation, monotonicity, access control, boundedness, state machine). The class determines the proof method. See Invariant Algebra.
4. Verification. For every (transition, invariant) pair, the compiler generates and discharges a proof obligation. If any obligation cannot be discharged, compilation fails with a counterexample. See Verification Rules.
5. Code generation. The verified Form is lowered to WASM linear memory layout, proven invariants are erased, and target-specific entry points and ABI encoding are emitted. See WASM Compilation.