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

(* Specifications: *)
Lemma begin_end_state_ctrace: forall {cmd state: Type} (ctr: trace (cmd * state)) cs mcs,
begin_end_state cs ctr mcs ->
begin_end_state (snd cs) (ctrace2trace ctr) (lift_function snd mcs).
Lemma begin_end_state_singleton_trace: forall {state: Type} (s: state) ms,
begin_end_state s (singleton_trace s ms) ms.
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'.