(*  { initial_core : nat -> M -> C -> Values.val -> list Values.val -> Prop; at_external : C -> M -> option (AST.external_function * AST.signature * list Values.val); after_external : option Values.val -> C -> M -> option C; halted : C -> Integers.Int.int -> Prop; corestep : G -> C -> M -> C -> M -> Prop; corestep_not_at_external : forall (ge : G) (m : M) (q : C) (m' : M) (q' : C), corestep ge q m q' m' -> at_external q m = None }  *)
Inductive state_sum (Cs Ct:Type): Type :=
| SState (c:Cs)
| TState (c:Ct).
Definition state_sum_options {Cs Ct:Type} (cso: option Cs): option (state_sum Cs Ct) :=
match cso with
| Some cs => Some (SState _ _ cs)
| _ => None
end.
Definition state_sum_optiont {Cs Ct:Type} (cto: option Ct): option (state_sum Cs Ct) :=
match cto with
| Some ct => Some (TState _ _ ct)
| _ => None
end.
Definition state_sum_optionms {Cs Ct M:Type} (cso: option (Cs * option M)): option (state_sum Cs Ct * option M) :=
match cso with
| Some (cs, m) => Some (SState _ _ cs, m)
| _ => None
end.
Definition state_sum_optionmt {Cs Ct M:Type} (cto: option (Ct * option M)): option (state_sum Cs Ct * option M) :=
match cto with
| Some (ct, m) => Some (TState _ _ ct, m)
| _ => None
end.
Definition lt_op (n: nat) (no:option nat): Prop :=
match no with
| None => True
| Some n' => n <= n' (* smallest is (Some 0) largest is None*)
end.
Definition initial_core_sum (no:option nat) (Cs Ct:Type) (M: Type)
(sinitial_core : nat -> M -> Cs -> M -> Values.val -> list Values.val -> Prop)
(tinitial_core : nat -> M -> Ct -> M -> Values.val -> list Values.val -> Prop):
nat -> M -> state_sum Cs Ct -> M -> Values.val -> list Values.val -> Prop :=
fun (n:nat) m c m' val vals =>
match c with
| SState c => lt_op n no /\ sinitial_core n m c m' val vals
| TState c => ~lt_op n no /\ tinitial_core n m c m' val vals
end.
Definition sum_func {Cs Ct X:Type} (fs:Cs -> X) (ft:Ct-> X) s:=
match s with
| SState c => (fs c)
| TState c => (ft c)
end.
Definition sum_func_option {Cs Ct Cs' Ct':Type}
(fs: Cs -> option Cs') (ft: Ct-> option Ct') s:=
match s with
| SState c => state_sum_options (fs c)
| TState c => state_sum_optiont (ft c)
end.
Definition at_external_sum (Cs Ct M: Type)
(sat_external: Cs -> M -> option (AST.external_function * list Values.val))
(tat_external: Ct -> M -> option (AST.external_function * list Values.val))
:=
sum_func sat_external tat_external.
Definition after_external_sum (Cs Ct M: Type)
(safter_external: option Values.val -> Cs -> M -> option Cs)
(tafter_external: option Values.val -> Ct -> M -> option Ct)
:=
fun vals c m => sum_func_option (fun c => safter_external vals c m)
(fun c => tafter_external vals c m) c.
Definition halted_sum Cs Ct
(shalted: Cs -> Integers.Int.int -> Prop)
(thalted: Ct -> Integers.Int.int -> Prop) :=
sum_func shalted thalted.
Inductive corestep_sum {M Cs Ct}
(scorestep: Cs -> M -> Cs -> M -> Prop)
(tcorestep: Ct -> M -> Ct -> M -> Prop):
state_sum Cs Ct -> M -> state_sum Cs Ct -> M -> Prop:=
| SCorestep: forall s m s' m',
scorestep s m s' m' ->
corestep_sum scorestep tcorestep (SState _ _ s) m (SState _ _ s') m'
| TCorestep: forall s m s' m',
tcorestep s m s' m' ->
corestep_sum scorestep tcorestep (TState _ _ s) m (TState _ _ s') m'.

Lemma corestep_not_at_external_sum:
forall M Cs Ct
{scorestep: Cs -> M -> Cs -> M -> Prop}
{sat_external: Cs -> M -> option (AST.external_function * list Values.val)}
(scorestep_not_at_external: forall (m : M) (q : Cs) (m' : M) (q' : Cs),
scorestep q m q' m' -> sat_external q m = None)
{tcorestep: Ct -> M -> Ct -> M -> Prop}
{tat_external: Ct -> M -> option (AST.external_function * list Values.val)}
(tcorestep_not_at_external: forall (m : M) (q : Ct) (m' : M) (q' : Ct),
tcorestep q m q' m' -> tat_external q m = None),
forall (m : M) (q : state_sum Cs Ct) (m' : M) (q' : state_sum Cs Ct),
corestep_sum scorestep tcorestep q m q' m' ->
at_external_sum _ _ _ sat_external tat_external q m = None.