% Demonstrate how
% - nested rcvMult should use different conversation-id(s)
% - to use shutdown predicate to intercept program termination
%   (try running this with "prova ex004.prova -t -1" and press Ctrl-C
%    when the message exchange is complete.)
%   Shutdown can be used to send messages to inform about the agent's death
%      or to release resources.

:- eval(ex004()).

% Shutdown procedure
shutdown() :-
	println(["Shutdown complete."]).

a(1).
a(2).

b(3).
b(4).

% Send out messages
ex004() :-
	println(["==========ex004=========="]),
	iam(Me),

	sendMsg(XID1,self,Me,queryref,a(I)),
	rcvMult(XID1,self,Me,reply,a(I)),
	println(["Inline reaction ",rcvMult(XID1,self,Me,reply,a(I))]),

	sendMsg(XID2,self,Me,queryref,b(J)),
	rcvMult(XID2,self,Me,reply,b(J)),
	println(["Inline reaction ",rcvMult(XID2,self,Me,reply,b(J))]).

% Reaction rule to general queryref
rcvMsg(XID,Protocol,From,queryref,[X|Xs]|LocalContext) :-
	println(["Rule reaction 1 ",rcvMsg(XID,Protocol,From,queryref,[X|Xs]|LocalContext)]),
	derive([X|Xs]),
	sendMsg(XID,Protocol,From,reply,[X|Xs]|LocalContext).
rcvMsg(XID,Protocol,From,queryref,[X|Xs]|LocalContext) :-
	println(["Rule reaction 2 ",rcvMsg(XID,Protocol,From,queryref,[X|Xs]|LocalContext)]),
	sendMsg(XID,Protocol,From,end_of_transmission,[X|Xs]|LocalContext).

% A testing harness for printing incoming end_of_transmission messages.
rcvMsg(XID,Protocol,From,end_of_transmission|Extra) :-
	println(["end_of_transmission for conversation-id ",XID,": "|Extra]).
