Definition world := (env var adr * env adr adr)%type.
Instance Join_world: Join world := _.
Instance Perm_world : Perm_alg world := _.
Instance Sep_world : Perm_alg world := _.
Instance Canc_world : Perm_alg world := _.
Instance Disj_world : Perm_alg world := _.
Fixpoint den_env {key}{A}{KE: EqDec key} (rho: table key A)  : env key A :=
match rho with
| (x,v)::xs => env_set x v (den_env xs)
| nil => empty_env
end.
Definition den (s: state) : world := (den_env (fst s), den_env (snd s)).
Definition world_op (P: pred (env var adr)) (Q: pred (env adr adr)) : pred world :=
fun w => P (fst w) /\ Q (snd w).
Notation "'^stk' e" := (world_op e emp) (at level 30, no associativity): pred.
Notation "'^hp' e" := (world_op emp e) (at level 30, no associativity): pred.
Definition world_op_sepcon:
forall P P' Q Q',
(world_op P P' * world_op Q Q' = world_op (P*Q) (P'*Q'))%pred.
Definition eval_var (x: var) (y: adr) : pred world :=
(EX sh: share, (^stk env_mapsto x sh y) * TT)%pred.
Notation "x '=#' v" := (eval_var x v) (at level 25, no associativity): pred.
Definition defined (x: var) : pred world := (EX v:adr, x =# v)%pred.
Definition subst (x: var) (v: option (pshare * adr)) (P: pred world) : pred world :=
fun w => P (env_set_sh x v (fst w), snd w).
(* Definition equal (x y: var) : pred world := fun w => env_get (fst w) x = env_get (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 v, P |-- subst x v P.
Definition subset (S1 S2: var -> Prop) :=
forall x, S1 x -> S2 x.
Definition semax (P: pred world) (c: command) (Q: pred world) : Prop :=
forall F s,
(P*F)%pred (den s) -> exists s', exec c s = Some s' /\ (Q*F)%pred (den s').

(* Specifications: *)
Lemma env_get_den {A B}{AE: EqDec A}:  forall s (y: A) sh (v: B), env_get (den_env s) y = Some (sh,v) ->
table_get s y = Some v /\ sh = pfullshare.
Lemma eval_var_get: forall s x v, (x =# v)%pred s ->
exists sh, env_get (fst s) x = Some (sh,v).