Module CSHL_Defs := DerivedDefs(CSHL_Def).
(***************** SEMAX_LEMMAS ****************)

(*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').  Axiom 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.  Axiom 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).  Axiom 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.  Axiom 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).  Axiom 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).  Axiom 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).  Axiom semax_body_subsumption: forall cs V V' F F' f spec (SF: @semax_body V F cs f spec) (TS: tycontext_sub (func_tycontext f V F nil) (func_tycontext f V' F' nil)), @semax_body V' F' cs f spec.  Axiom semax_body_cenv_sub: forall {CS CS'} (CSUB: cspecs_sub CS CS') V G f spec (COMPLETE : Forall (fun it : ident * type => complete_type (@cenv_cs CS) (snd it) = true) (fn_vars f)), @semax_body V G CS f spec -> @semax_body V G CS' f spec.  (* THESE RULES FROM semax_loop *)
Axiom 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.