(*
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.
Proof.
  intros.
  destruct c; simpl.
  apply (proj1 (a n)).
Qed.

Lemma rmap_chain_spec2: forall n (c: rmap_chain), age (c (S n)) (c n).
Proof.
  intros.
  destruct c; simpl.
  apply (proj2 (a n)).
Qed.

Lemma rmap_chain_S: forall r1 r2 (c: rmap_chain) n,
  age r1 r2 ->
  c (S n) = r1 ->
  c n = r2.
Proof.
  intros.
  pose proof rmap_chain_spec2 n c.
  rewrite H0 in H1.
  unfold age in *.
  rewrite H1 in H.
  inv H; auto.
Qed.

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.

Lemma semax_conjunction {CS: compspecs} Delta (P1 P2: environ -> mpred) c Q1 Q2: semax Espec Delta P1 c Q1 -> semax Espec Delta P2 c Q2 -> semax Espec Delta (fun rho => P1 rho && P2 rho) c (fun k v rho => Q1 k v rho && Q2 k v rho).