Definition tc_fn_return (Delta: tycontext) (ret: option ident) (t: type) :=
match ret with
| None => True
| Some i => match (temp_types Delta) ! i with Some t' => t=t' | _ => False end
end.

Lemma semax_call_external:
forall (Delta : tycontext) (A : TypeTree)
(P Q Q' : forall ts, dependent_type_functor_rec ts (AssertTT A) mpred)
(ts: list Type) (x : dependent_type_functor_rec ts A mpred)
(F : environ -> pred rmap) (F0 : assert)
(ret : option ident) (params : list (ident * type)) (retty : type) cc
(a : expr) (bl : list expr) (R : ret_assert) (psi : genv) (vx : env)
(tx : temp_env) (k : cont) (rho : environ) (ora : OK_ty) (jm : juicy_mem)
(b : block)
(Hora : juicy_mem_op (ext_compat ora) jm)
(TC0 : Cop.classify_fun (typeof a) =
Cop.fun_case_f (type_of_params params) retty cc)
(TCret : tc_fn_return Delta ret retty)
(TC1 : (|> tc_expr Delta a rho) (m_phi jm))
(TC2 : (|> tc_exprlist Delta (map snd params) bl rho) (m_phi jm))
(TC3 : guard_environ Delta (current_function k) rho)
(TC5 : retty = Tvoid -> ret = None)
(H : closed_wrt_modvars (Scall ret a bl) F0)
(HR : RA_normal R =
(fun rho0 : environ =>
EX  old : val,
substopt ret old F rho0 * maybe_retval (Q ts x) retty ret rho0))
(HGG:  genv_cenv psi = cenv_cs)
(H0 : rho = construct_rho (filter_genv psi) vx tx)
(H3 : eval_expr a rho = Vptr b Ptrofs.zero)
(H4 : (funassert Delta rho) (m_phi jm))
(H1 : (rguard Espec psi Delta
(frame_ret_assert R F0) k) (level (m_phi jm)))
(H11 : forall vl : environ, (!|>(Q' ts x vl <=> Q ts x vl)) (m_phi jm))
(H14 : (|>(F0 rho * F rho *
P ts x
(make_args (map fst params)
(eval_exprlist (map snd params) bl rho) rho))) (m_phi jm))
(n : nat)
(H2 : level (m_phi jm) = S n)
(H15 : (believe_external Espec psi (Vptr b Ptrofs.zero) (params, retty) cc A P Q')
(level (m_phi jm))),
exists (c' : corestate) (m' : juicy_mem),
jstep (cl_core_sem psi) (State vx tx (Kseq (Scall ret a bl) :: k)) jm c' m' /\
jm_bupd ora (jsafeN OK_spec psi n ora c') m'.