bag_of_all_servant(
?Template,
+Goal,
-Bag)
If the servant is running
on a different physical processor than the master, then it is
desirable to be able to achieve some degree of parallelism, to have both
machines doing useful work at the same time.
This is not the case with
call_servant/1
, since the master Prolog process is waiting the entire
time that the servant process is computing. The predicate
bag_of_all_servant/3
is provided to allow a sophisticated user to write
some truly parallel applications. (See the demo program queensdemo
for an example of using parallelism in a search problem.)
Semantically bag_of_all_servant/3
is very similar to bagof/3
. The
reader should be familiar with the operation of bagof/3
before reading
further. The differences are:
bag_of_all_servant/3
requires that
there be no free variables in Goal that do not appear in
Template. If there are, bag_of_all_servant/3
will report an
error. You may use the existential operator (^
) as in bagof/3
.
bag_of_all_servant/3
succeeds with Bag bound to []
if Goal
has no answers at all. This means that bag_of_all_servant/3
always
succeeds and returns in Bag exactly one answer: the list of instances
of Template, one instance for each success of Goal.
The exact operation of bag_of_all_servant/3
depends on the form of
Goal. If Goal is a conjunction of the form
(
Goal1,
Goal2)
or a disjunction of the form
(
Goal1;
Goal2)
, then the first subgoal (Goal1) will be
executed by the servant, and the second subgoal (Goal2) will be
executed by the current process. The system will try to overlap local and
remote evaluation as much as possible. If Goal is neither a
conjunction nor a disjunction,
then the entire goal will be sent to the servant to be
executed.
There are several restrictions on how bag_of_all_servant/3
can be used.
call_servant/1
or bag_of_all_servant/3
.