Module CSHL_MinimumLogic := DeepEmbeddedMinimumSeparationLogic.
Definition semax_set := @DeepEmbeddedMinimumSeparationLogic.SetB.semax_set_backward.
Arguments semax {_} {_} _ _ _ _.
(*moved up 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 semax_loop_nocontinue: forall {CS: compspecs} {Espec: OracleKind}, forall Delta P body incr R, @semax CS Espec Delta P (Ssequence body incr) (loop_nocontinue_ret_assert P R) -> @semax CS Espec Delta P (Sloop body incr) R.  Lemma semax_if_seq: forall {CS: compspecs} {Espec: OracleKind} Delta P e c1 c2 c Q, semax Delta P (Sifthenelse e (Ssequence c1 c) (Ssequence c2 c)) Q -> semax Delta P (Ssequence (Sifthenelse e c1 c2) c) Q.  Lemma semax_loop_unroll1: forall {CS: compspecs} {Espec: OracleKind} Delta P P' Q body incr R, @semax CS Espec Delta P body (loop1_ret_assert P' R) -> @semax CS Espec Delta P' incr (loop2_ret_assert Q R) -> @semax CS Espec Delta Q (Sloop body incr) R -> @semax CS Espec Delta P (Sloop body incr) R.  Theorem seq_assoc: forall {CS: compspecs} {Espec: OracleKind}, forall Delta P s1 s2 s3 R, @semax CS Espec Delta P (Ssequence s1 (Ssequence s2 s3)) R <-> @semax CS Espec Delta P (Ssequence (Ssequence s1 s2) s3) R.  Theorem semax_seq_skip: forall {CS: compspecs} {Espec: OracleKind}, forall Delta P s Q, @semax CS Espec Delta P s Q <-> @semax CS Espec Delta P (Ssequence s Sskip) Q.  Theorem semax_skip_seq: forall {CS: compspecs} {Espec: OracleKind}, forall Delta P s Q, @semax CS Espec Delta P s Q <-> @semax CS Espec Delta P (Ssequence Sskip s) Q.  Theorem semax_seq_Slabel: forall {CS:compspecs} {Espec: OracleKind}, forall Delta (P:environ -> mpred) (c1 c2:statement) (Q:ret_assert) l, @semax CS Espec Delta P (Ssequence (Slabel l c1) c2) Q <-> @semax CS Espec Delta P (Slabel l (Ssequence c1 c2)) Q.  Fixpoint fold_Ssequence lc := match lc with | nil => Sskip | c1 :: nil => c1 | c :: lc0 => Ssequence c (fold_Ssequence lc0) end.  Definition non_Sseq c := match c with | Ssequence _ _ => False | _ => True end.  Inductive unfold_Sseq_rel: statement -> list statement -> Prop := | singleton: forall c, non_Sseq c -> unfold_Sseq_rel c (c :: nil) | tl_step: forall c1 c2 lc, non_Sseq c1 -> unfold_Sseq_rel c2 lc -> unfold_Sseq_rel (Ssequence c1 c2) (c1 :: lc) | hd_step: forall c1 c2 c3 lc, unfold_Sseq_rel (Ssequence c1 (Ssequence c2 c3)) lc -> unfold_Sseq_rel (Ssequence (Ssequence c1 c2) c3) lc .  Lemma unfold_Sseq_rel_non_nil: forall {c} {P: Prop}, unfold_Sseq_rel c nil -> P.  Definition semax_equiv {CS: compspecs} {Espec: OracleKind} c1 c2: Prop := forall Delta P Q, semax Delta P c1 Q <-> semax Delta P c2 Q.  Lemma semax_equiv_seq: forall {CS: compspecs} {Espec: OracleKind} c1 c2 c3 c4, semax_equiv c1 c2 -> semax_equiv c3 c4 -> semax_equiv (Ssequence c1 c3) (Ssequence c2 c4).  Lemma semax_equiv_sym: forall {CS: compspecs} {Espec: OracleKind} c1 c2, semax_equiv c1 c2 -> semax_equiv c2 c1.  Lemma semax_equiv_trans: forall {CS: compspecs} {Espec: OracleKind} c1 c2 c3, semax_equiv c1 c2 -> semax_equiv c2 c3 -> semax_equiv c1 c3.  Lemma unfold_Sseq_rel_sound: forall {CS: compspecs} {Espec: OracleKind} c lc, unfold_Sseq_rel c lc -> semax_equiv (fold_Ssequence lc) c.  Lemma unfold_Ssequence_unfold_Sseq_rel: forall c, unfold_Sseq_rel c (unfold_Ssequence c).  Lemma unfold_Ssequence_sound: forall {CS: compspecs} {Espec: OracleKind} c, semax_equiv (fold_Ssequence (unfold_Ssequence c)) c.  Lemma semax_unfold_Ssequence': forall {CS: compspecs} {Espec: OracleKind} c1 c2, unfold_Ssequence c1 = unfold_Ssequence c2 -> (forall P Q Delta, semax Delta P c1 Q <-> semax Delta P c2 Q).  Lemma semax_unfold_Ssequence: forall {CS: compspecs} {Espec: OracleKind} c1 c2, unfold_Ssequence c1 = unfold_Ssequence c2 -> (forall P Q Delta, @semax CS Espec Delta P c1 Q -> @semax CS Espec Delta P c2 Q).  Lemma semax_fun_id: forall {CS: compspecs} {Espec: OracleKind}, forall id f Delta P Q c, (var_types Delta) ! id = None -> (glob_specs Delta) ! id = Some f -> (glob_types Delta) ! id = Some (type_of_funspec f) -> @semax CS Espec Delta (P && `(func_ptr f) (eval_var id (type_of_funspec f))) c Q -> @semax CS Espec Delta P c Q. intros. eapply semax_conseq; [| intros; apply derives_full_refl .. | apply H2]. reduceR. apply andp_right; [solve_andp |]. rewrite andp_comm. rewrite imp_andp_adjoint. rewrite imp_andp_adjoint. apply (allp_left _ id). apply (allp_left _ f). rewrite prop_imp by auto. apply exp_left; intros b. rewrite <- imp_andp_adjoint. rewrite <- imp_andp_adjoint. unfold local, lift1; unfold_lift; intro rho; simpl. unfold eval_var, func_ptr. apply (exp_right b). normalize. rewrite H3. apply andp_right; [| solve_andp]. apply prop_right. destruct H4 as [_ [? _]]. specialize (H4 id). rewrite H in H4. destruct (Map.get (ve_of rho) id) as [[? ?] |]; [exfalso | auto]. specialize (H4 t). destruct H4 as [_ ?]. specialize (H4 ltac:(eexists; eauto)). congruence. Qed. *)
(*Lemma semax_fun_id: forall {CS: compspecs} {Espec: OracleKind}, forall id f Delta P Q c, (var_types Delta) ! id = None -> (glob_specs Delta) ! id = Some f -> (glob_types Delta) ! id = Some (type_of_funspec f) -> @semax CS Espec Delta (P && `(func_ptr f) (eval_var id (type_of_funspec f))) c Q -> @semax CS Espec Delta P c Q. *)

Lemma semax_loop_nocontinue1:
forall CS Espec Delta Pre s1 s2 s3 Post,
nocontinue s1 = true ->
nocontinue s2 = true ->
nocontinue s3 = true ->
@semax CS Espec Delta Pre (Sloop (Ssequence s1 (Ssequence s2 s3)) Sskip) Post ->
@semax CS Espec Delta Pre (Sloop (Ssequence s1 s2) s3) Post.