Open Local Scope pred.
Hint Resolve @now_later @andp_derives @sepcon_derives.
(* Definition rmap_chain := {c: nat -> rmap | forall n, level (c n) = n /\ age (c (S n)) (c n)}.  Definition app_rmap_chain (c: rmap_chain) (n: nat) : rmap := proj1_sig c n.  Coercion app_rmap_chain: rmap_chain >-> Funclass.  Lemma rmap_chain_spec1: forall n (c: rmap_chain), level (c n) = n.  Lemma rmap_chain_spec2: forall n (c: rmap_chain), age (c (S n)) (c n).  Lemma rmap_chain_S: forall r1 r2 (c: rmap_chain) n, age r1 r2 -> c (S n) = r1 -> c n = r2.  Program Definition is_rmap_chain (c: rmap_chain): pred rmap := fun r => c (level r) = r. Next Obligation. hnf; intros. cbv beta in *. pose proof age_level _ _ H. rewrite H1 in H0. eapply rmap_chain_S; eauto. Defined.  Definition exact_at (st: environ * rmap_chain): assert := fun rho => !! (rho = fst st) && is_rmap_chain (snd st). *)
Program Definition exact_at (r: rmap): pred rmap :=
fun r' =>
if le_lt_dec (level r') (level r) then necR r r' else False.
Next Obligation.
hnf; simpl; intros.
destruct (le_lt_dec (level a) (level r)).
+ pose proof age_level _ _ H.
destruct (le_lt_dec (level a') (level r)); try omega.
apply rt_trans with a; auto.
apply rt_step; auto.
+ tauto.
Qed.
Definition exact_assert (S: ident -> Prop) (st: environ * rmap): assert :=
fun rho =>
!! (forall i, S i \/ Map.get (te_of rho) i = Map.get (te_of (fst st)) i) &&
!! (ve_of rho = ve_of (fst st)) &&
exact_at (snd st).

Lemma exact_assert_spec1: forall S st,
closed_wrt_vars S (exact_assert S st).