Proof using.
intros. unfold true_in_reachable, reachable in *.
intros. intuition.
- apply H; eexists; econstructor.
- apply H.
break_exists.
eexists. apply refl_trans_n1_1n_trace.
find_apply_lem_hyp refl_trans_1n_n1_trace.
econstructor; eauto.
Qed.
End StepRelations.
Section Step1.
Context `{params : OneNodeParams}.
Inductive step_1 : (step_relation data (input * output)) :=
| S1T_deliver : forall (i : input) s s' (out : output),
handler i s = (out, s') ->
step_1 s s' [(i, out)].
Definition step_1_star := refl_trans_1n_trace step_1.
End Step1.
Section StepSingle.
Context `{params : SingleParams}.
Inductive step_s : (step_relation data (input + output)) :=
| SST_deliver : forall i s s' out tr,
input_handler i s = (out, s') ->
tr = inl i :: map inr out ->
step_s s s' tr.
Definition step_s_star := refl_trans_1n_trace step_s.
End StepSingle.
Section StepAsync.
Context `{params : MultiParams}.
Record packet := mkPacket { pSrc  : name ;
pDst  : name ;
pBody : msg }.
Definition send_packets src ps := (map (fun m => mkPacket src (fst m) (snd m)) ps).
Definition packet_eq_dec (p q : packet) : {p = q} + {p <> q}.
decide equality; auto using name_eq_dec, msg_eq_dec.
Defined.
Record network := mkNetwork { nwPackets : list packet ;
nwState   : name -> data }.
Definition step_async_init : network :=
mkNetwork [] init_handlers.
Inductive step_async : step_relation network (name * (input + list output)) :=
| StepAsync_deliver : forall net net' p xs ys out d l,
nwPackets net = xs ++ p :: ys ->
net_handlers (pDst p) (pSrc p) (pBody p) (nwState net (pDst p)) = (out, d, l) ->
net' = mkNetwork (send_packets (pDst p) l ++ xs ++ ys)
(update name_eq_dec (nwState net) (pDst p) d) ->
step_async net net' [(pDst p, inr out)]
(* inject a message (f inp) into host h. analogous to step_1 *delivery* *)
| StepAsync_input : forall h net net' out inp d l,
input_handlers h inp (nwState net h) = (out, d, l) ->
net' = mkNetwork (send_packets h l ++ nwPackets net)
(update name_eq_dec (nwState net) h d) ->
step_async net net' [(h, inl inp); (h, inr out)].
Definition step_async_star := refl_trans_1n_trace step_async.
End StepAsync.
Arguments update _ _ _ _ _ _ / _.
Arguments send_packets _ _ _ _ /.
Section ParamsAux.
Context `{params : MultiParams}.

Lemma packet_eta :
forall p : packet,
{| pSrc := pSrc p; pDst := pDst p; pBody := pBody p |} = p.