Instance Age_world : Age_alg world.
constructor.
intros [nx x] [ny y] [nz z] [nx' x'] [? ?] ?; simpl in *. destruct H; subst.
unfold age in H1. simpl in H1. unfold age_world in H1. simpl in H1.
destruct nz; inv H1. unfold age; simpl. unfold age_world; simpl.
exists (nx', y); exists (nx', z); split; auto; split; auto.
intros [nx x] [ny y] [nz z] [nz' z'] [? ?] ?; simpl in *. destruct H; subst.
unfold age in H1. simpl in H1. unfold age_world in H1. simpl in H1.
destruct nz; inv H1. unfold age; simpl. unfold age_world; simpl.
exists (nz', x); exists (nz', y); split; auto; split; auto.
intros [nx x] [nx' x'] [ny' y'] [nz' z'] [? ?] ?; simpl in *. destruct H; subst.
unfold age in H1. simpl in H1. unfold age_world in H1. simpl in H1.
destruct nx; inv H1. unfold age; simpl. unfold age_world; simpl.
exists (S nz', y'); exists (S nz', z'); split; auto; split; auto.
intros [nz z] [nx' x'] [ny' y'] [nz' z'] [? ?] ?; simpl in *. destruct H; subst.
unfold age in H1. simpl in H1. unfold age_world in H1. simpl in H1.
destruct nz; inv H1. unfold age; simpl. unfold age_world; simpl.
exists (S nz', x'); exists (S nz', y'); split; auto; split; auto.
Qed.
Definition den (lev: nat) (s: state) : world := (lev, (table_get (fst s), table_get (snd s))).
Obligation Tactic := (try solve [repeat intro; match goal with H: age _ _ |- _ => inv H end]).
Program Definition defined (y: var) : pred world :=
fun w => exists v, fst (snd w) y = Some v.
Next Obligation.
intros. intro; intros.
unfold age in H;  destruct a; destruct a'; simpl in H. destruct n; inv H.
auto.
Qed.
Definition fun_set (f: nat -> option nat) (x: nat) (y: option nat) :=
fun i => if eq_dec i x then y else f i.
Program Definition subst (x y: var) (P: pred world) : pred world :=
fun w => P (fst w, (fun_set (fst (snd w)) x (fst (snd w) y), snd (snd w))).
Next Obligation.
intros. intro; intros.
unfold age in H;  destruct a; destruct a'; simpl in H. destruct n; inv H.
simpl in *. eapply pred_hereditary; eauto.
unfold age; simpl. unfold age_world; simpl. auto.
Qed.
Program Definition mapsto (x y: var) : pred world :=
fun w =>
exists ax, fst (snd w) x = Some ax /\
exists ay, fst (snd w) y = Some ay /\
forall a, if eq_dec a ax then snd (snd w) a = Some ay else snd (snd w) a = None.
Next Obligation.
intros. intro; intros.
unfold age in H;  destruct a; destruct a'; simpl in H. destruct n; inv H.
simpl in *. auto.
Qed.
Program Definition equal (x y: var) : pred world :=
fun w => fst (snd w) x = fst (snd w) y.
Next Obligation.
intros. intro; intros.
unfold age in H;  destruct a; destruct a'; simpl in H. destruct n; inv H.
simpl in *. auto.
Qed.
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 lev stk hp v, P (lev, (stk,hp)) -> P (lev, (fun_set stk x v, hp)).
Definition subset (S1 S2: var -> Prop) :=
forall x, S1 x -> S2 x.
Inductive safeN: nat -> (list command * state) -> Prop :=
| safe0: forall cs, safeN 0 cs
| safe_step: forall n cs1 cs2, step' cs1 cs2 -> safeN n cs2 -> safeN (S n) cs1
| safe_halt: forall n s, safeN (S n) (nil, s).
Definition guards (P: pred world) (k: list command) : Prop :=
forall lev s, P (den lev s) -> safeN lev (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.