(* AVM ISA v1 — Coq Formalization (Rocq 9.0) *) From Corelib Require Import BinNums PosDef NatDef IntDef Init.Datatypes. Require Import SilverSight.coq.ZCompat. Local Open Scope Z_scope. Module AVM. Fixpoint pow2_positive (n : nat) : positive := match n with O => xH | S m => xO (pow2_positive m) end. Definition q16_scale : Z := Zpos (pow2_positive 16). Inductive AvmTy : Set := Q0_16 | Q16_16 | Bool. Inductive AvmVal : Set := Vq0 (x : Z) | Vq16 (x : Z) | Vbool (b : bool). Inductive Prim : Set := AddQ16 | SubQ16 | MulQ16 | DivQ16 | LtQ16 | EqQ16 | And | Or | Not. Inductive Instr : Set := Push_q16 (x : Z) | Push_bool (b : bool) | Pop | Dup | Swap | Load (i : nat) | Store (i : nat) | Jump (t : nat) | Jump_if (t : nat) | Prim_op (p : Prim) | Halt. Record State : Set := mkState { pc : nat; stack : list AvmVal; locals : list (option AvmVal); halted : bool }. Definition empty_state : State := mkState O nil nil false. Definition q16_mul (a b : Z) : Z := Z.div (Z.mul a b) q16_scale. Definition q16_div (a b : Z) : Z := if Z.eqb b Z0 then q16_scale else Z.div (Z.mul a q16_scale) b. Infix "::" := cons (at level 60, right associativity). Infix "++" := app (at level 60, right associativity). Fixpoint nth_error {A} (l : list A) (n : nat) : option A := match l with | nil => None | x :: xs => match n with O => Some x | S n' => nth_error xs n' end end. Definition get_local (s : State) (i : nat) : option AvmVal := match nth_error s.(locals) i with | Some (Some v) => Some v | _ => None end. Definition exec_prim (p : Prim) (a b : option AvmVal) : option AvmVal := match p, a, b with | AddQ16, Some (Vq16 x), Some (Vq16 y) => Some (Vq16 (Z.add x y)) | SubQ16, Some (Vq16 x), Some (Vq16 y) => Some (Vq16 (Z.sub x y)) | MulQ16, Some (Vq16 x), Some (Vq16 y) => Some (Vq16 (q16_mul x y)) | DivQ16, Some (Vq16 x), Some (Vq16 y) => Some (Vq16 (q16_div x y)) | LtQ16, Some (Vq16 x), Some (Vq16 y) => Some (Vbool (Z.ltb x y)) | EqQ16, Some (Vq16 x), Some (Vq16 y) => Some (Vbool (Z.eqb x y)) | And, Some (Vbool x), Some (Vbool y) => Some (Vbool (x && y)) | Or, Some (Vbool x), Some (Vbool y) => Some (Vbool (x || y)) | Not, Some (Vbool x), None => Some (Vbool (negb x)) | _, _, _ => None end. Fixpoint firstn {A} (n : nat) (l : list A) : list A := match n with O => nil | S m => match l with nil => nil | x :: xs => x :: firstn m xs end end. Fixpoint skipn {A} (n : nat) (l : list A) : list A := match n with O => l | S m => match l with nil => nil | _ :: xs => skipn m xs end end. Definition step (s : State) (prog : list Instr) : option State := if s.(halted) then None else match nth_error prog s.(pc) with | None => Some (mkState s.(pc) s.(stack) s.(locals) true) | Some instr => let new_pc := S s.(pc) in let push v := Some (mkState new_pc (v :: s.(stack)) s.(locals) false) in match instr with | Push_q16 x => push (Vq16 x) | Push_bool x => push (Vbool x) | Pop => match s.(stack) with | _ :: rest => Some (mkState new_pc rest s.(locals) false) | nil => None end | Dup => match s.(stack) with | v :: _ => push v | nil => None end | Swap => match s.(stack) with | a :: b :: rest => Some (mkState new_pc (b :: a :: rest) s.(locals) false) | _ => None end | Load i => match get_local s i with | Some v => push v | None => None end | Store i => match s.(stack) with | v :: rest => Some (mkState new_pc rest (firstn i s.(locals) ++ Some v :: skipn (S i) s.(locals)) false) | nil => None end | Jump t => Some (mkState t s.(stack) s.(locals) false) | Jump_if t => match s.(stack) with | Vbool true :: rest => Some (mkState t rest s.(locals) false) | Vbool false :: rest => Some (mkState new_pc rest s.(locals) false) | _ :: _ => None | nil => None end | Prim_op p => (match p with | Not => match s.(stack) with | a :: rest => match exec_prim p (Some a) None with | Some v => Some (mkState new_pc (v :: rest) s.(locals) false) | None => None end | nil => None end | _ => match s.(stack) with | a :: b :: rest => match exec_prim p (Some a) (Some b) with | Some v => Some (mkState new_pc (v :: rest) s.(locals) false) | None => None end | _ => None end end) | Halt => Some (mkState s.(pc) s.(stack) s.(locals) true) end end. Fixpoint run (s : State) (prog : list Instr) (fuel : nat) {struct fuel} : option State := match fuel with | O => Some s | S k => if s.(halted) then Some s else match step s prog with | None => None | Some s' => run s' prog k end end. Lemma step_halted (s : State) (prog : list Instr) (h : s.(halted) = true) : step s prog = None. Proof. unfold step; rewrite h; reflexivity. Qed. End AVM.