Definition val_has_type_opt' (v: option val) (ty: typ) :=
match v with
| None => True
| Some v' => Val.has_type v' ty
end.
Definition val_has_type_opt (v: option val) (sig: signature) :=
val_has_type_opt' v (proj_sig_res sig).
(** A "core semantics represents" a fairly traditional, sequential, small step semantics of computation.  They are designed to cooperate with "extensions" which give semantics to primtive constructs not defined by the extensible semantics (e.g., external function calls).  The [G] type parameter is the type of global environments, the type [C] is the type of core states, and the type [E] is the type of extension requests.  The [at_external] function gives a way to determine when the sequential execution is blocked on an extension call, and to extract the data necessary to execute the call. [after_external] give a way to inject the extension call results back into the sequential state so execution can continue.  (* Previsouly, we had additionally  a) a type parameter [D] that stood for the type of initialization data, eg list (ident * globvar V).  b) a clause [initial_mem] that characterized memories suitable at module entry.  But we eliminated these, since these constructs refer to PROGRAMS, not CORES.  *)
[initial_core] that produces the core state
corresponding to an entry point of a module.
The arguments are the genv, a pointer to the
function to run, and the arguments for that function.
The [halted] predicate indicates when a program state
has reached a halted state, and what it's exit code/return value is
when it has reached such a state.
[corestep] is the fundamental small-step relation for
the sequential semantics.
The remaining properties give basic sanity properties which constrain
the behavior of programs.
1) a state cannot be both blocked on an extension call
and also step,
2) a state cannot both step and be halted
3) a state cannot both be halted and blocked on an external call
4) after external calls, cores are back in a "runnable" state
(NOTE: this axiom may be removed at some point) *)
Record CoreSemantics {G C M : Type} : Type :=
{ initial_core : G -> val -> list val -> option C;
at_external : C -> option (external_function * signature * list val);
after_external : option val -> C -> option C;
halted : C -> option val;
corestep : G -> C -> M -> C -> M -> Prop;
corestep_not_at_external: forall ge m q m' q',
corestep ge q m q' m' -> at_external q = None;
corestep_not_halted: forall ge m q m' q',
corestep ge q m q' m' -> halted q = None;
at_external_halted_excl: forall q,
at_external q = None \/ halted q = None;
after_at_external_excl : forall retv q q',
after_external retv q = Some q' -> at_external q' = None
}.
Implicit Arguments CoreSemantics [].
Definition corestep_fun {G C M : Type} (sem : CoreSemantics G C M) :=
forall (m m' m'' : M) ge c c' c'',
corestep sem ge c m c' m' ->
corestep sem ge c m c'' m'' ->
c'=c'' /\ m'=m''.
(** This module defines a core semantics typeclass, for building functors over coresem-like objects.  *)
Module Coresem.
Class t {G C M : Type} : Type :=
{ initial_core : G -> val -> list val -> option C
; at_external : C -> option (external_function * signature * list val)
; after_external : option val -> C -> option C
; halted : C -> option val
; corestep : G -> C -> M -> C -> M -> Prop
; corestep_not_at_external :
forall ge m q m' q', corestep ge q m q' m' -> at_external q = None
; corestep_not_halted:
forall ge m q m' q', corestep ge q m q' m' -> halted q = None
; at_external_halted_excl:
forall q, at_external q = None \/ halted q = None
; after_at_external_excl :
forall retv q q', after_external retv q = Some q' -> at_external q' = None
}.
End Coresem.
Instance core_instance (G C M: Type) (csem: @CoreSemantics G C M) : @Coresem.t G C M :=
Coresem.Build_t G C M
(initial_core csem)
(at_external csem)
(after_external csem)
(halted csem)
(corestep csem)
(corestep_not_at_external csem)
(corestep_not_halted csem)
(at_external_halted_excl csem)
(after_at_external_excl csem).
(**  Multistepping *)
Section corestepN.
Context {G C M E:Type} (Sem:CoreSemantics G C M) (ge:G).
Fixpoint corestepN (n:nat) : C -> M -> C -> M -> Prop :=
match n with
| O => fun c m c' m' => (c,m) = (c',m')
| S k => fun c1 m1 c3 m3 => exists c2, exists m2,
corestep Sem ge c1 m1 c2 m2 /\
corestepN k c2 m2 c3 m3
end.

(* Specifications: *)
Lemma corestepN_add : forall n m c1 m1 c3 m3,
corestepN (n+m) c1 m1 c3 m3 <->
exists c2, exists m2,
corestepN n c1 m1 c2 m2 /\
corestepN m c2 m2 c3 m3.