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').
Admitted.
Definition own (x: var) : pred world := (^stk (own_var pfullshare x) * TT) %pred.
Admitted.

Lemma semax_assign: forall P x y v,
semax (y =# v && (own x * TT) && subst x (Some(pfullshare, v)) P) (Assign x y) P.