Local Open Scope nat_scope.
Definition control_as_safe {Espec: OracleKind} ge n ctl1 ctl2 :=
forall (ora : OK_ty) (ve : env) (te : temp_env) (m : juicy_mem) (n' : nat),
n' <= n ->
jsafeN (@OK_spec Espec) ge n' ora (State ve te ctl1) m ->
jsafeN (@OK_spec Espec) ge n' ora (State ve te ctl2) m.
Fixpoint prebreak_cont (k: cont) : cont :=
match k with
| Kloop1 s e3 :: k' => k
| Kseq s :: k' => prebreak_cont k'
| Kloop2 s e3 :: k' => k
| Kswitch :: k' => k
| _ =>  nil (* stuck *)
end.

(* Specifications: *)
Lemma prebreak_cont_is: forall k,
match (prebreak_cont k) with
| Kloop1 _ _ :: _ => True
| Kloop2 _ _ :: _ => True
| Kswitch :: _ => True
| nil => True
| _ => False
end.
Lemma find_label_prefix:
forall lbl s ctl k, find_label lbl s ctl = Some k -> exists j, k = j++ctl
with
find_label_ls_prefix:
forall lbl s ctl k, find_label_ls lbl s ctl = Some k -> exists j, k = j++ctl.
Lemma find_label_None:
forall lbl s ctl, find_label lbl s ctl = None -> forall ctl', find_label lbl s ctl' = None
with
find_label_ls_None:
forall lbl s ctl, find_label_ls lbl s ctl = None ->  forall ctl', find_label_ls lbl s ctl' = None.
Lemma find_label_prefix2':
forall lbl s k1 pre, find_label lbl s k1 = Some (pre++k1) ->
forall k2, find_label lbl s k2 = Some (pre++k2)
with find_label_ls_prefix2':
forall lbl s k1 pre, find_label_ls lbl s k1 = Some (pre++k1) ->
forall k2, find_label_ls lbl s k2 = Some (pre++k2) .
Lemma find_label_prefix2:
forall lbl s pre j ctl1 ctl2,
find_label lbl s (pre++ctl1) = Some (j++ctl1) ->
find_label lbl s (pre++ctl2) = Some (j++ctl2).
Lemma control_as_safe_bupd {Espec: OracleKind}: forall ge n ctl1 ctl2, control_as_safe ge n ctl1 ctl2 ->
forall (ora : OK_ty) (ve : env) (te : temp_env) (m : juicy_mem) (n' : nat),
n' <= n ->
jm_bupd ora (jsafeN (@OK_spec Espec) ge n' ora (State ve te ctl1)) m ->
jm_bupd ora (jsafeN (@OK_spec Espec) ge n' ora (State ve te ctl2)) m.
Lemma corestep_preservation_lemma {Espec: OracleKind}:
forall ge ctl1 ctl2 ora ve te m n c l c' m',
filter_seq ctl1 = filter_seq ctl2 ->
(forall k : list cont', control_as_safe ge n (k ++ ctl1) (k ++ ctl2)) ->
control_as_safe ge (S n) ctl1 ctl2 ->
jstep (cl_core_sem ge) (State ve te (c :: l ++ ctl1)) m c' m' ->
jm_bupd ora (jsafeN (@OK_spec Espec) ge n ora c') m' ->
exists c2 : corestate,
exists m2 : juicy_mem,
jstep (cl_core_sem ge) (State ve te (c :: l ++ ctl2)) m c2 m2 /\
jm_bupd ora (jsafeN (@OK_spec Espec) ge n ora c2) m2.
Lemma control_as_safe_le {Espec: OracleKind}:
forall n' n ge ctl1 ctl2, n' <= n -> control_as_safe ge n ctl1 ctl2 -> control_as_safe ge n' ctl1 ctl2.
Lemma control_suffix_safe {Espec: OracleKind}:
forall
ge n ctl1 ctl2 k,
filter_seq ctl1 = filter_seq ctl2 ->
control_as_safe ge n ctl1 ctl2 ->
control_as_safe ge n (k ++ ctl1) (k ++ ctl2).
Lemma guard_safe_adj {Espec: OracleKind}:
forall
psi Delta P k1 k2,
current_function k1 = current_function k2 ->
(forall ora m ve te n,
jsafeN (@OK_spec Espec) psi n ora (State ve te k1) m ->
jsafeN (@OK_spec Espec) psi n ora (State ve te k2) m) ->
guard Espec psi Delta P k1 |-- guard Espec psi Delta P k2.
Lemma assert_safe_adj:
forall {Espec: OracleKind} ge ve te k k' rho,
(forall n, control_as_safe ge n k k') ->
assert_safe Espec ge ve te k rho |-- assert_safe Espec ge ve te k' rho.
Lemma assert_safe_adj':
forall {Espec: OracleKind} ge ve te k k' rho P w,
(forall n, control_as_safe ge n k k') ->
app_pred (P >=> assert_safe Espec ge ve te k rho) w ->
app_pred (P >=> assert_safe Espec ge ve te k' rho) w.
Lemma rguard_adj:
forall {Espec: OracleKind} ge Delta R k k',
current_function k = current_function k' ->
(forall ek vl n, control_as_safe ge n (exit_cont ek vl k) (exit_cont ek vl k')) ->
rguard Espec ge Delta R k |-- rguard Espec ge Delta R k'.
Lemma assert_safe_last': forall {Espec: OracleKind} ge ve te ctl rho w,
(age1 w <> None -> assert_safe Espec ge ve te ctl rho w) ->
assert_safe Espec ge ve te ctl rho w.
Lemma pjoinable_emp_None {A}{JA: Join A}{PA: Perm_alg A}{SA: Sep_alg A}:
forall w: option (psepalg.lifted JA), identity w ->  w=None.
Lemma pjoinable_None_emp {A}{JA: Join A}{PA: Perm_alg A}{SA: Sep_alg A}:
identity (None: option (psepalg.lifted JA)).
Lemma unage_mapsto:
forall sh t v1 v2 w, age1 w <> None -> (|> mapsto sh t v1 v2) w -> mapsto sh t v1 v2 w.
Lemma semax_extensionality_Delta {CS: compspecs} {Espec: OracleKind}:
forall Delta Delta' P c R,
tycontext_sub Delta Delta' ->
semax Espec Delta P c R -> semax Espec Delta' P c R.