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 convergent_controls_safe :
forall m q1 q2,
(at_external Hcore q1 m = at_external Hcore q2 m) ->
(forall ret m q', after_external Hcore ret q1 m = Some q' ->
after_external Hcore ret q2 m = Some q') ->
(halted Hcore q1 = halted Hcore q2) ->
(forall q' m', corestep Hcore q1 m q' m' ->
corestep Hcore q2 m q' m') ->
(forall n z, safeN_ n z q1 m -> safeN_ n z q2 m).