This is another multi threaded version of the train example
(see Train Example).
In this example, Prolog is the toplevel and Java is invoked via library(jasper).
// MultiSimple2.java
import se.sics.jasper.Jasper;
import se.sics.jasper.Query;
import se.sics.jasper.Prolog;
import se.sics.jasper.SICStus;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.ListIterator;
public class MultiSimple2
{
class Client extends Thread
{
Prolog jp;
SICStus sp;
String qs;
Client(Prolog p, SICStus s, String queryString)
{
jp = p;
sp = s;
qs = queryString;
}
public void run()
{
HashMap WayMap = new HashMap();
try {
synchronized(jp) {
Query query = jp.openPrologQuery(qs, WayMap);
try {
while (query.nextSolution()) {
System.out.println(WayMap);
}
} finally {
query.close();
}
}
} catch ( Exception e ) {
e.printStackTrace();
}
}
}
class Watcher extends Thread
{
SICStus mySp;
ArrayList threadList = new ArrayList(2);
public boolean add(Client cl)
{
return threadList.add((Object)cl);
}
boolean at_least_one_is_alive(ArrayList tl)
{
ListIterator li = tl.listIterator();
boolean f = false;
while (li.hasNext()) {
boolean alive = ((Client)(li.next())).isAlive();
f = f || alive;
}
return f;
}
public void run()
{
while (at_least_one_is_alive(threadList)) {
try {
this.sleep(1000);
} catch (InterruptedException ie) {
System.err.println("Watcher interrupted.");
}
}
mySp.stopServer();
}
Watcher(SICStus sp)
{
mySp = sp;
}
}
public void CallBack()
{
try {
SICStus sp = SICStus.getCaller(); // get the SICStus object
sp.load("train.ql");
Prolog jp = sp.newProlog(); // Create a new Prolog Interface
Client c1 =
new Client(jp, sp,
"connected('Örebro', 'Hallsberg', Way1, Way1).");
c1.start();
// The prolog variable names in the Map are different from above so
// we can tell which query gives what solution.
Client c2 =
new Client(jp, sp,
"connected('Stockholm', 'Hallsberg', Way2, Way2).");
c2.start();
Watcher w = new Watcher(sp);
w.add(c1);
w.add(c2);
w.start();
sp.startServer(); // And finally start the server. This
// method call does not return until
// some other thread calls sp.stopServer().
}
catch ( Exception e ) {
e.printStackTrace();
}
}
}
% multisimple2.pl
:- use_module(library(jasper)).
main:-
jasper_initialize(JVM),
jasper_new_object(JVM,
'MultiSimple2',
init,
init,
Obj),
jasper_call(JVM,
method('', 'CallBack', [instance]),
'CallBack'(+object('')),
'CallBack'(Obj)).
CallBack is called, we cannot use Jasper.newProlog to
obtain a Prolog interface. Instead we can use the SICStus
method getCaller to get a handle on the SICStus object.
restore method to load the
Prolog saved-state, since it unloads all foreign
resources. This includes library(jasper) from which the call to
Java was made. Instead the method SICStus.load can be used to
load a compiled Prolog file. See the HTML Jasper
documentation for details on this method. See ref-lod-lod for
how to create a ‘.ql’ file.
startServer
is to return. See the HTML Jasper documentation on the methods
SICStus.startServer and SICStus.stopServer.