Built with Alectryon, running Coq+SerAPI v8.18.0+0.18.1. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use instead of Ctrl.
[Loading ML file ring_plugin.cmxs (using legacy method) ... done]
[Loading ML file zify_plugin.cmxs (using legacy method) ... done]
[Loading ML file micromega_plugin.cmxs (using legacy method) ... done]
[Loading ML file btauto_plugin.cmxs (using legacy method) ... done]
[Loading ML file coq-itauto.plugin ... done]
From stdpp Require Import prelude. From Coq Require Import Streams. From VLSM.Lib Require Import Preamble ListExtras StreamExtras.

Core: VLSM Basics

This module provides basic VLSM infrastructure.

VLSM definition

The type of a VLSM

The type of a VLSM is a triple consisting of the underlying types of messages, states, and labels.
In Coq it is defined as a record taking message as parameter and having state and label as fields. message is a parameter to allow it to be easily shared by multiple VLSMs during composition.
Record VLSMType (message : Type) : Type :=
{
  state : Type;
  label : Type;
}.

Arguments state {_} _.
Arguments label {_} _.

VLSM class definition

VLSMMachine is parameterized by a VLSMType, and contains the remaining parameters to define a VLSM over the given types. These are the properties for initial states (initial_state_prop) and initial messages (initial_message_prop), from which we can immediately define the types initial_state (as states having the initial_state_property) and initial_message (as messages having the initial_message_property), a witness s0 that the initial_state is inhabited, and the transition function and validity predicate.
Record VLSMMachine {message : Type} (T : VLSMType message) : Type :=
{
  initial_state_prop : state T -> Prop;
  initial_state : Type := {s : state T | initial_state_prop s};
  s0 : Inhabited initial_state;
  initial_message_prop : message -> Prop;
  initial_message : Type := {m : message | initial_message_prop m};
  transition : label T -> state T * option message -> state T * option message;
  valid : label T -> state T * option message -> Prop;
}.

(* The & is a "bidirectionality hint", so that typechecking
   a VLSMMachine record definition will try to use the expected
   result type to determine <<T>> before typechecking the fields.
   Without this, the types of the values given for the fields would
   have to be written so they only mention the state and label type
   in ways that can be matched with [state ?T] and [label ?T].
*)
Arguments Build_VLSMMachine _ _ & _ _ _ _ _.

Arguments initial_state_prop {message T} VLSMMachine _, {message T VLSMMachine} _ : rename.
Arguments initial_state {message T} VLSMMachine : rename.
Arguments initial_message_prop {message T} VLSMMachine _, {message T VLSMMachine} _ : rename.
Arguments initial_message {message T} VLSMMachine : rename.
Arguments transition {message T} VLSMMachine _ _, {message T VLSMMachine} _ _ : rename.
Arguments valid {message T} VLSMMachine _ _, {message T VLSMMachine} _ _ : rename.

Definition option_initial_message_prop
  {message : Type} {T : VLSMType message} (M : VLSMMachine T) : option message -> Prop :=
    from_option (@initial_message_prop _ _ M) True.

Definition decidable_initial_messages_prop
  {message : Type} {T : VLSMType message} (M : VLSMMachine T) : Type :=
    forall (m : message), Decision (@initial_message_prop _ _ M m).

VLSM type definition

For technical reasons, e.g., the need to easily talk about VLSMs over the same set of messages and about VLSMs of the same type (over the same set of messages, labels and states), the VLSM definition is split into two parts, VLSMType and VLSMMachine, which are packaged together by the following definition.
Record VLSM (message : Type) : Type := mk_vlsm
{
  vlsm_type :> VLSMType message;
  vlsm_machine :> VLSMMachine vlsm_type;
}.

Arguments vlsm_type [message] v.
Arguments vlsm_machine [message] v.
Arguments mk_vlsm [message] [vlsm_type] vlsm_machine.

Section sec_traces.

Context
  {message : Type}
  {T : VLSMType message}
  .

Traces

We introduce the concept of a trace to formalize an execution of the protocol. It is abstracted as a pair (start, steps) where start is a state and steps is a tuple of objects which fully describe the transitions underwent during execution. Notably, steps might be infinite.
In Coq, we can define these objects (which we name transition_items) as consisting of:
Record transition_item : Type :=
{
  l : label T;
  input : option message;
  destination : state T;
  output : option message;
}.

Definition field_selector
  (field : transition_item -> option message) (m : message) (item : transition_item) : Prop :=
    field item = Some m.

Definition item_sends_or_receives (m : message) (item : transition_item) : Prop :=
  input item = Some m \/ output item = Some m.

Definition trace_has_message
  (message_selector : message -> transition_item -> Prop)
  (msg : message) (tr : list transition_item) : Prop :=
    List.Exists (message_selector msg) tr.

message: Type
T: VLSMType message
message_selector: message → transition_item → Prop
msg: message
prefix, suffix: list transition_item

trace_has_message message_selector msg prefix → trace_has_message message_selector msg (prefix ++ suffix)
message: Type
T: VLSMType message
message_selector: message → transition_item → Prop
msg: message
prefix, suffix: list transition_item

trace_has_message message_selector msg prefix → trace_has_message message_selector msg (prefix ++ suffix)
by intro Hprefix; apply Exists_app; left. Qed.
message: Type
T: VLSMType message
m: message
tr: list transition_item
Hobserved: trace_has_message item_sends_or_receives m tr

trace_has_message (field_selector input) m tr ∨ trace_has_message (field_selector output) m tr
message: Type
T: VLSMType message
m: message
tr: list transition_item
Hobserved: trace_has_message item_sends_or_receives m tr

trace_has_message (field_selector input) m tr ∨ trace_has_message (field_selector output) m tr
by unfold trace_has_message in *; rewrite !Exists_exists in *; firstorder. Qed.
Defines a message received but not sent by within the trace.
Definition trace_received_not_sent_before_or_after
  (tr : list transition_item) (m : message) : Prop :=
    trace_has_message (field_selector input) m tr /\
    ~ trace_has_message (field_selector output) m tr.
States that a property holds for all messages received but not sent by a trace.
Definition trace_received_not_sent_before_or_after_invariant
  (tr : list transition_item) (P : message -> Prop) : Prop :=
    forall (m : message), trace_received_not_sent_before_or_after tr m -> P m.

Inductive Trace : Type :=
| Finite : state T -> list transition_item -> Trace
| Infinite : state T -> Stream transition_item -> Trace.

Definition trace_first (tr : Trace) : state T :=
  match tr with
  | Finite s _ => s
  | Infinite s _ => s
  end.

Definition finite_trace_last (si : state T) (tr : list transition_item) : state T :=
  List.last (List.map destination tr) si.

Definition finite_trace_last_output (tr : list transition_item) : option message :=
  List.last (List.map output tr) None.

Definition finite_trace_nth
  (si : state T) (tr : list transition_item) : nat -> option (state T) :=
    nth_error (si :: List.map destination tr).

Definition trace_last (tr : Trace) : option (state T) :=
  match tr with
  | Finite s ls => Some (finite_trace_last s ls)
  | Infinite _ _ => None
  end.
This function extracts the nth state of a trace, where the sequence of states of a trace is obtained by appending the all destination states in the transition list/stream to the initial state of the trace.
Definition trace_nth (tr : Trace) (n : nat) : option (state T) :=
  match tr with
  | Finite s ls => finite_trace_nth s ls n
  | Infinite s st => Some (Str_nth n (Cons s (Streams.map destination st)))
  end.

End sec_traces.

Arguments Trace {message T}, {message} T.
Arguments transition_item {message} {T} , {message} T.
Arguments Build_transition_item {message T}, {message} T.
Arguments field_selector {_} {T} _ m item /.
Arguments item_sends_or_receives {_} {_} m item /.

Section sec_trace_lemmas.

Context
  [message : Type]
  [T : VLSMType message]
  .

message: Type
T: VLSMType message
tr: list transition_item
s: state T
Hlast: option_map destination (last_error tr) = Some s
default: state T

finite_trace_last default tr = s
message: Type
T: VLSMType message
tr: list transition_item
s: state T
Hlast: option_map destination (last_error tr) = Some s
default: state T

finite_trace_last default tr = s
message: Type
T: VLSMType message
tr: list transition_item
s: state T
Hlast: match last_error tr with | Some a => Some (destination a) | None => None end = Some s
default: state T

finite_trace_last default tr = s
message: Type
T: VLSMType message
tr: list transition_item
s: state T
t: transition_item
eq: last_error tr = Some t
Hlast: Some (destination t) = Some s
default: state T

finite_trace_last default tr = s
message: Type
T: VLSMType message
tr: list transition_item
s: state T
t: transition_item
eq: last_error tr = Some t
Hlast: Some (destination t) = Some s
default: state T
H0: destination t = s

finite_trace_last default tr = destination t
message: Type
T: VLSMType message
tr: list transition_item
s: state T
t: transition_item
eq: match tr with | [] => None | a :: t => Some (List.last t a) end = Some t
Hlast: Some (destination t) = Some s
default: state T
H0: destination t = s

finite_trace_last default tr = destination t
message: Type
T: VLSMType message
t0: transition_item
tr: list transition_item
s: state T
t: transition_item
eq: Some (List.last tr t0) = Some t
Hlast: Some (destination t) = Some s
default: state T
H0: destination t = s

finite_trace_last default (t0 :: tr) = destination t
message: Type
T: VLSMType message
t0: transition_item
tr: list transition_item
s: state T
t: transition_item
eq: Some (List.last tr t0) = Some t
Hlast: Some (destination t) = Some s
default: state T
H0: destination t = s
H1: List.last tr t0 = t

finite_trace_last default (t0 :: tr) = destination (List.last tr t0)
message: Type
T: VLSMType message
t0: transition_item
tr: list transition_item
s: state T
t: transition_item
eq: Some (List.last tr t0) = Some t
Hlast: Some (destination t) = Some s
default: state T
H0: destination t = s
H1: List.last tr t0 = t

List.last (List.map destination (t0 :: tr)) default = destination (List.last tr t0)
by rewrite last_map. Qed.
message: Type
T: VLSMType message
s: state T
x: transition_item
tl: list transition_item

finite_trace_last s (x :: tl) = finite_trace_last (destination x) tl
message: Type
T: VLSMType message
s: state T
x: transition_item
tl: list transition_item

finite_trace_last s (x :: tl) = finite_trace_last (destination x) tl
by unfold finite_trace_last; rewrite map_cons, unroll_last. Qed.
message: Type
T: VLSMType message

s : state T, finite_trace_last s [] = s
message: Type
T: VLSMType message

s : state T, finite_trace_last s [] = s
done. Qed.
message: Type
T: VLSMType message
s: state T
t1, t2: list transition_item

finite_trace_last s (t1 ++ t2) = finite_trace_last (finite_trace_last s t1) t2
message: Type
T: VLSMType message
s: state T
t1, t2: list transition_item

finite_trace_last s (t1 ++ t2) = finite_trace_last (finite_trace_last s t1) t2
by unfold finite_trace_last; rewrite map_app, last_app. Qed.
message: Type
T: VLSMType message
s: state T
x: transition_item
tl: list transition_item

finite_trace_last s (tl ++ [x]) = destination x
message: Type
T: VLSMType message
s: state T
x: transition_item
tl: list transition_item

finite_trace_last s (tl ++ [x]) = destination x
by unfold finite_trace_last; rewrite map_app; cbn; rewrite last_app. Qed.
message: Type
T: VLSMType message
x: transition_item
tl: list transition_item

finite_trace_last_output (tl ++ [x]) = output x
message: Type
T: VLSMType message
x: transition_item
tl: list transition_item

finite_trace_last_output (tl ++ [x]) = output x
by unfold finite_trace_last_output; rewrite map_app; cbn; rewrite last_app. Qed.
message: Type
T: VLSMType message
si: state T
tr: list transition_item

finite_trace_nth si tr 0 = Some si
message: Type
T: VLSMType message
si: state T
tr: list transition_item

finite_trace_nth si tr 0 = Some si
done. Qed.
message: Type
T: VLSMType message
si: state T
tr: list transition_item

finite_trace_nth si tr (length tr) = Some (finite_trace_last si tr)
message: Type
T: VLSMType message
si: state T
tr: list transition_item

finite_trace_nth si tr (length tr) = Some (finite_trace_last si tr)
message: Type
T: VLSMType message
si: state T
tr: list transition_item

nth_error (si :: List.map destination tr) (length tr) = Some (List.last (List.map destination tr) si)
message: Type
T: VLSMType message
si: state T
t: transition_item
tr: list transition_item

nth_error (si :: List.map destination (t :: tr)) (length (t :: tr)) = Some (List.last (List.map destination (t :: tr)) si)
message: Type
T: VLSMType message
si: state T
t: transition_item
tr: list transition_item

nth_error (List.map destination (t :: tr)) (length tr) = Some (List.last (List.map destination (t :: tr)) si)
message: Type
T: VLSMType message
si: state T
t: transition_item
tr: list transition_item

S (length tr) = length (List.map destination (t :: tr))
by rewrite map_length. Qed.
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat

n ≤ length t1 → finite_trace_nth si (t1 ++ t2) n = finite_trace_nth si t1 n
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat

n ≤ length t1 → finite_trace_nth si (t1 ++ t2) n = finite_trace_nth si t1 n
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat
Hle: n ≤ length t1

finite_trace_nth si (t1 ++ t2) n = finite_trace_nth si t1 n
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat
Hle: n ≤ length t1

nth_error (si :: List.map destination (t1 ++ t2)) n = nth_error (si :: List.map destination t1) n
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat
Hle: n ≤ length t1

nth_error ((si :: List.map destination t1) ++ List.map destination t2) n = nth_error (si :: List.map destination t1) n
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat
Hle: n ≤ length t1

n < S (length (List.map destination t1))
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat
Hle: n ≤ length t1

n < S (length t1)
by lia. Qed.
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat

length t1 ≤ n → finite_trace_nth si (t1 ++ t2) n = finite_trace_nth (finite_trace_last si t1) t2 (n - length t1)
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat

length t1 ≤ n → finite_trace_nth si (t1 ++ t2) n = finite_trace_nth (finite_trace_last si t1) t2 (n - length t1)
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat
H: length t1 ≤ n

finite_trace_nth si (t1 ++ t2) n = finite_trace_nth (finite_trace_last si t1) t2 (n - length t1)
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat
H: length t1 < n

finite_trace_nth si (t1 ++ t2) n = finite_trace_nth (finite_trace_last si t1) t2 (n - length t1)
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
finite_trace_nth si (t1 ++ t2) (length t1) = finite_trace_nth (finite_trace_last si t1) t2 (length t1 - length t1)
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat
H: length t1 < n

finite_trace_nth si (t1 ++ t2) n = finite_trace_nth (finite_trace_last si t1) t2 (n - length t1)
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat
H: length t1 < n

nth_error (si :: List.map destination (t1 ++ t2)) n = nth_error (finite_trace_last si t1 :: List.map destination t2) (n - length t1)
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat
H: length t1 < n

nth_error ((si :: List.map destination t1) ++ List.map destination t2) n = nth_error (finite_trace_last si t1 :: List.map destination t2) (n - length t1)
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat
H: length t1 < n

nth_error (List.map destination t2) (n - S (length t1)) = nth_error (finite_trace_last si t1 :: List.map destination t2) (n - length t1)
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item
n: nat
H: length t1 < S n

nth_error (List.map destination t2) (S n - S (length t1)) = nth_error (finite_trace_last si t1 :: List.map destination t2) (S n - length t1)
by rewrite (Nat.sub_succ_l (length t1) n); [| lia].
message: Type
T: VLSMType message
si: state T
t1, t2: list transition_item

finite_trace_nth si (t1 ++ t2) (length t1) = finite_trace_nth (finite_trace_last si t1) t2 (length t1 - length t1)
by rewrite finite_trace_nth_app1, finite_trace_nth_last, Nat.sub_diag, finite_trace_nth_first. Qed.
message: Type
T: VLSMType message
si: state T
tr: list transition_item
n: nat
s: state T

finite_trace_nth si tr n = Some s → n ≤ length tr
message: Type
T: VLSMType message
si: state T
tr: list transition_item
n: nat
s: state T

finite_trace_nth si tr n = Some s → n ≤ length tr
message: Type
T: VLSMType message
si: state T
tr: list transition_item
n: nat
s: state T
H: finite_trace_nth si tr n = Some s

n ≤ length tr
message: Type
T: VLSMType message
si: state T
tr: list transition_item
n: nat
s: state T
H: S n ≤ S (length (List.map destination tr))

n ≤ length tr
by rewrite map_length in H; lia. Qed.
message: Type
T: VLSMType message
s: state T
tr: list transition_item
n: nat
s': state T

finite_trace_nth s tr n = Some s' → finite_trace_last s (take n tr) = s'
message: Type
T: VLSMType message
s: state T
tr: list transition_item
n: nat
s': state T

finite_trace_nth s tr n = Some s' → finite_trace_last s (take n tr) = s'
message: Type
T: VLSMType message
s: state T
tr: list transition_item
n: nat
s': state T

nth_error (s :: List.map destination tr) n = Some s' → List.last (List.map destination (take n tr)) s = s'
message: Type
T: VLSMType message
s: state T
tr: list transition_item
n: nat
s': state T

nth_error (s :: List.map destination tr) n = Some s' → List.last (take n (List.map destination tr)) s = s'
message: Type
T: VLSMType message
s: state T
n: nat
s': state T
l: list (state T)

nth_error (s :: l) n = Some s' → List.last (take n l) s = s'
message: Type
T: VLSMType message
s, s': state T
l: list (state T)

Some s = Some s' → List.last (take 0 l) s = s'
message: Type
T: VLSMType message
s: state T
n: nat
s': state T
l: list (state T)
nth_error l n = Some s' → List.last (take (S n) l) s = s'
message: Type
T: VLSMType message
s, s': state T
l: list (state T)

Some s = Some s' → List.last (take 0 l) s = s'
by intros [= <-]; destruct l.
message: Type
T: VLSMType message
s: state T
n: nat
s': state T
l: list (state T)

nth_error l n = Some s' → List.last (take (S n) l) s = s'
by intros H; symmetry; apply take_nth_last. Qed.
message: Type
T: VLSMType message
s: state T
tr: list transition_item
n: nat

n < length tr → finite_trace_last s (drop n tr) = finite_trace_last s tr
message: Type
T: VLSMType message
s: state T
tr: list transition_item
n: nat

n < length tr → finite_trace_last s (drop n tr) = finite_trace_last s tr
message: Type
T: VLSMType message
s: state T
tr: list transition_item
n: nat
H: n < length tr

finite_trace_last s (drop n tr) = finite_trace_last s tr
message: Type
T: VLSMType message
s: state T
tr: list transition_item
n: nat
H: n < length tr

List.last (List.map destination (drop n tr)) s = List.last (List.map destination tr) s
message: Type
T: VLSMType message
s: state T
tr: list transition_item
n: nat
H: n < length tr

List.last (drop n (List.map destination tr)) s = List.last (List.map destination tr) s
message: Type
T: VLSMType message
s: state T
tr: list transition_item
n: nat
H: n < length tr

n < length (List.map destination tr)
by rewrite map_length. Qed.
message: Type
T: VLSMType message
s: state T
tr: list transition_item

finite_trace_last s tr = List.last (List.map destination tr) s
message: Type
T: VLSMType message
s: state T
tr: list transition_item

finite_trace_last s tr = List.last (List.map destination tr) s
done. Qed. End sec_trace_lemmas. Definition vs0 `(X : VLSM message) := @inhabitant _ (@s0 _ _ X).
message: Type
X: VLSM message

{| vlsm_type := X; vlsm_machine := X |} = X
message: Type
X: VLSM message

{| vlsm_type := X; vlsm_machine := X |} = X
by destruct X. Qed. Section sec_VLSM.
In this section we assume a fixed VLSM.
Context
  {message : Type}
  (X : VLSM message)
  .

Valid states and messages

We further characterize certain objects as being valid, which means they can be witnessed or experienced during executions of the protocol. For example, a message is a valid_message if there exists an execution of the protocol in which it is produced.
We choose here to define valid states and messages together as the valid_state_message_property, inductively defined over the state × option message product type, as this definition avoids the need of using a mutually recursive definition.
The inductive definition has three cases:
Inductive valid_state_message_prop : state X -> option message -> Prop :=
| valid_initial_state_message
    (s : state X)
    (Hs : initial_state_prop X s)
    (om : option message)
    (Hom : option_initial_message_prop X om) :
      valid_state_message_prop s om
| valid_generated_state_message
    (s : state X)
    (_om : option message)
    (Hps : valid_state_message_prop s _om)
    (_s : state X)
    (om : option message)
    (Hpm : valid_state_message_prop _s om)
    (l : label X)
    (Hv : valid X l (s, om))
    s' om'
    (Ht : transition X l (s, om) = (s', om')) :
      valid_state_message_prop s' om'.

Definition valid_initial_state
  [s : state X] (Hs : initial_state_prop s) : valid_state_message_prop s None :=
    valid_initial_state_message s Hs None I.
The valid_state_property and the valid_message_property are now definable as simple projections of the above definition.
Moreover, we use these derived properties to define the corresponding dependent types valid_state and valid_message.
Definition valid_state_prop (s : state X) :=
  exists (om : option message),
    valid_state_message_prop s om.

Definition valid_message_prop (m : message) :=
  exists (s : state X),
    valid_state_message_prop s (Some m).

Definition valid_state : Type :=
  {s : state X | valid_state_prop s}.

Definition valid_message : Type :=
  {m : message | valid_message_prop m}.

message: Type
X: VLSM message
s: state X
Hinitial: initial_state_prop s

valid_state_prop s
message: Type
X: VLSM message
s: state X
Hinitial: initial_state_prop s

valid_state_prop s
message: Type
X: VLSM message
s: state X
Hinitial: initial_state_prop s

valid_state_message_prop s None
by apply valid_initial_state_message. Qed.
message: Type
X: VLSM message
m: message
Hinitial: initial_message_prop m

valid_message_prop m
message: Type
X: VLSM message
m: message
Hinitial: initial_message_prop m

valid_message_prop m
message: Type
X: VLSM message
m: message
Hinitial: initial_message_prop m

valid_state_message_prop (`(vs0 X)) (Some m)
by apply valid_initial_state_message; [apply proj2_sig |]. Qed.
As often times we work with optional valid messages, it is convenient to define a valid message property for optional messages.
Definition option_valid_message_prop (om : option message) :=
  exists (s : state X),
    valid_state_message_prop s om.

message: Type
X: VLSM message

option_valid_message_prop None
message: Type
X: VLSM message

option_valid_message_prop None
message: Type
X: VLSM message

valid_state_message_prop (`(vs0 X)) None
by apply valid_initial_state_message; [apply proj2_sig |]. Qed.
message: Type
X: VLSM message
m: message
Hpm: valid_message_prop m

option_valid_message_prop (Some m)
message: Type
X: VLSM message
m: message
Hpm: valid_message_prop m

option_valid_message_prop (Some m)
by destruct Hpm as [s Hpm]; exists s. Qed.
message: Type
X: VLSM message
om: option message
Hinitial: option_initial_message_prop X om

option_valid_message_prop om
message: Type
X: VLSM message
om: option message
Hinitial: option_initial_message_prop X om

option_valid_message_prop om
message: Type
X: VLSM message
m: message
Hinitial: option_initial_message_prop X (Some m)

option_valid_message_prop (Some m)
message: Type
X: VLSM message
Hinitial: option_initial_message_prop X None
option_valid_message_prop None
message: Type
X: VLSM message
m: message
Hinitial: option_initial_message_prop X (Some m)

option_valid_message_prop (Some m)
by apply option_valid_message_Some, initial_message_is_valid.
message: Type
X: VLSM message
Hinitial: option_initial_message_prop X None

option_valid_message_prop None
by apply option_valid_message_None. Qed.
We also include the more intuitive, mutually recursive definition of valid states and messages.
This definition has three cases for valid_message_mrec:
There are also two cases for valid_state_mrec:
Inductive valid_message_mrec : option message -> Prop :=
| valid_message_mrec_None :
    valid_message_mrec None
| valid_message_mrec_initial :
    forall (m : message),
      initial_message_prop X m -> valid_message_mrec (Some m)
| valid_message_mrec_generated :
    forall {l : label X} {om om' : option message} {st st' : state X},
      valid X l (st, om) -> valid_state_mrec st -> valid_message_mrec om ->
      transition X l (st, om) = (st', om') -> valid_message_mrec om'
with valid_state_mrec : state X -> Prop :=
| valid_state_mrec_initial :
    forall (s : state X),
      initial_state_prop X s -> valid_state_mrec s
| valid_state_mrec_generated :
    forall {l : label X} {om om' : option message} {st st' : state X},
      valid X l (st, om) -> valid_state_mrec st -> valid_message_mrec om ->
      transition X l (st, om) = (st', om') -> valid_state_mrec st'.
Reasoning about this mutually recursive definition is facilitated by a custom induction scheme.
Scheme valid_message_ind := Induction for valid_message_mrec Sort Prop
with valid_state_ind := Induction for valid_state_mrec Sort Prop.

Arguments valid_message_ind Pmsg Pstate : rename.
Arguments valid_state_ind Pmsg Pstate : rename.
To guarantee the equivalence between valid_message_mrec coupled with valid_state_mrec and valid_state_message_prop we prove the following lemmas.
message: Type
X: VLSM message

(s : state X) (om : option message), valid_state_message_prop s om → valid_message_mrec om ∧ valid_state_mrec s
message: Type
X: VLSM message

(s : state X) (om : option message), valid_state_message_prop s om → valid_message_mrec om ∧ valid_state_mrec s
message: Type
X: VLSM message
s: state X
Hs: initial_state_prop s
om: option message
Hom: option_initial_message_prop X om

valid_message_mrec om
message: Type
X: VLSM message
s: state X
Hs: initial_state_prop s
om: option message
Hom: option_initial_message_prop X om
valid_state_mrec s
message: Type
X: VLSM message
s: state X
_om: option message
H: valid_state_message_prop s _om
_s: state X
om: option message
H0: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHvalid_state_message_prop1: valid_message_mrec _om ∧ valid_state_mrec s
IHvalid_state_message_prop2: valid_message_mrec om ∧ valid_state_mrec _s
valid_message_mrec om'
message: Type
X: VLSM message
s: state X
_om: option message
H: valid_state_message_prop s _om
_s: state X
om: option message
H0: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHvalid_state_message_prop1: valid_message_mrec _om ∧ valid_state_mrec s
IHvalid_state_message_prop2: valid_message_mrec om ∧ valid_state_mrec _s
valid_state_mrec s'
message: Type
X: VLSM message
s: state X
Hs: initial_state_prop s
om: option message
Hom: option_initial_message_prop X om

valid_message_mrec om
by destruct om; [apply valid_message_mrec_initial | constructor].
message: Type
X: VLSM message
s: state X
Hs: initial_state_prop s
om: option message
Hom: option_initial_message_prop X om

valid_state_mrec s
by apply valid_state_mrec_initial.
message: Type
X: VLSM message
s: state X
_om: option message
H: valid_state_message_prop s _om
_s: state X
om: option message
H0: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHvalid_state_message_prop1: valid_message_mrec _om ∧ valid_state_mrec s
IHvalid_state_message_prop2: valid_message_mrec om ∧ valid_state_mrec _s

valid_message_mrec om'
message: Type
X: VLSM message
s: state X
_om: option message
H: valid_state_message_prop s _om
_s: state X
om: option message
H0: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHvalid_state_message_prop1: valid_message_mrec _om ∧ valid_state_mrec s
IHvalid_state_message_prop2: valid_message_mrec om ∧ valid_state_mrec _s

valid_message_mrec (transition l0 (s, om)).2
message: Type
X: VLSM message
s: state X
_om: option message
H: valid_state_message_prop s _om
_s: state X
om: option message
H0: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHvalid_state_message_prop1: valid_message_mrec _om ∧ valid_state_mrec s
IHvalid_state_message_prop2: valid_message_mrec om ∧ valid_state_mrec _s

valid_message_mrec om'
by eapply valid_message_mrec_generated; [done | itauto.. |].
message: Type
X: VLSM message
s: state X
_om: option message
H: valid_state_message_prop s _om
_s: state X
om: option message
H0: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHvalid_state_message_prop1: valid_message_mrec _om ∧ valid_state_mrec s
IHvalid_state_message_prop2: valid_message_mrec om ∧ valid_state_mrec _s

valid_state_mrec s'
message: Type
X: VLSM message
s: state X
_om: option message
H: valid_state_message_prop s _om
_s: state X
om: option message
H0: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHvalid_state_message_prop1: valid_message_mrec _om ∧ valid_state_mrec s
IHvalid_state_message_prop2: valid_message_mrec om ∧ valid_state_mrec _s

valid_state_mrec (transition l0 (s, om)).1
message: Type
X: VLSM message
s: state X
_om: option message
H: valid_state_message_prop s _om
_s: state X
om: option message
H0: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHvalid_state_message_prop1: valid_message_mrec _om ∧ valid_state_mrec s
IHvalid_state_message_prop2: valid_message_mrec om ∧ valid_state_mrec _s

valid_state_mrec s
message: Type
X: VLSM message
s: state X
_om: option message
H: valid_state_message_prop s _om
_s: state X
om: option message
H0: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHvalid_state_message_prop1: valid_message_mrec _om ∧ valid_state_mrec s
IHvalid_state_message_prop2: valid_message_mrec om ∧ valid_state_mrec _s
valid_message_mrec om
message: Type
X: VLSM message
s: state X
_om: option message
H: valid_state_message_prop s _om
_s: state X
om: option message
H0: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHvalid_state_message_prop1: valid_message_mrec _om ∧ valid_state_mrec s
IHvalid_state_message_prop2: valid_message_mrec om ∧ valid_state_mrec _s
transition l0 (s, om) = ((transition l0 (s, om)).1, ?om')
message: Type
X: VLSM message
s: state X
_om: option message
H: valid_state_message_prop s _om
_s: state X
om: option message
H0: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHvalid_state_message_prop1: valid_message_mrec _om ∧ valid_state_mrec s
IHvalid_state_message_prop2: valid_message_mrec om ∧ valid_state_mrec _s

valid_state_mrec s
by apply IHvalid_state_message_prop1.
message: Type
X: VLSM message
s: state X
_om: option message
H: valid_state_message_prop s _om
_s: state X
om: option message
H0: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHvalid_state_message_prop1: valid_message_mrec _om ∧ valid_state_mrec s
IHvalid_state_message_prop2: valid_message_mrec om ∧ valid_state_mrec _s

valid_message_mrec om
by apply IHvalid_state_message_prop2.
message: Type
X: VLSM message
s: state X
_om: option message
H: valid_state_message_prop s _om
_s: state X
om: option message
H0: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHvalid_state_message_prop1: valid_message_mrec _om ∧ valid_state_mrec s
IHvalid_state_message_prop2: valid_message_mrec om ∧ valid_state_mrec _s

transition l0 (s, om) = ((transition l0 (s, om)).1, ?om')
by rewrite Ht. Qed.
message: Type
X: VLSM message

s : state X, valid_state_mrec s → valid_state_prop s
message: Type
X: VLSM message

s : state X, valid_state_mrec s → valid_state_prop s
message: Type
X: VLSM message

option_valid_message_prop None
message: Type
X: VLSM message
m : message, initial_message_prop m → option_valid_message_prop (Some m)
message: Type
X: VLSM message
(l : label X) (om om' : option message) (st st' : state X), valid l (st, om) → valid_state_mrec st → valid_state_prop st → valid_message_mrec om → option_valid_message_prop om → transition l (st, om) = (st', om') → option_valid_message_prop om'
message: Type
X: VLSM message
s : state X, initial_state_prop s → valid_state_prop s
message: Type
X: VLSM message
(l : label X) (om om' : option message) (st st' : state X), valid l (st, om) → valid_state_mrec st → valid_state_prop st → valid_message_mrec om → option_valid_message_prop om → transition l (st, om) = (st', om') → valid_state_prop st'
message: Type
X: VLSM message

option_valid_message_prop None
by apply option_valid_message_None.
message: Type
X: VLSM message

m : message, initial_message_prop m → option_valid_message_prop (Some m)
by apply initial_message_is_valid.
message: Type
X: VLSM message

(l : label X) (om om' : option message) (st st' : state X), valid l (st, om) → valid_state_mrec st → valid_state_prop st → valid_message_mrec om → option_valid_message_prop om → transition l (st, om) = (st', om') → option_valid_message_prop om'
message: Type
X: VLSM message
l0: label X
om, om': option message
st, st': state X
v: valid l0 (st, om)
v0: valid_state_mrec st
x: option message
H: valid_state_message_prop st x
v1: valid_message_mrec om
x0: state X
H0: valid_state_message_prop x0 om
Htr: transition l0 (st, om) = (st', om')

option_valid_message_prop om'
by eexists; eapply valid_generated_state_message; cycle 1.
message: Type
X: VLSM message

s : state X, initial_state_prop s → valid_state_prop s
by intros; apply initial_state_is_valid.
message: Type
X: VLSM message

(l : label X) (om om' : option message) (st st' : state X), valid l (st, om) → valid_state_mrec st → valid_state_prop st → valid_message_mrec om → option_valid_message_prop om → transition l (st, om) = (st', om') → valid_state_prop st'
message: Type
X: VLSM message
l0: label X
om, om': option message
st, st': state X
v: valid l0 (st, om)
v0: valid_state_mrec st
x: option message
H: valid_state_message_prop st x
v1: valid_message_mrec om
x0: state X
H0: valid_state_message_prop x0 om
Htr: transition l0 (st, om) = (st', om')

valid_state_prop st'
by eexists; eapply valid_generated_state_message; cycle 1. Qed.
message: Type
X: VLSM message

om : option message, valid_message_mrec om → option_valid_message_prop om
message: Type
X: VLSM message

om : option message, valid_message_mrec om → option_valid_message_prop om
message: Type
X: VLSM message

option_valid_message_prop None
message: Type
X: VLSM message
m : message, initial_message_prop m → option_valid_message_prop (Some m)
message: Type
X: VLSM message
(l : label X) (om om' : option message) (st st' : state X), valid l (st, om) → valid_state_mrec st → valid_state_prop st → valid_message_mrec om → option_valid_message_prop om → transition l (st, om) = (st', om') → option_valid_message_prop om'
message: Type
X: VLSM message
s : state X, initial_state_prop s → valid_state_prop s
message: Type
X: VLSM message
(l : label X) (om om' : option message) (st st' : state X), valid l (st, om) → valid_state_mrec st → valid_state_prop st → valid_message_mrec om → option_valid_message_prop om → transition l (st, om) = (st', om') → valid_state_prop st'
message: Type
X: VLSM message

option_valid_message_prop None
by apply option_valid_message_None.
message: Type
X: VLSM message

m : message, initial_message_prop m → option_valid_message_prop (Some m)
by apply initial_message_is_valid.
message: Type
X: VLSM message

(l : label X) (om om' : option message) (st st' : state X), valid l (st, om) → valid_state_mrec st → valid_state_prop st → valid_message_mrec om → option_valid_message_prop om → transition l (st, om) = (st', om') → option_valid_message_prop om'
message: Type
X: VLSM message
l0: label X
om, om': option message
st, st': state X
v: valid l0 (st, om)
v0: valid_state_mrec st
x: option message
H: valid_state_message_prop st x
v1: valid_message_mrec om
x0: state X
H0: valid_state_message_prop x0 om
Htr: transition l0 (st, om) = (st', om')

option_valid_message_prop om'
by eexists; eapply valid_generated_state_message; cycle 1.
message: Type
X: VLSM message

s : state X, initial_state_prop s → valid_state_prop s
by intros; apply initial_state_is_valid.
message: Type
X: VLSM message

(l : label X) (om om' : option message) (st st' : state X), valid l (st, om) → valid_state_mrec st → valid_state_prop st → valid_message_mrec om → option_valid_message_prop om → transition l (st, om) = (st', om') → valid_state_prop st'
message: Type
X: VLSM message
l0: label X
om, om': option message
st, st': state X
v: valid l0 (st, om)
v0: valid_state_mrec st
x: option message
H: valid_state_message_prop st x
v1: valid_message_mrec om
x0: state X
H0: valid_state_message_prop x0 om
Htr: transition l0 (st, om) = (st', om')

valid_state_prop st'
by eexists; eapply valid_generated_state_message; cycle 1. Qed.
message: Type
X: VLSM message

om : option message, valid_message_mrec om ↔ option_valid_message_prop om
message: Type
X: VLSM message

om : option message, valid_message_mrec om ↔ option_valid_message_prop om
message: Type
X: VLSM message
om: option message

valid_message_mrec om → option_valid_message_prop om
message: Type
X: VLSM message
om: option message
option_valid_message_prop om → valid_message_mrec om
message: Type
X: VLSM message
om: option message

valid_message_mrec om → option_valid_message_prop om
by apply valid_impl_valid_message_prop.
message: Type
X: VLSM message
om: option message

option_valid_message_prop om → valid_message_mrec om
by intros []; eapply valid_state_message_prop_impl_valid. Qed.
message: Type
X: VLSM message

s : state X, valid_state_mrec s ↔ valid_state_prop s
message: Type
X: VLSM message

s : state X, valid_state_mrec s ↔ valid_state_prop s
message: Type
X: VLSM message
s: state X

valid_state_mrec s → valid_state_prop s
message: Type
X: VLSM message
s: state X
valid_state_prop s → valid_state_mrec s
message: Type
X: VLSM message
s: state X

valid_state_mrec s → valid_state_prop s
by apply valid_impl_valid_state_prop.
message: Type
X: VLSM message
s: state X

valid_state_prop s → valid_state_mrec s
by intros []; eapply valid_state_message_prop_impl_valid. Qed.

Input validity and input valid transitions

To specify that a particular (input of a) transition can actually be encountered as part of a protocol execution, we define the notions of input_validity and input_valid_transition.
Input validity requires that the valid predicate holds for the given inputs and that they have a valid_state and a valid_message.
Definition input_valid (l : label X) (som : state X * option message) : Prop :=
  let (s, om) := som in
    valid_state_prop s /\ option_valid_message_prop om /\ valid X l (s, om).
Input valid transitions are transitions with input_valid inputs.
Definition input_valid_transition (l : label X) (som som' : state X * option message) : Prop :=
  input_valid l som /\ transition X l som = som'.

Definition input_valid_transition_item (s : state X) (item : transition_item) : Prop :=
  input_valid_transition (l item) (s, input item) (destination item, output item).

Definition input_valid_transition_preserving (R : state X -> state X -> Prop) : Prop :=
  forall (s1 s2 : state X) (l : label X) (om1 om2 : option message),
    input_valid_transition l (s1, om1) (s2, om2) -> R s1 s2.
Next three lemmas show the two definitions above are strongly related.
message: Type
X: VLSM message
l: label X
som, som': (state X * option message)%type
Ht: input_valid_transition l som som'

input_valid l som
message: Type
X: VLSM message
l: label X
som, som': (state X * option message)%type
Ht: input_valid_transition l som som'

input_valid l som
by destruct Ht. Qed.
message: Type
X: VLSM message
l: label X
som: (state X * option message)%type
Hv: input_valid l som

som' : state X * option message, transition l som = som' → input_valid_transition l som som'
message: Type
X: VLSM message
l: label X
som: (state X * option message)%type
Hv: input_valid l som

som' : state X * option message, transition l som = som' → input_valid_transition l som som'
done. Qed.
message: Type
X: VLSM message
l: label X
som: (state X * option message)%type

input_valid l som ↔ ( som' : state X * option message, input_valid_transition l som som')
message: Type
X: VLSM message
l: label X
som: (state X * option message)%type

input_valid l som ↔ ( som' : state X * option message, input_valid_transition l som som')
message: Type
X: VLSM message
l: label X
som: (state X * option message)%type

input_valid l som → som' : state X * option message, input_valid_transition l som som'
message: Type
X: VLSM message
l: label X
som: (state X * option message)%type
( som' : state X * option message, input_valid_transition l som som') → input_valid l som
message: Type
X: VLSM message
l: label X
som: (state X * option message)%type

input_valid l som → som' : state X * option message, input_valid_transition l som som'
by eexists; apply input_valid_can_transition.
message: Type
X: VLSM message
l: label X
som: (state X * option message)%type

( som' : state X * option message, input_valid_transition l som som') → input_valid l som
message: Type
X: VLSM message
l: label X
som, som': (state X * option message)%type
Hivt: input_valid_transition l som som'

input_valid l som
by apply input_valid_transition_valid with som'. Qed.
The next couple of lemmas relate the two definitions above with pre-existing concepts.
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

valid_state_prop s
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

valid_state_prop s
by destruct Ht as [[[_om Hp] _] _]; exists _om. Qed.
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

valid_state_prop s'
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

valid_state_prop s'
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

valid_state_message_prop s' om'
message: Type
X: VLSM message
l: label X
s, s': state X
om, om', _om: option message
Hs: valid_state_message_prop s _om
_s: state X
Hom: valid_state_message_prop _s om
Hv: valid l (s, om)
Ht: transition l (s, om) = (s', om')

valid_state_message_prop s' om'
by apply valid_generated_state_message with s _om _s om l. Qed.
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

option_valid_message_prop om
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

option_valid_message_prop om
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
_s: state X
Hom: valid_state_message_prop _s om

option_valid_message_prop om
by exists _s. Qed.
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

valid_state_message_prop s' om'
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

valid_state_message_prop s' om'
message: Type
X: VLSM message
l: label X
s, s': state X
om, om', _om: option message
Hps: valid_state_message_prop s _om
_s: state X
Hpm: valid_state_message_prop _s om
Hv: valid l (s, om)
Ht: transition l (s, om) = (s', om')

valid_state_message_prop s' om'
by apply valid_generated_state_message with s _om _s om l. Qed.
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

option_valid_message_prop om'
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

option_valid_message_prop om'
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: valid_state_message_prop s' om'

option_valid_message_prop om'
by exists s'. Qed.
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

valid l (s, om)
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

valid l (s, om)
by destruct Ht as [[_ [_ Hv]] _]. Qed.
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

transition l (s, om) = (s', om')
message: Type
X: VLSM message
l: label X
s, s': state X
om, om': option message
Ht: input_valid_transition l (s, om) (s', om')

transition l (s, om) = (s', om')
by destruct Ht as [_ Ht]. Qed.
message: Type
X: VLSM message
l: label X
s: state X
om: option message
Hv: input_valid l (s, om)
s': state X
om': option message
Ht: transition l (s, om) = (s', om')

valid_state_message_prop s' om'
message: Type
X: VLSM message
l: label X
s: state X
om: option message
Hv: input_valid l (s, om)
s': state X
om': option message
Ht: transition l (s, om) = (s', om')

valid_state_message_prop s' om'
message: Type
X: VLSM message
l: label X
s: state X
om, _om: option message
Hs: valid_state_message_prop s _om
_s: state X
Hom: valid_state_message_prop _s om
Hv: valid l (s, om)
s': state X
om': option message
Ht: transition l (s, om) = (s', om')

valid_state_message_prop s' om'
by apply valid_generated_state_message with s _om _s om l. Qed.
transitions are deterministic, i.e. the final state and output message are determined by the label, initial state and input message of the transition. This is because transition is a function.
Because of the above, input_valid_transitions are also deterministic.
message: Type
X: VLSM message

(lbl : label X) (s s1 s2 : state X) (iom oom1 oom2 : option message), input_valid_transition lbl (s, iom) (s1, oom1) → input_valid_transition lbl (s, iom) (s2, oom2) → s1 = s2 ∧ oom1 = oom2
message: Type
X: VLSM message

(lbl : label X) (s s1 s2 : state X) (iom oom1 oom2 : option message), input_valid_transition lbl (s, iom) (s1, oom1) → input_valid_transition lbl (s, iom) (s2, oom2) → s1 = s2 ∧ oom1 = oom2
by do 2 inversion 1; itauto congruence. Qed.
For VLSMs initialized with many initial messages such as the composite_vlsm_induced_projection the question of whether a VLSM can_emit a message m becomes more useful than that whether m is a valid_message.
Definition option_can_produce (s : state X) (om : option message) : Prop :=
  exists (som : state X * option message) (l : label X),
    input_valid_transition l som (s, om).

Definition can_produce (s : state X) (m : message) : Prop :=
  option_can_produce s (Some m).
Of course, if a VLSM can_emit (s, m), then (s, m) is valid.
message: Type
X: VLSM message
s: state X
om: option message
Hm: option_can_produce s om

valid_state_message_prop s om
message: Type
X: VLSM message
s: state X
om: option message
Hm: option_can_produce s om

valid_state_message_prop s om
message: Type
X: VLSM message
s: state X
om: option message
s0: state X
om0: option message
l: label X
_om0: option message
Hs0: valid_state_message_prop s0 _om0
_s0: state X
Hom0: valid_state_message_prop _s0 om0
Hv: valid l (s0, om0)
Ht: transition l (s0, om0) = (s, om)

valid_state_message_prop s om
by apply valid_generated_state_message with s0 _om0 _s0 om0 l. Qed.
message: Type
X: VLSM message
s: state X
m: message
Hm: can_produce s m

valid_state_message_prop s (Some m)
message: Type
X: VLSM message
s: state X
m: message
Hm: can_produce s m

valid_state_message_prop s (Some m)
exact (option_can_produce_valid s (Some m) Hm). Qed.
message: Type
X: VLSM message
s: state X
om: option message

valid_state_message_prop s om ↔ option_can_produce s om ∨ initial_state_prop s ∧ option_initial_message_prop X om
message: Type
X: VLSM message
s: state X
om: option message

valid_state_message_prop s om ↔ option_can_produce s om ∨ initial_state_prop s ∧ option_initial_message_prop X om
message: Type
X: VLSM message
s: state X
om: option message

valid_state_message_prop s om → option_can_produce s om ∨ initial_state_prop s ∧ option_initial_message_prop X om
message: Type
X: VLSM message
s: state X
om: option message
option_can_produce s om ∨ initial_state_prop s ∧ option_initial_message_prop X om → valid_state_message_prop s om
message: Type
X: VLSM message
s: state X
om: option message

valid_state_message_prop s om → option_can_produce s om ∨ initial_state_prop s ∧ option_initial_message_prop X om
message: Type
X: VLSM message
s: state X
om: option message
Hm: valid_state_message_prop s om
Hs: initial_state_prop s
Hom: option_initial_message_prop X om

option_can_produce s om ∨ initial_state_prop s ∧ option_initial_message_prop X om
message: Type
X: VLSM message
s: state X
om: option message
Hm: valid_state_message_prop s om
s1: state X
_om: option message
_s: state X
om0: option message
l0: label X
Hps: valid_state_message_prop s1 _om
Hpm: valid_state_message_prop _s om0
Hv: valid l0 (s1, om0)
Ht: transition l0 (s1, om0) = (s, om)
option_can_produce s om ∨ initial_state_prop s ∧ option_initial_message_prop X om
message: Type
X: VLSM message
s: state X
om: option message
Hm: valid_state_message_prop s om
Hs: initial_state_prop s
Hom: option_initial_message_prop X om

option_can_produce s om ∨ initial_state_prop s ∧ option_initial_message_prop X om
by right.
message: Type
X: VLSM message
s: state X
om: option message
Hm: valid_state_message_prop s om
s1: state X
_om: option message
_s: state X
om0: option message
l0: label X
Hps: valid_state_message_prop s1 _om
Hpm: valid_state_message_prop _s om0
Hv: valid l0 (s1, om0)
Ht: transition l0 (s1, om0) = (s, om)

option_can_produce s om ∨ initial_state_prop s ∧ option_initial_message_prop X om
by left; exists (s1, om0), l0; firstorder.
message: Type
X: VLSM message
s: state X
om: option message

option_can_produce s om ∨ initial_state_prop s ∧ option_initial_message_prop X om → valid_state_message_prop s om
message: Type
X: VLSM message
s: state X
om: option message
Hem: option_can_produce s om

valid_state_message_prop s om
message: Type
X: VLSM message
s: state X
om: option message
Him: initial_state_prop s ∧ option_initial_message_prop X om
valid_state_message_prop s om
message: Type
X: VLSM message
s: state X
om: option message
Hem: option_can_produce s om

valid_state_message_prop s om
by apply option_can_produce_valid.
message: Type
X: VLSM message
s: state X
om: option message
Him: initial_state_prop s ∧ option_initial_message_prop X om

valid_state_message_prop s om
by constructor; apply Him. Qed.
message: Type
X: VLSM message
s: state X
m: message

valid_state_message_prop s (Some m) ↔ can_produce s m ∨ initial_state_prop s ∧ initial_message_prop m
message: Type
X: VLSM message
s: state X
m: message

valid_state_message_prop s (Some m) ↔ can_produce s m ∨ initial_state_prop s ∧ initial_message_prop m
exact (option_can_produce_valid_iff s (Some m)). Qed. Definition can_emit (m : message) : Prop := exists (som : state X * option message) (l : label X) (s : state X), input_valid_transition l som (s, Some m).
message: Type
X: VLSM message

m : message, can_emit m ↔ ( s : state X, can_produce s m)
message: Type
X: VLSM message

m : message, can_emit m ↔ ( s : state X, can_produce s m)
message: Type
X: VLSM message
m: message

can_emit m → s : state X, can_produce s m
message: Type
X: VLSM message
m: message
( s : state X, can_produce s m) → can_emit m
message: Type
X: VLSM message
m: message

can_emit m → s : state X, can_produce s m
by intros [som [l [s Ht]]]; exists s, som, l.
message: Type
X: VLSM message
m: message

( s : state X, can_produce s m) → can_emit m
by intros [s [som [l Ht]]]; exists som, l, s. Qed.
If a VLSM can_emit a message m, then m is valid.
message: Type
X: VLSM message
m: message
Hm: can_emit m

valid_message_prop m
message: Type
X: VLSM message
m: message
Hm: can_emit m

valid_message_prop m
message: Type
X: VLSM message
m: message
Hm: s : state X, can_produce s m

valid_message_prop m
message: Type
X: VLSM message
m: message
s: state X
Hm: can_produce s m

valid_message_prop m
message: Type
X: VLSM message
m: message
s: state X
Hm: valid_state_message_prop s (Some m)

valid_message_prop m
by exists s. Qed.
A characterization of valid messages in terms of can_emit.
message: Type
X: VLSM message

m : message, valid_message_prop m ↔ initial_message_prop m ∨ can_emit m
message: Type
X: VLSM message

m : message, valid_message_prop m ↔ initial_message_prop m ∨ can_emit m
message: Type
X: VLSM message
m: message

valid_message_prop m → initial_message_prop m ∨ can_emit m
message: Type
X: VLSM message
m: message
initial_message_prop m ∨ can_emit m → valid_message_prop m
message: Type
X: VLSM message
m: message

valid_message_prop m → initial_message_prop m ∨ can_emit m
message: Type
X: VLSM message
m: message
s: state X
Hm: valid_state_message_prop s (Some m)

initial_message_prop m ∨ can_emit m
message: Type
X: VLSM message
m: message
s: state X
Hgen: can_produce s m

initial_message_prop m ∨ can_emit m
message: Type
X: VLSM message
m: message
s: state X
Him: initial_message_prop m
initial_message_prop m ∨ can_emit m
message: Type
X: VLSM message
m: message
s: state X
Hgen: can_produce s m

initial_message_prop m ∨ can_emit m
by right; apply can_emit_iff; exists s.
message: Type
X: VLSM message
m: message
s: state X
Him: initial_message_prop m

initial_message_prop m ∨ can_emit m
by left.
message: Type
X: VLSM message
m: message

initial_message_prop m ∨ can_emit m → valid_message_prop m
message: Type
X: VLSM message
m: message
Him: initial_message_prop m

valid_message_prop m
message: Type
X: VLSM message
m: message
Hm: can_emit m
valid_message_prop m
message: Type
X: VLSM message
m: message
Him: initial_message_prop m

valid_message_prop m
by apply initial_message_is_valid.
message: Type
X: VLSM message
m: message
Hm: can_emit m

valid_message_prop m
by apply emitted_messages_are_valid. Qed.

Valid state and valid message characterization

The definition and results below show that the mutually-recursive definitions for valid_states and valid_messages can be derived from the prior definitions.
The results below offers equivalent characterizations for valid_states and valid_messages, similar to their recursive definition.
message: Type
X: VLSM message

s' : state X, valid_state_prop s' ↔ ( is : initial_state X, s' = `is) ∨ ( (l : label X) (som : state X * option message) (om' : option message), input_valid_transition l som (s', om'))
message: Type
X: VLSM message

s' : state X, valid_state_prop s' ↔ ( is : initial_state X, s' = `is) ∨ ( (l : label X) (som : state X * option message) (om' : option message), input_valid_transition l som (s', om'))
message: Type
X: VLSM message
s': state X

valid_state_prop s' → ( is : initial_state X, s' = `is) ∨ ( (l : label X) (som : state X * option message) (om' : option message), input_valid_transition l som (s', om'))
message: Type
X: VLSM message
s': state X
( is : initial_state X, s' = `is) ∨ ( (l : label X) (som : state X * option message) (om' : option message), input_valid_transition l som (s', om')) → valid_state_prop s'
message: Type
X: VLSM message
s': state X

valid_state_prop s' → ( is : initial_state X, s' = `is) ∨ ( (l : label X) (som : state X * option message) (om' : option message), input_valid_transition l som (s', om'))
message: Type
X: VLSM message
s': state X
Hps': valid_state_prop s'

( is : initial_state X, s' = `is) ∨ ( (l : label X) (som : state X * option message) (om' : option message), input_valid_transition l som (s', om'))
message: Type
X: VLSM message
s': state X
om': option message
Hs: valid_state_message_prop s' om'

( is : initial_state X, s' = `is) ∨ ( (l : label X) (som : state X * option message) (om' : option message), input_valid_transition l som (s', om'))
message: Type
X: VLSM message
s': state X
om': option message
Hs: valid_state_message_prop s' om'
Hs0: initial_state_prop s'
Hom: option_initial_message_prop X om'

( is : initial_state X, s' = `is) ∨ ( (l : label X) (som : state X * option message) (om' : option message), input_valid_transition l som (s', om'))
message: Type
X: VLSM message
s': state X
om': option message
Hs: valid_state_message_prop s' om'
s: state X
_om: option message
_s: state X
om: option message
l0: label X
Hps: valid_state_message_prop s _om
Hpm: valid_state_message_prop _s om
Hv: valid l0 (s, om)
Ht: transition l0 (s, om) = (s', om')
( is : initial_state X, s' = `is) ∨ ( (l : label X) (som : state X * option message) (om' : option message), input_valid_transition l som (s', om'))
message: Type
X: VLSM message
s': state X
om': option message
Hs: valid_state_message_prop s' om'
Hs0: initial_state_prop s'
Hom: option_initial_message_prop X om'

( is : initial_state X, s' = `is) ∨ ( (l : label X) (som : state X * option message) (om' : option message), input_valid_transition l som (s', om'))
by left; exists (exist _ _ Hs0).
message: Type
X: VLSM message
s': state X
om': option message
Hs: valid_state_message_prop s' om'
s: state X
_om: option message
_s: state X
om: option message
l0: label X
Hps: valid_state_message_prop s _om
Hpm: valid_state_message_prop _s om
Hv: valid l0 (s, om)
Ht: transition l0 (s, om) = (s', om')

( is : initial_state X, s' = `is) ∨ ( (l : label X) (som : state X * option message) (om' : option message), input_valid_transition l som (s', om'))
by right; exists l0, (s, om), om'; firstorder.
message: Type
X: VLSM message
s': state X

( is : initial_state X, s' = `is) ∨ ( (l : label X) (som : state X * option message) (om' : option message), input_valid_transition l som (s', om')) → valid_state_prop s'
message: Type
X: VLSM message
s: state X
His: initial_state_prop s

valid_state_prop (`(s ↾ His))
message: Type
X: VLSM message
s': state X
l: label X
s: state X
om, om', _om: option message
Hps: valid_state_message_prop s _om
_s: state X
Hpm: valid_state_message_prop _s om
Hv: valid l (s, om)
Ht: transition l (s, om) = (s', om')
valid_state_prop s'
message: Type
X: VLSM message
s: state X
His: initial_state_prop s

valid_state_prop (`(s ↾ His))
by exists None; apply valid_initial_state_message.
message: Type
X: VLSM message
s': state X
l: label X
s: state X
om, om', _om: option message
Hps: valid_state_message_prop s _om
_s: state X
Hpm: valid_state_message_prop _s om
Hv: valid l (s, om)
Ht: transition l (s, om) = (s', om')

valid_state_prop s'
by exists om'; apply valid_generated_state_message with s _om _s om l. Qed.
A specialized induction principle for valid_state_prop.
Compared to opening the existential and using valid_state_message_prop_ind, this expresses the inductive assumptions simply in terms of input_valid_transition, rather than than having everything exploded as valid_state_message_prop assumptions over witnesses _s and _om, and a spurious inductive assumption P _s.
message: Type
X: VLSM message
P: state X → Prop
IHinit: s : state X, initial_state_prop s → P s
IHgen: (s' : state X) (l : label X) (om om' : option message) (s : state X), input_valid_transition l (s, om) (s', om') → P s → P s'

s : state X, valid_state_prop s → P s
message: Type
X: VLSM message
P: state X → Prop
IHinit: s : state X, initial_state_prop s → P s
IHgen: (s' : state X) (l : label X) (om om' : option message) (s : state X), input_valid_transition l (s, om) (s', om') → P s → P s'

s : state X, valid_state_prop s → P s
message: Type
X: VLSM message
P: state X → Prop
IHinit: s : state X, initial_state_prop s → P s
IHgen: (s' : state X) (l : label X) (om om' : option message) (s : state X), input_valid_transition l (s, om) (s', om') → P s → P s'
s: state X
Hs: valid_state_prop s

P s
message: Type
X: VLSM message
P: state X → Prop
IHinit: s : state X, initial_state_prop s → P s
IHgen: (s' : state X) (l : label X) (om om' : option message) (s : state X), input_valid_transition l (s, om) (s', om') → P s → P s'
s: state X
om: option message
Hs: valid_state_message_prop s om

P s
message: Type
X: VLSM message
P: state X → Prop
IHinit: s : state X, initial_state_prop s → P s
IHgen: (s' : state X) (l : label X) (om om' : option message) (s : state X), input_valid_transition l (s, om) (s', om') → P s → P s'
s: state X
Hs: initial_state_prop s
om: option message
Hom: option_initial_message_prop X om

P s
message: Type
X: VLSM message
P: state X → Prop
IHinit: s : state X, initial_state_prop s → P s
IHgen: (s' : state X) (l : label X) (om om' : option message) (s : state X), input_valid_transition l (s, om) (s', om') → P s → P s'
s: state X
_om: option message
Hs1: valid_state_message_prop s _om
_s: state X
om: option message
Hs2: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHHs1: P s
IHHs2: P _s
P s'
message: Type
X: VLSM message
P: state X → Prop
IHinit: s : state X, initial_state_prop s → P s
IHgen: (s' : state X) (l : label X) (om om' : option message) (s : state X), input_valid_transition l (s, om) (s', om') → P s → P s'
s: state X
Hs: initial_state_prop s
om: option message
Hom: option_initial_message_prop X om

P s
by apply IHinit.
message: Type
X: VLSM message
P: state X → Prop
IHinit: s : state X, initial_state_prop s → P s
IHgen: (s' : state X) (l : label X) (om om' : option message) (s : state X), input_valid_transition l (s, om) (s', om') → P s → P s'
s: state X
_om: option message
Hs1: valid_state_message_prop s _om
_s: state X
om: option message
Hs2: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHHs1: P s
IHHs2: P _s

P s'
by apply (IHgen s' l0 om om' s); firstorder. Qed.
Valid message characterization.
message: Type
X: VLSM message

m' : message, valid_message_prop m' ↔ ( im : initial_message X, m' = `im) ∨ ( (l : label X) (som : state X * option message) (s' : state X), input_valid_transition l som (s', Some m'))
message: Type
X: VLSM message

m' : message, valid_message_prop m' ↔ ( im : initial_message X, m' = `im) ∨ ( (l : label X) (som : state X * option message) (s' : state X), input_valid_transition l som (s', Some m'))
message: Type
X: VLSM message
m': message

valid_message_prop m' → ( im : initial_message X, m' = `im) ∨ ( (l : label X) (som : state X * option message) (s' : state X), input_valid_transition l som (s', Some m'))
message: Type
X: VLSM message
m': message
( im : initial_message X, m' = `im) ∨ ( (l : label X) (som : state X * option message) (s' : state X), input_valid_transition l som (s', Some m')) → valid_message_prop m'
message: Type
X: VLSM message
m': message

valid_message_prop m' → ( im : initial_message X, m' = `im) ∨ ( (l : label X) (som : state X * option message) (s' : state X), input_valid_transition l som (s', Some m'))
message: Type
X: VLSM message
m': message
s': state X
Hpm': valid_state_message_prop s' (Some m')

( im : initial_message X, m' = `im) ∨ ( (l : label X) (som : state X * option message) (s' : state X), input_valid_transition l som (s', Some m'))
message: Type
X: VLSM message
m': message
s': state X
Hpm': valid_state_message_prop s' (Some m')
Hs: initial_state_prop s'
Hom: option_initial_message_prop X (Some m')

( im : initial_message X, m' = `im) ∨ ( (l : label X) (som : state X * option message) (s' : state X), input_valid_transition l som (s', Some m'))
message: Type
X: VLSM message
m': message
s': state X
Hpm': valid_state_message_prop s' (Some m')
s: state X
_om: option message
_s: state X
om: option message
l0: label X
Hps: valid_state_message_prop s _om
Hpm: valid_state_message_prop _s om
Hv: valid l0 (s, om)
Ht: transition l0 (s, om) = (s', Some m')
( im : initial_message X, m' = `im) ∨ ( (l : label X) (som : state X * option message) (s' : state X), input_valid_transition l som (s', Some m'))
message: Type
X: VLSM message
m': message
s': state X
Hpm': valid_state_message_prop s' (Some m')
Hs: initial_state_prop s'
Hom: option_initial_message_prop X (Some m')

( im : initial_message X, m' = `im) ∨ ( (l : label X) (som : state X * option message) (s' : state X), input_valid_transition l som (s', Some m'))
by left; exists (exist _ m' Hom).
message: Type
X: VLSM message
m': message
s': state X
Hpm': valid_state_message_prop s' (Some m')
s: state X
_om: option message
_s: state X
om: option message
l0: label X
Hps: valid_state_message_prop s _om
Hpm: valid_state_message_prop _s om
Hv: valid l0 (s, om)
Ht: transition l0 (s, om) = (s', Some m')

( im : initial_message X, m' = `im) ∨ ( (l : label X) (som : state X * option message) (s' : state X), input_valid_transition l som (s', Some m'))
by right; exists l0, (s, om), s'; firstorder.
message: Type
X: VLSM message
m': message

( im : initial_message X, m' = `im) ∨ ( (l : label X) (som : state X * option message) (s' : state X), input_valid_transition l som (s', Some m')) → valid_message_prop m'
message: Type
X: VLSM message
s: message
His: initial_message_prop s

valid_message_prop (`(s ↾ His))
message: Type
X: VLSM message
m': message
l: label X
s: state X
om: option message
s': state X
_om: option message
Hps: valid_state_message_prop s _om
_s: state X
Hpm: valid_state_message_prop _s om
Hv: valid l (s, om)
Ht: transition l (s, om) = (s', Some m')
valid_message_prop m'
message: Type
X: VLSM message
s: message
His: initial_message_prop s

valid_message_prop (`(s ↾ His))
by apply initial_message_is_valid.
message: Type
X: VLSM message
m': message
l: label X
s: state X
om: option message
s': state X
_om: option message
Hps: valid_state_message_prop s _om
_s: state X
Hpm: valid_state_message_prop _s om
Hv: valid l (s, om)
Ht: transition l (s, om) = (s', Some m')

valid_message_prop m'
by exists s'; apply valid_generated_state_message with s _om _s om l. Qed.

Trace Properties

Note that it is unnecessary to specify the source state of the transition, as it is implied by the preceding transition_item (or by the start state, if such an item doesn't exist).
We will now split our groundwork for defining traces into the finite case and the infinite case.

Finite valid traces

A finite_valid_trace_from a state start is a pair (start, steps) where steps is a list of transition_items, and is inductively defined by:
Note that the definition is designed so that it extends an existing trace by adding a transition to its front. The reason for this choice is to have this definition be similar to the one for infinite traces, which can only be extended at the front.
Inductive finite_valid_trace_from : state X -> list transition_item -> Prop :=
| finite_valid_trace_from_empty :
    forall (s : state X) (Hs : valid_state_prop s),
      finite_valid_trace_from s []
| finite_valid_trace_from_extend :
    forall  (s : state X) (tl : list transition_item)
      (Htl : finite_valid_trace_from s tl)
      (s' : state X) (iom oom : option message) (l : label X)
      (Ht : input_valid_transition l (s', iom) (s, oom)),
        finite_valid_trace_from  s' (Build_transition_item l iom s oom :: tl).

message: Type
X: VLSM message

(l : label X) (s s' : state X) (iom oom : option message), input_valid_transition l (s, iom) (s', oom) → finite_valid_trace_from s [{| l := l; input := iom; destination := s'; output := oom |}]
message: Type
X: VLSM message

(l : label X) (s s' : state X) (iom oom : option message), input_valid_transition l (s, iom) (s', oom) → finite_valid_trace_from s [{| l := l; input := iom; destination := s'; output := oom |}]
message: Type
X: VLSM message
l: label X
s, s': state X
iom, oom: option message
Hptrans: input_valid_transition l (s, iom) (s', oom)

finite_valid_trace_from s [{| l := l; input := iom; destination := s'; output := oom |}]
message: Type
X: VLSM message
l: label X
s, s': state X
iom, oom: option message
Hptrans: input_valid_transition l (s, iom) (s', oom)

finite_valid_trace_from s' []
by constructor; apply input_valid_transition_destination in Hptrans. Defined.
To complete our definition of a finite valid trace, we must also guarantee that start is an initial state according to the protocol.
Definition finite_valid_trace (s : state X) (ls : list (transition_item X)) : Prop :=
  finite_valid_trace_from s ls /\ initial_state_prop X s.
In the remainder of the section we provide various results allowing us to prove or decompose the above properties in proofs.
finite_valid_trace_empty is a bit more useful than the small proof suggests, because applying it always leaves just one subgoal.
The tactical by split; [constructor; apply initial_state_is_valid |] only works if the premise is available in the context, which may require an assert and writing out the full VLSM and state expressions as part of the proof script.
message: Type
X: VLSM message

s : state X, initial_state_prop s → finite_valid_trace s []
message: Type
X: VLSM message

s : state X, initial_state_prop s → finite_valid_trace s []
by split; [constructor; apply initial_state_is_valid |]. Qed.
message: Type
X: VLSM message
s: state X
tr: list transition_item
te: transition_item
Htr: finite_valid_trace_from s (te :: tr)

input_valid_transition (l te) (s, input te) (destination te, output te)
message: Type
X: VLSM message
s: state X
tr: list transition_item
te: transition_item
Htr: finite_valid_trace_from s (te :: tr)

input_valid_transition (l te) (s, input te) (destination te, output te)
by inversion Htr. Qed.
message: Type
X: VLSM message
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr

valid_state_prop s
message: Type
X: VLSM message
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr

valid_state_prop s
by inversion Htr; subst; [| apply Ht]. Qed.
message: Type
X: VLSM message
s: state X
tr: list transition_item
te: transition_item
Htr: finite_valid_trace_from s (te :: tr)

finite_valid_trace_from (destination te) tr
message: Type
X: VLSM message
s: state X
tr: list transition_item
te: transition_item
Htr: finite_valid_trace_from s (te :: tr)

finite_valid_trace_from (destination te) tr
by inversion Htr. Qed.
message: Type
X: VLSM message
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr

valid_state_prop (finite_trace_last s tr)
message: Type
X: VLSM message
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr

valid_state_prop (finite_trace_last s tr)
message: Type
X: VLSM message
tr: list transition_item

s : state X, finite_valid_trace_from s tr → valid_state_prop (finite_trace_last s tr)
message: Type
X: VLSM message
s: state X
Htr: finite_valid_trace_from s []

valid_state_prop (finite_trace_last s [])
message: Type
X: VLSM message
a: transition_item
tr: list transition_item
IHtr: s : state X, finite_valid_trace_from s tr → valid_state_prop (finite_trace_last s tr)
s: state X
Htr: finite_valid_trace_from s (a :: tr)
valid_state_prop (finite_trace_last s (a :: tr))
message: Type
X: VLSM message
s: state X
Htr: finite_valid_trace_from s []

valid_state_prop (finite_trace_last s [])
by apply finite_valid_trace_first_pstate with [].
message: Type
X: VLSM message
a: transition_item
tr: list transition_item
IHtr: s : state X, finite_valid_trace_from s tr → valid_state_prop (finite_trace_last s tr)
s: state X
Htr: finite_valid_trace_from s (a :: tr)

valid_state_prop (finite_trace_last s (a :: tr))
message: Type
X: VLSM message
a: transition_item
tr: list transition_item
IHtr: s : state X, finite_valid_trace_from s tr → valid_state_prop (finite_trace_last s tr)
s: state X
Htr: finite_valid_trace_from (destination a) tr

valid_state_prop (finite_trace_last s (a :: tr))
message: Type
X: VLSM message
a: transition_item
tr: list transition_item
IHtr: s : state X, finite_valid_trace_from s tr → valid_state_prop (finite_trace_last s tr)
s: state X
Htr: valid_state_prop (finite_trace_last (destination a) tr)

valid_state_prop (finite_trace_last s (a :: tr))
message: Type
X: VLSM message
a: transition_item
tr: list transition_item
IHtr: s : state X, finite_valid_trace_from s tr → valid_state_prop (finite_trace_last s tr)
s: state X
Htr: valid_state_prop (finite_trace_last (destination a) tr)

finite_trace_last (destination a) tr = finite_trace_last s (a :: tr)
message: Type
X: VLSM message
a: transition_item
tr: list transition_item
IHtr: s : state X, finite_valid_trace_from s tr → valid_state_prop (finite_trace_last s tr)
s: state X
Htr: valid_state_prop (finite_trace_last (destination a) tr)

List.last (List.map destination tr) (destination a) = List.last (List.map destination (a :: tr)) s
by rewrite map_cons, unroll_last. Qed.
message: Type
X: VLSM message
s: state X
tr, tr1, tr2: list transition_item
te: transition_item
Htr: finite_valid_trace_from s tr
Heq: tr = tr1 ++ [te] ++ tr2
lst1:= finite_trace_last s tr1: state X

input_valid_transition (l te) (lst1, input te) (destination te, output te)
message: Type
X: VLSM message
s: state X
tr, tr1, tr2: list transition_item
te: transition_item
Htr: finite_valid_trace_from s tr
Heq: tr = tr1 ++ [te] ++ tr2
lst1:= finite_trace_last s tr1: state X

input_valid_transition (l te) (lst1, input te) (destination te, output te)
message: Type
X: VLSM message
tr, tr1, tr2: list transition_item
te: transition_item
Heq: tr = tr1 ++ [te] ++ tr2

s : state X, finite_valid_trace_from s tr → let lst1 := finite_trace_last s tr1 in input_valid_transition (l te) (lst1, input te) (destination te, output te)
message: Type
X: VLSM message
tr1, tr2: list transition_item
te: transition_item

tr : list transition_item, tr = tr1 ++ [te] ++ tr2 → s : state X, finite_valid_trace_from s tr → let lst1 := finite_trace_last s tr1 in input_valid_transition (l te) (lst1, input te) (destination te, output te)
message: Type
X: VLSM message
tr2: list transition_item
te: transition_item

tr : list transition_item, tr = [] ++ [te] ++ tr2 → s : state X, finite_valid_trace_from s tr → let lst1 := finite_trace_last s [] in input_valid_transition (l te) (lst1, input te) (destination te, output te)
message: Type
X: VLSM message
a: transition_item
tr1, tr2: list transition_item
te: transition_item
IHtr1: tr : list transition_item, tr = tr1 ++ [te] ++ tr2 → s : state X, finite_valid_trace_from s tr → let lst1 := finite_trace_last s tr1 in input_valid_transition (l te) (lst1, input te) (destination te, output te)
tr : list transition_item, tr = (a :: tr1) ++ [te] ++ tr2 → s : state X, finite_valid_trace_from s tr → let lst1 := finite_trace_last s (a :: tr1) in input_valid_transition (l te) (lst1, input te) (destination te, output te)
message: Type
X: VLSM message
tr2: list transition_item
te: transition_item

tr : list transition_item, tr = [] ++ [te] ++ tr2 → s : state X, finite_valid_trace_from s tr → let lst1 := finite_trace_last s [] in input_valid_transition (l te) (lst1, input te) (destination te, output te)
by intros tr [= ->] s; inversion 1.
message: Type
X: VLSM message
a: transition_item
tr1, tr2: list transition_item
te: transition_item
IHtr1: tr : list transition_item, tr = tr1 ++ [te] ++ tr2 → s : state X, finite_valid_trace_from s tr → let lst1 := finite_trace_last s tr1 in input_valid_transition (l te) (lst1, input te) (destination te, output te)

tr : list transition_item, tr = (a :: tr1) ++ [te] ++ tr2 → s : state X, finite_valid_trace_from s tr → let lst1 := finite_trace_last s (a :: tr1) in input_valid_transition (l te) (lst1, input te) (destination te, output te)
message: Type
X: VLSM message
a: transition_item
tr1, tr2: list transition_item
te: transition_item
IHtr1: s : state X, finite_valid_trace_from s (tr1 ++ [te] ++ tr2) → let lst1 := finite_trace_last s tr1 in input_valid_transition (l te) (lst1, input te) (destination te, output te)

tr : list transition_item, tr = (a :: tr1) ++ [te] ++ tr2 → s : state X, finite_valid_trace_from s tr → let lst1 := finite_trace_last s (a :: tr1) in input_valid_transition (l te) (lst1, input te) (destination te, output te)
message: Type
X: VLSM message
a: transition_item
tr1, tr2: list transition_item
te: transition_item
IHtr1: s : state X, finite_valid_trace_from s (tr1 ++ [te] ++ tr2) → let lst1 := finite_trace_last s tr1 in input_valid_transition (l te) (lst1, input te) (destination te, output te)
is: state X
Htr: finite_valid_trace_from is ((a :: tr1) ++ [te] ++ tr2)

let lst1 := finite_trace_last is (a :: tr1) in input_valid_transition (l te) (lst1, input te) (destination te, output te)
message: Type
X: VLSM message
tr1, tr2: list transition_item
te: transition_item
IHtr1: s : state X, finite_valid_trace_from s (tr1 ++ [te] ++ tr2) → let lst1 := finite_trace_last s tr1 in input_valid_transition (l te) (lst1, input te) (destination te, output te)
is, s: state X
iom, oom: option message
l0: label X
Htr: finite_valid_trace_from is (({| l := l0; input := iom; destination := s; output := oom |} :: tr1) ++ [te] ++ tr2)
Htl: finite_valid_trace_from s (tr1 ++ te :: tr2)
Ht: input_valid_transition l0 (is, iom) (s, oom)

let lst1 := finite_trace_last is ({| l := l0; input := iom; destination := s; output := oom |} :: tr1) in input_valid_transition (l te) (lst1, input te) (destination te, output te)
message: Type
X: VLSM message
tr1, tr2: list transition_item
te: transition_item
IHtr1: s : state X, finite_valid_trace_from s (tr1 ++ [te] ++ tr2) → let lst1 := finite_trace_last s tr1 in input_valid_transition (l te) (lst1, input te) (destination te, output te)
is, s: state X
iom, oom: option message
l0: label X
Htr: finite_valid_trace_from is (({| l := l0; input := iom; destination := s; output := oom |} :: tr1) ++ [te] ++ tr2)
Htl: finite_valid_trace_from s (tr1 ++ te :: tr2)
Ht: input_valid_transition l0 (is, iom) (s, oom)

let lst1 := finite_trace_last (destination {| l := l0; input := iom; destination := s; output := oom |}) tr1 in input_valid_transition (l te) (lst1, input te) (destination te, output te)
by apply IHtr1. Qed.
message: Type
X: VLSM message
s: state X
tr, tr1, tr2: list transition_item
te1, te2: transition_item
Htr: finite_valid_trace_from s tr
Heq: tr = tr1 ++ [te1; te2] ++ tr2

input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
message: Type
X: VLSM message
s: state X
tr, tr1, tr2: list transition_item
te1, te2: transition_item
Htr: finite_valid_trace_from s tr
Heq: tr = tr1 ++ [te1; te2] ++ tr2

input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
message: Type
X: VLSM message
s: state X
tr, tr1, tr2: list transition_item
te1, te2: transition_item
Htr: finite_valid_trace_from s tr
Heq: tr = tr1 ++ [te1] ++ [te2] ++ tr2

input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
message: Type
X: VLSM message
s: state X
tr, tr1, tr2: list transition_item
te1, te2: transition_item
Htr: finite_valid_trace_from s tr
Heq: tr = (tr1 ++ [te1]) ++ [te2] ++ tr2

input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
message: Type
X: VLSM message
s: state X
tr, tr1, tr2: list transition_item
te1, te2: transition_item
Htr: finite_valid_trace_from s tr
Heq: tr = (tr1 ++ [te1]) ++ [te2] ++ tr2
Ht: let lst1 := finite_trace_last s (tr1 ++ [te1]) in input_valid_transition (l te2) (lst1, input te2) (destination te2, output te2)

input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
by rewrite finite_trace_last_is_last in Ht. Qed.
message: Type
X: VLSM message
is: state X
tr: list transition_item
Htr: finite_valid_trace_from is tr
m: message
Houtput: trace_has_message (field_selector output) m tr

valid_message_prop m
message: Type
X: VLSM message
is: state X
tr: list transition_item
Htr: finite_valid_trace_from is tr
m: message
Houtput: trace_has_message (field_selector output) m tr

valid_message_prop m
message: Type
X: VLSM message
tr: list transition_item
m: message
Houtput: trace_has_message (field_selector output) m tr

is : state X, finite_valid_trace_from is tr → valid_message_prop m
message: Type
X: VLSM message
m: message
tr': list transition_item
s: state X
iom, oom: option message
l0: label X
Hm: field_selector output m {| l := l0; input := iom; destination := s; output := oom |}
is: state X
Htr: finite_valid_trace_from is ({| l := l0; input := iom; destination := s; output := oom |} :: tr')
Htl: finite_valid_trace_from s tr'
Ht: input_valid_transition l0 (is, iom) (s, oom)

valid_message_prop m
message: Type
X: VLSM message
m: message
tr': list transition_item
Houtput: List.Exists (field_selector output m) tr'
IHHoutput: is : state X, finite_valid_trace_from is tr' → valid_message_prop m
is, s: state X
iom, oom: option message
l0: label X
Htr: finite_valid_trace_from is ({| l := l0; input := iom; destination := s; output := oom |} :: tr')
Htl: finite_valid_trace_from s tr'
Ht: input_valid_transition l0 (is, iom) (s, oom)
valid_message_prop m
message: Type
X: VLSM message
m: message
tr': list transition_item
s: state X
iom, oom: option message
l0: label X
Hm: field_selector output m {| l := l0; input := iom; destination := s; output := oom |}
is: state X
Htr: finite_valid_trace_from is ({| l := l0; input := iom; destination := s; output := oom |} :: tr')
Htl: finite_valid_trace_from s tr'
Ht: input_valid_transition l0 (is, iom) (s, oom)

valid_message_prop m
message: Type
X: VLSM message
m: message
tr': list transition_item
s: state X
iom, oom: option message
l0: label X
Hm: oom = Some m
is: state X
Htr: finite_valid_trace_from is ({| l := l0; input := iom; destination := s; output := oom |} :: tr')
Htl: finite_valid_trace_from s tr'
Ht: input_valid_transition l0 (is, iom) (s, oom)

valid_message_prop m
message: Type
X: VLSM message
m: message
tr': list transition_item
s: state X
iom: option message
l0: label X
is: state X
Htr: finite_valid_trace_from is ({| l := l0; input := iom; destination := s; output := Some m |} :: tr')
Htl: finite_valid_trace_from s tr'
Ht: input_valid_transition l0 (is, iom) (s, Some m)

valid_message_prop m
by apply input_valid_transition_out in Ht.
message: Type
X: VLSM message
m: message
tr': list transition_item
Houtput: List.Exists (field_selector output m) tr'
IHHoutput: is : state X, finite_valid_trace_from is tr' → valid_message_prop m
is, s: state X
iom, oom: option message
l0: label X
Htr: finite_valid_trace_from is ({| l := l0; input := iom; destination := s; output := oom |} :: tr')
Htl: finite_valid_trace_from s tr'
Ht: input_valid_transition l0 (is, iom) (s, oom)

valid_message_prop m
by apply (IHHoutput s). Qed.
message: Type
X: VLSM message
is: state X
tr: list transition_item
Htr: finite_valid_trace_from is tr
m: message
Hinput: trace_has_message (field_selector input) m tr

valid_message_prop m
message: Type
X: VLSM message
is: state X
tr: list transition_item
Htr: finite_valid_trace_from is tr
m: message
Hinput: trace_has_message (field_selector input) m tr

valid_message_prop m
message: Type
X: VLSM message
tr: list transition_item
m: message
Hinput: trace_has_message (field_selector input) m tr

is : state X, finite_valid_trace_from is tr → valid_message_prop m
message: Type
X: VLSM message
m: message
tr': list transition_item
s: state X
iom, oom: option message
l: label X
Hm: field_selector input m {| l := l; input := iom; destination := s; output := oom |}
is: state X
Htr: finite_valid_trace_from is ({| l := l; input := iom; destination := s; output := oom |} :: tr')
Htr': finite_valid_trace_from s tr'
Ht: input_valid_transition l (is, iom) (s, oom)

valid_message_prop m
message: Type
X: VLSM message
m: message
tr': list transition_item
Hinput: List.Exists (field_selector input m) tr'
IHHinput: is : state X, finite_valid_trace_from is tr' → valid_message_prop m
is, s: state X
iom, oom: option message
l: label X
Htr: finite_valid_trace_from is ({| l := l; input := iom; destination := s; output := oom |} :: tr')
Htr': finite_valid_trace_from s tr'
Ht: input_valid_transition l (is, iom) (s, oom)
valid_message_prop m
message: Type
X: VLSM message
m: message
tr': list transition_item
s: state X
iom, oom: option message
l: label X
Hm: field_selector input m {| l := l; input := iom; destination := s; output := oom |}
is: state X
Htr: finite_valid_trace_from is ({| l := l; input := iom; destination := s; output := oom |} :: tr')
Htr': finite_valid_trace_from s tr'
Ht: input_valid_transition l (is, iom) (s, oom)

valid_message_prop m
message: Type
X: VLSM message
m: message
tr': list transition_item
s: state X
iom, oom: option message
l: label X
Hm: iom = Some m
is: state X
Htr: finite_valid_trace_from is ({| l := l; input := iom; destination := s; output := oom |} :: tr')
Htr': finite_valid_trace_from s tr'
Ht: input_valid_transition l (is, iom) (s, oom)

valid_message_prop m
message: Type
X: VLSM message
m: message
tr': list transition_item
s: state X
oom: option message
l: label X
is: state X
Htr: finite_valid_trace_from is ({| l := l; input := Some m; destination := s; output := oom |} :: tr')
Htr': finite_valid_trace_from s tr'
Ht: input_valid_transition l (is, Some m) (s, oom)

valid_message_prop m
by apply input_valid_transition_in in Ht.
message: Type
X: VLSM message
m: message
tr': list transition_item
Hinput: List.Exists (field_selector input m) tr'
IHHinput: is : state X, finite_valid_trace_from is tr' → valid_message_prop m
is, s: state X
iom, oom: option message
l: label X
Htr: finite_valid_trace_from is ({| l := l; input := iom; destination := s; output := oom |} :: tr')
Htr': finite_valid_trace_from s tr'
Ht: input_valid_transition l (is, iom) (s, oom)

valid_message_prop m
by apply (IHHinput s). Qed.
message: Type
X: VLSM message
is: state X
tr: list transition_item
Htr: finite_valid_trace_from is tr
m: message
Hobserved: trace_has_message item_sends_or_receives m tr

valid_message_prop m
message: Type
X: VLSM message
is: state X
tr: list transition_item
Htr: finite_valid_trace_from is tr
m: message
Hobserved: trace_has_message item_sends_or_receives m tr

valid_message_prop m
by apply trace_has_message_observed_iff in Hobserved as [Hm | Hm] ; revert Htr m Hm; [apply valid_trace_input_is_valid | apply valid_trace_output_is_valid]. Qed.
message: Type
X: VLSM message
s: state X
te: transition_item

finite_valid_trace_from s [te] ↔ input_valid_transition (l te) (s, input te) (destination te, output te)
message: Type
X: VLSM message
s: state X
te: transition_item

finite_valid_trace_from s [te] ↔ input_valid_transition (l te) (s, input te) (destination te, output te)
message: Type
X: VLSM message
s: state X
te: transition_item

input_valid_transition (l te) (s, input te) (destination te, output te) → finite_valid_trace_from s [te]
message: Type
X: VLSM message
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message

input_valid_transition (l {| l := l0; input := input0; destination := destination0; output := output0 |}) (s, input {| l := l0; input := input0; destination := destination0; output := output0 |}) (destination {| l := l0; input := input0; destination := destination0; output := output0 |}, output {| l := l0; input := input0; destination := destination0; output := output0 |}) → finite_valid_trace_from s [{| l := l0; input := input0; destination := destination0; output := output0 |}]
message: Type
X: VLSM message
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message

input_valid_transition l0 (s, input0) (destination0, output0) → finite_valid_trace_from s [{| l := l0; input := input0; destination := destination0; output := output0 |}]
message: Type
X: VLSM message
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message
Ht: input_valid_transition l0 ( s, input0) (destination0, output0)

finite_valid_trace_from s [{| l := l0; input := input0; destination := destination0; output := output0 |}]
message: Type
X: VLSM message
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message
Ht: input_valid_transition l0 ( s, input0) (destination0, output0)
Hdestination0: valid_state_prop destination0

finite_valid_trace_from s [{| l := l0; input := input0; destination := destination0; output := output0 |}]
by constructor; [constructor |]. Qed.
message: Type
X: VLSM message
s1: state X
ts: list transition_item
Ht12: finite_valid_trace_from s1 ts
l3: label X
s2:= finite_trace_last s1 ts: state X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (s2, iom3) (s3, oom3)

finite_valid_trace_from s1 (ts ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
message: Type
X: VLSM message
s1: state X
ts: list transition_item
Ht12: finite_valid_trace_from s1 ts
l3: label X
s2:= finite_trace_last s1 ts: state X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (s2, iom3) (s3, oom3)

finite_valid_trace_from s1 (ts ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
message: Type
X: VLSM message
s: state X
Hs: valid_state_prop s
l3: label X
s2:= finite_trace_last s []: state X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (s2, iom3) (s3, oom3)

finite_valid_trace_from s ([] ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
message: Type
X: VLSM message
s: state X
tl: list transition_item
Ht12: finite_valid_trace_from s tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s', iom) (s, oom)
l3: label X
s2:= finite_trace_last s' ({| l := l0; input := iom; destination := s; output := oom |} :: tl): state X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (s2, iom3) (s3, oom3)
IHHt12: let s2 := finite_trace_last s tl in input_valid_transition l3 ( s2, iom3) (s3, oom3) → finite_valid_trace_from s (tl ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
finite_valid_trace_from s' (({| l := l0; input := iom; destination := s; output := oom |} :: tl) ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
message: Type
X: VLSM message
s: state X
Hs: valid_state_prop s
l3: label X
s2:= finite_trace_last s []: state X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (s2, iom3) (s3, oom3)

finite_valid_trace_from s ([] ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
by apply finite_valid_trace_singleton.
message: Type
X: VLSM message
s: state X
tl: list transition_item
Ht12: finite_valid_trace_from s tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s', iom) (s, oom)
l3: label X
s2:= finite_trace_last s' ({| l := l0; input := iom; destination := s; output := oom |} :: tl): state X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (s2, iom3) (s3, oom3)
IHHt12: let s2 := finite_trace_last s tl in input_valid_transition l3 ( s2, iom3) (s3, oom3) → finite_valid_trace_from s (tl ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])

finite_valid_trace_from s' (({| l := l0; input := iom; destination := s; output := oom |} :: tl) ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
message: Type
X: VLSM message
s: state X
tl: list transition_item
Ht12: finite_valid_trace_from s tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s', iom) (s, oom)
l3: label X
s2:= finite_trace_last s' ({| l := l0; input := iom; destination := s; output := oom |} :: tl): state X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (s2, iom3) (s3, oom3)
IHHt12: let s2 := finite_trace_last s tl in input_valid_transition l3 ( s2, iom3) (s3, oom3) → finite_valid_trace_from s (tl ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])

finite_valid_trace_from s' ({| l := l0; input := iom; destination := s; output := oom |} :: tl ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
message: Type
X: VLSM message
s: state X
tl: list transition_item
Ht12: finite_valid_trace_from s tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s', iom) (s, oom)
l3: label X
s2:= finite_trace_last s' ({| l := l0; input := iom; destination := s; output := oom |} :: tl): state X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (s2, iom3) (s3, oom3)
IHHt12: let s2 := finite_trace_last s tl in input_valid_transition l3 ( s2, iom3) (s3, oom3) → finite_valid_trace_from s (tl ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])

finite_valid_trace_from s (tl ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
message: Type
X: VLSM message
s: state X
tl: list transition_item
Ht12: finite_valid_trace_from s tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s', iom) (s, oom)
l3: label X
s2:= finite_trace_last s' ({| l := l0; input := iom; destination := s; output := oom |} :: tl): state X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (s2, iom3) (s3, oom3)
IHHt12: input_valid_transition l3 (finite_trace_last s tl, iom3) ( s3, oom3) → finite_valid_trace_from s (tl ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])

finite_valid_trace_from s (tl ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
message: Type
X: VLSM message
s: state X
tl: list transition_item
Ht12: finite_valid_trace_from s tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s', iom) (s, oom)
l3: label X
s2:= finite_trace_last s' ({| l := l0; input := iom; destination := s; output := oom |} :: tl): state X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (s2, iom3) (s3, oom3)
IHHt12: input_valid_transition l3 (finite_trace_last s tl, iom3) ( s3, oom3) → finite_valid_trace_from s (tl ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])

input_valid_transition l3 (finite_trace_last s tl, iom3) (s3, oom3)
message: Type
X: VLSM message
s: state X
tl: list transition_item
Ht12: finite_valid_trace_from s tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s', iom) (s, oom)
l3: label X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (finite_trace_last s' ({| l := l0; input := iom; destination := s; output := oom |} :: tl), iom3) ( s3, oom3)
IHHt12: input_valid_transition l3 (finite_trace_last s tl, iom3) ( s3, oom3) → finite_valid_trace_from s (tl ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])

input_valid_transition l3 (finite_trace_last s tl, iom3) (s3, oom3)
by rewrite finite_trace_last_cons in Hv23. Qed.
We can now prove several general properties of finite_valid_traces. For example, the following lemma states that given two such traces, such that the latter's starting state is equal to the former's last state, it is possible to concatenate them into a single finite_valid_trace.
message: Type
X: VLSM message
s: state X
ls, ls': list transition_item
s':= finite_trace_last s ls: state X

finite_valid_trace_from s ls ∧ finite_valid_trace_from s' ls' ↔ finite_valid_trace_from s (ls ++ ls')
message: Type
X: VLSM message
s: state X
ls, ls': list transition_item
s':= finite_trace_last s ls: state X

finite_valid_trace_from s ls ∧ finite_valid_trace_from s' ls' ↔ finite_valid_trace_from s (ls ++ ls')
message: Type
X: VLSM message
s: state X
ls, ls': list transition_item

finite_valid_trace_from s ls ∧ finite_valid_trace_from (finite_trace_last s ls) ls' ↔ finite_valid_trace_from s (ls ++ ls')
message: Type
X: VLSM message
ls, ls': list transition_item

s : state X, finite_valid_trace_from s ls ∧ finite_valid_trace_from (finite_trace_last s ls) ls' ↔ finite_valid_trace_from s (ls ++ ls')
message: Type
X: VLSM message
ls': list transition_item
s: state X

finite_valid_trace_from s [] ∧ finite_valid_trace_from (finite_trace_last s []) ls' ↔ finite_valid_trace_from s ([] ++ ls')
message: Type
X: VLSM message
a: transition_item
ls, ls': list transition_item
IHls: s : state X, finite_valid_trace_from s ls ∧ finite_valid_trace_from (finite_trace_last s ls) ls' ↔ finite_valid_trace_from s (ls ++ ls')
s: state X
finite_valid_trace_from s (a :: ls) ∧ finite_valid_trace_from (finite_trace_last s (a :: ls)) ls' ↔ finite_valid_trace_from s ((a :: ls) ++ ls')
message: Type
X: VLSM message
ls': list transition_item
s: state X

finite_valid_trace_from s [] ∧ finite_valid_trace_from (finite_trace_last s []) ls' ↔ finite_valid_trace_from s ([] ++ ls')
message: Type
X: VLSM message
ls': list transition_item
s: state X

finite_valid_trace_from s [] ∧ finite_valid_trace_from s ls' ↔ finite_valid_trace_from s ([] ++ ls')
message: Type
X: VLSM message
ls': list transition_item
s: state X

finite_valid_trace_from s [] ∧ finite_valid_trace_from s ls' ↔ finite_valid_trace_from s ls'
by itauto (eauto using finite_valid_trace_first_pstate, finite_valid_trace_from_empty).
message: Type
X: VLSM message
a: transition_item
ls, ls': list transition_item
IHls: s : state X, finite_valid_trace_from s ls ∧ finite_valid_trace_from (finite_trace_last s ls) ls' ↔ finite_valid_trace_from s (ls ++ ls')
s: state X

finite_valid_trace_from s (a :: ls) ∧ finite_valid_trace_from (finite_trace_last s (a :: ls)) ls' ↔ finite_valid_trace_from s ((a :: ls) ++ ls')
message: Type
X: VLSM message
a: transition_item
ls, ls': list transition_item
IHls: s : state X, finite_valid_trace_from s ls ∧ finite_valid_trace_from (finite_trace_last s ls) ls' ↔ finite_valid_trace_from s (ls ++ ls')
s: state X

finite_valid_trace_from s (a :: ls) ∧ finite_valid_trace_from (finite_trace_last (destination a) ls) ls' ↔ finite_valid_trace_from s ((a :: ls) ++ ls')
message: Type
X: VLSM message
a: transition_item
ls, ls': list transition_item
IHls: s : state X, finite_valid_trace_from s ls ∧ finite_valid_trace_from (finite_trace_last s ls) ls' ↔ finite_valid_trace_from s (ls ++ ls')
s: state X

finite_valid_trace_from s (a :: ls) ∧ finite_valid_trace_from (finite_trace_last (destination a) ls) ls' ↔ finite_valid_trace_from s (a :: ls ++ ls')
message: Type
X: VLSM message
a: transition_item
ls, ls': list transition_item
IHls: finite_valid_trace_from (destination a) ls ∧ finite_valid_trace_from (finite_trace_last (destination a) ls) ls' ↔ finite_valid_trace_from (destination a) (ls ++ ls')
s: state X

finite_valid_trace_from s (a :: ls) ∧ finite_valid_trace_from (finite_trace_last (destination a) ls) ls' ↔ finite_valid_trace_from s (a :: ls ++ ls')
message: Type
X: VLSM message
a: transition_item
ls, ls': list transition_item
IHls: finite_valid_trace_from (destination a) ls ∧ finite_valid_trace_from (finite_trace_last (destination a) ls) ls' ↔ finite_valid_trace_from (destination a) (ls ++ ls')
s: state X

finite_valid_trace_from s (a :: ls) ∧ finite_valid_trace_from (finite_trace_last (destination a) ls) ls' → finite_valid_trace_from s (a :: ls ++ ls')
message: Type
X: VLSM message
a: transition_item
ls, ls': list transition_item
IHls: finite_valid_trace_from (destination a) ls ∧ finite_valid_trace_from (finite_trace_last (destination a) ls) ls' ↔ finite_valid_trace_from (destination a) (ls ++ ls')
s: state X
finite_valid_trace_from s (a :: ls ++ ls') → finite_valid_trace_from s (a :: ls) ∧ finite_valid_trace_from (finite_trace_last (destination a) ls) ls'
message: Type
X: VLSM message
a: transition_item
ls, ls': list transition_item
IHls: finite_valid_trace_from (destination a) ls ∧ finite_valid_trace_from (finite_trace_last (destination a) ls) ls' ↔ finite_valid_trace_from (destination a) (ls ++ ls')
s: state X

finite_valid_trace_from s (a :: ls) ∧ finite_valid_trace_from (finite_trace_last (destination a) ls) ls' → finite_valid_trace_from s (a :: ls ++ ls')
message: Type
X: VLSM message
a: transition_item
ls, ls': list transition_item
IHls: finite_valid_trace_from (destination a) ls ∧ finite_valid_trace_from (finite_trace_last (destination a) ls) ls' ↔ finite_valid_trace_from (destination a) (ls ++ ls')
s: state X
Hal: finite_valid_trace_from s (a :: ls)
Hl': finite_valid_trace_from (finite_trace_last (destination a) ls) ls'

finite_valid_trace_from s (a :: ls ++ ls')
message: Type
X: VLSM message
ls, ls': list transition_item
s1: state X
iom, oom: option message
l0: label X
IHls: finite_valid_trace_from s1 ls ∧ finite_valid_trace_from (finite_trace_last s1 ls) ls' ↔ finite_valid_trace_from s1 (ls ++ ls')
s: state X
Hl': finite_valid_trace_from (finite_trace_last s1 ls) ls'
Hal: finite_valid_trace_from s ({| l := l0; input := iom; destination := s1; output := oom |} :: ls)
Htl: finite_valid_trace_from s1 ls
Ht: input_valid_transition l0 (s, iom) (s1, oom)

finite_valid_trace_from s ({| l := l0; input := iom; destination := s1; output := oom |} :: ls ++ ls')
by constructor; [apply IHls |].
message: Type
X: VLSM message
a: transition_item
ls, ls': list transition_item
IHls: finite_valid_trace_from (destination a) ls ∧ finite_valid_trace_from (finite_trace_last (destination a) ls) ls' ↔ finite_valid_trace_from (destination a) (ls ++ ls')
s: state X

finite_valid_trace_from s (a :: ls ++ ls') → finite_valid_trace_from s (a :: ls) ∧ finite_valid_trace_from (finite_trace_last (destination a) ls) ls'
message: Type
X: VLSM message
ls, ls': list transition_item
s1: state X
iom, oom: option message
l0: label X
IHls: finite_valid_trace_from s1 ls ∧ finite_valid_trace_from (finite_trace_last s1 ls) ls' ↔ finite_valid_trace_from s1 (ls ++ ls')
s: state X
H: finite_valid_trace_from s ({| l := l0; input := iom; destination := s1; output := oom |} :: ls ++ ls')
Htl: finite_valid_trace_from s1 (ls ++ ls')
Ht: input_valid_transition l0 (s, iom) (s1, oom)

finite_valid_trace_from s ({| l := l0; input := iom; destination := s1; output := oom |} :: ls) ∧ finite_valid_trace_from (finite_trace_last s1 ls) ls'
message: Type
X: VLSM message
ls, ls': list transition_item
s1: state X
iom, oom: option message
l0: label X
IHls: finite_valid_trace_from s1 ls ∧ finite_valid_trace_from (finite_trace_last s1 ls) ls' ↔ finite_valid_trace_from s1 (ls ++ ls')
s: state X
H: finite_valid_trace_from s ({| l := l0; input := iom; destination := s1; output := oom |} :: ls ++ ls')
Hl: finite_valid_trace_from s1 ls
Hl': finite_valid_trace_from (finite_trace_last s1 ls) ls'
Ht: input_valid_transition l0 (s, iom) (s1, oom)

finite_valid_trace_from s ({| l := l0; input := iom; destination := s1; output := oom |} :: ls) ∧ finite_valid_trace_from (finite_trace_last s1 ls) ls'
by split; [constructor |]. Qed.
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: s : state X, valid_state_prop s → P s []
Hextend: (s : state X) (tr : list transition_item), finite_valid_trace_from s tr → P s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last s tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P s (tr ++ [x])

(s : state X) (tr : list transition_item), finite_valid_trace_from s tr → P s tr
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: s : state X, valid_state_prop s → P s []
Hextend: (s : state X) (tr : list transition_item), finite_valid_trace_from s tr → P s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last s tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P s (tr ++ [x])

(s : state X) (tr : list transition_item), finite_valid_trace_from s tr → P s tr
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: s : state X, valid_state_prop s → P s []
Hextend: (s : state X) (tr : list transition_item), finite_valid_trace_from s tr → P s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last s tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P s (tr ++ [x])
s: state X
Htr: finite_valid_trace_from s []

P s []
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: s : state X, valid_state_prop s → P s []
Hextend: (s : state X) (tr : list transition_item), finite_valid_trace_from s tr → P s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last s tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P s (tr ++ [x])
s: state X
x: transition_item
tr: list transition_item
IHtr: finite_valid_trace_from s tr → P s tr
Htr: finite_valid_trace_from s (tr ++ [x])
P s (tr ++ [x])
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: s : state X, valid_state_prop s → P s []
Hextend: (s : state X) (tr : list transition_item), finite_valid_trace_from s tr → P s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last s tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P s (tr ++ [x])
s: state X
Htr: finite_valid_trace_from s []

P s []
by inversion Htr; apply Hempty; congruence.
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: s : state X, valid_state_prop s → P s []
Hextend: (s : state X) (tr : list transition_item), finite_valid_trace_from s tr → P s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last s tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P s (tr ++ [x])
s: state X
x: transition_item
tr: list transition_item
IHtr: finite_valid_trace_from s tr → P s tr
Htr: finite_valid_trace_from s (tr ++ [x])

P s (tr ++ [x])
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: s : state X, valid_state_prop s → P s []
Hextend: (s : state X) (tr : list transition_item), finite_valid_trace_from s tr → P s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last s tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P s (tr ++ [x])
s: state X
x: transition_item
tr: list transition_item
IHtr: finite_valid_trace_from s tr → P s tr
Htr: finite_valid_trace_from s tr ∧ finite_valid_trace_from (finite_trace_last s tr) [x]

P s (tr ++ [x])
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: s : state X, valid_state_prop s → P s []
Hextend: (s : state X) (tr : list transition_item), finite_valid_trace_from s tr → P s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last s tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P s (tr ++ [x])
s: state X
x: transition_item
tr: list transition_item
IHtr: finite_valid_trace_from s tr → P s tr
Htr: finite_valid_trace_from s tr
Hx: finite_valid_trace_from (finite_trace_last s tr) [x]

P s (tr ++ [x])
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: s : state X, valid_state_prop s → P s []
Hextend: (s : state X) (tr : list transition_item), finite_valid_trace_from s tr → P s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last s tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P s (tr ++ [x])
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message
tr: list transition_item
IHtr: finite_valid_trace_from s tr → P s tr
Htr: finite_valid_trace_from s tr
Hx: finite_valid_trace_from (finite_trace_last s tr) [{| l := l0; input := input0; destination := destination0; output := output0 |}]

input_valid_transition l0 (finite_trace_last s tr, input0) (destination0, output0)
by inversion Hx; congruence. Qed.
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si []
Hextend: (si : state X) (tr : list transition_item), finite_valid_trace si tr → P si tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last si tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P si (tr ++ [x])

(si : state X) (tr : list transition_item), finite_valid_trace si tr → P si tr
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si []
Hextend: (si : state X) (tr : list transition_item), finite_valid_trace si tr → P si tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last si tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P si (tr ++ [x])

(si : state X) (tr : list transition_item), finite_valid_trace si tr → P si tr
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si []
Hextend: (si : state X) (tr : list transition_item), finite_valid_trace si tr → P si tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last si tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P si (tr ++ [x])
si: state X
tr: list transition_item
Htr: finite_valid_trace_from si tr
Hinit: initial_state_prop si

P si tr
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si []
Hextend: (si : state X) (tr : list transition_item), finite_valid_trace si tr → P si tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last si tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P si (tr ++ [x])
s: state X
H: valid_state_prop s
Hinit: initial_state_prop s

P s []
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si []
Hextend: (si : state X) (tr : list transition_item), finite_valid_trace si tr → P si tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last si tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P si (tr ++ [x])
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr
sf: state X
iom, oom: option message
l0: label X
Hx: input_valid_transition l0 (finite_trace_last s tr, iom) ( sf, oom)
x:= {| l := l0; input := iom; destination := sf; output := oom |}: transition_item
Hinit: initial_state_prop s
IHHtr: initial_state_prop s → P s tr
P s (tr ++ [x])
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si []
Hextend: (si : state X) (tr : list transition_item), finite_valid_trace si tr → P si tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last si tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P si (tr ++ [x])
s: state X
H: valid_state_prop s
Hinit: initial_state_prop s

P s []
by apply Hempty.
message: Type
X: VLSM message
P: state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si []
Hextend: (si : state X) (tr : list transition_item), finite_valid_trace si tr → P si tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l (finite_trace_last si tr, iom) (sf, oom) → let x := {| l := l; input := iom; destination := sf; output := oom |} in P si (tr ++ [x])
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr
sf: state X
iom, oom: option message
l0: label X
Hx: input_valid_transition l0 (finite_trace_last s tr, iom) ( sf, oom)
x:= {| l := l0; input := iom; destination := sf; output := oom |}: transition_item
Hinit: initial_state_prop s
IHHtr: initial_state_prop s → P s tr

P s (tr ++ [x])
by apply Hextend; auto. Qed.
Several other lemmas in this vein are necessary for proving results regarding traces.
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from s ls
n: nat

finite_valid_trace_from s (take n ls)
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from s ls
n: nat

finite_valid_trace_from s (take n ls)
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from s ls
n: nat
Hdecompose: take n ls ++ drop n ls = ls

finite_valid_trace_from s (take n ls)
message: Type
X: VLSM message
s: state X
ls: list transition_item
n: nat
Htr: finite_valid_trace_from s (take n ls ++ drop n ls)
Hdecompose: take n ls ++ drop n ls = ls

finite_valid_trace_from s (take n ls)
by apply finite_valid_trace_from_app_iff in Htr as [Hpr _]. Qed.
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from s ls
n: nat
nth: state X
Hnth: finite_trace_nth s ls n = Some nth

finite_valid_trace_from nth (drop n ls)
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from s ls
n: nat
nth: state X
Hnth: finite_trace_nth s ls n = Some nth

finite_valid_trace_from nth (drop n ls)
message: Type
X: VLSM message
s: state X
ls: list transition_item
n: nat
Htr: finite_valid_trace_from s (take n ls ++ drop n ls)
nth: state X
Hnth: finite_trace_nth s ls n = Some nth

finite_valid_trace_from nth (drop n ls)
message: Type
X: VLSM message
s: state X
ls: list transition_item
n: nat
Htr: finite_valid_trace_from s (take n ls) ∧ finite_valid_trace_from (finite_trace_last s (take n ls)) (drop n ls)
nth: state X
Hnth: finite_trace_nth s ls n = Some nth

finite_valid_trace_from nth (drop n ls)
message: Type
X: VLSM message
s: state X
ls: list transition_item
n: nat
Htr: finite_valid_trace_from (finite_trace_last s (take n ls)) (drop n ls)
nth: state X
Hnth: finite_trace_nth s ls n = Some nth

finite_valid_trace_from nth (drop n ls)
message: Type
X: VLSM message
s: state X
ls: list transition_item
n: nat
Htr: finite_valid_trace_from (finite_trace_last s (take n ls)) (drop n ls)
nth: state X
Hnth: finite_trace_nth s ls n = Some nth

nth = finite_trace_last s (take n ls)
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from (finite_trace_last s (take 0 ls)) (drop 0 ls)
nth: state X
Hnth: finite_trace_nth s ls 0 = Some nth

nth = finite_trace_last s (take 0 ls)
message: Type
X: VLSM message
s: state X
ls: list transition_item
n: nat
Htr: finite_valid_trace_from (finite_trace_last s (take (S n) ls)) (drop (S n) ls)
nth: state X
Hnth: finite_trace_nth s ls (S n) = Some nth
nth = finite_trace_last s (take (S n) ls)
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from (finite_trace_last s (take 0 ls)) (drop 0 ls)
nth: state X
Hnth: finite_trace_nth s ls 0 = Some nth

nth = finite_trace_last s (take 0 ls)
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from (finite_trace_last s (take 0 ls)) (drop 0 ls)
nth: state X
Hnth: Some s = Some nth

nth = finite_trace_last s (take 0 ls)
by destruct ls; cbn; congruence.
message: Type
X: VLSM message
s: state X
ls: list transition_item
n: nat
Htr: finite_valid_trace_from (finite_trace_last s (take (S n) ls)) (drop (S n) ls)
nth: state X
Hnth: finite_trace_nth s ls (S n) = Some nth

nth = finite_trace_last s (take (S n) ls)
message: Type
X: VLSM message
s: state X
ls: list transition_item
n: nat
Htr: finite_valid_trace_from (finite_trace_last s (take (S n) ls)) (drop (S n) ls)
nth: state X
Hnth: finite_trace_nth s ls (S n) = Some nth

nth = List.last (List.map destination (take (S n) ls)) s
message: Type
X: VLSM message
s: state X
ls: list transition_item
n: nat
Htr: finite_valid_trace_from (finite_trace_last s (take (S n) ls)) (drop (S n) ls)
nth: state X
Hnth: finite_trace_nth s ls (S n) = Some nth

nth = List.last (take (S n) (List.map destination ls)) s
by apply take_nth_last. Qed.
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from s ls
n1, n2: nat
Hle: n1 ≤ n2
n1th: state X
Hnth: finite_trace_nth s ls n1 = Some n1th

finite_valid_trace_from n1th (list_segment ls n1 n2)
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from s ls
n1, n2: nat
Hle: n1 ≤ n2
n1th: state X
Hnth: finite_trace_nth s ls n1 = Some n1th

finite_valid_trace_from n1th (list_segment ls n1 n2)
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from s ls
n1, n2: nat
Hle: n1 ≤ n2
n1th: state X
Hnth: finite_trace_nth s ls n1 = Some n1th

finite_valid_trace_from s (take n2 ls)
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from s ls
n1, n2: nat
Hle: n1 ≤ n2
n1th: state X
Hnth: finite_trace_nth s ls n1 = Some n1th
finite_trace_nth s (take n2 ls) n1 = Some n1th
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from s ls
n1, n2: nat
Hle: n1 ≤ n2
n1th: state X
Hnth: finite_trace_nth s ls n1 = Some n1th

finite_valid_trace_from s (take n2 ls)
by apply finite_valid_trace_from_prefix.
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from s ls
n1, n2: nat
Hle: n1 ≤ n2
n1th: state X
Hnth: finite_trace_nth s ls n1 = Some n1th

finite_trace_nth s (take n2 ls) n1 = Some n1th
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from s ls
n1, n2: nat
Hle: S n1 ≤ n2
n1th: state X
Hnth: finite_trace_nth s ls (S n1) = Some n1th

finite_trace_nth s (take n2 ls) (S n1) = Some n1th
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from s ls
n1, n2: nat
Hle: S n1 ≤ n2
n1th: state X
Hnth: nth_error (s :: List.map destination ls) (S n1) = Some n1th

nth_error (s :: List.map destination (take n2 ls)) (S n1) = Some n1th
message: Type
X: VLSM message
s: state X
ls: list transition_item
Htr: finite_valid_trace_from s ls
n1, n2: nat
Hle: S n1 ≤ n2
n1th: state X
Hnth: nth_error (List.map destination ls) n1 = Some n1th

nth_error (List.map destination (take n2 ls)) n1 = Some n1th
by rewrite <- firstn_map, take_nth. Qed.
message: Type
X: VLSM message
si: state X
tr: list transition_item
Htr: finite_valid_trace_from si tr

item : transition_item, item ∈ tr → option_can_produce (destination item) (output item)
message: Type
X: VLSM message
si: state X
tr: list transition_item
Htr: finite_valid_trace_from si tr

item : transition_item, item ∈ tr → option_can_produce (destination item) (output item)
message: Type
X: VLSM message
si: state X
tr: list transition_item
Htr: finite_valid_trace_from si tr
item: transition_item
Hitem: item ∈ tr

option_can_produce (destination item) (output item)
message: Type
X: VLSM message
si: state X
tr: list transition_item
Htr: finite_valid_trace_from si tr
item: transition_item
l1, l2: list transition_item
Heq: tr = l1 ++ item :: l2

option_can_produce (destination item) (output item)
message: Type
X: VLSM message
si: state X
tr: list transition_item
Htr: finite_valid_trace_from si tr
item: transition_item
l1, l2: list transition_item
Heq: tr = l1 ++ item :: l2

input_valid_transition ?Goal0 ?Goal (destination item, output item)
by eapply input_valid_transition_to; cbn. Qed.
message: Type
X: VLSM message
si: state X
m: message
tr: list transition_item
Htr: finite_valid_trace si tr
Hm: trace_has_message (field_selector output) m tr

can_emit m
message: Type
X: VLSM message
si: state X
m: message
tr: list transition_item
Htr: finite_valid_trace si tr
Hm: trace_has_message (field_selector output) m tr

can_emit m
message: Type
X: VLSM message
si: state X
m: message
tr: list transition_item
Htr: finite_valid_trace si tr
Hm: trace_has_message (field_selector output) m tr

s : state X, can_produce s m
message: Type
X: VLSM message
si: state X
m: message
tr: list transition_item
Htr: finite_valid_trace si tr
Hm: x : transition_item, x ∈ tr ∧ field_selector output m x

s : state X, can_produce s m
message: Type
X: VLSM message
si: state X
m: message
tr: list transition_item
Htr: finite_valid_trace si tr
item: transition_item
Hitem: item ∈ tr
Houtput: field_selector output m item

s : state X, can_produce s m
message: Type
X: VLSM message
si: state X
m: message
tr: list transition_item
Htr: finite_valid_trace si tr
item: transition_item
Hitem: item ∈ tr
Houtput: field_selector output m item

can_produce (destination item) m
message: Type
X: VLSM message
si: state X
m: message
tr: list transition_item
Htr: finite_valid_trace si tr
item: transition_item
Hitem: item ∈ tr
Houtput: field_selector output m item

option_can_produce (destination item) (output item)
by eapply can_produce_from_valid_trace; [apply Htr |]. Qed.

Finite valid traces with a final state

It is often necessary to refer to know ending state of a finite_valid_trace_from. This is either the destination of the last transition_item in the trace, or the starting state.
To avoid repeating reasoning about last, we define variants of finite_valid_trace_from and finite_valid_trace that include the final state, and give appropriate induction principles.
The final state of a finite portion of a valid trace. This is defined over finite_valid_trace_from because an initial state is necessary in case tr is empty, and this allows the definition to have only one non-implicit parameter.
Inductive finite_valid_trace_from_to : state X -> state X -> list transition_item -> Prop :=
| finite_valid_trace_from_to_empty :
    forall (s : state X)
      (Hs : valid_state_prop s),
        finite_valid_trace_from_to s s []
| finite_valid_trace_from_to_extend :
    forall (s f : state X) (tl : list transition_item)
      (Htl : finite_valid_trace_from_to s f tl)
      (s' : state X) (iom oom : option message) (l : label X)
      (Ht : input_valid_transition l (s', iom) (s, oom)),
        finite_valid_trace_from_to s' f (Build_transition_item l iom s oom :: tl).

message: Type
X: VLSM message
s, s': state X
iom, oom: option message
l: label X

input_valid_transition l (s, iom) (s', oom) → finite_valid_trace_from_to s s' [{| l := l; input := iom; destination := s'; output := oom |}]
message: Type
X: VLSM message
s, s': state X
iom, oom: option message
l: label X

input_valid_transition l (s, iom) (s', oom) → finite_valid_trace_from_to s s' [{| l := l; input := iom; destination := s'; output := oom |}]
message: Type
X: VLSM message
s, s': state X
iom, oom: option message
l: label X
Ht: input_valid_transition l (s, iom) (s', oom)

finite_valid_trace_from_to s s' [{| l := l; input := iom; destination := s'; output := oom |}]
message: Type
X: VLSM message
s, s': state X
iom, oom: option message
l: label X
Ht: input_valid_transition l (s, iom) (s', oom)

finite_valid_trace_from_to s' s' []
message: Type
X: VLSM message
s, s': state X
iom, oom: option message
l: label X
Ht: input_valid_transition l (s, iom) (s', oom)

valid_state_prop s'
by apply input_valid_transition_destination in Ht. Qed.
message: Type
X: VLSM message

(s f : state X) (tr : list transition_item), finite_valid_trace_from_to s f tr → finite_valid_trace_from s tr
message: Type
X: VLSM message

(s f : state X) (tr : list transition_item), finite_valid_trace_from_to s f tr → finite_valid_trace_from s tr
by induction 1; constructor; auto. Qed.
message: Type
X: VLSM message

(s f : state X) (tr : list transition_item), finite_valid_trace_from_to s f tr → finite_trace_last s tr = f
message: Type
X: VLSM message

(s f : state X) (tr : list transition_item), finite_valid_trace_from_to s f tr → finite_trace_last s tr = f
message: Type
X: VLSM message
s: state X
Hs: valid_state_prop s

finite_trace_last s [] = s
message: Type
X: VLSM message
s, f: state X
tl: list transition_item
H: finite_valid_trace_from_to s f tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s', iom) (s, oom)
IHfinite_valid_trace_from_to: finite_trace_last s tl = f
finite_trace_last s' ({| l := l0; input := iom; destination := s; output := oom |} :: tl) = f
message: Type
X: VLSM message
s: state X
Hs: valid_state_prop s

finite_trace_last s [] = s
by apply finite_trace_last_nil.
message: Type
X: VLSM message
s, f: state X
tl: list transition_item
H: finite_valid_trace_from_to s f tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s', iom) (s, oom)
IHfinite_valid_trace_from_to: finite_trace_last s tl = f

finite_trace_last s' ({| l := l0; input := iom; destination := s; output := oom |} :: tl) = f
by rewrite finite_trace_last_cons. Qed.
message: Type
X: VLSM message

(s f : state X) (tr : list transition_item), finite_valid_trace_from s tr → finite_trace_last s tr = f → finite_valid_trace_from_to s f tr
message: Type
X: VLSM message

(s f : state X) (tr : list transition_item), finite_valid_trace_from s tr → finite_trace_last s tr = f → finite_valid_trace_from_to s f tr
message: Type
X: VLSM message
f, s: state X
Hs: valid_state_prop s

finite_trace_last s [] = f → finite_valid_trace_from_to s f []
message: Type
X: VLSM message
f, s: state X
tl: list transition_item
H: finite_valid_trace_from s tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s', iom) (s, oom)
IHfinite_valid_trace_from: finite_trace_last s tl = f → finite_valid_trace_from_to s f tl
finite_trace_last s' ({| l := l0; input := iom; destination := s; output := oom |} :: tl) = f → finite_valid_trace_from_to s' f ({| l := l0; input := iom; destination := s; output := oom |} :: tl)
message: Type
X: VLSM message
f, s: state X
Hs: valid_state_prop s

finite_trace_last s [] = f → finite_valid_trace_from_to s f []
by rewrite finite_trace_last_nil; intros <-; constructor; auto.
message: Type
X: VLSM message
f, s: state X
tl: list transition_item
H: finite_valid_trace_from s tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s', iom) (s, oom)
IHfinite_valid_trace_from: finite_trace_last s tl = f → finite_valid_trace_from_to s f tl

finite_trace_last s' ({| l := l0; input := iom; destination := s; output := oom |} :: tl) = f → finite_valid_trace_from_to s' f ({| l := l0; input := iom; destination := s; output := oom |} :: tl)
by rewrite finite_trace_last_cons; intros <-; constructor; auto. Qed.
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_from_to s f tr → valid_state_prop s
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_from_to s f tr → valid_state_prop s
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr

valid_state_prop s
by apply finite_valid_trace_from_to_forget_last, finite_valid_trace_first_pstate in Htr. Qed.
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_from_to s f tr → valid_state_prop f
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_from_to s f tr → valid_state_prop f
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr

valid_state_prop f
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr

valid_state_prop (finite_trace_last s tr)
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr

finite_valid_trace_from s tr
by apply finite_valid_trace_from_to_forget_last in Htr. Qed.
message: Type
X: VLSM message
m, s, f: state X
ls, ls': list transition_item

finite_valid_trace_from_to s m ls → finite_valid_trace_from_to m f ls' → finite_valid_trace_from_to s f (ls ++ ls')
message: Type
X: VLSM message
m, s, f: state X
ls, ls': list transition_item

finite_valid_trace_from_to s m ls → finite_valid_trace_from_to m f ls' → finite_valid_trace_from_to s f (ls ++ ls')
by intros Hl Hl'; induction Hl; [| constructor; auto]. Qed.
message: Type
X: VLSM message
s, f: state X
ls, ls': list transition_item

finite_valid_trace_from_to s f (ls ++ ls') → let m := finite_trace_last s ls in finite_valid_trace_from_to s m ls ∧ finite_valid_trace_from_to m f ls'
message: Type
X: VLSM message
s, f: state X
ls, ls': list transition_item

finite_valid_trace_from_to s f (ls ++ ls') → let m := finite_trace_last s ls in finite_valid_trace_from_to s m ls ∧ finite_valid_trace_from_to m f ls'
message: Type
X: VLSM message
f: state X
ls': list transition_item
s: state X

finite_valid_trace_from_to s f ls' → finite_valid_trace_from_to s (finite_trace_last s []) [] ∧ finite_valid_trace_from_to (finite_trace_last s []) f ls'
message: Type
X: VLSM message
f: state X
a: transition_item
ls, ls': list transition_item
IHls: s : state X, finite_valid_trace_from_to s f (ls ++ ls') → let m := finite_trace_last s ls in finite_valid_trace_from_to s m ls ∧ finite_valid_trace_from_to m f ls'
s: state X
finite_valid_trace_from_to s f (a :: ls ++ ls') → finite_valid_trace_from_to s (finite_trace_last s (a :: ls)) (a :: ls) ∧ finite_valid_trace_from_to (finite_trace_last s (a :: ls)) f ls'
message: Type
X: VLSM message
f: state X
ls': list transition_item
s: state X

finite_valid_trace_from_to s f ls' → finite_valid_trace_from_to s (finite_trace_last s []) [] ∧ finite_valid_trace_from_to (finite_trace_last s []) f ls'
message: Type
X: VLSM message
f: state X
ls': list transition_item
s: state X

finite_valid_trace_from_to s f ls' → finite_valid_trace_from_to s s [] ∧ finite_valid_trace_from_to s f ls'
message: Type
X: VLSM message
f: state X
ls': list transition_item
s: state X
Htr: finite_valid_trace_from_to s f ls'

finite_valid_trace_from_to s s [] ∧ finite_valid_trace_from_to s f ls'
message: Type
X: VLSM message
f: state X
ls': list transition_item
s: state X
Htr: finite_valid_trace_from_to s f ls'

finite_valid_trace_from_to s s []
message: Type
X: VLSM message
f: state X
ls': list transition_item
s: state X
Htr: valid_state_prop s

finite_valid_trace_from_to s s []
by constructor.
message: Type
X: VLSM message
f: state X
a: transition_item
ls, ls': list transition_item
IHls: s : state X, finite_valid_trace_from_to s f (ls ++ ls') → let m := finite_trace_last s ls in finite_valid_trace_from_to s m ls ∧ finite_valid_trace_from_to m f ls'
s: state X

finite_valid_trace_from_to s f (a :: ls ++ ls') → finite_valid_trace_from_to s (finite_trace_last s (a :: ls)) (a :: ls) ∧ finite_valid_trace_from_to (finite_trace_last s (a :: ls)) f ls'
message: Type
X: VLSM message
f: state X
a: transition_item
ls, ls': list transition_item
IHls: s : state X, finite_valid_trace_from_to s f (ls ++ ls') → let m := finite_trace_last s ls in finite_valid_trace_from_to s m ls ∧ finite_valid_trace_from_to m f ls'
s: state X

finite_valid_trace_from_to s f (a :: ls ++ ls') → finite_valid_trace_from_to s (finite_trace_last (destination a) ls) (a :: ls) ∧ finite_valid_trace_from_to (finite_trace_last (destination a) ls) f ls'
message: Type
X: VLSM message
f: state X
ls, ls': list transition_item
IHls: s : state X, finite_valid_trace_from_to s f (ls ++ ls') → finite_valid_trace_from_to s (finite_trace_last s ls) ls ∧ finite_valid_trace_from_to (finite_trace_last s ls) f ls'
s, s1: state X
iom, oom: option message
l0: label X
H: finite_valid_trace_from_to s f ({| l := l0; input := iom; destination := s1; output := oom |} :: ls ++ ls')
Htl: finite_valid_trace_from_to s1 f (ls ++ ls')
Ht: input_valid_transition l0 (s, iom) (s1, oom)

finite_valid_trace_from_to s (finite_trace_last s1 ls) ({| l := l0; input := iom; destination := s1; output := oom |} :: ls) ∧ finite_valid_trace_from_to (finite_trace_last s1 ls) f ls'
message: Type
X: VLSM message
f: state X
ls, ls': list transition_item
IHls: s : state X, finite_valid_trace_from_to s f (ls ++ ls') → finite_valid_trace_from_to s (finite_trace_last s ls) ls ∧ finite_valid_trace_from_to (finite_trace_last s ls) f ls'
s, s1: state X
iom, oom: option message
l0: label X
H: finite_valid_trace_from_to s f ({| l := l0; input := iom; destination := s1; output := oom |} :: ls ++ ls')
H0: finite_valid_trace_from_to s1 (finite_trace_last s1 ls) ls
H1: finite_valid_trace_from_to (finite_trace_last s1 ls) f ls'
Ht: input_valid_transition l0 (s, iom) (s1, oom)

finite_valid_trace_from_to s (finite_trace_last s1 ls) ({| l := l0; input := iom; destination := s1; output := oom |} :: ls) ∧ finite_valid_trace_from_to (finite_trace_last s1 ls) f ls'
by auto using finite_valid_trace_from_to_extend. Qed.
message: Type
X: VLSM message

(s f : state X) (ls : list transition_item) (item : transition_item), finite_valid_trace_from_to s f (ls ++ [item]) ↔ (let m := finite_trace_last s ls in finite_valid_trace_from_to s m ls ∧ input_valid_transition_item m item ∧ destination item = f)
message: Type
X: VLSM message

(s f : state X) (ls : list transition_item) (item : transition_item), finite_valid_trace_from_to s f (ls ++ [item]) ↔ (let m := finite_trace_last s ls in finite_valid_trace_from_to s m ls ∧ input_valid_transition_item m item ∧ destination item = f)
message: Type
X: VLSM message
s, f: state X
ls: list transition_item
item: transition_item

finite_valid_trace_from_to s f (ls ++ [item]) → let m := finite_trace_last s ls in finite_valid_trace_from_to s m ls ∧ input_valid_transition_item m item ∧ destination item = f
message: Type
X: VLSM message
s, f: state X
ls: list transition_item
item: transition_item
(let m := finite_trace_last s ls in finite_valid_trace_from_to s m ls ∧ input_valid_transition_item m item ∧ destination item = f) → finite_valid_trace_from_to s f (ls ++ [item])
message: Type
X: VLSM message
s, f: state X
ls: list transition_item
item: transition_item

finite_valid_trace_from_to s f (ls ++ [item]) → let m := finite_trace_last s ls in finite_valid_trace_from_to s m ls ∧ input_valid_transition_item m item ∧ destination item = f
message: Type
X: VLSM message
s, f: state X
ls: list transition_item
item: transition_item
Htr: finite_valid_trace_from_to s (finite_trace_last s ls) ls
Hitem: finite_valid_trace_from_to (finite_trace_last s ls) f [item]

let m := finite_trace_last s ls in finite_valid_trace_from_to s m ls ∧ input_valid_transition_item m item ∧ destination item = f
by inversion Hitem; inversion Htl; subst.
message: Type
X: VLSM message
s, f: state X
ls: list transition_item
item: transition_item

(let m := finite_trace_last s ls in finite_valid_trace_from_to s m ls ∧ input_valid_transition_item m item ∧ destination item = f) → finite_valid_trace_from_to s f (ls ++ [item])
message: Type
X: VLSM message
s: state X
ls: list transition_item
item: transition_item
Htr: finite_valid_trace_from_to s (finite_trace_last s ls) ls
Hitem: input_valid_transition_item (finite_trace_last s ls) item

finite_valid_trace_from_to s (destination item) (ls ++ [item])
message: Type
X: VLSM message
s: state X
ls: list transition_item
item: transition_item
Htr: finite_valid_trace_from_to s (finite_trace_last s ls) ls
Hitem: input_valid_transition_item (finite_trace_last s ls) item

finite_valid_trace_from_to (finite_trace_last s ls) (destination item) [item]
by destruct item; apply finite_valid_trace_from_to_singleton. Qed. Definition finite_valid_trace_init_to (si sf : state X) (tr : list transition_item) : Prop := finite_valid_trace_from_to si sf tr /\ initial_state_prop X si.
message: Type
X: VLSM message
si, sf: state X
tr: list transition_item

finite_valid_trace si tr → finite_trace_last si tr = sf → finite_valid_trace_init_to si sf tr
message: Type
X: VLSM message
si, sf: state X
tr: list transition_item

finite_valid_trace si tr → finite_trace_last si tr = sf → finite_valid_trace_init_to si sf tr
message: Type
X: VLSM message
si, sf: state X
tr: list transition_item
Htr: finite_valid_trace_from si tr
Hinit: initial_state_prop si
Hf: finite_trace_last si tr = sf

finite_valid_trace_init_to si sf tr
by split; eauto using finite_valid_trace_from_add_last. Qed.
message: Type
X: VLSM message
si, sf: state X
tr: list transition_item

finite_valid_trace_init_to si sf tr → finite_valid_trace si tr
message: Type
X: VLSM message
si, sf: state X
tr: list transition_item

finite_valid_trace_init_to si sf tr → finite_valid_trace si tr
message: Type
X: VLSM message
si, sf: state X
tr: list transition_item
Hinit: finite_valid_trace_from_to si sf tr
Htr: initial_state_prop si

finite_valid_trace si tr
by split; eauto using finite_valid_trace_from_to_forget_last. Qed.
message: Type
X: VLSM message
si, sf: state X
tr: list transition_item

finite_valid_trace_init_to si sf tr → finite_trace_last si tr = sf
message: Type
X: VLSM message
si, sf: state X
tr: list transition_item

finite_valid_trace_init_to si sf tr → finite_trace_last si tr = sf
message: Type
X: VLSM message
si, sf: state X
tr: list transition_item
Htr: finite_valid_trace_from_to si sf tr

finite_trace_last si tr = sf
by eauto using finite_valid_trace_from_to_last. Qed.
message: Type
X: VLSM message

(si sf : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace_init_to si sf (tr ++ [item]) ↔ finite_valid_trace_init_to si (finite_trace_last si tr) tr ∧ input_valid_transition_item (finite_trace_last si tr) item ∧ destination item = sf
message: Type
X: VLSM message

(si sf : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace_init_to si sf (tr ++ [item]) ↔ finite_valid_trace_init_to si (finite_trace_last si tr) tr ∧ input_valid_transition_item (finite_trace_last si tr) item ∧ destination item = sf
message: Type
X: VLSM message
si, sf: state X
tr: list transition_item
item: transition_item

finite_valid_trace_from_to si sf (tr ++ [item]) ∧ initial_state_prop si ↔ (finite_valid_trace_from_to si (finite_trace_last si tr) tr ∧ initial_state_prop si) ∧ input_valid_transition_item (finite_trace_last si tr) item ∧ destination item = sf
message: Type
X: VLSM message
si, sf: state X
tr: list transition_item
item: transition_item

(let m := finite_trace_last si tr in finite_valid_trace_from_to si m tr ∧ input_valid_transition_item m item ∧ destination item = sf) ∧ initial_state_prop si ↔ (finite_valid_trace_from_to si (finite_trace_last si tr) tr ∧ initial_state_prop si) ∧ input_valid_transition_item (finite_trace_last si tr) item ∧ destination item = sf
by itauto. Qed.
message: Type
X: VLSM message

(si sf : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace_init_to si sf tr → input_valid_transition_item sf item → finite_valid_trace_init_to si (destination item) (tr ++ [item])
message: Type
X: VLSM message

(si sf : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace_init_to si sf tr → input_valid_transition_item sf item → finite_valid_trace_init_to si (destination item) (tr ++ [item])
message: Type
X: VLSM message

(si sf : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace_from_to si sf tr ∧ initial_state_prop si → input_valid_transition_item sf item → finite_valid_trace_from_to si (destination item) (tr ++ [item]) ∧ initial_state_prop si
message: Type
X: VLSM message
si, sf: state X
tr: list transition_item
item: transition_item
Htr: finite_valid_trace_from_to si sf tr
Hinit: initial_state_prop si
Hivt: input_valid_transition_item sf item

finite_valid_trace_from_to si (destination item) (tr ++ [item]) ∧ initial_state_prop si
message: Type
X: VLSM message
si, sf: state X
tr: list transition_item
item: transition_item
Htr: finite_valid_trace_from_to si sf tr
Hinit: initial_state_prop si
Hivt: input_valid_transition_item sf item

(let m := finite_trace_last si tr in finite_valid_trace_from_to si m tr ∧ input_valid_transition_item m item ∧ destination item = destination item) ∧ initial_state_prop si
message: Type
X: VLSM message
si: state X
tr: list transition_item
item: transition_item
Htr: finite_valid_trace_from_to si (finite_trace_last si tr) tr
Hinit: initial_state_prop si
Hivt: input_valid_transition_item (finite_trace_last si tr) item

(let m := finite_trace_last si tr in finite_valid_trace_from_to si m tr ∧ input_valid_transition_item m item ∧ destination item = destination item) ∧ initial_state_prop si
by itauto. Qed.
message: Type
X: VLSM message

(si sf : state X) (pre tr : list transition_item), finite_valid_trace_init_to si sf tr → pre `prefix_of` tr → finite_valid_trace_init_to si (finite_trace_last si pre) pre
message: Type
X: VLSM message

(si sf : state X) (pre tr : list transition_item), finite_valid_trace_init_to si sf tr → pre `prefix_of` tr → finite_valid_trace_init_to si (finite_trace_last si pre) pre
message: Type
X: VLSM message
si, sf: state X
pre, suf: list transition_item
H: finite_valid_trace_from_to si sf (pre ++ suf)
H0: initial_state_prop si

finite_valid_trace_from_to si (finite_trace_last si pre) pre
by eapply finite_valid_trace_from_to_app_split. Qed.
message: Type
X: VLSM message

(si sf : state X) (pre suf : list transition_item), finite_valid_trace_init_to si sf (pre ++ suf) → finite_valid_trace_init_to si (finite_trace_last si pre) pre
message: Type
X: VLSM message

(si sf : state X) (pre suf : list transition_item), finite_valid_trace_init_to si sf (pre ++ suf) → finite_valid_trace_init_to si (finite_trace_last si pre) pre
by intros; eapply finite_valid_trace_init_to_prefix; [| eexists]. Qed.
message: Type
X: VLSM message
s1, s2: state X
ts: list transition_item
Ht12: finite_valid_trace_from_to s1 s2 ts
l3: label X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (s2, iom3) (s3, oom3)

finite_valid_trace_from_to s1 s3 (ts ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
message: Type
X: VLSM message
s1, s2: state X
ts: list transition_item
Ht12: finite_valid_trace_from_to s1 s2 ts
l3: label X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (s2, iom3) (s3, oom3)

finite_valid_trace_from_to s1 s3 (ts ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
message: Type
X: VLSM message
s: state X
Hs: valid_state_prop s
l3: label X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (s, iom3) (s3, oom3)

finite_valid_trace_from_to s s3 ([] ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
message: Type
X: VLSM message
s, f: state X
tl: list transition_item
Ht12: finite_valid_trace_from_to s f tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s', iom) (s, oom)
l3: label X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (f, iom3) (s3, oom3)
IHHt12: input_valid_transition l3 ( f, iom3) (s3, oom3) → finite_valid_trace_from_to s s3 (tl ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
finite_valid_trace_from_to s' s3 (({| l := l0; input := iom; destination := s; output := oom |} :: tl) ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
message: Type
X: VLSM message
s: state X
Hs: valid_state_prop s
l3: label X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (s, iom3) (s3, oom3)

finite_valid_trace_from_to s s3 ([] ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
by apply finite_valid_trace_from_to_singleton.
message: Type
X: VLSM message
s, f: state X
tl: list transition_item
Ht12: finite_valid_trace_from_to s f tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s', iom) (s, oom)
l3: label X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (f, iom3) (s3, oom3)
IHHt12: input_valid_transition l3 ( f, iom3) (s3, oom3) → finite_valid_trace_from_to s s3 (tl ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])

finite_valid_trace_from_to s' s3 (({| l := l0; input := iom; destination := s; output := oom |} :: tl) ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
message: Type
X: VLSM message
s, f: state X
tl: list transition_item
Ht12: finite_valid_trace_from_to s f tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s', iom) (s, oom)
l3: label X
iom3: option message
s3: state X
oom3: option message
Hv23: input_valid_transition l3 (f, iom3) (s3, oom3)
IHHt12: input_valid_transition l3 ( f, iom3) (s3, oom3) → finite_valid_trace_from_to s s3 (tl ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])

finite_valid_trace_from_to s' s3 ({| l := l0; input := iom; destination := s; output := oom |} :: tl ++ [{| l := l3; input := iom3; destination := s3; output := oom3 |}])
by apply finite_valid_trace_from_to_extend; auto. Qed.
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, valid_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_from_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])

(si sf : state X) (tr : list transition_item), finite_valid_trace_from_to si sf tr → P si sf tr
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, valid_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_from_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])

(si sf : state X) (tr : list transition_item), finite_valid_trace_from_to si sf tr → P si sf tr
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, valid_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_from_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si, sf: state X
tr: list transition_item
Htr: finite_valid_trace_from_to si sf tr

P si sf tr
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, valid_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_from_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si: state X
tr: list transition_item

sf : state X, finite_valid_trace_from_to si sf tr → P si sf tr
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, valid_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_from_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si, sf: state X
Htr: finite_valid_trace_from_to si sf []

P si sf []
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, valid_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_from_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si: state X
x: transition_item
tr: list transition_item
IHtr: sf : state X, finite_valid_trace_from_to si sf tr → P si sf tr
sf: state X
Htr: finite_valid_trace_from_to si sf (tr ++ [x])
P si sf (tr ++ [x])
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, valid_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_from_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si, sf: state X
Htr: finite_valid_trace_from_to si sf []

P si sf []
by inversion Htr; subst; apply Hempty.
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, valid_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_from_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si: state X
x: transition_item
tr: list transition_item
IHtr: sf : state X, finite_valid_trace_from_to si sf tr → P si sf tr
sf: state X
Htr: finite_valid_trace_from_to si sf (tr ++ [x])

P si sf (tr ++ [x])
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, valid_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_from_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si: state X
x: transition_item
tr: list transition_item
IHtr: sf : state X, finite_valid_trace_from_to si sf tr → P si sf tr
sf: state X
Htr: finite_valid_trace_from_to si (finite_trace_last si tr) tr ∧ finite_valid_trace_from_to (finite_trace_last si tr) sf [x]

P si sf (tr ++ [x])
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, valid_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_from_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si: state X
x: transition_item
tr: list transition_item
IHtr: sf : state X, finite_valid_trace_from_to si sf tr → P si sf tr
sf: state X
Htr: finite_valid_trace_from_to si (finite_trace_last si tr) tr
Hstep: finite_valid_trace_from_to (finite_trace_last si tr) sf [x]

P si sf (tr ++ [x])
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, valid_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_from_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si: state X
tr: list transition_item
IHtr: sf : state X, finite_valid_trace_from_to si sf tr → P si sf tr
sf: state X
Htr: finite_valid_trace_from_to si (finite_trace_last si tr) tr
s: state X
iom, oom: option message
l0: label X
Hstep: finite_valid_trace_from_to (finite_trace_last si tr) sf [{| l := l0; input := iom; destination := s; output := oom |}]
Htl: finite_valid_trace_from_to s sf []
Ht: input_valid_transition l0 (finite_trace_last si tr, iom) ( s, oom)

P si sf (tr ++ [{| l := l0; input := iom; destination := s; output := oom |}])
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, valid_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_from_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si: state X
tr: list transition_item
IHtr: sf : state X, finite_valid_trace_from_to si sf tr → P si sf tr
sf: state X
Htr: finite_valid_trace_from_to si (finite_trace_last si tr) tr
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (finite_trace_last si tr, iom) ( sf, oom)
Htl: finite_valid_trace_from_to sf sf []
Hstep: finite_valid_trace_from_to (finite_trace_last si tr) sf [{| l := l0; input := iom; destination := sf; output := oom |}]
Hs: valid_state_prop sf

P si sf (tr ++ [{| l := l0; input := iom; destination := sf; output := oom |}])
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, valid_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_from_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si: state X
tr: list transition_item
IHtr: sf : state X, finite_valid_trace_from_to si sf tr → P si sf tr
sf: state X
Htr: finite_valid_trace_from_to si (finite_trace_last si tr) tr
iom, oom: option message
l0: label X
Htl: finite_valid_trace_from_to sf sf []
Hstep: finite_valid_trace_from_to (finite_trace_last si tr) sf [{| l := l0; input := iom; destination := sf; output := oom |}]
Hs: valid_state_prop sf

input_valid_transition l0 (finite_trace_last si tr, iom) (sf, oom) → P si sf (tr ++ [{| l := l0; input := iom; destination := sf; output := oom |}])
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, valid_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_from_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si: state X
tr: list transition_item
IHtr: sf : state X, finite_valid_trace_from_to si sf tr → P si sf tr
sf: state X
Htr: finite_valid_trace_from_to si (finite_trace_last si tr) tr
iom, oom: option message
l0: label X
Htl: finite_valid_trace_from_to sf sf []
Hstep: finite_valid_trace_from_to (finite_trace_last si tr) sf [{| l := l0; input := iom; destination := sf; output := oom |}]
Hs: valid_state_prop sf

P si (finite_trace_last si tr) tr
by apply IHtr. Qed.
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_init_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])

(si sf : state X) (tr : list transition_item), finite_valid_trace_init_to si sf tr → P si sf tr
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_init_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])

(si sf : state X) (tr : list transition_item), finite_valid_trace_init_to si sf tr → P si sf tr
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_init_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si, sf: state X
tr: list transition_item
Htr: finite_valid_trace_init_to si sf tr

P si sf tr
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_init_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si, sf: state X
tr: list transition_item
Htr: finite_valid_trace_from_to si sf tr
Hinit: initial_state_prop si

P si sf tr
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_init_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si: state X
Hsi: valid_state_prop si
Hinit: initial_state_prop si

P si si []
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_init_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to si s tr
sf: state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s, iom) (sf, oom)
Hinit: initial_state_prop si
IHHtr: initial_state_prop si → P si s tr
P si sf (tr ++ [{| l := l0; input := iom; destination := sf; output := oom |}])
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_init_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si: state X
Hsi: valid_state_prop si
Hinit: initial_state_prop si

P si si []
by apply Hempty.
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: si : state X, initial_state_prop si → P si si []
Hextend: (si s : state X) (tr : list transition_item), P si s tr → finite_valid_trace_init_to si s tr → (sf : state X) (iom oom : option message) (l : label X), input_valid_transition l ( s, iom) (sf, oom) → P si sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
si, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to si s tr
sf: state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s, iom) (sf, oom)
Hinit: initial_state_prop si
IHHtr: initial_state_prop si → P si s tr

P si sf (tr ++ [{| l := l0; input := iom; destination := sf; output := oom |}])
by apply Hextend with s; auto. Qed.
An inductive valid trace property which also identifies the final message.
As shown by the finite_valid_trace_init_to_emit_valid_state_message and finite_valid_trace_init_to_emit_valid_state_message_rev lemmas below, this definition is the trace-equivalent of the valid_state_message_property.
This inductive property is reflecting that fact that a that valid_state_message_prop (s, om) holds only if s and om are the final state and output of an initial valid trace, or a pair of an initial state and option-initial message. It follows the inductive structure of valid_state_message_prop, but augments every branch of the tree with such an exhibiting trace.
Its main benefit is that when performing induction over it, one can also use the induction hypothesis for the (trace generating the) message being received.
Although this definition could be used directly, we prefer to use it to derive a stronger induction principle (finite_valid_trace_init_to_rev_strong_ind) over finite_valid_trace_init_to traces.
Inductive finite_valid_trace_init_to_emit
  : state X -> state X -> option message -> list (transition_item X) -> Prop :=
| finite_valid_trace_init_to_emit_empty :
    forall (is : state X) (om : option message)
      (His : initial_state_prop X is)
      (Him : option_initial_message_prop X om),
        finite_valid_trace_init_to_emit is is om []
| finite_valid_trace_init_to_emit_extend :
    forall (is s : state X) (_om : option message) (tl : list (transition_item X))
      (Hs : finite_valid_trace_init_to_emit is s _om tl)
      (iom_is iom_s : state X) (iom : option message) (iom_tl : list (transition_item X))
      (Hiom : finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl)
      (l : label X)
      (Hv : valid X l (s, iom))
      (s' : state X) (oom : option message)
      (Ht : transition X l (s, iom) = (s', oom)),
        finite_valid_trace_init_to_emit is s' oom (tl ++ [Build_transition_item l iom s' oom]).

message: Type
X: VLSM message
is, f: state X
om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit is f om tl

initial_state_prop is
message: Type
X: VLSM message
is, f: state X
om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit is f om tl

initial_state_prop is
by induction Htl. Qed.
A property characterizing the "emit" message of finite_valid_trace_init_to_emit.
There are two cases: (1) either the trace is empty, and then we require the message to be initial; or (2) the trace is not empty, and the message is the output of the last transition.
message: Type
X: VLSM message
tl: list transition_item
om: option message

Prop
message: Type
X: VLSM message
tl: list transition_item
om: option message

Prop
message: Type
X: VLSM message
tl: list transition_item
om: option message
item: transition_item

Prop
message: Type
X: VLSM message
tl: list transition_item
om: option message
Prop
message: Type
X: VLSM message
tl: list transition_item
om: option message
item: transition_item

Prop
exact (output item = om).
message: Type
X: VLSM message
tl: list transition_item
om: option message

Prop
exact (option_initial_message_prop X om). Defined.
message: Type
X: VLSM message
s, f: state X
om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit s f om tl

empty_initial_message_or_final_output tl om
message: Type
X: VLSM message
s, f: state X
om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit s f om tl

empty_initial_message_or_final_output tl om
message: Type
X: VLSM message
s, f: state X
om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit s f om tl

match has_last_or_null tl with | inleft (existT x (x0 ↾ _)) => output x0 = om | inright _ => option_initial_message_prop X om end
message: Type
X: VLSM message
s, f: state X
om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit s f om []
Heqtl: tl = []

option_initial_message_prop X om
message: Type
X: VLSM message
s, f: state X
om: option message
tl, tl': list transition_item
item: transition_item
Htl: finite_valid_trace_init_to_emit s f om (tl' ++ [item])
Heqtl: tl = tl' ++ [item]
output item = om
message: Type
X: VLSM message
s, f: state X
om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit s f om []
Heqtl: tl = []

option_initial_message_prop X om
message: Type
X: VLSM message
s, f: state X
om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit s f om []
Heqtl: tl = []
is, s1: state X
_om: option message
tl0: list transition_item
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
l0: label X
s': state X
oom: option message
Hs: finite_valid_trace_init_to_emit s s1 _om tl0
Hiom: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
Hv: valid l0 (s1, iom)
Ht: transition l0 (s1, iom) = (f, om)
H: is = s
H0: s' = f
H1: oom = om
H3: tl0 ++ [{| l := l0; input := iom; destination := f; output := om |}] = []

option_initial_message_prop X om
by destruct tl0; simpl in *; congruence.
message: Type
X: VLSM message
s, f: state X
om: option message
tl, tl': list transition_item
item: transition_item
Htl: finite_valid_trace_init_to_emit s f om (tl' ++ [item])
Heqtl: tl = tl' ++ [item]

output item = om
message: Type
X: VLSM message
s, f: state X
om: option message
tl, tl': list transition_item
item: transition_item
Htl: finite_valid_trace_init_to_emit s f om tl
Heqtl: tl = tl' ++ [item]

output item = om
message: Type
X: VLSM message
s, f: state X
om: option message
tl, tl': list transition_item
item: transition_item
Htl: finite_valid_trace_init_to_emit s f om tl
Heqtl: tl = tl' ++ [item]
is, s1: state X
_om: option message
tl0: list transition_item
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
l0: label X
s': state X
oom: option message
Hs: finite_valid_trace_init_to_emit s s1 _om tl0
Hiom: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
Hv: valid l0 (s1, iom)
Ht: transition l0 (s1, iom) = (f, om)
H: is = s
H0: s' = f
H1: oom = om
H2: tl0 ++ [{| l := l0; input := iom; destination := f; output := om |}] = tl

output item = om
message: Type
X: VLSM message
s, f: state X
om: option message
tl': list transition_item
item: transition_item
tl0: list transition_item
iom: option message
l0: label X
Htl: finite_valid_trace_init_to_emit s f om (tl0 ++ [{| l := l0; input := iom; destination := f; output := om |}])
s1: state X
_om: option message
iom_is, iom_s: state X
iom_tl: list transition_item
Hs: finite_valid_trace_init_to_emit s s1 _om tl0
Hiom: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
Hv: valid l0 (s1, iom)
Ht: transition l0 (s1, iom) = (f, om)
Heqtl: tl0 ++ [{| l := l0; input := iom; destination := f; output := om |}] = tl' ++ [item]

output item = om
by apply app_inj_tail, proj2 in Heqtl; subst. Qed.
message: Type
X: VLSM message
s, f: state X
om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit s f om tl

valid_state_message_prop f om
message: Type
X: VLSM message
s, f: state X
om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit s f om tl

valid_state_message_prop f om
message: Type
X: VLSM message
is: state X
om: option message
His: initial_state_prop is
Him: option_initial_message_prop X om

valid_state_message_prop is om
message: Type
X: VLSM message
is, s: state X
_om: option message
tl: list transition_item
Htl1: finite_valid_trace_init_to_emit is s _om tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htl2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtl1: valid_state_message_prop s _om
IHHtl2: valid_state_message_prop iom_s iom
valid_state_message_prop s' oom
message: Type
X: VLSM message
is: state X
om: option message
His: initial_state_prop is
Him: option_initial_message_prop X om

valid_state_message_prop is om
by apply valid_initial_state_message.
message: Type
X: VLSM message
is, s: state X
_om: option message
tl: list transition_item
Htl1: finite_valid_trace_init_to_emit is s _om tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htl2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtl1: valid_state_message_prop s _om
IHHtl2: valid_state_message_prop iom_s iom

valid_state_message_prop s' oom
by apply valid_generated_state_message with s _om iom_s iom l0. Qed.
message: Type
X: VLSM message
sf: state X
om: option message
Hp: valid_state_message_prop sf om

(s : state X) (tl : list transition_item), finite_valid_trace_init_to_emit s sf om tl
message: Type
X: VLSM message
sf: state X
om: option message
Hp: valid_state_message_prop sf om

(s : state X) (tl : list transition_item), finite_valid_trace_init_to_emit s sf om tl
message: Type
X: VLSM message
s: state X
Hs: initial_state_prop s
om: option message
Hom: option_initial_message_prop X om

(s0 : state X) (tl : list transition_item), finite_valid_trace_init_to_emit s0 s om tl
message: Type
X: VLSM message
s: state X
_om: option message
Hp1: valid_state_message_prop s _om
_s: state X
om: option message
Hp2: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHHp1: (s0 : state X) (tl : list transition_item), finite_valid_trace_init_to_emit s0 s _om tl
IHHp2: (s : state X) (tl : list transition_item), finite_valid_trace_init_to_emit s _s om tl
(s : state X) (tl : list transition_item), finite_valid_trace_init_to_emit s s' om' tl
message: Type
X: VLSM message
s: state X
Hs: initial_state_prop s
om: option message
Hom: option_initial_message_prop X om

(s0 : state X) (tl : list transition_item), finite_valid_trace_init_to_emit s0 s om tl
by exists s, []; constructor.
message: Type
X: VLSM message
s: state X
_om: option message
Hp1: valid_state_message_prop s _om
_s: state X
om: option message
Hp2: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
IHHp1: (s0 : state X) (tl : list transition_item), finite_valid_trace_init_to_emit s0 s _om tl
IHHp2: (s : state X) (tl : list transition_item), finite_valid_trace_init_to_emit s _s om tl

(s : state X) (tl : list transition_item), finite_valid_trace_init_to_emit s s' om' tl
message: Type
X: VLSM message
s: state X
_om: option message
Hp1: valid_state_message_prop s _om
_s: state X
om: option message
Hp2: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
is: state X
tl: list transition_item
Hs: finite_valid_trace_init_to_emit is s _om tl
IHHp2: (s : state X) (tl : list transition_item), finite_valid_trace_init_to_emit s _s om tl

(s : state X) (tl : list transition_item), finite_valid_trace_init_to_emit s s' om' tl
message: Type
X: VLSM message
s: state X
_om: option message
Hp1: valid_state_message_prop s _om
_s: state X
om: option message
Hp2: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
is: state X
tl: list transition_item
Hs: finite_valid_trace_init_to_emit is s _om tl
om_is: state X
om_tl: list transition_item
Hom: finite_valid_trace_init_to_emit om_is _s om om_tl

(s : state X) (tl : list transition_item), finite_valid_trace_init_to_emit s s' om' tl
message: Type
X: VLSM message
s: state X
_om: option message
Hp1: valid_state_message_prop s _om
_s: state X
om: option message
Hp2: valid_state_message_prop _s om
l0: label X
Hv: valid l0 (s, om)
s': state X
om': option message
Ht: transition l0 (s, om) = (s', om')
is: state X
tl: list transition_item
Hs: finite_valid_trace_init_to_emit is s _om tl
om_is: state X
om_tl: list transition_item
Hom: finite_valid_trace_init_to_emit om_is _s om om_tl

finite_valid_trace_init_to_emit ?s s' om' ?tl
by eapply finite_valid_trace_init_to_emit_extend; cycle 1. Qed.
message: Type
X: VLSM message
s, f: state X
_om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit s f _om tl

finite_valid_trace_init_to s f tl
message: Type
X: VLSM message
s, f: state X
_om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit s f _om tl

finite_valid_trace_init_to s f tl
message: Type
X: VLSM message
s, f: state X
_om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit s f _om tl
Hinit: initial_state_prop s

finite_valid_trace_init_to s f tl
message: Type
X: VLSM message
s, f: state X
_om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit s f _om tl
Hinit: initial_state_prop s

finite_valid_trace_from_to s f tl
message: Type
X: VLSM message
s, f: state X
_om: option message
tl: list transition_item
Htl: finite_valid_trace_init_to_emit s f _om tl

finite_valid_trace_from_to s f tl
message: Type
X: VLSM message
is: state X
om: option message
His: initial_state_prop is
Him: option_initial_message_prop X om

finite_valid_trace_from_to is is []
message: Type
X: VLSM message
is, s: state X
_om: option message
tl: list transition_item
Htl1: finite_valid_trace_init_to_emit is s _om tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htl2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtl1: finite_valid_trace_from_to is s tl
IHHtl2: finite_valid_trace_from_to iom_is iom_s iom_tl
finite_valid_trace_from_to is s' (tl ++ [{| l := l0; input := iom; destination := s'; output := oom |}])
message: Type
X: VLSM message
is: state X
om: option message
His: initial_state_prop is
Him: option_initial_message_prop X om

finite_valid_trace_from_to is is []
by constructor; apply initial_state_is_valid.
message: Type
X: VLSM message
is, s: state X
_om: option message
tl: list transition_item
Htl1: finite_valid_trace_init_to_emit is s _om tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htl2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtl1: finite_valid_trace_from_to is s tl
IHHtl2: finite_valid_trace_from_to iom_is iom_s iom_tl

finite_valid_trace_from_to is s' (tl ++ [{| l := l0; input := iom; destination := s'; output := oom |}])
message: Type
X: VLSM message
is, s: state X
_om: option message
tl: list transition_item
Htl1: finite_valid_trace_init_to_emit is s _om tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htl2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtl1: finite_valid_trace_from_to is s tl
IHHtl2: finite_valid_trace_from_to iom_is iom_s iom_tl

finite_valid_trace_from_to s s' [{| l := l0; input := iom; destination := s'; output := oom |}]
message: Type
X: VLSM message
is, s: state X
_om: option message
tl: list transition_item
Htl1: finite_valid_trace_init_to_emit is s _om tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htl2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtl1: finite_valid_trace_from_to is s tl
IHHtl2: finite_valid_trace_from_to iom_is iom_s iom_tl

input_valid_transition l0 (s, iom) (s', oom)
message: Type
X: VLSM message
is, s: state X
_om: option message
tl: list transition_item
Htl1: valid_state_message_prop s _om
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htl2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtl1: finite_valid_trace_from_to is s tl
IHHtl2: finite_valid_trace_from_to iom_is iom_s iom_tl

input_valid_transition l0 (s, iom) (s', oom)
message: Type
X: VLSM message
is, s: state X
_om: option message
tl: list transition_item
Htl1: valid_state_message_prop s _om
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htl2: valid_state_message_prop iom_s iom
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtl1: finite_valid_trace_from_to is s tl
IHHtl2: finite_valid_trace_from_to iom_is iom_s iom_tl

input_valid_transition l0 (s, iom) (s', oom)
by firstorder. Qed.
message: Type
X: VLSM message
s, f: state X
tl: list transition_item
Htl: finite_valid_trace_init_to s f tl

finite_valid_trace_init_to_emit s f (finite_trace_last_output tl) tl
message: Type
X: VLSM message
s, f: state X
tl: list transition_item
Htl: finite_valid_trace_init_to s f tl

finite_valid_trace_init_to_emit s f (finite_trace_last_output tl) tl
message: Type
X: VLSM message
si, s: state X
tr: list transition_item
Htl: finite_valid_trace_init_to si s tr
sf: state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s, iom) (sf, oom)
IHHtl: finite_valid_trace_init_to_emit si s (finite_trace_last_output tr) tr

finite_valid_trace_init_to_emit si sf (finite_trace_last_output (tr ++ [{| l := l0; input := iom; destination := sf; output := oom |}])) (tr ++ [{| l := l0; input := iom; destination := sf; output := oom |}])
message: Type
X: VLSM message
si, s: state X
tr: list transition_item
Htl: finite_valid_trace_init_to si s tr
sf: state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s, iom) (sf, oom)
IHHtl: finite_valid_trace_init_to_emit si s (finite_trace_last_output tr) tr

finite_valid_trace_init_to_emit si sf (output {| l := l0; input := iom; destination := sf; output := oom |}) (tr ++ [{| l := l0; input := iom; destination := sf; output := oom |}])
message: Type
X: VLSM message
si, s: state X
tr: list transition_item
Htl: finite_valid_trace_init_to si s tr
sf: state X
iom, oom: option message
l0: label X
Ht: input_valid_transition l0 (s, iom) (sf, oom)
IHHtl: finite_valid_trace_init_to_emit si s (finite_trace_last_output tr) tr

finite_valid_trace_init_to_emit si sf oom (tr ++ [{| l := l0; input := iom; destination := sf; output := oom |}])
message: Type
X: VLSM message
si, s: state X
tr: list transition_item
Htl: finite_valid_trace_init_to si s tr
sf: state X
iom, oom: option message
l0: label X
_s: state X
Hiom: valid_state_message_prop _s iom
Hv: valid l0 (s, iom)
Ht: transition l0 (s, iom) = (sf, oom)
IHHtl: finite_valid_trace_init_to_emit si s (finite_trace_last_output tr) tr

finite_valid_trace_init_to_emit si sf oom (tr ++ [{| l := l0; input := iom; destination := sf; output := oom |}])
message: Type
X: VLSM message
si, s: state X
tr: list transition_item
Htl: finite_valid_trace_init_to si s tr
sf: state X
iom, oom: option message
l0: label X
_s: state X
Hiom: valid_state_message_prop _s iom
Hv: valid l0 (s, iom)
Ht: transition l0 (s, iom) = (sf, oom)
IHHtl: finite_valid_trace_init_to_emit si s (finite_trace_last_output tr) tr
iom_s: state X
iom_tr: list transition_item
Hiom_tr: finite_valid_trace_init_to_emit iom_s _s iom iom_tr

finite_valid_trace_init_to_emit si sf oom (tr ++ [{| l := l0; input := iom; destination := sf; output := oom |}])
by apply (finite_valid_trace_init_to_emit_extend _ _ _ _ IHHtl _ _ _ _ Hiom_tr _ Hv _ _ Ht). Qed.
Inspired by finite_valid_trace_init_to_add_emit, we can derive an induction principle for finite_valid_trace_init_to stronger than finite_valid_trace_init_to_rev_ind, which allows the induction hypothesis to be used for the trace generating the message received in the last transition.
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])

(si sf : state X) (tr : list transition_item), finite_valid_trace_init_to si sf tr → P si sf tr
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])

(si sf : state X) (tr : list transition_item), finite_valid_trace_init_to si sf tr → P si sf tr
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, sf: state X
tr: list transition_item
Htr: finite_valid_trace_init_to is sf tr

P is sf tr
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, sf: state X
tr: list transition_item
Htr: finite_valid_trace_init_to_emit is sf (finite_trace_last_output tr) tr

P is sf tr
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, sf: state X
tr: list transition_item
om: option message
Heqom: om = finite_trace_last_output tr
Htr: finite_valid_trace_init_to_emit is sf om tr

P is sf tr
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, sf: state X
tr: list transition_item
om: option message
Htr: finite_valid_trace_init_to_emit is sf om tr

P is sf tr
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is: state X
om: option message
His: initial_state_prop is
Him: option_initial_message_prop X om

P is is []
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, s: state X
_om: option message
tl: list transition_item
Htr1: finite_valid_trace_init_to_emit is s _om tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htr2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtr1: P is s tl
IHHtr2: P iom_is iom_s iom_tl
P is s' (tl ++ [{| l := l0; input := iom; destination := s'; output := oom |}])
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is: state X
om: option message
His: initial_state_prop is
Him: option_initial_message_prop X om

P is is []
by apply Hempty.
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, s: state X
_om: option message
tl: list transition_item
Htr1: finite_valid_trace_init_to_emit is s _om tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htr2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtr1: P is s tl
IHHtr2: P iom_is iom_s iom_tl

P is s' (tl ++ [{| l := l0; input := iom; destination := s'; output := oom |}])
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, s: state X
_om: option message
tl: list transition_item
Htr1: finite_valid_trace_init_to_emit is s _om tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htr2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtr1: P is s tl
IHHtr2: P iom_is iom_s iom_tl

input_valid_transition l0 (s, iom) (s', oom)
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, s: state X
_om: option message
tl: list transition_item
Htr1: finite_valid_trace_init_to_emit is s _om tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htr2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtr1: P is s tl
IHHtr2: P iom_is iom_s iom_tl
Hivt: input_valid_transition l0 (s, iom) (s', oom)
P is s' (tl ++ [{| l := l0; input := iom; destination := s'; output := oom |}])
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, s: state X
_om: option message
tl: list transition_item
Htr1: finite_valid_trace_init_to_emit is s _om tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htr2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtr1: P is s tl
IHHtr2: P iom_is iom_s iom_tl

input_valid_transition l0 (s, iom) (s', oom)
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, s: state X
_om: option message
tl: list transition_item
Htr1: valid_state_message_prop s _om
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htr2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtr1: P is s tl
IHHtr2: P iom_is iom_s iom_tl

input_valid_transition l0 (s, iom) (s', oom)
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, s: state X
_om: option message
tl: list transition_item
Htr1: valid_state_message_prop s _om
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htr2: valid_state_message_prop iom_s iom
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtr1: P is s tl
IHHtr2: P iom_is iom_s iom_tl

input_valid_transition l0 (s, iom) (s', oom)
by firstorder.
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, s: state X
_om: option message
tl: list transition_item
Htr1: finite_valid_trace_init_to_emit is s _om tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htr2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtr1: P is s tl
IHHtr2: P iom_is iom_s iom_tl
Hivt: input_valid_transition l0 (s, iom) (s', oom)

P is s' (tl ++ [{| l := l0; input := iom; destination := s'; output := oom |}])
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, s: state X
_om: option message
tl: list transition_item
Htr1: finite_valid_trace_init_to_emit is s _om tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htr2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtr1: P is s tl
IHHtr2: P iom_is iom_s iom_tl
Hivt: input_valid_transition l0 (s, iom) (s', oom)
Houtput: empty_initial_message_or_final_output iom_tl iom

P is s' (tl ++ [{| l := l0; input := iom; destination := s'; output := oom |}])
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, s: state X
_om: option message
tl: list transition_item
Htr1: finite_valid_trace_init_to is s tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htr2: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtr1: P is s tl
IHHtr2: P iom_is iom_s iom_tl
Hivt: input_valid_transition l0 (s, iom) (s', oom)
Houtput: empty_initial_message_or_final_output iom_tl iom

P is s' (tl ++ [{| l := l0; input := iom; destination := s'; output := oom |}])
message: Type
X: VLSM message
P: state X → state X → list transition_item → Prop
Hempty: is : state X, initial_state_prop is → P is is []
Hextend: (is s : state X) (tr : list transition_item), P is s tr → finite_valid_trace_init_to is s tr → (iom : option message) (iom_si iom_s : state X) (iom_tr : list transition_item), empty_initial_message_or_final_output iom_tr iom → P iom_si iom_s iom_tr → finite_valid_trace_init_to iom_si iom_s iom_tr → (sf : state X) (oom : option message) (l : label X), input_valid_transition l (s, iom) ( sf, oom) → P is sf (tr ++ [{| l := l; input := iom; destination := sf; output := oom |}])
is, s: state X
_om: option message
tl: list transition_item
Htr1: finite_valid_trace_init_to is s tl
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
Htr2: finite_valid_trace_init_to iom_is iom_s iom_tl
l0: label X
Hv: valid l0 (s, iom)
s': state X
oom: option message
Ht: transition l0 (s, iom) = (s', oom)
IHHtr1: P is s tl
IHHtr2: P iom_is iom_s iom_tl
Hivt: input_valid_transition l0 (s, iom) (s', oom)
Houtput: empty_initial_message_or_final_output iom_tl iom

P is s' (tl ++ [{| l := l0; input := iom; destination := s'; output := oom |}])
by apply (Hextend _ _ _ IHHtr1 Htr1 _ _ _ _ Houtput IHHtr2 Htr2 _ _ _ Hivt). Qed.

Infinite protocol traces

We now define infinite_valid_traces. The definitions resemble their finite counterparts, adapted to the technical necessities of defining infinite objects. Notably, steps is stored as a stream, as opposed to a list.
CoInductive infinite_valid_trace_from :
  state X -> Stream transition_item -> Prop :=
| infinite_valid_trace_from_extend :
    forall (s : state X) (tl : Stream transition_item)
      (Htl : infinite_valid_trace_from s tl)
      (s' : state X) (iom oom : option message) (l : label X)
      (Ht : input_valid_transition l (s', iom) (s, oom)),
        infinite_valid_trace_from  s' (Cons (Build_transition_item l iom s oom) tl).

Definition infinite_valid_trace (s : state X) (st : Stream (transition_item X)) : Prop :=
  infinite_valid_trace_from s st /\ initial_state_prop X s.
As for the finite case, the following lemmas help decompose teh above definitions, mostly reducing them to properties about their finite segments.
message: Type
X: VLSM message
is: state X
tr, tr2: Stream transition_item
tr1: list transition_item
te1, te2: transition_item
Htr: infinite_valid_trace_from is tr
Heq: tr = stream_app (tr1 ++ [te1; te2]) tr2

input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
message: Type
X: VLSM message
is: state X
tr, tr2: Stream transition_item
tr1: list transition_item
te1, te2: transition_item
Htr: infinite_valid_trace_from is tr
Heq: tr = stream_app (tr1 ++ [te1; te2]) tr2

input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
message: Type
X: VLSM message
tr, tr2: Stream transition_item
tr1: list transition_item
te1, te2: transition_item
Heq: tr = stream_app (tr1 ++ [te1; te2]) tr2

is : state X, infinite_valid_trace_from is tr → input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
message: Type
X: VLSM message
tr2: Stream transition_item
tr1: list transition_item
te1, te2: transition_item

tr : Stream transition_item, tr = stream_app (tr1 ++ [te1; te2]) tr2 → is : state X, infinite_valid_trace_from is tr → input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
message: Type
X: VLSM message
tr2: Stream transition_item
te1, te2: transition_item

tr : Stream transition_item, tr = stream_app ([] ++ [te1; te2]) tr2 → is : state X, infinite_valid_trace_from is tr → input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
message: Type
X: VLSM message
tr2: Stream transition_item
a: transition_item
tr1: list transition_item
te1, te2: transition_item
IHtr1: tr : Stream transition_item, tr = stream_app (tr1 ++ [te1; te2]) tr2 → is : state X, infinite_valid_trace_from is tr → input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
tr : Stream transition_item, tr = stream_app ((a :: tr1) ++ [te1; te2]) tr2 → is : state X, infinite_valid_trace_from is tr → input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
message: Type
X: VLSM message
tr2: Stream transition_item
te1, te2: transition_item

tr : Stream transition_item, tr = stream_app ([] ++ [te1; te2]) tr2 → is : state X, infinite_valid_trace_from is tr → input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
by cbn; intros tr -> is Htr; inversion Htr; inversion Htl; subst.
message: Type
X: VLSM message
tr2: Stream transition_item
a: transition_item
tr1: list transition_item
te1, te2: transition_item
IHtr1: tr : Stream transition_item, tr = stream_app (tr1 ++ [te1; te2]) tr2 → is : state X, infinite_valid_trace_from is tr → input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)

tr : Stream transition_item, tr = stream_app ((a :: tr1) ++ [te1; te2]) tr2 → is : state X, infinite_valid_trace_from is tr → input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
message: Type
X: VLSM message
tr2: Stream transition_item
a: transition_item
tr1: list transition_item
te1, te2: transition_item
IHtr1: is : state X, infinite_valid_trace_from is (stream_app (tr1 ++ [te1; te2]) tr2) → input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)

tr : Stream transition_item, tr = stream_app ((a :: tr1) ++ [te1; te2]) tr2 → is : state X, infinite_valid_trace_from is tr → input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
message: Type
X: VLSM message
tr2: Stream transition_item
tr1: list transition_item
te1, te2: transition_item
IHtr1: is : state X, infinite_valid_trace_from is (stream_app (tr1 ++ [te1; te2]) tr2) → input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
is, s: state X
iom, oom: option message
l0: label X
Htr: infinite_valid_trace_from is (stream_app (({| l := l0; input := iom; destination := s; output := oom |} :: tr1) ++ [te1; te2]) tr2)
Htl: infinite_valid_trace_from s (stream_app (tr1 ++ [te1; te2]) tr2)
Ht: input_valid_transition l0 (is, iom) (s, oom)

input_valid_transition (l te2) (destination te1, input te2) (destination te2, output te2)
by apply (IHtr1 s Htl). Qed.
message: Type
X: VLSM message
s: state X
ls: list transition_item
ls': Stream transition_item
s':= finite_trace_last s ls: state X

finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
message: Type
X: VLSM message
s: state X
ls: list transition_item
ls': Stream transition_item
s':= finite_trace_last s ls: state X

finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
message: Type
X: VLSM message
s: state X
ls: list transition_item
ls': Stream transition_item
s':= finite_trace_last s ls: state X

finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
message: Type
X: VLSM message
s: state X
ls: list transition_item
s':= finite_trace_last s ls: state X

ls' : Stream transition_item, finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
message: Type
X: VLSM message
ls: list transition_item

(s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
message: Type
X: VLSM message
s: state X
s':= finite_trace_last s []: state X
ls': Stream transition_item

finite_valid_trace_from s [] ∧ infinite_valid_trace_from s' ls' → infinite_valid_trace_from s (stream_app [] ls')
message: Type
X: VLSM message
s: state X
s':= finite_trace_last s []: state X
ls': Stream transition_item
infinite_valid_trace_from s (stream_app [] ls') → finite_valid_trace_from s [] ∧ infinite_valid_trace_from s' ls'
message: Type
X: VLSM message
a: transition_item
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s (a :: ls): state X
ls': Stream transition_item
finite_valid_trace_from s (a :: ls) ∧ infinite_valid_trace_from s' ls' → infinite_valid_trace_from s (stream_app (a :: ls) ls')
message: Type
X: VLSM message
a: transition_item
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s (a :: ls): state X
ls': Stream transition_item
infinite_valid_trace_from s (stream_app (a :: ls) ls') → finite_valid_trace_from s (a :: ls) ∧ infinite_valid_trace_from s' ls'
message: Type
X: VLSM message
s: state X
s':= finite_trace_last s []: state X
ls': Stream transition_item

finite_valid_trace_from s [] ∧ infinite_valid_trace_from s' ls' → infinite_valid_trace_from s (stream_app [] ls')
by destruct 1.
message: Type
X: VLSM message
s: state X
s':= finite_trace_last s []: state X
ls': Stream transition_item

infinite_valid_trace_from s (stream_app [] ls') → finite_valid_trace_from s [] ∧ infinite_valid_trace_from s' ls'
message: Type
X: VLSM message
s: state X
s':= finite_trace_last s []: state X
ls': Stream transition_item
Hls': infinite_valid_trace_from s ls'

finite_valid_trace_from s []
message: Type
X: VLSM message
s: state X
s':= finite_trace_last s []: state X
ls': Stream transition_item
Hls': infinite_valid_trace_from s ls'
s1: state X
tl: Stream transition_item
s'0: state X
iom, oom: option message
l0: label X
Htl: infinite_valid_trace_from s1 tl
Ht: input_valid_transition l0 (s, iom) (s1, oom)
H: s'0 = s
H0: Cons {| l := l0; input := iom; destination := s1; output := oom |} tl = ls'

valid_state_prop s
by apply (input_valid_transition_origin Ht).
message: Type
X: VLSM message
a: transition_item
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s (a :: ls): state X
ls': Stream transition_item

finite_valid_trace_from s (a :: ls) ∧ infinite_valid_trace_from s' ls' → infinite_valid_trace_from s (stream_app (a :: ls) ls')
message: Type
X: VLSM message
a: transition_item
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s (a :: ls): state X
ls': Stream transition_item

finite_valid_trace_from s (a :: ls) ∧ infinite_valid_trace_from s' ls' → infinite_valid_trace_from s (Cons a (stream_app ls ls'))
message: Type
X: VLSM message
a: transition_item
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s (a :: ls): state X
ls': Stream transition_item
Htr: finite_valid_trace_from s (a :: ls)
Htr': infinite_valid_trace_from s' ls'

infinite_valid_trace_from s (Cons a (stream_app ls ls'))
message: Type
X: VLSM message
l0: label X
input0: option message
destination0: state X
output0: option message
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls): state X
ls': Stream transition_item
Htr: finite_valid_trace_from s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls)
Htr': infinite_valid_trace_from s' ls'

infinite_valid_trace_from s (Cons {| l := l0; input := input0; destination := destination0; output := output0 |} (stream_app ls ls'))
message: Type
X: VLSM message
l0: label X
input0: option message
destination0: state X
output0: option message
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls): state X
ls': Stream transition_item
Htr: finite_valid_trace_from s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls)
Htr': infinite_valid_trace_from s' ls'

infinite_valid_trace_from destination0 (stream_app ls ls')
message: Type
X: VLSM message
l0: label X
input0: option message
destination0: state X
output0: option message
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls): state X
ls': Stream transition_item
Htr: finite_valid_trace_from s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls)
Htr': infinite_valid_trace_from s' ls'
input_valid_transition l0 ( s, input0) (destination0, output0)
message: Type
X: VLSM message
l0: label X
input0: option message
destination0: state X
output0: option message
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls): state X
ls': Stream transition_item
Htr: finite_valid_trace_from s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls)
Htr': infinite_valid_trace_from s' ls'

infinite_valid_trace_from destination0 (stream_app ls ls')
message: Type
X: VLSM message
l0: label X
input0: option message
destination0: state X
output0: option message
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls): state X
ls': Stream transition_item
Htr: finite_valid_trace_from s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls)
Htr': infinite_valid_trace_from s' ls'

finite_valid_trace_from destination0 ls ∧ infinite_valid_trace_from (finite_trace_last destination0 ls) ls'
message: Type
X: VLSM message
l0: label X
input0: option message
destination0: state X
output0: option message
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls): state X
ls': Stream transition_item
Htr: finite_valid_trace_from s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls)
Htr': infinite_valid_trace_from s' ls'
s1: state X
tl: list transition_item
s'0: state X
iom, oom: option message
l1: label X
Htl: finite_valid_trace_from destination0 ls
Ht: input_valid_transition l0 ( s, input0) (destination0, output0)
H: s'0 = s
H1: l1 = l0
H2: iom = input0
H3: s1 = destination0
H4: oom = output0
H5: tl = ls

finite_valid_trace_from destination0 ls ∧ infinite_valid_trace_from (finite_trace_last destination0 ls) ls'
message: Type
X: VLSM message
l0: label X
input0: option message
destination0: state X
output0: option message
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls): state X
ls': Stream transition_item
Htr: finite_valid_trace_from s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls)
Htr': infinite_valid_trace_from s' ls'
s1: state X
tl: list transition_item
s'0: state X
iom, oom: option message
l1: label X
Htl: finite_valid_trace_from destination0 ls
Ht: input_valid_transition l0 ( s, input0) (destination0, output0)
H: s'0 = s
H1: l1 = l0
H2: iom = input0
H3: s1 = destination0
H4: oom = output0
H5: tl = ls

infinite_valid_trace_from (finite_trace_last destination0 ls) ls'
message: Type
X: VLSM message
l0: label X
input0: option message
destination0: state X
output0: option message
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls): state X
ls': Stream transition_item
Htr: finite_valid_trace_from s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls)
Htr': infinite_valid_trace_from (finite_trace_last s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls)) ls'
s1: state X
tl: list transition_item
s'0: state X
iom, oom: option message
l1: label X
Htl: finite_valid_trace_from destination0 ls
Ht: input_valid_transition l0 ( s, input0) (destination0, output0)
H: s'0 = s
H1: l1 = l0
H2: iom = input0
H3: s1 = destination0
H4: oom = output0
H5: tl = ls

infinite_valid_trace_from (finite_trace_last destination0 ls) ls'
by rewrite finite_trace_last_cons in Htr'.
message: Type
X: VLSM message
l0: label X
input0: option message
destination0: state X
output0: option message
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls): state X
ls': Stream transition_item
Htr: finite_valid_trace_from s ({| l := l0; input := input0; destination := destination0; output := output0 |} :: ls)
Htr': infinite_valid_trace_from s' ls'

input_valid_transition l0 (s, input0) (destination0, output0)
by inversion Htr; apply Ht.
message: Type
X: VLSM message
a: transition_item
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s: state X
s':= finite_trace_last s (a :: ls): state X
ls': Stream transition_item

infinite_valid_trace_from s (stream_app (a :: ls) ls') → finite_valid_trace_from s (a :: ls) ∧ infinite_valid_trace_from s' ls'
message: Type
X: VLSM message
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s, s1: state X
iom, oom: option message
l0: label X
s':= finite_trace_last s ({| l := l0; input := iom; destination := s1; output := oom |} :: ls): state X
ls': Stream transition_item
H: infinite_valid_trace_from s (stream_app ({| l := l0; input := iom; destination := s1; output := oom |} :: ls) ls')
Htl: infinite_valid_trace_from s1 (stream_app ls ls')
Ht: input_valid_transition l0 (s, iom) (s1, oom)

finite_valid_trace_from s ({| l := l0; input := iom; destination := s1; output := oom |} :: ls) ∧ infinite_valid_trace_from s' ls'
message: Type
X: VLSM message
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s, s1: state X
iom, oom: option message
l0: label X
s':= finite_trace_last s ({| l := l0; input := iom; destination := s1; output := oom |} :: ls): state X
ls': Stream transition_item
H: infinite_valid_trace_from s (stream_app ({| l := l0; input := iom; destination := s1; output := oom |} :: ls) ls')
H0: finite_valid_trace_from s1 ls
H1: infinite_valid_trace_from (finite_trace_last s1 ls) ls'
Ht: input_valid_transition l0 (s, iom) (s1, oom)

finite_valid_trace_from s ({| l := l0; input := iom; destination := s1; output := oom |} :: ls)
message: Type
X: VLSM message
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s, s1: state X
iom, oom: option message
l0: label X
s':= finite_trace_last s ({| l := l0; input := iom; destination := s1; output := oom |} :: ls): state X
ls': Stream transition_item
H: infinite_valid_trace_from s (stream_app ({| l := l0; input := iom; destination := s1; output := oom |} :: ls) ls')
H0: finite_valid_trace_from s1 ls
H1: infinite_valid_trace_from (finite_trace_last s1 ls) ls'
Ht: input_valid_transition l0 (s, iom) (s1, oom)
infinite_valid_trace_from s' ls'
message: Type
X: VLSM message
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s, s1: state X
iom, oom: option message
l0: label X
s':= finite_trace_last s ({| l := l0; input := iom; destination := s1; output := oom |} :: ls): state X
ls': Stream transition_item
H: infinite_valid_trace_from s (stream_app ({| l := l0; input := iom; destination := s1; output := oom |} :: ls) ls')
H0: finite_valid_trace_from s1 ls
H1: infinite_valid_trace_from (finite_trace_last s1 ls) ls'
Ht: input_valid_transition l0 (s, iom) (s1, oom)

finite_valid_trace_from s ({| l := l0; input := iom; destination := s1; output := oom |} :: ls)
by constructor.
message: Type
X: VLSM message
ls: list transition_item
IHls: (s : state X) (s' := finite_trace_last s ls) (ls' : Stream transition_item), finite_valid_trace_from s ls ∧ infinite_valid_trace_from s' ls' ↔ infinite_valid_trace_from s (stream_app ls ls')
s, s1: state X
iom, oom: option message
l0: label X
s':= finite_trace_last s ({| l := l0; input := iom; destination := s1; output := oom |} :: ls): state X
ls': Stream transition_item
H: infinite_valid_trace_from s (stream_app ({| l := l0; input := iom; destination := s1; output := oom |} :: ls) ls')
H0: finite_valid_trace_from s1 ls
H1: infinite_valid_trace_from (finite_trace_last s1 ls) ls'
Ht: input_valid_transition l0 (s, iom) (s1, oom)

infinite_valid_trace_from s' ls'
by unfold s'; rewrite finite_trace_last_cons. Qed.
message: Type
X: VLSM message
s: state X
ls: Stream transition_item
Htr: infinite_valid_trace_from s ls
n: nat

finite_valid_trace_from s (stream_prefix ls n)
message: Type
X: VLSM message
s: state X
ls: Stream transition_item
Htr: infinite_valid_trace_from s ls
n: nat

finite_valid_trace_from s (stream_prefix ls n)
message: Type
X: VLSM message
s: state X
ls: Stream transition_item
Htr: infinite_valid_trace_from s ls
n: nat
Hdecompose: stream_app (stream_prefix ls n) (stream_suffix ls n) = ls

finite_valid_trace_from s (stream_prefix ls n)
message: Type
X: VLSM message
s: state X
ls: Stream transition_item
n: nat
Htr: infinite_valid_trace_from s (stream_app (stream_prefix ls n) (stream_suffix ls n))
Hdecompose: stream_app (stream_prefix ls n) (stream_suffix ls n) = ls

finite_valid_trace_from s (stream_prefix ls n)
by apply infinite_valid_trace_from_app_iff in Htr as [Hpr _]. Qed.
message: Type
X: VLSM message
s: state X
ls: Stream transition_item
Hpref: n : nat, finite_valid_trace_from s (stream_prefix ls n)

infinite_valid_trace_from s ls
message: Type
X: VLSM message
s: state X
ls: Stream transition_item
Hpref: n : nat, finite_valid_trace_from s (stream_prefix ls n)

infinite_valid_trace_from s ls
message: Type
X: VLSM message

(s : state X) (ls : Stream transition_item), ( n : nat, finite_valid_trace_from s (stream_prefix ls n)) → infinite_valid_trace_from s ls
message: Type
X: VLSM message
Hls: (s : state X) (ls : Stream transition_item), ( n : nat, finite_valid_trace_from s (stream_prefix ls n)) → infinite_valid_trace_from s ls

(s : state X) (ls : Stream transition_item), ( n : nat, finite_valid_trace_from s (stream_prefix ls n)) → infinite_valid_trace_from s ls
message: Type
X: VLSM message
Hls: (s : state X) (ls : Stream transition_item), ( n : nat, finite_valid_trace_from s (stream_prefix ls n)) → infinite_valid_trace_from s ls
s: state X
a: transition_item
ls: Stream transition_item
Hpref: n : nat, finite_valid_trace_from s (stream_prefix (Cons a ls) n)

infinite_valid_trace_from s (Cons a ls)
message: Type
X: VLSM message
Hls: (s : state X) (ls : Stream transition_item), ( n : nat, finite_valid_trace_from s (stream_prefix ls n)) → infinite_valid_trace_from s ls
s: state X
a: transition_item
ls: Stream transition_item
Hpref: n : nat, finite_valid_trace_from s (stream_prefix (Cons a ls) n)
Hpref0: finite_valid_trace_from s (stream_prefix (Cons a ls) 1)

infinite_valid_trace_from s (Cons a ls)
message: Type
X: VLSM message
Hls: (s : state X) (ls : Stream transition_item), ( n : nat, finite_valid_trace_from s (stream_prefix ls n)) → infinite_valid_trace_from s ls
s: state X
ls: Stream transition_item
s1: state X
iom, oom: option message
l0: label X
Hpref0: finite_valid_trace_from s (stream_prefix (Cons {| l := l0; input := iom; destination := s1; output := oom |} ls) 1)
Hpref: n : nat, finite_valid_trace_from s (stream_prefix (Cons {| l := l0; input := iom; destination := s1; output := oom |} ls) n)
Htl: finite_valid_trace_from s1 []
Ht: input_valid_transition l0 (s, iom) (s1, oom)

infinite_valid_trace_from s (Cons {| l := l0; input := iom; destination := s1; output := oom |} ls)
message: Type
X: VLSM message
Hls: (s : state X) (ls : Stream transition_item), ( n : nat, finite_valid_trace_from s (stream_prefix ls n)) → infinite_valid_trace_from s ls
s: state X
ls: Stream transition_item
s1: state X
iom, oom: option message
l0: label X
Hpref0: finite_valid_trace_from s (stream_prefix (Cons {| l := l0; input := iom; destination := s1; output := oom |} ls) 1)
Hpref: n : nat, finite_valid_trace_from s (stream_prefix (Cons {| l := l0; input := iom; destination := s1; output := oom |} ls) n)
Htl: finite_valid_trace_from s1 []
Ht: input_valid_transition l0 (s, iom) (s1, oom)

infinite_valid_trace_from s1 ls
message: Type
X: VLSM message
Hls: (s : state X) (ls : Stream transition_item), ( n : nat, finite_valid_trace_from s (stream_prefix ls n)) → infinite_valid_trace_from s ls
s: state X
ls: Stream transition_item
s1: state X
iom, oom: option message
l0: label X
Hpref0: finite_valid_trace_from s (stream_prefix (Cons {| l := l0; input := iom; destination := s1; output := oom |} ls) 1)
Hpref: n : nat, finite_valid_trace_from s (stream_prefix (Cons {| l := l0; input := iom; destination := s1; output := oom |} ls) n)
Htl: finite_valid_trace_from s1 []
Ht: input_valid_transition l0 (s, iom) (s1, oom)

n : nat, finite_valid_trace_from s1 (stream_prefix ls n)
message: Type
X: VLSM message
Hls: (s : state X) (ls : Stream transition_item), ( n : nat, finite_valid_trace_from s (stream_prefix ls n)) → infinite_valid_trace_from s ls
s: state X
ls: Stream transition_item
s1: state X
iom, oom: option message
l0: label X
Hpref0: finite_valid_trace_from s (stream_prefix (Cons {| l := l0; input := iom; destination := s1; output := oom |} ls) 1)
Hpref: n : nat, finite_valid_trace_from s (stream_prefix (Cons {| l := l0; input := iom; destination := s1; output := oom |} ls) n)
Htl: finite_valid_trace_from s1 []
Ht: input_valid_transition l0 (s, iom) (s1, oom)
n: nat

finite_valid_trace_from s1 (stream_prefix ls n)
message: Type
X: VLSM message
Hls: (s : state X) (ls : Stream transition_item), ( n : nat, finite_valid_trace_from s (stream_prefix ls n)) → infinite_valid_trace_from s ls
s: state X
ls: Stream transition_item
s1: state X
iom, oom: option message
l0: label X
Hpref0: finite_valid_trace_from s (stream_prefix (Cons {| l := l0; input := iom; destination := s1; output := oom |} ls) 1)
n: nat
Hpref: finite_valid_trace_from s (stream_prefix (Cons {| l := l0; input := iom; destination := s1; output := oom |} ls) (S n))
Htl: finite_valid_trace_from s1 []
Ht: input_valid_transition l0 (s, iom) (s1, oom)

finite_valid_trace_from s1 (stream_prefix ls n)
by inversion Hpref; subst. Qed.
message: Type
X: VLSM message

(s : state X) (tl1 tl2 : Stream transition_item), EqSt tl1 tl2 → infinite_valid_trace_from s tl1 → infinite_valid_trace_from s tl2
message: Type
X: VLSM message

(s : state X) (tl1 tl2 : Stream transition_item), EqSt tl1 tl2 → infinite_valid_trace_from s tl1 → infinite_valid_trace_from s tl2
message: Type
X: VLSM message
s: state X
tl1, tl2: Stream transition_item
Heq: EqSt tl1 tl2
Htl1: infinite_valid_trace_from s tl1

infinite_valid_trace_from s tl2
message: Type
X: VLSM message
s: state X
tl1, tl2: Stream transition_item
Heq: EqSt tl1 tl2
Htl1: infinite_valid_trace_from s tl1

n : nat, finite_valid_trace_from s (stream_prefix tl2 n)
message: Type
X: VLSM message
s: state X
tl1, tl2: Stream transition_item
Heq: EqSt tl1 tl2
Htl1: infinite_valid_trace_from s tl1
n: nat

finite_valid_trace_from s (stream_prefix tl2 n)
message: Type
X: VLSM message
s: state X
tl1, tl2: Stream transition_item
Heq: EqSt tl1 tl2
Htl1: infinite_valid_trace_from s tl1
n: nat

finite_valid_trace_from s (stream_prefix tl1 n)
by apply infinite_valid_trace_from_prefix. Qed.
message: Type
X: VLSM message
s: state X
ls: Stream transition_item
Htr: infinite_valid_trace_from s ls
n1, n2: nat
Hle: n1 ≤ n2
n1th:= Str_nth n1 (Cons s (map destination ls)): state X

finite_valid_trace_from n1th (stream_segment ls n1 n2)
message: Type
X: VLSM message
s: state X
ls: Stream transition_item
Htr: infinite_valid_trace_from s ls
n1, n2: nat
Hle: n1 ≤ n2
n1th:= Str_nth n1 (Cons s (map destination ls)): state X

finite_valid_trace_from n1th (stream_segment ls n1 n2)
message: Type
X: VLSM message
s: state X
ls: Stream transition_item
Htr: infinite_valid_trace_from s ls
n1, n2: nat
Hle: n1 ≤ n2
n1th:= Str_nth n1 (Cons s (map destination ls)): state X

finite_valid_trace_from s (stream_prefix ls n2)
message: Type
X: VLSM message
s: state X
ls: Stream transition_item
Htr: infinite_valid_trace_from s ls
n1, n2: nat
Hle: n1 ≤ n2
n1th:= Str_nth n1 (Cons s (map destination ls)): state X
finite_trace_nth s (stream_prefix ls n2) n1 = Some n1th
message: Type
X: VLSM message
s: state X
ls: Stream transition_item
Htr: infinite_valid_trace_from s ls
n1, n2: nat
Hle: n1 ≤ n2
n1th:= Str_nth n1 (Cons s (map destination ls)): state X

finite_valid_trace_from s (stream_prefix ls n2)
by apply infinite_valid_trace_from_prefix.
message: Type
X: VLSM message
s: state X
ls: Stream transition_item
Htr: infinite_valid_trace_from s ls
n1, n2: nat
Hle: n1 ≤ n2
n1th:= Str_nth n1 (Cons s (map destination ls)): state X

finite_trace_nth s (stream_prefix ls n2) n1 = Some n1th
message: Type
X: VLSM message
s: state X
ls: Stream transition_item
Htr: infinite_valid_trace_from s ls
n1, n2: nat
Hle: S n1 ≤ n2
n1th:= Str_nth (S n1) (Cons s (map destination ls)): state X

finite_trace_nth s (stream_prefix ls n2) (S n1) = Some n1th
message: Type
X: VLSM message
s: state X
ls: Stream transition_item
Htr: infinite_valid_trace_from s ls
n1, n2: nat
Hle: S n1 ≤ n2

nth_error (List.map destination (stream_prefix ls n2)) n1 = Some (Str_nth (S n1) (Cons s (map destination ls)))
by rewrite stream_prefix_map, stream_prefix_nth. Qed.

Valid traces

Finally, we define Trace as a sum-type of its finite/infinite variants. It inherits some previously introduced definitions, culminating with the valid_trace.
Definition valid_trace_from_prop (tr : Trace) : Prop :=
  match tr with
  | Finite s ls => finite_valid_trace_from s ls
  | Infinite s sm => infinite_valid_trace_from s sm
  end.

Definition valid_trace_prop (tr : Trace) : Prop :=
  match tr with
  | Finite s ls => finite_valid_trace s ls
  | Infinite s sm => infinite_valid_trace s sm
  end.

Definition valid_trace : Type :=
  {tr : Trace | valid_trace_prop tr}.

message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr

valid_trace_from_prop tr
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr

valid_trace_from_prop tr
by destruct tr, Htr. Qed.
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr

initial_state_prop (trace_first tr)
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr

initial_state_prop (trace_first tr)
by destruct tr, Htr. Qed.
message: Type
X: VLSM message

tr : Trace, valid_trace_prop tr ↔ valid_trace_from_prop tr ∧ initial_state_prop (trace_first tr)
message: Type
X: VLSM message

tr : Trace, valid_trace_prop tr ↔ valid_trace_from_prop tr ∧ initial_state_prop (trace_first tr)
message: Type
X: VLSM message
tr: Trace

valid_trace_prop tr → valid_trace_from_prop tr ∧ initial_state_prop (trace_first tr)
message: Type
X: VLSM message
tr: Trace
valid_trace_from_prop tr ∧ initial_state_prop (trace_first tr) → valid_trace_prop tr
message: Type
X: VLSM message
tr: Trace

valid_trace_prop tr → valid_trace_from_prop tr ∧ initial_state_prop (trace_first tr)
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr

valid_trace_from_prop tr
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
initial_state_prop (trace_first tr)
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr

valid_trace_from_prop tr
by apply valid_trace_from.
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr

initial_state_prop (trace_first tr)
by apply valid_trace_initial.
message: Type
X: VLSM message
tr: Trace

valid_trace_from_prop tr ∧ initial_state_prop (trace_first tr) → valid_trace_prop tr
by destruct tr; cbn; intros [Htr Hinit]. Qed.
Having defined valid_traces, we now connect them to valid states and messages, in the following sense: for each state-message pair (s, m) that has the valid_state_message_property, there exists a valid_trace which ends in s by outputting m
message: Type
X: VLSM message
s: state X
om: option message
Hp: valid_state_message_prop s om

initial_state_prop s ∧ option_initial_message_prop X om ∨ ( (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr ∧ finite_trace_last_output tr = om)
message: Type
X: VLSM message
s: state X
om: option message
Hp: valid_state_message_prop s om

initial_state_prop s ∧ option_initial_message_prop X om ∨ ( (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr ∧ finite_trace_last_output tr = om)
message: Type
X: VLSM message
s: state X
om: option message
is: state X
tr: list transition_item
Htr: finite_valid_trace_init_to_emit is s om tr

initial_state_prop s ∧ option_initial_message_prop X om ∨ ( (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr ∧ finite_trace_last_output tr = om)
message: Type
X: VLSM message
s: state X
om: option message
is: state X
tr: list transition_item
Htr: finite_valid_trace_init_to_emit is s om tr
Houtput: empty_initial_message_or_final_output tr om

initial_state_prop s ∧ option_initial_message_prop X om ∨ ( (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr ∧ finite_trace_last_output tr = om)
message: Type
X: VLSM message
s: state X
om: option message
is: state X
tr: list transition_item
Htr: finite_valid_trace_init_to_emit is s om tr
Houtput: match has_last_or_null tr with | inleft (existT x (x0 ↾ _)) => output x0 = om | inright _ => option_initial_message_prop X om end

initial_state_prop s ∧ option_initial_message_prop X om ∨ ( (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr ∧ finite_trace_last_output tr = om)
message: Type
X: VLSM message
s: state X
om: option message
is: state X
tr: list transition_item
Htr: finite_valid_trace_init_to_emit is s om []
Heqtr: tr = []
Houtput: option_initial_message_prop X om

initial_state_prop s ∧ option_initial_message_prop X om ∨ ( (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr ∧ finite_trace_last_output tr = om)
message: Type
X: VLSM message
s: state X
om: option message
is: state X
tr, tr': list transition_item
item: transition_item
Htr: finite_valid_trace_init_to_emit is s om (tr' ++ [item])
Heqtr: tr = tr' ++ [item]
Houtput: output item = om
initial_state_prop s ∧ option_initial_message_prop X om ∨ ( (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr ∧ finite_trace_last_output tr = om)
message: Type
X: VLSM message
s: state X
om: option message
is: state X
tr: list transition_item
Htr: finite_valid_trace_init_to_emit is s om []
Heqtr: tr = []
Houtput: option_initial_message_prop X om

initial_state_prop s ∧ option_initial_message_prop X om ∨ ( (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr ∧ finite_trace_last_output tr = om)
message: Type
X: VLSM message
s: state X
om: option message
is: state X
tr: list transition_item
Htr: finite_valid_trace_init_to_emit is s om []
Heqtr: tr = []
Houtput: option_initial_message_prop X om

initial_state_prop s
message: Type
X: VLSM message
s: state X
om: option message
is: state X
tr: list transition_item
Htr: finite_valid_trace_init_to_emit is s om []
Heqtr: tr = []
Houtput: option_initial_message_prop X om
is0, s1: state X
_om: option message
tl: list transition_item
iom_is, iom_s: state X
iom: option message
iom_tl: list transition_item
l0: label X
s': state X
oom: option message
Hs: finite_valid_trace_init_to_emit is s1 _om tl
Hiom: finite_valid_trace_init_to_emit iom_is iom_s iom iom_tl
Hv: valid l0 (s1, iom)
Ht: transition l0 (s1, iom) = (s, om)
H: is0 = is
H0: s' = s
H1: oom = om
H3: tl ++ [{| l := l0; input := iom; destination := s; output := om |}] = []

initial_state_prop s
by destruct tl; simpl in *; congruence.
message: Type
X: VLSM message
s: state X
om: option message
is: state X
tr, tr': list transition_item
item: transition_item
Htr: finite_valid_trace_init_to_emit is s om (tr' ++ [item])
Heqtr: tr = tr' ++ [item]
Houtput: output item = om

initial_state_prop s ∧ option_initial_message_prop X om ∨ ( (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr ∧ finite_trace_last_output tr = om)
message: Type
X: VLSM message
s: state X
om: option message
is: state X
tr, tr': list transition_item
item: transition_item
Htr: finite_valid_trace_init_to is s (tr' ++ [item])
Heqtr: tr = tr' ++ [item]
Houtput: output item = om

initial_state_prop s ∧ option_initial_message_prop X om ∨ ( (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr ∧ finite_trace_last_output tr = om)
by right; eexists _, _; rewrite finite_trace_last_output_is_last. Qed.
Giving a trace for valid_state_prop can be stated more simply than valid_state_message_has_trace, because we don't need a disjunction because we are not making claims about output messages.
message: Type
X: VLSM message
s: state X
Hp: valid_state_prop s

(is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr
message: Type
X: VLSM message
s: state X
Hp: valid_state_prop s

(is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr
message: Type
X: VLSM message
s: state X
_om: option message
Hp: valid_state_message_prop s _om

(is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr
message: Type
X: VLSM message
s: state X
_om: option message
Hp: initial_state_prop s ∧ option_initial_message_prop X _om ∨ ( (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr ∧ finite_trace_last_output tr = _om)

(is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr
message: Type
X: VLSM message
s: state X
_om: option message
Hinit: initial_state_prop s

(is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr
message: Type
X: VLSM message
s: state X
_om: option message
Htrace: (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr ∧ finite_trace_last_output tr = _om
(is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr
message: Type
X: VLSM message
s: state X
_om: option message
Hinit: initial_state_prop s

(is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr
message: Type
X: VLSM message
s: state X
_om: option message
Hinit: initial_state_prop s

finite_valid_trace_init_to s s []
message: Type
X: VLSM message
s: state X
_om: option message
Hinit: initial_state_prop s

finite_valid_trace_from_to s s []
message: Type
X: VLSM message
s: state X
_om: option message
Hinit: initial_state_prop s

valid_state_prop s
by apply initial_state_is_valid.
message: Type
X: VLSM message
s: state X
_om: option message
Htrace: (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr ∧ finite_trace_last_output tr = _om

(is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr
by destruct Htrace as [is [tr [Htr _]]]; eauto. Qed.
For any input valid transition there exists a valid trace ending in it.
message: Type
X: VLSM message
l: label X
s1: state X
iom: option message
s2: state X
oom: option message
Ht: input_valid_transition l (s1, iom) (s2, oom)

(s0 : state X) (ts : list transition_item), finite_valid_trace_init_to s0 s2 (ts ++ [{| l := l; input := iom; destination := s2; output := oom |}]) ∧ finite_trace_last s0 ts = s1
message: Type
X: VLSM message
l: label X
s1: state X
iom: option message
s2: state X
oom: option message
Ht: input_valid_transition l (s1, iom) (s2, oom)

(s0 : state X) (ts : list transition_item), finite_valid_trace_init_to s0 s2 (ts ++ [{| l := l; input := iom; destination := s2; output := oom |}]) ∧ finite_trace_last s0 ts = s1
message: Type
X: VLSM message
l: label X
s1: state X
iom: option message
s2: state X
oom: option message
Ht: input_valid_transition l (s1, iom) (s2, oom)
Hs1: valid_state_prop s1

(s0 : state X) (ts : list transition_item), finite_valid_trace_init_to s0 s2 (ts ++ [{| l := l; input := iom; destination := s2; output := oom |}]) ∧ finite_trace_last s0 ts = s1
message: Type
X: VLSM message
l: label X
s1: state X
iom: option message
s2: state X
oom: option message
Ht: input_valid_transition l (s1, iom) (s2, oom)
Hs1: (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s1 tr

(s0 : state X) (ts : list transition_item), finite_valid_trace_init_to s0 s2 (ts ++ [{| l := l; input := iom; destination := s2; output := oom |}]) ∧ finite_trace_last s0 ts = s1
message: Type
X: VLSM message
l: label X
s1: state X
iom: option message
s2: state X
oom: option message
Ht: input_valid_transition l (s1, iom) (s2, oom)
s0: state X
ts: list transition_item
Hts: finite_valid_trace_init_to s0 s1 ts

(s0 : state X) (ts : list transition_item), finite_valid_trace_init_to s0 s2 (ts ++ [{| l := l; input := iom; destination := s2; output := oom |}]) ∧ finite_trace_last s0 ts = s1
message: Type
X: VLSM message
l: label X
s1: state X
iom: option message
s2: state X
oom: option message
Ht: input_valid_transition l (s1, iom) (s2, oom)
s0: state X
ts: list transition_item
Hts: finite_valid_trace_init_to s0 s1 ts

finite_valid_trace_init_to s0 s2 (ts ++ [{| l := l; input := iom; destination := s2; output := oom |}]) ∧ finite_trace_last s0 ts = s1
message: Type
X: VLSM message
l: label X
s1: state X
iom: option message
s2: state X
oom: option message
Ht: input_valid_transition l (s1, iom) (s2, oom)
s0: state X
ts: list transition_item
Hts: finite_valid_trace_from_to s0 s1 ts
Hinit: initial_state_prop s0

finite_valid_trace_init_to s0 s2 (ts ++ [{| l := l; input := iom; destination := s2; output := oom |}]) ∧ finite_trace_last s0 ts = s1
message: Type
X: VLSM message
l: label X
s1: state X
iom: option message
s2: state X
oom: option message
Ht: input_valid_transition l (s1, iom) (s2, oom)
s0: state X
ts: list transition_item
Hts: finite_valid_trace_from_to s0 s1 ts
Hinit: initial_state_prop s0

finite_valid_trace_from_to s0 s2 (ts ++ [{| l := l; input := iom; destination := s2; output := oom |}])
message: Type
X: VLSM message
l: label X
s1: state X
iom: option message
s2: state X
oom: option message
s0: state X
ts: list transition_item
Hts: finite_valid_trace_from_to s0 s1 ts
Hinit: initial_state_prop s0

input_valid_transition l (s1, iom) (s2, oom) → finite_valid_trace_from_to s0 s2 (ts ++ [{| l := l; input := iom; destination := s2; output := oom |}])
by apply extend_right_finite_trace_from_to. Qed.
message: Type
X: VLSM message
m: message

can_emit m → (is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace is (tr ++ [item]) ∧ output item = Some m
message: Type
X: VLSM message
m: message

can_emit m → (is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace is (tr ++ [item]) ∧ output item = Some m
message: Type
X: VLSM message
m: message
s: state X
im: option message
l: label X
s': state X
Hm: input_valid_transition l (s, im) (s', Some m)

(is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace is (tr ++ [item]) ∧ output item = Some m
message: Type
X: VLSM message
m: message
s: state X
im: option message
l: label X
s', is: state X
tr: list transition_item
Htr: finite_valid_trace_init_to is s' (tr ++ [{| l := l; input := im; destination := s'; output := Some m |}])

(is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace is (tr ++ [item]) ∧ output item = Some m
message: Type
X: VLSM message
m: message
s: state X
im: option message
l: label X
s', is: state X
tr: list transition_item
Htr: finite_valid_trace is (tr ++ [{| l := l; input := im; destination := s'; output := Some m |}])

(is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace is (tr ++ [item]) ∧ output item = Some m
by eexists is, tr, _. Qed.
Any trace with the finite_valid_trace_from property can be completed (to the left) to start in an initial state.
message: Type
X: VLSM message
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr

(is : state X) (trs : list transition_item), finite_valid_trace is (trs ++ tr) ∧ finite_trace_last is trs = s
message: Type
X: VLSM message
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr

(is : state X) (trs : list transition_item), finite_valid_trace is (trs ++ tr) ∧ finite_trace_last is trs = s
message: Type
X: VLSM message
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr
Hs: valid_state_prop s

(is : state X) (trs : list transition_item), finite_valid_trace is (trs ++ tr) ∧ finite_trace_last is trs = s
message: Type
X: VLSM message
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr
Hs: (is : state X) (tr : list transition_item), finite_valid_trace_init_to is s tr

(is : state X) (trs : list transition_item), finite_valid_trace is (trs ++ tr) ∧ finite_trace_last is trs = s
message: Type
X: VLSM message
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr
is: state X
trs: list transition_item
Htrs: finite_valid_trace_from_to is s trs
His: initial_state_prop is

(is : state X) (trs : list transition_item), finite_valid_trace is (trs ++ tr) ∧ finite_trace_last is trs = s
message: Type
X: VLSM message
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr
is: state X
trs: list transition_item
Htrs: finite_valid_trace_from_to is s trs
His: initial_state_prop is

finite_valid_trace is (trs ++ tr) ∧ finite_trace_last is trs = s
message: Type
X: VLSM message
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr
is: state X
trs: list transition_item
Htrs: finite_valid_trace_from_to is s trs
His: initial_state_prop is
Hlast: finite_trace_last is trs = s

finite_valid_trace is (trs ++ tr) ∧ finite_trace_last is trs = s
message: Type
X: VLSM message
s: state X
tr: list transition_item
is: state X
trs: list transition_item
Htr: finite_valid_trace_from (finite_trace_last is trs) tr
Htrs: finite_valid_trace_from_to is s trs
His: initial_state_prop is
Hlast: finite_trace_last is trs = s

finite_valid_trace is (trs ++ tr) ∧ finite_trace_last is trs = s
message: Type
X: VLSM message
s: state X
tr: list transition_item
is: state X
trs: list transition_item
Htr: finite_valid_trace_from (finite_trace_last is trs) tr
Htrs: finite_valid_trace_from is trs
His: initial_state_prop is
Hlast: finite_trace_last is trs = s

finite_valid_trace is (trs ++ tr) ∧ finite_trace_last is trs = s
by firstorder using finite_valid_trace_from_app_iff. Qed.
Any trace with the finite_valid_trace_from_to property can be completed (to the left) to start in an initial state.
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr

(is : state X) (trs : list transition_item), finite_valid_trace_init_to is f (trs ++ tr) ∧ finite_trace_last is trs = s
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr

(is : state X) (trs : list transition_item), finite_valid_trace_init_to is f (trs ++ tr) ∧ finite_trace_last is trs = s
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr

valid_state_prop s
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr
Hs: valid_state_prop s
(is : state X) (trs : list transition_item), finite_valid_trace_init_to is f (trs ++ tr) ∧ finite_trace_last is trs = s
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr

valid_state_prop s
by apply finite_valid_trace_from_to_forget_last, finite_valid_trace_first_pstate in Htr.
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr
Hs: valid_state_prop s

(is : state X) (trs : list transition_item), finite_valid_trace_init_to is f (trs ++ tr) ∧ finite_trace_last is trs = s
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr
is: state X
trs: list transition_item
Htrs: finite_valid_trace_from_to is s trs
His: initial_state_prop is

(is : state X) (trs : list transition_item), finite_valid_trace_init_to is f (trs ++ tr) ∧ finite_trace_last is trs = s
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr
is: state X
trs: list transition_item
Htrs: finite_valid_trace_from_to is s trs
His: initial_state_prop is

finite_valid_trace_init_to is f (trs ++ tr) ∧ finite_trace_last is trs = s
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr
is: state X
trs: list transition_item
Htrs: finite_valid_trace_from_to is s trs
His: initial_state_prop is

finite_valid_trace_init_to is f (trs ++ tr)
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr
is: state X
trs: list transition_item
Htrs: finite_valid_trace_from_to is s trs
His: initial_state_prop is
finite_trace_last is trs = s
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr
is: state X
trs: list transition_item
Htrs: finite_valid_trace_from_to is s trs
His: initial_state_prop is

finite_valid_trace_init_to is f (trs ++ tr)
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr
is: state X
trs: list transition_item
Htrs: finite_valid_trace_from_to is s trs
His: initial_state_prop is

finite_valid_trace_from_to is f (trs ++ tr)
by apply finite_valid_trace_from_to_app with s.
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s f tr
is: state X
trs: list transition_item
Htrs: finite_valid_trace_from_to is s trs
His: initial_state_prop is

finite_trace_last is trs = s
by apply finite_valid_trace_from_to_last in Htrs. Qed.
Another benefit of defining traces is that we can succinctly describe indirect transitions between arbitrary pairs of states.
We say that state second is in state first's futures if there exists a finite (possibly empty) valid trace that begins with first and ends in second.
This relation is often used in stating safety and liveness properties.
Definition in_futures (first second : state X) : Prop :=
  exists (tr : list transition_item),
    finite_valid_trace_from_to first second tr.

message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: PreOrder R
Ht: input_valid_transition_preserving R
s1, s2: state X
Hin: in_futures s1 s2

R s1 s2
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: PreOrder R
Ht: input_valid_transition_preserving R
s1, s2: state X
Hin: in_futures s1 s2

R s1 s2
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: PreOrder R
Ht: input_valid_transition_preserving R
s1, s2: state X
Hin: tr : list transition_item, finite_valid_trace_from_to s1 s2 tr

R s1 s2
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: PreOrder R
Ht: input_valid_transition_preserving R
s1, s2: state X
tr: list transition_item
Htr: finite_valid_trace_from_to s1 s2 tr

R s1 s2
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: PreOrder R
Ht: input_valid_transition_preserving R
s, f: state X
tl: list transition_item
Htr: finite_valid_trace_from_to s f tl
s': state X
iom, oom: option message
l0: label X
Ht0: input_valid_transition l0 (s', iom) (s, oom)
IHHtr: R s f

R s' f
by apply Ht in Ht0; transitivity s. Qed. #[export] Instance eq_equiv : @Equivalence (state X) eq := _.
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: StrictOrder R
Ht: input_valid_transition_preserving R
s1, s2: state X
Hin: in_futures s1 s2
Hneq: s1 ≠ s2

R s1 s2
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: StrictOrder R
Ht: input_valid_transition_preserving R
s1, s2: state X
Hin: in_futures s1 s2
Hneq: s1 ≠ s2

R s1 s2
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: PreOrder (relation_disjunction R eq)
Ht: input_valid_transition_preserving R
s1, s2: state X
Hin: in_futures s1 s2
Hneq: s1 ≠ s2

R s1 s2
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: StrictOrder R
Ht: input_valid_transition_preserving R
s1, s2: state X
Hin: in_futures s1 s2
Hneq: s1 ≠ s2
Proper (eq ==> eq ==> iff) R
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: PreOrder (relation_disjunction R eq)
Ht: input_valid_transition_preserving R
s1, s2: state X
Hin: in_futures s1 s2
Hneq: s1 ≠ s2

R s1 s2
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: PreOrder (relation_disjunction R eq)
Ht: input_valid_transition_preserving R
s1, s2: state X
Hin: in_futures s1 s2
Hneq: s1 ≠ s2
Hpreserve: input_valid_transition_preserving (relation_disjunction R eq) → s1 s2 : state X, in_futures s1 s2 → relation_disjunction R eq s1 s2

R s1 s2
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: PreOrder (relation_disjunction R eq)
Ht: input_valid_transition_preserving R
s1, s2: state X
Hin: in_futures s1 s2
Hneq: s1 ≠ s2
Hpreserve: input_valid_transition_preserving (relation_disjunction R eq) → s1 s2 : state X, in_futures s1 s2 → relation_disjunction R eq s1 s2

input_valid_transition_preserving (relation_disjunction R eq)
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: PreOrder (relation_disjunction R eq)
Ht: input_valid_transition_preserving R
s1, s2: state X
Hin: in_futures s1 s2
Hneq: s1 ≠ s2
Hpreserve: s1 s2 : state X, in_futures s1 s2 → relation_disjunction R eq s1 s2
R s1 s2
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: PreOrder (relation_disjunction R eq)
Ht: input_valid_transition_preserving R
s1, s2: state X
Hin: in_futures s1 s2
Hneq: s1 ≠ s2
Hpreserve: input_valid_transition_preserving (relation_disjunction R eq) → s1 s2 : state X, in_futures s1 s2 → relation_disjunction R eq s1 s2

input_valid_transition_preserving (relation_disjunction R eq)
by intro; intros; left; eapply Ht.
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: PreOrder (relation_disjunction R eq)
Ht: input_valid_transition_preserving R
s1, s2: state X
Hin: in_futures s1 s2
Hneq: s1 ≠ s2
Hpreserve: s1 s2 : state X, in_futures s1 s2 → relation_disjunction R eq s1 s2

R s1 s2
by destruct (Hpreserve s1 s2).
message: Type
X: VLSM message
R: state X → state X → Prop
Hpre: StrictOrder R
Ht: input_valid_transition_preserving R
s1, s2: state X
Hin: in_futures s1 s2
Hneq: s1 ≠ s2

Proper (eq ==> eq ==> iff) R
by intros x1 x2 -> y1 y2 ->. Qed.
message: Type
X: VLSM message
first, second: state X
Hfuture: in_futures first second

valid_state_prop first
message: Type
X: VLSM message
first, second: state X
Hfuture: in_futures first second

valid_state_prop first
message: Type
X: VLSM message
first, second: state X
tr: list transition_item
Htr: finite_valid_trace_from_to first second tr

valid_state_prop first
by apply finite_valid_trace_from_to_forget_last, finite_valid_trace_first_pstate in Htr. Qed.
message: Type
X: VLSM message
first: state X
Hps: valid_state_prop first

in_futures first first
message: Type
X: VLSM message
first: state X
Hps: valid_state_prop first

in_futures first first
by exists []; constructor. Qed.
message: Type
X: VLSM message

Transitive in_futures
message: Type
X: VLSM message

Transitive in_futures
message: Type
X: VLSM message
s1, s2, s3: state X
tr12: list transition_item
Htr12: finite_valid_trace_from_to s1 s2 tr12
tr23: list transition_item
Htr23: finite_valid_trace_from_to s2 s3 tr23

in_futures s1 s3
by eexists; eapply finite_valid_trace_from_to_app. Qed.
message: Type
X: VLSM message
l: label X
s: state X
im: option message
s': state X
om: option message
Ht: input_valid_transition l (s, im) (s', om)

in_futures s s'
message: Type
X: VLSM message
l: label X
s: state X
im: option message
s': state X
om: option message
Ht: input_valid_transition l (s, im) (s', om)

in_futures s s'
message: Type
X: VLSM message
l: label X
s: state X
im: option message
s': state X
om: option message
Ht: finite_valid_trace_from s [{| l := l; input := im; destination := s'; output := om |}]

in_futures s s'
by apply finite_valid_trace_from_add_last with (f := s') in Ht; [eexists |]. Qed.
message: Type
X: VLSM message
is, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to is s tr

item : transition_item, item ∈ tr → in_futures (destination item) s
message: Type
X: VLSM message
is, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to is s tr

item : transition_item, item ∈ tr → in_futures (destination item) s
message: Type
X: VLSM message
is, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to is s tr
item: transition_item
Hitem: item ∈ tr

in_futures (destination item) s
message: Type
X: VLSM message
is, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to is s tr
item: transition_item
pre, suf: list transition_item
Heqtr: tr = pre ++ item :: suf

in_futures (destination item) s
message: Type
X: VLSM message
is, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to is s tr
item: transition_item
pre, suf: list transition_item
Heqtr: tr = pre ++ item :: suf

finite_valid_trace_from_to (destination item) s suf
message: Type
X: VLSM message
is, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to is s tr
item: transition_item
pre, suf: list transition_item
Heqtr: tr = pre ++ item :: suf

finite_valid_trace_from_to (finite_trace_last ?s (?tl ++ [item])) s suf
message: Type
X: VLSM message
is, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to is s tr
item: transition_item
pre, suf: list transition_item
Heqtr: tr = pre ++ item :: suf

finite_valid_trace_from_to ?s s ((?tl ++ [item]) ++ suf)
by rewrite <- app_assoc; cbn; rewrite <- Heqtr. Qed.
message: Type
X: VLSM message
is, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to is s tr

item : transition_item, item ∈ tr → in_futures is (destination item)
message: Type
X: VLSM message
is, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to is s tr

item : transition_item, item ∈ tr → in_futures is (destination item)
message: Type
X: VLSM message
is, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to is s tr
item: transition_item
Hitem: item ∈ tr

in_futures is (destination item)
message: Type
X: VLSM message
is, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to is s tr
item: transition_item
pre, suf: list transition_item
Heqtr: tr = pre ++ item :: suf

in_futures is (destination item)
message: Type
X: VLSM message
is, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to is s tr
item: transition_item
pre, suf: list transition_item
Heqtr: tr = pre ++ item :: suf

finite_valid_trace_from_to is (destination item) (pre ++ [item])
message: Type
X: VLSM message
is, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to is s tr
item: transition_item
pre, suf: list transition_item
Heqtr: tr = pre ++ item :: suf

finite_valid_trace_from_to is (finite_trace_last ?s (?tl ++ [item])) (pre ++ [item])
message: Type
X: VLSM message
is, s: state X
tr: list transition_item
Htr: finite_valid_trace_from_to is s tr
item: transition_item
pre, suf: list transition_item
Heqtr: tr = pre ++ item :: suf

finite_valid_trace_from_to is ?f ((pre ++ [item]) ++ ?ls')
by rewrite <- app_assoc; cbn; rewrite <- Heqtr. Qed.
message: Type
X: VLSM message
first, second: state X
Hfutures: in_futures first second

(tr : valid_trace) (n1 n2 : nat), n1 ≤ n2 ∧ trace_nth (`tr) n1 = Some first ∧ trace_nth (`tr) n2 = Some second
message: Type
X: VLSM message
first, second: state X
Hfutures: in_futures first second

(tr : valid_trace) (n1 n2 : nat), n1 ≤ n2 ∧ trace_nth (`tr) n1 = Some first ∧ trace_nth (`tr) n2 = Some second
message: Type
X: VLSM message
first, second: state X
Hfutures: in_futures first second
Hps: valid_state_prop first

(tr : valid_trace) (n1 n2 : nat), n1 ≤ n2 ∧ trace_nth (`tr) n1 = Some first ∧ trace_nth (`tr) n2 = Some second
message: Type
X: VLSM message
first, second: state X
Hfutures: in_futures first second
Hps: (is : state X) (tr : list transition_item), finite_valid_trace_init_to is first tr

(tr : valid_trace) (n1 n2 : nat), n1 ≤ n2 ∧ trace_nth (`tr) n1 = Some first ∧ trace_nth (`tr) n2 = Some second
message: Type
X: VLSM message
first, second: state X
Hfutures: in_futures first second
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_valid_trace_from_to prefix_start first prefix_tr
Hinit: initial_state_prop prefix_start

(tr : valid_trace) (n1 n2 : nat), n1 ≤ n2 ∧ trace_nth (`tr) n1 = Some first ∧ trace_nth (`tr) n2 = Some second
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_valid_trace_from_to first second suffix_tr
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_valid_trace_from_to prefix_start first prefix_tr
Hinit: initial_state_prop prefix_start

(tr : valid_trace) (n1 n2 : nat), n1 ≤ n2 ∧ trace_nth (`tr) n1 = Some first ∧ trace_nth (`tr) n2 = Some second
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_valid_trace_from_to first second suffix_tr
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_valid_trace_from_to prefix_start first prefix_tr
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from_to prefix_start second (prefix_tr ++ suffix_tr)

(tr : valid_trace) (n1 n2 : nat), n1 ≤ n2 ∧ trace_nth (`tr) n1 = Some first ∧ trace_nth (`tr) n2 = Some second
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_valid_trace_from_to first second suffix_tr
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_valid_trace_from_to prefix_start first prefix_tr
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from prefix_start (prefix_tr ++ suffix_tr)

(tr : valid_trace) (n1 n2 : nat), n1 ≤ n2 ∧ trace_nth (`tr) n1 = Some first ∧ trace_nth (`tr) n2 = Some second
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_valid_trace_from_to first second suffix_tr
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_valid_trace_from_to prefix_start first prefix_tr
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from prefix_start (prefix_tr ++ suffix_tr)
Htr: valid_trace_prop (Finite prefix_start (prefix_tr ++ suffix_tr))

(tr : valid_trace) (n1 n2 : nat), n1 ≤ n2 ∧ trace_nth (`tr) n1 = Some first ∧ trace_nth (`tr) n2 = Some second
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_valid_trace_from_to first second suffix_tr
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_valid_trace_from_to prefix_start first prefix_tr
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from prefix_start (prefix_tr ++ suffix_tr)
Htr: valid_trace_prop (Finite prefix_start (prefix_tr ++ suffix_tr))

n1 n2 : nat, n1 ≤ n2 ∧ trace_nth (`(Finite prefix_start (prefix_tr ++ suffix_tr) ↾ Htr)) n1 = Some first ∧ trace_nth (`(Finite prefix_start (prefix_tr ++ suffix_tr) ↾ Htr)) n2 = Some second
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_valid_trace_from_to first second suffix_tr
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_valid_trace_from_to prefix_start first prefix_tr
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from prefix_start (prefix_tr ++ suffix_tr)
Htr: valid_trace_prop (Finite prefix_start (prefix_tr ++ suffix_tr))

n1 n2 : nat, n1 ≤ n2 ∧ finite_trace_nth prefix_start (prefix_tr ++ suffix_tr) n1 = Some first ∧ finite_trace_nth prefix_start (prefix_tr ++ suffix_tr) n2 = Some second
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_valid_trace_from_to first second suffix_tr
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_valid_trace_from_to prefix_start first prefix_tr
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from prefix_start (prefix_tr ++ suffix_tr)
Htr: valid_trace_prop (Finite prefix_start (prefix_tr ++ suffix_tr))

length prefix_tr ≤ length prefix_tr + length suffix_tr ∧ finite_trace_nth prefix_start (prefix_tr ++ suffix_tr) (length prefix_tr) = Some first ∧ finite_trace_nth prefix_start (prefix_tr ++ suffix_tr) (length prefix_tr + length suffix_tr) = Some second
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_valid_trace_from_to first second suffix_tr
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_valid_trace_from_to prefix_start first prefix_tr
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from prefix_start (prefix_tr ++ suffix_tr)
Htr: valid_trace_prop (Finite prefix_start (prefix_tr ++ suffix_tr))

finite_trace_nth prefix_start (prefix_tr ++ suffix_tr) (length prefix_tr) = Some first ∧ finite_trace_nth prefix_start (prefix_tr ++ suffix_tr) (length prefix_tr + length suffix_tr) = Some second
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_valid_trace_from_to first second suffix_tr
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_trace_last prefix_start prefix_tr = first
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from prefix_start (prefix_tr ++ suffix_tr)
Htr: valid_trace_prop (Finite prefix_start (prefix_tr ++ suffix_tr))

finite_trace_nth prefix_start (prefix_tr ++ suffix_tr) (length prefix_tr) = Some first ∧ finite_trace_nth prefix_start (prefix_tr ++ suffix_tr) (length prefix_tr + length suffix_tr) = Some second
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_trace_last first suffix_tr = second
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_trace_last prefix_start prefix_tr = first
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from prefix_start (prefix_tr ++ suffix_tr)
Htr: valid_trace_prop (Finite prefix_start (prefix_tr ++ suffix_tr))

finite_trace_nth prefix_start (prefix_tr ++ suffix_tr) (length prefix_tr) = Some first ∧ finite_trace_nth prefix_start (prefix_tr ++ suffix_tr) (length prefix_tr + length suffix_tr) = Some second
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_trace_last first suffix_tr = second
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_trace_last prefix_start prefix_tr = first
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from prefix_start (prefix_tr ++ suffix_tr)
Htr: valid_trace_prop (Finite prefix_start (prefix_tr ++ suffix_tr))

finite_trace_nth prefix_start (prefix_tr ++ suffix_tr) (length prefix_tr) = Some first
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_trace_last first suffix_tr = second
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_trace_last prefix_start prefix_tr = first
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from prefix_start (prefix_tr ++ suffix_tr)
Htr: valid_trace_prop (Finite prefix_start (prefix_tr ++ suffix_tr))
finite_trace_nth prefix_start (prefix_tr ++ suffix_tr) (length prefix_tr + length suffix_tr) = Some second
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_trace_last first suffix_tr = second
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_trace_last prefix_start prefix_tr = first
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from prefix_start (prefix_tr ++ suffix_tr)
Htr: valid_trace_prop (Finite prefix_start (prefix_tr ++ suffix_tr))

finite_trace_nth prefix_start (prefix_tr ++ suffix_tr) (length prefix_tr) = Some first
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_trace_last first suffix_tr = second
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_trace_last prefix_start prefix_tr = first
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from prefix_start (prefix_tr ++ suffix_tr)
Htr: valid_trace_prop (Finite prefix_start (prefix_tr ++ suffix_tr))

finite_trace_nth prefix_start prefix_tr (length prefix_tr) = Some first
by rewrite finite_trace_nth_last; congruence.
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_trace_last first suffix_tr = second
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_trace_last prefix_start prefix_tr = first
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from prefix_start (prefix_tr ++ suffix_tr)
Htr: valid_trace_prop (Finite prefix_start (prefix_tr ++ suffix_tr))

finite_trace_nth prefix_start (prefix_tr ++ suffix_tr) (length prefix_tr + length suffix_tr) = Some second
message: Type
X: VLSM message
first, second: state X
suffix_tr: list transition_item
Hsuffix_tr: finite_trace_last first suffix_tr = second
prefix_start: state X
prefix_tr: list transition_item
Hprefix_tr: finite_trace_last prefix_start prefix_tr = first
Hinit: initial_state_prop prefix_start
Happ: finite_valid_trace_from prefix_start (prefix_tr ++ suffix_tr)
Htr: valid_trace_prop (Finite prefix_start (prefix_tr ++ suffix_tr))

finite_trace_nth (finite_trace_last prefix_start prefix_tr) suffix_tr (length prefix_tr + length suffix_tr - length prefix_tr) = Some second
by rewrite Nat.add_comm, Nat.add_sub, finite_trace_nth_last; congruence. Qed. Definition trace_segment (tr : Trace) (n1 n2 : nat) : list (transition_item X) := match tr with | Finite s l => list_segment l n1 n2 | Infinite s l => stream_segment l n1 n2 end.
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n1, n2: nat
Hle: n1 ≤ n2
first: state X
Hfirst: trace_nth tr n1 = Some first

finite_valid_trace_from first (trace_segment tr n1 n2)
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n1, n2: nat
Hle: n1 ≤ n2
first: state X
Hfirst: trace_nth tr n1 = Some first

finite_valid_trace_from first (trace_segment tr n1 n2)
message: Type
X: VLSM message
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr
Hinit: initial_state_prop s
n1, n2: nat
Hle: n1 ≤ n2
first: state X
Hfirst: finite_trace_nth s tr n1 = Some first

finite_valid_trace_from first (list_segment tr n1 n2)
message: Type
X: VLSM message
s: state X
tr: Stream transition_item
Htr: infinite_valid_trace_from s tr
Hinit: initial_state_prop s
n1, n2: nat
Hle: n1 ≤ n2
first: state X
Hfirst: Some (Str_nth n1 (Cons s (map destination tr))) = Some first
finite_valid_trace_from first (stream_segment tr n1 n2)
message: Type
X: VLSM message
s: state X
tr: list transition_item
Htr: finite_valid_trace_from s tr
Hinit: initial_state_prop s
n1, n2: nat
Hle: n1 ≤ n2
first: state X
Hfirst: finite_trace_nth s tr n1 = Some first

finite_valid_trace_from first (list_segment tr n1 n2)
by apply finite_valid_trace_from_segment with s.
message: Type
X: VLSM message
s: state X
tr: Stream transition_item
Htr: infinite_valid_trace_from s tr
Hinit: initial_state_prop s
n1, n2: nat
Hle: n1 ≤ n2
first: state X
Hfirst: Some (Str_nth n1 (Cons s (map destination tr))) = Some first

finite_valid_trace_from first (stream_segment tr n1 n2)
message: Type
X: VLSM message
s: state X
tr: Stream transition_item
Htr: infinite_valid_trace_from s tr
Hinit: initial_state_prop s
n1, n2: nat
Hle: n1 ≤ n2

finite_valid_trace_from (Str_nth n1 (Cons s (map destination tr))) (stream_segment tr n1 n2)
by apply (infinite_valid_trace_from_segment s tr Htr n1 n2 Hle). Qed. Inductive Trace_messages : Type := | Finite_messages : list (option message) -> Trace_messages | Infinite_messages : Stream (option message) -> Trace_messages. Definition protocol_output_messages_trace (tr : valid_trace) : Trace_messages := match proj1_sig tr with | Finite _ ls => Finite_messages (List.map output ls) | Infinite _ st => Infinite_messages (map output st) end. Definition protocol_input_messages_trace (tr : valid_trace) : Trace_messages := match proj1_sig tr with | Finite _ ls => Finite_messages (List.map input ls) | Infinite _ st => Infinite_messages (map input st) end. Definition trace_prefix (tr : Trace) (last : transition_item X) (prefix : list (transition_item X)) : Prop := match tr with | Finite s ls => exists suffix, ls = prefix ++ (last :: suffix) | Infinite s st => exists suffix, st = stream_app prefix (Cons last suffix) end. Definition trace_prefix_fn (tr : Trace) (n : nat) : Trace X := match tr with | Finite s ls => Finite s (take n ls) | Infinite s st => Finite s (stream_prefix st n) end.
message: Type
X: VLSM message
tr: valid_trace
last: transition_item
prefix: list transition_item
Hprefix: trace_prefix (`tr) last prefix

valid_trace_prop (Finite (trace_first (`tr)) (prefix ++ [last]))
message: Type
X: VLSM message
tr: valid_trace
last: transition_item
prefix: list transition_item
Hprefix: trace_prefix (`tr) last prefix

valid_trace_prop (Finite (trace_first (`tr)) (prefix ++ [last]))
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
last: transition_item
prefix: list transition_item
Hprefix: trace_prefix (`(tr ↾ Htr)) last prefix

valid_trace_prop (Finite (trace_first (`(tr ↾ Htr))) (prefix ++ [last]))
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
last: transition_item
prefix: list transition_item
Hprefix: trace_prefix tr last prefix

finite_valid_trace (trace_first tr) (prefix ++ [last])
message: Type
X: VLSM message
last: transition_item
prefix: list transition_item

tr : Trace, valid_trace_prop tr → trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
message: Type
X: VLSM message
prefix: list transition_item

(last : transition_item) (tr : Trace), valid_trace_prop tr → trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
message: Type
X: VLSM message
prefix: list transition_item

(last : transition_item) (tr : Trace), valid_trace_prop tr → trace_prefix tr last [] → finite_valid_trace (trace_first tr) ([] ++ [last])
message: Type
X: VLSM message
prefix: list transition_item
(x : transition_item) (l : list transition_item), ( (last : transition_item) (tr : Trace), valid_trace_prop tr → trace_prefix tr last l → finite_valid_trace (trace_first tr) (l ++ [last])) → (last : transition_item) (tr : Trace), valid_trace_prop tr → trace_prefix tr last (l ++ [x]) → finite_valid_trace (trace_first tr) ((l ++ [x]) ++ [last])
message: Type
X: VLSM message
prefix: list transition_item

(last : transition_item) (tr : Trace), valid_trace_prop tr → trace_prefix tr last [] → finite_valid_trace (trace_first tr) ([] ++ [last])
by intros last tr Htr Hprefix; destruct tr; unfold trace_prefix in Hprefix; simpl in Hprefix ; destruct Hprefix as [suffix Heq]; subst; destruct Htr as [Htr Hinit] ; unfold trace_first; simpl; constructor; try done ; inversion Htr; subst; clear Htr ; apply finite_valid_trace_singleton.
message: Type
X: VLSM message
prefix: list transition_item

(x : transition_item) (l : list transition_item), ( (last : transition_item) (tr : Trace), valid_trace_prop tr → trace_prefix tr last l → finite_valid_trace (trace_first tr) (l ++ [last])) → (last : transition_item) (tr : Trace), valid_trace_prop tr → trace_prefix tr last (l ++ [x]) → finite_valid_trace (trace_first tr) ((l ++ [x]) ++ [last])
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
Hind: (last : transition_item) (tr : Trace), valid_trace_prop tr → trace_prefix tr last p → finite_valid_trace (trace_first tr) (p ++ [last])
last: transition_item
tr: Trace
Htr: valid_trace_prop tr
Hprefix: trace_prefix tr last (p ++ [last_p])

finite_valid_trace (trace_first tr) ((p ++ [last_p]) ++ [last])
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
tr: Trace
Hind: trace_prefix tr last_p p → finite_valid_trace (trace_first tr) (p ++ [last_p])
last: transition_item
Htr: valid_trace_prop tr
Hprefix: trace_prefix tr last (p ++ [last_p])

finite_valid_trace (trace_first tr) ((p ++ [last_p]) ++ [last])
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
last: transition_item
suffix: list transition_item
Htr: finite_valid_trace_from s ((p ++ [last_p]) ++ last :: suffix)
Hinit: initial_state_prop s
Hind: ( suffix0 : list transition_item, (p ++ [last_p]) ++ last :: suffix = p ++ last_p :: suffix0) → finite_valid_trace s (p ++ [last_p])

finite_valid_trace_from s ((p ++ [last_p]) ++ [last])
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
last: transition_item
suffix: Stream transition_item
Htr: infinite_valid_trace_from s (stream_app (p ++ [last_p]) (Cons last suffix))
Hinit: initial_state_prop s
Hind: ( suffix0 : Stream transition_item, stream_app (p ++ [last_p]) (Cons last suffix) = stream_app p (Cons last_p suffix0)) → finite_valid_trace s (p ++ [last_p])
finite_valid_trace_from s ((p ++ [last_p]) ++ [last])
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
last: transition_item
suffix: list transition_item
Htr: finite_valid_trace_from s ((p ++ [last_p]) ++ last :: suffix)
Hinit: initial_state_prop s
Hind: ( suffix0 : list transition_item, (p ++ [last_p]) ++ last :: suffix = p ++ last_p :: suffix0) → finite_valid_trace s (p ++ [last_p])

finite_valid_trace_from s ((p ++ [last_p]) ++ [last])
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message
suffix: list transition_item
Htr: finite_valid_trace_from s ((p ++ [last_p]) ++ {| l := l0; input := input0; destination := destination0; output := output0 |} :: suffix)
Hinit: initial_state_prop s
Hptr: finite_valid_trace_from s (p ++ [last_p])

input_valid_transition l0 (finite_trace_last s (p ++ [last_p]), input0) (destination0, output0)
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message
suffix: list transition_item
Htr: finite_valid_trace_from s (p ++ last_p :: {| l := l0; input := input0; destination := destination0; output := output0 |} :: suffix)
Hinit: initial_state_prop s
Hptr: finite_valid_trace_from s (p ++ [last_p])

input_valid_transition l0 (finite_trace_last s (p ++ [last_p]), input0) (destination0, output0)
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message
suffix: list transition_item
Htr: finite_valid_trace_from s (p ++ last_p :: {| l := l0; input := input0; destination := destination0; output := output0 |} :: suffix)
Hinit: initial_state_prop s
Hptr: finite_valid_trace_from s (p ++ [last_p])

input_valid_transition (l {| l := l0; input := input0; destination := destination0; output := output0 |}) (destination last_p, input {| l := l0; input := input0; destination := destination0; output := output0 |}) (destination {| l := l0; input := input0; destination := destination0; output := output0 |}, output {| l := l0; input := input0; destination := destination0; output := output0 |}) → input_valid_transition l0 (finite_trace_last s (p ++ [last_p]), input0) (destination0, output0)
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message
suffix: list transition_item
Htr: finite_valid_trace_from s (p ++ last_p :: {| l := l0; input := input0; destination := destination0; output := output0 |} :: suffix)
Hinit: initial_state_prop s
Hptr: finite_valid_trace_from s (p ++ [last_p])

input_valid_transition l0 (destination last_p, input0) (destination0, output0) → input_valid_transition l0 (finite_trace_last s (p ++ [last_p]), input0) (destination0, output0)
by rewrite finite_trace_last_is_last.
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
last: transition_item
suffix: Stream transition_item
Htr: infinite_valid_trace_from s (stream_app (p ++ [last_p]) (Cons last suffix))
Hinit: initial_state_prop s
Hind: ( suffix0 : Stream transition_item, stream_app (p ++ [last_p]) (Cons last suffix) = stream_app p (Cons last_p suffix0)) → finite_valid_trace s (p ++ [last_p])

finite_valid_trace_from s ((p ++ [last_p]) ++ [last])
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message
suffix: Stream transition_item
Htr: infinite_valid_trace_from s (stream_app (p ++ [last_p]) (Cons {| l := l0; input := input0; destination := destination0; output := output0 |} suffix))
Hinit: initial_state_prop s
Hptr: finite_valid_trace_from s (p ++ [last_p])

input_valid_transition l0 (finite_trace_last s (p ++ [last_p]), input0) (destination0, output0)
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message
suffix: Stream transition_item
Htr: infinite_valid_trace_from s (stream_app (p ++ [last_p]) (stream_app [{| l := l0; input := input0; destination := destination0; output := output0 |}] suffix))
Hinit: initial_state_prop s
Hptr: finite_valid_trace_from s (p ++ [last_p])

input_valid_transition l0 (finite_trace_last s (p ++ [last_p]), input0) (destination0, output0)
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message
suffix: Stream transition_item
Htr: infinite_valid_trace_from s (stream_app ((p ++ [last_p]) ++ [{| l := l0; input := input0; destination := destination0; output := output0 |}]) suffix)
Hinit: initial_state_prop s
Hptr: finite_valid_trace_from s (p ++ [last_p])

input_valid_transition l0 (finite_trace_last s (p ++ [last_p]), input0) (destination0, output0)
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message
suffix: Stream transition_item
Htr: infinite_valid_trace_from s (stream_app (p ++ [last_p] ++ [{| l := l0; input := input0; destination := destination0; output := output0 |}]) suffix)
Hinit: initial_state_prop s
Hptr: finite_valid_trace_from s (p ++ [last_p])

input_valid_transition l0 (finite_trace_last s (p ++ [last_p]), input0) (destination0, output0)
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message
suffix: Stream transition_item
Htr: infinite_valid_trace_from s (stream_app (p ++ [last_p; {| l := l0; input := input0; destination := destination0; output := output0 |}]) suffix)
Hinit: initial_state_prop s
Hptr: finite_valid_trace_from s (p ++ [last_p])

input_valid_transition l0 (finite_trace_last s (p ++ [last_p]), input0) (destination0, output0)
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message
suffix: Stream transition_item
Htr: infinite_valid_trace_from s (stream_app (p ++ [last_p; {| l := l0; input := input0; destination := destination0; output := output0 |}]) suffix)
Hinit: initial_state_prop s
Hptr: finite_valid_trace_from s (p ++ [last_p])

input_valid_transition (l {| l := l0; input := input0; destination := destination0; output := output0 |}) (destination last_p, input {| l := l0; input := input0; destination := destination0; output := output0 |}) (destination {| l := l0; input := input0; destination := destination0; output := output0 |}, output {| l := l0; input := input0; destination := destination0; output := output0 |}) → input_valid_transition l0 (finite_trace_last s (p ++ [last_p]), input0) (destination0, output0)
message: Type
X: VLSM message
prefix: list transition_item
last_p: transition_item
p: list transition_item
s: state X
l0: label X
input0: option message
destination0: state X
output0: option message
suffix: Stream transition_item
Htr: infinite_valid_trace_from s (stream_app (p ++ [last_p; {| l := l0; input := input0; destination := destination0; output := output0 |}]) suffix)
Hinit: initial_state_prop s
Hptr: finite_valid_trace_from s (p ++ [last_p])

input_valid_transition l0 (destination last_p, input0) (destination0, output0) → input_valid_transition l0 (finite_trace_last s (p ++ [last_p]), input0) (destination0, output0)
by rewrite finite_trace_last_is_last. Qed. Definition build_trace_prefix_valid {tr : valid_trace} {last : transition_item} {prefix : list transition_item} (Hprefix : trace_prefix (proj1_sig tr) last prefix) : valid_trace := exist _ (Finite (trace_first (proj1_sig tr)) (prefix ++ [last])) (trace_prefix_valid tr last prefix Hprefix).
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat

valid_trace_prop (trace_prefix_fn tr n)
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat

valid_trace_prop (trace_prefix_fn tr n)
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])

valid_trace_prop (trace_prefix_fn tr n)
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
pref_tr: Trace
Heqpref_tr: pref_tr = trace_prefix_fn tr n

valid_trace_prop pref_tr
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
l: Stream transition_item
Heqpref_tr: Infinite s l = trace_prefix_fn tr n

valid_trace_prop (Infinite s l)
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
l: list transition_item
Heqpref_tr: Finite s l = trace_prefix_fn tr n
valid_trace_prop (Finite s l)
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
l: Stream transition_item
Heqpref_tr: Infinite s l = trace_prefix_fn tr n

valid_trace_prop (Infinite s l)
by destruct tr as [s' l' | s' l']; inversion Heqpref_tr.
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
l: list transition_item
Heqpref_tr: Finite s l = trace_prefix_fn tr n

valid_trace_prop (Finite s l)
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
Heqpref_tr: Finite s [] = trace_prefix_fn tr n

valid_trace_prop (Finite s [])
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
item: transition_item
l: list transition_item
Heqpref_tr: Finite s (item :: l) = trace_prefix_fn tr n
valid_trace_prop (Finite s (item :: l))
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
Heqpref_tr: Finite s [] = trace_prefix_fn tr n

valid_trace_prop (Finite s [])
by destruct tr as [s' l' | s' l'] ; destruct Htr as [Htr Hinit] ; inversion Heqpref_tr; subst ; (split; [| done]) ; constructor ; apply initial_state_is_valid.
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
item: transition_item
l: list transition_item
Heqpref_tr: Finite s (item :: l) = trace_prefix_fn tr n

valid_trace_prop (Finite s (item :: l))
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
item: transition_item
l: list transition_item
Heqpref_tr: Finite s (item :: l) = trace_prefix_fn tr n
Hnnil: item :: l ≠ []

valid_trace_prop (Finite s (item :: l))
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
item: transition_item
l: list transition_item
Heqpref_tr: Finite s (item :: l) = trace_prefix_fn tr n
Hnnil: item :: l ≠ []
prefix: list transition_item
last: transition_item
Heq: item :: l = prefix ++ [last]

valid_trace_prop (Finite s (item :: l))
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
prefix: list transition_item
last: transition_item
Heqpref_tr: Finite s (prefix ++ [last]) = trace_prefix_fn tr n

valid_trace_prop (Finite s (prefix ++ [last]))
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
prefix: list transition_item
last: transition_item
Heqpref_tr: Finite s (prefix ++ [last]) = trace_prefix_fn tr n

valid_trace_prop (Finite (trace_first (`(tr ↾ Htr))) (prefix ++ [last]))
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
prefix: list transition_item
last: transition_item
Heqpref_tr: Finite s (prefix ++ [last]) = trace_prefix_fn tr n

trace_prefix (`(tr ↾ Htr)) last prefix
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
prefix: list transition_item
last: transition_item
prefix_last: list transition_item
Heqprefix_last: prefix_last = prefix ++ [last]
Heqpref_tr: Finite s prefix_last = trace_prefix_fn tr n

trace_prefix (`(tr ↾ Htr)) last prefix
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix tr last prefix → finite_valid_trace (trace_first tr) (prefix ++ [last])
s: state X
prefix: list transition_item
last: transition_item
prefix_last: list transition_item
Heqpref_tr: Finite s prefix_last = trace_prefix_fn tr n

prefix_last = prefix ++ [last] → trace_prefix (`(tr ↾ Htr)) last prefix
message: Type
X: VLSM message
s': state X
l': list transition_item
Htr: valid_trace_prop (Finite s' l')
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix (Finite s' l') last prefix → finite_valid_trace (trace_first (Finite s' l')) (prefix ++ [last])
prefix: list transition_item
last: transition_item
Heqprefix: take n l' = prefix ++ [last]

suffix : list transition_item, l' = prefix ++ last :: suffix
message: Type
X: VLSM message
s': state X
l': Stream transition_item
Htr: valid_trace_prop (Infinite s' l')
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix (Infinite s' l') last prefix → finite_valid_trace (trace_first (Infinite s' l')) (prefix ++ [last])
prefix: list transition_item
last: transition_item
Heqprefix: stream_prefix l' n = prefix ++ [last]
suffix : Stream transition_item, l' = stream_app prefix (Cons last suffix)
message: Type
X: VLSM message
s': state X
l': list transition_item
Htr: valid_trace_prop (Finite s' l')
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix (Finite s' l') last prefix → finite_valid_trace (trace_first (Finite s' l')) (prefix ++ [last])
prefix: list transition_item
last: transition_item
Heqprefix: take n l' = prefix ++ [last]

suffix : list transition_item, l' = prefix ++ last :: suffix
message: Type
X: VLSM message
s': state X
l': list transition_item
Htr: valid_trace_prop (Finite s' l')
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix (Finite s' l') last prefix → finite_valid_trace (trace_first (Finite s' l')) (prefix ++ [last])
prefix: list transition_item
last: transition_item
Heqprefix: take n l' = prefix ++ [last]
Hl': take n l' ++ drop n l' = l'

suffix : list transition_item, l' = prefix ++ last :: suffix
message: Type
X: VLSM message
s': state X
l': list transition_item
Htr: valid_trace_prop (Finite s' l')
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix (Finite s' l') last prefix → finite_valid_trace (trace_first (Finite s' l')) (prefix ++ [last])
prefix: list transition_item
last: transition_item
Heqprefix: take n l' = prefix ++ [last]
Hl': take n l' ++ drop n l' = l'

suffix : list transition_item, take n l' ++ drop n l' = prefix ++ last :: suffix
message: Type
X: VLSM message
s': state X
l': list transition_item
Htr: valid_trace_prop (Finite s' l')
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix (Finite s' l') last prefix → finite_valid_trace (trace_first (Finite s' l')) (prefix ++ [last])
prefix: list transition_item
last: transition_item
Heqprefix: take n l' = prefix ++ [last]
Hl': take n l' ++ drop n l' = l'

suffix : list transition_item, (prefix ++ [last]) ++ drop n l' = prefix ++ last :: suffix
message: Type
X: VLSM message
s': state X
l': list transition_item
Htr: valid_trace_prop (Finite s' l')
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix (Finite s' l') last prefix → finite_valid_trace (trace_first (Finite s' l')) (prefix ++ [last])
prefix: list transition_item
last: transition_item
Heqprefix: take n l' = prefix ++ [last]
Hl': take n l' ++ drop n l' = l'

(prefix ++ [last]) ++ drop n l' = prefix ++ last :: drop n l'
by rewrite <- app_assoc.
message: Type
X: VLSM message
s': state X
l': Stream transition_item
Htr: valid_trace_prop (Infinite s' l')
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix (Infinite s' l') last prefix → finite_valid_trace (trace_first (Infinite s' l')) (prefix ++ [last])
prefix: list transition_item
last: transition_item
Heqprefix: stream_prefix l' n = prefix ++ [last]

suffix : Stream transition_item, l' = stream_app prefix (Cons last suffix)
message: Type
X: VLSM message
s': state X
l': Stream transition_item
Htr: valid_trace_prop (Infinite s' l')
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix (Infinite s' l') last prefix → finite_valid_trace (trace_first (Infinite s' l')) (prefix ++ [last])
prefix: list transition_item
last: transition_item
Heqprefix: stream_prefix l' n = prefix ++ [last]
Hl': stream_app (stream_prefix l' n) (stream_suffix l' n) = l'

suffix : Stream transition_item, l' = stream_app prefix (Cons last suffix)
message: Type
X: VLSM message
s': state X
l': Stream transition_item
Htr: valid_trace_prop (Infinite s' l')
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix (Infinite s' l') last prefix → finite_valid_trace (trace_first (Infinite s' l')) (prefix ++ [last])
prefix: list transition_item
last: transition_item
Heqprefix: stream_prefix l' n = prefix ++ [last]
Hl': stream_app (stream_prefix l' n) (stream_suffix l' n) = l'

suffix : Stream transition_item, stream_app (stream_prefix l' n) (stream_suffix l' n) = stream_app prefix (Cons last suffix)
message: Type
X: VLSM message
s': state X
l': Stream transition_item
Htr: valid_trace_prop (Infinite s' l')
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix (Infinite s' l') last prefix → finite_valid_trace (trace_first (Infinite s' l')) (prefix ++ [last])
prefix: list transition_item
last: transition_item
Heqprefix: stream_prefix l' n = prefix ++ [last]
Hl': stream_app (stream_prefix l' n) (stream_suffix l' n) = l'

suffix : Stream transition_item, stream_app (prefix ++ [last]) (stream_suffix l' n) = stream_app prefix (Cons last suffix)
message: Type
X: VLSM message
s': state X
l': Stream transition_item
Htr: valid_trace_prop (Infinite s' l')
n: nat
Hpref: (last : transition_item) (prefix : list transition_item), trace_prefix (Infinite s' l') last prefix → finite_valid_trace (trace_first (Infinite s' l')) (prefix ++ [last])
prefix: list transition_item
last: transition_item
Heqprefix: stream_prefix l' n = prefix ++ [last]
Hl': stream_app (stream_prefix l' n) (stream_suffix l' n) = l'

stream_app (prefix ++ [last]) (stream_suffix l' n) = stream_app prefix (Cons last (stream_suffix l' n))
by rewrite <- stream_app_assoc. Qed.
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
s: state X
Hnth: trace_nth tr n = Some s

valid_state_prop s
message: Type
X: VLSM message
tr: Trace
Htr: valid_trace_prop tr
n: nat
s: state X
Hnth: trace_nth tr n = Some s

valid_state_prop s
message: Type
X: VLSM message
s0: state X
l: list transition_item
Htr: finite_valid_trace_from s0 l
Hinit: initial_state_prop s0
n: nat
s: state X
Hnth: trace_nth (Finite s0 l) n = Some s

valid_state_prop s
message: Type
X: VLSM message
s0: state X
l: Stream transition_item
Htr: infinite_valid_trace_from s0 l
Hinit: initial_state_prop s0
n: nat
s: state X
Hnth: trace_nth (Infinite s0 l) n = Some s
valid_state_prop s
message: Type
X: VLSM message
s0: state X
l: list transition_item
Htr: finite_valid_trace_from s0 l
Hinit: initial_state_prop s0
n: nat
s: state X
Hnth: trace_nth (Finite s0 l) n = Some s

valid_state_prop s
message: Type
X: VLSM message
s0: state X
l: list transition_item
Htr: finite_valid_trace_from s0 l
Hinit: initial_state_prop s0
n: nat
s: state X
Hnth: trace_nth (Finite s0 l) n = Some s

finite_valid_trace_from s (drop n l) → valid_state_prop s
message: Type
X: VLSM message
s0: state X
l: list transition_item
Htr: finite_valid_trace_from s0 l
Hinit: initial_state_prop s0
n: nat
s: state X
Hnth: trace_nth (Finite s0 l) n = Some s
Hsuf: finite_valid_trace_from s (drop n l)

valid_state_prop s
by apply finite_valid_trace_first_pstate in Hsuf.
message: Type
X: VLSM message
s0: state X
l: Stream transition_item
Htr: infinite_valid_trace_from s0 l
Hinit: initial_state_prop s0
n: nat
s: state X
Hnth: trace_nth (Infinite s0 l) n = Some s

valid_state_prop s
message: Type
X: VLSM message
s0: state X
l: Stream transition_item
Htr: infinite_valid_trace_from s0 l
Hinit: initial_state_prop s0
n: nat
s: state X
Hnth: trace_nth (Infinite s0 l) n = Some s
Hle: n ≤ n

valid_state_prop s
message: Type
X: VLSM message
s0: state X
l: Stream transition_item
Htr: infinite_valid_trace_from s0 l
Hinit: initial_state_prop s0
n: nat
s: state X
Hnth: trace_nth (Infinite s0 l) n = Some s
Hle: n ≤ n
Hseg: finite_valid_trace_from (Str_nth n (Cons s0 (map destination l))) (stream_segment l n n)

valid_state_prop s
message: Type
X: VLSM message
s0: state X
l: Stream transition_item
Htr: infinite_valid_trace_from s0 l
Hinit: initial_state_prop s0
n: nat
s: state X
Hnth: trace_nth (Infinite s0 l) n = Some s
Hle: n ≤ n
Hseg: finite_valid_trace_from (Str_nth n (Cons s0 (map destination l))) (stream_segment l n n)
H0: Str_nth n (Cons s0 (map destination l)) = s

valid_state_prop (Str_nth n (Cons s0 (map destination l)))
by apply finite_valid_trace_first_pstate in Hseg. Qed.
message: Type
X: VLSM message
first, second: state X
Hfutures: in_futures first second

valid_state_prop second
message: Type
X: VLSM message
first, second: state X
Hfutures: in_futures first second

valid_state_prop second
message: Type
X: VLSM message
first, second: state X
Hfutures: in_futures first second
tr: valid_trace
n1, n2: nat
Hle: n1 ≤ n2
Hn1: trace_nth (`tr) n1 = Some first
Hn2: trace_nth (`tr) n2 = Some second

valid_state_prop second
message: Type
X: VLSM message
first, second: state X
Hfutures: in_futures first second
tr: Trace
Htr: valid_trace_prop tr
n1, n2: nat
Hle: n1 ≤ n2
Hn1: trace_nth (`(tr ↾ Htr)) n1 = Some first
Hn2: trace_nth tr n2 = Some second

valid_state_prop second
by apply valid_trace_nth with tr n2. Qed.
message: Type
X: VLSM message
first, second: state X
tr: valid_trace
n1, n2: nat
Hle: n1 ≤ n2
Hs1: trace_nth (`tr) n1 = Some first
Hs2: trace_nth (`tr) n2 = Some second

in_futures first second
message: Type
X: VLSM message
first, second: state X
tr: valid_trace
n1, n2: nat
Hle: n1 ≤ n2
Hs1: trace_nth (`tr) n1 = Some first
Hs2: trace_nth (`tr) n2 = Some second

in_futures first second
message: Type
X: VLSM message
first, second: state X
tr: Trace
Htr: valid_trace_prop tr
n1, n2: nat
Hle: n1 ≤ n2
Hs1: trace_nth (`(tr ↾ Htr)) n1 = Some first
Hs2: trace_nth (`(tr ↾ Htr)) n2 = Some second

in_futures first second
message: Type
X: VLSM message
first, second: state X
tr: Trace
Htr: valid_trace_prop tr
n1, n2: nat
Hle: n1 ≤ n2
Hs1: trace_nth tr n1 = Some first
Hs2: trace_nth tr n2 = Some second

in_futures first second
message: Type
X: VLSM message
first, second: state X
tr: Trace
Htr: valid_trace_prop tr
n2: nat
Hs1: trace_nth tr n2 = Some first
Hs2: trace_nth tr n2 = Some second

in_futures first second
message: Type
X: VLSM message
first, second: state X
tr: Trace
Htr: valid_trace_prop tr
n1, m: nat
Hs1: trace_nth tr n1 = Some first
Hs2: trace_nth tr (S m) = Some second
H: n1 ≤ m
in_futures first second
message: Type
X: VLSM message
first, second: state X
tr: Trace
Htr: valid_trace_prop tr
n2: nat
Hs1: trace_nth tr n2 = Some first
Hs2: trace_nth tr n2 = Some second

in_futures first second
message: Type
X: VLSM message
first, second: state X
tr: Trace
Htr: valid_trace_prop tr
n2: nat
Hs1: trace_nth tr n2 = Some first
Hs2: Some first = Some second

in_futures first second
message: Type
X: VLSM message
second: state X
tr: Trace
Htr: valid_trace_prop tr
n2: nat
Hs1: trace_nth tr n2 = Some second

in_futures second second
by exists []; constructor; apply valid_trace_nth with tr n2.
message: Type
X: VLSM message
first, second: state X
tr: Trace
Htr: valid_trace_prop tr
n1, m: nat
Hs1: trace_nth tr n1 = Some first
Hs2: trace_nth tr (S m) = Some second
H: n1 ≤ m

in_futures first second
message: Type
X: VLSM message
first, second: state X
tr: Trace
Htr: valid_trace_prop tr
n1, m: nat
Hs1: trace_nth tr n1 = Some first
Hs2: trace_nth tr (S m) = Some second
H: n1 ≤ m

finite_valid_trace_from_to first second (trace_segment tr n1 (S m))
message: Type
X: VLSM message
first, second: state X
tr: Trace
Htr: valid_trace_prop tr
n1, m: nat
Hs1: trace_nth tr n1 = Some first
Hs2: trace_nth tr (S m) = Some second
H: n1 ≤ m

finite_trace_last first (trace_segment tr n1 (S m)) = second
message: Type
X: VLSM message
first, second, s: state X
tr: list transition_item
Htr: valid_trace_prop (Finite s tr)
n1, m: nat
Hs1: trace_nth (Finite s tr) n1 = Some first
Hs2: trace_nth (Finite s tr) (S m) = Some second
H: n1 ≤ m

finite_trace_last first (list_segment tr n1 (S m)) = second
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: trace_nth (Infinite s tr) (S m) = Some second
H: n1 ≤ m
finite_trace_last first (stream_segment tr n1 (S m)) = second
message: Type
X: VLSM message
first, second, s: state X
tr: list transition_item
Htr: valid_trace_prop (Finite s tr)
n1, m: nat
Hs1: trace_nth (Finite s tr) n1 = Some first
Hs2: trace_nth (Finite s tr) (S m) = Some second
H: n1 ≤ m

finite_trace_last first (list_segment tr n1 (S m)) = second
message: Type
X: VLSM message
first, second, s: state X
tr: list transition_item
Htr: valid_trace_prop (Finite s tr)
n1, m: nat
Hs1: finite_trace_nth s tr n1 = Some first
Hs2: finite_trace_nth s tr (S m) = Some second
H: n1 ≤ m

finite_trace_last first (list_segment tr n1 (S m)) = second
message: Type
X: VLSM message
first, second, s: state X
tr: list transition_item
Htr: valid_trace_prop (Finite s tr)
n1, m: nat
Hs1: finite_trace_nth s tr n1 = Some first
Hs2: finite_trace_nth s tr (S m) = Some second
H: n1 ≤ m

finite_trace_last first (drop n1 (take (S m) tr)) = second
message: Type
X: VLSM message
first, second, s: state X
tr: list transition_item
Htr: valid_trace_prop (Finite s tr)
n1, m: nat
Hs1: finite_trace_nth s tr n1 = Some first
Hs2: finite_trace_nth s tr (S m) = Some second
H: n1 ≤ m

finite_trace_last first (take (S m) tr) = second
message: Type
X: VLSM message
first, second, s: state X
tr: list transition_item
Htr: valid_trace_prop (Finite s tr)
n1, m: nat
Hs1: finite_trace_nth s tr n1 = Some first
Hs2: finite_trace_nth s tr (S m) = Some second
H: n1 ≤ m
n1 < length (take (S m) tr)
message: Type
X: VLSM message
first, second, s: state X
tr: list transition_item
Htr: valid_trace_prop (Finite s tr)
n1, m: nat
Hs1: finite_trace_nth s tr n1 = Some first
Hs2: finite_trace_nth s tr (S m) = Some second
H: n1 ≤ m

finite_trace_last first (take (S m) tr) = second
by apply finite_trace_last_prefix.
message: Type
X: VLSM message
first, second, s: state X
tr: list transition_item
Htr: valid_trace_prop (Finite s tr)
n1, m: nat
Hs1: finite_trace_nth s tr n1 = Some first
Hs2: finite_trace_nth s tr (S m) = Some second
H: n1 ≤ m

n1 < length (take (S m) tr)
message: Type
X: VLSM message
first, second, s: state X
tr: list transition_item
Htr: valid_trace_prop (Finite s tr)
n1, m: nat
Hs1: finite_trace_nth s tr n1 = Some first
Hs2: S m ≤ length tr
H: n1 ≤ m

n1 < length (take (S m) tr)
by rewrite take_length; lia.
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: trace_nth (Infinite s tr) (S m) = Some second
H: n1 ≤ m

finite_trace_last first (stream_segment tr n1 (S m)) = second
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: trace_nth (Infinite s tr) (S m) = Some second
H: n1 ≤ m

finite_trace_last first (drop n1 (stream_prefix tr (S m))) = second
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: trace_nth (Infinite s tr) (S m) = Some second
H: n1 ≤ m

List.last (List.map destination (drop n1 (stream_prefix tr (S m)))) first = second
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: trace_nth (Infinite s tr) (S m) = Some second
H: n1 ≤ m

List.last (drop n1 (stream_prefix (map destination tr) (S m))) first = second
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: Some (Str_nth (S m) (Cons s (map destination tr))) = Some second
H: n1 ≤ m

List.last (drop n1 (stream_prefix (map destination tr) (S m))) first = second
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: Some (Str_nth (S m) (Cons s (map destination tr))) = Some second
H: n1 ≤ m

List.last (stream_prefix (map destination tr) (S m)) first = second
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: Some (Str_nth (S m) (Cons s (map destination tr))) = Some second
H: n1 ≤ m
n1 < length (stream_prefix (map destination tr) (S m))
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: Some (Str_nth (S m) (Cons s (map destination tr))) = Some second
H: n1 ≤ m

List.last (stream_prefix (map destination tr) (S m)) first = second
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: Some (Str_nth (S m) (Cons s (map destination tr))) = Some second
H: n1 ≤ m

second = List.last (stream_prefix (map destination tr) (S m)) first
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: Some (Str_nth (S m) (Cons s (map destination tr))) = Some second
H: n1 ≤ m

second = Str_nth m (map destination tr)
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: Some (hd (Str_nth_tl (S m) (Cons s (map destination tr)))) = Some second
H: n1 ≤ m

second = Str_nth m (map destination tr)
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: Some (hd (Str_nth_tl m (map destination tr))) = Some second
H: n1 ≤ m

second = Str_nth m (map destination tr)
by inversion Hs2; subst.
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: Some (Str_nth (S m) (Cons s (map destination tr))) = Some second
H: n1 ≤ m

n1 < length (stream_prefix (map destination tr) (S m))
message: Type
X: VLSM message
first, second, s: state X
tr: Stream transition_item
Htr: valid_trace_prop (Infinite s tr)
n1, m: nat
Hs1: trace_nth (Infinite s tr) n1 = Some first
Hs2: Some (Str_nth (S m) (Cons s (map destination tr))) = Some second
H: n1 ≤ m
Hpref_len: length (stream_prefix (map destination tr) (S m)) = S m

n1 < length (stream_prefix (map destination tr) (S m))
by rewrite Hpref_len; lia. Qed.
Stating liveness properties will require quantifying over complete executions of the protocol. To make this possible, we will now define complete valid_traces.
A valid_trace is terminating if there's no other valid_trace that contains it as a prefix.
Definition terminating_trace_prop (tr : Trace) : Prop :=
  match tr with
  | Finite s ls =>
      ~ exists (tr : valid_trace) (last : transition_item),
        trace_prefix (proj1_sig tr) last ls
  | Infinite s ls => False
  end.
A valid_trace is complete, if it is either terminating or infinite.
Definition complete_trace_prop (tr : Trace) : Prop :=
  valid_trace_prop tr /\
  match tr with
  | Finite _ _ => terminating_trace_prop tr
  | Infinite _ _ => True
  end.

(*
  Implicitly, the state itself must be in the trace, and minimally the last
  element of the trace. Also implicitly, the trace leading up to the state
  is finite.

  Defining equivocation on these trace definitions

  Section 7:
  A message m received by a valid state s with a transition label l in a
  valid execution trace is called "an equivocation" if it wasn't produced
  in that trace
*)

(* 6.2.2 Equivocation-free as a composition constraint *)
Definition composition_constraint : Type :=
  label X -> state X * option message -> Prop.

(* Decidable VLSMs *)

Class VLSM_vdecidable : Type :=
{
  valid_decidable :
    forall (l : label X) (som : state X * option message),
      {valid X l som} + {~ valid X l som}
}.

End sec_VLSM.
Make all arguments of valid_state_prop_ind explicit so it will work with the induction using tactic (closing the section added {message} as an implicit argument).
Arguments valid_state_message_prop_ind : clear implicits.
Arguments valid_state_prop_ind : clear implicits.
Arguments finite_valid_trace_from_to_ind : clear implicits.

Arguments finite_valid_trace_rev_ind : clear implicits.
Arguments finite_valid_trace_from_rev_ind : clear implicits.
Arguments finite_valid_trace_from_to_rev_ind : clear implicits.
Arguments finite_valid_trace_init_to_rev_ind : clear implicits.
Arguments finite_valid_trace_init_to_rev_strong_ind : clear implicits.

Arguments extend_right_finite_trace_from [message] X [s1 ts] Ht12 [l3 iom3 s3 oom3] Hv23.
Arguments extend_right_finite_trace_from_to [message] X [s1 s2 ts] Ht12 [l3 iom3 s3 oom3] Hv23.

Class TraceWithLast
  (base_prop :
    forall {message} (X : VLSM message), state X -> list transition_item -> Prop)
  (trace_prop :
    forall {message} (X : VLSM message), state X -> state X -> list transition_item -> Prop)
  : Prop :=
{
  valid_trace_add_last :
    forall [msg] [X : VLSM msg] [s f tr],
      base_prop X s tr -> finite_trace_last s tr = f -> trace_prop X s f tr;
  valid_trace_get_last :
    forall [msg] [X : VLSM msg] [s f tr],
      trace_prop X s f tr -> finite_trace_last s tr = f;
  valid_trace_last_pstate :
    forall [msg] [X : VLSM msg] [s f tr],
      trace_prop X s f tr -> valid_state_prop X f;
  valid_trace_forget_last :
    forall [msg] [X : VLSM msg] [s f tr],
      trace_prop X s f tr -> base_prop X s tr;
}.

#[global] Hint Mode TraceWithLast - ! : typeclass_instances.
#[global] Hint Mode TraceWithLast ! - : typeclass_instances.

base_prop: (message : Type) (X : VLSM message), state X → list transition_item → Prop
trace_prop: (message : Type) (X : VLSM message), state X → state X → list transition_item → Prop
H: TraceWithLast base_prop trace_prop
msg: Type
X: VLSM msg
s: state X
tr: list transition_item
Htr: base_prop msg X s tr

trace_prop msg X s (finite_trace_last s tr) tr
base_prop: (message : Type) (X : VLSM message), state X → list transition_item → Prop
trace_prop: (message : Type) (X : VLSM message), state X → state X → list transition_item → Prop
H: TraceWithLast base_prop trace_prop
msg: Type
X: VLSM msg
s: state X
tr: list transition_item
Htr: base_prop msg X s tr

trace_prop msg X s (finite_trace_last s tr) tr
by apply valid_trace_add_last. Defined. #[export] Instance trace_with_last_valid_trace_from : TraceWithLast (@finite_valid_trace_from) (@finite_valid_trace_from_to) := { valid_trace_add_last := @finite_valid_trace_from_add_last; valid_trace_get_last := @finite_valid_trace_from_to_last; valid_trace_last_pstate := @finite_valid_trace_from_to_last_pstate; valid_trace_forget_last := @finite_valid_trace_from_to_forget_last; }. #[export] Instance trace_with_last_valid_trace_init : TraceWithLast (@finite_valid_trace) (@finite_valid_trace_init_to) := { valid_trace_add_last := @finite_valid_trace_init_add_last; valid_trace_get_last := @finite_valid_trace_init_to_last; valid_trace_last_pstate _ _ _ _ _ H := valid_trace_last_pstate (proj1 H); valid_trace_forget_last := @finite_valid_trace_init_to_forget_last; }. Class TraceWithStart {message} {X : VLSM message} (start : state X) (trace_prop : list (transition_item X) -> Prop) : Prop := { valid_trace_first_pstate : forall [tr], trace_prop tr -> valid_state_prop X start; }. #[global] Hint Mode TraceWithStart - - - ! : typeclass_instances. #[export] Instance trace_with_start_valid_trace_from message (X : VLSM message) s : TraceWithStart s (finite_valid_trace_from X s) := { valid_trace_first_pstate := finite_valid_trace_first_pstate X s }. #[export] Instance trace_with_start_valid_trace message (X : VLSM message) s : TraceWithStart s (finite_valid_trace X s) := { valid_trace_first_pstate tr H := valid_trace_first_pstate (proj1 H); }. #[export] Instance trace_with_start_valid_trace_from_to message (X : VLSM message) s f : TraceWithStart s (finite_valid_trace_from_to X s f) := { valid_trace_first_pstate tr H := valid_trace_first_pstate (valid_trace_forget_last H); }. #[export] Instance trace_with_start_valid_trace_init_to message (X : VLSM message) s f : TraceWithStart s (finite_valid_trace_init_to X s f) := { valid_trace_first_pstate tr H := valid_trace_first_pstate (valid_trace_forget_last H); }.
message: Type
X: VLSM message
s: state X
m: message

can_produce X s m ↔ ( (is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace X is tr ∧ last_error tr = Some item ∧ destination item = s ∧ output item = Some m)
message: Type
X: VLSM message
s: state X
m: message

can_produce X s m ↔ ( (is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace X is tr ∧ last_error tr = Some item ∧ destination item = s ∧ output item = Some m)
message: Type
X: VLSM message
s: state X
m: message

can_produce X s m → (is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace X is tr ∧ last_error tr = Some item ∧ destination item = s ∧ output item = Some m
message: Type
X: VLSM message
s: state X
m: message
( (is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace X is tr ∧ last_error tr = Some item ∧ destination item = s ∧ output item = Some m) → can_produce X s m
message: Type
X: VLSM message
s: state X
m: message

can_produce X s m → (is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace X is tr ∧ last_error tr = Some item ∧ destination item = s ∧ output item = Some m
message: Type
X: VLSM message
s: state X
m: message
s': state X
om': option message
l: label X
Hsm: input_valid_transition X l (s', om') (s, Some m)

(is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace X is tr ∧ last_error tr = Some item ∧ destination item = s ∧ output item = Some m
message: Type
X: VLSM message
s: state X
m: message
s': state X
om': option message
l: label X
Hsm: input_valid_transition X l (s', om') (s, Some m)
Hp: valid_state_prop X s'

(is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace X is tr ∧ last_error tr = Some item ∧ destination item = s ∧ output item = Some m
message: Type
X: VLSM message
s: state X
m: message
s': state X
om': option message
l: label X
Hsm: input_valid_transition X l (s', om') (s, Some m)
Hp: valid_state_prop X s'
Htr: finite_valid_trace_from X s' [{| l := l; input := om'; destination := s; output := Some m |}]

(is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace X is tr ∧ last_error tr = Some item ∧ destination item = s ∧ output item = Some m
message: Type
X: VLSM message
s: state X
m: message
s': state X
om': option message
l: label X
Hsm: input_valid_transition X l (s', om') (s, Some m)
Hp: valid_state_prop X s'
Htr: (is : state X) (trs : list transition_item), finite_valid_trace X is (trs ++ [{| l := l; input := om'; destination := s; output := Some m |}]) ∧ finite_trace_last is trs = s'

(is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace X is tr ∧ last_error tr = Some item ∧ destination item = s ∧ output item = Some m
message: Type
X: VLSM message
s: state X
m: message
s': state X
om': option message
l: label X
Hsm: input_valid_transition X l (s', om') (s, Some m)
Hp: valid_state_prop X s'
is: state X
trs: list transition_item
Htrs: finite_valid_trace X is (trs ++ [{| l := l; input := om'; destination := s; output := Some m |}])

(is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace X is tr ∧ last_error tr = Some item ∧ destination item = s ∧ output item = Some m
message: Type
X: VLSM message
s: state X
m: message
s': state X
om': option message
l: label X
Hsm: input_valid_transition X l (s', om') (s, Some m)
Hp: valid_state_prop X s'
is: state X
trs: list transition_item
Htrs: finite_valid_trace X is (trs ++ [{| l := l; input := om'; destination := s; output := Some m |}])

finite_valid_trace X is (trs ++ ?Goal0) ∧ last_error (trs ++ ?Goal0) = Some ?Goal1 ∧ destination ?Goal1 = s ∧ output ?Goal1 = Some m
by rewrite last_error_is_last.
message: Type
X: VLSM message
s: state X
m: message

( (is : state X) (tr : list transition_item) (item : transition_item), finite_valid_trace X is tr ∧ last_error tr = Some item ∧ destination item = s ∧ output item = Some m) → can_produce X s m
message: Type
X: VLSM message
s: state X
m: message
is: state X
tr: list transition_item
item: transition_item
Htr: finite_valid_trace X is tr
Hitem: last_error tr = Some item
Hs: destination item = s
Hm: output item = Some m

can_produce X s m
message: Type
X: VLSM message
s: state X
m: message
is: state X
tr: list transition_item
item: transition_item
tr': list transition_item
item': transition_item
Htr: finite_valid_trace X is (tr' ++ [item'])
Hitem: last_error (tr' ++ [item']) = Some item
Hs: destination item = s
Hm: output item = Some m
Heq: tr = tr' ++ [item']

can_produce X s m
message: Type
X: VLSM message
s: state X
m: message
is: state X
tr: list transition_item
item: transition_item
tr': list transition_item
item': transition_item
Htr: finite_valid_trace X is (tr' ++ [item'])
Hitem: last_error (tr' ++ [item']) = Some item
Hs: destination item = s
Hm: output item = Some m

can_produce X s m
message: Type
X: VLSM message
s: state X
m: message
is: state X
tr: list transition_item
item: transition_item
tr': list transition_item
item': transition_item
Htr: finite_valid_trace X is (tr' ++ [item'])
Hitem: Some item' = Some item
Hs: destination item = s
Hm: output item = Some m

can_produce X s m
message: Type
X: VLSM message
s: state X
m: message
is: state X
tr: list transition_item
item: transition_item
tr': list transition_item
item': transition_item
Htr: finite_valid_trace X is (tr' ++ [item'])
Hitem: Some item' = Some item
Hs: destination item = s
Hm: output item = Some m
H0: item' = item

can_produce X s m
message: Type
X: VLSM message
s: state X
m: message
is: state X
tr: list transition_item
item: transition_item
tr': list transition_item
item': transition_item
Htr: finite_valid_trace X is (tr' ++ [item'])
Hs: destination item = s
Hm: output item = Some m
H0: item' = item

can_produce X s m
message: Type
X: VLSM message
s: state X
m: message
is: state X
tr: list transition_item
item: transition_item
tr': list transition_item
Htr: finite_valid_trace X is (tr' ++ [item])
Hs: destination item = s
Hm: output item = Some m

can_produce X s m
message: Type
X: VLSM message
s: state X
m: message
is: state X
tr: list transition_item
item: transition_item
tr': list transition_item
Htr: finite_valid_trace_from X is (tr' ++ [item])
Hs: destination item = s
Hm: output item = Some m

can_produce X s m
message: Type
X: VLSM message
s: state X
m: message
is: state X
tr: list transition_item
item: transition_item
tr': list transition_item
Htr: finite_valid_trace_from X is tr' ∧ finite_valid_trace_from X (finite_trace_last is tr') [item]
Hs: destination item = s
Hm: output item = Some m

can_produce X s m
message: Type
X: VLSM message
s: state X
m: message
is: state X
tr: list transition_item
item: transition_item
tr': list transition_item
Htr: finite_valid_trace_from X (finite_trace_last is tr') [item]
Hs: destination item = s
Hm: output item = Some m

can_produce X s m
message: Type
X: VLSM message
s: state X
m: message
is: state X
tr: list transition_item
item: transition_item
tr': list transition_item
Htr: finite_valid_trace_from X (finite_trace_last is tr') [item]
Hs: destination item = s
Hm: output item = Some m
s1: state X
tl: list transition_item
s': state X
iom, oom: option message
l0: label X
Htl: finite_valid_trace_from X s1 []
Ht: input_valid_transition X l0 (finite_trace_last is tr', iom) ( s1, oom)
H: s' = finite_trace_last is tr'
H1: {| l := l0; input := iom; destination := s1; output := oom |} = item
H2: tl = []

can_produce X s m
message: Type
X: VLSM message
s: state X
m: message
is: state X
tr: list transition_item
item: transition_item
tr': list transition_item
Hs: destination item = s
Hm: output item = Some m
s1: state X
tl: list transition_item
s': state X
iom, oom: option message
l0: label X
Htl: finite_valid_trace_from X s1 []
Ht: input_valid_transition X l0 (finite_trace_last is tr', iom) ( s1, oom)
H: s' = finite_trace_last is tr'
H1: {| l := l0; input := iom; destination := s1; output := oom |} = item
H2: tl = []

can_produce X s m
message: Type
X: VLSM message
m: message
is: state X
tr, tr': list transition_item
s1: state X
iom, oom: option message
l0: label X
Hm: output {| l := l0; input := iom; destination := s1; output := oom |} = Some m
Htl: finite_valid_trace_from X s1 []
Ht: input_valid_transition X l0 (finite_trace_last is tr', iom) ( s1, oom)

can_produce X (destination {| l := l0; input := iom; destination := s1; output := oom |}) m
message: Type
X: VLSM message
m: message
is: state X
tr, tr': list transition_item
s1: state X
iom, oom: option message
l0: label X
Hm: oom = Some m
Htl: finite_valid_trace_from X s1 []
Ht: input_valid_transition X l0 (finite_trace_last is tr', iom) ( s1, oom)

can_produce X (destination {| l := l0; input := iom; destination := s1; output := oom |}) m
message: Type
X: VLSM message
m: message
is: state X
tr, tr': list transition_item
s1: state X
iom: option message
l0: label X
Htl: finite_valid_trace_from X s1 []
Ht: input_valid_transition X l0 (finite_trace_last is tr', iom) ( s1, Some m)

can_produce X (destination {| l := l0; input := iom; destination := s1; output := Some m |}) m
by eexists _, l0; apply Ht. Qed.
The last transition of a valid VLSM trace is valid
message: Type
X: VLSM message

(s f : state X) (tr tr' : list transition_item) (li : transition_item), finite_valid_trace_from_to X s f tr' → tr' = tr ++ [li] → input_valid_transition_item X (finite_trace_last s tr) li
message: Type
X: VLSM message

(s f : state X) (tr tr' : list transition_item) (li : transition_item), finite_valid_trace_from_to X s f tr' → tr' = tr ++ [li] → input_valid_transition_item X (finite_trace_last s tr) li
by intros * Htr; eapply input_valid_transition_to, valid_trace_forget_last. Qed.

Properties of provably-equal VLSMs

If we know that two VLSMs are provably equal, we could try rewriting by them. However, that gets usually quite technical. To go around that, we will prove that there is a VLSMProjections.VLSM_embedding between them which will allow trace-based results to be easily moved between the two VLSMs.
Below are some preliminary results; the actual projection is given in VLSMProjections.same_VLSM_embedding.
Section sec_same_VLSM.

Context
  {message : Type}
  .

Section sec_definitions.

Context
  [X1 X2 : VLSM message]
  (Heq : X1 = X2)
  .

Definition same_VLSM_label_rew (l1 : label X1) : label X2 :=
  eq_rect X1 (@label _) l1 _ Heq.

Definition same_VLSM_state_rew (s1 : state X1) : state X2 :=
  eq_rect X1 (@state _) s1 _ Heq.

End sec_definitions.

Context
  (X1 X2 : VLSM message)
  (Heq : X1 = X2)
  .

message: Type
X1, X2: VLSM message
Heq: X1 = X2

(l1 : label X1) (s1 : state X1) (om : option message), valid l1 (s1, om) → valid (same_VLSM_label_rew Heq l1) (same_VLSM_state_rew Heq s1, om)
message: Type
X1, X2: VLSM message
Heq: X1 = X2

(l1 : label X1) (s1 : state X1) (om : option message), valid l1 (s1, om) → valid (same_VLSM_label_rew Heq l1) (same_VLSM_state_rew Heq s1, om)
by subst. Qed.
message: Type
X1, X2: VLSM message
Heq: X1 = X2
l1: label X1
s1: state X1
om: option message
s1': state X1
om': option message

transition l1 (s1, om) = (s1', om') → transition (same_VLSM_label_rew Heq l1) (same_VLSM_state_rew Heq s1, om) = (same_VLSM_state_rew Heq s1', om')
message: Type
X1, X2: VLSM message
Heq: X1 = X2
l1: label X1
s1: state X1
om: option message
s1': state X1
om': option message

transition l1 (s1, om) = (s1', om') → transition (same_VLSM_label_rew Heq l1) (same_VLSM_state_rew Heq s1, om) = (same_VLSM_state_rew Heq s1', om')
by subst. Qed.
message: Type
X1, X2: VLSM message
Heq: X1 = X2

s1 : state X1, initial_state_prop s1 → initial_state_prop (same_VLSM_state_rew Heq s1)
message: Type
X1, X2: VLSM message
Heq: X1 = X2

s1 : state X1, initial_state_prop s1 → initial_state_prop (same_VLSM_state_rew Heq s1)
by subst. Qed.
message: Type
X1, X2: VLSM message
Heq: X1 = X2

m : message, initial_message_prop m → initial_message_prop m
message: Type
X1, X2: VLSM message
Heq: X1 = X2

m : message, initial_message_prop m → initial_message_prop m
by subst. Qed. End sec_same_VLSM. Record valid_transition `(X : VLSM message) l s1 iom s2 oom : Prop := { vt_valid : valid X l (s1, iom); vt_transition : transition X l (s1, iom) = (s2, oom); }. Inductive valid_transition_next `(X : VLSM message) (s1 s2 : state X) : Prop := | transition_next : forall (l : label X) (iom oom : option message) (Ht : valid_transition X l s1 iom s2 oom), valid_transition_next X s1 s2. Section sec_valid_transition_props. Context `(X : VLSM message) .
message: Type
X: VLSM message

(l : label X) (s1 : state X) (iom : option message) (s2 : state X) (oom : option message), input_valid_transition X l (s1, iom) (s2, oom) → valid_transition X l s1 iom s2 oom
message: Type
X: VLSM message

(l : label X) (s1 : state X) (iom : option message) (s2 : state X) (oom : option message), input_valid_transition X l (s1, iom) (s2, oom) → valid_transition X l s1 iom s2 oom
by firstorder. Qed. End sec_valid_transition_props. Section sec_finite_valid_trace_init_to_alt.

Alternate definitions of valid traces and states

Inspired from the constrained_transitions_from_to definition we can derive an alternate definition for valid traces which is easier to use when checking whether a concrete trace is valid.
Context
  `(X : VLSM message)
  .

Inductive message_valid_transitions_from_to :
  state X -> state X -> list (transition_item X) -> Prop :=
| mvt_empty :
    forall (s : state X),
      message_valid_transitions_from_to s s []
| mvt_extend :
    forall s s' om om' l f tr,
      option_valid_message_prop X om ->
      transition X l (s, om) = (s', om') -> valid X l (s, om) ->
      message_valid_transitions_from_to s' f tr ->
      message_valid_transitions_from_to s f (Build_transition_item l om s' om' :: tr).

Definition finite_valid_trace_init_to_alt
  (s f : state X) (tr : list (transition_item X)) : Prop :=
    message_valid_transitions_from_to s f tr /\ initial_state_prop X s.

message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_init_to X s f tr → finite_valid_trace_init_to_alt s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_init_to X s f tr → finite_valid_trace_init_to_alt s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to X s f tr
Hinit: initial_state_prop s

finite_valid_trace_init_to_alt s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to X s f tr

message_valid_transitions_from_to s f tr
message: Type
X: VLSM message
s: state X
Hs: valid_state_prop X s

message_valid_transitions_from_to s s []
message: Type
X: VLSM message
s, f: state X
tl: list transition_item
Htr: finite_valid_trace_from_to X s f tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition X l0 (s', iom) (s, oom)
IHHtr: message_valid_transitions_from_to s f tl
message_valid_transitions_from_to s' f ({| l := l0; input := iom; destination := s; output := oom |} :: tl)
message: Type
X: VLSM message
s: state X
Hs: valid_state_prop X s

message_valid_transitions_from_to s s []
by constructor.
message: Type
X: VLSM message
s, f: state X
tl: list transition_item
Htr: finite_valid_trace_from_to X s f tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition X l0 (s', iom) (s, oom)
IHHtr: message_valid_transitions_from_to s f tl

message_valid_transitions_from_to s' f ({| l := l0; input := iom; destination := s; output := oom |} :: tl)
by constructor; [apply Ht.. |]. Qed.
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_init_to_alt s f tr → finite_valid_trace_init_to X s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_init_to_alt s f tr → finite_valid_trace_init_to X s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: message_valid_transitions_from_to s f tr
Hs: initial_state_prop s

finite_valid_trace_init_to X s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: message_valid_transitions_from_to s f tr
Hs: initial_state_prop s

finite_valid_trace_from_to X s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: message_valid_transitions_from_to s f tr
Hs: valid_state_prop X s

finite_valid_trace_from_to X s f tr
message: Type
X: VLSM message
f: state X
tr: list transition_item

s : state X, valid_state_prop X s → message_valid_transitions_from_to s f tr → finite_valid_trace_from_to X s f tr
message: Type
X: VLSM message
f: state X
Htr: message_valid_transitions_from_to f f []
Hs: valid_state_prop X f

finite_valid_trace_from_to X f f []
message: Type
X: VLSM message
f: state X
tr: list transition_item
IHtr: s : state X, valid_state_prop X s → message_valid_transitions_from_to s f tr → finite_valid_trace_from_to X s f tr
s: state X
Hs: valid_state_prop X s
s': state X
om, om': option message
l0: label X
Htr: message_valid_transitions_from_to s f ({| l := l0; input := om; destination := s'; output := om' |} :: tr)
H1: option_valid_message_prop X om
H2: transition l0 (s, om) = (s', om')
H5: valid l0 (s, om)
H6: message_valid_transitions_from_to s' f tr
finite_valid_trace_from_to X s f ({| l := l0; input := om; destination := s'; output := om' |} :: tr)
message: Type
X: VLSM message
f: state X
Htr: message_valid_transitions_from_to f f []
Hs: valid_state_prop X f

finite_valid_trace_from_to X f f []
by apply (finite_valid_trace_from_to_empty X).
message: Type
X: VLSM message
f: state X
tr: list transition_item
IHtr: s : state X, valid_state_prop X s → message_valid_transitions_from_to s f tr → finite_valid_trace_from_to X s f tr
s: state X
Hs: valid_state_prop X s
s': state X
om, om': option message
l0: label X
Htr: message_valid_transitions_from_to s f ({| l := l0; input := om; destination := s'; output := om' |} :: tr)
H1: option_valid_message_prop X om
H2: transition l0 (s, om) = (s', om')
H5: valid l0 (s, om)
H6: message_valid_transitions_from_to s' f tr

finite_valid_trace_from_to X s f ({| l := l0; input := om; destination := s'; output := om' |} :: tr)
message: Type
X: VLSM message
f: state X
tr: list transition_item
IHtr: s : state X, valid_state_prop X s → message_valid_transitions_from_to s f tr → finite_valid_trace_from_to X s f tr
s: state X
Hs: valid_state_prop X s
s': state X
om, om': option message
l0: label X
Htr: message_valid_transitions_from_to s f ({| l := l0; input := om; destination := s'; output := om' |} :: tr)
H1: option_valid_message_prop X om
H2: transition l0 (s, om) = (s', om')
H5: valid l0 (s, om)
H6: message_valid_transitions_from_to s' f tr

finite_valid_trace_from_to X s' f tr
message: Type
X: VLSM message
f: state X
tr: list transition_item
IHtr: s : state X, valid_state_prop X s → message_valid_transitions_from_to s f tr → finite_valid_trace_from_to X s f tr
s: state X
Hs: valid_state_prop X s
s': state X
om, om': option message
l0: label X
Htr: message_valid_transitions_from_to s f ({| l := l0; input := om; destination := s'; output := om' |} :: tr)
H1: option_valid_message_prop X om
H2: transition l0 (s, om) = (s', om')
H5: valid l0 (s, om)
H6: message_valid_transitions_from_to s' f tr

valid_state_prop X s'
message: Type
X: VLSM message
f: state X
tr: list transition_item
IHtr: s : state X, valid_state_prop X s → message_valid_transitions_from_to s f tr → finite_valid_trace_from_to X s f tr
s: state X
Hs: valid_state_prop X s
s': state X
om, om': option message
l0: label X
Htr: message_valid_transitions_from_to s f ({| l := l0; input := om; destination := s'; output := om' |} :: tr)
H1: option_valid_message_prop X om
H2: transition l0 (s, om) = (s', om')
H5: valid l0 (s, om)
H6: message_valid_transitions_from_to s' f tr

(l : label X) (som : state X * option message) (om' : option message), input_valid_transition X l som (s', om')
by exists l0, (s, om), om'. Qed.
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_init_to X s f tr ↔ finite_valid_trace_init_to_alt s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_init_to X s f tr ↔ finite_valid_trace_init_to_alt s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_init_to X s f tr → finite_valid_trace_init_to_alt s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
finite_valid_trace_init_to_alt s f tr → finite_valid_trace_init_to X s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_init_to X s f tr → finite_valid_trace_init_to_alt s f tr
by apply finite_valid_trace_init_to_alt_left_impl.
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_init_to_alt s f tr → finite_valid_trace_init_to X s f tr
by apply finite_valid_trace_init_to_alt_right_impl. Qed. Definition finite_valid_trace_from_to_alt (s f : state X) (tr : list (transition_item X)) : Prop := message_valid_transitions_from_to s f tr /\ valid_state_prop X s.
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_from_to X s f tr → finite_valid_trace_from_to_alt s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_from_to X s f tr → finite_valid_trace_from_to_alt s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to X s f tr

finite_valid_trace_from_to_alt s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
Htr: finite_valid_trace_from_to X s f tr

message_valid_transitions_from_to s f tr
message: Type
X: VLSM message
s: state X
Hs: valid_state_prop X s

message_valid_transitions_from_to s s []
message: Type
X: VLSM message
s, f: state X
tl: list transition_item
Htr: finite_valid_trace_from_to X s f tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition X l0 (s', iom) (s, oom)
IHHtr: message_valid_transitions_from_to s f tl
message_valid_transitions_from_to s' f ({| l := l0; input := iom; destination := s; output := oom |} :: tl)
message: Type
X: VLSM message
s: state X
Hs: valid_state_prop X s

message_valid_transitions_from_to s s []
by constructor.
message: Type
X: VLSM message
s, f: state X
tl: list transition_item
Htr: finite_valid_trace_from_to X s f tl
s': state X
iom, oom: option message
l0: label X
Ht: input_valid_transition X l0 (s', iom) (s, oom)
IHHtr: message_valid_transitions_from_to s f tl

message_valid_transitions_from_to s' f ({| l := l0; input := iom; destination := s; output := oom |} :: tl)
by constructor; [apply Ht.. |]. Qed.
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_from_to_alt s f tr → finite_valid_trace_from_to X s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_from_to_alt s f tr → finite_valid_trace_from_to X s f tr
message: Type
X: VLSM message
f: state X
tr: list transition_item

s : state X, valid_state_prop X s → message_valid_transitions_from_to s f tr → finite_valid_trace_from_to X s f tr
message: Type
X: VLSM message
f: state X
Htr: message_valid_transitions_from_to f f []
Hs: valid_state_prop X f

finite_valid_trace_from_to X f f []
message: Type
X: VLSM message
f: state X
tr: list transition_item
IHtr: s : state X, valid_state_prop X s → message_valid_transitions_from_to s f tr → finite_valid_trace_from_to X s f tr
s: state X
Hs: valid_state_prop X s
s': state X
om, om': option message
l0: label X
Htr: message_valid_transitions_from_to s f ({| l := l0; input := om; destination := s'; output := om' |} :: tr)
H1: option_valid_message_prop X om
H2: transition l0 (s, om) = (s', om')
H5: valid l0 (s, om)
H6: message_valid_transitions_from_to s' f tr
finite_valid_trace_from_to X s f ({| l := l0; input := om; destination := s'; output := om' |} :: tr)
message: Type
X: VLSM message
f: state X
Htr: message_valid_transitions_from_to f f []
Hs: valid_state_prop X f

finite_valid_trace_from_to X f f []
by apply (finite_valid_trace_from_to_empty X).
message: Type
X: VLSM message
f: state X
tr: list transition_item
IHtr: s : state X, valid_state_prop X s → message_valid_transitions_from_to s f tr → finite_valid_trace_from_to X s f tr
s: state X
Hs: valid_state_prop X s
s': state X
om, om': option message
l0: label X
Htr: message_valid_transitions_from_to s f ({| l := l0; input := om; destination := s'; output := om' |} :: tr)
H1: option_valid_message_prop X om
H2: transition l0 (s, om) = (s', om')
H5: valid l0 (s, om)
H6: message_valid_transitions_from_to s' f tr

finite_valid_trace_from_to X s f ({| l := l0; input := om; destination := s'; output := om' |} :: tr)
message: Type
X: VLSM message
f: state X
tr: list transition_item
IHtr: s : state X, valid_state_prop X s → message_valid_transitions_from_to s f tr → finite_valid_trace_from_to X s f tr
s: state X
Hs: valid_state_prop X s
s': state X
om, om': option message
l0: label X
Htr: message_valid_transitions_from_to s f ({| l := l0; input := om; destination := s'; output := om' |} :: tr)
H1: option_valid_message_prop X om
H2: transition l0 (s, om) = (s', om')
H5: valid l0 (s, om)
H6: message_valid_transitions_from_to s' f tr

finite_valid_trace_from_to X s' f tr
message: Type
X: VLSM message
f: state X
tr: list transition_item
IHtr: s : state X, valid_state_prop X s → message_valid_transitions_from_to s f tr → finite_valid_trace_from_to X s f tr
s: state X
Hs: valid_state_prop X s
s': state X
om, om': option message
l0: label X
Htr: message_valid_transitions_from_to s f ({| l := l0; input := om; destination := s'; output := om' |} :: tr)
H1: option_valid_message_prop X om
H2: transition l0 (s, om) = (s', om')
H5: valid l0 (s, om)
H6: message_valid_transitions_from_to s' f tr

valid_state_prop X s'
message: Type
X: VLSM message
f: state X
tr: list transition_item
IHtr: s : state X, valid_state_prop X s → message_valid_transitions_from_to s f tr → finite_valid_trace_from_to X s f tr
s: state X
Hs: valid_state_prop X s
s': state X
om, om': option message
l0: label X
Htr: message_valid_transitions_from_to s f ({| l := l0; input := om; destination := s'; output := om' |} :: tr)
H1: option_valid_message_prop X om
H2: transition l0 (s, om) = (s', om')
H5: valid l0 (s, om)
H6: message_valid_transitions_from_to s' f tr

(l : label X) (som : state X * option message) (om' : option message), input_valid_transition X l som (s', om')
by exists l0, (s, om), om'. Qed.
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_from_to X s f tr ↔ finite_valid_trace_from_to_alt s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_from_to X s f tr ↔ finite_valid_trace_from_to_alt s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_from_to X s f tr → finite_valid_trace_from_to_alt s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item
finite_valid_trace_from_to_alt s f tr → finite_valid_trace_from_to X s f tr
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_from_to X s f tr → finite_valid_trace_from_to_alt s f tr
by apply finite_valid_trace_from_to_alt_left_impl.
message: Type
X: VLSM message
s, f: state X
tr: list transition_item

finite_valid_trace_from_to_alt s f tr → finite_valid_trace_from_to X s f tr
by apply finite_valid_trace_from_to_alt_right_impl. Qed.
Similarly, we can alternately define valid states as states at the end of a trace satisfying finite_valid_trace_init_to_alt.
Definition valid_state_prop_alt (s : state X) : Prop :=
  exists (is : state X) (tr : list (transition_item X)),
    finite_valid_trace_init_to_alt is s tr.

message: Type
X: VLSM message
s: state X

valid_state_prop X s ↔ valid_state_prop_alt s
message: Type
X: VLSM message
s: state X

valid_state_prop X s ↔ valid_state_prop_alt s
message: Type
X: VLSM message
s: state X

valid_state_prop X s ↔ ( (is : state X) (tr : list transition_item), finite_valid_trace_init_to X is s tr)
message: Type
X: VLSM message
s: state X

valid_state_prop X s → (is : state X) (tr : list transition_item), finite_valid_trace_init_to X is s tr
message: Type
X: VLSM message
s: state X
( (is : state X) (tr : list transition_item), finite_valid_trace_init_to X is s tr) → valid_state_prop X s
message: Type
X: VLSM message
s: state X

valid_state_prop X s → (is : state X) (tr : list transition_item), finite_valid_trace_init_to X is s tr
by intros Hs; apply valid_state_has_trace in Hs.
message: Type
X: VLSM message
s: state X

( (is : state X) (tr : list transition_item), finite_valid_trace_init_to X is s tr) → valid_state_prop X s
message: Type
X: VLSM message
s, x: state X
x0: list transition_item
Htr: finite_valid_trace_from_to X x s x0

valid_state_prop X s
by eapply finite_valid_trace_from_to_last_pstate. Qed. End sec_finite_valid_trace_init_to_alt.
Custom tactic used to simplify proofs of valid VLSM transitions.
Ltac app_valid_tran :=
  repeat split; cbn; try done;
  match goal with
  | |- option_valid_message_prop _ _ => by apply initial_message_is_valid
  | |- option_valid_message_prop _ _ => eapply emitted_messages_are_valid
  | |- valid_state_prop _ _ => by apply initial_state_is_valid
  | |- valid_state_prop _ _ => eapply input_valid_transition_destination
  end.