Add LoadPath "../..".
Definition world := ((var -> option adr)*(adr -> option adr))%type.
Instance Join_world: Join world :=
Join_prod
(var -> option adr) (Join_equiv _)
(adr -> option adr) (Join_fun adr (option adr) (Join_lower (Join_discrete adr))).
Instance Perm_world : Perm_alg world := _.
Instance Sep_world : Perm_alg world := _.
Instance Canc_world : Perm_alg world := _.
Instance Disj_world : Perm_alg world := _.
Definition den (s: state) : world := (table_get (fst s), table_get (snd s)).
Definition defined (y: var) : pred world :=
fun w => exists v, fst w y = Some v.
Definition fun_set (f: nat -> option nat) (x: nat) (y: option nat) :=
fun i => if eq_dec i x then y else f i.
Definition subst (x y: var) (P: pred world) : pred world :=
fun w => P (fun_set (fst w) x (fst w y), snd w).
Definition mapsto (x y: var) : pred world :=
fun w =>
exists ax, fst w x = Some ax /\
exists ay, fst w y = Some ay /\
forall a, if eq_dec a ax then snd w a = Some ay else snd w a = None.
Definition equal (x y: var) : pred world :=
fun w => fst w x = fst w y.
Inductive modvars : command -> var -> Prop :=
| mod_assign: forall x y, modvars (Assign x y) x
| mod_load: forall x y, modvars (Load x y) x
| mod_seq1: forall x c1 c2, modvars c1 x -> modvars (Seq c1 c2) x
| mod_seq2: forall x c1 c2, modvars c2 x -> modvars (Seq c1 c2) x.
Definition nonfreevars (P: pred world) (x: var) : Prop :=
forall stk hp v, P (stk,hp) -> P (fun_set stk x v, hp).
Definition subset (S1 S2: var -> Prop) :=
forall x, S1 x -> S2 x.
Inductive safe: (list command * state) -> Prop :=
| safe_step: forall cs1 cs2, step' cs1 cs2 -> safe cs2 -> safe cs1
| safe_halt: forall s, safe (nil, s).
Definition guards (P: pred world) (k: list command) : Prop :=
forall s, P (den s) -> safe (k,s).
Definition semax (P: pred world) (c: command) (Q: pred world) : Prop :=
forall F, subset (modvars c) (nonfreevars F) ->
forall k, guards (Q*F) k -> guards (P*F) (c :: k).

(* Specifications: *)
Lemma semax_assign: forall P x y,
semax (defined y && subst x y P) (Assign x y) P.
Lemma semax_load: forall x y z, x <> y -> x <> z ->
semax (mapsto y z)  (Load x y) (mapsto y z && equal x z).
Lemma semax_store: forall x y z,
semax (defined y && mapsto x z) (Store x y) (mapsto x y).
Lemma semax_seq: forall P c1 Q c2 R,
semax P c1 Q -> semax Q c2 R -> semax P (Seq c1 c2) R.
Lemma frame: forall F P c Q,
subset (modvars c) (nonfreevars F) ->
semax P c Q -> semax (P * F) c (Q * F).
Lemma semax_pre_post:
forall P P' c Q' Q,
P |-- P' -> Q' |-- Q -> semax P' c Q' -> semax P c Q.