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.
Definition Delta1 V G {C: compspecs}: tycontext :=
make_tycontext ((1%positive,(Tfunction Tnil Tvoid cc_default))::nil) nil nil Tvoid V G nil.
(* Definition Delta_types V G {C: compspecs} (tys : list type) : tycontext := make_tycontext (params_of_types 1 ((Tfunction (type_of_params (params_of_types 2 tys)) Tvoid cc_default) :: tys)) nil nil Tvoid V G nil. *)

Lemma semax_prog_entry_point {CS: compspecs} V G prog b id_fun params args A
(P Q: forall ts : list Type, (dependent_type_functor_rec ts (AssertTT A)) mpred)
NEP NEQ h z:
let retty := tint in
postcondition_allows_exit retty ->
@semax_prog CS prog z V G ->
Genv.find_symbol (globalenv prog) id_fun = Some b ->
find_id id_fun G =
Some (mk_funspec (params, retty) cc_default A P Q NEP NEQ) ->
tc_vals (map snd params) args ->
let rho1 : environ := make_args (map fst params) args
(empty_environ (globalenv prog)) in
{ q : CC_core |
(forall jm,
Forall (fun v => Val.inject (Mem.flat_inj (nextblock (m_dry jm))) v v)  args->
inject_neutral (nextblock (m_dry jm)) (m_dry jm) /\
Coqlib.Ple (Genv.genv_next (Genv.globalenv prog)) (nextblock (m_dry jm)) ->
exists jm', semantics.initial_core
(juicy_core_sem (cl_core_sem (globalenv prog))) h
jm q jm' (Vptr b Ptrofs.zero) args) /\
forall (jm : juicy_mem) ts (a: (dependent_type_functor_rec ts A) mpred),
app_pred (P ts a rho1) (m_phi jm) ->
app_pred (funassert (nofunc_tycontext V G) rho1) (m_phi jm) ->
nth_error (ghost_of (m_phi jm)) 0 = Some (Some (ext_ghost z, NoneP)) ->
jsafeN (@OK_spec Espec) (globalenv prog) (level jm) z q jm }.