JPL 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.
Paul Singleton
Friday12th March 2004
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)
-
- 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...
Paul Singleton
Sunday 22nd February 2004
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
use Query.hasSolution()
instead
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
Paul Singleton
Wednesday 4th February 2004
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 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).
Paul Singleton
drafted Tuesday 20th February 2001
revised Thursday 19th April 2001