Declarativa

## InterProlog Frequently Asked Questions

1. How can I try/port my Prolog program ?
2. How can I visualize Prolog structures ?
3. How can I make a Java program that calls Prolog ?
4. How can I return a list from Prolog to Java ?
5. Why do I get a nullPointerException on startup ?
6. How do I get a full object specification as a javaMessage result, instead of just an object reference ?
7. PrologEngine has only deterministicGoal methods, how do you call goals with multiple solutions ?
8. How to pass a custom object structure from Prolog to/from Java ?
9. Why do I get an IllegalAccessException when using javaMessage ?
10. Why can't I obtain instance variables in Prolog for an object returned by javaMessage ?
11. Where should I put a Prolog file that my Java app uses?
12. Can I build Applets with InterProlog ?
13. How do I change and recompile InterProlog ?
14. How do I know from Java which Prolog is being used by a PrologEngine?
15. Is technical support and project guidance available?

For comments/additions to this FAQ please email interprolog@declarativa.com

### How can I try/port my Prolog program ?

Just run one of the Prolog listener windows, either with runSubprocessListener.bat or runNativeListener.bat, consult your files and call your goals as you would in a shell console. Both invoke the same XSB Prolog installed in your machine.

The first uses a SubprocessEngine, which redirects Prolog I/O to the listener window, so using it feels just like using Prolog's regular top level interpreter in a standard shell console, tracer and all, except that you get the ability to use javaMessage, such as for visualization. SubprocessEngine may be useful for development.

The second uses a NativeEngine invoked by deterministicGoal, so you only get the first solution to your goals; Prolog I/O is performed in the Java console, and Prolog's regular top level interpreter is not used. NativeEngine is what you want to use for Java applications.

##### Back to Top

### How can I visualize Prolog structures ?

Call from a Prolog listener window:

- browseTerm(Term) to display a term as a tree
- browseList(List) to display a list
- browseLiteralInstances(GroundTerm,Instances) to display a table
- browseTreeTerm(T) to display a tree in a hierarchical multi-list browser

Take a look at their implementation in the com.declarativa.interprolog.gui package, and in the associated Prolog file visualize.P, and develop your own Swing models based on objects specified by Prolog.

##### Back to Top

### How can I make a Java program that calls Prolog ?

To develop a Java application using InterProlog you must import the relevant class packages, typically com.declarativa.interprolog and com.xsb.interprolog, and include interprolog.jar in your CLASSPATH. The other packages are needed only if you use them :) Take a look at com/declarativa/interprolog/gui/ListenerWindow.java for inspiration.

Here's a simple "hello world" Java program that uses Prolog, already included in the InterProlog examples package:

`package com.declarativa.interprolog.examples;
import com.declarativa.interprolog.*;
import com.xsb.interprolog.*;
public class HelloWorld{
public static void main(String args[]) {
PrologEngine engine = new NativeEngine(args[0]);
engine.command("import append/3 from basics");
Object[] bindings = engine.deterministicGoal(
"name(User,UL),append(\"Hello,\", UL, ML), name(Message,ML)",
"[string(User)]",
new Object[]{System.getProperty("user.name")},
"[string(Message)]");
String message = (String)bindings[0];
System.out.println("\nMessage:"+message);
// the above demonstrates object passing both ways;
// since we may simply concatenate strings, an alternative coding would be:
bindings = engine.deterministicGoal(
"name('"+System.getProperty("user.name")+"',UL),append(\"Hello,\", UL, ML), name(Message,ML)",
"[string(Message)]");
// (notice the ' surrounding the user name, unnecessary in the first case)
System.out.println("Same:"+bindings[0]);
System.exit(0);
}
}`

You can run it with java -classpath interprolog.jar com.declarativa.interprolog.examples.HelloWorld YOUR_XSB_DIR. The same program will run using a SubprocessEngine by changing the 6th line and passing as argument YOUR_XSB_EXECUTABLE_PATH instead.

##### Back to Top

### How can I return a list from Prolog to Java?

It depends on how variant your list elements can be. Prolog imposes nearly no constraints on terms, but Java needs more structure.

The short answer to the question is: one can use the TermModel class, which is able to represent any Prolog term on the Java side, but putting the burden on Java to know about term structure. One can write something like:

`PrologEngine engine = ... ...
Object[] bindings = engine.deterministicGoal("..., buildTermModel(List,TM)","[TM]");
TermModel list = (TermModel)bindings[0];
System.out.println("Here is the result:"+list);
if (list.isList()) {
// Visit the list using getChild(0) (for head) and getChild(1) (for tail)
...
}`

(buildTermModel is a predicate that constructs a TermModel object specification for any given Prolog term.)

The longer answer involves "typing" the list elements. Suppose that the list contained just atoms, corresponding to String objects. One might write instead:

On the Prolog side:
`processList([],[]).
processList([A|L],[string(A)|LL]) :- atom(A), processList(L,LL).
% string(S) specifies a Java String object`

On the Java side:

`PrologEngine engine = ... ...
Object[] bindings = engine.deterministicGoal(
"..., processList(List,LL), ipObjectTemplate('ArrayOfString',AS,_,[LL],_)","[AS]");
String[] list = (String[])bindings[0];
System.out.println("Here is the list of Strings:");
for (int i=0;i<list.length;i++)
System.out.println(list[i]);`

For more complex list elements, e.g corresponding to instances of a. custom class, the class would need to be taught to the PrologEngine with teachMoreObjects, and a different ipObjectTemplate or ipObjectSpec goal would be used.

##### Back to Top

### Why do I get a nullPointerException on startup?

Perhaps because InterProlog assumes that its own Prolog files are in a jar file, and is unable to read them.

##### Back to Top

### How do I get a full object specification as a javaMessage result, instead of just an object reference ?

You need to use an extra javaMessage to obtain a full object specification; say your InvisibleObject is X and you want a specification for the referred object in S : ipPrologEngine(E), javaMessage(E,S,getRealJavaObject(X))

##### Back to Top

### PrologEngine has only deterministicGoal methods, how do you call goals with multiple solutions?

There's no "nonDeterministicGoal" in this version. But one can collect all solutions on the Prolog side at once and return them as a single list. For a simple implementation one might want to use a Java TermModel object to encapsulate the list. So on the Prolog side define:

`nonDeterministicGoal(InterestingVarsTerm,G,ListTM) :-
findall(InterestingVarsTerm,G,L), buildTermModel(L,ListTM).`

And on the Java side do something like (assuming you wanted to collect all solution bindings for mygoal(A,B)):

`String goal = "nonDeterministicGoal(A+B,mygoal(A,B),ListModel)";
// Notice that 'ListModel' is referred in both deterministicGoal arguments:
TermModel solutionVars = (TermModel)(engine.deterministicGoal(goal,"[ListModel]")[0]);
System.out.println("Solution bindings list:"+solutionVars);
...`

...and at this point one can use TermModel methods (or access its two public instance variables) to visit the list and gather bindings; at the atomic level this means collecting TermModel nodes, which will be either String or numeric type wrapper objects.

##### Back to Top

### How to pass a custom object structure from Prolog to/from Java?

Make the object class Serializable, teach it to the PrologEngine, use ipObjectSpec on the Prolog side, and use deterministicGoal Object[] arguments and/or return values. See BackEnd.java in com/declarativa/interprolog/examples

##### Back to Top

### Why do I get an IllegalAccessException when using javaMessage?

Make sure your class and the methods invoked by javaMessage are 'public'. Prolog->Java calls go through Java's Reflection mechanisms so all invoked classes/methods must be public, including constructors.

##### Back to Top

### Why can't I obtain instance variables in Prolog for an object returned by javaMessage?

When you create a Java object from the Prolog side, the message result on the Prolog side is always an InvisibleObject specifier, which encapsulates a compact reference to the Java object - just an integer, which is a key into an ObjectRegistry, an object kept by a PrologEngine. So the object variables are not returned to Prolog.

But if you send the InvisibleObject back to Java as a javaMessage argument it will automatically be converted into the real object just prior to invoking the Java method. And so in both directions communication involves a few bytes, rather than perhaps a few K of the fully serialized objec; if you want this, see here

##### Back to Top

### Where should I put a Prolog file that my Java app uses?

Place it in the same directory and jar file as the Java package more closely related to the file, and load it into the PrologEngine with consultFromPackage(filename,MyClass.class)

##### Back to Top

### Can I build Applets with InterProlog?

Not in general. InterProlog needs access beyond the security permissions of typical Java applet viewers such as web browsers. In principle it should be possible to sign an applet to enlarge its permissions, but anyway the Prolog system must be installed in the machine running the applet, which probably makes it less appealing.

However it is possible to write a simple Java server application running InterProlog and accepting connections from applets. Beware though that although PrologEngine handles deterministicGoals/javaMessages from multiple Java threads, their Prolog handling is sequential, so it is possible for a hanging goal (say, because it calls some Java method that blocks waiting for something that never comes) to hang others.

##### Back to Top

### How do I change and recompile InterProlog ?

To change/recompile InterProlog using Metrowerks Codewarrior for Java 5 or later on Windows, use the interprolog.mcp project file. But you will need to compile the *.P files manually, cf. compile_Ps scrip

To change/recompile InterProlog using Sun's reference Java Development Kit, use the build script, or derive your own make script from there

To change/recompile InterProlog using another IDE, check the steps in build.bat; in addition to Java class files, the *compiled versions* (filenames ending in .xwam or .O depending on XSB Prolog being 2.6 or earlier resp.) of interprolog.P and visualization.P (this only if you're using classes of pt.servisoft.interprolog.gui) must be up-to-date and placed in the jar, so that later they can be extracted by PrologEngine.

InterProlog is open source, so if you're ready to share your additions within the same licensing model feel free to contribute them to interprolog@declarativa.com

##### Back to Top

### How do I know from Java which Prolog system is being used by a PrologEngine?

Just test the class of its peer:

if (engine.getImplementationPeer() instanceof XSBPeer){
// XSB Prolog
}

##### Back to Top

### Is technical support and project guidance available ?

Yes. Simple technical support and project guidance questions are usually answered within a couple of days, and bugs tend to get fixed although slower. Faster or deeper support and development aid is available through Declarativa consulting, please contact interprolog@declarativa.com

##### Back to Top