Local Open Scope pred.
(* This file contains two parts: 1. Proof of semax_conseq. 2. Deriving simpler and older version of consequence rules from semax_conseq. *)
(* Part 1: Proof of semax_conseq *)
Definition bupd_ret_assert (Q: ret_assert): ret_assert :=
{| RA_normal := fun rho => bupd (RA_normal Q rho);
RA_break := fun rho => bupd (RA_break Q rho);
RA_continue := fun rho => bupd (RA_continue Q rho);
RA_return := fun v rho => bupd (RA_return Q v rho) |}.
(* The following four lemmas is not now used. but after deep embedded hoare logic (SL_as_Logic) is ported, the frame does not need to be quantified in the semantic definition of semax. Then, these two lemmas can replace the other two afterwards. *)
Definition except_0_ret_assert (Q: ret_assert): ret_assert :=
{| RA_normal := fun rho => (|> FF || RA_normal Q rho);
RA_break := fun rho => (|> FF || RA_break Q rho);
RA_continue := fun rho => (|> FF || RA_continue Q rho);
RA_return := fun v rho => (|> FF || RA_return Q v rho) |}.
(* Lemma rguard_except_0: forall {Espec: OracleKind} ge Delta f (F: environ -> pred rmap) Q k, rguard Espec ge Delta f (frame_ret_assert Q F) k = rguard Espec ge Delta f (frame_ret_assert (except_0_ret_assert Q) F) k. *)

Lemma semax_pre_post {CS: compspecs} {Espec: OracleKind}:
forall P' (R': ret_assert) Delta P c (R: ret_assert) ,
(forall rho,  !!(typecheck_environ Delta rho) &&  P rho |-- P' rho )%pred ->
(forall rho,  !!(typecheck_environ Delta rho)
&&  RA_normal R' rho |-- RA_normal R rho) ->
(forall rho, !! (typecheck_environ Delta rho)
&& RA_break R' rho |-- RA_break R rho) ->
(forall rho, !! (typecheck_environ Delta rho)
&& RA_continue R' rho |-- RA_continue R rho) ->
(forall vl rho, !! (typecheck_environ Delta rho)
&& RA_return R' vl rho |-- RA_return R vl rho) ->
semax Espec Delta P' c R' ->  semax Espec Delta P c R.