Definition trace (state: Type): Type := stream (state * MetaState state).
Identity Coercion trace_stream: trace >-> stream.
Definition singleton_trace {state: Type} s ms: trace state :=
fin_stream ((s, ms) :: nil).
Definition sequential_trace {state: Type} (tr: trace state) : Prop :=
forall k s ms s' ms',
tr k = Some (s, ms) ->
tr (S k) = Some (s' , ms') ->
ms = Terminating s'.
Definition sound_trace {state: Type} (R: state -> MetaState state -> Prop) (tr: trace state) : Prop :=
forall k s ms,
tr k = Some (s, ms) ->
R s ms.
Inductive begin_end_state {state: Type}: state -> trace state -> MetaState state -> Prop :=
| begin_end_empty: forall s, begin_end_state s empty_stream (Terminating s)
| begin_end_fin: forall s ms s' ms' tr n,
is_n_stream (S n) tr ->
tr 0 = Some (s, ms) ->
tr n = Some (s', ms') ->
begin_end_state s tr ms'
| begin_end_inf: forall s ms tr,
is_inf_stream tr ->
tr 0 = Some (s, ms) ->
begin_end_state s tr NonTerminating.
Definition begin_state {state: Type} (tr: trace state) (s: state): Prop :=
exists ms, begin_end_state s tr ms.
Definition end_state {state: Type} (tr: trace state) (ms: MetaState state): Prop :=
exists s, begin_end_state s tr ms.
Definition ctrace2trace
{cmd: Type}
{state: Type}: trace (cmd * state) -> trace state :=
stream_map (fun p => match p with ((c, s), mcs) => (s, lift_function snd mcs) end).

Lemma begin_end_state_singleton_trace_rev: forall {state: Type} (s s': state) ms ms',
begin_end_state s' (singleton_trace s ms) ms' ->
s = s' /\ ms = ms'.