read the README.txt file, and run the various examples which it describes.jpl/examples/
If you see some plausible output, with no serious error messages, then all may be well.
Type the following in a text editor and save the result in a file called test.pl
child_of(joe, ralf).You may wish to load this database into an interactive Prolog session to experiment with the predicates in this database before experimenting with JPL.
child_of(mary, joe).
child_of(steve, joe).descendent_of(X, Y) :-
child_of(X, Y).
descendent_of(X, Y) :-
child_of(Z, Y),
descendent_of(X, Z).
First we construct an instance of jpl.Query, whose name is consult and whose arguments (just one) comprise the atom 'test.pl':
Query q1 =Then we call the query() method of this Query object, which returns a Boolean value indicating its success:
new Query(
"consult",
new Term[] {new Atom("test.pl")}
);
System.out.println( "consult " + (q1.query() ? "succeeded" : "failed"));At this point, this process may seem a bit long-winded; however, you should soon see that the classes are sufficiently general that they provide a robust and powerful interface into the Prolog engine. There is also considerable scope for writing "convenience" classes and methods, but in this introduction we deliberately employ the general, primitive facilities of the JPL 2.x Java API overview.
Query q2 =To take an example that requires a bit more work on the part of the Prolog engine, on the other hand, we can ask whether descendent_of(steve,ralf) is true:
new Query(
"child_of",
new Term[] {new Atom("joe"),new Atom("ralf")}
);System.out.println(
"child_of(joe,ralf) is " +
( q2.query() ? "provable" : "not provable" )
);
Query q3 =
new Query(
"descendent_of",
new Term[] {new Atom("steve"),new Atom("ralf")}
);System.out.println(
"descendent_of(joe,ralf) is " +
( q3.query() ? "provable" : "not provable" )
);
Using the jpl.Variable class, we can construct a non ground query; and using other methods of Query we can obtain a solution in the form of a java.util.Hashtable. If the Query has one or more solutions, then its Query.oneSolution() method returns a Hashtable representing the first solution, otherwise it returns null:
Variable X = new Variable();The HashTable contains bindings in the form of Terms, each of which is indexed by its corresponding Variable in the Query.Query q4 =
new Query(
"descendent_of",
new Term[] {X,new Atom("ralf")}
);java.util.Hashtable solution;
solution = q4.oneSolution();
System.out.println( "first solution of descendent_of(X, ralf)");
System.out.println( "X = " + solution.get(X));
In this example we reuse the query q4, which was reset to its initial state by the call of oneSolution(), and instead call allSolutions(), which returns an array of solutions:
java.util.Hashtable[] solutions = q4.allSolutions();Equivalently, one can obtain each solution by exploiting the Enumeration interface, which the Query class implements. In this example, we iteratively call hasMoreSolutions() and nextSolution() to exhaustion:for ( int i=0 ; i<solutions.length ; i++ ) {
System.out.println( "X = " + solutions[i].get(X));
}
In this final example, we reuse the previous variable X with a new variable Y in a new query q5:System.out.println( "each solution of descendent_of(X, ralf)");while ( q4.hasMoreSolutions() ){
solution = q4.nextSolution();
System.out.println( "X = " + solution.get(X));
}
Variable Y = new Variable();The hasMoreSolutions method of the Query class returns a boolean, indicating whether there are any solutions "left" in the query. If the answer to this is 'yes', then the solution can be obtained in the form of a Hashtable by the nextSolution method.Query q5 =
new Query(
"descendent_of",
new Term[] {X,Y}
);while ( q5.hasMoreSolutions() ){
solution = q5.nextSolution();
System.out.println( "X = " + solution.get(X) + ", Y = " + solution.get(Y));
}
Note. By calling hasMoreSolutions you are actually making the query to the Prolog engine; the "answer" to the query is cached in the Query class instance and returned from nextSolution.