Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

The formal core, v1 and v2

nazm.formal-core/1 — N61, 2026-10-02. This document is the semantics; crates/nazm-formal is it transcribed rule by rule (each rule’s name is a comment on its arm), and crates/nazm-formal/tests/exhaustive.rs checks the properties below over every program of the core up to a stated size. It is a bounded, machine-checked model, not a proof: nothing outside the bound is established, and no proof assistant was used.

Syntax

e ::= n                      integer literal, n ∈ [-2^63, 2^63)
    | true | false
    | x                      a bound name
    | e + e | e - e | e * e | e / e | e % e
    | e < e | e == e
    | !e | e && e
    | if e { e } else { e }
    | let x = e; e

A core program is one expression, the body of fn main() -> T. It is printed to Nazm source by nazm_formal::to_source and so is also a Nazm program — that is the correspondence.

Types

τ ::= Int | Bool. Γ maps names to types.

rule
T-IntΓ ⊢ n : Int
T-BoolΓ ⊢ true : Bool, Γ ⊢ false : Bool
T-VarΓ(x) = τ ⟹ Γ ⊢ x : τ
T-ArithΓ ⊢ a : Int, Γ ⊢ b : Int ⟹ Γ ⊢ a ⊕ b : Int, ⊕ ∈ {+,-,*,/,%}
T-LtΓ ⊢ a : Int, Γ ⊢ b : Int ⟹ Γ ⊢ a < b : Bool
T-EqΓ ⊢ a : τ, Γ ⊢ b : τ ⟹ Γ ⊢ a == b : Bool
T-NotΓ ⊢ a : Bool ⟹ Γ ⊢ !a : Bool
T-AndΓ ⊢ a : Bool, Γ ⊢ b : Bool ⟹ Γ ⊢ a && b : Bool
T-IfΓ ⊢ c : Bool, Γ ⊢ a : τ, Γ ⊢ b : τ ⟹ Γ ⊢ if c { a } else { b } : τ
T-LetΓ ⊢ a : σ, Γ[x ↦ σ] ⊢ b : τ ⟹ Γ ⊢ let x = a; b : τ

Evaluation (big step)

Outcomes r ::= v | trap(c), values v ::= n | true | false, c ∈ {N0400, N0401}. ρ maps names to values. Evaluation is left to right; a trap propagates.

rule
E-Litρ ⊢ n ⇓ n, ρ ⊢ true ⇓ true, ρ ⊢ false ⇓ false
E-Varρ ⊢ x ⇓ ρ(x)
E-Arithρ ⊢ a ⇓ m, ρ ⊢ b ⇓ k ⟹ ρ ⊢ a ⊕ b ⇓ m ⊕ k when the mathematical result is in range, else trap(N0400)
E-Div/ and % truncate toward zero; k = 0 is trap(N0401); i64::MIN / -1 is trap(N0400); i64::MIN % -1 is 0, which is representable (docs/spec.md)
E-Lt, E-Eqcompare; == on Bool is equality of truth values
E-Notρ ⊢ a ⇓ b ⟹ ρ ⊢ !a ⇓ ¬b
E-Andρ ⊢ a ⇓ false ⟹ ρ ⊢ a && b ⇓ false (b not evaluated); ρ ⊢ a ⇓ true, ρ ⊢ b ⇓ v ⟹ ρ ⊢ a && b ⇓ v
E-Ifρ ⊢ c ⇓ true ⟹ the then branch; false ⟹ the else branch; only one branch is evaluated
E-Letρ ⊢ a ⇓ v, ρ[x ↦ v] ⊢ b ⇓ r ⟹ ρ ⊢ let x = a; b ⇓ r
E-Trapany premise ⇓ trap(c) ⟹ the conclusion ⇓ trap(c), for the first such premise in order

Properties checked

propertyover
P1Soundness: if ∅ ⊢ e : τ then evaluation terminates in a value of type τ or a trap — never stuckevery well-typed program up to the bound
P2Determinism: two evaluations agreethe same
P3Checked arithmetic: an Int result equals the mathematical value whenever no trap occurredthe same, against 128-bit arithmetic
P4Correspondence: the Nazm interpreter, run on to_source(e), prints the same value or fails with the same codethe same, and a sample through the native backend
P5Typing agrees: Nazm’s checker accepts to_source(e) exactly when the formal rules type eevery program up to the bound, typed or not

2. Statements, loops and recursion — nazm.formal-core/2 (N97)

E ::= n | x | E ⊕ E | f(E)                       Int expressions, ⊕ as in §1
C ::= E < E | E == E | !C
S ::= x = E; | while C { S* } | if C { S* } else { S* } | return E;
B ::= (let mut x = E;)* S* E                      a body: bindings, statements, its result
P ::= [fn f(n: Int) -> Int { B }] fn main() -> Int { B }

W-Prog (well formed — every value is Int, so well formed is well typed): every name is bound; every assigned name is a let mut in scope; f is called only when it exists.

Evaluation, big step, with fuel φ (400 at the start), outcomes v | trap(c) | out-of-fuel:

rule
S-Expras §1, left to right, the first trap wins
S-Callthe argument, then one fuel (none left: out-of-fuel), then f’s body with n bound to it
S-Assignevaluate, then update the innermost binding of x
S-Whilethe condition; false: next; true: one fuel (none left: out-of-fuel), the body, again
S-Ifthe condition, then exactly one branch
S-Returnevaluate, and leave the body with that value
S-Bodythe bindings in order, the statements, then the result — unless a statement returned, trapped or ran out of fuel

Properties over every program of the bound — loops let mut x = a; let mut y = b; while C { x = E1; y = E2; } R (5 × 3 × 6 × 8 × 5 × 3), branches let mut x = a; if C { x = E1; } else { return E2; } x (5 × 6 × 8 × 8), recursion fn f(n) { if n < 1 { return B; } A } on 9 arguments (4 × 5 × 9): 12,900 programs. S1 never stuck; S2 deterministic; S3 the interpreter’s value or trap equals the model’s for every program the model finishes — 11,137, 3,194 of them traps; 1,763 run out of fuel and are not compared; S4 the checker accepts each. crates/nazm-formal/tests/statements.rs.

Not in the core

Records, enums, strings, sequences, effects and capabilities, provenance, tasks, channels, closures, the memory model and the backends’ code generation. Each is outside the properties above, and no claim is made about it.