Section TotalMapExecutionSimulations.
Context {base_fst : BaseParams}.
Context {base_snd : BaseParams}.
Context {labeled_multi_fst : LabeledMultiParams base_fst}.
Context {labeled_multi_snd : LabeledMultiParams base_snd}.
Context {base_map : BaseParamsTotalMap base_fst base_snd}.
Context {name_map : MultiParamsNameTotalMap (@unlabeled_multi_params _ labeled_multi_fst) (@unlabeled_multi_params _ labeled_multi_snd)}.
Context {msg_map : MultiParamsMsgTotalMap (@unlabeled_multi_params _ labeled_multi_fst) (@unlabeled_multi_params _ labeled_multi_snd)}.
Context {label_map : LabeledMultiParamsLabelTotalMap labeled_multi_fst labeled_multi_snd}.
Context {name_map_bijective : MultiParamsNameTotalMapBijective name_map}.
Context {multi_map_congr : MultiParamsTotalMapCongruency base_map name_map msg_map}.
Context {multi_map_lb_congr : LabeledMultiParamsTotalMapCongruency base_map name_map msg_map label_map}.
Hypothesis tot_map_label_injective :
forall l l', tot_map_label l = tot_map_label l' -> l = l'.
(* lb_step_failure *)
Proof using name_map_bijective multi_map_lb_congr multi_map_congr.
move => net net' failed failed' lb tr H_step.
invcs H_step => //=.
- have ->: tot_map_name (pDst p) = pDst (tot_map_packet p) by destruct p.
apply: (@LabeledStepFailure_deliver _ _ _ _ _ _ (List.map tot_map_packet xs) (List.map tot_map_packet ys) (List.map tot_map_output out) (tot_map_data d) (@tot_map_name_msgs _ _ _ _ _ msg_map l)).
* rewrite /tot_map_net /=.
find_rewrite.
by rewrite map_app.
* destruct p.
simpl in *.
exact: not_in_failed_not_in.
* destruct p.
simpl in *.
rewrite tot_map_name_inv_inverse.
have H_q := @tot_net_handlers_eq _ _ _ _ _ _ _ multi_map_congr pDst pSrc pBody (nwState net pDst).
rewrite /tot_mapped_net_handlers /net_handlers /= /unlabeled_net_handlers in H_q.
repeat break_let.
repeat tuple_inversion.
have H_q' := @tot_lb_net_handlers_eq _ _ _ _ _ _ _ _ multi_map_lb_congr _ _ _ _ _ _ _ _ Heqp1.
rewrite /tot_mapped_lb_net_handlers_label in H_q'.
repeat break_let.
by repeat tuple_inversion.
* rewrite /tot_map_net /= 2!map_app -(@tot_map_update_packet_eq _ _ _ _ _ _ _ name_map_bijective).
destruct p.
by rewrite tot_map_packet_map_eq.
- apply: (@LabeledStepFailure_input _ _ _ _ _ _ _ _ (tot_map_data d) (tot_map_name_msgs l)).
* exact: not_in_failed_not_in.
* rewrite /tot_map_net /= tot_map_name_inv_inverse.
have H_q := @tot_input_handlers_eq _ _ _ _ _ _ _ multi_map_congr h inp (nwState net h).
rewrite /tot_mapped_input_handlers /= /unlabeled_input_handlers in H_q.
repeat break_let.
repeat tuple_inversion.
have H_q' := @tot_lb_input_handlers_eq _ _ _ _ _ _ _ _ multi_map_lb_congr _ _ _ _ _ _ _ Heqp1.
rewrite /tot_mapped_lb_input_handlers_label in H_q'.
repeat break_let.
by repeat tuple_inversion.
* by rewrite /tot_map_net /= map_app tot_map_packet_map_eq -(@tot_map_update_eq _ _ _ _ _ _ name_map_bijective).
- rewrite tot_lb_label_silent_fst_snd.
exact: LabeledStepFailure_stutter.
Qed.
Definition tot_map_net_event e :=
{| evt_a := (List.map tot_map_name (fst e.(evt_a)), tot_map_net (snd e.(evt_a))) ;
evt_l := tot_map_label e.(evt_l) ;
evt_trace := List.map tot_map_trace_occ e.(evt_trace) |}.
Proof using.
by move => s; rewrite -map_Cons /= -{3}(recons s).
Qed.
Proof using name_map_bijective multi_map_lb_congr multi_map_congr.
cofix c.
move => s H_exec.
rewrite -tot_map_net_event_map_unfold {1}/tot_map_net_event /=.
inversion H_exec; subst => /=.
rewrite -tot_map_net_event_map_unfold /= /tot_map_net_event /=.
apply: (@Cons_lb_step_exec _ _ _ _ _ _ (List.map tot_map_trace_occ tr)) => /=.
- apply: lb_step_failure_tot_mapped_simulation_1.
have <-: evt_a e = (fst (evt_a e), snd (evt_a e)) by destruct e, evt_a.
by have <-: evt_a e' = (fst (evt_a e'), snd (evt_a e')) by destruct e', evt_a.
- simpl in *.
find_rewrite.
by rewrite map_app.
- set e0 := {| evt_a := _ ; evt_l := _ ; evt_trace := _ |}.
have ->: e0 = tot_map_net_event e' by [].
pose s' := Cons e' s0.
rewrite (tot_map_net_event_map_unfold s').
exact: c.
Qed.
Proof using.
move => l.
apply: always_map.
apply: eventually_map.
case => e s.
rewrite /= /occurred /=.
move => H_eq.
by rewrite H_eq.
Qed.
Proof using tot_map_label_injective.
move => l.
apply: always_map_conv.
apply: eventually_map_conv => //.
- rewrite /extensional /=.
case => e s1.
case => e' s2.
move => H_eq.
by inversion H_eq; subst_max.
- rewrite /extensional /=.
case => e s1.
case => e' s2.
move => H_eq.
by inversion H_eq; subst_max.
- case => e s.
rewrite /= /occurred /=.
move => H_eq.
exact: tot_map_label_injective.
Qed.
Context {fail_fst : FailureParams (@unlabeled_multi_params _ labeled_multi_fst)}.
Context {fail_snd : FailureParams (@unlabeled_multi_params _ labeled_multi_snd)}.
Context {fail_map_congr : FailureParamsTotalMapCongruency fail_fst fail_snd base_map}.
Proof using name_map_bijective multi_map_lb_congr multi_map_congr fail_map_congr.
case => e s H_star H_exec.
apply: step_failure_star_lb_step_execution.
rewrite /=.
rewrite /tot_map_net_event /= /event_step_star /=.
apply: step_failure_tot_mapped_simulation_star_1.
by have <-: evt_a e = (fst (evt_a e), snd (evt_a e)) by destruct e, evt_a.
exact: lb_step_trace_execution_lb_step_failure_tot_map_net_infseq.
Qed.
(* lb_step_ordered_failure *)

Theorem lb_step_ordered_failure_tot_mapped_simulation_1 :
forall net net' failed failed' lb tr,
@lb_step_ordered_failure _ labeled_multi_fst (failed, net) lb (failed', net') tr ->
@lb_step_ordered_failure _ labeled_multi_snd (List.map tot_map_name failed, tot_map_onet net) (tot_map_label lb) (List.map tot_map_name failed', tot_map_onet net') (List.map tot_map_trace tr).