Definition ack_in_flight_to_primary (l : list packet) : nat :=
length (filterMap
(fun p => if msg_eq_dec (pBody p) ack
then if name_eq_dec (pDst p) primary
then Some tt else None
else None)
l).

(* Specifications: *)
Lemma ack_in_flight_to_primary_app :
forall xs ys,
ack_in_flight_to_primary (xs ++ ys) = ack_in_flight_to_primary xs + ack_in_flight_to_primary ys.
Lemma ack_in_flight_to_primary_backup :
forall p,
pDst p = backup ->
ack_in_flight_to_primary [p] = 0.
Lemma InputHandler_trace_preserved :
forall h i d u o d' l,
InputHandler h i d = (u, o, d', l) ->
trace_inputs [(h, inl i)] =
trace_outputs [(h, inr o)] +
inc_in_flight_to_backup (send_packets h l) +
ack_in_flight_to_primary (send_packets h l).
Lemma NetHandler_trace_preserved :
forall p d u o d' l,
NetHandler (pDst p) (pBody p) d = (u, o, d', l) ->
inc_in_flight_to_backup [p] +
ack_in_flight_to_primary [p] =
trace_outputs [((pDst p), inr o)] +
inc_in_flight_to_backup (send_packets (pDst p) l) +
ack_in_flight_to_primary (send_packets (pDst p) l).
Lemma trace_inputs_output :
forall h os,
trace_inputs [(h, inr os)] = 0.
Lemma trace_outputs_input :
forall h i,
trace_outputs [(h, inl i)] = 0.
Lemma trace_outputs_backup :
forall e,
trace_outputs [(backup, e)] = 0.
Lemma inputs_eq_outputs_plus_inc_plus_ack :
forall net tr,
step_async_star (params := Counter_MultiParams) step_async_init net tr ->
trace_inputs tr = trace_outputs tr +
inc_in_flight_to_backup (nwPackets net) +
ack_in_flight_to_primary (nwPackets net).
Theorem inputs_ge_outputs :
forall net tr,
step_async_star (params := Counter_MultiParams) step_async_init net tr ->
trace_outputs tr <= trace_inputs tr.