Structured word-RAM programs #
Flat programs (Cslib.WordRAM.Program) are lists of instructions with numeric jump targets,
which is inconvenient to write and to reason about. A structured program
(Cslib.WordRAM.Code) is built from data instructions by sequencing, conditionals and while
loops on the comparisons of Cslib.WordRAM.Cond. It has a big-step semantics
(Cslib.WordRAM.Exec) that counts exactly the instructions of the flat program it compiles to
(Cslib.WordRAM.Code.assemble, Cslib.WordRAM.Exec.runs): a conditional costs one branch
instruction, plus a jump when the second alternative runs, and a loop costs a branch and a jump
per test. No rule executes a Lean function as one instruction.
Proofs about structured programs mostly need upper bounds on time rather than exact counts,
and Cslib.WordRAM.ExecWithin packages these. Its rules compose like Hoare logic, with time
bounds added along sequences:
Cslib.WordRAM.ExecWithin.const,….alu,….copy,….load,….store: forward rules for the data instructions, with the resulting data in closed form, and….bin,….widthfor the operations of the standard basis;Cslib.WordRAM.ExecWithin.seq,….branch_pos,….branch_neg: sequencing and conditionals;Cslib.WordRAM.ExecWithin.loop: a loop through an explicit family of states, andCslib.WordRAM.ExecWithin.loop_invariant: a loop with an invariant and a decreasing measure, whose iterations are counted by the measure.
Loop-free code can instead be executed symbolically: Cslib.WordRAM.Code.eval is a structurally
recursive interpreter, so simp and decide evaluate it, and Cslib.WordRAM.Exec.of_eval turns
its result into an execution.
Subprograms are reused through Cslib.WordRAM.Code.rename, which runs a program on any
injectively chosen registers of a larger register file and leaves the others untouched
(Cslib.WordRAM.Exec.rename).
Main definitions #
Cslib.WordRAM.Code: structured programs over a basis, andCslib.WordRAM.Code.size, the length of the flat program they compile to.Cslib.WordRAM.Exec,Cslib.WordRAM.ExecWithin: executions with an exact instruction count, and within a time bound.Cslib.WordRAM.Code.eval: an interpreter with a budget of loop iterations.Cslib.WordRAM.Code.rename: running a program on other registers.
Main results #
Cslib.WordRAM.Exec.unique: executions are deterministic.Cslib.WordRAM.Exec.of_eval: the interpreter only finds executions.Cslib.WordRAM.ExecWithin.loop_invariant: the loop rule with an invariant and a measure.Cslib.WordRAM.Exec.regs_eq: registers that a program never writes keep their contents.Cslib.WordRAM.Exec.rename: renamed programs run on the chosen registers.Cslib.WordRAM.Exec.mono_width,Cslib.WordRAM.Exec.bounded: a program that does not read the word size runs in the same way at every larger word size, and executions keep data word-sized.
References #
- MIT–ULB CompGeom Group, Undecidability of tiling with a tromino; the structured programs, their cost-exact semantics, register preservation and register embedding are adapted from its accompanying Lean formalization.
Structured programs #
Structured programs: data instructions combined by sequencing, conditionals and loops.
- op {B : Basis} {r : ℕ} (o : Op B r) : Code B r
A data instruction.
- seq {B : Basis} {r : ℕ} (c₁ c₂ : Code B r) : Code B r
Run
c₁, thenc₂. - branch {B : Basis} {r : ℕ} (c : Cond r) (pos neg : Code B r) : Code B r
Run
posifcholds, andnegotherwise. - loop {B : Basis} {r : ℕ} (c : Cond r) (body : Code B r) : Code B r
Run
bodywhilecholds.
Instances For
Executions #
Exec w c x y n: at word size w, the structured program c leads from data x to data y
executing exactly n instructions of the flat program it compiles to.
- op {B : Basis} {r w : ℕ} {o : Op B r} {x y : Data r} : Op.eval w o x = some y → Exec w (Code.op o) x y 1
A data instruction is one instruction.
- seq {B : Basis} {r w : ℕ} {c₁ c₂ : Code B r} {x y z : Data r} {m n : ℕ} : Exec w c₁ x y m → Exec w c₂ y z n → Exec w (c₁.seq c₂) x z (m + n)
Sequencing adds the instruction counts.
- branch_pos {B : Basis} {r w : ℕ} {c : Cond r} {pos neg : Code B r} {x y : Data r} {n : ℕ} : c.Holds x → Exec w pos x y n → Exec w (Code.branch c pos neg) x y (n + 1)
The first alternative of a conditional costs one branch instruction.
- branch_neg {B : Basis} {r w : ℕ} {c : Cond r} {pos neg : Code B r} {x y : Data r} {n : ℕ} : ¬c.Holds x → Exec w neg x y n → Exec w (Code.branch c pos neg) x y (n + 2)
The second alternative of a conditional costs a branch and a jump.
- loop_exit {B : Basis} {r w : ℕ} {c : Cond r} {body : Code B r} {x : Data r} : ¬c.Holds x → Exec w (Code.loop c body) x x 2
Leaving a loop costs a branch and a jump.
- loop_iter {B : Basis} {r w : ℕ} {c : Cond r} {body : Code B r} {x y z : Data r} {m n : ℕ} : c.Holds x → Exec w body x y m → Exec w (Code.loop c body) y z n → Exec w (Code.loop c body) x z (m + n + 2)
An iteration of a loop costs its body, a branch and a jump back.
Instances For
ExecWithin w c x y T: at word size w, the structured program c leads from data x to
data y within T instructions.
Instances For
Data instructions #
Each data instruction leads to explicitly given data in one instruction. Only constants and operations need the written number to fit a word.
A loop through the states xs 0, …, xs k: the condition holds at the first k of them and
fails at the last, and the body leads from each to the next in T instructions.
Time bounds #
A conditional, with one time bound for both alternatives.
A loop whose condition holds initially and fails after one body execution runs within T + 4
instructions.
Loop rule, explicit states. If the condition holds at xs 0, …, xs (k - 1) and fails at
xs k, and the body leads from each state to the next within T instructions, the loop leads
from xs 0 to xs k within k (T + 2) + 2 instructions.
Loop rule, invariant and measure. If every state satisfying the invariant I and the
condition is led by the body, within T instructions, to a state satisfying I with a smaller
measure μ, then from a state satisfying I the loop terminates within μ x (T + 2) + 2
instructions, in a state satisfying I where the condition fails.
Data instructions #
Symbolic execution #
Run a structured program at word size w, allowing each loop at most fuel iterations per
entry: some (y, n) if it leads to y executing n instructions, and none if it faults or
runs out of iterations. The definition is structurally recursive, so simp and decide
evaluate it.
Instances For
Registers a program does not write #
Running a program on other registers #
A program over r registers runs on r' registers through an injective choice
f : Fin r → Fin r': register i of the program is register f i of the larger file. The other
registers keep their contents, so a caller can keep its own state across the call.
Renaming. A program run on the registers chosen by an injective f does what it does on
its own registers, with the same instruction count, and leaves the other registers unchanged.
Word sizes and word bounds #
Executions keep data word-sized.