Call-out Call-in Solution Counter

In this example we will show the capability of the Prolog API to arbitrarily mix call-out and call-in. We will define a Java foreign predicate that counts the number of solutions of a given goal.  We want it to become a predicate count/2 and use the same name for the method. The method will have a primitive integer return type and two arguments:

  public static int count(Interpreter inter, AbstractTerm goal)
throws InterpreterException, InterpreterMessage {

Since it is deterministic we will not need a call-out argument. Note also that the goal is of type AbstractTerm and not of type Object, this will assure that when atoms are supplied that they will have a call-site attached. The method implementation first initializes a call-in object and a count:

     CallIn callin = inter.iterator(goal);
int count = 0;

The method implementation then proceeds by a loop. In particular we will update the counter and look for further solutions as long as there was a previous solution. Finally the Java method will terminate by creating the solution object. The interpreter will do the unification with the last argument for us. The corresponding code looks as follows:

    while (callin.hasNext()) {
callin.next();
count++;
}
return count;
}

In the above we will exit the loop when hasNext() has failed, and a close() call is not neces-sary. Assume this time that the Java method for the foreign predicate is part of a Java class OutInCount. We first proceed in registering the Java method in the main method of the Java class OutInCount similarly as in the previous example:

  foreignGoal = inter.parseTerm("foreign(count/2, " +
"'example04.OutInCount', count('Interpreter', 'AbstractTerm'))");
inter.iterator(foreignGoal).next().close();

The main method will proceed by first creating an employee goal and then a count this goal. The employee goal will need a variable and the count goal will need a variable. The idea is to create a query of the form count(employee(X), Y). The variables and terms can be created by the following sequence:

  TermVar employeeVar = new TermVar();
TermCompound employeeGoal = new TermCompound("employee", employeeVar);
TermVar countVar = new TermVar();
TermCompound countGoal = new TermCompound(inter, "count",
employeeGoal, countVar);

For invoking the count goal and thus retrieving the number of employees we can again use the method next() and close() from the call-in. We will defer the close until we have printed the count value. This is achieved by the following code:

  Writer wr = (Writer) 
inter.getProperty(ToolkitLibrary.PROP_SYS_CUR_OUTPUT);
CallIn callin = inter.iterator(countGoal);
callin.next();
wr.write(inter.unparseTerm(0, countVar));
wr.write('\n');
wr.flush();
callin.close();

The following line will be displayed on the standard output when we run the main method with the help of the runtime library:

4

Alternatively we can use the development environment. We will make use of the following Prolog text stored in the file ‘outincount.p’:

:- foreign(employee/1, 'example03.OutTable', employee('CallOut')).

:- foreign(count/2, 'example04.OutInCount', count('Interpreter',
                                      'AbstractTerm')).

:- count(employee(X),Y), write(Y), nl.

After having configured the path or library of the Java class OutTable we can run the following query from the development environment:

?- consult('countoutin.p').

We will receive the following result:

4
Yes

Kommentare