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
.

(* Specifications: *)
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.
Lemma nocontinue_ls_spec: forall sl, nocontinue_ls sl = true -> nocontinue (seq_of_labeled_statement sl) = true.
Lemma nocontinue_ls_spec': forall sl n, nocontinue_ls sl = true -> nocontinue (seq_of_labeled_statement (select_switch n sl)) = true.
Lemma semax_nocontinue_inv:
forall CS Espec Delta Pre s Post Post',
nocontinue s = true ->
RA_normal Post = RA_normal Post' ->
RA_break Post = RA_break Post' ->
RA_return Post = RA_return Post' ->
@semax CS Espec Delta Pre s Post -> @semax CS Espec Delta Pre s Post'.
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.
Lemma semax_convert_for_while':
forall CS Espec Delta Pre s1 e2 s3 s4 s5 Post,
nocontinue s4 = true ->
nocontinue s3 = true ->
@semax CS Espec Delta Pre
(Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post ->
@semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post.