% Demonstrate how to
% - send messages to self including
%      inform and queryref;
% - write and use reaction rules
%      to intercept incoming messages based on patterns.
% - use rcvMult to intercept multiple messages inside a rule body (inline)
% - use 'cut' in reaction rules

:- eval(test037()).

parent(cell,intracellular).

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

	% Update the mental state by way of a message 'inform'
	% Note: one extra "parent" record will be added
	sendMsg(XID1,self,Me,inform,parent(cellular_component,cell)),

	% Send a queryref message with replies to be sent back to the agent
	sendMsg(XID2,self,Me,queryref,parent(X,Y),id0),
	rcvMult(XID2,self,Me,reply,parent(X,Y),id0),
	println(["Inline reaction ",rcvMult(XID2,self,Me,reply,parent(X,Y),id0)]).

% Reaction to inform
rcvMsg(XID,Protocol,From,inform,[X|Xs]) :-
	println(["Rule reaction ",rcvMsg(XID,Protocol,From,inform,[X|Xs])]),
	retractall([X|Xs]),
	assert([X|Xs]).

% 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),
	!.
rcvMsg(XID,Protocol,From,queryref,[X|Xs]|LocalContext) :-
	println(["This is never printed because of the cut in the rule above!"]).
