(*Obtained from Cminor.state by deleting the memory components.*)
Inductive CSharpMin_core: Type :=
  | CSharpMin_State:                      (**r Execution within a function *)
      forall (f: function)              (**r currently executing function  *)
             (s: stmt)                  (**r statement under consideration *)
             (k: cont)                  (**r its continuation -- what to do next *)
             (e: Csharpminor.env)                   (**r current local environment *)
             (le: Csharpminor.temp_env),             (**r current temporary environment *)
      CSharpMin_core
  | CSharpMin_Callstate:                  (**r Invocation of a function *)
      forall (f: fundef)                (**r function to invoke *)
             (args: list val)           (**r arguments provided by caller *)
             (k: cont),                  (**r what to do next  *)
      CSharpMin_core
  | CSharpMin_Returnstate:                (**r Return from a function *)
      forall (v: val)                   (**r Return value *)
             (k: cont),                  (**r what to do next *)
      CSharpMin_core.(*Obtained from Cminor.state by deleting the memory components.*)
Inductive CSharpMin_core: Type :=
  | CSharpMin_State:                      (**r Execution within a function *)
      forall (f: function)              (**r currently executing function  *)
             (s: stmt)                  (**r statement under consideration *)
             (k: cont)                  (**r its continuation -- what to do next *)
             (e: Csharpminor.env)                   (**r current local environment *)
             (le: Csharpminor.temp_env),             (**r current temporary environment *)
      CSharpMin_core
  | CSharpMin_Callstate:                  (**r Invocation of a function *)
      forall (f: fundef)                (**r function to invoke *)
             (args: list val)           (**r arguments provided by caller *)
             (k: cont),                  (**r what to do next  *)
      CSharpMin_core
  | CSharpMin_Returnstate:                (**r Return from a function *)
      forall (v: val)                   (**r Return value *)
             (k: cont),                  (**r what to do next *)
      CSharpMin_core.(*Obtained from Cminor.state by deleting the memory components.*)
Inductive CSharpMin_core: Type :=
  | CSharpMin_State:                      (**r Execution within a function *)
      forall (f: function)              (**r currently executing function  *)
             (s: stmt)                  (**r statement under consideration *)
             (k: cont)                  (**r its continuation -- what to do next *)
             (e: Csharpminor.env)                   (**r current local environment *)
             (le: Csharpminor.temp_env),             (**r current temporary environment *)
      CSharpMin_core
  | CSharpMin_Callstate:                  (**r Invocation of a function *)
      forall (f: fundef)                (**r function to invoke *)
             (args: list val)           (**r arguments provided by caller *)
             (k: cont),                  (**r what to do next  *)
      CSharpMin_core
  | CSharpMin_Returnstate:                (**r Return from a function *)
      forall (v: val)                   (**r Return value *)
             (k: cont),                  (**r what to do next *)
      CSharpMin_core.(*Obtained from Cminor.state by deleting the memory components.*)
Inductive CSharpMin_core: Type :=
  | CSharpMin_State:                      (**r Execution within a function *)
      forall (f: function)              (**r currently executing function  *)
             (s: stmt)                  (**r statement under consideration *)
             (k: cont)                  (**r its continuation -- what to do next *)
             (e: Csharpminor.env)                   (**r current local environment *)
             (le: Csharpminor.temp_env),             (**r current temporary environment *)
      CSharpMin_core
  | CSharpMin_Callstate:                  (**r Invocation of a function *)
      forall (f: fundef)                (**r function to invoke *)
             (args: list val)           (**r arguments provided by caller *)
             (k: cont),                  (**r what to do next  *)
      CSharpMin_core
  | CSharpMin_Returnstate:                (**r Return from a function *)
      forall (v: val)                   (**r Return value *)
             (k: cont),                  (**r what to do next *)
      CSharpMin_core.Definition ToState (q:CSharpMin_core) (m:mem): Csharpminor.state :=
  match q with
     CSharpMin_State f s k sp e => State f s k sp e m
   | CSharpMin_Callstate f args k => Callstate f args k m
   | CSharpMin_Returnstate v k => Returnstate v k m
  end.Definition FromState (c: Csharpminor.state) : CSharpMin_core * mem :=
  match c with
     State f s k sp e m => (CSharpMin_State f s k sp e, m)
   | Callstate f args k m => (CSharpMin_Callstate f args k, m)
   | Returnstate v k m => (CSharpMin_Returnstate v k, m)
  end.Definition CSharpMin_at_external (c: CSharpMin_core) : option (external_function * signature * list val) :=
  match c with
  | CSharpMin_State _ _ _ _ _ => None
  | CSharpMin_Callstate fd args k => match fd with
                                  Internal f => None
                                | External ef => Some (ef, ef_sig ef, args)
                              end
  | CSharpMin_Returnstate v k => None
 end.Definition CSharpMin_after_external (vret: option val) (c: CSharpMin_core) : option CSharpMin_core :=
  match c with
    CSharpMin_Callstate fd args k =>
         match fd with
            Internal f => None
          | External ef => match vret with
                             None => Some (CSharpMin_Returnstate Vundef k)
                           | Some v => Some (CSharpMin_Returnstate v k)
                           end
         end
  | _ => None
  end.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.Inductive CSharpMin_corestep (ge : genv) : CSharpMin_core -> mem -> CSharpMin_core ->  mem -> Prop :=
   csharpmin_corestep_skip_seq: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kseq s k) e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_skip_block: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f Sskip (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | csharpmin_corestep_skip_call: forall f k e le m m',
      is_call_cont k ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f Sskip k e le) m
        (CSharpMin_Returnstate Vundef k) m'

  | csharpmin_corestep_set: forall f id a k e le m v,
      eval_expr ge e le m a v ->
      CSharpMin_corestep ge (CSharpMin_State f (Sset id a) k e le) m
        (CSharpMin_State f Sskip k e (PTree.set id v le)) m

  | csharpmin_corestep_store: forall f chunk addr a k e le m vaddr v m',
      eval_expr ge e le m addr vaddr ->
      eval_expr ge e le m a v ->
      Mem.storev chunk m vaddr v = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sstore chunk addr a) k e le) m
        (CSharpMin_State f Sskip k e le) m'

  | csharpmin_corestep_call: forall f optid sig a bl k e le m vf vargs fd,
      eval_expr ge e le m a vf ->
      eval_exprlist ge e le m bl vargs ->
      Genv.find_funct ge vf = Some fd ->
      funsig fd = sig ->
      CSharpMin_corestep ge (CSharpMin_State f (Scall optid sig a bl) k e le) m
        (CSharpMin_Callstate fd vargs (Kcall optid f e le k)) m

(* WE DO NOT TREAT BUILTINS
  | csharpmin_corestep_builtin: forall f optid ef bl k e le m vargs t vres m',
      eval_exprlist ge e le m bl vargs ->
      external_call ef ge vargs m t vres m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sbuiltin optid ef bl) k e le) m
         (CSharpMin_State f Sskip k e (Cminor.set_optvar optid vres le)) m'
*)

  | csharpmin_corestep_seq: forall f s1 s2 k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sseq s1 s2) k e le) m
        (CSharpMin_State f s1 (Kseq s2 k) e le) m

  | csharpmin_corestep_ifthenelse: forall f a s1 s2 k e le m v b,
      eval_expr ge e le m a v ->
      Val.bool_of_val v b ->
      CSharpMin_corestep ge (CSharpMin_State f (Sifthenelse a s1 s2) k e le) m
        (CSharpMin_State f (if b then s1 else s2) k e le) m

  | csharpmin_corestep_loop: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sloop s) k e le) m
        (CSharpMin_State f s (Kseq (Sloop s) k) e le) m

  | csharpmin_corestep_block: forall f s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sblock s) k e le) m
        (CSharpMin_State f s (Kblock k) e le) m

  | csharpmin_corestep_exit_seq: forall f n s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit n) (Kseq s k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m
  | csharpmin_corestep_exit_block_0: forall f k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit O) (Kblock k) e le) m
        (CSharpMin_State f Sskip k e le) m
  | step_exit_block_S: forall f n k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Sexit (S n)) (Kblock k) e le) m
        (CSharpMin_State f (Sexit n) k e le) m

  | csharpmin_corestep_switch: forall f a cases k e le m n,
      eval_expr ge e le m a (Vint n) ->
      CSharpMin_corestep ge (CSharpMin_State f (Sswitch a cases) k e le) m
        (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e le) m

  | csharpmin_corestep_return_0: forall f k e le m m',
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn None) k e le) m
        (CSharpMin_Returnstate Vundef (call_cont k)) m'
  | csharpmin_corestep_return_1: forall f a k e le m v m',
      eval_expr ge e le m a v ->
      Mem.free_list m (blocks_of_env e) = Some m' ->
      CSharpMin_corestep ge (CSharpMin_State f (Sreturn (Some a)) k e le) m
        (CSharpMin_Returnstate v (call_cont k)) m'
  | csharpmin_corestep_label: forall f lbl s k e le m,
      CSharpMin_corestep ge (CSharpMin_State f (Slabel lbl s) k e le) m
        (CSharpMin_State f s k e le) m

  | csharpmin_corestep_goto: forall f lbl k e le m s' k',
      find_label lbl f.(fn_body) (call_cont k) = Some(s', k') ->
      CSharpMin_corestep ge (CSharpMin_State f (Sgoto lbl) k e le) m
        (CSharpMin_State f s' k' e le) m

  | csharpmin_corestep_internal_function: forall f vargs k m m1 e le,
      list_norepet (map fst f.(fn_vars)) ->
      list_norepet f.(fn_params) ->
      list_disjoint f.(fn_params) f.(fn_temps) ->
      alloc_variables empty_env m (fn_vars f) e m1 ->
      bind_parameters f.(fn_params) vargs (create_undef_temps f.(fn_temps)) = Some le ->
      CSharpMin_corestep ge (CSharpMin_Callstate (Internal f) vargs k) m
        (CSharpMin_State f f.(fn_body) k e le) m1
(*
  | csharpmin_corestep_external_function: forall ef vargs k m t vres m',
      external_call ef ge vargs m t vres m' ->
      step (Callstate (External ef) vargs k) m
         t (Returnstate vres k m')
*)
  | csharpmin_corestep_return: forall v optid f e le k m,
      CSharpMin_corestep ge (CSharpMin_Returnstate v (Kcall optid f e le k)) m
        (CSharpMin_State f Sskip k e (Cminor.set_optvar optid v le)) m.

Lemma CSharpMin_corestep_not_at_external: forall ge m q m' q', CSharpMin_corestep ge q m q' m' -> CSharpMin_at_external q = None.