Proof using.
intros.
apply ghost_simulation_2 with (gnet := reghost net) in H0.
- break_exists. intuition. subst.
eapply H; eauto.
rewrite reghost_deghost_partial_inverses.
auto.
- eauto using reghost_deghost_partial_inverses.
Qed.
End GhostVars.
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
}.
Section MsgGhostVars.
Context {base_params : BaseParams}.
Context {multi_params : MultiParams base_params}.
Context {failure_params : FailureParams multi_params}.
Context {msg_ghost_params : MsgGhostMultiParams multi_params}.
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}.
Proof using.
intros.
decide equality; auto using msg_eq_dec, ghost_msg_eq_dec.
Qed.
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).
refine (@mkNetwork _ multi_params
(map mgv_deghost_packet
(nwPackets net))
_
).
intros.
destruct net.
concludes.
auto.
Defined.
Arguments mgv_deghost_packet /_.
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 := _
}.
Next Obligation.
rewrite /tot_mapped_net_handlers /= /mgv_refined_net_handlers /= /tot_map_name_msgs /= /id /=.
repeat break_let.
find_inversion.
rewrite -/id map_id /= /add_ghost_msg /=.
elim l0 => //=.
case => n m' l IH.
find_inversion.
by find_rewrite; find_rewrite.
Qed.
Next Obligation.
rewrite /tot_mapped_input_handlers /=.
repeat break_let.
rewrite map_id /id /=.
unfold mgv_refined_input_handlers in *.
repeat break_let.
find_inversion.
elim l1 => //=.
case => n m l.
move => IH.
find_inversion.
by find_rewrite; find_rewrite.
Qed.
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
}.

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.