Program Definition ext_compat {Z} (ora : Z) : mpred :=
fun w => joins (ghost_of w) (Some (ghost_PCM.ext_ref ora, NoneP) :: nil).
Next Obligation.
Program Definition assert_safe
(Espec : OracleKind)
(ge: genv) ve te (ctl: cont) : assert :=
fun rho => bupd (fun w => forall ora (jm:juicy_mem),
ext_compat ora w ->
rho = construct_rho (filter_genv ge) ve te ->
m_phi jm = w ->
jsafeN (@OK_spec Espec) ge (level w) ora (State ve te ctl) jm).
Next Obligation.
intro; intros.
subst.
destruct (oracle_unage _ _ H) as [jm0 [? ?]].
subst.
specialize (H0 ora jm0); spec H0.
{ erewrite age1_ghost_of in H1 by eauto.
eapply ext_join_unapprox; eauto. }
specialize (H0 (eq_refl _) (eq_refl _)).
forget (State ve te ctl) as c. clear H ve te ctl.
change (level (m_phi jm)) with (level jm).
change (level (m_phi jm0)) with (level jm0) in H0.
eapply age_safe; eauto.
Qed.
Definition list2opt {T: Type} (vl: list T) : option T :=
match vl with nil => None | x::_ => Some x end.
Definition match_venv (ve: venviron) (vars: list (ident * type)) :=
forall id, match ve id with Some (b,t) => In (id,t) vars | _ => True end.
Definition guard_environ (Delta: tycontext) (f: option function) (rho: environ) : Prop :=
typecheck_environ Delta rho /\
match f with
| Some f' => match_venv (ve_of rho) (fn_vars f')
/\ ret_type Delta = fn_return f'
| None => True
end.

(* Specifications: *)
Lemma guard_environ_e1:
forall Delta f rho, guard_environ Delta f rho ->
typecheck_environ Delta rho.