Built with Alectryon, running Coq+SerAPI v8.12.0+0.12.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
Require Import POCS.
Specification of Variables.
There are three variables, which we will call x, y, and z.
To refer to a particular variable name, we use this type.
Inductive var := | VarX | VarY | VarZ.EqualDec varEqualDec vardestruct x, y; simpl; (left; congruence) || (right; congruence). Defined.forall x y : var, {x = y} + {x <> y}
The values of these variables are the spec state:
Record State := mkState {
StateX : nat;
StateY : nat;
StateZ : nat;
}.
StateVar extracts a particular variable by its var name
from a State.
Definition StateVar (v:var) (state:State) : nat :=
match v with
| VarX => StateX state
| VarY => StateY state
| VarZ => StateZ state
end.
Operations on variables.
The specification for reading a variable, read_spec, is
parametrized by the variable that we are reading, v.
Definition read_spec v : Specification _ _ unit _ :=
fun (_ : unit) state => {|
(** The precondition is [True], reflecting the fact that it's
always OK to read any variable [v]. *)
pre := True;
(** The postcondition has two parts to it. First, it says
that the resulting state after reading a variable, [state'],
is the same as the state before reading the variable, [state].
In other words, reading a variable doesn't change the state. *)
post := fun r state' =>
state' = state /\
(** The second part of the postcondition says that the return
value [r] is the value of the variable [v] in the [state]. *)
r = StateVar v state;
(** Since our framework supports reasoning about crashes, we must
supply a recovered condition, but here we will ignore crashes
by saying that recovery can never occur, by stating [False]. *)
recovered := fun _ _ => False
|}.
The specification for writing a variable, write_spec is
parametrized by two things: the variable being modified, v,
and the value being written to that variable, val.
The precondition and recovery condition are the same as for
reading (True and False respectively).
Definition write_spec v val : Specification _ _ unit _ :=
fun (_ : unit) state => {|
pre := True;
(** The postcondition says that the return value is always equal
to [tt] (a way of representing a procedure that has no return
value), and *)
post := fun r state' =>
r = tt /\
(** the new state, [state'], is updated based on which variable
we were trying to modify. *)
match v with
| VarX => state' = mkState val (StateY state) (StateZ state)
| VarY => state' = mkState (StateX state) val (StateZ state)
| VarZ => state' = mkState (StateX state) (StateY state) val
end;
recovered := fun _ _ => False
|}.
Variables module
Module Type VarsAPI. Axiom init : proc InitResult. Axiom read : var -> proc nat. Axiom write : var -> nat -> proc unit. Axiom recover : proc unit. Axiom abstr : Abstraction State. Axiom init_ok : init_abstraction init recover abstr inited_any. Axiom read_ok : forall v, proc_spec (read_spec v) (read v) recover abstr. Axiom write_ok : forall v val, proc_spec (write_spec v val) (write v val) recover abstr. Axiom recover_wipe : rec_wipe recover abstr no_crash. Hint Resolve init_ok : core. Hint Resolve read_ok : core. Hint Resolve write_ok : core. Hint Resolve recover_wipe : core. End VarsAPI.