Class BaseParams :=
  {
    data : Type;
    input : Type;
    output : Type
  }.Class BaseParams :=
  {
    data : Type;
    input : Type;
    output : Type
  }.Class BaseParams :=
  {
    data : Type;
    input : Type;
    output : Type
  }.Class BaseParams :=
  {
    data : Type;
    input : Type;
    output : Type
  }.Class OneNodeParams (P : BaseParams) :=
  {
    init : data;
    handler : input -> data -> (output * data)
  }.Class OneNodeParams (P : BaseParams) :=
  {
    init : data;
    handler : input -> data -> (output * data)
  }.Class OneNodeParams (P : BaseParams) :=
  {
    init : data;
    handler : input -> data -> (output * data)
  }.Class SingleParams (P : BaseParams) :=
  {
    init_handler : data;
    input_handler : input -> data -> (list output * data)
  }.Class SingleParams (P : BaseParams) :=
  {
    init_handler : data;
    input_handler : input -> data -> (list output * data)
  }.Class SingleParams (P : BaseParams) :=
  {
    init_handler : data;
    input_handler : input -> data -> (list output * data)
  }.Class MultiParams (P : BaseParams) :=
  {
    name : Type ;
    msg : Type ;
    msg_eq_dec : forall x y : msg, {x = y} + {x <> y} ;
    name_eq_dec : forall x y : name, {x = y} + {x <> y} ;
    nodes : list name ;
    all_names_nodes : forall n, In n nodes ;
    no_dup_nodes : NoDup nodes ;
    init_handlers : name -> data;
    net_handlers : name -> name -> msg -> data -> (list output) * data * list (name * msg) ;
    input_handlers : name -> input -> data -> (list output) * data * list (name * msg)
  }.Class MultiParams (P : BaseParams) :=
  {
    name : Type ;
    msg : Type ;
    msg_eq_dec : forall x y : msg, {x = y} + {x <> y} ;
    name_eq_dec : forall x y : name, {x = y} + {x <> y} ;
    nodes : list name ;
    all_names_nodes : forall n, In n nodes ;
    no_dup_nodes : NoDup nodes ;
    init_handlers : name -> data;
    net_handlers : name -> name -> msg -> data -> (list output) * data * list (name * msg) ;
    input_handlers : name -> input -> data -> (list output) * data * list (name * msg)
  }.Class MultiParams (P : BaseParams) :=
  {
    name : Type ;
    msg : Type ;
    msg_eq_dec : forall x y : msg, {x = y} + {x <> y} ;
    name_eq_dec : forall x y : name, {x = y} + {x <> y} ;
    nodes : list name ;
    all_names_nodes : forall n, In n nodes ;
    no_dup_nodes : NoDup nodes ;
    init_handlers : name -> data;
    net_handlers : name -> name -> msg -> data -> (list output) * data * list (name * msg) ;
    input_handlers : name -> input -> data -> (list output) * data * list (name * msg)
  }.Class MultiParams (P : BaseParams) :=
  {
    name : Type ;
    msg : Type ;
    msg_eq_dec : forall x y : msg, {x = y} + {x <> y} ;
    name_eq_dec : forall x y : name, {x = y} + {x <> y} ;
    nodes : list name ;
    all_names_nodes : forall n, In n nodes ;
    no_dup_nodes : NoDup nodes ;
    init_handlers : name -> data;
    net_handlers : name -> name -> msg -> data -> (list output) * data * list (name * msg) ;
    input_handlers : name -> input -> data -> (list output) * data * list (name * msg)
  }.Class MultiParams (P : BaseParams) :=
  {
    name : Type ;
    msg : Type ;
    msg_eq_dec : forall x y : msg, {x = y} + {x <> y} ;
    name_eq_dec : forall x y : name, {x = y} + {x <> y} ;
    nodes : list name ;
    all_names_nodes : forall n, In n nodes ;
    no_dup_nodes : NoDup nodes ;
    init_handlers : name -> data;
    net_handlers : name -> name -> msg -> data -> (list output) * data * list (name * msg) ;
    input_handlers : name -> input -> data -> (list output) * data * list (name * msg)
  }.Class MultiParams (P : BaseParams) :=
  {
    name : Type ;
    msg : Type ;
    msg_eq_dec : forall x y : msg, {x = y} + {x <> y} ;
    name_eq_dec : forall x y : name, {x = y} + {x <> y} ;
    nodes : list name ;
    all_names_nodes : forall n, In n nodes ;
    no_dup_nodes : NoDup nodes ;
    init_handlers : name -> data;
    net_handlers : name -> name -> msg -> data -> (list output) * data * list (name * msg) ;
    input_handlers : name -> input -> data -> (list output) * data * list (name * msg)
  }.Class MultiParams (P : BaseParams) :=
  {
    name : Type ;
    msg : Type ;
    msg_eq_dec : forall x y : msg, {x = y} + {x <> y} ;
    name_eq_dec : forall x y : name, {x = y} + {x <> y} ;
    nodes : list name ;
    all_names_nodes : forall n, In n nodes ;
    no_dup_nodes : NoDup nodes ;
    init_handlers : name -> data;
    net_handlers : name -> name -> msg -> data -> (list output) * data * list (name * msg) ;
    input_handlers : name -> input -> data -> (list output) * data * list (name * msg)
  }.Class MultiParams (P : BaseParams) :=
  {
    name : Type ;
    msg : Type ;
    msg_eq_dec : forall x y : msg, {x = y} + {x <> y} ;
    name_eq_dec : forall x y : name, {x = y} + {x <> y} ;
    nodes : list name ;
    all_names_nodes : forall n, In n nodes ;
    no_dup_nodes : NoDup nodes ;
    init_handlers : name -> data;
    net_handlers : name -> name -> msg -> data -> (list output) * data * list (name * msg) ;
    input_handlers : name -> input -> data -> (list output) * data * list (name * msg)
  }.Class MultiParams (P : BaseParams) :=
  {
    name : Type ;
    msg : Type ;
    msg_eq_dec : forall x y : msg, {x = y} + {x <> y} ;
    name_eq_dec : forall x y : name, {x = y} + {x <> y} ;
    nodes : list name ;
    all_names_nodes : forall n, In n nodes ;
    no_dup_nodes : NoDup nodes ;
    init_handlers : name -> data;
    net_handlers : name -> name -> msg -> data -> (list output) * data * list (name * msg) ;
    input_handlers : name -> input -> data -> (list output) * data * list (name * msg)
  }.Class MultiParams (P : BaseParams) :=
  {
    name : Type ;
    msg : Type ;
    msg_eq_dec : forall x y : msg, {x = y} + {x <> y} ;
    name_eq_dec : forall x y : name, {x = y} + {x <> y} ;
    nodes : list name ;
    all_names_nodes : forall n, In n nodes ;
    no_dup_nodes : NoDup nodes ;
    init_handlers : name -> data;
    net_handlers : name -> name -> msg -> data -> (list output) * data * list (name * msg) ;
    input_handlers : name -> input -> data -> (list output) * data * list (name * msg)
  }.Class MultiParams (P : BaseParams) :=
  {
    name : Type ;
    msg : Type ;
    msg_eq_dec : forall x y : msg, {x = y} + {x <> y} ;
    name_eq_dec : forall x y : name, {x = y} + {x <> y} ;
    nodes : list name ;
    all_names_nodes : forall n, In n nodes ;
    no_dup_nodes : NoDup nodes ;
    init_handlers : name -> data;
    net_handlers : name -> name -> msg -> data -> (list output) * data * list (name * msg) ;
    input_handlers : name -> input -> data -> (list output) * data * list (name * msg)
  }.Class FailureParams `(P : MultiParams) :=
  {
    reboot : data -> data
  }.Class FailureParams `(P : MultiParams) :=
  {
    reboot : data -> data
  }.Definition do_disk file_name :=
  file_name -> option IOStreamWriter.t.Inductive disk_op file_name :=
| Append :  file_name -> IOStreamWriter.t -> disk_op file_name
| Write : file_name -> IOStreamWriter.t -> disk_op file_name
| Delete : file_name -> disk_op file_name.Inductive disk_op file_name :=
| Append :  file_name -> IOStreamWriter.t -> disk_op file_name
| Write : file_name -> IOStreamWriter.t -> disk_op file_name
| Delete : file_name -> disk_op file_name.Inductive disk_op file_name :=
| Append :  file_name -> IOStreamWriter.t -> disk_op file_name
| Write : file_name -> IOStreamWriter.t -> disk_op file_name
| Delete : file_name -> disk_op file_name.Inductive disk_op file_name :=
| Append :  file_name -> IOStreamWriter.t -> disk_op file_name
| Write : file_name -> IOStreamWriter.t -> disk_op file_name
| Delete : file_name -> disk_op file_name.Class DiskOpMultiParams (P : BaseParams) :=
  {
    do_name : Type ;
    file_name : Type ;
    do_msg : Type ;
    do_msg_eq_dec : forall x y : do_msg, {x = y} + {x <> y} ;
    do_name_eq_dec : forall x y : do_name, {x = y} + {x <> y} ;
    file_name_eq_dec : forall x y : file_name, {x = y} + {x <> y} ;
    do_nodes : list do_name ;
    do_all_names_nodes : forall n, In n do_nodes ;
    do_no_dup_nodes : NoDup do_nodes ;
    do_net_handlers : do_name -> do_name -> do_msg -> data ->
                      list (disk_op file_name) * (list output) * data * list (do_name * do_msg) ;
    do_input_handlers : do_name -> input -> data ->
                        list (disk_op file_name) * (list output) * data * list (do_name * do_msg);
  }.Class DiskOpMultiParams (P : BaseParams) :=
  {
    do_name : Type ;
    file_name : Type ;
    do_msg : Type ;
    do_msg_eq_dec : forall x y : do_msg, {x = y} + {x <> y} ;
    do_name_eq_dec : forall x y : do_name, {x = y} + {x <> y} ;
    file_name_eq_dec : forall x y : file_name, {x = y} + {x <> y} ;
    do_nodes : list do_name ;
    do_all_names_nodes : forall n, In n do_nodes ;
    do_no_dup_nodes : NoDup do_nodes ;
    do_net_handlers : do_name -> do_name -> do_msg -> data ->
                      list (disk_op file_name) * (list output) * data * list (do_name * do_msg) ;
    do_input_handlers : do_name -> input -> data ->
                        list (disk_op file_name) * (list output) * data * list (do_name * do_msg);
  }.Class DiskOpMultiParams (P : BaseParams) :=
  {
    do_name : Type ;
    file_name : Type ;
    do_msg : Type ;
    do_msg_eq_dec : forall x y : do_msg, {x = y} + {x <> y} ;
    do_name_eq_dec : forall x y : do_name, {x = y} + {x <> y} ;
    file_name_eq_dec : forall x y : file_name, {x = y} + {x <> y} ;
    do_nodes : list do_name ;
    do_all_names_nodes : forall n, In n do_nodes ;
    do_no_dup_nodes : NoDup do_nodes ;
    do_net_handlers : do_name -> do_name -> do_msg -> data ->
                      list (disk_op file_name) * (list output) * data * list (do_name * do_msg) ;
    do_input_handlers : do_name -> input -> data ->
                        list (disk_op file_name) * (list output) * data * list (do_name * do_msg);
  }.Class DiskOpMultiParams (P : BaseParams) :=
  {
    do_name : Type ;
    file_name : Type ;
    do_msg : Type ;
    do_msg_eq_dec : forall x y : do_msg, {x = y} + {x <> y} ;
    do_name_eq_dec : forall x y : do_name, {x = y} + {x <> y} ;
    file_name_eq_dec : forall x y : file_name, {x = y} + {x <> y} ;
    do_nodes : list do_name ;
    do_all_names_nodes : forall n, In n do_nodes ;
    do_no_dup_nodes : NoDup do_nodes ;
    do_net_handlers : do_name -> do_name -> do_msg -> data ->
                      list (disk_op file_name) * (list output) * data * list (do_name * do_msg) ;
    do_input_handlers : do_name -> input -> data ->
                        list (disk_op file_name) * (list output) * data * list (do_name * do_msg);
  }.Class DiskOpMultiParams (P : BaseParams) :=
  {
    do_name : Type ;
    file_name : Type ;
    do_msg : Type ;
    do_msg_eq_dec : forall x y : do_msg, {x = y} + {x <> y} ;
    do_name_eq_dec : forall x y : do_name, {x = y} + {x <> y} ;
    file_name_eq_dec : forall x y : file_name, {x = y} + {x <> y} ;
    do_nodes : list do_name ;
    do_all_names_nodes : forall n, In n do_nodes ;
    do_no_dup_nodes : NoDup do_nodes ;
    do_net_handlers : do_name -> do_name -> do_msg -> data ->
                      list (disk_op file_name) * (list output) * data * list (do_name * do_msg) ;
    do_input_handlers : do_name -> input -> data ->
                        list (disk_op file_name) * (list output) * data * list (do_name * do_msg);
  }.Class DiskOpMultiParams (P : BaseParams) :=
  {
    do_name : Type ;
    file_name : Type ;
    do_msg : Type ;
    do_msg_eq_dec : forall x y : do_msg, {x = y} + {x <> y} ;
    do_name_eq_dec : forall x y : do_name, {x = y} + {x <> y} ;
    file_name_eq_dec : forall x y : file_name, {x = y} + {x <> y} ;
    do_nodes : list do_name ;
    do_all_names_nodes : forall n, In n do_nodes ;
    do_no_dup_nodes : NoDup do_nodes ;
    do_net_handlers : do_name -> do_name -> do_msg -> data ->
                      list (disk_op file_name) * (list output) * data * list (do_name * do_msg) ;
    do_input_handlers : do_name -> input -> data ->
                        list (disk_op file_name) * (list output) * data * list (do_name * do_msg);
  }.Class DiskOpMultiParams (P : BaseParams) :=
  {
    do_name : Type ;
    file_name : Type ;
    do_msg : Type ;
    do_msg_eq_dec : forall x y : do_msg, {x = y} + {x <> y} ;
    do_name_eq_dec : forall x y : do_name, {x = y} + {x <> y} ;
    file_name_eq_dec : forall x y : file_name, {x = y} + {x <> y} ;
    do_nodes : list do_name ;
    do_all_names_nodes : forall n, In n do_nodes ;
    do_no_dup_nodes : NoDup do_nodes ;
    do_net_handlers : do_name -> do_name -> do_msg -> data ->
                      list (disk_op file_name) * (list output) * data * list (do_name * do_msg) ;
    do_input_handlers : do_name -> input -> data ->
                        list (disk_op file_name) * (list output) * data * list (do_name * do_msg);
  }.Class DiskOpMultiParams (P : BaseParams) :=
  {
    do_name : Type ;
    file_name : Type ;
    do_msg : Type ;
    do_msg_eq_dec : forall x y : do_msg, {x = y} + {x <> y} ;
    do_name_eq_dec : forall x y : do_name, {x = y} + {x <> y} ;
    file_name_eq_dec : forall x y : file_name, {x = y} + {x <> y} ;
    do_nodes : list do_name ;
    do_all_names_nodes : forall n, In n do_nodes ;
    do_no_dup_nodes : NoDup do_nodes ;
    do_net_handlers : do_name -> do_name -> do_msg -> data ->
                      list (disk_op file_name) * (list output) * data * list (do_name * do_msg) ;
    do_input_handlers : do_name -> input -> data ->
                        list (disk_op file_name) * (list output) * data * list (do_name * do_msg);
  }.Class DiskOpMultiParams (P : BaseParams) :=
  {
    do_name : Type ;
    file_name : Type ;
    do_msg : Type ;
    do_msg_eq_dec : forall x y : do_msg, {x = y} + {x <> y} ;
    do_name_eq_dec : forall x y : do_name, {x = y} + {x <> y} ;
    file_name_eq_dec : forall x y : file_name, {x = y} + {x <> y} ;
    do_nodes : list do_name ;
    do_all_names_nodes : forall n, In n do_nodes ;
    do_no_dup_nodes : NoDup do_nodes ;
    do_net_handlers : do_name -> do_name -> do_msg -> data ->
                      list (disk_op file_name) * (list output) * data * list (do_name * do_msg) ;
    do_input_handlers : do_name -> input -> data ->
                        list (disk_op file_name) * (list output) * data * list (do_name * do_msg);
  }.Class DiskOpMultiParams (P : BaseParams) :=
  {
    do_name : Type ;
    file_name : Type ;
    do_msg : Type ;
    do_msg_eq_dec : forall x y : do_msg, {x = y} + {x <> y} ;
    do_name_eq_dec : forall x y : do_name, {x = y} + {x <> y} ;
    file_name_eq_dec : forall x y : file_name, {x = y} + {x <> y} ;
    do_nodes : list do_name ;
    do_all_names_nodes : forall n, In n do_nodes ;
    do_no_dup_nodes : NoDup do_nodes ;
    do_net_handlers : do_name -> do_name -> do_msg -> data ->
                      list (disk_op file_name) * (list output) * data * list (do_name * do_msg) ;
    do_input_handlers : do_name -> input -> data ->
                        list (disk_op file_name) * (list output) * data * list (do_name * do_msg);
  }.Class DiskOpMultiParams (P : BaseParams) :=
  {
    do_name : Type ;
    file_name : Type ;
    do_msg : Type ;
    do_msg_eq_dec : forall x y : do_msg, {x = y} + {x <> y} ;
    do_name_eq_dec : forall x y : do_name, {x = y} + {x <> y} ;
    file_name_eq_dec : forall x y : file_name, {x = y} + {x <> y} ;
    do_nodes : list do_name ;
    do_all_names_nodes : forall n, In n do_nodes ;
    do_no_dup_nodes : NoDup do_nodes ;
    do_net_handlers : do_name -> do_name -> do_msg -> data ->
                      list (disk_op file_name) * (list output) * data * list (do_name * do_msg) ;
    do_input_handlers : do_name -> input -> data ->
                        list (disk_op file_name) * (list output) * data * list (do_name * do_msg);
  }.Class DiskOpMultiParams (P : BaseParams) :=
  {
    do_name : Type ;
    file_name : Type ;
    do_msg : Type ;
    do_msg_eq_dec : forall x y : do_msg, {x = y} + {x <> y} ;
    do_name_eq_dec : forall x y : do_name, {x = y} + {x <> y} ;
    file_name_eq_dec : forall x y : file_name, {x = y} + {x <> y} ;
    do_nodes : list do_name ;
    do_all_names_nodes : forall n, In n do_nodes ;
    do_no_dup_nodes : NoDup do_nodes ;
    do_net_handlers : do_name -> do_name -> do_msg -> data ->
                      list (disk_op file_name) * (list output) * data * list (do_name * do_msg) ;
    do_input_handlers : do_name -> input -> data ->
                        list (disk_op file_name) * (list output) * data * list (do_name * do_msg);
  }.Class DiskOpFailureParams `(P : DiskOpMultiParams) :=
  {
    do_reboot : do_name -> (file_name -> option IOStreamWriter.in_channel) ->
                data * list (disk_op file_name)
  }.Class DiskOpFailureParams `(P : DiskOpMultiParams) :=
  {
    do_reboot : do_name -> (file_name -> option IOStreamWriter.in_channel) ->
                data * list (disk_op file_name)
  }.Class NameOverlayParams `(P : MultiParams) :=
  {
    adjacent_to : relation name ;
    adjacent_to_dec : forall x y : name, {adjacent_to x y} + {~ adjacent_to x y} ;
    adjacent_to_symmetric : Symmetric adjacent_to ;
    adjacent_to_irreflexive : Irreflexive adjacent_to
  }.Class NameOverlayParams `(P : MultiParams) :=
  {
    adjacent_to : relation name ;
    adjacent_to_dec : forall x y : name, {adjacent_to x y} + {~ adjacent_to x y} ;
    adjacent_to_symmetric : Symmetric adjacent_to ;
    adjacent_to_irreflexive : Irreflexive adjacent_to
  }.Class NameOverlayParams `(P : MultiParams) :=
  {
    adjacent_to : relation name ;
    adjacent_to_dec : forall x y : name, {adjacent_to x y} + {~ adjacent_to x y} ;
    adjacent_to_symmetric : Symmetric adjacent_to ;
    adjacent_to_irreflexive : Irreflexive adjacent_to
  }.Class NameOverlayParams `(P : MultiParams) :=
  {
    adjacent_to : relation name ;
    adjacent_to_dec : forall x y : name, {adjacent_to x y} + {~ adjacent_to x y} ;
    adjacent_to_symmetric : Symmetric adjacent_to ;
    adjacent_to_irreflexive : Irreflexive adjacent_to
  }.Class NameOverlayParams `(P : MultiParams) :=
  {
    adjacent_to : relation name ;
    adjacent_to_dec : forall x y : name, {adjacent_to x y} + {~ adjacent_to x y} ;
    adjacent_to_symmetric : Symmetric adjacent_to ;
    adjacent_to_irreflexive : Irreflexive adjacent_to
  }.Class FailMsgParams `(P : MultiParams) :=
  {
    msg_fail : msg
  }.Class FailMsgParams `(P : MultiParams) :=
  {
    msg_fail : msg
  }.Class NewMsgParams `(P : MultiParams) :=
  {
    msg_new : msg
  }.Class NewMsgParams `(P : MultiParams) :=
  {
    msg_new : msg
  }.Definition step_relation := A -> A -> list trace -> Prop.Inductive refl_trans_1n_trace (step : step_relation) : step_relation :=
  | RT1nTBase : forall x, refl_trans_1n_trace step x x []
  | RT1nTStep : forall x x' x'' cs cs',
                   step x x' cs ->
                   refl_trans_1n_trace step x' x'' cs' ->
                   refl_trans_1n_trace step x x'' (cs ++ cs').Inductive refl_trans_1n_trace (step : step_relation) : step_relation :=
  | RT1nTBase : forall x, refl_trans_1n_trace step x x []
  | RT1nTStep : forall x x' x'' cs cs',
                   step x x' cs ->
                   refl_trans_1n_trace step x' x'' cs' ->
                   refl_trans_1n_trace step x x'' (cs ++ cs').Inductive refl_trans_1n_trace (step : step_relation) : step_relation :=
  | RT1nTBase : forall x, refl_trans_1n_trace step x x []
  | RT1nTStep : forall x x' x'' cs cs',
                   step x x' cs ->
                   refl_trans_1n_trace step x' x'' cs' ->
                   refl_trans_1n_trace step x x'' (cs ++ cs').

Theorem refl_trans_1n_trace_trans : forall step (a b c : A) (os os' : list trace), refl_trans_1n_trace step a b os -> refl_trans_1n_trace step b c os' -> refl_trans_1n_trace step a c (os ++ os').