Local Open Scope pred.
(* Scall *)
Fixpoint alloc_juicy_variables (ge: genv) (rho: env) (jm: juicy_mem) (vl: list (ident*type)) : env * juicy_mem :=
match vl with
| nil => (rho,jm)
| (id,ty)::vars => match JuicyMemOps.juicy_mem_alloc jm 0 (@sizeof ge ty) with
(m1,b1) => alloc_juicy_variables ge (PTree.set id (b1,ty) rho) m1 vars
end
end.
Definition substopt {A} (ret: option ident) (v: val) (P: environ -> A)  : environ -> A :=
match ret with
| Some id => subst id v P
| None => P
end.

Lemma semax_call_typecheck_environ:
forall (Delta : tycontext) (args: list val) (psi : genv)
(jm : juicy_mem) (b : block) (f : function)
(H17 : list_norepet (map fst (fn_params f) ++ map fst (fn_temps f)))
(H17' : list_norepet (map fst (fn_vars f)))
(H16 : Genv.find_funct_ptr psi b = Some (Internal f))
(ve' : env) (jm' : juicy_mem) (te' : temp_env)
(H15 : alloc_variables psi empty_env (m_dry jm) (fn_vars f) ve' (m_dry jm'))
(TC5: typecheck_glob_environ (filter_genv psi) (glob_types Delta))
(H : forall (b : ident) (b0 : funspec) (a' : rmap),
necR (m_phi jm') a' ->
(glob_specs Delta) ! b = Some b0 ->
exists b1 : block,
filter_genv psi b = Some b1 /\
func_at b0 (b1,0) a')
(TC8 : tc_vals (snd (split (fn_params f))) args)
(H21 : bind_parameter_temps (fn_params f) args
(create_undef_temps (fn_temps f)) = Some te'),
typecheck_environ (func_tycontext' f Delta)
(construct_rho (filter_genv psi) ve' te').