Definition Hrel n' m m' :=
    n' = level m' /\
    (level m' < level m)%nat /\
    pures_eq (m_phi m) (m_phi m').Inductive jsafeN_:
    nat -> Z -> C -> juicy_mem -> Prop :=
  | jsafeN_0: forall z c m, jsafeN_ O z c m
  | jsafeN_step:
      forall n z c m c' m',
      jstep Hcore c m c' m' ->
      jm_bupd z (jsafeN_ n z c') m' ->
      jsafeN_ (S n) z c m
  | jsafeN_external:
      forall n z c m e args x,
      j_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',
           semantics.after_external Hcore ret c (m_dry m') = Some c' /\
           jm_bupd z' (jsafeN_ n' z' c') m') ->
      jsafeN_ (S n) z c m
  | jsafeN_halted:
      forall n z c m i,
      semantics.halted Hcore c i ->
      ext_spec_exit Hspec (Some (Vint i)) z m ->
      jsafeN_ n z c m.Inductive jsafeN_:
    nat -> Z -> C -> juicy_mem -> Prop :=
  | jsafeN_0: forall z c m, jsafeN_ O z c m
  | jsafeN_step:
      forall n z c m c' m',
      jstep Hcore c m c' m' ->
      jm_bupd z (jsafeN_ n z c') m' ->
      jsafeN_ (S n) z c m
  | jsafeN_external:
      forall n z c m e args x,
      j_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',
           semantics.after_external Hcore ret c (m_dry m') = Some c' /\
           jm_bupd z' (jsafeN_ n' z' c') m') ->
      jsafeN_ (S n) z c m
  | jsafeN_halted:
      forall n z c m i,
      semantics.halted Hcore c i ->
      ext_spec_exit Hspec (Some (Vint i)) z m ->
      jsafeN_ n z c m.Inductive jsafeN_:
    nat -> Z -> C -> juicy_mem -> Prop :=
  | jsafeN_0: forall z c m, jsafeN_ O z c m
  | jsafeN_step:
      forall n z c m c' m',
      jstep Hcore c m c' m' ->
      jm_bupd z (jsafeN_ n z c') m' ->
      jsafeN_ (S n) z c m
  | jsafeN_external:
      forall n z c m e args x,
      j_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',
           semantics.after_external Hcore ret c (m_dry m') = Some c' /\
           jm_bupd z' (jsafeN_ n' z' c') m') ->
      jsafeN_ (S n) z c m
  | jsafeN_halted:
      forall n z c m i,
      semantics.halted Hcore c i ->
      ext_spec_exit Hspec (Some (Vint i)) z m ->
      jsafeN_ n z c m.Inductive jsafeN_:
    nat -> Z -> C -> juicy_mem -> Prop :=
  | jsafeN_0: forall z c m, jsafeN_ O z c m
  | jsafeN_step:
      forall n z c m c' m',
      jstep Hcore c m c' m' ->
      jm_bupd z (jsafeN_ n z c') m' ->
      jsafeN_ (S n) z c m
  | jsafeN_external:
      forall n z c m e args x,
      j_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',
           semantics.after_external Hcore ret c (m_dry m') = Some c' /\
           jm_bupd z' (jsafeN_ n' z' c') m') ->
      jsafeN_ (S n) z c m
  | jsafeN_halted:
      forall n z c m i,
      semantics.halted Hcore c i ->
      ext_spec_exit Hspec (Some (Vint i)) z m ->
      jsafeN_ n z c m.Inductive jsafeN_:
    nat -> Z -> C -> juicy_mem -> Prop :=
  | jsafeN_0: forall z c m, jsafeN_ O z c m
  | jsafeN_step:
      forall n z c m c' m',
      jstep Hcore c m c' m' ->
      jm_bupd z (jsafeN_ n z c') m' ->
      jsafeN_ (S n) z c m
  | jsafeN_external:
      forall n z c m e args x,
      j_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',
           semantics.after_external Hcore ret c (m_dry m') = Some c' /\
           jm_bupd z' (jsafeN_ n' z' c') m') ->
      jsafeN_ (S n) z c m
  | jsafeN_halted:
      forall n z c m i,
      semantics.halted Hcore c i ->
      ext_spec_exit Hspec (Some (Vint i)) z m ->
      jsafeN_ n z c m.

Lemma juicy_core_sem_preserves_corestep_fun {C} (csem: @CoreSemantics C mem) : corestep_fun csem -> corestep_fun (juicy_core_sem csem).