Previous: Multi Threaded Example, Up: Calling Prolog from Java [Contents][Index]
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
.