Definition has_opttyp (v : option val) (t : option typ) :=
match v, t with
None, None => True
| Some v, Some t => Val.has_type v t
| _, _ => False
end.
Section safety.
Context {G C M Z:Type}.
Context {genv_symb: G -> injective_PTree block}.
Context {Hrel: nat -> M -> M -> Prop}.
Context (Hcore:@CoreSemantics C M).
Variable (Hspec:external_specification M external_function Z).
Variable ge : G.
Inductive safeN_ : nat -> Z -> C -> M -> Prop :=
| safeN_0: forall z c m, safeN_ O z c m
| safeN_step:
forall n z c m c' m',
corestep Hcore c m c' m' ->
safeN_ n z c' m' ->
safeN_ (S n) z c m
| safeN_external:
forall n z c m e args x,
at_external Hcore c m = Some (e,args) ->
ext_spec_pre Hspec e x (genv_symb ge) (sig_args (ef_sig e)) args z m ->
(forall ret m' z' n'
(Hargsty : Val.has_type_list args (sig_args (ef_sig e)))
(Hretty : has_opttyp ret (sig_res (ef_sig e))),
(n' <= n)%nat ->
Hrel n' m m' ->
ext_spec_post Hspec e x (genv_symb ge) (sig_res (ef_sig e)) ret z' m' ->
exists c',
after_external Hcore ret c m' = Some c' /\
safeN_ n' z' c' m') ->
safeN_ (S n) z c m
| safeN_halted:
forall n z c m i,
halted Hcore c i ->
ext_spec_exit Hspec (Some (Vint i)) z m ->
safeN_ n z c m.
Definition corestep_fun  :=
forall m q m1 q1 m2 q2 ,
corestep Hcore q m q1 m1 ->
corestep Hcore q m q2 m2 ->
(q1, m1) = (q2, m2).

Lemma safe_corestepN_backward:
forall z c m c' m' n n0,
corestepN Hcore n0 c m c' m' ->
safeN_ (n - n0) z c' m' ->
safeN_ n z c m.