Require Export Verdi.VerdiHints.
Set Implicit Arguments.
Class BaseParams :=
{
data : Type;
input : Type;
output : Type
}.
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 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
}.
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.
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 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 NewMsgParams `(P : MultiParams) :=
{
msg_new : msg
}.
Section StepRelations.
Variable A : Type.
Variable trace : Type.
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').

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