Section semax_prog.
Context (Espec: OracleKind).
Definition prog_contains (ge: genv) (fdecs : list (ident * Clight.fundef)) : Prop :=
forall id f, In (id,f) fdecs ->
exists b, Genv.find_symbol ge id = Some b /\ Genv.find_funct_ptr ge b = Some f.
Definition entry_tempenv (te: temp_env) (f: function) (vl: list val) :=
length vl = length f.(fn_params) /\
forall id v, PTree.get id te = Some v ->
In (id,v)
(combine (map (@fst _ _) f.(fn_params)) vl
++ map (fun tv => (fst tv, Vundef)) f.(fn_temps)).
Definition semax_body_params_ok f : bool :=
andb
(compute_list_norepet (map (@fst _ _) (fn_params f) ++ map (@fst _ _) (fn_temps f)))
(compute_list_norepet (map (@fst _ _) (fn_vars f))).
Definition semax_body
(V: varspecs) (G: funspecs) {C: compspecs} (f: function) (spec: ident * funspec): Prop :=
match spec with (_, mk_funspec fsig cc A P Q _ _) =>
(map snd (fst fsig) = map snd (fst (fn_funsig f))
/\ snd fsig = snd (fn_funsig f)
/\ list_norepet (map fst (fst fsig))) /\
forall Espec ts x,
semax Espec (func_tycontext f V G nil)
(fun rho => close_precondition (map fst (fst fsig)) (map fst f.(fn_params)) (P ts x) rho * stackframe_of f rho)
f.(fn_body)
(frame_ret_assert (function_body_ret_assert (fn_return f) (Q ts x)) (stackframe_of f))
end.
Definition genv_contains (ge: Genv.t Clight.fundef type) (fdecs : list (ident * Clight.fundef)) : Prop :=
forall id f, In (id,f) fdecs ->
exists b, Genv.find_symbol ge id = Some b /\ Genv.find_funct_ptr ge b = Some f.
Definition main_pre {Z} (prog: program) (ora: Z) : list Type -> (ident->val) -> assert :=
(fun nil gv rho => globvars2pred gv (prog_vars prog) rho * has_ext ora).
Definition Tint32s := Tint I32 Signed noattr.
Definition main_post (prog: program) : list Type -> (ident->val) -> assert :=
(fun nil _ _ => TT).
Definition main_spec_ext' {Z} (prog: program) (ora: Z)
(post: list Type -> (ident->val) -> environ ->pred rmap): funspec :=
mk_funspec (nil, tint) cc_default
(ConstType (ident->val)) (main_pre prog ora) post
(const_super_non_expansive _ _) (const_super_non_expansive _ _).
Definition main_spec_ext (prog: program) (ora: OK_ty): funspec :=
mk_funspec (nil, tint) cc_default
(ConstType (ident->val)) (main_pre prog ora) (main_post prog)
(const_super_non_expansive _ _) (const_super_non_expansive _ _).
Definition is_Internal (prog : program) (f : ident) :=
match Genv.find_symbol (Genv.globalenv prog) f with
None => false
| Some b =>
match Genv.find_funct_ptr (Genv.globalenv prog) b with
| None => false
| Some f =>
match f with
| External _ _ _ _ => false
| Internal _ => true
end
end
end.
Definition postcondition_allows_exit retty :=
forall
v  ora (jm : juicy_mem),
tc_option_val retty v ->
app_pred (ext_compat ora) (m_phi jm) ->
ext_spec_exit OK_spec v ora jm.
Definition semax_prog {C: compspecs}
(prog: program) (ora: OK_ty) (V: varspecs) (G: funspecs) : Prop :=
compute_list_norepet (prog_defs_names prog) = true  /\
all_initializers_aligned prog /\
cenv_cs = prog_comp_env prog /\
(*  @semax_func V G C (prog_funct prog) G /\*)
@semax_func V G C (Genv.globalenv prog) (prog_funct prog) G /\
match_globvars (prog_vars prog) V = true /\
match find_id prog.(prog_main) G with
| Some s => exists post,
s = main_spec_ext' prog ora post
| None => False
end.
Program Definition HO_pred_eq {T}{agT: ageable T}
(A: Type) (P: A -> pred T) (A': Type) (P': A' -> pred T) : pred nat :=
fun v => exists H: A=A',
match H in (_ = A) return (A -> pred T) -> Prop with
| refl_equal => fun (u3: A -> pred T) =>
forall x: A, (P x <=> u3 x) v
end P'.
Next Obligation.
try (intros; intro; intros).
destruct H0. exists x.
destruct x.
intros. specialize (H0 x). eapply pred_hereditary; eauto.
Qed.
(* EXPERIMENT Lemma semax_func_skip: forall V (G: funspecs) {C: compspecs} fs idf (G': funspecs), semax_func V G fs G' -> semax_func V G (idf::fs) G'. *)
intros.
hnf; intros.
simpl.
intros.
destruct H2 as [? [? [? [? [? ?]]]]].
contradiction.
Qed.

Lemma semax_func_cons_ext:
forall (V: varspecs) (G: funspecs) {C: compspecs} ge fs id ef argsig retsig A P Q NEP NEQ
argsig'
(G': funspecs) cc (ids: list ident) b,
ids = map fst argsig' -> (* redundant but useful for the client,
to calculate ids by reflexivity *)
argsig' = zip_with_tl ids argsig ->
ef_sig ef =
mksignature
(typlist_of_typelist (type_of_params argsig'))
(opttyp_of_type retsig) cc ->
id_in_list id (map (@fst _ _) fs) = false ->
length ids = length (typelist2list argsig) ->
(ef_inline ef = false \/ withtype_empty A) ->
(forall gx ts x (ret : option val),
(Q ts x (make_ext_rval gx ret)
&& !!has_opttyp ret (opttyp_of_type retsig)
|-- !!tc_option_val retsig ret)) ->