Call-in Employees Table

We first turn to an example where will show how we can call a non-deterministic Prolog predi-cate from a Java application. We want to call a predicate that will list some employees. Before we can invoke a Prolog predicate we must set up an interpreter with an associated knowledge base. The basic objects can be created as follows:

  Knowledgebase know = new Knowledgebase(ToolkitLibrary.DEFAULT);
  Interpreter inter = know.iterable();

The knowledge base will be initially blank. This means that the knowledge base will even not contain system predicates or system built-ins. The following interpreter method initializes the associated knowledge base accordingly. This is to initialize a base knowledge base and is only needed once if we were to work with multiple sub knowledge bases:

  Knowledgebase.initKnowledgebase(inter);

The employees will be stored as facts for a predicate employee/1. The predicate is stored in the file ‘intable.p’ in a folder ‘example01’:

  employee(bundy).
employee(canby).
employee(ozias).
employee(watson).

The Prolog API does not provide a method to consult the file. But we can construct a goal that will consult the file, and then invoke this goal. The easiest way to construct this goal is to use the parse method of the interpreter. We can first use the setProperty() method call to set the working directory so that a short relative file name suffices:

  inter.setProperty(ToolkitLibrary.PROP_BASE_URL, "<base>");
Object consultGoal = inter.parseTerm("consult('example01/tablein.p')");

Since the goal does not contain variables the parsing will not have any side effects which we would need to undo later. The goal can be invoked by obtaining an iterator via the method iterator(). We can call next() on the iterator which will expect one solution. Finally we can call close() to undo any choice points or trails the goal might have nevertheless left:

  inter.iterator(consultGoal).next().close();

We want the Java application to query all the employees and display them on the standard output. The query we would issue on the command line of a Prolog interpreter would have the following form of a predicate employee/1 and a variable X:

  ?- employee(X).

We will rebuild this query inside the Java application. We begin with creating the variable X. New variables can be requested via the constructor of the Java class TermVar. We will create only one variable which will correspond to X:

  TermVar employeeVar = new TermVar();

The functor of the query will be the atom ‘employee’. The query will now be a compound based on this atom and with the variable as the single argument. Compounds can be requested from via the corresponding constructor. Since there is only one variable we do not need to pass an interpreter parameter:

  TermCompound employeeGoal = new TermCompound("employee", employeeVar);

The key in obtaining all the employees is a loop. The loop starts with a first search invocation and it will continue as long as solutions have been found:

  Writer wr = (Writer)    
inter.getProperty(ToolkitLibrary.PROP_SYS_CUR_OUTPUT);
CallIn callin = inter.iterator(employeeGoal);
while (callin.hasNext()) {

Whenever a solution is found, we will write it to the standard output. In the command line the employee name would be instantiated the variable named X supplied by the end-user. In the Java application the employee name will be instantiated to our created variable:

      callin.next();
wr.write(inter.unparseTerm(0, employeeVar));
wr.write('\n');
wr.flush();
}

Since the ISO core standard requires that the current output may also point to a binary stream, we cannot guarantee that it is of type Writer. Therefore the above code could throw a class cast exception. Also the current code might throw an IOException by the character output. For the sake of simplicity we do not handle both situations.

The example is found in the Java class InTable. We can now compile and then execute the Java class. The following lines will be displayed on the standard output as a result:
  bundy
canby
ozias
watson

Comments