mirror of
https://github.com/allaunthefox/SilverSight.git
synced 2026-07-31 01:25:21 +00:00
All 5 Coq files now use: From Corelib Require Import BinNums PosDef NatDef IntDef. Require Import SilverSight.coq.ZCompat. instead of Require Import ZArith Lia. Build: 5 Coq files, 0 errors
148 lines
5.1 KiB
Coq
148 lines
5.1 KiB
Coq
(* 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.
|