Local Arguments update {_} {_} _ _ _ _ _ : simpl never.
Set Implicit Arguments.
Class BaseParamsPartialMap (P0 : BaseParams) (P1 : BaseParams) :=
{
pt_map_data : @data P0 -> @data P1 ;
pt_map_input : @input P0 -> option (@input P1) ;
pt_map_output : @output P0 -> option (@output P1)
}.
Class MultiParamsMsgPartialMap
(B0 : BaseParams) (B1 : BaseParams)
(P0 : MultiParams B0) (P1 : MultiParams B1) :=
{
pt_map_msg : @msg B0 P0 -> option (@msg B1 P1)
}.
Section PartialMapDefs.
Context {base_fst : BaseParams}.
Context {base_snd : BaseParams}.
Context {multi_fst : MultiParams base_fst}.
Context {multi_snd : MultiParams base_snd}.
Context {base_map : BaseParamsPartialMap base_fst base_snd}.
Context {name_map : MultiParamsNameTotalMap multi_fst multi_snd}.
Context {msg_map : MultiParamsMsgPartialMap multi_fst multi_snd}.
Definition pt_map_name_msg nm :=
match pt_map_msg (snd nm) with
| Some m => Some (tot_map_name (fst nm), m)
| None => None
end.
Definition pt_mapped_net_handlers me src m st :=
let '(out, st', ps) := net_handlers me src m st in
(filterMap pt_map_output out, pt_map_data st', filterMap pt_map_name_msg ps).
Definition pt_mapped_input_handlers me inp st :=
let '(out, st', ps) := input_handlers me inp st in
(filterMap pt_map_output out, pt_map_data st', filterMap pt_map_name_msg ps).
End PartialMapDefs.
Class MultiParamsPartialMapCongruency
(B0 : BaseParams) (B1 : BaseParams)
(P0 : MultiParams B0) (P1 : MultiParams B1)
(B : BaseParamsPartialMap B0 B1)
(N : MultiParamsNameTotalMap P0 P1)
(P : MultiParamsMsgPartialMap P0 P1) : Prop :=
{
pt_init_handlers_eq : forall n,
pt_map_data (init_handlers n) = init_handlers (tot_map_name n) ;
pt_net_handlers_some : forall me src m st m',
pt_map_msg m = Some m' ->
pt_mapped_net_handlers me src m st =
net_handlers (tot_map_name me) (tot_map_name src) m' (pt_map_data st) ;
pt_net_handlers_none : forall me src m st out st' ps,
pt_map_msg m = None ->
net_handlers me src m st = (out, st', ps) ->
pt_map_data st' = pt_map_data st /\
filterMap pt_map_name_msg ps = [] /\ filterMap pt_map_output out = [] ;
pt_input_handlers_some : forall me inp st inp',
pt_map_input inp = Some inp' ->
pt_mapped_input_handlers me inp st =
input_handlers (tot_map_name me) inp' (pt_map_data st) ;
pt_input_handlers_none : forall me inp st out st' ps,
pt_map_input inp = None ->
input_handlers me inp st = (out, st', ps) ->
pt_map_data st' = pt_map_data st /\
filterMap pt_map_name_msg ps = [] /\ filterMap pt_map_output out = []
}.
Class FailureParamsPartialMapCongruency
(B0 : BaseParams) (B1 : BaseParams)
(P0 : MultiParams B0) (P1 : MultiParams B1)
(F0 : FailureParams P0) (F1 : FailureParams P1)
(B : BaseParamsPartialMap B0 B1) : Prop :=
{
pt_reboot_eq : forall d, pt_map_data (reboot d) = reboot (pt_map_data d)
}.
Class FailMsgParamsPartialMapCongruency
(B0 : BaseParams) (B1 : BaseParams)
(P0 : MultiParams B0) (P1 : MultiParams B1)
(F0 : FailMsgParams P0) (F1 : FailMsgParams P1)
(P : MultiParamsMsgPartialMap P0 P1) : Prop :=
{
pt_fail_msg_fst_snd : pt_map_msg msg_fail = Some msg_fail
}.
Class NewMsgParamsPartialMapCongruency
(B0 : BaseParams) (B1 : BaseParams)
(P0 : MultiParams B0) (P1 : MultiParams B1)
(N0 : NewMsgParams P0) (N1 : NewMsgParams P1)
(P : MultiParamsMsgPartialMap P0 P1) : Prop :=
{
pt_new_msg_fst_snd : pt_map_msg msg_new = Some msg_new
}.
Section PartialMapSimulations.
Context {base_fst : BaseParams}.
Context {base_snd : BaseParams}.
Context {multi_fst : MultiParams base_fst}.
Context {multi_snd : MultiParams base_snd}.
Context {base_map : BaseParamsPartialMap base_fst base_snd}.
Context {name_map : MultiParamsNameTotalMap multi_fst multi_snd}.
Context {msg_map : MultiParamsMsgPartialMap multi_fst multi_snd}.
Context {name_map_bijective : MultiParamsNameTotalMapBijective name_map}.
Context {multi_map_congr : MultiParamsPartialMapCongruency base_map name_map msg_map}.
Definition pt_map_trace_occ (e : @name _ multi_fst * (@input base_fst + list (@output base_fst))) :
option (@name _ multi_snd * (@input base_snd + list (@output base_snd))) :=
match e with
| (n, inl io) =>
match pt_map_input io with
| Some io' => Some (tot_map_name n, inl io')
| None => None
end
| (n, inr out) => Some (tot_map_name n, inr (filterMap pt_map_output out))
end.
Definition pt_map_packet (p : @packet _ multi_fst)  :=
match p with
| mkPacket src dst m =>
match pt_map_msg m with
| Some m' => Some (mkPacket (tot_map_name src) (tot_map_name dst) m')
| None => None
end
end.
Definition pt_map_net (net : @network _ multi_fst) : @network _ multi_snd :=
{| nwPackets := filterMap pt_map_packet net.(nwPackets) ;
nwState := fun n => pt_map_data (net.(nwState) (tot_map_name_inv n)) |}.

Lemma pt_init_handlers_fun_eq :
init_handlers = fun n : name => pt_map_data (init_handlers (tot_map_name_inv n)).