# JPL release notes

- JPL 3.0.3 Release Notes
- JPL 3.0.2 Release Notes
- JPL 3.0.0 Java API Release Notes
- JPL 2.0.2 Java API Release Notes

## JPL 3.0.3 Release Notes

### Changes within the distribution

- the demo folder has been renamed examples (more idiomatic)(?) and its contents have been moved into a new java folder, which is accompanied by a new prolog folder for Prolog examples

### Java API changes

- to simplify the construction of queries, the Query(java.lang.String) constructor now parses its string arg as if it were Prolog source text, and constructs a new query whose goal is the resulting term. This is backwards compatible with (all but very unusual) previous usage, e.g.

    new Query("statistics")

and allows arbitrarily complex goals to be created textually, e.g.

    new Query("setof(_A,current_atom(_A),_As),length(_As,N)")

NB _A and _As are dont-tell-me variables (this property is determined by their initial underscore), whose bindings are by default not returned when the query is called (saving computational time and space). This behaviour can be overridden (globally) with

    jpl.JPL.setDTMMode( false)

to allow Java+JPL+Prolog implementation of a Prolog IDE which emulates the behaviour of the traditional top-level interpreter.

- to further simplify construction of queries, the Query(java.lang.String text, jpl.Term[] args) constructor now parses its text argument as a Prolog source text fragment; if it represents an atom, the constructor behaves as before (building a Compound goal from the given name and args), but if it represents a compound term with one or more atomic subterms whose names are a single questionmark character, e.g.

    "setof(P,mypred(?,P,?),Ps), length(Ps,?)"

and the args comprise as many terms as there are questionmarks, then the new query's goal is a rewriting of text's term, with each questionmark replaced by the corresponding element of args. This is designed to mimic the established and useful idiom of passing parameters into SQL prepared statements. It allows all the constant parts of a parameterised query to be defined textually.

## JPL 3.0.2 Release Notes

### Changes within the distribution

- new classes folder: the root directory of the distribution now contains a classes folder, holding copies of the jpl.* and jpl.fli.* class files
- new demo: in demo/FamilyMT is a new variant of the Family demo which exercises multiple Prolog engines (from a shared pool) called by multiple Java threads.

### C library changes:

- lots of refactoring and tidying in preparation for porting (to Linux+gcc initially)
- added Prolog "foreign" functions jpl_c_lib_version/1 and jpl_c_lib_version/4 for making library version identification available to Prolog
- added Java "native" method get_string_chars(), needed if Prolog returns a string to Java (which it does sometime even if you don't want it to)
- commented out various unused functions
- added Java "native" method action_abort() but it doesn't work yet...
- added support for new jpl.JRef type

### Java API changes

- altered the semantics of Variable to be a purely lexical entity; a Variable instance should be created with a name which is valid in Prolog source syntax; the argumentless Variable() constructor is currently deprecated and constructs a variable with a "new" name in the sequence "_1", "_2" etc. so as not to completely break older programs
- bindings from successful calls are now keyed by the names of the variables, rather than by Variable objects themselves; this is part of a revamp to allow goals to be defined by source text fragments
- implemented these methods for all Term subclasses (to simplify coding of term checking and traversal etc.):

type()

  returns jpl.fli.Prolog.ATOM, COMPOUND, FLOAT, INT or VARIABLE
hasFunctor( String name, int arity)
  fails unless called appropriately;
intValue()
longValue()
floatValue()
doubleValue()
  yield the Java int value (or long, float or double value respectively) of an Integer or Float instance; each will throw an exception for Atom, Compound and Variable instances; the names of these methods follow the precedent set by java.lang.Integer etc. and remember that a Prolog integer is not equivalent to a Java int (it may be longer or shorter), nor is a Prolog float equivalent to a Java float (it may have a different precision)
  <ddstyle ="margin-left: 80px;"> </ddstyle>
arg( int argNo)
  calling arg() inappropriately (i.e. for jpl.Atom, jpl.Integer, jpl.Float and jpl.Variable instances) throws a runtime exception but is not a compile-time error; this method considers the args to be numbered from 1 upwards (i.e. Prolog convention, not Java array convention)
name()

  Variable.name() returns the variable's lexical name, Atom.name() and Compound.name() behave as before, Integer.name() and Float.name() each throw an exception if called (but are valid at compile time)

- altered these methods for all Term subclasses:

- toString() now yields a valid (quoted if necessary) Prolog source text representation

- deprecated Compound.arg0() and all *.debugString() methods
- deprecated Float.value() (see floatValue() and doubleValue())
- jpl.Integer now holds a long value (to allow for other/future Prolog implementations with >32-bit integers) but this is backwards compatible if I understand Java correctly...
- deprecated jpl.Halt() pending a rethink about how best to clean up and terminate a hybrid Java+Prolog application
- added Query.abort() but it doesn't work yet...

## JPL 3.0.0 Release Notes

This release is a work-in-progress, and is being made available only to a few enthusiasts who don't mind the likelihood that the API will change before 3.x becomes stable.

### Java API: new Variable semantics

> A Variable must be created with a name, e.g.

>     new Variable("X")

> or as an anonymous variable

>     new Variable("_")

or as a dont-tell-me variable

>     new Variable("_Q")

Each binding within a solution is now indexed by the name of its associated Variable, hence

>     solution.get("X")

New variables returned in bindings are given new, sequential names, e.g. "_283".
Each Variable instance within a Java application is just a lexical token in the alternative Prolog concrete syntax which Term and its subclasses comprise. Two instances of Variable("X") are no different from one shared instance: you are free to reuse such lexical elements, but this has nothing to do with the sharing of variables which can occur within a Prolog engine.
The bindings of anonymous and dont-tell-me variables (i.e. those whose names begin with an underscore character) are not returned to Java: use them to avoid the computational time and space costs of constructing Term representations of bindings in which you are not interested.

### Java API: easier Term and Query construction

> Now that Variables are named, and bindings are keyed by the names of variables, it is easier to construct Term (and hence Query) instances.
> This utility (NB liable to be renamed or moved into a different class) converts a valid Prolog source text representation of a term into a corresponding Term hierarchy:

>     Term jpl.Util.textToTerm( String sourcetext)

> A new (in JPL 3.0.0) Query constructor

>     Query( String sourcetext)

> allows queries to be created from source text, e.g.

>     new Query("findall(_A,current_atom(_A),_As),length(_As,N)")

> and oneSolution(), allSolutions() and nextSolution() will return bindings of N (but not of the dont-tell-me variables _A and _As), e.g.

>     q.oneSolution().get("N")

> returns a jpl.Integer representing the Prolog integer value to which N was bound by the successful call of the query.

### Java API: deprecated methods

- Query.query()

use Query.hasSolution() instead

- Query.rewind()

use Query.close() instead

### Java API: fixes

array methods inherited from java.lang.Object are now callable, e.g.

    jpl_new(array(int), [4,5,6], A),
    jpl_call(A, hashCode, [], H).

### Java API: planned or under consideration

- drop Term.display(), which cutely displays any Term in a Swing tree view in a new window.

- support non-virtual method calls, e.g. by

    jpl_call(+Obj, +Class:Method, +Args, -Result)

- finish the current tidy-up

- passing (or returning) Prolog terms to Java by reference; we might stash them in Prolog's recorded database (see PL_record in the SWI-Prolog Reference Manual), and return an instance of some yet-to-be-designed JPL class which erases the recorded term when the referring object is garbage-collected

- convenience constructs in Prolog akin to import in Java, allowing us to write e.g.

    jpl_new('Timestamp', X, R)

when we mean

    jpl_new('javax.sql.Timestamp', X, R)

- renaming the package jpl more globally: unfortunately, org.jpl has already been taken :-)

- ditching jpl.Util and moving its (static, utility) methods into jpl.JPL

- deprecate all .args(), .arg0(), .arg1() methods and replace with

    public final Term[] args;

- require any Variable's name to conform to Prolog source syntax, so that valid source texts can be reconstructed from Term instances by the toString() methods

## JPL 2.0.2 Release Notes

### Java API: canonical representation of terms

> ### rationale

> "List" and "Tuple" terms are not recognised as distinct types by the Prolog engine: they are just conventions: it doesn't follow that every `./2` or `[]/0` should be represented externally as instances of List or Nil, nor that `{}/2` should be represented as Tuple. There are many other informal types, and it's not clear which of them deserve the same treatment. The simplest policy is to provide special support for none of them, and this is what JPL 2.x.x does. This also ensures that there is only one valid representation of a Prolog term as JPL class instances (otherwise we would have to be careful to recognise every Atom whose name is "[]" as being equivalent to an instance of Nil).

- these classes have been dropped (sorry, not deprecated: they don't fit into the new scheme)

- Tuple (see above)
- List (see above)
- Nil (see above)
- String (these are obsolete and more-or-less deprecated in recent SWI-Prolog releases)
- Long (this doesn't have a clear role)

- the Term class hierarchy has been rearranged thus:

    Term (abstract)
      |
      +--- Compound
      |      |
      |      +--- Atom (special case)
      |
      +--- Integer
      |
      +--- Float
      |
      +--- Variable

    Query

Note that an Atom is a Compound whose arity is zero. It is naughty to construct a Compound with zero arity (this violates canonicity), and JPL code never does this when exporting terms from Prolog. Application code written in Java, using JPL, should avoid doing this. Maybe we should raise an exception if it is attempted (maybe we do, I can't remember :-)

Note also that, although a Query contains a Term (among other Prolog-related state), it is not related to it by inheritance.

### Java API: lazy initialisation

> It is no longer necessary to explicitly initialise JPL before calling any of the methods which access the Prolog engine. This allows you to develop Java classes which make use of JPL, and to make them available as "library" classes for use freely in applications, without placing a burden upon the application programmer to explicitly initialise JPL.

> Instead, JPL (and, if necessary, the Prolog engine) is initialised "lazily", at the first attempt to invoke the Prolog engine. At this point, a "default" sequence of initialisation parameters is used: initial values for these are compiled into JPL, but they can be redefined at any time up until initialisation occurs.

> It is also possible for Java applications to discover (as a String[]) exactly what sequence of JPL initialisation parameters were actually used (this call returns null if Prolog is not yet initialised, and can thus be used as a test of this state).

> If a Java application needs to use Prolog with, say, a larger than normal heap or stack, it should attempt to redefine the default initialisation parameters, and hope that the Prolog engine is not yet initialised (if it is, there's not much it can do about it) (in newer versions of SWI-Prolog it could restart it, but this is rather drastic, might disrupt other activities, and is not yet supported via JPL).

> Finally, the JPL 1.0.1 static `jpl.JPL.init()` method is still supported, for backwards compatibility.

> These changes are not only for convenience, and to allow development of easy-to-use library code, but are part of a plan to combine Fred Dushin's Java-calls-Prolog interface with Paul Singleton's Prolog-calls-Java interface, to support hybrid Prolog+Java application programming in which either

> - the JVM is alive before Prolog is started
> - the Prolog engine is alive before a JVM is started
> - a C or C++ main() starts both of them.

### Java API: miscellaneous changes

- new constructors:

    new jpl.Query( Term t)

- withdrawn constructors:

all the multi-argument convenience constructors for Compound etc., since Java 1.1 onwards supports "anonymous arrays" which can (fairly) conveniently be used to create Compounds of any arity, e.g.

    new Compound( "pair", new Term[] { new Atom("one"), new Atom("two") } )

- new accessor methods:

    String Compound.name()

    int Compound.arity()

NB an Atom is a special case of a Compound, and inherits its `name()` and an `arity()` accessors
- deprecated accessor methods:

    Compound.atom()

(although Prolog conventionally, and necessarily, returns the "name" of a term's principal functor as an atom, this "name" is really a string, and in Java we can represent it as such; the best Prolog can return is "the atom whose name is the same as the name of this compound", whereas we can simply return the name).
- deprecated method:

    jpl.Query.query() is renamed jpl.Query.hasSolution()

for consistency with oneSolution() and allSolutions()

### Java API: bug fixes

> Only one "bug" has been fixed, and this was already flagged by Fred as an issue: it concerns the conversion, from Prolog into JPL, of terms which contain shared variables (i.e. several instances of the same variable). Transput of any (non-cyclic) term from Prolog into Java and back, using JPL, should yield a new term which is identical to the original apart from having all new variables (but in a similar pattern of sharing).