send(1,m1), send(2,m2), send(3,m3), send(4,m4).
nextSend(1).  nextRec(1).  dataReceived(nil).
limit, limit, limit.

SendPacket@@
send(N,D), nextSend(N2), limit :-
   N=:=N2, unary(D) |
   a(N,D), send(N,D), nextSend(N).

TransmitPacket1@@
a(N,D) :- b(N,D).
TransmitPacket2@@
a(N,D) :- int(N), unary(D) | limit.

ReceivePacket1@@
b(N,D), dataReceived(L), nextRec(K) :-
   N=:=K, K1=K+1 |
   c(K1), nextRec(K1), dataReceived(L+D).
ReceivePacket2@@
b(N,D), dataReceived(L), nextRec(K) :-
   N=\=K, unary(D) |
   c(K), nextRec(K), dataReceived(L).

TransmitAck1@@
c(N) :- d(N).
TransmitAck2@@
c(N) :- int(N) | limit.

ReceiveAck@@
d(N), nextSend(K) :- int(K) | nextSend(N), limit.