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'.