Class MsgGhostMultiParams `(P : MultiParams) :=
  {
    ghost_msg : Type;
    ghost_msg_eq_dec : forall x y : ghost_msg, {x = y} + {x <> y} ;
    ghost_msg_default : ghost_msg ;
    write_ghost_msg :
      name -> data -> ghost_msg
  }.Class MsgGhostMultiParams `(P : MultiParams) :=
  {
    ghost_msg : Type;
    ghost_msg_eq_dec : forall x y : ghost_msg, {x = y} + {x <> y} ;
    ghost_msg_default : ghost_msg ;
    write_ghost_msg :
      name -> data -> ghost_msg
  }.Class MsgGhostMultiParams `(P : MultiParams) :=
  {
    ghost_msg : Type;
    ghost_msg_eq_dec : forall x y : ghost_msg, {x = y} + {x <> y} ;
    ghost_msg_default : ghost_msg ;
    write_ghost_msg :
      name -> data -> ghost_msg
  }.Class MsgGhostMultiParams `(P : MultiParams) :=
  {
    ghost_msg : Type;
    ghost_msg_eq_dec : forall x y : ghost_msg, {x = y} + {x <> y} ;
    ghost_msg_default : ghost_msg ;
    write_ghost_msg :
      name -> data -> ghost_msg
  }.Class MsgGhostMultiParams `(P : MultiParams) :=
  {
    ghost_msg : Type;
    ghost_msg_eq_dec : forall x y : ghost_msg, {x = y} + {x <> y} ;
    ghost_msg_default : ghost_msg ;
    write_ghost_msg :
      name -> data -> ghost_msg
  }.Definition add_ghost_msg (me : name) (st : data) (ps : list (name * msg)) :
                                                    list (name * (ghost_msg * msg)) :=
  map (fun m => (fst m, (write_ghost_msg me st, snd m))) ps.Definition mgv_refined_net_handlers me src (m : ghost_msg * msg) st :=
  let '(out, st', ps) := net_handlers me src (snd m) st in
  (out, st', add_ghost_msg me st' ps).Definition mgv_refined_input_handlers me inp st :=
  let '(out, st', ps) := input_handlers me inp st in
  (out, st', add_ghost_msg me st' ps).Definition mgv_msg_eq_dec :
  forall x y : ghost_msg * msg, {x = y} + {x <> y}.Instance mgv_refined_base_params : BaseParams :=
  {
    data := data ;
    input := input ;
    output := output
  }.Instance mgv_refined_multi_params : MultiParams _ :=
  {
    name := name ;
    msg := (ghost_msg * msg) ;
    msg_eq_dec := mgv_msg_eq_dec ;
    name_eq_dec := name_eq_dec ;
    nodes := nodes ;
    all_names_nodes := all_names_nodes ;
    no_dup_nodes := no_dup_nodes ;
    init_handlers := init_handlers;
    net_handlers := mgv_refined_net_handlers ;
    input_handlers := mgv_refined_input_handlers
  }.Instance mgv_refined_failure_params : FailureParams _ :=
  {
    reboot := (@reboot base_params multi_params failure_params)
  }.Definition mgv_deghost_packet p :=
  @mkPacket _ multi_params
            (@pSrc _ mgv_refined_multi_params p)
            (pDst p)
            (snd (pBody p)).Definition mgv_deghost (net : @network _ mgv_refined_multi_params) : (@network _ multi_params).Instance mgv_refined_base_params_tot_map :
 BaseParamsTotalMap mgv_refined_base_params base_params :=
  {
    tot_map_data := id ;
    tot_map_input := id ;
    tot_map_output := id
  }.Instance mgv_refined_multi_params_name_tot_map :
 MultiParamsNameTotalMap mgv_refined_multi_params multi_params :=
  {
    tot_map_name := id ;
    tot_map_name_inv := id ;
  }.Instance mgv_refined_multi_params_name_tot_map_bijective :
 MultiParamsNameTotalMapBijective mgv_refined_multi_params_name_tot_map :=
  {
    tot_map_name_inv_inverse := fun _ => eq_refl ;
    tot_map_name_inverse_inv := fun _ => eq_refl
  }.Instance mgv_refined_multi_params_tot_map :
 MultiParamsMsgTotalMap mgv_refined_multi_params multi_params :=
  {
    tot_map_msg := snd ;
  }.Program Instance mgv_refined_multi_params_map_congruency :
 MultiParamsTotalMapCongruency mgv_refined_base_params_tot_map
  mgv_refined_multi_params_name_tot_map mgv_refined_multi_params_tot_map :=
  {
    tot_init_handlers_eq := fun _ => eq_refl ;
    tot_net_handlers_eq := _ ;
    tot_input_handlers_eq := _
  }.Instance mgv_refined_failure_params_map_congruency :
 FailureParamsTotalMapCongruency mgv_refined_failure_params
  failure_params mgv_refined_base_params_tot_map :=
  {
    tot_reboot_eq := fun _ => eq_refl
  }.

(* Specifications: *)
Lemma mgv_map_id_tr : forall out, map (fun e : name * (input + list output) => let (n, s) := e in match s with | inl io => (n, inl io) | inr lo => (n, inr (map id lo)) end) out = out.
Theorem mgv_ghost_simulation_1 : forall net net' failed failed' out, @step_failure _ _ mgv_refined_failure_params (failed, net) (failed', net') out -> @step_failure _ _ failure_params (failed, mgv_deghost net) (failed', mgv_deghost net') out.