8/26/2009

SWI-Prolog's Java Interface JPL

I would like to mix Java and Prolog code on a number of occasions. Together with a student of mine (Joachim Pehl), we just convinced ourselves that the JPL library of SWI-Prolog is really cool. Basically JPL allows you to call Prolog from Java and Java from Prolog.

But the question is, of course, how easy is it and can you easily go back and forth. For instance, can we call Prolog from Java and call back Java from Prolog and share Java state throughout? Sure it works!


PROLOG PORTION FOLLOWS


% This library is all we need to call Java from Prolog
:- ensure_loaded(library(jpl)).

main
:-
% Create an object
jpl_new(class([],['Test']), [], X),

% Printing objects is like printing object ids
write(X),nl,

% Access a field of the object; happens to be static
jpl_get(X, state, Y),

% Prints whatever the state's value is
write(Y),nl.


JAVA PORTION FOLLOWS


// This jar is all we need to call Prolog from Java
import jpl.*;

public class Test {

public static int state = 0;

public static void main(String[] args) {

// Consult a Prolog file
Query q1 = new Query("consult", new Term[] { new Atom("Test.pro") });

// Prints boolean success/failure value
System.out.println(q1.query());

// Affect static field.
// This way we can see whether Prolog sees the same JVM instance.
Test.state = 42;

// Invoke a predicate
Query q2 = new Query("main");

// Prints boolean success/failure value
System.out.println(q2.query());
}
}


BUILDING and RUNNING BOTH

javac -cp $CLASSPATH:/opt/local/lib/swipl-5.6.62/lib/jpl.jar:. Test.java
java -cp $CLASSPATH:/opt/local/lib/swipl-5.6.62/lib/jpl.jar:. -Djava.library.path="/opt/local/lib/swipl-5.6.62/lib/i386-darwin9.5.0" Test
true
@(J#00000000000016809476)
42
true


SO WHAT?

Hence, we can start a Java app, have it start a Prolog engine and consult the Prolog portion of our app, then delegate from Java to Prolog, where we in turn call back on Java in the same JVM and can access some state that we left off in Java before we were calling Prolog.

PF

3 comments:

  1. JPL is cool.

    What would be even cooler would be a standard API for java->prolog and prolog->java. This would allow for greater flexibilty in implementations. E.g. sometimes calling a prolog engine on a server over HTTP may be preferable to a local prolog engine.

    ReplyDelete
  2. Great!!
    How do I set up the jpl.jar library in eclipse 3.5.1.
    I am using SWI prolog 5.8 in Windows, and I guess it already comes with the JPL interface.
    When I run your above code it is giving me errors, can not recognise "import jpl.*;"
    Please can you share how to set it up in eclipse. Thank you.

    ReplyDelete
  3. hello, I'm trying for a university exam to make JPL work with SWI-Prolog but when I try to print the Query status (System.out.println(q.query() ? "ok" : "no") it returns strange errors:

    Problematic Frame: C [libjpl.so+0xbdd2f]

    The crash happened outside the Java Virtual Machine in native code. See problematic frame for where to report the bug.

    Could you please help me to solve it in some way? I'm working in Linux Ubuntu 9.10

    ReplyDelete