When the master is a Prolog program, a very flexible interface is supported because the nondeterminacy of the two Prolog programs can be combined. Also, general Prolog data structures can be passed between the programs easily, since both programs support the same data types. Using this interface, a complex Prolog system can achieve significant parallel evaluation, by using a servant on another processor and communicating over a network. The routines described below allow a master to have only a single servant process. (They could be extended without much difficulty to support multiple servants and servants being masters of other servants, if that proves important.)
There are two sides to any interface: here we have the calling Prolog program (the master), and the called Prolog program (the servant). Each must perform certain functions that allow them to cooperate.
For a master to use a servant, the master must first create it. This is
done by starting a Prolog process that will be the servant. The system
creates that process by running a saved state previously created by
the programmer. After the servant has been created and is running, the
master may send it goals to evaluate using call_servant/1
and
bag_of_all_servant/3
. All goals sent to the servant are evaluated in
the database of the servant, which is disjoint from the database of the
master. This means that all programs that the servant will execute must
either already be in the saved state that was initially loaded, or a goal
must be sent to the servant telling it to compile (or consult) the
appropriate files. One could also use remote call to have the servant
evaluate an assert/1
.
For an example of using a Prolog servant from Prolog, see the IPC/RPC/demo
library directory (qplib('IPC/RPC/demo')
).
All the following predicates are defined in the module qpcallqp
. To
be able to use them, the master program must first load them by entering
the directive:
:- use_module(library(qpcallqp)).