import .imp_syntax def string.index : string → nat → option char := fun s n, s.to_list.nth n namespace imp -- Stores def store.empty : store := [] @[irreducible] def update (x : string) (v : val) : store → store | [] := [(x, v)] | ((x', v') :: rest) := if x = x' then (x, v) :: rest else (x', v') :: (update rest). def updates : list string → list val → store → option store | [] [] s := some s | (x :: xs') (v :: vs') s := updates xs' vs' (update x v s) | _ _ _ := none def store.lookup (x : string) : store → option val | [] := none | ((x', v) :: rest) := if x = x' then some v else store.lookup rest -- Common def heap.size : heap → ℤ | [] := 0 | (_ :: rest) := 1 + heap.size rest. def is_nop (p : stmt) : decidable (p = stmt.nop) := begin refine (if H : p = stmt.nop then _ else _), apply decidable.is_true, assumption, apply decidable.is_false, assumption, end def heap.emtpy : heap := [] def copy : nat → val → list val | 0 v := [] | (n + 1) v := v :: copy n v def heap.alloc (h : heap) (i : ℤ) (v : val) : heap := h ++ (val.int i :: copy (int.to_nat i) v). def heap.read : heap → int → option val | [] _ := none | (v :: vs) 0 := some v | (v :: vs) i := heap.read vs (i - 1) def heap.write : heap → ℤ → val → option heap | [] _ _ := none | (x :: xs) 0 v := some (v :: xs) | (x :: xs) i v := match heap.write xs (i - 1) v with | some h' := some (x :: h') | none := none end -- (** Common *) def heap.length : heap → ℤ | [] := 0 | (_ :: rest) := 1 + heap.length rest open stmt def stmt.size : stmt → nat | nop := 0 | (set _ _) := 0 | (alloc _ _ _) := 0 | (write _ _ _) := 0 | (ifelse _ p1 p2) := nat.succ (stmt.size p1 + stmt.size p2) | (while _ p1) := nat.succ (stmt.size p1) | (seq p1 p2) := nat.succ (stmt.size p1 + stmt.size p2) inductive result : Type | done : heap -> val -> result | timeout : store -> heap -> stmt -> expr -> result | stuck : store -> heap -> stmt -> expr -> result. end imp