% Since Prova 2.0 RC2, March 10, 2008
% Demonstrate
%   - new concurrent processing of inbound messages sent with protocol "async";
%   - new "increment_value" built-in.
%
% Any message with protocol "async" gets processed by the thread pool in true concurrency.
% Note that the destination equal to 0 must be used to send self messages with protocol "async".
%
% The built-in "increment_value" takes a Predicate(Context,Key) as its argument.
% It assumes that numeric data is stored as values of a (Predicate,Key,Value) triples
% stored as Predicate(Context,Key,Value) for a given Context.
% The built-in can be safely used to modify the same record concurrently.

:- eval(async_001()).

score("Aberdeen v Kilmarnock","Aberdeen",1).
score("Aberdeen v Kilmarnock","Kilmarnock",2).

async_001() :-
	println(["==========async test 001=========="]),

	sendMsg(XID,async,0,score,["Aberdeen v Kilmarnock","Aberdeen"]),
	sendMsg(XID,async,0,score,["Aberdeen v Kilmarnock","Kilmarnock"]),
	sendMsg(XID,async,0,score,["Aberdeen v Kilmarnock","Kilmarnock"]).

on_event(score(Match,Team)) :-
	increment_value(score(Match,Team)),
	score(Match,Team),
	println(score(Match,Team)," > ").

% A testing harness catch-all reaction for printing all messages.
rcvMsg(XID,Protocol,From,Performative|Content) :-
	println([Performative|Content]).

rcvMsg(XID,Protocol,From,score,[Match,Team]) :-
	TH=Thread.currentThread(),
	println([TH]),
	on_event(score(Match,Team)).

% One of possible outputs:
% ==========async test 001==========
% score["Aberdeen v Kilmarnock","Aberdeen"]
% Thread[pool-2-thread-1,5,main]
% score["Aberdeen v Kilmarnock","Kilmarnock"]
% Thread[pool-2-thread-2,5,main]
% score > Aberdeen v Kilmarnock > Aberdeen > 2
% score > Aberdeen v Kilmarnock > Kilmarnock > 3
% score["Aberdeen v Kilmarnock","Kilmarnock"]
% Thread[pool-2-thread-3,5,main]
% score > Aberdeen v Kilmarnock > Kilmarnock > 4

