77
Jekejeke Runtime Interface Version 1.1.5, July 7 th , 2016 XLOG Technologies GmbH

Jekejeke Runtime Interface

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Jekejeke Runtime Interface

Jekejeke Runtime InterfaceVersion 1.1.5, July 7th, 2016

XLOG Technologies GmbH

Page 2: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 2 of 77

Jekejeke Prolog

Runtime Library 1.1.5Programming Interface

Author: XLOG Technologies GmbHJan BurseFreischützgasse 14 8004 Zürich Switzerland

Date: July 7th, 2016Version: 0.36

Participants: None

Warranty & LiabilityTo the extent permitted by applicable law and unless explicitly otherwise agreed upon, XLOG Technologies GmbH makes no warranties regarding the provided information. XLOG Tech-nologies GmbH assumes no liability that any problems might be solved with the information provided by XLOG Technologies GmbH.

Rights & LicenseAll industrial property rights regarding the information - copyright and patent rights in particu-lar - are the sole property of XLOG Technologies GmbH. If the company was not the origina-tor of some excerpts, XLOG Technologies GmbH has at least obtained the right to repro-duce, change and translate the information.

Reproduction is restricted to the whole unaltered document. Reproduction of the information is only allowed for non-commercial uses. Small excerpts can be used if properly cited. Cita-tions must at least include the document title, the product family, the product version, the company, the date and the page. Example:

… Defined predicates with arity>0, both static and dynamic, are indexed on the functor of their first argument [1, p.17] ...

[1] Language Reference, Jekejeke Prolog 0.8.1, XLOG Technologies GmbH, Switzerland, February 22nd, 2010

TrademarksJekejeke is a registered trademark of XLOG Technologies GmbH.

Page 3: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 3 of 77

Table of Contents1 Introduction ......................................................................................................................6

2 Programming Examples...................................................................................................72.1 Call-in Employees Table............................................................................................82.2 Call-in Exception Handling.......................................................................................102.3 Call-out Employees Table........................................................................................112.4 Call-out Call-in Solution Counter..............................................................................142.5 Call-out Call-in Solution Limiter................................................................................162.7 Custom Mutex Object ..............................................................................................192.8 Multiple Call-in Combiner.........................................................................................222.9 Custom Queue Object .............................................................................................24

3 Interoperability Concepts ...............................................................................................273.1 Interpreter Objects...................................................................................................283.2 Knowledgebase Objects ..........................................................................................303.3 Term Objects...........................................................................................................323.4 Special Objects........................................................................................................353.5 Interaction Protocol..................................................................................................383.6 Foreign Function Interface.......................................................................................413.7 Auto Loaded Classes ..............................................................................................433.8 Proxy Generated Classes........................................................................................45

4 Knowledgebase & Term API ..........................................................................................464.1 Class Knowledgebase .............................................................................................474.2 Class RuntimeWrap.................................................................................................494.3 Interface Slots .........................................................................................................504.4 Class Term..............................................................................................................514.5 Class TermAtom......................................................................................................534.6 Class TermCompound.............................................................................................544.7 Class TermVar ........................................................................................................55

5 Call & Interpreter API .....................................................................................................565.1 Class CallIn .............................................................................................................575.2 Class CallOut ..........................................................................................................585.3 Class Capability.......................................................................................................595.4 Class Controller.......................................................................................................605.5 Class Interpreter ......................................................................................................615.6 Class InterpreterException ......................................................................................635.7 Class InterpreterMessage........................................................................................655.8 Class Toolkit............................................................................................................67

6 Headless API .................................................................................................................686.1 Class ToolkitLibrary .................................................................................................696.2 Class CapabilityRuntime..........................................................................................70

7 Appendix Example Listings ............................................................................................717.1 Call-in Employees Table..........................................................................................727.2 Call-in Exception Handling.......................................................................................727.3 Call-out Employees Table........................................................................................727.4 Call-out Call-in Solution Counter..............................................................................727.5 Call-out Call-in Solution Limiter................................................................................727.6 Custom Mutex Object ..............................................................................................737.7 Multiple Call-in Combiner.........................................................................................737.8 Custom Queue Object .............................................................................................73

Index ....................................................................................................................................74

Pictures ................................................................................................................................77

Page 4: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 4 of 77

Tables ..................................................................................................................................77

References...........................................................................................................................77

Change HistoryJan Burse, March 15th, 2010, 0.1: Initial Version.Jan Burse, Mai 14th, 2010, 0.2: Added API java doc and first examples.Jan Burse, Mai 18th, 2010, 0.3: Better exception handling and examples completed.Jan Burse, June 2nd, 2010, 0.4: Better exception handling and examples completed.Jan Burse, July 2nd, 2010, 0.5: Code styling introduced and some API fixes.Jan Burse, October 2nd, 2010, 0.6: Improved interaction protocol and some API fixes.Jan Burse, November 22nd, 2010, 0.7: Data types reference and decimal.Jan Burse, December 2nd, 2010, 0.8: Stream control parameters in knowledge base and some API fixes.Jan Burse, January 2nd, 2011, 0.9: Some API fixes and mutex example completed.Jan Burse, April 8th, 2011, 0.10: Some API fixes.Jan Burse, April 15th, 2011, 0.11: Capability initialization introduced.Jan Burse, Mai 6th, 2011, 0.12: Capability activation introduced and some API fixes.Jan Burse, June 15th, 2011, 0.13: Some API enhancements and paths explained.Jan Burse, September 16th, 2011, 0.14: Barrier, cutter and accumulation API introduced.Jan Burse, October 6th, 2011, 0.15: Some example fixes and some API enhancements.Jan Burse, February 16th, 2012, 0.16: Some API enhancements and library toolkit introduced.Jan Burse, July 19th, 2012, 0.17: Library toolkit moved to package platform.Jan Burse, August 8th, 2012, 0.18: Some API fixes.Jan Burse, September 6th, 2012, 0.19: Some example fixes and some API enhancements.Jan Burse, October 29th, 2012, 0.20: Some API fixes.Jan Burse, March 4th, 2013, 0.21: Member index introduced.Jan Burse, July 9th, 2013, 0.22: Surrogate pairs introduced.Jan Burse, August 9th, 2013, 0.23: Comparable references introduced.Jan Burse, November 11th, 2013, 0.24: Some API enhancements.Jan Burse, February 3rd, 2014, 0.25:

Page 5: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 5 of 77

New decimal compression introduced.Jan Burse, April 9th, 2014, 0.26: Improve absolute file name introduced.Jan Burse, August 23rd, 2014, 0.27: Additional exception methods introduced and absolute file name methods eliminated.Jan Burse, September 12th, 2014, 0.28: Additional input/output methods introduced.Jan Burse, May 11th, 2015, 0.29: New properties file API introduced.Jan Burse, September 12th, 2015, 0.30: New widening and norming API introduced and new small float data type.Jan Burse, October 15th, 2015, 0.31: Term reference doesn’t take comparator anymore and interactor interface.Jan Burse, November 29th, 2015, 0.32: Rootless term hierarchy, elimination of atomic wrappers and proxy classes.Jan Burse, January 2nd, 2016, 0.33: New slots interface.Jan Burse, February 21st, 2016, 0.34: New castXXX procedures.Jan Burse, June 9th, 2016, 0.35: The class TermAtom was removed, new class TermAtomic.Jan Burse, July 7th, 2016, 0.36: Some improvements to allow the module thread.

Page 6: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 6 of 77

1 IntroductionThis document gives a reference of the Jekejeke Prolog application programming interfaceas provided by the runtime library.

Programming Examples: We show some examples of the use of the Jekejeke Prolog application programming interface. We first show how we can call a non-deterministic Prolog predicate from within a Java application. We then go on to show on the other hand how we can define a non-deterministic predicate inside Java that is callable from Prolog.

Interoperability Concepts: The interoperability between the runtime Prolog and an application is provided via a set of interface objects. The objects hide the details of the runtime Prolog implementation. The dominant objects are interpreter objects and term objects. But we also find predicate and reference objects.

Knowledgebase & Term API: The knowledge base class provides a handle to clauses and operator definitions. The term sub classes mirror the Prolog data types. Primitive data types can be directly constructed via the corresponding term construc-tors. The common base class for the term sub classes is the class Term. Terms uni-formly provide comparison and printing.

Call & Interpreter API: The interpreter class is the working horse. On the knowledge base side the interpreter supports initialization and the definition of Java foreign pred-icates. On the term side the interpreter supports parsing and un-parsing of terms. The interpreter also supports variable and compound creation, as well as unification. Fi-nally the interpreter provides a set of methods to invoke Prolog goals. The call-in class is used when non-deterministically calling Prolog whereas the call-out class is used by non-deterministic Java foreign predicates.

Headless API: The runtime library provides a core set of predicates and executes code without instrumentation. It is represented by a singleton.

Appendix Example Listing: The full source code of the Java classes and Prolog sources for the programming examples is given.

Page 7: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 7 of 77

2 Programming ExamplesWe show some examples of the use of the Jekejeke Prolog application programming inter-face. We first show how we can call a non-deterministic Prolog predicate from within a Java application. We then go on to show on the other hand how we can define a non-deterministic predicate inside Java that is callable from Prolog.

Call-in Employees Table: We first turn to an example where will show how we can call a non-deterministic Prolog predicate from a Java application. We want to call a predicate that will list some employees.

Call-in Exception Handling: This example deals with Prolog predicates that throw an exception. We want to call a predicate that will throw a custom ball which we will then analyse.

Call-out Employees Table: We give a further example where Java will be non-deterministically called from the Prolog interpreter. We want to define a Java foreign predicate that returns some employees.

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 predi-cate that counts the number of solutions of a given goal.

Call-out Call-in Solution Limiter: We finally give an example that will show the full power of the Prolog API. We will define a Java foreign predicate that will redo-ably call a given goal and terminate it when the solution count crosses a given threshold.

Custom Mutex Object: This example serves two purposes. First of all it contrasts the foreign function interface with Java class auto loading. Second it gives some idea how the programming interface can be used to deal with Java threads.

Multiple Call-in Combiner: This example shows the use of multiple Prolog interac-tors from within the same thread. Besides piggybacking interactors we also allow the forking of an interpreter inside the same thread and spawning from there new interac-tors.

Custom Queue Object: The example makes use of the auto loader from the begin-ning but highlights the use of a Prolog Java proxy objects. We use them to show how a call-back cannot only be implemented in Java but also scripted by Prolog.

Page 8: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 8 of 77

2.1 Call-in Employees TableWe first turn to an example where will show how we can call a non-deterministic Prolog pred-icate from a Java application. We want to call a predicate that will list some employees. Be-fore we can invoke a Prolog predicate we must set up an interpreter with an associated knowledge base. The basic objects can be created and associated programmatically as fol-lows:

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:

inter.initKnowledgebase();

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

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:

inter.setProperty(ToolkitLibrary.PROP_BASE_URL, "<base>");Term consultGoal = inter.parseTerm("consult('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() and then calling nextClose(). This method will expect and search one solution:

inter.iterator(consultGoal).nextClose();

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:

?- 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 static method createVars() of the class TermVar. We will create only one variable which will correspond to X:

TermVar[] vars = TermVar.createVars(1);

Page 9: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 9 of 77

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 re-quested from the interpreter via the corresponding constructor:

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

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(Term.toString(0, inter, employeeVars[0]));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 out-put. 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:

bundycanbyoziaswatson

Page 10: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 10 of 77

2.2 Call-in Exception HandlingThis example deals with Prolog predicates that throw an exception. We want to call a predi-cate that will throw a custom ball which we will then analyse. The predicate will be defined in a Prolog text. It is stored in the file ‘inthrow.p’:

throw_ball :- throw(ball(123)).

Let’s assume that the Java application already consulted this file. We want the Java applica-tion to catch the exception that is thrown by the predicate. For this purpose we simply wrap the predicate call into a Java try-catch statement:

try {Object throwGoal = "throw_ball";inter.iterator(throwGoal).nextClose();

} catch (InterpreterException capturedException) {

The Java application can now analyse the captured object. As a first step we recover the exception term that was thrown. This is done via the method getValue():

Object exceptionTerm = capturedException.getValue();

In the analysis itself we check for the type, arity and functor of the exception term. This is readily done by a Java type check and then via accessing the getArity() and getFunctor()methods of the TermCompound:

if (exceptionTerm instanceof TermCompound &&((TermCompound) exceptionTerm).getArity() == 1 &&((TermCompound) exceptionTerm).getFunctor().equals("ball")) {

When we have hit the correct compound we can write out its argument. This time we access the getArg() method from the TermCompound. Note that the argument numbering starts with zero (0) and not with one (1) as in the predicate arg/3:

Writer wr = (Writer) inter.getProperty(ToolkitLibrary.PROP_SYS_CUR_OUTPUT);

wr.write(Term.toString(0, inter, ((TermCompound) exceptionTerm).getArg(0)));

wr.write('\n');wr.flush();

When we did not hit on the exception we simply do nothing. The example is found in the Ja-va class InThrow. We can now run the example similar as we have done in the first example by an appropriate command line. The following line will be displayed on the standard output as a result:

123

Page 11: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 11 of 77

2.3 Call-out Employees TableWe further give an example where Java will be non-deterministically called from the Prolog interpreter. We want to define a Java foreign predicate that returns some employees. We approach the problem by first defining a vector with the employees. We use a static variable and a static initialization method as follows:

static Vector<String> employees = new Vector<String>();

static {employees.addElement("bundy");employees.addElement("canby");employees.addElement("ozias");employees.addElement("watson");

}

We now proceed in designing our Java foreign predicate. Since the Java foreign predicate will be non-deterministic it will also need a choice point. We can define our own data struc-ture for the choice point. We will do so in that we use the example class as the data structure definition. We will define the choice point fields as follows:

public class OutTable {/* choice point data */private Enumeration<String> elements = employees.elements();

The elements field will be used to enumerate the employees. We want the Java foreign pred-icate to become a predicate employee/1. We will use the same name for the Java method. The method will have a String return type. We will also see a call-out argument, since the Java foreign predicate will be non-deterministic:

public static Term employee(CallOut co) {

The method implementation should start with initializing the choice point. We can use the getFirst() method from the call-out object to check whether our Java method was called for the first time and to decide whether we have to create the choice point. And we can further use the methods setData() and getData() to set and retrieve the choice point. When the Java method was not called for the first time we will reuse the existing choice point:

OutTable table;if (co.getFirst()) {

table = new OutTable();co.setData(table);

} else {table = (OutTable) co.getData();

}

Whenever there are more elements our Java method should succeed with the next element. We can simply return the element itself to indicate success and at the same time delegate the unification of the last argument to the interpreter. But since the predicate is non-deterministic we cannot only return the element. We must also set the retry flag so as to in-form the interpreter that our Java method should be retried.

if (table.elements.hasMoreElements()) {

Page 12: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 12 of 77

co.setRetry(true);return table.elements.nextElement();

There is no need to announce a special barrier handling. The default barrier handling is suffi-cient. It will automatically undo the unification upon redo. Our code does also not temporarily create some variables or perform some unification. Therefore we also don’t need some man-ual mark or release. Now if there are no more elements our Java method should fail. We can return null to indicate failure.

}return null;

}

Assume this time that the method is part of a Java class OutTable. We proceed again by programmatically registering the Java foreign predicate and placing the corresponding code in the main method of the Java class OutTable itself. Note the difference in the arity specified for the Java foreign predicate (1) and the number of argument types specified for the Java method (2). This is explained by the two extra arguments Interpreter and CallOut necessary to deal with our non-deterministic Java foreign predicate:

Object foreignGoal = Term.parseTerm("foreign(employee/1, " +"'example03.OutTable', employee('CallOut'))", inter);

inter.iterator(foreignGoal).nextClose();

Note also that the method signature does not show the return type. This type is inquired by the interpreter at runtime from the resolved Java method. A return type that is not void or Boolean increases the arity of the Prolog predicate by one. After we have registered the Java foreign predicate, we can invoke it as we already did for the predicate of the second exam-ple. The corresponding code looks as follows:

TermVar[] employeeVars = TermVar.createVars(1);TermCompound employeeGoal = new TermCompound("employee", employeeVars);

Writer wr = (Writer) inter.getProperty(ToolkitLibrary.PROP_SYS_CUR_OUTPUT);

CallIn callin = inter.iterator(employeeGoal);while (callin.hasNext()) {

callin.next();wr.write(Term.toString(0, inter, employeeVars[0]));wr.write('\n');wr.flush();

}

We can also run this example similar as we have done in the first example by an appropriate command line. The following line will be displayed on the standard output as a result:

bundycanbyoziaswatson

Page 13: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 13 of 77

Also here we can use the development environment instead of the runtime library to execute the example. For this purpose we put again the Java foreign predicate registration and the Java foreign predicate invocation into a Prolog text. It will be stored in the file ‘outtable.p’:

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

:- employee(X), write(X), nl, fail; true.

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

?- consult('tableout.p').

We will receive the following result:

bundycanbyoziaswatsonYes

Page 14: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 14 of 77

2.4 Call-out Call-in Solution CounterIn 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. The Java foreign predicate has thus to call into Prolog in turn. We want it to become a predicate count/2. We will use the same name for the method. The method will have an Inte-ger return type and two arguments. One argument for the interpreter and one argument for the goal we will count:

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

Since it is deterministic we will not need a call-out argument. Note also that the goal is of type Term and not of type Object, this will assure a callable/1 check before passing the ar-gument and it will also assure that atoms will have a call-site. 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;

}

Assume this time that the Java method for the foreign predicate is part of a Java class OutInCount. As an example we will count the employee/1 predicate from the previous exam-ple. Therefore we will reuse the employee foreign predicate from the Java class OutTable. We first proceed in registering the Java method in the main method of the Java class OutInCount. We only show the Java method registrations for our new foreign predicate count/2:

foreignGoal = Term.parseTerm("foreign(count/2, " +"'example04.OutInCount', count('Interpreter', 'Term'))", inter);

inter.iterator(foreignGoal).nextClose();

The main method will proceed by first creating an employee goal and then a count 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). Both variables can be created by the fol-lowing statement:

TermVar[] vars = TermVar.createVars(2);

The employee goal will have the first variable as its argument. It is readily created as follows:

Page 15: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 15 of 77

TermCompound employeeGoal = new TermCompound("employee",employeeVars[0]);

The count goal will have the employee goal as its first argument and the second variable as its second argument. It is readily created as follows:

TermCompound countGoal = new TermCompound("count", employeeGoal, employeeVars[1]);

For invoking the count goal and thus retrieving the number of employees we can again use the method nextClose() from the call-in. The call-in can be constructed with a return value and we can use the result of nextClose() to obtain the a copy of the return value. This is achieved by the following code:

Writer wr = (Writer) inter.getProperty(ToolkitLibrary.PROP_SYS_CUR_OUTPUT);

Object res = inter.iterator(employeeVars[1], countGoal).nextClose();wr.write(Term.toString(0, inter, res));wr.write('\n');wr.flush();

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','Term')).

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

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

?- consult('countoutin.p').

We will receive the following result:

4Yes

Page 16: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 16 of 77

2.5 Call-out Call-in Solution LimiterWe finally give an example that will show the full power of the Prolog API. We will define a Java foreign predicate that will redo-ably call a given goal and terminate it when the solution count crosses a given threshold. The Java foreign predicate to limit the number of solutions will be called limit/2. We will use the same method name. The method will have a term argu-ment and an integer argument besides the interpreter and call-out argument:

public static boolean limit(Interpreter inter,CallOut callout,Term goal, int max)

throws InterpreterException, InterpreterMessage {

The call-out argument is needed because the predicate will be non-deterministic. The inter-preter exception is mentioned to be able to pass down any exception thrown by the goal ar-gument. The method implementation starts with two different initializations for the call and the redo scenario. In case of the call scenario we will first create the choice point data object. We simply reuse the main class of our example as the class for the choice point data:

public class OutInLimit {private final CallIn callin;private int count = 0;private OutInLimit(CallIn c) {

callin = c;}

The implementation of the foreign function limit() starts with obtaining the choice point data. If the call is the first call, then the choice point data is created and set to the call-out parameter. The choice point data will receive a new iterator for the given goal. If the call is not the first call, the choice point data is obtained from the call-out parameter:

OutInLimit limit;if (callout.getFirst()) {

limit = new OutInLimit(inter.iterator(goal));callout.setData(limit);

} else {limit = (OutInLimit) callout.getData();

}

We need also to care for a clean-up call. This happens when in the continuation a cut or an exception happens. The code here is:

if (callout.getCleanup()) {InterpreterException ex = callout.getException();ex = limit.callin.cleanup(ex);callout.setException(ex);return true;

}

As a first step we can check whether we have already reached the iteration limit. If the itera-tion limit is already reached we close the iterator and fail the foreign function:

if (!(limit.count < max)) {

Page 17: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 17 of 77

limit.callin.close();return false;

}

Otherwise, if we have not yet reached the limited we check whether the given goal produces more results. If this is the case we can increase the counter and notify the interpreter that we are expecting redo calls by invoking the method setRetry(). Otherwise we fail our foreign predicate by returning false:

if (limit.callin.hasNext()) {limit.callin.next();limit.count++;callout.setRetry(true);callout.setSpecial(true);callout.setCutter(true);return true;

}return false;;

The above code informs the interpreter that we do not want to rely on the default barrier han-dling. This is done by invoking the method setSpecial() before successfully returning. This is necessary since the default barrier handling would undo all variable bindings upon redo and thus corrupting the prior success of the goal. Further the above code also informs the inter-preter we handle clean up events. This is done by invoking the method setCutter() before successfully returning.

The Java method for the foreign predicate will be part of the Java class OutInLimit which has already been used for the choice point data. As an example we will limit the employee/1 predicate from one of the previous examples. Therefore we will reuse the employee foreign predicate from the Java class OutTable. We first proceed in registering the Java method in the main method of the Java class OutInLimit. We only show the Java method registrations for our new foreign predicate limit/2:

foreignGoal = inter.parseTerm("foreign(limit/2, " +"'OutInLimit', limit('Interpreter', 'CallOut', " +"'Term', 'int'))");

inter.iterator(foreignGoal).nextClose();

The main method will proceed by first creating an employee goal and then a limit goal. The employee goal will need a variable, but the limit goal will not need a variable. We will use the values max=3, max=4 and max=6. For the first scenario with max=3 the main method will then use a loop to enumerate all solutions to the limit goal. The following lines will be dis-played in the first scenario on the standard output:

bundycanbyozias

We can differently proceed for the second scenario with max=4. In this scenario we will not loop through all results but use nextClose() and thus put the cutter to a test. The following lines will be displayed in the second scenario on the standard output:

bundy

Page 18: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 18 of 77

The last scenario with max=6 will correspond again to the first scenario, in that we will loop again. The following lines will be displayed in the last scenario on the standard output:

bundycanbyoziaswatson

Alternatively we can use the development environment to invoke queries. The corresponding Prolog text is given in the appendix as ‘limitoutin.p’.

Page 19: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 19 of 77

2.7 Custom Mutex ObjectThis example serves two purposes. First of all it contrasts the foreign function interface with Java class auto loading. Second it gives some idea how the programming interface can be used to deal with Java threads. In the console manual we find a tour that shows how the Jekejeke Prolog development environment can be used to run multiple threads. We will con-tinue working on the example process given there. The process there was defined as follows:

process(X) :-repeat,log(X, 'Ha'),log(X, 'Tschi'),fail.

When running two processes in parallel we observed interleaving. For example in the below screenshot we see that between the ‘Ha’ of process B and the ‘Tschi’ of process B, the process A is able to issue 3 write instructions:

Picture 1: Interleaving of two Processes

Sometimes interleaving is not desired for a critical section. In the following we will first intro-duce a custom Java object that allows creating boundaries for critical sections. And then we will show how to call this Java object from Prolog. The Java object has the following interface definition, consisting of a constructor and two methods:

public class Mutex {public Mutex();public void acquire() throws InterruptedException;public void release();

}

The code of the Java object is found in the appendix. To protect a critical section from inter-leaving we simply have to surround it with an invocation of the methods acquire() and release(). Since the Java object is subject to garbage collection, the programming pattern is especially simple. We do not have to explicitly destroy the lock object.

The first approach to call this Java object from Prolog is to define a couple of foreign predi-cates. We can do this as follows, whereby the Java object will be mapped to the Prolog ref-erence data type:

Page 20: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 20 of 77

:- foreign_constructor(new/1, 'example06.Mutex', new).:- foreign(acquire/1, 'example06.Mutex', acquire).:- foreign(release/1, 'example06.Mutex', release).

We can readily start testing our simple locks. We use a modified version of the thread tour example that is found in the Prolog text “mutexobj.p”. Our new Prolog text starts first with registering the foreign predicates and then gives a modified version of the predicate init/0. The new initialization not only asserts a fact for the console but also for the lock, so as to share it later between multiple processes:

init :-current_output(X),assertz(console(X)),new(Y),assertz(lock(Y)).

Although our simple locks are not re-entrant, they are nevertheless cancellable via a thread interrupt. We can issue a thread interrupt by the menu item File | Abort. The result will be that the predicate acquire/1 will abort with a system error and the lock will remain in status locked. Let’s now turn to a practical application of guarding a critical section.

The subsequent code of our Prolog text contains the same logging predicate as in the con-sole manual thread tour. We will therefore not repeat it here. But the process/1 predicate looks different now. The critical section is the logging of the ‘Ha’ and the ‘Tschi’. To allow a graceful interruption via the menu item File | Abort we have wrapped the critical section by the setup_call_cleanup/3 construct:

process(X) :-repeat,lock(Y),setup_call_cleanup(

acquire(Y),(log(X, 'Ha'),log(X, 'Tschi')),release(Y)),

fail.

The setup_call_cleanup/3 hooks into the Fail and into the Exit port. It will use the Exit port when the goal deterministically succeeds. Thus the unlocking will immediately be done after the logging. When running two processes ‘A’ and ‘B’, we will not observe some interleaving for the critical section anymore:

Page 21: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 21 of 77

Picture 2: No Interleaving for the Critical Section

An alternative method to invoke the Java object is to use the auto loader. Using the auto loader obviates the tedious listing of foreign/3 directives. The auto loader derives the predi-cate and evaluable function names from the names of the class members. For more details see the programming interface documentation.

The Prolog code that uses the auto loader is found in the Prolog text ‘mutexobj2.p’. This Prolog text does not contain a foreign/3 directive section anymore. The alternative init2/1 predicate definition has the following reading, using the auto generated constructor. The auto loader will only act the first time a foreign module is seen.

init2 :-current_output(X),assertz(console(X)),example06/'Mutex':new(Y),assertz(lock(Y)).

The Prolog text also contains an alternative process2/1 predicate definition, using again the auto generated methods. Auto generated predicates perform similarly to foreign/3 directive define predicates, since the auto loader uses the same directives under the hood except for some additional dispatching of overloaded methods.

process2(X) :-repeat,lock(Y),setup_call_cleanup(

example06/'Mutex':acquire(Y),(log2(X, 'Ha'),log2(X, 'Tschi')),example06/'Mutex':release(Y)),

fail.

Page 22: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 22 of 77

2.8 Multiple Call-in CombinerThis example shows the use of multiple Prolog interactors from within the same thread. An interpreter allows spawning interactors in a piggyback fashion. This cares for the situation that the solving of a goal of an interactor performs a call-out which in turn performs a call-in again. Besides piggybacking interactors we also allow the forking of an interpreter inside the same thread and spawning from there new interactors.

In the following example we use two predicates p/1 and q/1 that define simple one column tables of data. We then use one interpreter respective interactor to run along the first table and another interpreter respective interactor to run along the second table. The first inter-preter is created as usual from the knowledge base, but the second interpreter is created from an existing interpreter:

Interpreter inter = know.iterable();Interpreter inter2 = inter.iterable();

Creating an interpreter from a knowledge base should be done only once. Under the hood this will create an interpreter object and a controller object. Forking a new interpreter from an existing interpreter can then be done multiple times. Each forked interpreter will share the initial controller object. The controller object carries shared data such as the input/output streams and the thread local predicates.

We construct a goal for the first table and a goal for the second table. The creation of interac-tors from the two interpreters then works as follows:

CallIn callin = inter.iterator(pGoal);CallIn callin2 = inter2.iterator(qGoal);

The application programmer can freely switch between differently forked interpreters inside the same thread. The controller object can be used to interrupt any of the interpreters that are currently used in the thread. We will use this switching capability to implement a simple combiner that alternately displays a row from the first table and a row from the second table. This is a stream programming pattern that has many applications.

We use a Boolean flag to decide which of the two tables should be displayed. We have to loop through both tables as long as both tables still have rows:

boolean flip = true;while (callin.hasNext() && callin2.hasNext()) {

if (flip) {callin.next();wr.write("p(");wr.write(Term.toString(0, inter, pVars[0]));wr.write(").\n");wr.flush();

} else {callin2.next();wr.write("q(");wr.write(Term.toString(0, inter2, qVars[0]));wr.write(").\n");wr.flush();

}flip = !flip;

}

Page 23: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 23 of 77

The code then also contains the handling of each of the single tables. When we run the complete code we get the following result:

p(a).q(1).p(b).q(2).p(c).p(d).

The various iterable() and iterator() methods have been introduced in release 1.0.10 of Jeke-jeke Prolog together with the new controller object. A new feature is also the static method currentInterpreter() which does a lookup of the current interpreter for the current thread. These methods do not yet implement or yield the corresponding interfaces from Java since they throw exceptions. This might improve in the future.

Interactors were mainly introduced for the Prolog Java proxy classes demonstrated in the subsequent section. The handler of a Prolog Java proxy class uses an interactor to execute a corresponding predicate or evaluable function. Since this execution uses methods from the nextClose() family the Prolog Java proxy class mechanism cannot yet be used to leave a trace of forward chaining or to fill a constraint store.

Page 24: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 24 of 77

2.9 Custom Queue ObjectThe example makes use of the auto loader from the beginning but highlights the use of a Prolog Java proxy objects. We use them to show how a call-back cannot only be implement-ed in Java but also scripted by Prolog. The example makes use of Java object for a concur-rent queue. The Java object has the following interface definition, consisting of a constructor and two methods:

public class Queue {public Queue();public Runnable take() throws InterruptedException;public void post(Runnable r, long w)

}

In our example this queue is used to schedule and run call-backs that display a line “Ha” fol-lowed by a line “Tschi”. Since only one call-back is run at a time by the executor thread we don’t need a lock and nevertheless observe no interleaving. We begin with defining the call-back in Java. The following Java code does the job:

public void run() {try {

long time = System.currentTimeMillis();StringBuilder buf = new StringBuilder();buf.append("Process ");buf.append(name);buf.append(": ");buf.append(count);buf.append('\n');writer.write(buf.toString());writer.flush();count++;if (count < 10)

queue.post(this, time + 1000);} catch (IOException x) {

throw new RuntimeWrap(x);}

}

The call-back will increment a counter, display the counter and re-schedule itself with a delay of 1000ms. It will do so for 10 times. We can already script the executor code in Prolog itself. This code will first create two counters and the in an infinite loop execute the runnable of the queue. The code uses the auto loading of Java classes and interfaces:

main :-current_output(W),example08/'Queue':new(Q),example08/'Counter':new('P1', Q, W, C1),example08/'Counter':new('P2', Q, W, C2),'Runnable':run(C1),'Runnable':run(C2),repeat,

example08/'Queue':take(Q, R),'Runnable':run(R),

fail.

Page 25: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 25 of 77

The two lines with the invocation example08/’Counter’:new create the two counters. The in-vocation will call the constructor of the counter. This constructor takes various parameters,such as the name of the counter, the queue for self-re-scheduling and the stream for output. The call-backs of the counter are invoked via 'Runnable'. When the main loop is invoked the result will be as follows:

Picture 3: Screenshot of Queue Example Run

Prolog Java proxy classes now allow scripting the call-backs in Prolog. The replacement for a Java class is a Prolog module. This Prolog module has to use reexport/1 directives to im-port the Java interfaces that the Prolog Java proxy class is going to implement. In the pre-sent case we reexport/1 the Java interface ’Runnable’:

:- module(example08/counter2, []).:- use_module(foreign('Runnable')).:- reexport(foreign('Slots')).

We also import the Java interface ‘Slots’. When this interface is present in the Prolog Java proxy class it will also be possible to access a state of an instance via some predicates and evaluable functions arg/3, set_arg/3 and arity/2 that are automatically handled. To create an instance we use the predicate sys_instance/1:

Page 26: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 26 of 77

:- public new/4.new(N, Q, W, R) :-

sys_instance_size(4, R),R:set_arg(1, N),R:set_arg(2, Q),R:set_arg(3, W),R:set_arg(4, 0).

The call-back can now be scripted via Prolog. The Prolog code is a literal translation of the Java counter code from above. Our proxy handler will use an interactor to execute the call-back predicate. Currently the handler will execute the predicate once and then close the in-teractor, so that no trail and no choice points are left. We might support further executing policies in the future:

:- public run/1.:- override run/1.run(R) :-

T is 'System':currentTimeMillis,R:arg(1, N),R:arg(2, Q),R:arg(3, W),R:arg(4, C),atom_concat('Process ', N, A1),atom_concat(A1, ': ', A2),number_codes(C, L),atom_codes(A, L),atom_concat(A2, A, A3),atom_concat(A3, '\n', A4),write(W, A4),flush_output(W),D is C+1,R:set_arg(4, D),(D < 10 ->

S is T+1000,example08/'Queue':post(Q, R, S); true).

The override/1 directive is a module system specific feature. It suppresses a warning that the’Runnable’ interface is overridden. We might change this style check in the future in that we might not require this directive for abstract members. Currently our module system has not yet a distinction between abstract and non-abstract members.

The foreign function interface exception RuntimeWrap is not seen, since the proxy handler uses it automatically for us. Using the above Prolog scripted counter in an executor gives the same result as the Java coded counter. The variant of an executor with a Prolog scripted counter is found in the Prolog text “queueobj2.p” in the appendix.

Page 27: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 27 of 77

3 Interoperability ConceptsThe interoperability between the runtime Prolog and an application is provided via a set of interface objects. The objects hide the details of the runtime Prolog implementation. The dominant objects are interpreter objects and term objects. But we also find predicate and reference objects.

Interpreter Objects: The execution of a Prolog goal is an activity. Since Prolog goals are non-deterministic their activity will leave some trace which is beyond the side effects of the Prolog goals themselves. The trace will be some data structure suitable for backtrack-ing. The interpreter objects circle around this data structures.

Knowledgebase Objects: The execution of Prolog goals is based on defined predicates and built-in predicates. These predicates are found inside a knowledge base. The Prolog interpreter initializes a knowledge base with system defined predicates and system built-in predicates. The Prolog API allows the application programmer to define custom built-ins in the form of Java foreign predicates.

Term Objects: Prolog does not feature the kind of variables and data structures that are usually found in imperative programming languages. The value of a variable is tight to the progress of the search procedure and as a data structure we usually find the term model. The Prolog API allows the creation and inspection of these structures.

Special Objects: The term model is usually restricted to compounds, atoms and num-bers. We extend the term model by reference objects and decimals. The reference ob-jects can then participate in the proof search and can be used to wrap objects from the application. Among the possible uses we find resource access and synchronization primi-tives. The decimals give better support to some financial calculations.

Interaction Protocol: The duties of a foreign predicate are minimized in that the inter-preter automatically performs some housekeeping. The housekeeping includes rolling back the variable creations and instantiations made by the foreign predicate. The house-keeping varies on whether the foreign predicate is deterministic or not.

Foreign Function Interface: The Prolog interpreter provides an internal API that allows defining built-in predicates and evaluable functions. This internal API is not public availa-ble since it is an unsafe API. For less time critical and specialized predicates and evalua-ble functions we provide an external API here. The call-out mechanism is based on asso-ciating a knowledge base member with a Java class member.

Auto Loaded Classes: With release 1.0.9 the Prolog interpreter provides auto loading of modules. This happens when a qualified predicate or evaluable function call is specified and the specified module has not yet been loaded. The auto loader will try Prolog mod-ules and Java classes. For a Java class the auto loader will on the fly generate a synthet-ic module.

Proxy Generated Classes: With release 1.0.10 the Prolog interpreter can generate Java classes from modules. The module must be either a Prolog text loaded from a text source or a dynamic module. The Java class will be a Java proxy class with an invocation han-dler. This invocation handler will dispatch method calls to the module.

Page 28: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 28 of 77

3.1 Interpreter ObjectsThe execution of a Prolog goal is an activity. Since Prolog goals are non-deterministic their activity will leave some trace which is beyond the side effects of the Prolog goals them-selves. The trace will be some data structure suitable for backtracking. The interpreter ob-jects circle around this data structures.

The interplay between the interpreter and an application poses various challenges. These challenges can be summarized as follows:

Call-in API: The search procedure should be exhibited in an enumerator fashion. After each solution the Prolog interpreter should return to the call point of the application. The application can then control whether it needs a further solution or whether it wants to ter-minate the search.

Call-out API: It should be possible to plug-in custom predicates to the Prolog interpreter. Predicates must be realized in an enumerator fashion similar to the search procedure. Further it should be allowed that an invoked custom predicate can in turn perform a call-in to the Prolog interpreter without disturbing it.

Exception Handling: Modern search procedures not only return success or failure, they might also throw a program exception. The Prolog interpreter must provide a way to safe-ly deal with the occurrence of program exceptions. Further it must be also possible for custom predicates to throw program exceptions.

Multi-Threading: It must be possible that multiple invocations of the Prolog interpreter happen simultaneously over the same knowledge base. For this purpose not only the in-ference steps and built-ins must be thread save. Also the data structures needed for backtracking must be replicated.

The following interaction diagram highlights the aforementioned requirements. We see a shared knowledge base and two threads. The first thread performs a call-in which terminates normally. The second thread performs a call-in, a call-out, a call-in and then throws a pro-gram exception which is only caught back in the application:

SharedKnowledgebase

Call-in

Return

Call-in

Call-out

Call-in

Exception

Caller 1 Interpreter 1 Interpreter 2 Caller 2

Picture 4: Interpreter Challenges

Page 29: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 29 of 77

Object oriented technology is quite suitable to provide solutions to the posed challenges. An object can encapsulate state and behaviour. Both are needed for the search procedure. Therefore the first design idea is to have interpreter objects besides the shared knowledge base object. We also postulate light weight call objects for call-ins, so as to avoid creating heavy weight interpreter objects each time we perform a new call-in.

The above exception handling and multi-threading and is very much motivated by the facili-ties already present in the host object-oriented programming language, in particular the Java virtual machine. The current Java virtual machine supports an operating system model based on processes that do not share the heap, and threads that share the heap and have individ-ual stacks. It would be possible to have micro threads, thus doing context switching inside the Prolog interpreter itself. The current product version does not have any support for this although this could be useful for massive multi-agent programming.

The execution flow of a Prolog interpreter can be externally influence by two facilities. A Prolog interpreter has a status and a signal. The status of a Prolog interpreter can be changed via the method setStatus(). The status change has an immediate effect and is seen via the method getStatus(). In certain situation it might be desirable that the Prolog interpret-er ignores the status. The Prolog flag sys_cloak indicates that the status should not be ig-nored. The flag can be temporarily cleared via the system predicate sys_ignore/1.

A signal is an interpreter message. A signal can be set via the method setSignal(). The Prolog interpreter will recognize the signal when it reaches the next call port and then throw the interpreter message instead of executing the goal. When the call port has not yet been reached the signal can be retrieved and cleared via the method getAndClearSignal().The Prolog flag sys_mask indicates that a signal should not be ignored. The flag can be tempo-rarily cleared via the system predicate sys_atomic/1.

When setting the signal the target thread will be interrupted. As a result blocked Java calls receive an InterruptedException respectively IOInterruptedExceiption exception. Retrieving and clearing a signal will also clear the interrupt status of the actual thread. It is recommend-ed that Java foreign predicates to catch these signals and re-throw the signal.

Page 30: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 30 of 77

3.2 Knowledgebase ObjectsThe execution of Prolog goals is based on defined predicates and built-in predicates. These predicates are found inside a knowledge base. The Prolog interpreter initializes a knowledge base with system defined predicates and system built-in predicates. The Prolog API allows the application programmer to define custom built-ins in the form of Java foreign predicates.

Since we do not yet have a module system the organization of predicates is relatively simple. Each interpreter can maximally have one knowledge base associated. For each predicate specification there is a separate entry in the knowledge base, independent whether it is a defined predicate or built-in predicate. Defined predicates have a list of clauses associated. System built-ins have some protected data associated. Custom built-ins in the form of a Java foreign predicates refer exactly to one Java method.

Knowledgebase

Clause 1

append/3

hello/0

Clause 2

Java Class

Method

write/1

DefinedPredicate

SystemBuilt-in

Java ForeignPredicate

Picture 5: Example Knowledgebase

The clauses of defined predicates can be either asserted dynamically or statically consulted from a file. Dynamic predicates can be abolished dynamically whereas static predicates are only abolished in the initialization phase of a re-consult. Java foreign predicates can be regis-tered dynamically or via a directive in a file. In both cases they can be abolished dynamically and they will be also abolished in the initialization phase of a re-consult.

There is a contract between a predicate and the interpreter. This contract regulates what the interpreter has to expect form a predicate and vice versa. A first element of the contract is the handling of exception. Each defined predicate and built-in predicate is expected to either throw an interpreter message or an interpreter exception. Interpreter messages do not con-sists of a Prolog stack trace. When the interpreter receives an interpreter message it will turn it into an interpreter exception by adding a Prolog stack trace. Interpreter exceptions are di-rectly passed down.

The contract also regulates the behaviour of deterministic and non-deterministic predicates. A deterministic predicate does either succeed or fail without leaving a choice point. Non-deterministic predicates on succeeding for the first time might create a new choice point. When there is a choice point the predicate is retried upon backtracking. The predicate might then succeed again by adapting the choice point or it might even succeed with dropping the choice point. Whenever a predicate succeeds without a choice point, the interpreter can ap-ply tail recursion optimization.

Page 31: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 31 of 77

Class Path

Archive myarch.zip

Directory mydir2

Directory mydir1

Relative Source Pathmyfile.p

Absolute Source Pathmydir2/myfile.p

Class Namemyclass

Class Locationmyarch.zip!/myclass.class

Picture 6: Example Class Path

Besides collecting a number of predicates a knowledge base servers further functions to the interpreter. It also holds the class loader which is responsible for the resolution of Prolog source file names and Java class names. The class loader is equipped with a class path. The class path can contain either directories or archives. Relative source paths are resolved by looking them up in the directories and archives, and returning the first found location. Java class names are resolved by first converting the full class name into a relative source path, and then looking up this relative source path.

The development environment allows enhancing the class path via its settings dialog. As a result the developer can easily work with Java foreign predicates. The developer has only to add the directory or archives that contain the Java classes of the Java methods he wants to use. In case of the runtime library there are multiple scenarios. For standalone applications the class path can be specified on the command line. For applets the class path can be specified inside the applet tag. For servlets the class path corresponds to the WEB-INF/lib directory. The later should also work when the runtime library is shared among different web contexts. The directories and archives can also deliver Prolog sources.

Finally the knowledge base gives a context for internationalization. This is explored for both the runtime library and the development environment. But we do not provide an exposure of an application programming interface to access this facility at the current stage. But it is in-ternally used by the runtime library and the development environment for the display of user friendly error messages. The facility allows the mapping of Prolog terms to text templates found in Java property files. And then apply the text templates to some arguments of the Prolog terms. The facility is further use to internationalize the dialogs and menus of the de-velopment environment.

Page 32: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 32 of 77

3.3 Term ObjectsProlog does not feature the kind of variables and data structures that are usually found in imperative programming languages. The value of a variable is tight to the progress of the search procedure and as a data structure we usually find the term model. The Prolog API allows the creation and inspection of these structures.

There are various choices for the internal representation of the term model and of the varia-bles. The choice must at least support efficiently the following operations:

Clause Instantiation: Whenever the search procedure executes a defined predicate, it needs to make fresh copies of the clauses of this predicate. This means that all the vari-ables in a picked clause need to be replaced by fresh variables.

Term Unification: To determine whether a newly instantiated clause is applicable the Prolog interpreter needs to attempt a unification of the clause head with the given goal. When the unification fails at some point the rollback of the already done instantiations must be supported.

Error Instantiation: Execution errors must survive the rollback of choice points. There-fore execution errors are kind of one time clauses. When handling execution errors a fresh copy is made of the error term.

We follow the same approach that has already been followed in the DEC-10 Prolog imple-mentation [1]. In this approach a dynamically instantiated clause is represented by two point-ers. One pointer referring to the so called skeleton of the clause and the other pointer refer-ring to the instantiation frame of the clause. The frame will hold the fresh variables of the clause. Each new instantiation of the clause requires a new frame. The skeleton contains indexes into the frame. The pair of the two pointers is usually called a molecule.

In the original DEC-10 Prolog implementation such a molecule could be represented in one machine word. We do not bother with machine representation in our Prolog interpreter. Since machine representation would violate the security provided by our object oriented host lan-guages. We also do not try to generate byte code for the Java virtual machine. Byte code can only capture the surface of a clause and will not help when a real unification is requiredor when heavy backtracking is involved. We have evidence of this fact by our test scenarios which show this trend.

This is also not to say that we are against local or global program analysis. But we also be-lieve that this can be done inside an object model without regress to some byte code. And even eventually such an analysis can be done dynamically and varying during runtime which invalidates the idea of static byte code to some extent. Proof of concept that an object model can easily be instrumented is our development Prolog which has been built on top of the runtime Prolog. Further the runtime Prolog itself shows some optimizations such as tail re-cursion and indexing without the use of any byte code.

Nevertheless we have also to be careful when using an object oriented programming lan-guage for implementation. For example it would not be feasible to use little pair objects to represent the molecules, instead we pass around two arguments. Further to avoid stack overflow we have to manually convert most of the needed internal routines so that they take advantage of tail recursion. Many of these details will be hidden from the application pro-grammer by the Prolog API. So that externally we will provide objects representing a pair of a frame and a skeleton for the convenience of the application programmer.

Page 33: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 33 of 77

In the following we see frames and skeletons in action. We show the object configuration before and after the successful unification of f(X) = f(g(Y)). Each frame is basically an array of molecule containers. A un-instantiated variable corresponds to an empty molecule which we represent by a null () frame and a null () skeleton:

Skeleton:Before

After

Frame:

Skeleton:

Frame:

f(#1) f(g(#1))

f(#1) f(g(#1))

Picture 7: Example Unification

The result of the unification is the instantiation X = g(Y). The instantiation is stored in the frame. Both the frame and the skeleton of the instantiation source are stored in the instantia-tion target molecule. On the other hand the skeletons themselves are left untouched. The skeletons are only referenced completely or partially by eventual instantiations.

Unification is an operation that is heavily used by the interpreter during defined predicate execution. Each successful logical inference is based on the unification between a given goal and a clause head. Nevertheless we will less often see unification in the application pro-gramming interface. Instead we will provide the application programmer explicit construction and deconstruction operations. The reason is that these operations are easier to deal with than using a detour over unification based on patterns. Also it is not clear where the needed patterns come from in the first place.

Constructors solve the chicken egg problem for the existence of patterns. They will be partic-ular useful in the call-in interface of the Prolog interpreter. They will allow the application pro-grammer to create goals on the fly as he wishes and to submit them to the Prolog interpreter. The goals can contain built-in predicates and/or user defined predicates. So that constructors provide a uniform access to all predicates of the Prolog interpreter. The constructors should not only allow the construction of atomic values, it should also be possible to construct varia-bles and compounds so that that all kinds of predicates can be invoked.

De-constructors can simulate many steps of unification. A basic operation that will be useful for the call-in interface is the retrieval of the instantiation of a variable. This way the applica-tion programmer can retrieve terms after the successful execution of goals. But the applica-tion programmer might also be interested in analysing and dissecting the resulting terms. Therefore we will further find type checking and various accessors among the deconstructing operations. Accessors are needed to retrieve the Java values from atomic terms and to pick the arguments of a compound.

Page 34: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 34 of 77

Call-in

Return

Caller Interpreter Called

Call-out

Return

Constructors

Deconstructors

Deconstructors

ConstructorsUnification

Picture 8: Terms during Execution

Whereby the usage of the call-in interface starts with construction and ends with deconstruc-tion, the roles are reversed for the call-out interface. When custom code from the application programmer is called by the Prolog interpreter, the first step to do is to analyse and dissect the provided arguments. When this phase was successful the custom code will perform the desired task and produce some results. To return these results to the Prolog interpreter a repackaging as terms will be necessary again and thus constructors will be invoked. Finally the custom code can decide by itself which arguments are output. Output arguments can be instantiated by unification.

An alternative to manually constructing terms is the use of the Prolog syntax. The Prolog API should provide methods to parse and un-parse terms. The Prolog syntax is an umbrella for canonical written terms and terms written by respecting operator definitions. Therefore one parse method is sufficient. On the other hand multiple un-parse methods seem appropriate. One un-parse method that writes terms canonical might be directly defined for terms. On the other hand writing terms by respecting operator definitions must come from inside an inter-preter that has an associated knowledgebase.

The unification schema allows a high degree of sharing. We are not forced to copy terms during unification since we can re-use the same skeleton by multiple unifications. On the other when a clause is asserted we need to recreate the given skeletons. We have arranged that ground skeletons are not copied but shared. Further methods are known such as shar-ing common sub-terms [3]. We did not implement a detection of common sub-terms since this also slows down the system. There exist optimizations to share common sub-terms across a find all invocation [3]. We did also not implement such detection.

Page 35: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 35 of 77

3.4 Special ObjectsThe term model is usually restricted to compounds, atoms and numbers. We extend the term model by reference objects, small floats and decimals. The reference objects can then partic-ipate in the proof search and can be used to wrap objects from the application. Among the possible uses we find resource access and synchronization primitives. The small floats and decimals give better support to some scientific and financial calculations.

The ISO Prolog core standard allows the introduction of additional data types in a Prolog system in non-strict mode. The standard requires that the syntax and behaviour of the data types is defined. Compared to the ISO Prolog core standard we have introduced three new data types with the following corresponding syntax:

Small Floats: Small floats are internally represented as the Java Float. The syntax for small floats is a float with a prepended small float indicator (“0f”). Examples are: 3.14 is a float, 0f3.14 is a small float.

Decimal: Decimals are internally represented as the Java BigDecimal or Java Long. The syntax for decimals is a float with a prepended decimal indicator (“0d”). Exam-ples: 3.14 is a float, 0d3.14 is a decimal.

Reference: References are internally represented as a Java object of any class. The syntax for references is a hexadecimal integer with a prepended reference indicator (“0r”). Examples: 254 is an integer, 0rFE is a reference.

The implementation of small floats and decimals differs from the implementation of refer-ences in that small floats and decimals can always be ordered and in that decimals can be parsed. Otherwise the implementation was done along similar lines as for references. For the identity test the equals() method of the Java Float, Java Long and Java BigDecimal was di-rectly used. This method is sensitive to the scale of the BigDecimal. Thus small floats and decimals give a slightly different identity test as one might expect from floats. This can be seen here:

?- 3.14 = 3.1400.Yes?- 0f3 = 3.0.No?- 0d3.14 = 0d3.1400.No

The reference data type is a replacement for the various pointers found in the ISO Prolog core standard such as file handles. Since the ISO Prolog core standard pointers are memory addresses and thus numbers they are typically orderable. We lose this property for our refer-ence data types in general in favour of the safer Java memory model. Also we do not make any assumptions whether the Java object is part of a name space. The consequence here is that our reference data objects cannot be currently read in from a file or from the user input.

A great deal of work for the small floats and decimals had to be put into the arithmetic opera-tions. Arithmetic operations are not available for references but they are available for small floats and decimals. The basic arithmetic operations and the rounding operations could be extended to small floats and decimals. Small floats and decimals can also participate in trig-onometric operations but they are simply narrowed up or down to floats.

Page 36: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 36 of 77

Although arithmetic comparison between small floats and floats is supported, the result might look counter intuitive since due to the smaller precision equality between converted data and the original data might not hold. This can be seen here:

?- 0f3 =:= 3.0.Yes?- 0f3.14 =:= 3.14.No

What concerns the arithmetic comparison of decimals, contrary to the equality it is not sensi-tive to the scale anymore since the compareTo() method of the Java class BigDecimal is used. This can be seen here:

?- 3.14 =:= 3.1400.Yes?- 0d3.14 =:= 0d3.1400.Yes

A comparison of the functionality introduced by the new data types can be found below. As can be seen above the reference objects share many properties with the other data types of the Prolog standard. Most of the properties automatically result because the reference ob-jects implement equal(), hashCode() and compareTo():

Table 1: Comparison Jekejeke and ISO Data TypesJekejeke ISO w r a u t < = c f + \ sVariable Variable x x x x x x x x xInteger Integer x x x x x x x x x x xSmall Float n/a x x x x x x x x x xFloat Float x x x x x x x x x x xDecimal n/a x x x x x x x x x xObject n/a x x x x x x xComparable n/a x x x x x x x xAtom Atom x x x x x x x x xCompound Compound x x x x x x x x x

Legend:w = write; r = read; a = atomic, number, etc..; u = unify, etc..;t = term_hash; < = <, @<, etc..; = = ==, =:=, etc..;c = assert, clause, etc..; f = functor, =.., etc..; + = +, div, etc..;\ = /\, etc..; s = sin, cos, etc..

Reference objects implement these methods by delegating to the Java object. They already allow reference objects to participate in unification, clause indexing, term equality and term hashes. Reference objects can also participate in lexical comparisons when they implement the comparable interface.

It is also possible to use copied terms that use reference objects and to even assert clauses that contain the reference objects. What concerns the garbage collection of the reference objects, the implementation is such that we fully rely on the Java runtime system. So when there is no more clause or search pointing to a Prolog reference then also the Java object is not anymore referenced from the Prolog system. It might still be referenced from elsewheresuch as the application, but if there is no such reference it will be eligible for garbage collec-tion.

Page 37: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 37 of 77

The new data types are not only available from within the Prolog system. The application programmer can also work with references and decimals. Small floats and decimals can be accessed directly as sub classes from the Java Number class via the application program-ming interface. Reference data types can also be accessed directly via their original Java class. Foreign predicates that have small floats, decimals or references as arguments are also possible. Otherwise no major changes to the application programming interface were necessary.

Page 38: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 38 of 77

3.5 Interaction ProtocolThe duties of a foreign predicate are minimized in that the interpreter automatically performs some housekeeping. The housekeeping includes rolling back the variable creations and in-stantiations made by the foreign predicate. The housekeeping varies on whether the foreign predicate is deterministic or not. It is based on two primitive operations that allow manipulat-ing the variable bindings and variable creations performed by a predicate. Variable bindings are typically established during unification whereas variable creations are needed for tempo-rary place holders.

The binding and creation of variables can be viewed as filling a log. It is possible to put a mark on the log via the method markFrame(). The log is filled by methods such asunifyTerm(), createVars(), etc... Via the method releaseFrame() the log can be reset to the given mark. As a result all variable bindings and variable creations from the top back to the mark are rolled back. The log does not only support a single mark. It is possible to create multiple marks and if needed one can rollback over multiple marks.

Top

Top

Mark

Top

Top

Mark

Before Call ofmarkFrame()

Before some Work

Before Call ofreleaseFrame()

After Call ofreleaseFrame()

Picture 9: Log Primitives

The log is only a simplified view of what is provided by the system. For example the body variable optimization will remove unused variable bindings and variable creations between the last mark and the top. It will thus reduce the size of the log without following the two prim-itive operations markFrame() and releaseFrame(). Operations for the body variable optimiza-tion are currently not exposed in the Jekejeke Prolog API.

The system now keeps one important mark always on the current. It is the tail recursion bar-rier. This mark indicates the variable bindings and variable creations up to the last choice point. Characteristic of a deterministic predicate is that it will not create a new choice pointand it will therefore never move the tail recursion barrier. A deterministic predicate will either fail or succeeds, but it will never be retried because of its lack of a choice point. The system provides some automatic housekeeping for deterministic predicates.

When a deterministic predicate succeeds the system will automatically call the next goal in the continuation goal list. When a deterministic predicate fails the system will automatically retry the last choice point. When a choice point is tried it will use the tail recursion barrier to roll back the log, provided it is interested in variable bindings or the variable count.

Page 39: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 39 of 77

Top

Top

Barrier

Before Call of the Predicate

After Exit of the Predicate

Barrier

TopBarrierBefore Call of the Continuation

TopBarrierAfter Fail of the Predicate

Before Retry of Choice Points

TopBarrier

Picture 10: Housekeeping for Deterministic Predicates

Both failed and successful deterministic predicates might fill the log. That a failed predicates might fill the log is a feature that saves some operations. The failed predicate might have allocated some place holders and attempted unification. The failed predicate does not need to establish its own mark and perform a rollback on its own. It can simple delegate this task to the housekeeping of the system.

The tail recursion barrier is also involved in non-deterministic predicates that create choice points. In this respect there is no difference between the first call of a deterministic or non-deterministic predicate. Both deterministic and non-deterministic predicates are called with a tail recursion barrier in place. The predicate can then do some work and call the method markFrame(). The predicate might also then do some further work. If the work did not lead to some result it might call releaseFrame().

If the predicate is satisfied with the result and if it desires a choice point it might then turn the mark into a new barrier. For this purpose it has to call the method swapBarrier(). The predi-cate will then indicate that it wants a choice point via the method setRetry(). The predicatewill also have called setData() so as to tell the system the desired barrier mark. The house-keeping of the system is such that it will create the choice point and call the next goal in the continuation goal list.

Back tracking is usually caused by a deterministic or non-deterministic predicate that failsafter a sequence of deterministic predicates that succeeded. The system will first do the normal book keeping for a failed predicate. This consists in rolling back the log to the now new barrier and retrying the choice point. The choice point for the predicate will then invoke the predicate with getFirst() returning false. The return of false by this method informs the predicate that the invocation is not a call but a redo.

It is also possible for the predicate to attach some additional information besides a barrier mark to the choice point. The sole possibility to do this is also the method setData(). The easiest approach is to define a class for the desired data structure and add enough instance fields to the class. Upon redo the additional information and the barrier mark can then be retrieved via the method getData(). Upon redo a predicate has first to undo its move of the barrier via the method swapBarrier(). The predicate can then also call again releaseBind()before doing some further work.

Page 40: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 40 of 77

Top

Top

Barrier

Before Call of the Predicate

Before Call of markFrame()

Barrier

TopBarrierBefore Call of Continuation

Before Retry of the Predicate

Before Call of swapBarrier()

Before Call of swapBarrier()

TopBarrier Mark

TopBarrier

TopBarrierMark

Before Call of releaseBind()

TopMarkBarrier

TopBarrier

After Call of releaseBind()

Picture 11: Housekeeping for Non-Deterministic Predicates

Since the barrier handling is very tedious the interpreter does default barrier handling for non-deterministic predicates. Since intervention is impossible the default handling can be switched off by the method setSpecial(). There can be situations where no barrier handling at all is necessary. This is for example the case for certain patterns of doing a call-in by the predicate since the call-in API does already barrier handling. Other situations might require more custom control.

There is also a housekeeping defined for local cuts, normal cuts and execution errors. All three events have in common that they do not simply restore a particular mark. Local cuts rollback all choice points inside the current rule. Normal cuts rollback all choice points skip-ping cut transparent rules. Execution errors rollback all choice points in the Prolog processor invocation. Currently to be able to handle execution errors new Prolog processor invocations are created, inside which the execution error can happen and then returning to the previous Prolog processor invocation to perform the execution error handling.

Page 41: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 41 of 77

3.6 Foreign Function InterfaceThe Prolog interpreter provides an internal API that allows defining built-in predicates and evaluable functions. This internal API is not public available since it is an unsafe API. The API is based on passing directly the skeleton and display data structures which could then potentially be modified by client code and make the Prolog interpreter unusable. On the other hand the internal API allows realizing fast built-ins with a broad functionality.

For less time critical and specialized predicates and evaluable functions we provide an ex-ternal API here. This API consists of the already described interpreter, knowledgebase, term and special objects. The main use cases are call-in and call-out. In this section we explain in more detail which automatic call-out mechanisms are provided by the Prolog interpreter. The call-out mechanism is based on associating a knowledge base member with a Java class member.

On the knowledge base side the members can be either predicates or evaluable functions. When using the foreign_XX/3 directive the application programmer can freely choose a name for a predicate or an evaluable function. It is also possible to use qualified names and/or to place foreign_XX/3 directives inside a module. The necessary arity depends on the associat-ed Java class member. Among the Java class members we find Constructors, Methods and Fields. Only public members are accepted, and setter Field member must not be final.

Table 2: Java Class ArgumentsKnowledge Base Class Member Parameter Types Return TypePredicateConstructor Constructor <Constructor Paras> <Declared Class>Method Method <Method Paras> <Method Return>Getter Field None <Field Type>Setter Field <Field Type> VoidEvaluable FunctionFunction Method <Method Paras> <Method Return>Constant Field None Field Type

A parameter type of the Java class member of type Interpreter or CallOut is not counted. All other parameter types are counted as an input Prolog argument. If the Java class member is non-static then the knowledge base member has an additional input Prolog argument in the first position which will be a reference to the receiver object. If the Java class member has a return type then the knowledge base member has an addition output Prolog argument in the last position.

The parameter types determine the de-normalization applied to the input Prolog argument before calling the Java class member. Evaluable function input arguments are first evaluated before the de-normalization. The return type determines the normalization applied to the Ja-va value before unifying with the output Prolog argument. If the Java class member throws an exception during invocation the exception is mapped to a Prolog term and this error is further thrown by the Prolog interpreter.

Page 42: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 42 of 77

Table 3: Java Array Class ArgumentsKnowledge Base Parameter Types Return TypePredicateDimension int <Declared Class>Element int <Component Type>Update int, <Component Type> VoidEvaluable FunctionLength None intMember int <Component Type>

With release 1.1.2 it is also possible to register delegates for Java array classes. Except for the constructor these delegates expect the array instance as a receiver object. The dele-gates use the component type of the Java array class to determine the desired de-normalization and normalization. The same component types are supported as for the pa-rameters types and return type of Java class members.

Page 43: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 43 of 77

3.7 Auto Loaded ClassesWith release 1.0.9 the Prolog interpreter provides auto loading of modules. This happens when a qualified predicate or evaluable function call is specified and the specified module has not yet been loaded. The auto loader will try Prolog modules and Java classes. For a Java class the auto loader will on the fly generate a synthetic module. This synthetic module is only generated once so that further access to the module can profit from the polymorphic cache in each call-site of the qualified predicate or evaluable function call.

The synthetic module consists of a number of automatically generated foreign_XX/3 direc-tives. The choice of a predicate or evaluable function name is replaced by an automatic choice by the auto loader. The end-user can thus not anymore choose a custom predicate or evaluable function name for an auto loaded Java class member. Which is not a great loss since the call is anyway qualified by the module name and there will be no ambiguity in the determination of the Java class.

For methods and fields the auto loader will first try to automatically generate an evaluable function or constant. This is only possible if the parameter types and the return type are all numbers. If the signature of the method or the type of the field does not allow creating an evaluable functor or constant the auto loader will then attempt creating a method predicate respectively a getter predicate.

Table 4: Java Class FunctorKnowledge Base Class Member FunctorPredicateConstructor Constructor newMethod Method <Method Name>Getter Field <Field Name>Setter Field set_<Field Name>Evaluable FunctionFunction Method <Method Name>Constant Field <Field Name>

On the other hand there can be a collision inside a Java class itself since the Java language allows overloading of method and constructor names by different parameter types. The actu-al implementation of the auto loader will create a predicate that will branch into the different variants of the same method or constructor name depending on the actual type of the argu-ments at runtime. For evaluable functions additionally a bridge between the evaluable func-tion and the branching predicate will be created.

The branching code will also respect the specificity of the formal parameters of a Java class member. For this purpose we obtain a scoring of the formal parameters and sort the Java class members accordingly. The scoring currently works for both primitive and non-primitive Java data types. If a Java class extends a parent Java class the ancient members that are not overridden are also considered in the branching. The branching is then a call into the ancient Prolog predicate.

Page 44: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 44 of 77

Table 5: Java Array FunctorKnowledge Base FunctorPredicateDimension newElement atUpdate set_atEvaluable FunctionLength lengthMember at

With release 1.1.2 the auto loader will also automatically register delegates for Java array classes. For array element access the auto loader will first try to automatically generate an evaluable member access. This is only possible if the component type is a number. If the component type does not allow creating an evaluable member access the auto loader will then attempt creating a predicate element access.

Page 45: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 45 of 77

3.8 Proxy Generated ClassesWith release 1.0.10 the Prolog interpreter can generate Java classes from modules. The module must be either a Prolog text loaded from a text source or a dynamic module. A di-rective allows preparing a module as a Java class. During the preparation step the set of interfaces is collected from the re-exported auto loaded Java classes.

The Java class will be a Java proxy class with an invocation handler. This invocation handler will dispatch method calls to the module. Currently the invocation handler assumes that each method is mapped either to a predicate or an evaluable function which is deterministically called. This might improve in the future. The mapping is done by unpacking the actual Java parameters into Prolog terms, building an appropriate goal, calling the goal via an interactorand packing the result.

When building an appropriate goal, the formal parameter types are ignored. Thus overloaded methods are mapped to the same predicate or evaluable functions. The methods need not have an Interpreter and/or CallOut formal parameter type. The invocation handler will auto-matically determine the current interpreter form the current thread and use this interpreter to obtain the interactor.

Table 6: Generated Prolog NamesKnowledge Base Class Member Prolog NamePredicateMethod Method <Method Name>Evaluable FunctionFunction Method <Method Name>

The only information from the method signature that is used is the fact whether the method is static or not and the fact whether the method is a function or not. Non-static methods will have an additional first parameter the goal for the current Java proxy class instance. Func-tion methods will have an additional last Prolog variable parameter in the goal for the result of the method invocation.

Since we use the Java bundled Proxy facility the handler will only deal with methods from the given set of interfaces that the module has re-exported. This might improve in the future. The Java proxy class will exist parallel to the proxy marked module. As a result the members of the module can be still invoked by the (:)/2 Prolog operator. The invocation handler only comes into play when a Java proxy class instance is invoked.

Page 46: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 46 of 77

4 Knowledgebase & Term APIThe knowledge base class provides a handle to clauses and operator definitions. The term sub classes mirror the Prolog data types. Primitive data types can be directly constructed via the corresponding term constructors. The common base class for the term sub classes is the class Term. Terms uniformly provide comparison and printing.

This part of the API has the following class diagram:

Picture 12: Class Diagram Knowledgebase & Term API

This part of the API consists of the following classes:

Class Knowledgebase: This class represents a knowledge base.

Class RuntimeWrap: The class allows wrapping checked exceptions.

Interface Slots: The slots interface for a state-full proxy.

Class Term: This class provides access to Prolog terms.

Class TermAtomic: This class provides an atomic wrapper and number access.

Class TermCompound: This represents a compound term.

Class TermVar: This represents a variable term.

Page 47: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 47 of 77

4.1 Class KnowledgebaseThis class represents a knowledge base. A knowledgebase can be created via its constructorthat takes a toolkit and optionally a hint. The hint can indicate whether the knowledge base is used in a GUI or non-GUI environment. The application programmer might subclass the knowledgebase class if needed. The toolkit associated with a knowledge base can be ac-cessed by the method getToolkit().

An interactor can be obtained from a knowledge base via the method iterable(). After crea-tion, the knowledge base will be uninitialized. To initialize the knowledge base the methods initKnowledgebase() can be used. This will initialize the capabilities already defined in the toolkit. The method finiKnowledgebase() will finish the currently initialized capabilities of the knowledge base and render the knowledge base unusable.

A knowledgebase provides a context for a base URL. The base URL is used in resolving relative write paths. The GUI and the non-GUI console will initialize the base URL to the cur-rent user directory. Otherwise the base URL is left uninitialized. A knowledgebase also pro-vides a context for a locale. The GUI console will initialize the locale to the settings. Other-wise the locale is set to the JVM locale.

A knowledge base also provides a context for a class path. The class path is used in resolv-ing path/1 and library/1 read paths. The class path is also used to resolve class names. Classes can be loaded via the method stringToClass(). The method respects short hands as defined in the foreign function interface. The possibly shortened class name can be recon-structed by the method classToString().

The method addClassPath() allows adding further paths to the class loader. The currently added paths can be queried with the method getClassPaths(). Depending on the platform the adding of class paths might defer the creation of a class loader. The creation of a class load-er can be forced via the method getCommittedLoader(). The GUI console will automatically add the paths defined in the settings. The GUI and the non-GUI console will also add the paths defined in the command line.

The method stringToCapability() allows retrieving a capability by name. The capability need not already be defined in the toolkit. All that is need is that the corresponding class is found in the added paths. The method capabilityToString() allows reconstructing the lookup name. The method getCapabilities() allows querying the currently initialized capabilities of the knowledge base.

The getErrorProperties() allows retrieving the union of all error properties that have been loaded and registered so far. The method might return different properties for different lo-cales. The method getCache() gives the actual local cache for a given error property. To find a cache the error property need not be registered but at least loaded.

package jekpro.tools.term;

import java.util.ArrayList;import java.util.Locale;import java.util.Properties;import java.util.HashMap;import matula.util.system.AbstractDecoder;import matula.util.system.AbstractRecognizer;

public class Knowledgebase extends AbstractRecognizer {public final static String OP_ON;public final static String OP_OFF;

Page 48: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 48 of 77

public final static String OP_NIL;public final static String OP_CONS;public final static String OP_SUB;public final static String OP_TRUE;

public Knowledgebase(Toolkit k)throws InterpreterMessage;

public Knowledgebase(Toolkit k, int hint)throws InterpreterMessage;

public Toolkit getToolkit()public Interpreter iterable();public static void initKnowledgebase(Interpreter inter)

throws InterpreterMessage, InterpreterException;public static void initKnowledgebase(Interpreter inter, boolean prompt)

throws InterpreterMessage, InterpreterException;public void finiKnowledgebase()

throws InterpreterMessage;

public Class<?> stringToClass(String c) throws InterpreterMessage;

public String classToString(Class<?> c);public void addClassPath(String path)

throws InterpreterMessage;public ArrayList<String> getClassPaths();public ClassLoader getCommittedLoader ();

public Capability stringToCapability(String n)throws InterpreterMessage;

public ArrayList<Capability> getCapabilities();

public AbstractDecoder pathToDecoder(String path);public String pathToRelative(String path);

public Properties getErrorProperties(Locale locale);public HashMap<String,Properties> getCache(String key);

}

Page 49: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 49 of 77

4.2 Class RuntimeWrapThe class indicates that a checked exception happened. This is currently used for interfaces such as Comparator, Runnable, etc.. that don't allow checked exceptions. The exception is understood by foreign/3 defined predicates and evaluable functions, and the exception is used in our Prolog Java proxy classes.

package jekpro.tools.term;

public final class RuntimeWrap extends RuntimeException {

public RuntimeWrap(Exception e);

}

Page 50: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 50 of 77

4.3 Interface SlotsThe slots interface for a state-full proxy. The interface allows accessing and modifying the slots of a proxy instance. The slots are indexed starting with 1. The number of the slots is specified when creating the proxy instance.

The methods arg() and set_arg() tolerate an index that is outside the range 1..size where size is the number of slots and indicate a failure. The method arity() returns the size of the given proxy instance.

package jekpro.tools.term;

public interface Slots {Term arg(int idx);boolean set_arg(int idx, Term data);int arity();

}

Page 51: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 51 of 77

4.4 Class TermThis class provides writing, reading, unification and copying of Prolog terms. The Java to Prolog API does provide specific data types for all Prolog terms. But the end-user has choic-es, he might have Prolog atomics unwrapped. Only compounds and variables need always be wrapped, since the API data type aggregates a skeleton and display.

The external API roots the terms either in the Java Object class or in the Term class. In both cases the hashCode(), equals() and toString() methods of the Java Object class can be used. The realization is such that that even for non-ground Prolog terms these methods cor-respond to the Prolog term_hash/2, ==/2 and write/1..

The toString() methods convert a term to a string. If an interpreter is supplied operator defini-tions will be available and variable are dereferenced. The following flags are recognized. The method with an option term recognizes all options from the write_term/2 predicate, but can-not handle a null interpreter. The following flags are available:

FLAG_QUOTED: Quote atoms when necessary. FLAG_NUMBERVARS: Write $VAR(n) as a variable name. FLAG_IGNORE_OPS: Ignore operator definitions. FLAG_IGNORE_MOD: Ignore module prefixes.

The parseNumber() method converts a string to a number term. The parseTerm() methods convert a string or stream to a term. The method that takes a string doesn't require that the term is terminated by a period and returns null when an empty string has been supplied. The method with an option term recognizes all options from the read_term/2 predicate and re-turns null when the option unification fails.

The method unifyTerm() attempts a unification. For performance reasons a failed unification might leave variable bindings. If the variable bindings need an undoing by the applicationprogram it is bested to use unification in combination with an empty interactor, see also the class Interpreter.

The method copyTerm() creates a copy of the given term. The method will create new com-pounds for those sub branches of the original term that either contain variables or that need to dereference variables and don't lead to atomics. The method variant copyTermWrapped()returns a wrapped result.

package jekpro.tools.term;

public abstract class Term {public static final int FLAG_QUOTED = 1;public static final int FLAG_NUMBERVARS = 2;public static final int FLAG_IGNORE_OPS = 4;public static final int FLAG_IGNORE_MOD = 8;

public static String toString(int flags, Object t);public static String toString(int flags, Interpreter inter, Object t);public static void toString(Writer wr, int flags, Interpreter inter,

Term t) throws InterpreterMessage, IOException;public static void toString(Writer wr, Object opt, Interpreter inter,

Object t) throws InterpreterMessage, IOException;

public static Object parseNumber(String s, Interpreter inter) throws InterpreterException;

public static Object parseTerm(String s, Interpreter inter) throws InterpreterException;

Page 52: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 52 of 77

public static Object parseTerm(Reader lr, Interpreter inter) throws InterpreterException;

public static Term parseTermWrapped(Reader lr, Object opt, Interpreter inter) throws InterpreterException;

public static boolean unifyTerm(Interpreter inter, Object fst,Object snd) throws InterpreterException;

public static Object copyTerm(Interpreter inter, Object t);public static Term copyTermWrapped(Interpreter inter, Object t);

}

Page 53: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 53 of 77

4.5 Class TermAtomicThis class can also be used to wrap strings, numbers and references. The constructor takes an unwrapped atomic and gives a wrapped atomic. There are two advantages of wrapped atomics. Firstly they fit into the Term class hierarchy. Secondly wrapped strings can carry call-site information and the polymorphic cache.

This class also provides access, guard, normalization and widening for the Prolog number data type. The Java to Prolog API does not provide specific data types for the number data type. Instead directly the various types in the hierarchy of the Java Number class are used.

The Prolog integer data type is represented either as a Java Integer class or as a Java BigInteger class. The methods normBigInteger() allow normalizing into a Prolog integer data type. The method widenBigInteger() allows widening into the Java BigInteger class.

The Prolog float data type is represented either as a Java Float class or as a Java Double class. The methods guardFloat() and guardDouble() allow sanitizing a Java float data type into a Prolog float data type.

The Prolog decimal data type is represented either as a Java Long class or as a Java BigDecimal class. The methods scale() and unscaledValue() allow accessing the compo-nents of a Prolog decimal data type. The methods normBigDecimal() allow normalizing into a Prolog decimal data type. The method widenBigDecimal() allows widening into the Java BigDecimal class.

package jekpro.tools.term;

public final class TermAtomic extends Term {public TermAtom(Object s);public Object getValue();

public int hashCode();public boolean equals(Object o);public String toString();

public static Number normBigInteger(long val);public static Number normBigInteger(BigInteger i);public static BigInteger widenBigInteger(Number m);

public static Float guardFloat(Float f)throws ArithmeticException;

public static Double guardDouble(Double d) throws ArithmeticException;

public static int scale(Number n);public static BigInteger unscaledValue(Number n);public static Number normBigDecimal(BigDecimal d);public static Number normBigDecimal(BigInteger m, int s);public static BigDecimal widenBigDecimal(Number m);

}

Page 54: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 54 of 77

4.6 Class TermCompoundThis represents a compound term. There are two functor and argument based constructor. The constructor without the interpreter parameter assumes that the arguments belong to the same variable set. The constructor with the interpreter parameter can deal with arguments that belong to different variables sets.

The constructors have been declared with variable arguments so that multiple arguments can be easily specified by simply adding them to the constructor call. The later constructor might create variable bindings as a side effect. But it is recommended over the now depre-cated method createCompound().

The functor and arity can be retrieved by the methods getFunctor() and getArity(). An individ-ual argument can be retrieved by the method getArg(). The later method will automatically do a dereferencing. The method variants getFunctorWrapped() and getArgWrapped() returnwrapped results.

package jekpro.tools.term;

public final class TermCompound extends Term {public TermCompound(String sym, Object... args);public TermCompound(TermAtomic sym, Object... args);public TermCompound(Interpreter inter, String sym, Object... args);public TermCompound(Interpreter inter, TermAtomic sym, Object... args);

public int hashCode();public boolean equals(Object o);public String toString();

public String getFunctor();public TermAtomic getFunctorWrapped();public int getArity();public Object getArg(int k);public Term getArgWrapped(int k);

}

Page 55: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 55 of 77

4.7 Class TermVarThis represents a variable term. New variables can be created via the method createVars(). This will create multiple variables that share the same display. These variables will have as-cending local indexes.

The serial number can be retrieved via getValue(). If the interpreter is null then the local in-dex is returned. If the interpreter is non-null then if necessary a new serial number is created and this serial number is returned.

A variable can be dereferenced by the method deref(). Dereferencing a un-instantiated vari-able yields the variable itself. Dereferencing a variable that is bound to a term yields this term or the dereferencing of this term when the term was a variable again. The method variant derefWrapped() returns a wrapped result.

package jekpro.tools.term;

public final class TermVar extends Term {public static TermVar[] createVars(int n);public int getValue(Interpreter inter);

public int hashCode();public boolean equals(Object o);public String toString();

public Object deref();public Term derefWrapped();

}

Page 56: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 56 of 77

5 Call & Interpreter APIThe interpreter class is the working horse. On the knowledge base side the interpreter sup-ports initialization and the definition of Java foreign predicates. On the term side the inter-preter supports parsing and un-parsing of terms. The interpreter also supports variable and compound creation, as well as unification. Finally the interpreter provides a set of methods to invoke Prolog goals. The call-in class is used when non-deterministically calling Prolog whereas the call-out class is used by non-deterministic Java foreign predicates.

This part of the API has the following class diagram:

Picture 13: Class Diagram Call & Interpreter API

This part of the API consists of the following classes:

Class CallIn: This class represents a call-in.

Class CallOut: This class represents a call-out.

Class Capability: This class represents the base for all capabilities.

Class Controller: This class represents what is common for interactors.

Class Interpreter: This class represents an interactor.

Class InterpreterException: This class defines an interpreter exception which consists of a message, eventually a text location and a back trace.

Class InterpreterMessage: This class defines an interpreter message which con-sists of a message only.

Class Toolkit: This class represents the base for all toolkits.

Page 57: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 57 of 77

5.1 Class CallInThe call-in object can be obtained from an interpreter by providing optionally a goal and op-tionally a result by the iterator() methods. A call-in object is needed to interact with choice points and variable bindings. Thus call-in objects are needed when Prolog goals are called.The application programmer cannot subclass the call-in class.

The method hasNext() can be used check whether the interactor can be advanced. Initially the interactor is positioned before the first solution. The method next() effectively advances the interactor. The method throws a NoSuchElementException when there was no solution.The method close() closes an interactor. The method need not be called when there was no solution.

The method getNondet() allows checking whether there are choices and potentially further solutions. Further solutions can be prevented by calling the method cut() which will remove choice points. As a result the method getNondet() will return false. An alternative way to close an interactor is to use the method cleanup(). This method takes an initial exception which will accumulate further exceptions during closing.

It is possible to use call-in objects to implement meta-predicates, provide the special directive is given to the CallOut argument. But because separate choice points and tail recursion bar-rier are created for invoked goals, it is not possible to program cut transparent arguments for meta-predicates this way.

Inside the Prolog execution of hasNext() or next() or when these methods have been com-pleted during Java execution it is allowed to create and use further call-in objects, as long as the interaction with these objects is complete. For non-stack use call-in objects have to be drawn from multiple interpreters inside the same thread.

The method nextClose() throws an exception when the interactor failed, the method hasNextClose() returns null when the interactor failed. These methods will copy the result term and always close the interactor. The later behaviour might be not appropriate if a varia-ble binding side effect of the goal is desired. The method run() acts similar to nextClose() but swallows failure and exceptions.

package jekpro.tools.call;

public final class CallIn implements Runnable {public boolean hasNext() throws InterpreterException;public Object next()

throws InterpreterMessage, InterpreterException;public void close() throws InterpreterException;public boolean getNondet();public void cut() throws InterpreterException;public InterpreterException cleanup(InterpreterException x);public Object nextClose()

throws InterpreterMessage, InterpreterException;public Object nextCloseWrapped()

throws InterpreterMessage, InterpreterException;public Object hasNextClose()

throws InterpreterMessage, InterpreterException;public Object hasNextCloseWrapped()

throws InterpreterMessage, InterpreterException;public void run();

}

Page 58: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 58 of 77

5.2 Class CallOutThis class represents a call-out. Call-out objects cannot be directly constructed by the appli-cation programmer. A call-out object is created by the interpreter and passed to a foreign predicate if it has such a parameter.

Foreign predicates can be programmatically registered via the method defineForeign() of the Interpreter class in the programming interface or by invoking the built-in foreign/3. The ac-cepted formal parameters and their interpretation are listed in the language reference docu-mentation. A formal parameter of type Interpreter is needed for foreign predicate that change variable bindings. A formal parameter of type CallOut is needed for non-deterministic foreign predicates.

The API of the CallOut allows fine control of choice points. Via the method getFirst() the for-eign predicate can query whether it was called for the first time. Via the method setRetry()the foreign predicate can indicate that it desires a choice point. The methods setData() and getData() can be used to access client data in the choice point.

In case a choice point was desired the foreign predicate can additionally indicate via the method setCutter() whether it desires to be notified when the choice point is cleaned up. Choice points are cleaned up by the interpreter when a cut occurs in the continuation, when an exception occurs in the continuation or when the search is externally terminated. Via themethod getCleanup() the foreign predicate can query whether it is called for a clean-up.

During a clean-up the foreign predicate can query the current exception via the method getException(). If needed it can then accumulated further exceptions and store the new cur-rent exception via the method setException().

By default the interpreter does barrier handling for non-deterministic foreign predicates. This includes invoking markFrame() prior to invoking a foreign predicate and then when the predi-cate succeeds swapBarrier (). This also includes invoking swapBarrier() and releaseFrame()upon redo of the foreign predicate. Finally this also includes invoking swapBarrier() during a clean-up for foreign predicates with a cutter. The method setSpecial() allows switching off this default barrier handling.

package jekpro.tools.call;

public final class CallOut {public boolean getFirst();public boolean getCleanup();public void setRetry(boolean r);public void setCutter(boolean c);public void setSpecial(boolean s);public Object getData();public void setData(Object o);public InterpreterException getException();public void setException(InterpreterException o);

}

Page 59: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 59 of 77

5.3 Class CapabilityThis class represents the base for all capabilities. A capability can be associated to a knowledge base and initialized via the method initCapability(). A capability can be finalized and de-associated from a knowledge base via the method finiCapability().

A capability has certain properties, some do exist already when the capability has not yet been associated and some are specific to the association of the capability to a knowledge base. The properties can be retrieved via the method getProperty().

Capabilities govern resources. To access a resource inside a capability the method prepareStream() has to be used. Further the method getDescriptionProperties() allows re-trieving the description properties of this capability. The method might return different proper-ties for different locales.

package jekpro.tools.call;

import java.util.Locale;import java.util.Properties;

public class Capability {public static final String PROP_NEEDS_ACT = "needs_act";public static final String PROP_ACT_STATUS = "act_status";public static final String PROP_EXPIRATION_DATE = "expiration_date";public static final String PROP_BUNDLE_DIR = "bundle_dir";public static final String PROP_IMAGE_ICON = "image_icon";public static final String PROP_BIG_IMAGE_ICON = "big_image_icon";public static final String PROP_SYS_NOTRACE = "sys_notrace"; public static final String PROP_LANGUAGE_CODE = "language_code";public static final String PROP_INSTALL_CODE = "install_code";public static final String PROP_LICENSE_CODE = "license_code";

public void initCapability(Interpreter inter) throws InterpreterMessage, InterpreterException;

public void initCapability(Interpreter inter, boolean prompt) throws InterpreterMessage, InterpreterException;

public void finiCapability(Knowledgebase know) throws InterpreterMessage;

public Object getProperty(String prop, Knowledgebase know) throws InterpreterMessage;

public InputStream prepareStream(InputStream in, Interpreter inter)throws InterpreterMessage, IOException;

public Properties getDescriptionProperties(Locale locale);}

Page 60: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 60 of 77

5.4 Class ControllerThe controller object cannot be manually created. It is automatically created when an inter-preter is obtained from a knowledge base, and it is shared when an interpreter is forked from an interpreter. The controller carries the basic input/output streams and thread local predi-cates of an interpreter. For an instrumented interpreter it might also carry spy points and break points.

In a multithreaded application an interactor running in a primary thread might be controlled by a secondary thread. A signal can be issued from a controlling thread by calling setSignal(m)where m is non-null. A signal can then be consumed from the controlled thread by calling throw getSignal(null) after catching InterruptedException.

package jekpro.tools.call;

public final class Controller {public Controller(Knowledgebase k);

public InterpreterMessage setSignal(InterpreterMessage m);}

Page 61: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 61 of 77

5.5 Class InterpreterThis class represents an interpreter. The interpreter object can be obtained from a knowledge base by the iterable() method. Inside Prolog proxies the current interpreter can be retrieved via the static method currentInterpreter().The application programmer cannot sub-class the call-in class.

The knowledge base associated with an interpreter can be retrieved via the method getKnowledgebase(). The controller associated with an interpreter can be retrieved via the method getController(). If multiple interactors are needed a further interpreter object can be forked from an existing interpreter object by the iterable() method. Multiple interactors share the same controller.

To consistently compare variables their serial numbers are used. Serial numbers are allocat-ed and maintained similar to variable bindings in the interpreter. Lexical comparison is there-fore defined as a method compare() of the class Interpreter. This method corresponds to the Prolog predicate compare/3. The existence of this method is marked by the implemented interface Comparator.

The interpreter further carries choice points and tail recursion barriers. They are used when solving a goal. An interactor for a solution set can be obtained via the iterator() methods. The interactor can be controlled via the different methods of the interactor itself. For more details see the CallIn class.

Table 7: Java Class ISO Stream MappingISO Mode ISO Type Java Class

Read Text Stream ReaderBinary Stream InputStream

Write Text Stream WriterBinary Stream OutputStream

All Prolog flags can be accessed via the methods getProperty() and setProperty(). The set of available Prolog flags depends on the initialized capabilities and on the used toolkit. The properties that are defined inside the toolkit can be used before initKnowledgebase(). The properties that are defined inside a capability can be used after initKnowledgebase() and the corresponding initCapability(). For properties that represent streams the following Java clas-ses are used:

package jekpro.tools.call;

public class Interpreter implements Comparator<Object> {public Interpreter(Knowledgebase k, Controller c);

public Knowledgebase getKnowledgebase();public Controller getController();

public static Interpreter currentInterpreter(Thread t);public Interpreter iterable();public CallIn iterator();public CallIn iterator(Object goal);public CallIn iterator(Object result, Object goal);

public int compare(Object t1, Object t2)throws ArithmeticException;

public ArrayList<String> getProperties();public Object getProperty(String flag);

Page 62: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 62 of 77

public void setProperty(String prop, Object val) throws InterpreterMessage;

public String findKey(String path, String key, int mask)throws InterpreterMessage;

public String findPrefix(String name, String key, int mask)throws InterpreterMessage;

}

Page 63: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 63 of 77

5.6 Class InterpreterExceptionThis class defines an interpreter exception which consists of a message, eventually a text location and a back trace. This is typically thrown by the interpreter which has access to the text location and the back trace. The interpreter exception class cannot be sub-classed by the application programmer. But the application programmer can create and also throw inter-preter exceptions.

The application programmer can provide an arbitrary exception term to the basic constructor. A copy of the given term will be created and stored in the exception. The copied exception term can be retrieved via the method getValue().The location of the message term depends on the form of the exception term. The following exception terms are recognized:

error(Message, Context)warning(Message, Context)cause(Exception, Exception)Message

Alternatively the application programmer can provide a message and a context. This time error(Message, Context) will be created. Or the application programmer can provide a mes-sage, a context and a type. This will create <fun>(Message, Context). Further the constructor that takes two interpreter exceptions will create a cause/1 exception term.

There are a couple of convenience methods to create the context. The method fetchStack()retrieves the back trace from the current call chain. The method fetchPos() adds the text po-sition to a back trace. The method fetchLocation() adds the text location to a back trace.

The detailed message methods getMessage() will give the message term without the con-text. The variant without an interpreter argument can only display skeletons. The variant with an interpreter argument will attempt a user-friendly display. The printStackTrace() methods will attempt to produce a user-friendly display of the message together with the context. The variant without a writer argument will display to the error stream. The variant with a writer argument will produce the stack trace to this writer.

There are a couple of convenience methods to analyse the exception term. The method exceptionType() will return the Message when the original exception term does have the form <fun>(Message,_) or cause(<fun>(Message,_),_). Otherwise the method will return null. The method causeChainRest() will return the Rest when the original exception term does have the form cause(_,Rest). Otherwise the method will return null.

package jekpro.tools.call;

import java.io.Writer;

public class InterpreterException extends Exception {public InterpreterException(Object t);public InterpreterException(InterpreterMessage msg, Object ctxt);public InterpreterException(InterpreterMessage msg, Object ctxt,

String type);public InterpreterException(InterpreterException e1,

InterpreterException e2);

public Object getValue();public static Object fetchStack(Interpreter inter);public static Object fetchLocation(Object t, String o, int l,

Interpreter inter);

Page 64: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 64 of 77

public static Object fetchPos(Object t, String line, Interpreter inter);

public String getMessage();public String getMessage(Interpreter inter);public void printStackTrace(Interpreter inter)

throws InterpreterMessage;public void printStackTrace(Writer pw, Interpreter inter)

throws InterpreterMessage;public InterpreterMessage exceptionType(String fun);public InterpreterException causeChainRest();

}

Page 65: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 65 of 77

5.7 Class InterpreterMessageThis class defines an interpreter message which consists of a message only. This is typically thrown by the Java methods which do not have access to the stack. The interpreter message class cannot be sub-classed by the application programmer. But the application programmer can create and also throw interpreter messages.

The application programmer can provide an arbitrary message term. A copy will be created and stored when the constructor is invoked. The copy can be retrieved via the method getValue().

The methods toString() will un-parse the message term. The method without a knowledge base argument will only display the skeleton. The method without a knowledge base argu-ment will attempt to produce a user-friendly display by taking into account the message defi-nitions from the given toolkit.

The xxxError() methods provide conveniences to create message terms known from the ISO core standard. The checkXXX() methods provide convenience methods to check terms for certain conditions, and if these conditions are not met, a corresponding message is thrown. The castXXX() methods also return a type casted or unboxed value.

The method messageType() will return the Type when the original message term does have the form <fun>(Type). Otherwise the method will return null. The method mapIOException()will map an IOException to an InterpreterMessage. The latter method shouldn’t be used for InterruptedIOException, which should be handled by the Controller’s setSignal() method.

package jekpro.tools.call;

public final class InterpreterMessage extends Exception {public InterpreterMessage(Object t);

public Object getValue();public String toString();public String toString(Knowledgebase k);public Object messageType(String fun);

public static String instantiationError();public static Object typeError(String type, Object t);public static Object domainError(String type, Object t);public static Object representationError(String type);public static Object existenceError(String type, Object t);public static Object syntaxError(String type);public static Object syntaxError(String type, Object t);public static Object permissionError(String operation,

String type, Object t);public static Object systemError(String type);public static Object resourceError(String type);public static Object licenseError(String type);public static Object evaluationError(String type);

public static void checkInstantiated(Object t)throws InterpreterMessage;

public static void checkCallable(Object t)throws InterpreterMessage;

public static void checkNotLessThanZero(Number n)throws InterpreterMessage;

public static void checkCharacterCode(int n)throws InterpreterMessage;

Page 66: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 66 of 77

public static void checkByte(int n) throws InterpreterMessage;

public static void checkRef(Object t)throws InterpreterMessage;

public static String castString(Object t) throws InterpreterMessage;

public static Number castNumber(Object t)throws InterpreterMessage;

public static Number castInteger(Object t)throws InterpreterMessage;

public static int castIntValue(Number n)throws InterpreterMessage;

public static long castLongValue(Number n)throws InterpreterMessage;

public static int castCharacter(String s) throws InterpreterMessage;

public static InterpreterMessage mapIOException(IOException exception);

}

Page 67: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 67 of 77

5.8 Class ToolkitThis class represents the base for all toolkits. Each toolkit predefines a set of capabilities for a knowledge base. Further capabilities can be added to a knowledge base after its initializa-tion. Some capabilities need activation before they can be added to a knowledge base. Ca-pabilities can be activated via the activate dialog of the development environment. The li-cense texts are stored in the user preferences file.

It is also possible to activate license programmatically. The method activateCapability() does automatically activate a capability over an internet service. If you are behind a firewall, you can also query the install ID of a capability via the method calcInstallID(). You can then use the install ID together with a license key to obtain the license text. The license text can then be stored via the method regLicenseText().

The activation status of an initialized capability can be re-evaluated via the methodcheckLicense(). The overall activation status can be re-evaluated via the methodcheckLicenses(). The list of predefined capabilities can be retrieved via the method getInitCapabilities(). The brand capability among the predefined capabilities can be retrieved via the method getBrandCapability().

package jekpro.tools.call;

public abstract class Toolkit {public void activateCapability(Capability c,

String h) throws InterpreterMessage;public String calcInstallID(Capability c) throws InterpreterMessage;public void regLicenseText(Capability c,

String t) throws InterpreterMessage;public static void checkLicense(Capability c,

Knowledgebase k) throws InterpreterMessage;public static void checkLicenses(Knowledgebase k)

throws InterpreterMessage;public abstract Capability[] getInitCapabilities();public abstract Capability getBrandCapability();public String capabilityToString(Capability c);

}

Page 68: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 68 of 77

6 Headless APIThe runtime library provides a core set of predicates and executes code without instrumenta-tion. It is represented by a singleton.

This part of the API has the following class diagram:

Picture 14: Class Diagram Headless API

This part of the API consists of the following classes and messages:

Class ToolkitLibrary: The runtime library toolkit provides a knowledge base and an interpreter that is not instrumented for debugging.

Class CapabilityRuntime: The runtime library capability provides the system predi-cates as defined in the language reference of the runtime library.

Page 69: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 69 of 77

6.1 Class ToolkitLibraryThe runtime library toolkit provides a knowledge base and an interpreter that is not instru-mented for debugging. This class implements the singleton pattern. There is only one in-stance per Java class loader.

The class can be used to execute the development environment either with or without a graphical interface. For this purpose the main() method of the class can be statically called. The method will setup a knowledge base and an interpreter, and then enter a query answer loop. When started without a graphical interface, the method will also install a ^C interrupt handler for the duration of the interactive session.

The Android version of the class ToolkitLibrary does not provide a main() method and does not declare the constants for the command line options. Otherwise the class ToolkitLibrary is identical to the Swing version.

The main() method recognizes the following options:

-h: Don't create graphical user interface.

-a <path>,...:Add the paths <path>,....

-e <capability>,...:Add the capabilities <capability>,....

-b <goal>:Use <goal> as the banner.

-t <goal>: Use <goal> as the top level.

package jekpro.platform.headless;

import jekpro.tools.api.Toolkit;

public final class ToolkitLibrary extends Toolkit {public static final ToolkitLibrary DEFAULT;

public static final String OPTION_HEADLESS = "-h";public static final String OPTION_PATHS = "-a";public static final String OPTION_CAPABILITIES = "-e";public static final String OPTION_BANNER = "-b";public static final String OPTION_TOPLEVEL = "-t";

public static final String PROP_SYS_DISP_INPUT = "sys_disp_input";public static final String PROP_SYS_DISP_OUTPUT = "sys_disp_output";public static final String PROP_SYS_DISP_ERROR = "sys_disp_error";public static final String PROP_SYS_CUR_INPUT = "sys_cur_input";public static final String PROP_SYS_CUR_OUTPUT = "sys_cur_output";public static final String PROP_SYS_CUR_ERROR = "sys_cur_error";public static final String PROP_SYS_ATTACHED_TO = "sys_attached_to";public static final String PROP_BASE_URL = "base_url";public static final String PROP_SYS_LOCALE = "sys_locale";

public static void main(String[] args);}

Page 70: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 70 of 77

6.2 Class CapabilityRuntimeThe runtime library capability provides the system predicates as defined in the language ref-erence of the runtime library. It does not provide the system predicates of the language ref-erence of the development environment. This class implements the singleton pattern. There is only one instance per Java class loader.

This capability is already predefined by a toolkit and it need not be added to the knowledge base after its initialization. This capability does not need activation. It will be useable without activation. The capability also declares some well-known interpreter properties.

package jekpro.platform.headless;

import jekpro.tools.api.Capability;

public final class CapabilityRuntime extends Capability {public static final CapabilityRuntime DEFAULT;

public static final String PROP_SYS_MASK = "sys_mask";}

Page 71: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 71 of 77

7 Appendix Example ListingsIn the following we give a short summary of the files of each example program. The following example programs are provided:

Call-in Employees Table Call-in Exception Handling Call-out Employees Table Call-out Call-in Solution Counter Call-out Call-in Solution Limiter Custom Mutex Object Multiple Call-in Combiner Custom Queue Object

We have used the following directory layout for the sources (Java classes and Prolog texts) and the Jekejeke Prolog runtime library (interpreter.jar) during compilation. The Jekejeke Prolog runtime library can be downloaded from the Jekejeke web site (www.jekejeke.ch):

XXX.java % Java classesXXX.p % Prolog textslib+--- interpreter.jar

The examples can be compiled with the following command line on the windows platform. On the Linux and Mac OS platform the backslash (\) directory separator needs to be replaced by the slash (/). The command needs to be put on one line and the single standing backslashes (\) need to be removed so that the command can be issued:

javac -sourcepath . \-cp lib\interpreter.jar \-d classes \XXX.java

We have used the following directory layout for the byte code (compiled Java classes), the resources (Prolog texts) and the Jekejeke Prolog runtime library (interpreter.jar) during exe-cution. The byte code is automatically placed in the specified location by the previous compi-lation command line. The location of the Jekejeke Prolog runtime library has not been changed. The resources (Prolog texts) eventually need to be manually copied:

classes+--- XXX.class % Compiled Java classes+--- XXX.p % Prolog textslib+--- interpreter.jar

The examples can then be executed by the following command line on the windows platform. On the Linux and Mac OS platform the semicolon (;) path separator needs to be replaced by the colon (:):

java -cp classes; lib\interpreter.jar \XXX % Main Java class name

Page 72: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 72 of 77

This document does not contain the source code of the test programs. A browsable version of the source code of the test programs can be found on the following web site:

www.jekejeke.ch/idatab/doclet/prod/en/docs/05_run/10_docu/03_interface/09_appendix/package.html

Further the source code is also bundled in the suprun.zip when downloading the Jekejeke Prolog runtime library from the web site.

7.1 Call-in Employees TableFor the Call-in Employees Table example there are the following sources:

InTable.java: The Java Class tablein.p: The Prolog Text

7.2 Call-in Exception HandlingFor the Call-in Exception Handling example there are the following sources:

InThrow.java: The Java Class throwin.p: The Prolog Text

7.3 Call-out Employees TableFor the Call-out Employees Table example there are the following sources:

tableout.p: The Prolog Text OutTable.java: The Java Class

7.4 Call-out Call-in Solution CounterFor the Call-out Call-in Solution Counter example there are the following sources:

countoutin.p: The Prolog Text OutInCount.java: The Java Class

7.5 Call-out Call-in Solution LimiterFor the Call-out Call-in Solution Limiter example there are the following sources:

limitoutin.p: The Prolog Text OutInLimit.java: The Java Class

Page 73: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 73 of 77

7.6 Custom Mutex ObjectFor the custom mutex object example there are the following sources:

Mutex.java: The simple lock Java class. mutexobj.p: The Prolog text for the processes using foreign function interface. mutexobj2.p: The Prolog text for the processes using auto loading.

7.7 Multiple Call-in CombinerFor the Multiple Call-in Combiner example there are the following sources:

Combine.java: The combiner Java class. data.p: The data for the combiner.

7.8 Custom Queue ObjectFor the custom queue object example there are the following sources:

Counter.java: The counter Java class. counter2.java: The counter Prolog Java proxy class. Queue.java: The simple queue Java class. QueueEntry.java: The simple queue entry Java class. queueobj.p: The Prolog text for the process using Java class. queueobj2.p: The Prolog text for the process using Prolog Java proxy class.

Page 74: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 74 of 77

Index

absoluteWriteName(String) .......................................Class Interpreter, Class KnowledgebaseactivateCapability(Capability,String) .................................................................... Class ToolkitaddClassPath(String) .................................................................................... Class InterpreterATOM_CONS........................................................................................Class KnowledgebaseATOM_NIL ............................................................................................Class KnowledgebasecalcInstallID(Capability) ....................................................................................... Class ToolkitcapabilityToString(Capability) ................................................................Class KnowledgebasecauseChainRest()...........................................................................Class InterpreterExceptioncheckAtom(Term)............................................................................ Class InterpreterMessagecheckByte(Number)......................................................................... Class InterpreterMessagecheckCharacter(String).................................................................... Class InterpreterMessagecheckCharacterCode(Number)........................................................ Class InterpreterMessagecheckInstantiated(Term).................................................................. Class InterpreterMessagecheckInteger(Term) ......................................................................... Class InterpreterMessagecheckLicense(Capability,Knowledgebase)........................................................... Class ToolkitcheckLicenses(Knowledgebase) ......................................................................... Class ToolkitcheckNotLessThanZero(Number).................................................... Class InterpreterMessageclassToString(Class<?>) .......................................................................Class Knowledgebasecompare(Object,Object) ................................................................................ Class InterpretercreateCompound(Interpreter,Term...) ............................................................ Class TermAtomcreateVars(int)..................................................................................................Class TermVarDEFAULT..................................................................................................Class ToolkitLibrarydefineForeign(String,int,Method) ....................................... Class Interpreter, Class Interpreterderef() ..............................................................................................................Class TermVardomainError(String,Term)................................................................ Class InterpreterMessageequals(Object)....................................................................................................... Class TermexceptionType(String) ....................................................................Class InterpreterExceptionexistenceError(String,Term) ............................................................ Class InterpreterMessagefiniCapability(Knowledgebase) ....................................................................... Class CapabilityfiniKnowledgebase()..............................................................................Class KnowledgebaseFLAG_IGNORE_OPS ........................................................................................... Class TermFLAG_NUMBERVARS.......................................................................................... Class TermFLAG_QUOTED.................................................................................................... Class TermgetArg(int) ............................................................................................ Class TermCompoundgetArity()............................................................................................... Class TermCompoundgetBase()...............................................................................................Class KnowledgebasegetBigDecimalValue()................................................................................Class TermDecimalgetBigIntegerValue()................................................................................... Class TermIntegergetBrandCapability()............................................................................................ Class ToolkitgetCapabilities() ....................................................................................Class KnowledgebasegetClassPaths().....................................................................................Class KnowledgebasegetCleanup() ......................................................................................................Class CallOutgetCodePointValue() ..................................................................................... Class TermAtomgetCommittedLoader()...........................................................................Class KnowledgebasegetComparator() ...............................................................................................Class TermRefgetData() ............................................................................................................Class CallOutgetException() ....................................................................................................Class CallOutgetFirst().............................................................................................................Class CallOutgetFunctor().......................................................................................... Class TermCompoundgetInitCapabilities().............................................................................................. Class ToolkitgetIntValue()............................................................................................... Class TermIntegergetKnowledgebase()...................................................................................... Class Interpreter

Page 75: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 75 of 77

getLongValue()........................................................................................... Class TermIntegergetMessage() .......................................Class InterpreterMessage, Class InterpreterExceptiongetMoneyValue() .......................................................................................Class TermDecimalgetNondet() ...........................................................................................................Class CallIngetProperty(String) ........................................................................................ Class InterpretergetProperty(String,Knowledgebase)............................................................... Class CapabilitygetToolkit() ............................................................................................Class KnowledgebasegetValue().................. Class InterpreterMessage, Class InterpreterException, Class TermRef,

Class TermInteger, Class TermFloat, Class TermDecimal, Class TermAtomgetValue(Interpreter) ........................................................................................Class TermVarhashCode() ........................................................................................................... Class TerminitCapability(Interpreter) ................................................................................ Class CapabilityinitCapability(Interpreter,boolean)................................................................... Class CapabilityinitKnowledgebase()...................................................................................... Class InterpreterinitKnowledgebase(boolean) ......................................................................... Class InterpreterinstantiationError()........................................................................... Class InterpreterMessageInterpreter(Knowledgebase) .......................................................................... Class InterpreterInterpreterException(InterpreterException,InterpreterException) ....Class InterpreterExceptionInterpreterException(InterpreterMessage,Interpreter) .....................Class InterpreterExceptionInterpreterException(InterpreterMessage,String,Interpreter,String).Class InterpreterExceptionInterpreterException(Term).............................................................Class InterpreterExceptionInterpreterMessage(Term)............................................................... Class InterpreterMessageKnowledgebase(Toolkit) ........................................................................Class Knowledgebasemain(String[]).............................................................................................Class ToolkitLibrarymarkFrame(Interpreter) ................................................................................. Class CallFramemessageType(String) ...................................................................... Class InterpreterMessageOPTION_BANNER....................................................................................Class ToolkitLibraryOPTION_ENLIST.....................................................Class ToolkitLibrary, Class ToolkitLibraryOPTION_HEADLESS................................................................................Class ToolkitLibraryOPTION_TOPLEVEL ................................................................................Class ToolkitLibraryparseTerm(String) ......................................................................................... Class InterpreterpermissionError(String,String,Term) ................................................ Class InterpreterMessageprintStackTrace(Writer,Interpreter) .................................................Class InterpreterExceptionprintStackTrace(Writer,Term,Interpreter) ........................................Class InterpreterExceptionPROP_ACT_STATUS.................................................................................... Class CapabilityPROP_BIG_IMAGE_ICON............................................................................. Class CapabilityPROP_BUNDLE_DIR..................................................................................... Class CapabilityPROP_EXPIRATION_DATE .......................................................................... Class CapabilityPROP_FAMILY_DESCR................................................................................ Class CapabilityPROP_HELP_DOCS...................................................................................... Class CapabilityPROP_IMAGE_ICON..................................................................................... Class CapabilityPROP_LANGUAGE_DESCR......................................................................... Class CapabilityPROP_LICENSE_DESCR.............................................................................. Class CapabilityPROP_NEEDS_ACT...................................................................................... Class CapabilityPROP_PLATFORM_DESCR ......................................................................... Class CapabilityPROP_PRODUCT_DESCR ........................................................................... Class CapabilityPROP_SHOP_URL........................................................................................ Class CapabilityPROP_SYS_ATTACHED_TO...................................................................Class ToolkitLibraryPROP_SYS_CUR_ERROR.......................................................................Class ToolkitLibraryPROP_SYS_CUR_INPUT.........................................................................Class ToolkitLibraryPROP_SYS_CUR_OUTPUT.....................................................................Class ToolkitLibraryPROP_SYS_DISP_ERROR......................................................................Class ToolkitLibraryPROP_SYS_DISP_INPUT ........................................................................Class ToolkitLibraryPROP_SYS_DISP_OUTPUT ....................................................................Class ToolkitLibraryPROP_SYS_MASK........................................................................... Class CapabilityRuntimePROP_SYS_NOTRACE................................................................................. Class Capability

Page 76: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 76 of 77

regLicenseText(Capability,String)........................................................................ Class ToolkitreleaseFrame(Interpreter) ............................................................................. Class CallFramerepresentationError(String).............................................................. Class InterpreterMessageresourceError(String)....................................................................... Class InterpreterMessagesetBase(String)......................................................................................Class KnowledgebasesetCutter(boolean)..............................................................................................Class CallOutsetData(Object) ..................................................................................................Class CallOutsetException(InterpreterException).....................................................................Class CallOutsetProperty(String,Term) ............................................................................... Class InterpretersetRetry(boolean)...............................................................................................Class CallOutsetSignal(InterpreterMessage) ...................................................................... Class InterpretersetSignalAndWait(InterpreterMessage) ......................................................... Class InterpretersetSpecial(boolean)............................................................................................Class CallOutstringToCapability(String) ......................................................................Class KnowledgebasestringToClass(String).............................................................................Class KnowledgebaseswapBarrier(Interpreter) ................................................................................ Class CallFramesyntaxError(String) .......................................................................... Class InterpreterMessagesyntaxError(String,Term) ................................................................. Class InterpreterMessagesystemError(String) ......................................................................... Class InterpreterMessageTermAtom(int) ............................................................................................... Class TermAtomTermAtom(String).......................................................................................... Class TermAtomTermDecimal(BigDecimal).........................................................................Class TermDecimalTermDecimal(long)....................................................................................Class TermDecimalTermFloat(double)..........................................................................................Class TermFloatTermFloat(float)..............................................................................................Class TermFloatTermInteger(BigInteger) ............................................................................. Class TermIntegerTermInteger(int).......................................................................................... Class TermIntegerTermInteger(long)....................................................................................... Class TermIntegerTermRef(Object)...............................................................................................Class TermRefTermRef(Object,Comparator) ...........................................................................Class TermReftoString() ............................................................................................................... Class TermtoString(int,Interpreter) .......................................................................................... Class TermtoString(Interpreter) ............................................................................................... Class TermtoString(Knowledgebase) ...............................................................Class InterpreterExceptiontoString(String[],TermVar[],int,Interpreter).............................................................. Class TermtoString(String[],TermVar[],Interpreter) .................................................................. Class TermtoString(Toolkit ................................................................................ Class InterpreterMessagetypeError(String,Term)..................................................................... Class InterpreterMessageunfoldChecked(Term).................................................................................... Class InterpreterunfoldClose(CallIn)........................................................................................ Class InterpreterunfoldCut(InterpreterException,CallIn)........................................................... Class InterpreterunfoldException(InterpreterException,CallIn)................................................. Class InterpreterunfoldFirst(Term,CallIn)................................................................................. Class InterpreterunfoldNext(CallIn).......................................................................................... Class InterpreterunifyTerm(Term,Term) .................................................................................. Class Interpreter

Page 77: Jekejeke Runtime Interface

Jan Burse Programming Runtime XLOG Technologies GmbH

July 11, 2016 jekejeke_prog_run_2016_07_04_e.docx Page 77 of 77

Pictures

Picture 1: Interleaving of two Processes...............................................................................19Picture 2: No Interleaving for the Critical Section..................................................................21Picture 3: Screenshot of Queue Example Run......................................................................25Picture 4: Interpreter Challenges ..........................................................................................28Picture 5: Example Knowledgebase .....................................................................................30Picture 6: Example Class Path .............................................................................................31Picture 7: Example Unification..............................................................................................33Picture 8: Terms during Execution........................................................................................34Picture 9: Log Primitives.......................................................................................................38Picture 10: Housekeeping for Deterministic Predicates ........................................................39Picture 11: Housekeeping for Non-Deterministic Predicates.................................................40Picture 12: Class Diagram Knowledgebase & Term API.......................................................46Picture 13: Class Diagram Call & Interpreter API..................................................................56Picture 14: Class Diagram Headless API..............................................................................68

Tables

Table 1: Comparison Jekejeke and ISO Data Types ............................................................36Table 2: Java Class Arguments............................................................................................41Table 3: Java Array Class Arguments ..................................................................................42Table 4: Java Class Functor.................................................................................................43Table 5: Java Array Functor .................................................................................................44Table 6: Generated Prolog Names .......................................................................................45Table 7: Java Class ISO Stream Mapping............................................................................61

References

[1] Brady, M. (2005): Open Prolog: a Structure-Sharing Prolog for the Macintosh, A the-sis submitted to the University of Dublin, Trinity College, August 2005

[2] Cook, J. J. (2004): Language Interoperability and Logic Programming Languages, University of Edinburgh, 2004

[3] Nguyen, P.-L. and Demoen, B. (2011): Representation Sharing for Prolog, Theory and Practice of Logic Programming, 2011http://arxiv.org/abs/1106.1311