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.

(*new*) Genv.find_symbol ge id = Some b -> Genv.find_funct_ptr ge b = Some (External ef argsig retsig cc) -> (forall n, semax_external Espec ids ef A P Q n) -> semax_func V G ge fs G' -> semax_func V G ge ((id, External ef argsig retsig cc)::fs) ((id, mk_funspec (argsig', retsig) cc A P Q NEP NEQ)  :: G').  Definition main_params (ge: genv) start : Prop := exists b, exists func, Genv.find_symbol ge start = Some b /\ Genv.find_funct ge (Vptr b Ptrofs.zero) = Some (Internal func) /\ func.(fn_params) = nil.  Lemma in_prog_funct'_in {F V}: forall i f (g: list (ident * globdef F V)), In (i,f) (prog_funct' g) -> In (i, Gfun f) g.  Lemma in_prog_funct_in_prog_defs: forall i f prog, In (i,f) (prog_funct prog) -> In (i, Gfun f) (prog_defs prog).  Lemma in_prog_vars_in_prog_defs: forall i v prog, In (i,v) (prog_vars prog) -> In (i, Gvar v) (prog_defs prog).  Lemma find_funct_ptr_exists: forall (p: program) id f, list_norepet (prog_defs_names p) -> In (id, Gfun f) (prog_defs p) -> exists b, Genv.find_symbol (Genv.globalenv p) id = Some b /\ Genv.find_funct_ptr (Genv.globalenv p) b = Some f.  Lemma funassert_initial_core: forall (prog: program) ve te V G n, list_norepet (prog_defs_names prog) -> match_fdecs (prog_funct prog) G -> app_pred (funassert (nofunc_tycontext V G) (mkEnviron (filter_genv (globalenv prog)) ve te)) (initial_core (Genv.globalenv prog) G n).  Lemma prog_contains_prog_funct: forall prog: program, list_norepet (prog_defs_names prog) -> prog_contains (globalenv prog) (prog_funct prog).  Lemma funassert_initial_core_ext: forall (ora : OK_ty) (prog: program) ve te V G n, list_norepet (prog_defs_names prog) -> match_fdecs (prog_funct prog) G -> app_pred (funassert (nofunc_tycontext V G) (mkEnviron (filter_genv (globalenv prog)) ve te)) (initial_core_ext ora (Genv.globalenv prog) G n).  (* there's a place this lemma should be applied, perhaps in proof of semax_call *)
Lemma funassert_rho:
forall G rho rho', ge_of rho = ge_of rho' -> funassert G rho |-- funassert G rho'.