(*Obtained from Cminor.state by deleting the memory components.*)
Inductive CMin_core: Type :=
| CMin_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 *)
(sp: val)                  (**r current stack pointer *)
(e: env),                   (**r current local environment *)
CMin_core
| CMin_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  *)
CMin_core
| CMin_Returnstate:                (**r Return from a function *)
forall (v: val)                   (**r Return value *)
(k: cont),                  (**r what to do next *)
CMin_core.
Definition ToState (q:CMin_core) (m:mem): Cminor.state :=
match q with
CMin_State f s k sp e => State f s k sp e m
| CMin_Callstate f args k => Callstate f args k m
| CMin_Returnstate v k => Returnstate v k m
end.
Definition FromState (c: Cminor.state) : CMin_core * mem :=
match c with
State f s k sp e m => (CMin_State f s k sp e, m)
| Callstate f args k m => (CMin_Callstate f args k, m)
| Returnstate v k m => (CMin_Returnstate v k, m)
end.
(* Definition CMin_init_mem (ge:genv)  (m:mem) d:  Prop:= Genv.alloc_variables ge Mem.empty d = Some m. (*Defined initial memory, by adapting the definition of Genv.init_mem*)
*)
(* initial_core : G -> val -> list val -> option C;*)
Definition CMin_initial_core (ge:Cminor.genv) (v: val) (args:list val): option CMin_core :=
match v with
Vptr b i =>
if Int.eq_dec i  Int.zero
then match Genv.find_funct_ptr ge b with
| None => None
| Some f => Some (CMin_Callstate f args Kstop)
end
else None
| _ => None
end.
(* Parameter CMin_MainIdent:ident.  Definition CMin_make_initial_core (ge:genv) (v: val) (args:list val): option CMin_core := match Genv.find_symbol ge CMin_MainIdent with None => None | Some b => match Genv.find_funct_ptr ge b with None => None | Some f => match funsig f with {| sig_args := sargs; sig_res := sres |} => match sargs, sres with nil, Some Tint => Some (CMin_Callstate f nil Kstop) (*args = nil???*)
| _ , _ => None
end
end
end
end.
*)
(*Original Cminor_semantics has this for initial states: Genv.find_symbol ge p.(prog_main) = Some b -> Genv.find_funct_ptr ge b = Some f -> funsig f = mksignature nil (Some Tint) -> initial_state p (Callstate f nil Kstop m0).*)
Definition CMin_at_external (c: CMin_core) : option (external_function * signature * list val) :=
match c with
| CMin_State f s k sp e => None
| CMin_Callstate fd args k => match fd with
Internal f => None
| External ef => Some (ef, ef_sig ef, args)
end
| CMin_Returnstate v k => None
end.
Definition CMin_after_external (vret: option val) (c: CMin_core) : option CMin_core :=
match c with
CMin_Callstate fd args k =>
match fd with
Internal f => None
| External ef => match vret with
None => Some (CMin_Returnstate Vundef k)
| Some v => Some (CMin_Returnstate v k)
end
end
| _ => None
end.
Definition CMin_corestep (ge : genv)  (q : CMin_core) (m : mem) (q' : CMin_core) (m' : mem) : Prop.
destruct q; destruct q'.
(*State - State*)
apply (exists t, Cminor.step ge (State f s k sp e m)  t (State f0 s0 k0 sp0 e0 m')).
(*State - Callstate: two cases: step_call, step_tailcall*)
apply (exists t, Cminor.step ge (State f s k sp e m)  t (Callstate f0 args k0 m')).
(*State - Returnstate - three cases: step_skip_call, step_return_0, step_return_1*)
apply (exists t, Cminor.step ge (State f s k sp e m)  t (Returnstate v k0 m')).
(*Callstate - State: only case: step_internal_function*)
apply (match f with
Internal ff =>
exists t, Cminor.step ge (Callstate f args k m) t (State f0 s k0 sp e m')
| External _ => False
end).
(*Callstate - Callstate: no case*)
apply False.
(*Callstate - Returnstate: one case: step_external_function : we don't want this as a step in this semantics, since stepping should not happen at_external*)
apply False.
(*Returnstate - State: one case: step_return*)
apply (exists t, Cminor.step ge (Returnstate v k m) t (State f s k0 sp e m')).
(*Returnstate - Callstate: no case*)
apply False.
(*Returnstate - Returnstate: no case*)
apply False.
Defined.
Definition CMin_halted (q : CMin_core): option val :=
match q with
CMin_Returnstate v Kstop => Some v
| _ => None
end.
Definition CMin_core_sem : CoreSemantics genv CMin_core mem.
eapply @Build_CoreSemantics with (at_external:=CMin_at_external)
(after_external:=CMin_after_external) (corestep:=CMin_corestep)
(halted:=CMin_halted).
apply CMin_initial_core.
apply CMin_corestep_not_at_external.
apply CMin_corestep_not_halted.
apply CMin_at_external_halted_excl.
apply CMin_after_at_external_excl.
Defined.
(************************NOW SHOW THAT WE ALSO HAVE A COOPSEM******)
(*A global assumption we need on external calls, in particular builtins mem_wd deprecated Parameter external_call_mem_wd: forall (ef : external_function) (F V : Type) (ge : Genv.t F V) (vargs : list val) (m1 : mem) (t : trace) (vres : val) (m2 : mem), external_call ef ge vargs m1 t vres m2 -> mem_wd m1 -> mem_wd m2. *)
Definition coopstep g c m c' m' :=
CMin_corestep g c m c' m'.
Program Definition cmin_core_sem :
CoreSemantics Cminor.genv CMin_core mem :=
@Build_CoreSemantics _ _ _ (*_*)
(*cl_init_mem*)
CMin_initial_core
CMin_at_external
CMin_after_external
CMin_halted
coopstep
cmin_coopstep_not_at_external
cmin_coopstep_not_halted
CMin_at_external_halted_excl
CMin_after_at_external_excl.

Lemma CMin_core2state_injective: forall q m q' m',
ToState q m = ToState q' m' -> q'=q /\ m'=m.