Section AuxDefs.
Variable semax_external: forall {Hspec: OracleKind} (ids: list ident) (ef: external_function)
(A: rmaps.TypeTree)
(P Q: forall ts, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred),
Prop.
Inductive semax {CS: compspecs} {Espec: OracleKind} (Delta: tycontext): (environ -> mpred) -> statement -> ret_assert -> Prop :=
| semax_ifthenelse :
forall P (b: expr) c d R,
@semax CS Espec Delta (P && local (`(typed_true (typeof b)) (eval_expr b))) c R ->
@semax CS Espec Delta (P && local (`(typed_false (typeof b)) (eval_expr b))) d R ->
@semax CS Espec Delta (!! (bool_type (typeof b) = true) && tc_expr Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr)) && P) (Sifthenelse b c d) R
| semax_seq:
forall R P Q h t,
@semax CS Espec Delta P h (overridePost Q R) ->
@semax CS Espec Delta Q t R ->
@semax CS Espec Delta P (Ssequence h t) R
| semax_break: forall Q,
@semax CS Espec Delta (RA_break Q) Sbreak Q
| semax_continue: forall Q,
@semax CS Espec Delta (RA_continue Q) Scontinue Q
| semax_loop: forall Q Q' incr body R,
@semax CS Espec Delta  Q body (loop1_ret_assert Q' R) ->
@semax CS Espec Delta Q' incr (loop2_ret_assert Q R) ->
@semax CS Espec Delta Q (Sloop body incr) R
| semax_switch: forall (Q: environ->mpred) a sl R,
(forall rho, Q rho |-- tc_expr Delta a rho) ->
(forall n,
@semax CS Espec Delta
(local (`eq (eval_expr a) `(Vint n)) &&  Q)
(seq_of_labeled_statement (select_switch (Int.unsigned n) sl))
(switch_ret_assert R)) ->
@semax CS Espec Delta (!! (is_int_type (typeof a) = true) && Q) (Sswitch a sl) R
(*| semax_call_backward: forall ret a bl R, @semax CS Espec Delta (EX argsig: _, EX retsig: _, EX cc: _, EX A: _, EX P: _, EX Q: _, EX NEP: _, EX NEQ: _, EX ts: _, EX x: _, !! (Cop.classify_fun (typeof a) = Cop.fun_case_f (type_of_params argsig) retsig cc /\ (retsig = Tvoid -> ret = None) /\ tc_fn_return Delta ret retsig) && (|>((tc_expr Delta a) && (tc_exprlist Delta (snd (split argsig)) bl)))  && `(func_ptr (mk_funspec  (argsig,retsig) cc A P Q NEP NEQ)) (eval_expr a) && |>((`(P ts x: environ -> mpred) (make_args' (argsig,retsig) (eval_exprlist (snd (split argsig)) bl))) * oboxopt Delta ret (maybe_retval (Q ts x) retsig ret -* R))) (Scall ret a bl) (normal_ret_assert R)*)
| semax_call_backward: forall ret a bl R,
@semax CS Espec Delta
(EX argsig: _, EX retsig: _, EX cc: _,
EX A: _, EX P: _, EX Q: _, EX NEP: _, EX NEQ: _, EX ts: _, EX x: _,
!! (Cop.classify_fun (typeof a) =
Cop.fun_case_f (type_of_params argsig) retsig cc /\
(retsig = Tvoid -> ret = None) /\
tc_fn_return Delta ret retsig) &&
(((tc_expr Delta a) && (tc_exprlist Delta (snd (split argsig)) bl)))  &&
`(func_ptr (mk_funspec  (argsig,retsig) cc A P Q NEP NEQ)) (eval_expr a) &&
|>((`(P ts x: environ -> mpred) (make_args' (argsig,retsig) (eval_exprlist (snd (split argsig)) bl))) * oboxopt Delta ret (maybe_retval (Q ts x) retsig ret -* R)))
(Scall ret a bl)
(normal_ret_assert R)
| semax_return: forall (R: ret_assert) ret ,
@semax CS Espec Delta
( (tc_expropt Delta ret (ret_type Delta)) &&
`(RA_return R : option val -> environ -> mpred) (cast_expropt ret (ret_type Delta)) (@id environ))
(Sreturn ret)
R
| semax_set_ptr_compare_load_cast_load_backward: forall (P: environ->mpred) id e,
@semax CS Espec Delta
((|> ( (tc_expr Delta e) &&
(tc_temp_id id (typeof e) Delta e) &&
subst id (eval_expr e) P)) ||
(EX cmp: Cop.binary_operation, EX e1: expr, EX e2: expr,
EX ty: type, EX sh1: share, EX sh2: share,
!! (e = Ebinop cmp e1 e2 ty /\
sepalg.nonidentity sh1 /\ sepalg.nonidentity sh2 /\
is_comparison cmp = true /\
eqb_type (typeof e1) int_or_ptr_type = false /\
eqb_type (typeof e2) int_or_ptr_type = false /\
typecheck_tid_ptr_compare Delta id = true) &&
( |> ( (tc_expr Delta e1) &&
(tc_expr Delta e2)  &&
local (`(blocks_match cmp) (eval_expr e1) (eval_expr e2)) &&
(`(mapsto_ sh1 (typeof e1)) (eval_expr e1) * TT) &&
(`(mapsto_ sh2 (typeof e2)) (eval_expr e2) * TT) &&
subst id (eval_expr (Ebinop cmp e1 e2 ty)) P))) ||
(EX sh: share, EX t2: type, EX v2: val,
!! (typeof_temp Delta id = Some t2 /\
is_neutral_cast (typeof e) t2 = true /\
readable_share sh) &&
|> ( (tc_lvalue Delta e) &&
local (`(tc_val (typeof e) v2)) &&
(`(mapsto sh (typeof e)) (eval_lvalue e) (`v2) * TT) &&
subst id (`v2) P)) ||
(EX sh: share, EX e1: expr, EX t1: type, EX v2: val,
!! (e = Ecast e1 t1 /\
typeof_temp Delta id = Some t1 /\
cast_pointer_to_bool (typeof e1) t1 = false /\
readable_share sh) &&
|> ( (tc_lvalue Delta e1) &&
local (`(tc_val t1) (`(eval_cast (typeof e1) t1 v2))) &&
(`(mapsto sh (typeof e1)) (eval_lvalue e1) (`v2) * TT) &&
subst id (`(force_val (sem_cast (typeof e1) t1 v2))) P)))
(Sset id e) (normal_ret_assert P)
| semax_store_backward: forall e1 e2 P,
@semax CS Espec Delta
(EX sh: share, !! writable_share sh && |> ( (tc_lvalue Delta e1) &&  (tc_expr Delta (Ecast e2 (typeof e1)))  &&
((`(mapsto_ sh (typeof e1)) (eval_lvalue e1)) * (`(mapsto sh (typeof e1)) (eval_lvalue e1) (`force_val (`(sem_cast (typeof e2) (typeof e1)) (eval_expr e2))) -* P))))
(Sassign e1 e2)
(normal_ret_assert P)
| semax_skip: forall P, @semax CS Espec Delta P Sskip (normal_ret_assert P)
| semax_builtin: forall P opt ext tl el, @semax CS Espec Delta FF (Sbuiltin opt ext tl el) P
| semax_label: forall (P:environ -> mpred) (c:statement) (Q:ret_assert) l,
@semax CS Espec Delta P c Q -> @semax CS Espec Delta P (Slabel l c) Q
| semax_goto: forall P l, @semax CS Espec Delta FF (Sgoto l) P
| semax_conseq: forall P' (R': ret_assert) P c (R: ret_assert) ,
local (tc_environ Delta) && ((allp_fun_id Delta) && P) |-- |==> |> FF || P' ->
local (tc_environ Delta) && ((allp_fun_id Delta) && RA_normal R') |-- |==> |> FF || RA_normal R ->
local (tc_environ Delta) && ((allp_fun_id Delta) && RA_break R') |-- |==> |> FF || RA_break R ->
local (tc_environ Delta) && ((allp_fun_id Delta) && RA_continue R') |-- |==> |> FF || RA_continue R ->
(forall vl, local (tc_environ Delta) && ((allp_fun_id Delta) && RA_return R' vl) |-- |==> |> FF || RA_return R vl) ->
@semax CS Espec Delta P' c R' -> @semax CS Espec Delta P c R.
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 C Espec (func_tycontext f V G nil)
(Clight_seplog.close_precondition (map fst (fst fsig)) (map fst f.(fn_params)) (P ts x) * stackframe_of f)
f.(fn_body)
(frame_ret_assert (function_body_ret_assert (fn_return f) (Q ts x)) (stackframe_of f))
end.
Inductive semax_func: forall {Espec: OracleKind} (V: varspecs) (G: funspecs) {C: compspecs} (ge: Genv.t Clight.fundef type)(fdecs: list (ident * Clight.fundef)) (G1: funspecs), Prop :=
| semax_func_nil:   forall {Espec: OracleKind},
forall V G C ge, @semax_func Espec V G C ge nil nil
| semax_func_cons:
forall {Espec: OracleKind},
forall fs id f fsig cc A P Q NEP NEQ (V: varspecs) (G G': funspecs) {C: compspecs} ge b,
andb (id_in_list id (map (@fst _ _) G))
(andb (negb (id_in_list id (map (@fst ident Clight.fundef) fs)))
(semax_body_params_ok f)) = true ->
Forall
(fun it : ident * type =>
complete_type cenv_cs (snd it) =
true) (fn_vars f) ->
var_sizes_ok (f.(fn_vars)) ->
f.(fn_callconv) = cc ->
Genv.find_symbol ge id = Some b -> Genv.find_funct_ptr ge b = Some (Internal f) ->
semax_body V G f (id, mk_funspec fsig cc A P Q NEP NEQ)->
semax_func V G ge fs G' ->
semax_func V G ge ((id, Internal f)::fs)
((id, mk_funspec fsig cc A P Q NEP NEQ)  :: G')
| semax_func_cons_ext:
forall {Espec: OracleKind},
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)
&& !!step_lemmas.has_opttyp ret (opttyp_of_type retsig)
|-- !!tc_option_val retsig ret)) ->

(*new*) Genv.find_symbol ge id = Some b -> Genv.find_funct_ptr ge b = Some (External ef argsig retsig cc) -> @semax_external Espec ids ef A P Q -> 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') | semax_func_mono: forall  {Espec CS CS'} (CSUB: cspecs_sub CS CS') ge ge' (Gfs: forall i,  sub_option (Genv.find_symbol ge i) (Genv.find_symbol ge' i)) (Gffp: forall b, sub_option (Genv.find_funct_ptr ge b) (Genv.find_funct_ptr ge' b)) V G fdecs G1 (H: @semax_func Espec V G CS ge fdecs G1), @semax_func Espec V G CS' ge' fdecs G1  | semax_func_app: forall Espec ge cs V H funs1 funs2 G1 G2 (SF1: @semax_func Espec V H cs ge funs1 G1) (SF2: @semax_func Espec V H cs ge funs2 G2) (L:length funs1 = length G1), @semax_func Espec V H cs ge (funs1 ++ funs2) (G1++G2)  | semax_func_subsumption: forall Espec ge cs V V' F F' (SUB: tycontext_sub (nofunc_tycontext V F) (nofunc_tycontext V F')) (HV: forall id, sub_option (make_tycontext_g V F) ! id (make_tycontext_g V' F') ! id), forall funs G (SF: @semax_func Espec V F cs ge funs G),  @semax_func Espec V' F' cs ge funs G  | semax_func_join: forall {Espec cs ge V1 H1 V2 H2 V funs1 funs2 G1 G2 H} (SF1: @semax_func Espec V1 H1 cs ge funs1 G1) (SF2: @semax_func Espec V2 H2 cs ge funs2 G2)  (K1: forall i, sub_option ((make_tycontext_g V1 H1) ! i) ((make_tycontext_g V1 H) ! i)) (K2: forall i, subsumespec ((make_tycontext_s H1) ! i) ((make_tycontext_s H) ! i)) (K3: forall i, sub_option ((make_tycontext_g V1 H) ! i) ((make_tycontext_g V H) ! i))  (N1: forall i, sub_option ((make_tycontext_g V2 H2) ! i) ((make_tycontext_g V2 H) ! i)) (N2: forall i, subsumespec ((make_tycontext_s H2) ! i) ((make_tycontext_s H) ! i)) (N3: forall i, sub_option ((make_tycontext_g V2 H) ! i) ((make_tycontext_g V H) ! i)), @semax_func Espec V H cs ge (funs1 ++ funs2) (G1++G2)  | semax_func_firstn: forall {Espec cs ge H V n funs G} (SF: @semax_func Espec V H cs ge funs G), @semax_func Espec V H cs ge (firstn n funs) (firstn n G)  | semax_func_skipn: forall {Espec cs ge H V funs G} (HV:list_norepet (map fst funs)) (SF: @semax_func Espec V H cs ge funs G) n, @semax_func Espec V H cs ge (skipn n funs) (skipn n G).  End AuxDefs.  End AuxDefs.  Module DeepEmbedded (Def: CLIGHT_SEPARATION_HOARE_LOGIC_DEF) (MinimumLogic: MINIMUM_CLIGHT_SEPARATION_HOARE_LOGIC with Module CSHL_Def := Def).  Module DeepEmbeddedDef <: CLIGHT_SEPARATION_HOARE_LOGIC_DEF.  Definition semax := @AuxDefs.semax.  Definition semax_func := @AuxDefs.semax_func (@Def.semax_external).  Definition semax_external := @Def.semax_external.  End DeepEmbeddedDef.  Module DeepEmbeddedDefs := DerivedDefs (DeepEmbeddedDef).  Import DeepEmbeddedDef DeepEmbeddedDefs.  Module CConseq: CLIGHT_SEPARATION_HOARE_LOGIC_COMPLETE_CONSEQUENCE with Module CSHL_Def := DeepEmbeddedDef.  Module CSHL_Def := DeepEmbeddedDef.  Definition semax_conseq := @AuxDefs.semax_conseq.  End CConseq.  Module CConseqFacts := GenCConseqFacts (DeepEmbeddedDef) (CConseq).  Module Conseq := GenConseq (DeepEmbeddedDef) (CConseq).  Module ConseqFacts := GenConseqFacts (DeepEmbeddedDef) (Conseq).  Import CConseq CConseqFacts Conseq ConseqFacts.  Lemma semax_skip_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R, @semax CS Espec Delta P Sskip R -> local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || RA_normal R.  Lemma semax_break_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R, @semax CS Espec Delta P Sbreak R -> local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || RA_break R.  Lemma semax_continue_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R, @semax CS Espec Delta P Scontinue R -> local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || RA_continue R.  Lemma semax_return_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P ret R, @semax CS Espec Delta P (Sreturn ret) R -> local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || ((tc_expropt Delta ret (ret_type Delta)) && `(|==> |> FF || RA_return R : option val -> environ -> mpred) (cast_expropt ret (ret_type Delta)) (@id environ)).  Lemma semax_seq_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R h t, @semax CS Espec Delta P (Ssequence h t) R -> exists Q, @semax CS Espec Delta P h (overridePost Q R) /\ @semax CS Espec Delta Q t R.  Lemma semax_seq_inv': forall {CS: compspecs} {Espec: OracleKind} Delta P R h t, @semax CS Espec Delta P (Ssequence h t) R -> @semax CS Espec Delta P h (overridePost (EX Q: environ -> mpred, !! (@semax CS Espec Delta Q t R) && Q) R).  Lemma semax_store_inv: forall {CS: compspecs} {Espec: OracleKind} Delta e1 e2 P Q, @semax CS Espec Delta P (Sassign e1 e2) Q -> local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || (EX sh: share, !! writable_share sh && |> ( (tc_lvalue Delta e1) &&  (tc_expr Delta (Ecast e2 (typeof e1)))  && ((`(mapsto_ sh (typeof e1)) (eval_lvalue e1)) * (`(mapsto sh (typeof e1)) (eval_lvalue e1) (`force_val (`(sem_cast (typeof e2) (typeof e1)) (eval_expr e2))) -* |==> |> FF || RA_normal Q)))).  Lemma tc_fn_return_temp_guard_opt: forall ret retsig Delta, tc_fn_return Delta ret retsig -> temp_guard_opt Delta ret.  Lemma oboxopt_ENTAILL: forall Delta ret retsig P Q, tc_fn_return Delta ret retsig -> local (tc_environ Delta) && (allp_fun_id Delta && P) |-- Q -> local (tc_environ Delta) && (allp_fun_id Delta && oboxopt Delta ret P) |-- oboxopt Delta ret Q.  Lemma semax_call_inv: forall {CS: compspecs} {Espec: OracleKind} Delta ret a bl Pre Post, @semax CS Espec Delta Pre (Scall ret a bl) Post -> local (tc_environ Delta) && (allp_fun_id Delta && Pre) |-- |==> |> FF || (EX argsig: _, EX retsig: _, EX cc: _, EX A: _, EX P: _, EX Q: _, EX NEP: _, EX NEQ: _, EX ts: _, EX x: _, !! (Cop.classify_fun (typeof a) = Cop.fun_case_f (type_of_params argsig) retsig cc /\ (retsig = Tvoid -> ret = None) /\ tc_fn_return Delta ret retsig) && ((*|>*)((tc_expr Delta a) && (tc_exprlist Delta (snd (split argsig)) bl)))  && `(func_ptr (mk_funspec  (argsig,retsig) cc A P Q NEP NEQ)) (eval_expr a) && |>((`(P ts x: environ -> mpred) (make_args' (argsig,retsig) (eval_exprlist (snd (split argsig)) bl))) * oboxopt Delta ret (maybe_retval (Q ts x) retsig ret -* |==> |> FF || RA_normal Post))).  Lemma semax_Sset_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R id e, @semax CS Espec Delta P (Sset id e) R -> local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || ( (|> ( (tc_expr Delta e) && (tc_temp_id id (typeof e) Delta e) && subst id (eval_expr e) (|==> |> FF || RA_normal R))) || (EX cmp: Cop.binary_operation, EX e1: expr, EX e2: expr, EX ty: type, EX sh1: share, EX sh2: share, !! (e = Ebinop cmp e1 e2 ty /\ sepalg.nonidentity sh1 /\ sepalg.nonidentity sh2 /\ is_comparison cmp = true /\ eqb_type (typeof e1) int_or_ptr_type = false /\ eqb_type (typeof e2) int_or_ptr_type = false /\ typecheck_tid_ptr_compare Delta id = true) && ( |> ( (tc_expr Delta e1) && (tc_expr Delta e2)  && local (`(blocks_match cmp) (eval_expr e1) (eval_expr e2)) && (`(mapsto_ sh1 (typeof e1)) (eval_expr e1) * TT) && (`(mapsto_ sh2 (typeof e2)) (eval_expr e2) * TT) && subst id (eval_expr (Ebinop cmp e1 e2 ty)) (|==> |> FF || RA_normal R)))) || (EX sh: share, EX t2: type, EX v2: val, !! (typeof_temp Delta id = Some t2 /\ is_neutral_cast (typeof e) t2 = true /\ readable_share sh) && |> ( (tc_lvalue Delta e) && local (`(tc_val (typeof e) v2)) && (`(mapsto sh (typeof e)) (eval_lvalue e) (`v2) * TT) && subst id (`v2) (|==> |> FF || RA_normal R))) || (EX sh: share, EX e1: expr, EX t1: type, EX v2: val, !! (e = Ecast e1 t1 /\ typeof_temp Delta id = Some t1 /\ cast_pointer_to_bool (typeof e1) t1 = false /\ readable_share sh) && |> ( (tc_lvalue Delta e1) && local (`(tc_val t1) (`(eval_cast (typeof e1) t1 v2))) && (`(mapsto sh (typeof e1)) (eval_lvalue e1) (`v2) * TT) && subst id (`(force_val (sem_cast (typeof e1) t1 v2))) (|==> |> FF || RA_normal R)))).  Lemma semax_Sbuiltin_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R opt ext tl el, @semax CS Espec Delta P (Sbuiltin opt ext tl el) R -> local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || FF.  Lemma semax_Slabel_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R l c, @semax CS Espec Delta P (Slabel l c) R -> @semax CS Espec Delta P c R.  Lemma semax_Sgoto_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R l, @semax CS Espec Delta P (Sgoto l) R -> local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || FF.  Lemma semax_ifthenelse_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R b c1 c2, @semax CS Espec Delta P (Sifthenelse b c1 c2) R -> local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || (!! (bool_type (typeof b) = true) && tc_expr Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr)) && EX P': environ -> mpred, !! (@semax CS Espec Delta (P' && local (`(typed_true (typeof b)) (eval_expr b))) c1 R /\ @semax CS Espec Delta (P' && local (`(typed_false (typeof b)) (eval_expr b))) c2 R) && P').  Lemma semax_loop_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R body incr, @semax CS Espec Delta P (Sloop body incr) R -> local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || EX Q: environ -> mpred, EX Q': environ -> mpred, !! (@semax CS Espec Delta Q body (loop1_ret_assert Q' R) /\ @semax CS Espec Delta Q' incr (loop2_ret_assert Q R)) && Q.  Lemma semax_switch_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R a sl, @semax CS Espec Delta P (Sswitch a sl) R -> local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || !! (is_int_type (typeof a) = true) && (tc_expr Delta a) && EX P': environ -> mpred, !! (forall n, @semax CS Espec Delta (local (`eq (eval_expr a) `(Vint n)) && P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R)) && P'.  Module Extr: CLIGHT_SEPARATION_HOARE_LOGIC_EXTRACTION with Module CSHL_Def := CSHL_Def.  Module CSHL_Def := CSHL_Def. Import CSHL_Def.  Arguments semax {_} {_} _ _ _ _.  Lemma semax_extract_exists: forall {CS: compspecs} {Espec: OracleKind}, forall (A : Type)  (P : A -> environ->mpred) c (Delta: tycontext) (R: ret_assert), (forall x, @semax CS Espec Delta (P x) c R) -> @semax CS Espec Delta (EX x:A, P x) c R.  End Extr.  Module ExtrFacts := GenExtrFacts (CSHL_Def) (Conseq) (Extr). Module ExtrIFacts := GenIExtrFacts (CSHL_Def) (CConseq) (Extr).  Import Extr ExtrFacts ExtrIFacts.  Module DeepEmbeddedMinimumSeparationLogic <: MINIMUM_CLIGHT_SEPARATION_HOARE_LOGIC with Module CSHL_Def := DeepEmbeddedDef.  Module CSHL_Def := DeepEmbeddedDef.  Module CSHL_Defs := DeepEmbeddedDefs.  Definition semax_extract_exists := @semax_extract_exists.  Definition semax_func_nil := @AuxDefs.semax_func_nil (@Def.semax_external).  Definition semax_func_cons := @AuxDefs.semax_func_cons (@Def.semax_external).  Definition semax_func_cons_ext := @AuxDefs.semax_func_cons_ext (@Def.semax_external).  Theorem semax_ifthenelse : forall {CS: compspecs} {Espec: OracleKind}, forall Delta P (b: expr) c d R, bool_type (typeof b) = true -> @semax CS Espec Delta (P && local (`(typed_true (typeof b)) (eval_expr b))) c R -> @semax CS Espec Delta (P && local (`(typed_false (typeof b)) (eval_expr b))) d R -> @semax CS Espec Delta (tc_expr Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr)) && P) (Sifthenelse b c d) R.  Definition semax_seq := @AuxDefs.semax_seq.  Definition semax_break := @AuxDefs.semax_break.  Definition semax_continue := @AuxDefs.semax_continue.  Definition semax_loop := @AuxDefs.semax_loop.  Theorem semax_switch: forall {CS: compspecs} Espec Delta (Q: environ -> mpred) a sl R, is_int_type (typeof a) = true -> (forall rho, Q rho |-- tc_expr Delta a rho) -> (forall n, @semax CS Espec Delta (fun rho => andp (prop (eval_expr a rho = Vint n)) (Q rho)) (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R)) -> @semax CS Espec Delta Q (Sswitch a sl) R.  Module CallB: CLIGHT_SEPARATION_HOARE_LOGIC_CALL_BACKWARD with Module CSHL_Def := DeepEmbeddedDef.  Module CSHL_Def := DeepEmbeddedDef.  Definition semax_call_backward := @AuxDefs.semax_call_backward.  End CallB.  Module CallF := CallB2F (DeepEmbeddedDef) (Conseq) (CallB).  Definition semax_call := @CallF.semax_call_forward.  Definition semax_return := @AuxDefs.semax_return.  Module Sset: CLIGHT_SEPARATION_HOARE_LOGIC_SSET_BACKWARD with Module CSHL_Def := DeepEmbeddedDef.  Module CSHL_Def := DeepEmbeddedDef.  Definition semax_set_ptr_compare_load_cast_load_backward := @AuxDefs.semax_set_ptr_compare_load_cast_load_backward.  End Sset.  Module SetB := Sset2Set (DeepEmbeddedDef) (Conseq) (Sset).  Module SetF := SetB2F (DeepEmbeddedDef) (Conseq) (SetB).  Definition semax_set_forward := @SetF.semax_set_forward.  Module PtrCmpB := Sset2PtrCmp (DeepEmbeddedDef) (Conseq) (Sset).  Module PtrCmpF := PtrCmpB2F (DeepEmbeddedDef) (Conseq) (PtrCmpB).  Definition semax_ptr_compare := @PtrCmpF.semax_ptr_compare_forward.  Module LoadB := Sset2Load (DeepEmbeddedDef) (Conseq) (Sset).  Module LoadF := LoadB2F (DeepEmbeddedDef) (Conseq) (LoadB).  Definition semax_load := @LoadF.semax_load_forward.  Module CastLoadB := Sset2CastLoad (DeepEmbeddedDef) (Conseq) (Sset).  Module CastLoadF := CastLoadB2F (DeepEmbeddedDef) (Conseq) (CastLoadB).  Definition semax_cast_load := @CastLoadF.semax_cast_load_forward.  Module StoreB: CLIGHT_SEPARATION_HOARE_LOGIC_STORE_BACKWARD with Module CSHL_Def := DeepEmbeddedDef.  Module CSHL_Def := DeepEmbeddedDef.  Definition semax_store_backward := @AuxDefs.semax_store_backward.  End StoreB.  Module StoreF := StoreB2F (DeepEmbeddedDef) (Conseq) (StoreB).  Definition semax_store := @StoreF.semax_store_forward.  Definition semax_skip := @AuxDefs.semax_skip.  Definition semax_conseq := @AuxDefs.semax_conseq.  Definition semax_Slabel := @AuxDefs.semax_label.  Definition semax_ext := @MinimumLogic.semax_ext.  Definition semax_ext_void := @MinimumLogic.semax_ext_void.  Definition semax_external_FF := @MinimumLogic.semax_external_FF. Definition semax_external_binaryintersection := @MinimumLogic.semax_external_binaryintersection. Definition semax_body_binaryintersection: forall {V G cs} f sp1 sp2 phi (SB1: @semax_body V G cs f sp1) (SB2: @semax_body V G cs f sp2) (BI: binary_intersection (snd sp1) (snd sp2) = Some phi), @semax_body V G cs f (fst sp1, phi).  Definition semax_func_mono := @AuxDefs.semax_func_mono (@Def.semax_external).  Definition semax_func_app := @AuxDefs.semax_func_app (@Def.semax_external). Definition semax_func_subsumption := @AuxDefs.semax_func_subsumption (@Def.semax_external). Definition semax_func_join  := @AuxDefs.semax_func_join (@Def.semax_external). Definition semax_func_firstn := @AuxDefs.semax_func_firstn (@Def.semax_external). Definition semax_func_skipn := @AuxDefs.semax_func_skipn (@Def.semax_external).  Lemma tc_fn_return_sub: forall (CS : compspecs) (Delta Delta' : tycontext), tycontext_sub Delta Delta' -> forall ret retsig, tc_fn_return Delta ret retsig -> tc_fn_return Delta' ret retsig.  Lemma obox_sub: forall (Delta Delta' : tycontext) id P rho, tycontext_sub Delta Delta' -> temp_guard Delta id -> tc_environ Delta rho -> obox Delta id P rho |-- obox Delta' id P rho.  Lemma oboxopt_sub: forall (Delta Delta' : tycontext) id P rho, tycontext_sub Delta Delta' -> temp_guard_opt Delta id -> tc_environ Delta rho -> oboxopt Delta id P rho |-- oboxopt Delta' id P rho.  Lemma typecheck_tid_ptr_compare_sub: forall Delta Delta' id, tycontext_sub Delta Delta' -> typecheck_tid_ptr_compare Delta id = true -> typecheck_tid_ptr_compare Delta' id = true.  Theorem semax_Delta_subsumption: forall {CS: compspecs} {Espec: OracleKind}, forall Delta Delta' P c R, tycontext_sub Delta Delta' -> @semax CS Espec Delta P c R -> @semax CS Espec Delta' P c R.  Lemma rvalue_cenv_sub: forall {CS CS'} (CSUB: cenv_sub (@cenv_cs CS) (@cenv_cs CS')) Delta e rho, tc_environ Delta rho -> @tc_expr CS Delta e rho |-- !! (@eval_expr CS e rho = @eval_expr CS' e rho). Lemma rvalue_cspecs_sub: forall {CS CS'} (CSUB: cspecs_sub  CS CS') Delta e rho, tc_environ Delta rho -> @tc_expr CS Delta e rho |-- !! (@eval_expr CS e rho = @eval_expr CS' e rho). Lemma lvalue_cspecs_sub: forall {CS CS'} (CSUB: cspecs_sub  CS CS') Delta e rho, tc_environ Delta rho -> @tc_lvalue CS Delta e rho |-- !! (@eval_lvalue CS e rho = @eval_lvalue CS' e rho).  Definition SETpre CS Delta id e P := |> (@tc_expr CS Delta e && @tc_temp_id id (typeof e) CS Delta e && @subst mpred id (@eval_expr CS e) P) || (EX cmp : Cop.binary_operation, EX e1 : expr, EX e2 : expr, EX ty : type, EX sh1 : share, EX sh2 : share, !! (e = Ebinop cmp e1 e2 ty /\ @sepalg.nonidentity share Share.Join_ba pa_share sh1 /\ @sepalg.nonidentity share Share.Join_ba pa_share sh2 /\ is_comparison cmp = true /\ eqb_type (typeof e1) int_or_ptr_type = false /\ eqb_type (typeof e2) int_or_ptr_type = false /\ typecheck_tid_ptr_compare Delta id = true) && |> (@tc_expr CS Delta e1 && @tc_expr CS Delta e2 && local ((` (blocks_match cmp)) (@eval_expr CS e1) (@eval_expr CS e2)) && ((` (mapsto_ sh1 (typeof e1))) (@eval_expr CS e1) * @TT (LiftEnviron mpred) (@LiftNatDed' mpred Nveric)) && ((` (mapsto_ sh2 (typeof e2))) (@eval_expr CS e2) * @TT (LiftEnviron mpred) (@LiftNatDed' mpred Nveric)) && @subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P)) || (EX sh : share, EX t2 : type, EX v2 : val, !! (typeof_temp Delta id = @Some type t2 /\ is_neutral_cast (typeof e) t2 = true /\ readable_share sh) && |> (@tc_lvalue CS Delta e && local (` (tc_val (typeof e) v2)) && ((` (mapsto sh (typeof e))) (@eval_lvalue CS e) (` v2) * @TT (LiftEnviron mpred) (@LiftNatDed' mpred Nveric)) && @subst mpred id (` v2) P)) || (EX sh : share, EX e1 : expr, EX t1 : type, EX v2 : val, !! (e = Ecast e1 t1 /\ typeof_temp Delta id = @Some type t1 /\ cast_pointer_to_bool (typeof e1) t1 = false /\ readable_share sh) && |> (@tc_lvalue CS Delta e1 && local ((` (tc_val t1)) (` (eval_cast (typeof e1) t1 v2))) && ((` (mapsto sh (typeof e1))) (@eval_lvalue CS e1) (` v2) * @TT (LiftEnviron mpred) (@LiftNatDed' mpred Nveric)) && @subst mpred id (` (force_val (sem_cast (typeof e1) t1 v2))) P)).  Definition STOREpre CS Delta e1 e2 P := (EX sh : share, !! writable_share sh && |> (@tc_lvalue CS Delta e1 && @tc_expr CS Delta (Ecast e2 (typeof e1)) && ((` (mapsto_ sh (typeof e1))) (@eval_lvalue CS e1) * ((` (mapsto sh (typeof e1))) (@eval_lvalue CS e1) ((` force_val) ((` (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) -* P)))).  Definition CALLpre CS Delta ret a bl R := EX argsig : list (ident * type), EX retsig : type, EX cc : calling_convention, EX A : rmaps.TypeTree, EX P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred, EX Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred, EX NEP : @super_non_expansive A P, EX NEQ : @super_non_expansive A Q, EX ts : list Type, EX x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.SigType A f => @functors.MixVariantFunctorGenerator.fsig A (fun a => dtfr (f a)) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred, !! (Cop.classify_fun (typeof a) = Cop.fun_case_f (type_of_params argsig) retsig cc /\ (retsig = Tvoid -> ret = @None ident) /\ tc_fn_return Delta ret retsig) && (*|>*) (@tc_expr CS Delta a && @tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl) && (` (func_ptr (mk_funspec (argsig, retsig) cc A P Q NEP NEQ))) (@eval_expr CS a) && |>  (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (@make_args' (argsig, retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (maybe_retval (Q ts x) retsig ret -* R))).  (*A variant where (CSUB: cspecs_sub  CS CS') is replaced by (CSUB: cenv_sub (@cenv_cs CS) (@cenv_cs CS')) may be provable once tc_expr lemmas (and maybe eval_expr lemmas, sem_binop etc have been modified to only take a composite_env rather than a compspecs*)
Lemma semax_cssub {CS CS'} (CSUB: cspecs_sub  CS CS') Espec Delta P c R:
@semax CS Espec Delta P c R -> @semax CS' Espec Delta P c R.