upgrade JPL

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1936 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
vsc 2007-09-27 15:25:34 +00:00
parent 5f9555baa4
commit 31ff28d3ee
70 changed files with 12020 additions and 9030 deletions

View File

@ -91,7 +91,6 @@ CreateNewArena(CELL *ptr, UInt size)
dst->_mp_size = 0L;
dst->_mp_alloc = arena2big_sz(size);
ptr[size-1] = EndSpecials;
return t;
}
@ -263,6 +262,16 @@ p_allocate_default_arena(void)
#endif
return TRUE;
}
static void
adjust_cps(UInt size)
{
/* adjust possible back pointers in choice-point stack */
choiceptr b_ptr = B;
while (b_ptr->cp_h == H) {
b_ptr->cp_h += size;
b_ptr = b_ptr->cp_b;
}
}
static int
@ -279,22 +288,16 @@ GrowArena(Term arena, CELL *pt, UInt old_size, UInt size, UInt arity)
size = 4096;
}
if (pt == H) {
choiceptr b_ptr;
if (H+size > ASP-1024) {
XREGS[arity+1] = arena;
if (!Yap_gcl(size*sizeof(CELL), arity+1, ENV, P)) {
Yap_Error(OUT_OF_STACK_ERROR, TermNil, Yap_ErrorMessage);
return FALSE;
return FALSE;
}
arena = XREGS[arity+1];
}
/* adjust possible back pointers in choice-point stack */
b_ptr = B;
while (b_ptr->cp_h == H) {
b_ptr->cp_h += size;
b_ptr = b_ptr->cp_b;
}
adjust_cps(size);
H += size;
} else {
XREGS[arity+1] = arena;

View File

@ -3040,8 +3040,13 @@ compact_heap(void)
}
#endif
next_hb = set_next_hb(gc_B);
dest = (CELL_PTR) H0 + total_marked - 1;
dest = H0 + total_marked - 1;
gc_B = update_B_H(gc_B, H, dest+1, dest+2
#ifdef TABLING
, &depfr
#endif
);
for (current = H - 1; current >= start_from; current--) {
if (MARKED_PTR(current)) {
CELL ccell = UNMARK_CELL(*current);
@ -3219,6 +3224,11 @@ icompact_heap(void)
#endif
next_hb = set_next_hb(gc_B);
dest = (CELL_PTR) H0 + total_marked - 1;
gc_B = update_B_H(gc_B, H, dest+1, dest+2
#ifdef TABLING
, &depfr
#endif
);
for (iptr = iptop - 1; iptr >= ibase; iptr--) {
CELL ccell;
CELL_PTR current;
@ -3658,9 +3668,13 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop)
gc_phase = (UInt)IntegerOfTerm(Yap_ReadTimedVar(GcPhase));
/* old HGEN are not very reliable, but still may have data to recover */
#ifdef FIX
if (gc_phase != GcCurrentPhase) {
HGEN = H0;
}
#else
HGEN = H0;
#endif
/* fprintf(stderr,"HGEN is %ld, %p, %p/%p\n", IntegerOfTerm(Yap_ReadTimedVar(GcGeneration)), HGEN, H,H0);*/
OldTR = (tr_fr_ptr)(old_TR = TR);
push_registers(predarity, nextop);
@ -3710,8 +3724,10 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop)
pop_registers(predarity, nextop);
TR = new_TR;
/* fprintf(Yap_stderr,"NEW HGEN %ld (%ld)\n", H-H0, HGEN-H0);*/
#ifdef FIX
Yap_UpdateTimedVar(GcGeneration, MkIntegerTerm(H-H0));
Yap_UpdateTimedVar(GcPhase, MkIntegerTerm(GcCurrentPhase));
#endif
c_time = Yap_cputime();
if (gc_verbose) {
fprintf(Yap_stderr, "%% Compress: took %g sec\n", (double)(c_time-time_start)/1000);

View File

@ -2143,6 +2143,25 @@ check_bom(int sno, StreamDesc *st)
}
}
static Int
p_access(char *file_name)
{
#if HAVE_STAT
#if _MSC_VER || defined(__MINGW32__)
struct _stat ss;
if (_stat(file_name, &ss) != 0) {
#else
struct stat ss;
if (stat(file_name, &ss) != 0) {
#endif
/* ignore errors while checking a file */
return FALSE;
}
return TRUE;
#else
return FALSE;
#endif
}
static Int
p_open (void)
@ -5885,6 +5904,7 @@ Yap_InitIOPreds(void)
Yap_InitCPred ("$get0", 2, p_get0, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("$get0_line_codes", 2, p_get0_line_codes, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("$get_byte", 2, p_get_byte, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("$access", 1, p_access, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("$open", 5, p_open, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("$file_expansion", 2, p_file_expansion, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("$open_null_stream", 1, p_open_null_stream, SafePredFlag|SyncPredFlag|HiddenPredFlag);

View File

@ -2598,6 +2598,42 @@ p_continue_signals(void)
return TRUE;
}
static Int
p_unix(void)
{
#ifdef unix
return TRUE;
#else
#ifdef __unix__
return TRUE;
#else
return FALSE;
#endif
#endif
}
static Int
p_win32(void)
{
#ifdef _WIN32
return TRUE;
#else
#ifdef __CYGWIN__
return TRUE;
#else
return FALSE;
#endif
#endif
}
static Int
p_ld_path(void)
{
return Yap_unify(ARG1,MkAtomTerm(Yap_LookupAtom("LD_LIBRARY_PATH")));
}
void
Yap_InitSysPreds(void)
{
@ -2624,6 +2660,9 @@ Yap_InitSysPreds(void)
Yap_InitCPred ("$continue_signals", 0, p_continue_signals, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("file_directory_name", 2, p_file_directory_name, SafePredFlag);
Yap_InitCPred ("$env_separator", 1, p_env_separator, SafePredFlag);
Yap_InitCPred ("$unix", 0, p_unix, SafePredFlag);
Yap_InitCPred ("$win32", 0, p_win32, SafePredFlag);
Yap_InitCPred ("$ld_path", 1, p_ld_path, SafePredFlag);
CurrentModule = SYSTEM_MODULE;
Yap_InitCPred ("true_file_name", 2, p_true_file_name, SyncPredFlag);
CurrentModule = cm;

View File

@ -37,17 +37,16 @@ CWD=$(PWD)
#
JAVAC=@JAVAC@
JAR=@JAR@
JPL=jpl.jar
JPLJAR=jpl.jar
TESTJAR=jpltest.jar
CLS= jpl/Atom.java \
jpl/Compound.java \
jpl/Float.java \
jpl/Integer.java \
jpl/JBoolean.java \
jpl/JRef.java \
jpl/JPLException.java \
jpl/JPL.java \
jpl/JRef.java \
jpl/JVoid.java \
jpl/PrologException.java \
jpl/Query.java \
jpl/Term.java \
@ -62,6 +61,7 @@ FLI= jpl/fli/atom_t.java \
jpl/fli/fid_t.java \
jpl/fli/functor_t.java \
jpl/fli/IntHolder.java \
jpl/fli/Int64Holder.java \
jpl/fli/LongHolder.java \
jpl/fli/module_t.java \
jpl/fli/ObjectHolder.java \
@ -72,26 +72,48 @@ FLI= jpl/fli/atom_t.java \
jpl/fli/StringHolder.java \
jpl/fli/term_t.java
TEST= jpl/test/Family.java \
jpl/test/FetchBigTree.java \
jpl/test/FetchLongList.java \
jpl/test/Ga2.java \
jpl/test/Ga.java \
jpl/test/Garbo.java \
jpl/test/Masstest.java \
jpl/test/MaxObjects.java \
jpl/test/ShadowA.java \
jpl/test/ShadowB.java \
jpl/test/SyntaxError.java \
jpl/test/Test.java \
jpl/test/TestJUnit.java \
jpl/test/TestOLD.java
JAVA=$(CLS) $(FLI)
CLASSES=$(JAVA:.java=.class)
all: $(JPL)
TESTCLASSES=$(TEST:.java=.class)
all: $(JPLJAR)
$(JAVA):
for f in $(CLS); do cp $(srcdir)/$$f jpl ; done
for f in $(FLI); do cp $(srcdir)/$$f jpl/fli ; done
for f in $(TEST); do cp $(srcdir)/$$f jpl/test ; done
$(JPL): $(JAVA)
$(JPLJAR): $(JAVA)
$(JAVAC) $(JAVA)
$(JAR) cf $(JPL) $(CLASSES)
$(JAR) cf $(JPLJAR) $(CLASSES)
$(TESTJAR): $(JAVA) $(TEST)
$(JAVAC) -classpath $(JPLJAR):$(JUNIT) $(TEST)
$(JAR) cf $(JPL) $(TESTCLASSES)
clean::
rm -f *~ $(CLASSES)
distclean: clean
rm -r $(JPL)
install: $(JPL)
mkdir -p $(DESTDIR)$(SHAREDIR)/Yap
$(INSTALL_DATA) $(JPL) $(DESTDIR)$(SHAREDIR)/Yap
install: $(JPLJAR)
mkdir -p $(DESTDIR)$(SHAREDIR)/Yap
$(INSTALL_DATA) $(JPLJAR) $(DESTDIR)$(SHAREDIR)/Yap

View File

@ -2,9 +2,10 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: Atom.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: Atom.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
// Author: Paul Singleton <paul@jbgb.com>
//
//
// Description:
@ -57,7 +58,7 @@ import jpl.fli.term_t;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
* @see jpl.Term
* @see jpl.Compound
*/
@ -88,6 +89,14 @@ public class Atom extends Compound {
return Prolog.ATOM;
}
/**
* returns the name of the type of this term, as "Atom"
*
* @return the name of the type of this term, as "Atom"
*/
public String typeName() { // overrides same in jpl.Term
return "Atom";
}
//==================================================================/
// Methods (deprecated)
//==================================================================/
@ -113,15 +122,15 @@ public class Atom extends Compound {
//==================================================================/
/**
* Converts a Prolog term to a JPL Atom. This is only called from Term.getTerm(),
* and we can assume the term_t refers to a Prolog atom,
* so we just create a new Atom object with the atom's name.
* Converts a Prolog term (as a term_t), which is known to be an atom, to a new jpl.Atom.
* This is only called from Term.getTerm(),
* and just creates a new Atom object initialised with the atom's name.
*
* @param vars_to_Vars A Map from Prolog variables to JPL Variables.
* @param term The Prolog term to be converted
* @return A new Atom instance
*/
protected static Term getTerm(Map vars_to_Vars, term_t term) {
protected static Term getTerm1(Map vars_to_Vars, term_t term) {
StringHolder holder = new StringHolder();
Prolog.get_atom_chars(term, holder); // ignore return val; assume success...
@ -129,8 +138,8 @@ public class Atom extends Compound {
}
/**
* Converts a term_t to an Atom, knowing that it refers to a SWI-Prolog string,
* so we just create a new Atom object initialised with the string's value.
* Converts a Prolog term (as a term_t), which is known to be a SWI-Prolog string, to a new jpl.Atom,
* by creating a new Atom object initialised with the string's value.
* JPL users should avoid SWI-Prolog's non-ISO strings, but in some obscure
* circumstances they are returned unavoidably, so we have to handle them
* (and this is how).
@ -142,7 +151,6 @@ public class Atom extends Compound {
protected static Term getString(Map vars_to_Vars, term_t term) {
StringHolder holder = new StringHolder();
Prolog.get_string_chars(term, holder); // ignore return val; assume success...
// System.err.println("Warning: Prolog returns a string: \"" + holder.value + "\"");
return new Atom(holder.value);
}

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: Compound.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: Compound.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -28,8 +28,8 @@
package jpl;
import java.util.Map;
import jpl.fli.IntHolder;
import jpl.fli.ObjectHolder;
import jpl.fli.Prolog;
import jpl.fli.StringHolder;
import jpl.fli.term_t;
@ -56,7 +56,8 @@ import jpl.fli.term_t;
* Util.textToTerm("f(a)")
* </pre>
* The <i>arity</i> of a Compound is the quantity of its arguments.
* Once constructed, neither the name, arity nor any argument of a Compound can be altered.
* Once constructed, neither the name nor the arity of a Compound can be altered.
* An argument of a Compound can be replaced with the setArg() method.
* <hr><i>
* Copyright (C) 2004 Paul Singleton<p>
* Copyright (C) 1998 Fred Dushin<p>
@ -72,32 +73,29 @@ import jpl.fli.term_t;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
* @see jpl.Term
* @see jpl.Atom
*/
public class Compound extends Term {
//==================================================================/
// Attributes
//==================================================================/
/**
* the name of this Compound
*/
protected final String name;
/**
* the arguments of this Compound
*/
protected final Term[] args;
//==================================================================/
// Constructors
//==================================================================/
/**
* Creates a Compound with name but no args (i.e. an Atom).
* This condsructor is protected (from illegal public use) and is used
* only by Atom, which inherits it.
*
* @param name the name of this Compound
* @param args the arguments of this Compound
@ -107,15 +105,13 @@ public class Compound extends Term {
throw new JPLException("jpl.Atom: cannot construct with null name");
}
this.name = name;
this.args = new Term[] {
};
this.args = new Term[] {};
}
/**
* Creates a Compound with name and args.
*
* @param name the name of this Compound
* @param args the arguments of this Compound
* @param args the (one or more) arguments of this Compound
*/
public Compound(String name, Term[] args) {
if (name == null) {
@ -130,11 +126,27 @@ public class Compound extends Term {
this.name = name;
this.args = args;
}
/**
* Creates a Compound with name and arity.
* This constructor, along with the setArg method, serves the new, native Prolog-term-to-Java-term routine,
* and is public only so as to be accessible via JNI: it is not intended for general use.
*
* @param name the name of this Compound
* @param arity the arity of this Compound
*/
public Compound(String name, int arity) {
if (name == null) {
throw new JPLException("jpl.Compound: cannot construct with null name");
}
if (arity < 0) {
throw new JPLException("jpl.Compound: cannot construct with negative arity");
}
this.name = name;
this.args = new Term[arity];
}
//==================================================================/
// Methods (common)
//==================================================================/
/**
* Returns the ith argument (counting from 1) of this Compound;
* throws an ArrayIndexOutOfBoundsException if i is inappropriate.
@ -144,16 +156,62 @@ public class Compound extends Term {
public final Term arg(int i) {
return args[i - 1];
}
/**
* Tests whether this Compound's functor has (String) 'name' and 'arity'.
*
* @return whether this Compound's functor has (String) 'name' and 'arity'
*/
public final boolean hasFunctor(String name, int arity) {
return name.equals(name) && arity == args.length;
return name.equals(this.name) && arity == args.length; // BUGFIX: was just name.equals(name)
}
/**
* whether this Term is a 'jboolean' structure denoting Java's false, i.e. @(false)
*
* @return whether this Term is a 'jboolean' structure denoting Java's false, i.e. @(false)
*/
public boolean isJFalse() {
return hasFunctor("@", 1) && arg(1).hasFunctor("false", 0);
}
/**
* whether this Term is a 'jboolean' structure denoting Java's true, i.e. @(fatruelse)
*
* @return whether this Term is a 'jboolean' structure denoting Java's true, i.e. @(fatruelse)
*/
public boolean isJTrue() {
return hasFunctor("@", 1) && arg(1).hasFunctor("true", 0);
}
/**
* whether this Term is a 'jnull' structure, i.e. @(null)
*
* @return whether this Term is a 'jnull' structure, i.e. @(null)
*/
public boolean isJNull() {
return hasFunctor("@", 1) && arg(1).hasFunctor("null", 0);
}
/**
* whether this Term is a 'jvoid' structure, i.e. @(void)
*
* @return whether this Term is a 'jvoid' structure, i.e. @(void)
*/
public boolean isJVoid() {
return hasFunctor("@", 1) && arg(1).hasFunctor("void", 0);
}
/**
* whether this Term is a 'jobject' structure, i.e. @(Tag)
*
* @return whether this Term is a 'jobject' structure, i.e. @(Tag)
*/
public boolean isJObject() {
return hasFunctor("@", 1) && arg(1).isAtom() && JPL.isTag(arg(1).name());
}
/**
* whether this Term is a 'jref' structure, i.e. @(Tag) or @(null)
*
* @return whether this Term is a 'jref' structure, i.e. @(Tag) or @(null)
*/
public boolean isJRef() {
return isJObject() || isJNull();
}
/**
* Returns the name (unquoted) of this Compound.
*
@ -162,7 +220,6 @@ public class Compound extends Term {
public final String name() {
return name;
}
/**
* Returns the arity (1+) of this Compound.
*
@ -171,20 +228,16 @@ public class Compound extends Term {
public final int arity() {
return args.length;
}
/**
* Returns a prefix functional representation of a Compound of the form name(arg1,...),
* where each argument is represented according to its toString() method.
* <br>
* NB 'name' should be quoted iff necessary, and Term.toString(Term[]) is not
* really a Term method, more a utility...
* where 'name' is quoted iff necessary (to be valid Prolog soutce text)
* and each argument is represented according to its toString() method.
*
* @return string representation of an Compound
*/
public String toString() {
return quotedName() + (args.length > 0 ? "(" + Term.toString(args) + ")" : "");
}
/**
* Two Compounds are equal if they are identical (same object) or their names and arities are equal and their
* respective arguments are equal.
@ -195,46 +248,67 @@ public class Compound extends Term {
public final boolean equals(Object obj) {
return (this == obj || (obj instanceof Compound && name.equals(((Compound) obj).name) && Term.terms_equals(args, ((Compound) obj).args)));
}
/**
* returns the type of this term, as jpl.fli.Prolog.COMPOUND
*
* @return the type of this term, as jpl.fli.Prolog.COMPOUND
*/
public int type() {
return Prolog.COMPOUND;
}
/**
* returns the name of the type of this term, as "Compound"
*
* @return the name of the type of this term, as "Compound"
*/
public String typeName(){
return "Compound";
}
/**
* Sets the i-th (from 1) arg of this Compound to the given Term instance.
* This method, along with the Compound(name,arity) constructor, serves the new, native Prolog-term-to-Java-term routine,
* and is public only so as to be accessible via JNI: it is not intended for general use.
*
* @param i the index (1+) of the arg to be set
* @param arg the Term which is to become the i-th (from 1) arg of this Compound
*/
public void setArg(int i, Term arg) {
if (i <= 0) {
throw new JPLException("jpl.Compound#setArg: bad (non-positive) argument index");
}
if (i > args.length) {
throw new JPLException("jpl.Compound#setArg: bad (out-of-range) argument index");
}
if (arg == null) {
throw new JPLException("jpl.Compound#setArg: bad (null) argument");
}
args[i - 1] = arg;
}
//==================================================================/
// Methods (protected)
//==================================================================/
/**
* Returns a quoted (iff necessary) form of the Atom's name, as understood by Prolog read/1
* (I suspect that there are more efficient ways of doing this)
*
* @return a quoted form of the Atom's name, as understood by Prolog read/1
*/
protected String quotedName() {
return ((Atom) (new Query(new Compound("sformat", new Term[] { new Variable("S"), new Atom("~q"), new Compound(".", new Term[] { new Atom(this.name), new Atom("[]")})
})))
.oneSolution()
.get(
return ((Atom) (new Query(new Compound("sformat", new Term[] { new Variable("S"), new Atom("~q"), new Compound(".", new Term[] { new Atom(this.name), new Atom("[]") }) }))).oneSolution().get(
"S")).name;
}
//==================================================================/
// Methods (deprecated)
//==================================================================/
/**
* Returns the arguments of this Compound.
* Returns the arguments of this Compound (1..arity) of this Compound as an array[0..arity-1] of Term.
*
* @return the arguments of this Compound
* @return the arguments (1..arity) of this Compound as an array[0..arity-1] of Term
* @deprecated
*/
public final Term[] args() {
return args;
}
/**
* Returns the ith argument (counting from 0) of this Compound.
*
@ -244,7 +318,6 @@ public class Compound extends Term {
public final Term arg0(int i) {
return args[i];
}
/**
* Returns a debug-friendly representation of a Compound.
*
@ -254,11 +327,9 @@ public class Compound extends Term {
public String debugString() {
return "(Compound " + name + " " + Term.debugString(args) + ")";
}
//==================================================================/
// Converting JPL Terms to Prolog terms
//==================================================================/
/**
* To put a Compound in a term, we create a sequence of term_t
* references from the Term.terms_to_term_ts() method, and then
@ -271,14 +342,11 @@ public class Compound extends Term {
* (Atom, Variable, Compound, etc.) on which the method is invoked.
*/
protected final void put(Map varnames_to_vars, term_t term) {
Prolog.cons_functor_v(term, Prolog.new_functor(Prolog.new_atom(name), args.length), Term.putTerms(varnames_to_vars, args));
}
//==================================================================/
// Converting Prolog terms to JPL Terms
//==================================================================/
/**
* Converts the Prolog term in term_t (known to be a compound) to a JPL Compound.
* In this case, we create a list of Terms by calling Term.getTerm for each
@ -289,13 +357,11 @@ public class Compound extends Term {
* @param term The Prolog term to convert
* @return A new Compound
*/
protected static Term getTerm(Map varnames_to_vars, term_t term) {
// we need holders to get the term's name and arity back from the FLI:
protected static Term getTerm1(Map varnames_to_vars, term_t term) {
ObjectHolder jthing_holder = new ObjectHolder();
StringHolder name_holder = new StringHolder();
IntHolder arity_holder = new IntHolder();
Prolog.get_name_arity(term, name_holder, arity_holder); // assume it succeeds
Term args[] = new Term[arity_holder.value];
for (int i = 1; i <= arity_holder.value; i++) {
term_t termi = Prolog.new_term_ref();
@ -304,11 +370,9 @@ public class Compound extends Term {
}
return new Compound(name_holder.value, args);
}
//==================================================================/
// Computing Substitutions
//==================================================================/
/**
* Nothing needs to be done except to pass the buck to this Compound's args.
*
@ -318,7 +382,5 @@ public class Compound extends Term {
protected final void getSubst(Map varnames_to_Terms, Map vars_to_Vars) {
Term.getSubsts(varnames_to_Terms, vars_to_Vars, args);
}
}
//345678901234567890123456789012346578901234567890123456789012345678901234567890

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: Float.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: Float.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -59,7 +59,7 @@ import jpl.fli.term_t;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
* @see jpl.Term
* @see jpl.Compound
*/
@ -98,7 +98,16 @@ public class Float extends Term {
* @return the ith argument (counting from 1) of this Float (never)
*/
public final Term arg(int i) {
throw new JPLException("jpl.Float.arg(int) is undefined");
throw new JPLException("jpl.Float#arg(int) is undefined");
}
/**
* The (nonexistent) args of this Float
*
* @return the (nonexistent) args of this Float
*/
public Term[] args() {
return new Term[] {};
}
/**
@ -134,7 +143,7 @@ public class Float extends Term {
* @return the name of this Float (never)
*/
public final String name() {
throw new JPLException("jpl.Float.name() is undefined");
throw new JPLException("jpl.Float#name() is undefined");
}
/**
@ -182,6 +191,14 @@ public class Float extends Term {
return this.value;
}
public final int type() {
return Prolog.FLOAT;
}
public String typeName(){
return "Float";
}
/**
* Returns a Prolog source text representation of this Float
*
@ -201,28 +218,10 @@ public class Float extends Term {
return this == obj || (obj instanceof Float && value == ((Float) obj).value);
}
public final int type() {
return Prolog.FLOAT;
}
public String typeName(){
return "Float";
}
//==================================================================/
// Methods (deprecated)
//==================================================================/
/**
* The (nonexistent) args of this Float
*
* @return the (nonexistent) args of this Float
* @deprecated
*/
public Term[] args() {
return new Term[] {};
}
/**
* The immutable value of this jpl.Float object, as a Java double
*
@ -270,7 +269,7 @@ public class Float extends Term {
* @param term The Prolog term (a float) to convert
* @return A new Float instance
*/
protected static Term getTerm(Map vars_to_Vars, term_t term) {
protected static Term getTerm1(Map vars_to_Vars, term_t term) {
DoubleHolder double_holder = new DoubleHolder();
Prolog.get_float(term, double_holder); // assume it succeeds...

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: Integer.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: Integer.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -28,8 +28,7 @@
package jpl;
import java.util.Map;
import jpl.fli.IntHolder;
import jpl.fli.Int64Holder;
import jpl.fli.Prolog;
import jpl.fli.term_t;
@ -59,7 +58,7 @@ import jpl.fli.term_t;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
* @see jpl.Term
* @see jpl.Compound
*/
@ -85,19 +84,22 @@ public class Integer extends Term {
this.value = value;
}
/**
* @param value This Integer's (int) value
*/
public Integer(int value) {
this.value = value;
}
//==================================================================/
// Methods (common)
//==================================================================/
/**
* Tests whether this Integer's functor has (int) 'name' and 'arity'
* The (nonexistent) args of this Integer
*
* @return the (nonexistent) args of this Integer
*/
public Term[] args() {
return new Term[] {
};
}
/**
* Tests whether this Integer's functor has (int) 'name' and 'arity' (c.f. functor/3)
*
* @return whether this Integer's functor has (int) 'name' and 'arity'
*/
@ -106,7 +108,16 @@ public class Integer extends Term {
}
/**
* Returns the arity (0) of this jpl.Integer
* throws a JPLException (name() is defined only for Compound, Atom and Variable)
*
* @return the name of this Integer (never)
*/
public final String name() {
throw new JPLException("jpl.Integer#name() is undefined");
}
/**
* Returns the arity (0) of this jpl.Integer (c.f. functor/3)
*
* @return the arity (0) of this jpl.Integer
*/
@ -115,9 +126,10 @@ public class Integer extends Term {
}
/**
* Returns the value of this Integer as an int if possible, else throws exception
* Returns the value of this Integer as an int if possible, else throws a JPLException
*
* @return the int value of this Integer (if representable)
* @throws JPLException if the value of this Integer is too great to be represented as a Java int
* @return the int value of this Integer
*/
public final int intValue() {
if (value < java.lang.Integer.MIN_VALUE || value > java.lang.Integer.MAX_VALUE) {
@ -128,12 +140,12 @@ public class Integer extends Term {
}
/**
* Returns the value of this Integer converted to a long
* Returns the value of this Integer as a long
*
* @return the value of this Integer converted to a long
* @return the value of this Integer as a long
*/
public final long longValue() {
return (new java.lang.Long(value)).longValue(); // safe but inefficient...
return value;
}
/**
@ -154,17 +166,23 @@ public class Integer extends Term {
return (new java.lang.Long(value)).doubleValue(); // safe but inefficient...
}
public final int type() {
return Prolog.INTEGER;
}
public String typeName(){
return "Integer";
}
/**
* Returns a Prolog source text representation of this Integer's value
*
* @return a Prolog source text representation of this Integer's value
*/
public String toString() {
return "" + value + ""; // hopefully invokes Integer.toString() or equivalent
return "" + value; // hopefully invokes Integer.toString() or equivalent
}
//------------------------------------------------------------------/
// equals
/**
* Two Integer instances are equal if they are the same object, or if their values are equal
*
@ -175,14 +193,6 @@ public class Integer extends Term {
return this == obj || (obj instanceof Integer && value == ((Integer) obj).value);
}
public final int type() {
return Prolog.INTEGER;
}
public String typeName(){
return "Integer";
}
//==================================================================/
// Methods (deprecated)
//==================================================================/
@ -197,17 +207,6 @@ public class Integer extends Term {
return (int) value;
}
/**
* The (nonexistent) args of this Integer
*
* @return the (nonexistent) args of this Integer
* @deprecated
*/
public Term[] args() {
return new Term[] {
};
}
/**
* Returns a debug-friendly representation of this Integer's value
*
@ -244,11 +243,11 @@ public class Integer extends Term {
* @param term The Prolog term (an integer) which is to be converted
* @return A new Integer instance
*/
protected static Term getTerm(Map vars_to_Vars, term_t term) {
IntHolder int_holder = new IntHolder();
protected static Term getTerm1(Map vars_to_Vars, term_t term) {
Int64Holder int64_holder = new Int64Holder();
Prolog.get_integer(term, int_holder); // assume it succeeds...
return new jpl.Integer(int_holder.value);
Prolog.get_integer(term, int64_holder); // assume it succeeds...
return new jpl.Integer(int64_holder.value);
}
//==================================================================/

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: JPL.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: JPL.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -56,14 +56,18 @@ import jpl.fli.Prolog;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
public class JPL {
protected static final boolean DEBUG = false;
//
public static final Term JFALSE = new Compound("@", new Term[] {new Atom("false")});
public static final Term JTRUE = new Compound("@", new Term[] {new Atom("true")});
public static final Term JNULL = new Compound("@", new Term[] {new Atom("null")});
public static final Term JVOID = new Compound("@", new Term[] {new Atom("void")});
protected static boolean modeDontTellMe = true;
//------------------------------------------------------------------/
// setDTMMode
/**
* Sets the global "dont-tell-me" mode (default value: true).
@ -83,7 +87,6 @@ public class JPL {
modeDontTellMe = dtm;
}
//------------------------------------------------------------------/
// getDefaultInitArgs
/**
* Returns, in an array of String, the sequence of command-line
@ -98,7 +101,6 @@ public class JPL {
return Prolog.get_default_init_args();
}
//------------------------------------------------------------------/
// setDefaultInitArgs
/**
* Specifies, in an array of String, the sequence of command-line
@ -110,7 +112,6 @@ public class JPL {
Prolog.set_default_init_args(args);
}
//------------------------------------------------------------------/
// getActualInitArgs
/**
* Returns, in an array of String, the sequence of command-line
@ -125,7 +126,6 @@ public class JPL {
return Prolog.get_actual_init_args();
}
//------------------------------------------------------------------/
// init
/**
* Initializes the Prolog engine, using the String argument
@ -145,7 +145,6 @@ public class JPL {
return Prolog.set_default_init_args(args) && init();
}
//------------------------------------------------------------------/
// init
/**
* Initialises the Prolog engine using the current default initialisation parameters,
@ -155,7 +154,22 @@ public class JPL {
return Prolog.initialise();
}
//------------------------------------------------------------------/
// isTag(String)
/**
* whether the String arg is a plausible tag, e.g. "J#0123456789".
*/
public static boolean isTag(String s) {
return s.length()==12 && s.charAt(0)=='J' && s.charAt(1)=='#' && Character.isDigit(s.charAt(2)) && Character.isDigit(s.charAt(3)) && Character.isDigit(s.charAt(4)) && Character.isDigit(s.charAt(5)) && Character.isDigit(s.charAt(6)) && Character.isDigit(s.charAt(7)) && Character.isDigit(s.charAt(8)) && Character.isDigit(s.charAt(9)) && Character.isDigit(s.charAt(10)) && Character.isDigit(s.charAt(11));
}
// newJRef(Object)
/**
* returns a new Term instance which represents the given object
*/
public static Term newJRef(Object obj) {
return new Compound( "@", new Term[]{new Atom(Prolog.object_to_tag(obj))});
}
// halt
/**
* Terminates the Prolog session.<p>
@ -171,7 +185,6 @@ public class JPL {
// a static reference to the current Version
private static final Version version_ = new Version();
//------------------------------------------------------------------/
// version
/**
* Returns (as a Version) an identification of this version of JPL.
@ -181,7 +194,6 @@ public class JPL {
return version_;
}
//------------------------------------------------------------------/
// version_string
/**
* Returns a String (eg "3.0.0-alpha") identifying this version of JPL.

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: JPLException.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: JPLException.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -48,9 +48,11 @@ package jpl;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
public class JPLException extends RuntimeException {
private static final long serialVersionUID = 1L;
public JPLException() {
super();
}

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: JRef.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: JRef.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -28,8 +28,6 @@
package jpl;
import java.util.Map;
import jpl.fli.ObjectHolder;
import jpl.fli.Prolog;
import jpl.fli.term_t;
@ -57,9 +55,11 @@ import jpl.fli.term_t;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
* @see jpl.Term
* @see jpl.Compound
*
* @deprecated
*/
public class JRef extends Term {
@ -177,26 +177,6 @@ public class JRef extends Term {
Prolog.put_jref(term, ref);
}
//==================================================================/
// Converting Prolog terms to JPL Terms
//==================================================================/
/**
* Converts a term_t to a JRef. Assuming the Prolog term is a
* ref, we just create a new JRef using the term_t's value.
* NB This conversion is only invoked if "JPL-aware" term import is specified.
*
* @param vars_to_Vars A Map from Prolog variables to JPL Variables.
* @param term The term (a ref) to convert
* @return A new JRef instance
*/
protected static Term getTerm(Map vars_to_Vars, term_t term) {
ObjectHolder obj = new ObjectHolder();
Prolog.get_jref(term, obj); // assume it succeeds...
return new jpl.JRef(obj.value);
}
//==================================================================/
// Computing Substitutions
//==================================================================/
@ -212,4 +192,4 @@ public class JRef extends Term {
}
//345678901234567890123456789012346578901234567890123456789012345678901234567890
//345678901234567890123456789012346578901234567890123456789012345678901234567890

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: PrologException.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: PrologException.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -54,9 +54,10 @@ package jpl;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
public final class PrologException extends JPLException {
private static final long serialVersionUID = 1L;
private Term term_ = null;
protected PrologException(Term term) {

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: Query.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: Query.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -31,40 +31,39 @@ import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;
import jpl.fli.*;
//----------------------------------------------------------------------/
// Query
/**
* A Query instance is created by an application in order to query the Prolog engine.
* A Query instance is created by an application in order to query the Prolog database
* (or to invoke a built-in predicate).
* It is initialised with a
* Compound (or Atom) denoting the goal which is to be called, and also contains assorted private state
* relating to solutions. In some future version, it will contain details of the module
* relating to solutions. In some future version, it may contain details of the module
* in which the goal is to be called.<p>
* A Query is either open or closed: when closed, it has no connection to the Prolog engine;
* when open, it is linked to an active goal within the Prolog engine.
* Only one Query can be open at any one time<p>
* The Query class implements the Enumeration interface, and it is
* through this interface that one obtains successive solutions. The Enumeration
* A Query is either open or closed: when closed, it has no connection to the Prolog system;
* when open, it is linked to an active goal within a Prolog engine.<p>
* The Query class implements the Enumeration interface,
* through which one can obtain successive solutions. The Enumeration
* hasMoreElements() method returns true if the call or redo succeeded (otherwise
* false), and if the call or redo did succeed, the nextElement() method returns
* a Hashtable representing variable bindings; the elements in the
* Hashtable are Terms, indexed by the Variables with which they are associated.
* Hashtable are Terms, indexed by the (String) names of the Variables with which they are associated.
* For example, if <i>p(a)</i> and <i>p(b)</i> are facts in the Prolog
* database, then the following is equivalent to printing all
* the solutions to the Prolog query <i>p(X)</i>:
* <pre>
* Variable X = new Variable();
* Variable X = new Variable("X");
* Term arg[] = { X };
* Query q = new Query( "p", arg );
* Query q = new Query("p", arg);
*
* while ( q.hasMoreElements() ){
* Term bound_to_x = ((Hashtable)q.nextElement()).get( X );
* System.out.println( bound_to_x );
* while (q.hasMoreElements()){
* Term bound_to_x = ((Hashtable) q.nextElement()).get("X");
* System.out.println(bound_to_x);
* }
* </pre>
* Make sure to close the Query (using the rewind() method) if you do not need
* Make sure to close the Query (using the close() method) if you do not need
* any further solutions which it may have.
* It is safe (although redundant) to close a Query whose solutions are already exhausted,
* or which is already closed.
@ -73,12 +72,14 @@ import jpl.fli.*;
*
* To obtain all solutions, use the allSolutions() method.
*
* To obtain at most N solutions, use the nSolutions() method.
*
* To determine merely whether the Query is provable,
* use the query() method (soon to be deprecated in favour of hasSolution()).
* use the hasSolution() method
* (i.e. has at least one solution).
* <hr>
* <i>
* Copyright (C) 2004 Paul Singleton<p>
* Copyright (C) 2007 Paul Singleton<p>
* Copyright (C) 1998 Fred Dushin
* <p>
* This library is free software; you can redistribute it and/or
@ -93,26 +94,22 @@ import jpl.fli.*;
* </i>
* <hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
//
//----------------------------------------------------------------------/
public class Query implements Enumeration {
//==================================================================/
// Attributes
//==================================================================/
private static Map m = new Hashtable(); // maps (engine_t) engine handle to (Query) topmost query
private static Map m = new Hashtable(); // maps (engine_t) engine handle to (Query) topmost query
/**
* the Compound (hence perhaps an Atom, but not Integer, Float or Variable) corresponding to the goal of this Query
*/
protected final Compound goal_; // set by all initialisers
protected final String hostModule = "user"; // until revised constructors allow this to be specified
protected final String contextModule = "user"; // until revised constructors allow this to be specified
protected final Compound goal_; // set by all initialisers
protected final String hostModule = "user"; // until revised constructors allow this to be specified
protected final String contextModule = "user"; // until revised constructors allow this to be specified
/**
* @deprecated Use .goal().name() instead.
* @return the name of this Query's goal (redundant, deprecated)
@ -120,7 +117,6 @@ public class Query implements Enumeration {
public final String name() {
return goal_.name(); // it can only be a Compound or Atom
}
/**
* @deprecated Use .goal().args() instead.
* @return the arguments of this Query's goal (redundant, deprecated)
@ -128,7 +124,6 @@ public class Query implements Enumeration {
public final Term[] args() {
return goal_.args();
}
/**
* Returns the Compound (hence perhaps an Atom) which is the goal of this Query
* @return a Term representing the goal of this Query
@ -136,11 +131,9 @@ public class Query implements Enumeration {
public final Compound goal() {
return goal_;
}
//==================================================================/
// Constructors and Initialization
//==================================================================/
//------------------------------------------------------------------/
// Query
/**
@ -148,15 +141,14 @@ public class Query implements Enumeration {
* The Query is initially closed.
* <b>NB</b> Creating an instance of the Query class does not
* result in a call to a Prolog engine.
* <b>NB</b> The goal can be an Atom (Atom extends Compound), but cannot be an instance
* <b>NB</b> The goal can be a Compound or an Atom (Atom extends Compound), but cannot be an instance
* of jpl.Float, jpl.Integer or jpl.Variable.
* @param t the goal of this Query
*/
public Query(Term t) { // formerly insisted (confusingly) on a Compound (or Atom)
this.goal_ = Query1( t);
this.goal_ = Query1(t);
}
private Compound Query1( Term t ) {
private Compound Query1(Term t) {
if (t instanceof Compound) {
return (Compound) t;
} else if (t instanceof Integer) {
@ -169,12 +161,11 @@ public class Query implements Enumeration {
throw new JPLException("a Query's goal must be an Atom or Compound");
}
}
// Query
/**
* If text denotes an atom, this constructor is shorthand for
* <font face="monospace">new Query(new Compound(name,args))</font>,
* but if text denotes a term containing N query symbols
* but if text denotes a term containing N query (?) symbols
* and there are N args, each query is replaced by its corresponding arg
* to provide the new Query's goal.
*
@ -184,60 +175,56 @@ public class Query implements Enumeration {
public Query(String text, Term[] args) {
this(Query1(text, args));
}
// convenience case for a single arg
public Query(String text, Term arg) {
this(Query1(text, new Term[] {arg}));
this(Query1(text, new Term[] { arg }));
}
private static Term Query1( String text, Term[] args) {
private static Term Query1(String text, Term[] args) {
Term t = Util.textToTerm(text);
if ( t instanceof Atom ){
return new Compound(text,args);
if (t instanceof Atom) {
return new Compound(text, args);
} else {
return t.putParams(args);
}
}
// Query
/**
* This constructor builds a Query from the given Prolog source text
* This constructor builds a Query from the given Prolog source text.
* Throws PrologException containing error(syntax_error(_),_) if text is invalid.
*
* @param text the Prolog source text of this Query
*/
public Query(String text) {
this(Util.textToTerm(text));
}
//==================================================================/
// Making Prolog Queries
//==================================================================/
/**
* These variables are used and set across the hasMoreElements
* and nextElement Enumeration interface implementation
*/
private boolean open = false;
private boolean open = false;
// the following state variables are used and defined only if this query is open:
private boolean called = false; // open/get/close vs. hasMoreSolutions/nextSolution
private engine_t engine = null; // handle of attached Prolog engine iff open, else null
private Query subQuery = null; // the open Query (if any) on top of which this open Query is stacked, else null
private predicate_t predicate = null; // handle of this Query's predicate iff open, else undefined
private fid_t fid = null; // id of current Prolog foreign frame iff open, else null
private term_t term0 = null; // term refs of this Query's args iff open, else undefined
private qid_t qid = null; // id of current Prolog query iff open, else null
// private boolean called = false; // open/get/close vs. hasMoreSolutions/nextSolution
private engine_t engine = null; // handle of attached Prolog engine iff open, else null
private Query subQuery = null; // the open Query (if any) on top of which this open Query is stacked, else null
private predicate_t predicate = null; // handle of this Query's predicate iff open, else undefined
// private fid_t fid = null; // id of current Prolog foreign frame iff open, else null
// private fid_t fid2 = null; // id of experimental inner frame
private term_t term0 = null; // term refs of this Query's args iff open, else undefined
private qid_t qid = null; // id of current Prolog query iff open, else null
//------------------------------------------------------------------/
// hasMoreSolutions
/**
* This method returns true if JPL was able to initiate a "call" of this
* Query within the Prolog engine. It is designed to be used
* Query within a Prolog engine. It is designed to be used
* with the nextSolution() method to retrieve one or
* more substitutions in the form of Hashtables. To iterate through
* all the solutions to a Query, for example, one might write
* <pre>
* Query q = // obtain Query reference
* while ( q.hasMoreSolutions() ){
* while (q.hasMoreSolutions()) {
* Hashtable solution = q.nextSolution();
* // process solution...
* }
@ -254,22 +241,15 @@ public class Query implements Enumeration {
* }
* }
* </pre>
* <p>
* If this method is called on an already-open Query,
* or while another Query is open, then a
* QueryInProgressException will be thrown, containing a reference to the currently
* open Query.
*
* @return true if the Prolog query succeeds; otherwise false.
*/
public synchronized final boolean hasMoreSolutions() {
if (!open) {
open();
}
return get1();
}
//------------------------------------------------------------------/
// open
/**
@ -295,11 +275,10 @@ public class Query implements Enumeration {
* then a JPLException will be thrown.
*/
public synchronized final void open() {
if (open) {
throw new JPLException("Query is already open");
}
int self = Prolog.thread_self();
// int self = Prolog.thread_self();
// System.out.println("JPL thread_self()=" + self);
if (Prolog.thread_self() == -1) { // this Java thread has no attached Prolog engine?
engine = Prolog.attach_pool_engine(); // may block for a while, or fail
@ -315,21 +294,40 @@ public class Query implements Enumeration {
subQuery = null;
}
m.put(new Long(engine.value), this); // update this engine's topmost query
predicate = Prolog.predicate(goal_.name(), goal_.args.length, hostModule);
fid = Prolog.open_foreign_frame(); // always succeeds?
//
// here, we must check for a module prefis, e.g. jpl:jpl_modifier_bit(volatile,T)
String module;
Term goal;
if (goal_.hasFunctor(":", 2)) {
if (goal_.arg(1).isAtom()) {
module = goal_.arg(1).name();
} else if (goal_.arg(1).isVariable()) {
throw new PrologException(Util.textParamsToTerm("error(instantiation_error,?)", new Term[] { goal_ }));
} else {
throw new PrologException(Util.textParamsToTerm("error(type_error(atom,?),?)", new Term[] { goal_.arg(1), goal_ }));
}
goal = goal_.arg(2);
} else {
module = contextModule;
goal = goal_;
}
predicate = Prolog.predicate(goal.name(), goal.arity(), module); // was hostModule
// fid = Prolog.open_foreign_frame(); // always succeeds?
Map varnames_to_vars = new Hashtable();
term0 = Term.putTerms(varnames_to_vars, goal_.args);
term0 = Term.putTerms(varnames_to_vars, goal.args());
// THINKS: invert varnames_to_Vars and use it when getting substitutions?
qid = Prolog.open_query(Prolog.new_module(Prolog.new_atom(contextModule)), Prolog.Q_NORMAL, predicate, term0);
qid = Prolog.open_query(Prolog.new_module(Prolog.new_atom(contextModule)), Prolog.Q_CATCH_EXCEPTION, predicate, term0);
open = true;
called = false;
// called = false;
}
private final boolean get1() {
// try to get the next solution; if none, close the query;
private final boolean get1() { // try to get the next solution; if none, close the query;
// if (fid2 != null) { // PS 23/Mar/2007 ensure inner frame is closed
// Prolog.close_foreign_frame(fid2);
// fid2 = null;
// }
if (Prolog.next_solution(qid)) {
called = true; // OK to call get2()
// fid2 = Prolog.open_foreign_frame(); // PS 23/Mar/2007 open an inner frame
// called = true; // OK to call get2()
return true;
} else {
// if failure was due to throw/1, build exception term and throw it
@ -344,25 +342,22 @@ public class Query implements Enumeration {
}
}
}
//------------------------------------------------------------------/
// getSolution
/**
* This method returns a java.util.Hashtable, which represents
* a set of bindings from the names of query variables to terms within the solution.
* The Hashtable contains instances of Terms, keyed on those
* Variables which were referenced in this Query's goal.
* <p>
* For example, if a Query has an occurrence of a jpl.Variable,
* say, named X, one can obtain the Term bound to X in the solution
* by looking up X in the Hashtable.
* say, named "X", one can obtain the Term bound to "X" in the solution
* by looking up "X" in the Hashtable.
* <pre>
* Variable X = new Variable();
* Query q = // obtain Query reference (with X in the Term array)
* while ( q.hasMoreSolutions() ){
* Variable x = new Variable("X");
* Query q = // obtain Query reference (with x in the Term array)
* while (q.hasMoreSolutions()) {
* Hashtable solution = q.nextSolution();
* // make t the Term bound to X in the solution
* Term t = (Term)solution.get( X );
* // make t the Term bound to "X" in the solution
* Term t = (Term) solution.get("X");
* // ...
* }
* </pre>
@ -370,19 +365,13 @@ public class Query implements Enumeration {
* <menu>
* <li> The nextSolution() method should only be called after the
* hasMoreSolutions() method returns true; otherwise a JPLException
* will be raised, indicating that no Query is in progress.
* will be raised, indicating that the Query is no longer open.
* <li> The nextSolution() and hasMoreSolutions() should be called
* in the same thread of execution, at least for a given Query
* in the same thread of execution, for a given Query
* instance.
* <li> The nextSolution() method should not be called while
* another Thread is in the process of evaluating a Query. The
* JPL High-Level interface is designed to be thread safe, and
* is thread-safe as long as the previous two rules are obeyed.
* </menu>
*
* This method will throw a JPLException if no query is in progress.
* It will throw a QueryInProgressException if another Query
* (besides this one) is in progress while this method is called.
* This method will throw a JPLException if Query is not open.
*
* @return A Hashtable representing a substitution, or null
*/
@ -394,7 +383,6 @@ public class Query implements Enumeration {
return null;
}
}
public synchronized final Hashtable getSubstWithNameVars() {
// oughta check: Query is open and thread has its engine
if (get1()) {
@ -403,25 +391,22 @@ public class Query implements Enumeration {
return null;
}
}
//------------------------------------------------------------------/
// nextSolution
/**
* This method returns a java.util.Hashtable, which represents
* a binding from the names of query variables to terms within the solution.
* The Hashtable contains instances of Terms, keyed on those
* Variables which were referenced in this Query's goal.
* <p>
* For example, if a Query has an occurrence of a jpl.Variable,
* say, named X, one can obtain the Term bound to X in the solution
* by looking up X in the Hashtable.
* say, named "X", one can obtain the Term bound to "X" in the solution
* by looking up "X" in the Hashtable.
* <pre>
* Variable X = new Variable();
* Query q = // obtain Query reference (with X in the Term array)
* while ( q.hasMoreSolutions() ){
* Variable x = new Variable("X");
* Query q = // obtain Query reference (with x in the Term array)
* while (q.hasMoreSolutions()) {
* Hashtable solution = q.nextSolution();
* // make t the Term bound to X in the solution
* Term t = (Term)solution.get( X );
* // make t the Term bound to "X" in the solution
* Term t = (Term) solution.get("X");
* // ...
* }
* </pre>
@ -429,26 +414,19 @@ public class Query implements Enumeration {
* <menu>
* <li> The nextSolution() method should only be called after the
* hasMoreSolutions() method returns true; otherwise a JPLException
* will be raised, indicating that no Query is in progress.
* will be raised, indicating that the Query is no longer open.
* <li> The nextSolution() and hasMoreSolutions() should be called
* in the same thread of execution, at least for a given Query
* in the same thread of execution, for a given Query
* instance.
* <li> The nextSolution() method should not be called while
* another Thread is in the process of evaluating a Query. The
* JPL High-Level interface is designed to be thread safe, and
* is thread-safe as long as the previous two rules are obeyed.
* </menu>
*
* This method will throw a JPLException if no query is in progress.
* It will throw a QueryInProgressException if another Query
* (besides this one) is in progress while this method is called.
* This method will throw a JPLException if Query is not open.
*
* @return A Hashtable representing a substitution.
*/
public synchronized final Hashtable nextSolution() {
return get2();
}
private final Hashtable get2() {
if (!open) {
throw new JPLException("Query is not open");
@ -459,7 +437,6 @@ public class Query implements Enumeration {
return substitution;
}
}
// assumes that Query's last arg is a Variable which will be bound to a [Name=Var,..] dict
private final Hashtable get2WithNameVars() {
if (!open) {
@ -468,72 +445,56 @@ public class Query implements Enumeration {
Term[] args = goal_.args; // for slight convenience below
Term argNV = args[args.length - 1]; // the Query's last arg
String nameNV = ((Variable) argNV).name; // its name
// get the [Name=Var,..] dict from the last arg
Map varnames_to_Terms1 = new Hashtable();
Map vars_to_Vars1 = new Hashtable();
args[args.length - 1].getSubst(varnames_to_Terms1, vars_to_Vars1);
Hashtable varnames_to_Terms2 = new Hashtable();
Term nvs = (Term) varnames_to_Terms1.get(nameNV);
Map vars_to_Vars2 = Util.namevarsToMap(nvs);
for (int i = 0; i < args.length - 1; ++i) {
args[i].getSubst(varnames_to_Terms2, vars_to_Vars2);
}
return varnames_to_Terms2;
}
}
//------------------------------------------------------------------/
// hasMoreElements
/**
* This method is completes the java.util.Enumeration
* This method implements part of the java.util.Enumeration
* interface. It is a wrapper for hasMoreSolutions.
*
* @return true if the Prolog query succeeds; false, o/w.
* @return true if the Prolog query yields a (or another) solution, else false.
*/
public synchronized final boolean hasMoreElements() {
return hasMoreSolutions();
}
//------------------------------------------------------------------/
// nextElement
/**
* This method completes the java.util.Enumeration
* This method implements part of the java.util.Enumeration
* interface. It is a wrapper for nextSolution.
* <p>
* This method will throw a QueryInProgressException if another Query
* (besides this one) is in progress while this method is called.
*
* @return A Hashtable representing a substitution.
*/
public synchronized final Object nextElement() {
return nextSolution();
}
public synchronized final void rewind() {
close();
}
//------------------------------------------------------------------/
// close
/**
* This method is used to close an open query so that the query
* may be re-run, even if the Query's Enumeration has more
* elements. Calling rewind() on an exhausted Enumeration has
* no effect.<p>
* This method can be used to close an open query before its solutions are exhausted.
* It is called automatically when solutions are exhausted, i.e. when hasMoreSolutions() fails.
* Calling close() on an already closed Query is harmless (has no effect).<p>
*
* Here is a way to get the first three solutions to a Query,
* while subsequently being able to use the same Query object to
* obtain new solutions:
* Here is one way to get the first three solutions to a Query:
* <pre>
* Query q = new Query( predicate, args );
* int i = 0;
* for ( int i = 0; i < 3 && q.hasMoreSolutions(); ++i ){
* Hasthable sub = (Hashtable) q.nextSolution();
* ...
* }
* Query q = new Query(predicate, args);
* Hashtable sub1 = (Hashtable) q.nextSolution();
* Hashtable sub2 = (Hashtable) q.nextSolution();
* Hashtable sub3 = (Hashtable) q.nextSolution();
* q.close();
* </pre><p>
*/
@ -549,23 +510,11 @@ public class Query implements Enumeration {
}
Query topmost = (Query) m.get(new Long(engine.value));
if (topmost != this) {
throw new JPLException(
"this Query ("
+ this.hashCode()
+ ":"
+ this.toString()
+ ") is not topmost ("
+ topmost.hashCode()
+ ":"
+ topmost.toString()
+ ") within its engine["
+ engine.value
+ "]");
throw new JPLException("this Query (" + this.hashCode() + ":" + this.toString() + ") is not topmost (" + topmost.hashCode() + ":" + topmost.toString() + ") within its engine["
+ engine.value + "]");
}
Prolog.close_query(qid);
qid = null; // for tidiness
Prolog.discard_foreign_frame(fid);
fid = null; // for tidiness
m.remove(new Long(engine.value));
if (subQuery == null) { // only Query open in this engine?
if (Prolog.current_engine_is_pool()) { // this (Query's) engine is from the pool?
@ -578,36 +527,20 @@ public class Query implements Enumeration {
m.put(new Long(engine.value), subQuery);
// System.out.println("JPL retaining engine[" + engine.value + "] popping subQuery(" + subQuery.hashCode() + ":" + subQuery.toString() + ")");
}
// eid = -1; // for tidiness
engine = null;
subQuery = null;
open = false;
called = false;
open = false; // this Query is now closed
engine = null; // this Query, being closed, is no longer associated with any Prolog engine
subQuery = null; // this Query, being closed, is not stacked upon any other Query
}
//------------------------------------------------------------------/
// allSolutions
/**
* calls the Query's goal to exhaustion and returns an array containing every solution
* (in the order in which they were found).
* @return an array of Hashtables (possibly none), each of which is a solution
* (in the order in which they were found) of the Query.
* <b>NB</b> in JPL 1.0.1, this method returned null when a Query had no solutions;
* in JPL 2.x.x it returns an emprt array (thus the length of the array is, in every case,
* calls the Query's goal to exhaustion
* and returns an array of zero or more Hashtables of zero or more variablename-to-term bindings (each Hashtable represents a solution, in the order in which they were found).
* @return an array of zero or more Hashtables of zero or more variablename-to-term bindings (each Hashtable represents a solution, in the order in which they were found)
* <b>NB</b> in JPL 1.0.1, this method (inconsistently) returned null when a Query had no solutions;
* in JPL 2.x onwards it returns an empty array (thus the length of the array is, in every case,
* the quantity of solutions).<p>
*
* This method will throw a QueryInProgressException if this or another Query
* is already open.
*
* @see jpl.Query#hasMoreElements
* @see jpl.Query#nextElement
* @see jpl.Query#hasMoreSolutions
* @see jpl.Query#nextSolution
* @see jpl.Query#rewind
* @see jpl.Query#oneSolution
* @see jpl.Query#allSolutions
* @see jpl.Query#query
* <b>NB</b> in JPL 1.0.1, bindings were keyed (awkwardly) by Variable instances;
* in JPL 2.x onwards they are keyed by the (String) names of variables,
* which is consistent with the Term type being just a concrete syntax for terms (and hence queries).<p>
*/
public synchronized final Hashtable[] allSolutions() {
if (open) {
@ -618,99 +551,249 @@ public class Query implements Enumeration {
while (hasMoreSolutions()) {
v.addElement(nextSolution());
}
// turn the vector into an array:
Hashtable solutions[] = new Hashtable[v.size()]; // 0 solutions -> Hashtable[0]
v.copyInto(solutions);
return solutions;
}
}
//------------------------------------------------------------------/
// oneSolution
/**
* Returns the first solution, if any, as a (possibly empty) Hashtable.
* This static method creates a Query whose goal is the given Term,
* calls it to exhaustion,
* and returns an array of zero or more Hashtables of zero or more variablename-to-term bindings (each Hashtable represents a solution, in the order in which they were found).
* Throws JPLException if goal is neither a jpl.Atom nor a jpl.Compound.
*
* This method will throw a JPLException if this Query
* is already open, and the Query will remain open as before.
* @return an array of zero or more Hashtables of zero or more variablename-to-term bindings (each Hashtable represents a solution, in the order in which they were found)
*
* @param goal the goal of this Query
*/
public static final Hashtable[] allSolutions(Term goal) {
return (new Query(goal)).allSolutions();
}
/**
* This static method creates a Query from the given Prolog source text fragment,
* calls it to exhaustion,
* and returns an array of zero or more Hashtables of zero or more variablename-to-term bindings (each Hashtable represents a solution, in the order in which they were found).
* Throws PrologException containing error(syntax_error(_),_) if text is invalid.
*
* @return an array of zero or more Hashtables of zero or more variablename-to-term bindings (each Hashtable represents a solution, in the order in which they were found)
*
* @param text a Prolog source text fragment denoting a goal
*/
public static final Hashtable[] allSolutions(String text) {
return (new Query(text)).allSolutions();
}
/**
* If text denotes (in traditional Prolog source syntax) a term containing N questionmark (?) symbols and there are N accompanying Term params,
* this static method replaces each questionmark symbol by its respective param,
* calls the resulting goal to exhaustion,
* and returns an array of zero or more Hashtables of zero or more variablename-to-term bindings (each Hashtable represents a solution, in the order in which they were found).
*
* Otherwise, if text denotes an atom, this static method creates a Query
* where text is the name of the goal and params are the args;
* the resulting goal is then called as above.
* This letter mode is redundant, deprecated (informally), and retained only for backward compatibility.
*
* @return an array of zero or more Hashtables of zero or more variablename-to-term bindings (each Hashtable represents a solution, in the order in which they were found)
*
* @param text the Prolog source text of a goal, in which questionmarks are regarded as substitutible parameters
* @param params terms to be substituted for the respective questionmarks in the query text
*/
public static final Hashtable[] allSolutions(String text, Term[] params) {
return (new Query(text, params)).allSolutions();
}
/**
* calls the Query's goal to exhaustion or until N solutions are found, whichever is sooner,
* and returns an array containing (as possibly empty Hashtables of variablename-to-term bindings) every found solution (in the order in which they were found).
* @return an array of Hashtables (possibly none), each of which is a solution
* (in the order in which they were found) of the Query; at most 'n' solutions will be found and returned.
* <b>NB</b> in JPL 1.0.1, this method (inconsistently) returned null when a Query had no solutions;
* in JPL 2.x onwards it returns an empty array (thus the length of the array is, in every case,
* the quantity of solutions).<p>
* <b>NB</b> in JPL 1.0.1, bindings were keyed (awkwardly) by Variable instances;
* in JPL 2.x onwards they are keyed by the (String) names of variables,
* which is consistent with the Term type being just a concrete syntax for terms (and hence queries).<p>
*/
public synchronized final Hashtable[] nSolutions(long n) {
if (open) {
throw new JPLException("Query is already open");
} else {
// get a vector of solutions:
Vector v = new Vector();
for (long i = 0; i++ < n && hasMoreSolutions();) {
v.addElement(nextSolution());
}
// turn the vector into an array:
Hashtable solutions[] = new Hashtable[v.size()]; // 0 solutions -> Hashtable[0]
v.copyInto(solutions);
return solutions;
}
}
/**
* This static method creates a Query whose goal is the given Term,
* calls it to exhaustion or until N solutions are found, whichever is sooner,
* and returns an array containing (as possibly empty Hashtables of variablename-to-term bindings) every found solution (in the order in which they were found).
* Throws JPLException if goal is neither a jpl.Atom nor a jpl.Compound.
*
* @param goal the goal of this Query
*/
public static final Hashtable[] nSolutions(Term goal, long n) {
return (new Query(goal)).nSolutions(n);
}
/**
* This static method creates a Query from the given Prolog source text fragment,
* calls it to exhaustion or until N solutions are found, whichever is sooner,
* and returns an array containing (as possibly empty Hashtables of variablename-to-term bindings) every found solution (in the order in which they were found).
* Throws PrologException containing error(syntax_error(_),_) if text is invalid.
*
* @param text a Prolog source text fragment denoting a goal
*/
public static final Hashtable[] nSolutions(String text, long n) {
return (new Query(text)).nSolutions(n);
}
/**
* If text denotes (in traditional Prolog source syntax) a term containing N questionmark (?) symbols and there are N accompanying params,
* this static method replaces each questionmark symbol by its respective param,
* calls the resulting goal to exhaustion or until N solutions are found, whichever is sooner,
* and returns an array containing (as possibly empty Hashtables of variablename-to-term bindings) every found solution (in the order in which they were found).
*
* Otherwise, if text denotes an atom, this static method creates a Query
* where text is the name of the goal and params are the args;
* the resulting goal is then called as above.
* This latter mode is redundant, deprecated (informally), and retained only for backward compatibility.
*
* @param text the Prolog source text of a goal, in which questionmarks are regarded as substitutible parameters
* @param params terms to be substituted for the respective questionmarks in the query text
*/
public static final Hashtable[] nSolutions(String text, Term[] params, long n) {
return (new Query(text, params)).nSolutions(n);
}
/**
* Returns the first solution, if any, as a (possibly empty) Hashtable of variablename-to-term bindings, else null.
*
* This method will throw a JPLException if this Query is already open (and the Query will remain open as before).
* Otherwise, upon return, the Query will be closed.
* @return the first solution, if the query has one, as a (possibly empty) Hashtable.
* If the return value is null, this means that the Query has no solutions.<p>
*
* @see jpl.Query#hasMoreElements
* @see jpl.Query#nextElement
* @see jpl.Query#hasMoreSolutions
* @see jpl.Query#nextSolution
* @see jpl.Query#rewind
* @see jpl.Query#oneSolution
* @see jpl.Query#allSolutions
* @see jpl.Query#query
*/
public synchronized final Hashtable oneSolution() {
if (open) {
throw new JPLException("Query is already open");
} else {
Hashtable solution = null;
Hashtable solution;
if (hasMoreSolutions()) {
solution = nextSolution();
close(); // safe, whether or not this is the only solution
} else {
solution = null;
}
rewind();
return solution;
}
}
//------------------------------------------------------------------/
// query
/**
* @deprecated Use .hasSolution() instead.
* JPL will attempt to call this Query's goal within the attached Prolog engine.
* This static method creates a Query (whose goal is the specified Term)
* and calls it at most once, returning the first solution, if there is one, as a (possibly empty) Hashtable, else null.
* The goal can be a jpl.Atom or a jpl.Compound, but cannot be an instance
* of jpl.Float, jpl.Integer or jpl.Variable.
*
* @param goal the goal of this Query
*/
public static final Hashtable oneSolution(Term goal) {
return (new Query(goal)).oneSolution();
}
/**
* This static method creates a Query from the given Prolog source text fragment,
* and calls it at most once, returning the first solution, if there is one, as a (possibly empty) Hashtable, else null.
* Throws PrologException containing error(syntax_error(_),_) if text is invalid.
*
* @param text a Prolog source text fragment denoting a goal
*/
public static final Hashtable oneSolution(String text) {
return (new Query(text)).oneSolution();
}
/**
* If text denotes (in traditional Prolog source syntax) a term containing N questionmark (?) symbols
* and there are N params, each questionmark symbol is replaced by its respective param
* to provide the goal of this query:
* the resulting goal is then called (at most once) and the first solution, if there is one, is returned as a (possibly empty) Hashtable, else null.
*
* Otherwise, if text denotes an atom, this static method creates a Query
* where text is the name of the goal and params are the args;
* the resulting goal is then called as above.
* This latter mode is redundant, deprecated (informally), and retained only for backward compatibility.
*
* @param text the Prolog source text of a goal, in which questionmarks are regarded as substitutible parameters
* @param params terms to be substituted for the respective questionmarks in the query text
*/
public static final Hashtable oneSolution(String text, Term[] params) {
return (new Query(text, params)).oneSolution();
}
/**
* This method will attempt to call this Query's goal within an available Prolog engine.
* @return the provability of the Query, i.e. 'true' if it has at least
* one solution, 'false' if the call fails without finding a solution.<p>
*
* Only the first solution (if there is one) will be found;
* any bindings will be discarded, and the Query will be closed.<p>
* This method will throw a QueryInProgressException if this or another Query
* is already open.
* This method will throw a JPLException if this Query is already open.
*
* @see jpl.Query#hasMoreElements
* @see jpl.Query#nextElement
* @see jpl.Query#hasMoreSolutions
* @see jpl.Query#nextSolution
* @see jpl.Query#rewind
* @see jpl.Query#oneSolution
* @see jpl.Query#allSolutions
* @see jpl.Query#query
* @deprecated Use .hasSolution() instead.
*/
public synchronized final boolean query() {
return oneSolution() != null;
}
//------------------------------------------------------------------/
// hasSolution
/**
* JPL will attempt to call this Query's goal within the attached Prolog engine.
* This method will attempt to call this Query's goal within an available Prolog engine.
* @return the provability of the Query, i.e. 'true' if it has at least
* one solution, 'false' if the call fails without finding a solution.<p>
*
* Only the first solution (if there is one) will be found;
* any bindings will be discarded, and the Query will be closed.<p>
* This method will throw a QueryInProgressException if this or another Query
* is already open.
*
* @see jpl.Query#hasMoreElements
* @see jpl.Query#nextElement
* @see jpl.Query#hasMoreSolutions
* @see jpl.Query#nextSolution
* @see jpl.Query#rewind
* @see jpl.Query#oneSolution
* @see jpl.Query#allSolutions
* @see jpl.Query#query
* This method will throw a JPLException if this Query is already open.
*/
public synchronized final boolean hasSolution() {
return oneSolution() != null;
}
/**
* This static method creates a Query (whose goal is the specified Term)
* and calls it at most once, returning true if a solution was found, else false.
* The goal can be a jpl.Atom or a jpl.Compound, but cannot be an instance
* of jpl.Float, jpl.Integer or jpl.Variable.
*
* @param goal the goal of this Query
*/
public static final boolean hasSolution(Term goal) {
return (new Query(goal)).hasSolution();
}
/**
* This static method creates a Query from the given Prolog source text
* and calls it at most once, returning true if a solution was found, else false.
* Throws PrologException containing error(syntax_error(_),_) if text is invalid.
*
* @param text the goal of this Query, as Prolog source text
*/
public static final boolean hasSolution(String text) {
return (new Query(text)).hasSolution();
}
/**
* If text denotes (in traditional Prolog source syntax) a term containing N questionmark (?) symbols
* and there are N params, each questionmark symbol is replaced by its corresponding arg
* to provide the new Query's goal: the resulting Query is called as described above.
*
* Otherwise, if text denotes an atom, this static method creates a Query
* where text is the name of its goal and args are its args;
* it then calls this goal (at most once) and returns true if a solution was found, else false.
* This latter mode is redundant, deprecated (informally), and retained only for backward compatibility.
*
* @param text the Prolog source text of a goal, in which questionmarks are regarded as substitutible parameters
* @param params terms to be substituted for the respective questionmarks in the query text
*/
public static final boolean hasSolution(String text, Term[] params) {
return (new Query(text, params)).hasSolution();
}
//
// this method doesn't work, but is intended to be called from another thread,
// to abort a Query which is open and possibly currently executing nextSolution() or similar
public final int abort() {
if (open) {
(new Thread(new Runnable() {
@ -723,37 +806,36 @@ public class Query implements Enumeration {
// int rc3 = Prolog.release_pool_engine();
// System.out.println("q.abort(): release_pool_engine() returns " + rc3);
} catch (Exception e) {
}
}
})).start(); // call the query in a separate thread
/*
int rc0a = Prolog.pool_engine_id(this.engine);
System.out.println("q.abort(): this.engine has id=" + rc0a);
int rc0a = Prolog.pool_engine_id(this.engine);
System.out.println("q.abort(): this.engine has id=" + rc0a);
engine_t e = Prolog.current_engine();
System.out.println("q.abort(): " + (e == null ? "no current engine" : "current engine id=" + Prolog.pool_engine_id(e)));
engine_t e = Prolog.current_engine();
System.out.println("q.abort(): " + (e == null ? "no current engine" : "current engine id=" + Prolog.pool_engine_id(e)));
int rc0b = Prolog.release_pool_engine();
System.err.println("q.abort(): release_pool_engine() returns " + rc0b);
int rc0b = Prolog.release_pool_engine();
System.err.println("q.abort(): release_pool_engine() returns " + rc0b);
engine_t e2 = Prolog.current_engine();
System.out.println("q.abort(): " + (e == null ? "no current engine" : "current engine id=" + Prolog.pool_engine_id(e2)));
engine_t e2 = Prolog.current_engine();
System.out.println("q.abort(): " + (e == null ? "no current engine" : "current engine id=" + Prolog.pool_engine_id(e2)));
int rc1 = Prolog.attach_engine(this.engine);
System.out.println("q.abort(): attach_engine() returns " + rc1);
int rc1 = Prolog.attach_engine(this.engine);
System.out.println("q.abort(): attach_engine() returns " + rc1);
engine_t e3 = Prolog.current_engine();
System.out.println("q.abort(): " + (e == null ? "no current engine" : "current engine id=" + Prolog.pool_engine_id(e3)));
engine_t e3 = Prolog.current_engine();
System.out.println("q.abort(): " + (e == null ? "no current engine" : "current engine id=" + Prolog.pool_engine_id(e3)));
int rc2 = Prolog.action_abort();
System.out.println("q.abort(): action_abort() returns " + rc2);
int rc2 = Prolog.action_abort();
System.out.println("q.abort(): action_abort() returns " + rc2);
int rc3 = Prolog.release_pool_engine();
System.out.println("q.abort(): release_pool_engine() returns " + rc3);
int rc3 = Prolog.release_pool_engine();
System.out.println("q.abort(): release_pool_engine() returns " + rc3);
int rc4 = Prolog.attach_engine(e);
System.out.println("q.abort(): attach_engine() returns " + rc4);
int rc4 = Prolog.attach_engine(e);
System.out.println("q.abort(): attach_engine() returns " + rc4);
*/
return 0;
} else {
@ -761,24 +843,20 @@ public class Query implements Enumeration {
return -1;
}
}
//==================================================================/
// misc
//==================================================================/
/**
* Returns the String representation of a Query.
* Returns a crude String representation of a Query.
*
* @return the String representation of a Query
* @return a crude String representation of a Query
*/
public String toString() {
return goal_.name + "( " + Term.toString(goal_.args) + " )";
}
//==================================================================/
// Methods (deprecated)
//==================================================================/
/**
* Returns a debug-friendly representation of a Query
*

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: Term.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: Term.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -27,10 +27,14 @@
//*****************************************************************************/
package jpl;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import jpl.fli.DoubleHolder;
import jpl.fli.Int64Holder;
import jpl.fli.IntHolder;
import jpl.fli.Prolog;
import jpl.fli.StringHolder;
import jpl.fli.term_t;
//----------------------------------------------------------------------/
@ -58,7 +62,7 @@ import jpl.fli.term_t;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
public abstract class Term {
//==================================================================/
@ -90,6 +94,15 @@ public abstract class Term {
throw new JPLException("jpl." + this.typeName() + ".arg() is undefined");
};
/**
* returns, as a Term[], the arguments of a Compound
* returns an empty Term[] from an Atom, Integer or Float
* throws a JPLException from a Variable
*
* @return the arguments of a Compound as a Term[
*/
public abstract Term[] args();
/**
* Tests whether this Term's functor has (String) 'name' and 'arity'
* Returns false if called inappropriately
@ -232,33 +245,6 @@ public abstract class Term {
return this instanceof Integer;
}
/**
* whether this Term is a JBoolean
*
* @return whether this Term is a JBoolean
*/
public boolean isJBoolean() {
return this instanceof JBoolean;
}
/**
* whether this Term is a JRef
*
* @return whether this Term is a JRef
*/
public boolean isJRef() {
return this instanceof JRef;
}
/**
* whether this Term is a JVoid
*
* @return whether this Term is a JVoid
*/
public boolean isJVoid() {
return this instanceof JVoid;
}
/**
* whether this Term is a variable
*
@ -268,6 +254,60 @@ public abstract class Term {
return this instanceof Variable;
}
/**
* whether this Term is a 'jfalse' structure, i.e. @(false)
*
* @return whether this Term is a 'jfalse' structure, i.e. @(false)
*/
public boolean isJFalse() {
return false; // overridden in Compound, where it might sometimes be true
}
/**
* whether this Term is a 'jtrue' structure, i.e. @(true)
*
* @return whether this Term is a 'jtrue' structure, i.e. @(true)
*/
public boolean isJTrue() {
return false; // overridden in Compound, where it might sometimes be true
}
/**
* whether this Term is a 'jnull' structure, i.e. @(null)
*
* @return whether this Term is a 'jnull' structure, i.e. @(null)
*/
public boolean isJNull() {
return false; // overridden in Compound, where it might sometimes be true
}
/**
* whether this Term is a 'jvoid' structure, i.e. @(void)
*
* @return whether this Term is a 'jvoid' structure, i.e. @(void)
*/
public boolean isJVoid() {
return false; // overridden in Compound, where it might sometimes be true
}
/**
* whether this Term is a 'jobject' structure, i.e. @(Tag)
*
* @return whether this Term is a 'jobject' structure, i.e. @(Tag)
*/
public boolean isJObject() {
return false; // overridden in Compound, where it might sometimes be true
}
/**
* whether this Term is a 'jref' structure, i.e. @(Tag) or @(null)
*
* @return whether this Term is a 'jref' structure, i.e. @(Tag) or @(null)
*/
public boolean isJRef() {
return false; // overridden in Compound, where it might sometimes be true
}
public Term putParams(Term[] ps) {
IntHolder next = new IntHolder();
next.value = 0;
@ -351,16 +391,6 @@ public abstract class Term {
// Methods (deprecated)
//==================================================================/
/**
* returns, as a Term[], the arguments of a Compound
* returns an empty Term[] from an Atom, Integer or Float
* throws a JPLException from a Variable
*
* @return the arguments of a Compound as a Term[
* @deprecated
*/
public abstract Term[] args();
/**
* Returns a debug-friendly representation of a Term
*
@ -412,6 +442,9 @@ public abstract class Term {
// instances, keyed on Variable instances.
//==================================================================/
public void put( term_t term){
put( new Hashtable(), term);
}
/**
* Cache the reference to the Prolog term_t here.
*
@ -457,6 +490,15 @@ public abstract class Term {
return term0;
}
// experiment: for jni_jobject_to_term_byval/2 in jpl.c
public static void putTerm( Object obj, term_t termref){
if (obj instanceof Term){
((Term)obj).put(termref);
} else {
throw new JPLException("not a Term");
}
}
//==================================================================/
// Converting Prolog terms to JPL Terms
//
@ -543,7 +585,7 @@ public abstract class Term {
* @param term The Prolog term (in a term_t holder) to convert
* @return The converted Term subtype instance.
*/
protected static Term getTerm(Map vars_to_Vars, term_t term) {
protected static Term getTerm1(Map vars_to_Vars, term_t term) {
int type = Prolog.term_type(term);
switch (type) {
@ -565,6 +607,62 @@ public abstract class Term {
}
}
protected static Term getTerm(Map vars_to_Vars, term_t term) {
StringHolder hString;
IntHolder hInt;
Int64Holder hInt64;
// int type = Prolog.term_type(term);
switch (Prolog.term_type(term)) {
case Prolog.VARIABLE:
for (Iterator i = vars_to_Vars.keySet().iterator(); i.hasNext();) {
term_t varX = (term_t) i.next(); // a previously seen Prolog variable
if (Prolog.compare(varX, term) == 0) { // identical Prolog variables?
return (Term) vars_to_Vars.get(varX); // return the associated JPL Variable
}
}
// otherwise, the Prolog variable in term has not been seen before
Variable Var = new Variable(); // allocate a new (sequentially named) Variable to represent it
Var.term_ = term; // this should become redundant...
vars_to_Vars.put(term, Var); // use Hashtable(var,null), but only need set(var)
return Var;
case Prolog.ATOM: // return Atom.getTerm(vars_to_Vars, term);
hString = new StringHolder();
Prolog.get_atom_chars(term, hString); // ignore return val; assume success...
return new Atom(hString.value);
case Prolog.STRING: // return Atom.getString(vars_to_Vars, term);
hString = new StringHolder();
Prolog.get_string_chars(term, hString); // ignore return val; assume success...
return new Atom(hString.value);
case Prolog.INTEGER: // return Integer.getTerm(vars_to_Vars, term);
hInt64 = new Int64Holder();
Prolog.get_integer(term, hInt64); // assume it succeeds...
return new jpl.Integer(hInt64.value);
case Prolog.FLOAT: // return Float.getTerm(vars_to_Vars, term);
DoubleHolder hFloatValue = new DoubleHolder();
Prolog.get_float(term, hFloatValue); // assume it succeeds...
return new jpl.Float(hFloatValue.value);
case Prolog.COMPOUND: // return Compound.getTerm(vars_to_Vars, term);
hString = new StringHolder();
hInt = new IntHolder();
Prolog.get_name_arity(term, hString, hInt); // assume it succeeds
Term args[] = new Term[hInt.value];
// term_t term1 = Prolog.new_term_refs(hArity.value);
for (int i = 1; i <= hInt.value; i++) {
term_t termi = Prolog.new_term_ref();
Prolog.get_arg(i, term, termi);
args[i - 1] = Term.getTerm(vars_to_Vars, termi);
}
return new Compound(hString.value, args);
default:
// should never happen...
throw new JPLException("Term.from_term_t: unknown term type=" + Prolog.term_type(term));
}
}
protected static Term getTerm( term_t term){
return getTerm( new Hashtable(), term);
}
//==================================================================/
// Computing Substitutions
//
@ -645,6 +743,20 @@ public abstract class Term {
return true;
}
// newJRef
/**
* This method is used (by Compound.equals) to determine the Terms in two Term arrays
* are pairwise equal, where two Terms are equal if they satisfy
* the equals predicate (defined differently in each Term subclass).
*
* @param t1 an array of Terms
* @param t2 another array of Terms
* @return true if all of the Terms in the (same-length) arrays are pairwise equal
*/
protected static Term newJRef(Object obj) {
return JPL.JNULL; // not yet implemented
}
//------------------------------------------------------------------/
// toString
/**

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: Util.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: Util.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -51,7 +51,7 @@ import java.util.Map;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
public final class Util {
//------------------------------------------------------------------/
@ -168,5 +168,114 @@ public final class Util {
return null;
}
}
//
// textParamsToTerm
/**
* Converts a Prolog source text to a corresponding JPL Term (in which each Variable has the appropriate name from the source text), replacing successive occurrences of ? in the text by the
* corresponding element of Term[] params. (New in JPL 3.0.4)
*
* Throws PrologException containing error(syntax_error(_),_) if text is invalid.
*
* @param text
* A Prolog source text denoting a term
* @return Term a JPL Term equivalent to the given source text
*/
public static Term textParamsToTerm(String text, Term[] params) {
return Util.textToTerm(text).putParams(params);
}
//
/**
* Converts an array of String to a corresponding JPL list
*
* @param a
* An array of String objects
* @return Term a JPL list corresponding to the given String array
*/
public static Term stringArrayToList(String[] a) {
Term list = new Atom("[]");
for (int i = a.length - 1; i >= 0; i--) {
list = new Compound(".", new Term[]{new Atom(a[i]), list});
}
return list;
}
//
/**
* Converts an array of int to a corresponding JPL list
*
* @param a
* An array of int values
* @return Term a JPL list corresponding to the given int array
*/
public static Term intArrayToList(int[] a) {
Term list = new Atom("[]");
for (int i = a.length - 1; i >= 0; i--) {
list = new Compound(".", new Term[]{new jpl.Integer(a[i]), list});
}
return list;
}
//
/**
* Converts an array of arrays of int to a corresponding JPL list of lists
*
* @param a
* An array of arrays of int values
* @return Term a JPL list of lists corresponding to the given int array of arrays
*/
public static Term intArrayArrayToList(int[][] a) {
Term list = new Atom("[]");
for (int i = a.length - 1; i >= 0; i--) {
list = new Compound(".", new Term[]{intArrayToList(a[i]), list});
}
return list;
}
public static int listToLength(Term t) {
int length = 0;
Term head = t;
while (head.hasFunctor(".", 2)) {
length++;
head = head.arg(2);
}
return (head.hasFunctor("[]", 0) ? length : -1);
}
/** converts a proper list to an array of terms, else throws an exception
*
* @throws JPLException
* @return an array of terms whose successive elements are the corresponding members of the list (if it is a list)
*/
public static Term[] listToTermArray(Term t) {
try {
int len = t.listLength();
Term[] ts = new Term[len];
for (int i = 0; i < len; i++) {
ts[i] = t.arg(1);
t = t.arg(2);
}
return ts;
} catch (JPLException e) {
throw new JPLException("Util.listToTermArray: term is not a proper list");
}
}
public static String[] atomListToStringArray( Term t){
int n = listToLength(t);
String[] a;
if ( n<0){
return null;
} else {
a = new String[n];
}
int i = 0;
Term head = t;
while ( head.hasFunctor(".", 2)){
Term x = head.arg(1);
if ( x.isAtom()){
a[i++]=x.name();
} else {
return null;
}
head = head.arg(2);
}
return (head.hasFunctor("[]", 0) ? a : null );
}
}

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: Variable.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: Variable.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -29,7 +29,6 @@ package jpl;
import java.util.Iterator;
import java.util.Map;
import jpl.fli.Prolog;
import jpl.fli.term_t;
@ -58,28 +57,22 @@ import jpl.fli.term_t;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
//
//----------------------------------------------------------------------/
public class Variable extends Term {
//==================================================================/
// Attributes
//==================================================================/
private static long n = 0; // the integral part of the next automatic variable name to be allocated
public final String name; // the name of this Variable
protected transient term_t term_ = null; // defined between Query.open() and Query.get2()
protected transient int index; // only used by (redundant?)
//==================================================================/
// Constructors
//==================================================================/
/**
* Create a new Variable with 'name' (which must not be null or ""),
* and may one day be constrained to comply with traditional Prolog syntax.
@ -95,24 +88,25 @@ public class Variable extends Term {
}
this.name = name;
}
//==================================================================/
// Constructors (deprecated)
//==================================================================/
/**
* Create a new Variable with new sequential name of the form "_261".
*
* @deprecated use Variable(String name) instead
*/
public Variable() {
this.name = "_" + Long.toString(n++); // e.g. _0, _1 etc.
}
//==================================================================/
// Methods (common)
//==================================================================/
/**
* The (nonexistent) args of this Variable
* @throws JPLException
*
* @return the (nonexistent) args of this Variable (never)
*/
public Term[] args() {
throw new JPLException("jpl.Variable#args(): call is improper");
}
/**
* returns the lexical name of this Variable
*
@ -121,7 +115,22 @@ public class Variable extends Term {
public final String name() {
return this.name;
}
/**
* returns the type of this subclass of Term, i.e. Prolog.VARIABLE
*
* @return the type of this subclass of Term, i.e. Prolog.VARIABLE
*/
public final int type() {
return Prolog.VARIABLE;
}
/**
* returns the typeName of this subclass of Term, i.e. "Variable"
*
* @return the typeName of this subclass of Term, i.e. "Variable"
*/
public String typeName() {
return "Variable";
}
/**
* Returns a Prolog source text representation of this Variable
*
@ -130,7 +139,6 @@ public class Variable extends Term {
public String toString() {
return this.name;
}
/**
* A Variable is equal to another if their names are the same and they are not anonymous.
*
@ -140,19 +148,9 @@ public class Variable extends Term {
public final boolean equals(Object obj) {
return obj instanceof Variable && !this.name.equals("_") && this.name.equals(((Variable) obj).name);
}
public final int type() {
return Prolog.VARIABLE;
}
public String typeName() {
return "Variable";
}
//==================================================================/
// Methods (private)
//==================================================================/
/**
* Tests the lexical validity of s as a variable's name
*
@ -179,22 +177,9 @@ public class Variable extends Term {
}
return true;
}
//==================================================================/
// Methods (deprecated)
//==================================================================/
/**
* The (nonexistent) args of this Variable
*
* @return the (nonexistent) args of this Variable
* @deprecated
*/
public Term[] args() {
return new Term[] {
};
}
/**
* Returns a debug-friendly String representation of an Atom.
*
@ -204,11 +189,9 @@ public class Variable extends Term {
public String debugString() {
return "(Variable " + toString() + ")";
}
//==================================================================/
// Converting JPL Terms to Prolog terms
//==================================================================/
/**
* To put a Variable, we must check whether a (non-anonymous) variable with the same name
* has already been put in the Term. If one has, then the corresponding Prolog variable has
@ -238,11 +221,9 @@ public class Variable extends Term {
Prolog.put_term(term, var);
}
}
//==================================================================/
// Converting Prolog terms to JPL Terms
//==================================================================/
/**
* Converts a term_t (known to refer to a Prolog variable) to a Variable.
* If the variable has already been seen (and hence converted),
@ -254,8 +235,7 @@ public class Variable extends Term {
* @param var The term_t (known to be a variable) to convert
* @return A new or reused Variable
*/
protected static Term getTerm(Map vars_to_Vars, term_t var) {
protected static Term getTerm1(Map vars_to_Vars, term_t var) {
for (Iterator i = vars_to_Vars.keySet().iterator(); i.hasNext();) {
term_t varX = (term_t) i.next(); // a previously seen Prolog variable
if (Prolog.compare(varX, var) == 0) { // identical Prolog variables?
@ -268,11 +248,9 @@ public class Variable extends Term {
vars_to_Vars.put(var, Var); // use Hashtable(var,null), but only need set(var)
return Var;
}
//==================================================================/
// Computing Substitutions
//==================================================================/
/**
* If this Variable instance is not an anonymous or (in dont-tell-me mode) a dont-tell-me variable, and its binding is not already in the varnames_to_Terms Map,
* put the result of converting the term_t to which this variable
@ -288,7 +266,6 @@ public class Variable extends Term {
varnames_to_Terms.put(this.name, Term.getTerm(vars_to_Vars, this.term_));
}
}
// whether, according to prevailing policy and theis Variable's name,
// any binding should be returned
// (yes, unless it's anonymous or we're in dont-tell-me mode and its a dont-tell-me variable)
@ -297,5 +274,4 @@ public class Variable extends Term {
// return !this.name.equals("_");
}
}
//345678901234567890123456789012346578901234567890123456789012345678901234567890

View File

@ -1,9 +1,9 @@
// $Id: Version.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// $Id: Version.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
package jpl;
class Version
{
class Version {
public final int major = 3;
public final int minor = 0;
public final int minor = 1;
public final int patch = 3;
public final String status = "alpha";
}

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: BooleanHolder.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: BooleanHolder.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -47,7 +47,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
//

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: DoubleHolder.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: DoubleHolder.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -47,7 +47,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
//

View File

@ -0,0 +1,34 @@
package jpl.fli;
//----------------------------------------------------------------------/
//Int64Holder
/**
* An Int64Holder is merely a Holder class for an int64 value.
*
* <hr><i>
* Copyright (C) 2005 Paul Singleton<p>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.<p>
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Paul Singleton <paul@jbgb.com>
* @version $Revision: 1.1 $
*/
//Implementation notes:
//
//----------------------------------------------------------------------/
public class Int64Holder
{
public long value;
}
//345678901234567890123456789012346578901234567890123456789012345678901234567890

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: IntHolder.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: IntHolder.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -47,7 +47,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
//

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: LongHolder.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: LongHolder.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -45,7 +45,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
//

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: ObjectHolder.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: ObjectHolder.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -47,7 +47,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
//

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: PointerHolder.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: PointerHolder.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -49,7 +49,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
// There could be issues in the future with signedness, since Java

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: Prolog.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: Prolog.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -26,6 +26,7 @@
//*****************************************************************************/
package jpl.fli;
//----------------------------------------------------------------------/
// Prolog
/**
@ -34,7 +35,7 @@ package jpl.fli;
* (almost) strict 1-1 correspondence with the functions in the Prolog
* FLI by the same name (except without the PL_, SQ_, etc. prefixes).<p>
*
* See the file jpl_fli_Prolog.c for the native implementations of these
* See the file jpl.c for the native (ANSI C) implementations of these
* methods. Refer to your local Prolog FLI documentations for the meanings
* of these methods, and observe the following:<p>
*
@ -74,7 +75,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
public final class Prolog {
static {
@ -127,91 +128,48 @@ public final class Prolog {
/* Creating and destroying term-refs */
public static native term_t new_term_ref();
public static native term_t new_term_refs(int n);
public static native term_t copy_term_ref(term_t from);
public static native void reset_term_refs(term_t r);
public static native term_t copy_term_ref(term_t from); // NOT USED
/* Constants */
public static native atom_t new_atom(String s);
public static native String atom_chars(atom_t a);
public static native functor_t new_functor(atom_t f, int a);
public static native atom_t functor_name(functor_t f);
public static native int functor_arity(functor_t f);
public static native void unregister_atom(atom_t a); // called from atom_t's finalize()
/* Get Java-values from Prolog terms */
public static native boolean get_atom(term_t t, atom_t a);
public static native boolean get_atom_chars(term_t t, StringHolder a);
public static native boolean get_string_chars(term_t t, StringHolder s);
public static native boolean get_integer(term_t t, IntHolder i);
public static native boolean get_pointer(term_t t, PointerHolder ptr);
public static native boolean get_integer(term_t t, Int64Holder i);
public static native boolean get_float(term_t t, DoubleHolder d);
public static native boolean get_functor(term_t t, functor_t f);
public static native boolean get_name_arity(term_t t, StringHolder name, IntHolder arity);
public static native boolean get_module(term_t t, module_t module);
public static native boolean get_arg(int index, term_t t, term_t a);
public static native boolean get_jref(term_t t, ObjectHolder obj);
public static native boolean get_jboolean(term_t t, BooleanHolder b);
public static native String object_to_tag(Object obj);
/* Verify types */
public static native int term_type(term_t t);
public static native boolean is_variable(term_t t);
public static native boolean is_atom(term_t t);
public static native boolean is_integer(term_t t);
public static native boolean is_float(term_t t);
public static native boolean is_compound(term_t t);
public static native boolean is_functor(term_t t, functor_t f);
public static native boolean is_atomic(term_t t);
public static native boolean is_number(term_t t);
/* Assign to term-references */
public static native void put_variable(term_t t);
public static native void put_atom(term_t t, atom_t a);
public static native void put_integer(term_t t, long i);
public static native void put_pointer(term_t t, PointerHolder ptr);
public static native void put_float(term_t t, double f);
public static native void put_functor(term_t t, functor_t functor);
public static native void put_term(term_t t1, term_t t2);
public static native void put_jref(term_t t, Object ref);
public static native void put_jboolean(term_t t, boolean b);
public static native void put_jvoid(term_t t);
/* ... */
public static native void cons_functor_v(term_t h, functor_t fd, term_t a0);
public static native void cons_list(term_t l, term_t h, term_t t);
// unification:
// public static native int unify(term_t t1, term_t t2);
// predicates:
public static native predicate_t pred(functor_t f, module_t m);
public static native predicate_t predicate(String name, int arity, String module);
public static native int predicate_info(predicate_t pred, atom_t name, IntHolder arity, module_t module);
// querying (general):
public static native qid_t open_query(module_t m, int flags, predicate_t pred, term_t t0);
public static native boolean next_solution(qid_t qid);
public static native void close_query(qid_t qid);
public static native void cut_query(qid_t qid);
// querying (simplified):
public static native boolean call(term_t t, module_t m);
public static native boolean call_predicate(module_t m, int debug, predicate_t pred, term_t t0);
// foreign frames:
public static native fid_t open_foreign_frame();
public static native void close_foreign_frame(fid_t cid);
public static native void discard_foreign_frame(fid_t cid);
// modules:
public static native module_t context();
public static native atom_t module_name(module_t module);
public static native module_t new_module(atom_t name);
public static native int strip_module(term_t in, module_t m, term_t out);
// not yet mapped: raise_exception()
// not yet mapped: throw()
// exceptions:
public static native term_t exception(qid_t qid);
@ -229,12 +187,51 @@ public final class Prolog {
public static native int release_pool_engine();
public static native engine_t current_engine();
public static native boolean current_engine_is_pool();
public static native int attach_engine(engine_t e);
// misc.
public static native String get_c_lib_version();
public static native int action_abort();
public static native int attach_engine(engine_t e);
public static native int pool_engine_id(engine_t e);
// not used:
// public static native void reset_term_refs(term_t r);
// public static native atom_t functor_name(functor_t f);
// public static native int functor_arity(functor_t f);
// public static native boolean get_atom(term_t t, atom_t a);
// public static native boolean get_pointer(term_t t, PointerHolder ptr);
// public static native boolean get_functor(term_t t, functor_t f);
// public static native boolean get_module(term_t t, module_t module);
// public static native boolean get_jref(term_t t, ObjectHolder obj);
// public static native boolean get_jboolean(term_t t, BooleanHolder b);
// public static native boolean get_jpl_term(term_t t, ObjectHolder obj); // withdrawn 17/Oct/2004
// public static native boolean is_variable(term_t t);
// public static native boolean is_atom(term_t t);
// public static native boolean is_integer(term_t t);
// public static native boolean is_float(term_t t);
// public static native boolean is_compound(term_t t);
// public static native boolean is_functor(term_t t, functor_t f);
// public static native boolean is_atomic(term_t t);
// public static native boolean is_number(term_t t);
// public static native void put_atom(term_t t, atom_t a);
// public static native void put_pointer(term_t t, PointerHolder ptr);
// public static native void put_functor(term_t t, functor_t functor);
// public static native void put_jboolean(term_t t, boolean b);
// public static native void put_jvoid(term_t t);
// public static native void cons_list(term_t l, term_t h, term_t t);
// public static native int unify(term_t t1, term_t t2);
// public static native predicate_t pred(functor_t f, module_t m);
// public static native int predicate_info(predicate_t pred, atom_t name, IntHolder arity, module_t module);
// public static native void cut_query(qid_t qid);
// public static native boolean call(term_t t, module_t m);
// public static native boolean call_predicate(module_t m, int debug, predicate_t pred, term_t t0);
// public static native fid_t open_foreign_frame(); // NOT USED
// public static native void close_foreign_frame(fid_t cid); // NOT USED
// public static native void discard_foreign_frame(fid_t cid); // NOT USED
// public static native module_t context();
// public static native atom_t module_name(module_t module);
// public static native int strip_module(term_t in, module_t m, term_t out);
// public static native int pool_engine_id(engine_t e);
}
//345678901234567890123456789012346578901234567890123456789012345678901234567890

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: StringHolder.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: StringHolder.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -47,7 +47,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
//

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: atom_t.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: atom_t.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -48,7 +48,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
//

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: engine_t.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: engine_t.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -45,7 +45,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes: Note that a engine_t is not a term,
// consistent with the treatment in the Prolog FLI.

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: fid_t.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: fid_t.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -47,7 +47,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
//

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: functor_t.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: functor_t.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -48,7 +48,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes: Note that a functor_t is not a term,
// consistent with the treatment in the Prolog FLI.

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: module_t.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: module_t.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -48,7 +48,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
//

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: predicate_t.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: predicate_t.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -48,7 +48,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
//

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: qid_t.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: qid_t.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -47,7 +47,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
//

View File

@ -2,8 +2,8 @@
//*****************************************************************************/
// Project: jpl
//
// File: $Id: term_t.java,v 1.1 2004-08-27 20:27:56 vsc Exp $
// Date: $Date: 2004-08-27 20:27:56 $
// File: $Id: term_t.java,v 1.2 2007-09-27 15:25:32 vsc Exp $
// Date: $Date: 2007-09-27 15:25:32 $
// Author: Fred Dushin <fadushin@syr.edu>
//
//
@ -50,7 +50,7 @@ package jpl.fli;
* GNU Library Public License for more details.<p>
* </i><hr>
* @author Fred Dushin <fadushin@syr.edu>
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
// Implementation notes:
//

View File

@ -0,0 +1,78 @@
package jpl.test;
/**
* CelsiusConverter.java is a 1.4 application that
* demonstrates the use of JButton, JTextField and
* JLabel. It requires no other files.
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CelsiusConverter implements ActionListener {
JFrame converterFrame;
JPanel converterPanel;
JTextField tempCelsius;
JLabel celsiusLabel, fahrenheitLabel;
JButton convertTemp;
public CelsiusConverter() { // initially locate the window at top-left of desktop
this(0, 0);
}
public CelsiusConverter(int left, int top) { // initially locate the window at top-left of desktop
// create and set up the window
converterFrame = new JFrame("Convert Celsius to Fahrenheit");
converterFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
converterFrame.setSize(new Dimension(120, 40));
converterFrame.setLocation(left, top);
// create and set up the panel
converterPanel = new JPanel(new GridLayout(2, 2));
// create widgets
tempCelsius = new JTextField(2);
celsiusLabel = new JLabel("Celsius", SwingConstants.LEFT);
celsiusLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
//
convertTemp = new JButton("Convert");
fahrenheitLabel = new JLabel("Fahrenheit", SwingConstants.LEFT);
// listen to events from the Convert button
convertTemp.addActionListener(this);
// add the widgets to the container
converterPanel.add(tempCelsius);
converterPanel.add(celsiusLabel);
converterPanel.add(convertTemp);
converterPanel.add(fahrenheitLabel);
fahrenheitLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
converterFrame.getRootPane().setDefaultButton(convertTemp); // make "convert" the window's default button
// add the panel to the window
converterFrame.getContentPane().add(converterPanel, BorderLayout.CENTER);
// display the window
converterFrame.pack();
converterFrame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
// parse degrees Celsius as a double
double tC = (Double.parseDouble(tempCelsius.getText()));
//
// convert to Fahrenheit (in Java)
// int tempFahr = (int) (tC * 1.8 + 32);
//
// convert to Fahrenheit (in Prolog, via JPL)
int tempFahr = ((jpl.Float) jpl.Query.oneSolution("TF is ? * 1.8 + 32", new jpl.Term[] {new jpl.Float(tC)}).get("TF")).intValue();
//
// display the result
fahrenheitLabel.setText(tempFahr + " Fahrenheit");
}
public static void spawnGUI(final int left, final int top) {
// schedule a job for the event-dispatching thread: create and show an instance of this application at (left,top)
javax.swing.SwingUtilities.invokeLater(new Runnable() {
int x = left;
int y = top;
public void run() {
new CelsiusConverter(x, y); // can we be sure this won't be garbage collected?
}
});
}
public static void main(String[] args) {
// just for fun, we ask Prolog to start five instances of this class (at stepped offsets from top-left of display)
jpl.Query.allSolutions("between(1, 5, N), X is 10*N, Y is 20*N, jpl_call('jpl.test.CelsiusConverter', spawnGUI, [X,Y], _)");
}
}

View File

@ -0,0 +1,96 @@
package jpl.test;
import jpl.Atom;
import jpl.Query;
import jpl.Term;
import jpl.Variable;
public class Family extends Thread {
int id; // client thread id
private static final int delay = 0;
Family(int i) {
this.id = i;
}
public static void main(String argv[]) {
Query q1 = new Query("consult", new Term[] { new Atom("jpl/test/family.pl")});
System.err.println("consult " + (q1.hasSolution() ? "succeeded" : "failed"));
for (int i = 0; i < 20; i++) {
System.out.println("spawning client[" + i + "]");
new Family(i).start();
}
}
public void run() {
java.util.Hashtable solution;
Variable X = new Variable("X");
//--------------------------------------------------
Query q2 = new Query("child_of", new Term[] { new Atom("joe"), new Atom("ralf")});
System.err.println("child_of(joe,ralf) is " + (q2.hasSolution() ? "provable" : "not provable"));
new Query("sleep", new Term[] { new jpl.Integer(delay)}).hasSolution();
//--------------------------------------------------
Query q3 = new Query("descendent_of", new Term[] { new Atom("steve"), new Atom("ralf")});
System.err.println("descendent_of(steve,ralf) is " + (q3.hasSolution() ? "provable" : "not provable"));
new Query("sleep", new Term[] { new jpl.Integer(delay)}).hasSolution();
//--------------------------------------------------
Query q4 = new Query("descendent_of", new Term[] { X, new Atom("ralf")});
solution = q4.oneSolution();
System.err.println("first solution of descendent_of(X, ralf)");
System.err.println("X = " + solution.get(X.name));
new Query("sleep", new Term[] { new jpl.Integer(delay)}).hasSolution();
//--------------------------------------------------
java.util.Hashtable[] solutions = q4.allSolutions();
System.err.println("all solutions of descendent_of(X, ralf)");
for (int i = 0; i < solutions.length; i++) {
System.err.println("X = " + solutions[i].get(X.name));
}
new Query("sleep", new Term[] { new jpl.Integer(delay)}).hasSolution();
//--------------------------------------------------
System.err.println("each solution of descendent_of(X, ralf)");
while (q4.hasMoreSolutions()) {
solution = q4.nextSolution();
System.err.println("X = " + solution.get(X.name));
}
new Query("sleep", new Term[] { new jpl.Integer(delay)}).hasSolution();
//--------------------------------------------------
Variable Y = new Variable("Y");
Query q5 = new Query("descendent_of", new Term[] { X, Y });
System.err.println(id + ": each solution of descendent_of(X, Y)");
while (q5.hasMoreSolutions()) {
solution = q5.nextSolution();
System.err.println(id + ": X = " + solution.get(X.name) + ", Y = " + solution.get(Y.name));
new Query("sleep", new Term[] { new jpl.Integer(delay)}).hasSolution();
}
}
}

View File

@ -0,0 +1,18 @@
package jpl.test;
import jpl.Query;
import jpl.Term;
public class FetchBigTree {
public static void main(String[] args) {
// Prolog.set_default_init_args(new String[] { "libpl.dll", "-f", "D:/pcm/bin/pcm.ini", "-g", "pcm_2000" });
(new Query("consult('jpl/test/test.pl')")).oneSolution();
Term t = (Term)((new Query("p(18,T)")).oneSolution().get("T"));
int i = 1;
while ( t.hasFunctor("a", 2)){
t = t.arg(2);
i = i+1;
}
System.err.println("got a tree of " + i+" generations");
}
}

View File

@ -0,0 +1,17 @@
package jpl.test;
import jpl.Query;
import jpl.Term;
public class FetchLongList {
public static void main(String[] args) {
// Prolog.set_default_init_args(new String[] { "libpl.dll", "-f", "D:/pcm/bin/pcm.ini", "-g", "pcm_2000" });
Term t = (Term)((new Query("findall(foo(N,bar),between(1,2308,N),L)")).oneSolution().get("L"));
int i = 0;
while ( t.hasFunctor(".", 2)){
t = t.arg(2);
i = i+1;
}
System.err.println("got a list of " + i+" members");
}
}

View File

@ -0,0 +1,23 @@
package jpl.test;
import jpl.Query;
public class Ga {
public static void main(String argv[]) {
// Prolog.set_default_init_args(new String[] { "libpl.dll", "-f", "D:/pcm/bin/pcm.ini", "-g", "pcm_2000" });
// (new Query("loadall(jpl_test:jr)")).hasSolution();
// System.err.println("jr " + ((new Query("jr")).hasSolution() ? "succeeded" : "failed"));
// System.err.println( "something " + (new Query("statistics(atoms,X)")).oneSolution().get("X"));
// Query.hasSolution("statistics");
// (new Query("x")).hasSolution();
// (new Query("statistics,x")).hasSolution();
// (new Query(new Atom("statistics"))).hasSolution();
// Query.hasSolution("write(hello),nl");
// Query.hasSolution("write(hello),nl");
// (new Query("nl")).hasSolution();
(new Query("nl,nl")).hasSolution();
// (new Query("user:nl")).hasSolution();
}
}

View File

@ -0,0 +1,10 @@
package jpl.test;
import jpl.Query;
public class Ga2 {
public static void main(String argv[]) {
// Prolog.set_default_init_args(new String[] { "libpl.dll", "-f", "D:/pcm/bin/pcm.ini", "-g", "pcm_2000" });
(new Query("current_prolog_flag(K,V),write(K-V),nl,fail")).oneSolution();
}
}

View File

@ -0,0 +1,19 @@
package jpl.test;
public class Garbo {
public static int created = 0;
public static int destroyed = 0;
//
public final int i;
public Garbo( ) {
this.i = created++;
}
protected void finalize() throws Throwable {
try {
destroyed++;
// System.out.println("gced["+i+"]");
} finally {
super.finalize();
}
}
}

View File

@ -0,0 +1,93 @@
/*
* JPLTest.java
* JUnit based test
*
* Created on 13 February 2006, 11:31
*/
package jpl.test;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import junit.framework.*;
import jpl.*;
/**
*
* @author rick
*/
public class JPLTest extends TestCase {
// private static final Logger logger = Logger.getLogger(JPLTest.class.getName());
private CountDownLatch latch;
public JPLTest(String testName) {
super(testName);
}
protected void setUp() throws Exception {
/*
* Prolog file can be an empty file. The JVM seems to crash with a
* SIGSEGV if you don't consult a file prior to interacting with JPL.
final String prologFile = "jpl/test/test.pl"; // was "/home/rick/temp/test.pl";
System.out.println("prolog file is: " + prologFile);
String qString = "consult('" + prologFile + "')";
System.out.println("about to: " + qString);
Query query = new Query(qString);
System.out.println("Generated Query: " + query);
if (!query.hasSolution()) {
System.out.println(qString + " failed");
fail("Failed to consult prolog file.");
}
(new Query("true")).hasSolution();
*/
}
public void testThreadedAdds() {
latch = new CountDownLatch(4);
final AddWithThreads[] addTasks = { new AddWithThreads("a", latch), new AddWithThreads("b", latch), new AddWithThreads("c", latch), new AddWithThreads("d", latch) };
// System.out.println("Starting threads...");
for (int i = 0; i < addTasks.length; i++) {
addTasks[i].start();
}
try {
// System.out.println("Latch is waiting");
assertTrue("Timed out waiting for action to execute", latch.await(20, TimeUnit.SECONDS));
// System.out.println("Latch has been flipped");
} catch (final InterruptedException e) {
fail("Waiting thread was interrupted: " + e);
}
for (int i = 0; i < AddWithThreads.REPS; i++) {
for (int j = 0; j < addTasks.length; j++) {
Query query = new Query(addTasks[j].getNamespace() + "(test('" + i + "'))");
// System.out.println("query: " + query);
boolean ret = query.hasMoreElements();
query.close();
}
}
}
}
class AddWithThreads extends Thread {
private final CountDownLatch latch;
private final String namespace;
private static final Logger logger = Logger.getLogger(JPLTest.class.getName());
public static final int REPS = 2000; // was 200
public AddWithThreads(final String namespace, final CountDownLatch latch) {
this.latch = latch;
this.namespace = namespace;
setName("namespace" + namespace); //set thread name for debugging
}
public String getNamespace() {
return namespace;
}
public void run() {
for (int i = 0; i < REPS; i++) {
// System.out.println("Asserting test('" + i + "')");
Query queryA = new Query("assert(" + namespace + "(test('" + i + "')))");
Thread.yield();
// System.out.println("adding query: " + queryA);
boolean retA = queryA.hasMoreElements();
queryA.close();
}
latch.countDown();
}
}

View File

@ -0,0 +1,42 @@
package jpl.test;
import jpl.Query;
import jpl.fli.Prolog;
public class Masstest extends Thread {
public static void main(String[] args) {
// String[] dia = Prolog.get_default_init_args();
// String s = "default init args: ";
// for (int i = 0; i < dia.length; i++) {
// s += " " + dia[i];
// }
// System.out.println(s);
//
// Prolog.set_default_init_args(new String[] { "libpl.dll", "-f", "none", "-g", "true", "-q" });
// empirically, needs this at least:
// Prolog.set_default_init_args(new String[] { "libpl.dll" });
// Prolog.set_default_init_args(new String[] { "pl" });
//
// (new Query("assert(diagnose_declaration(_,_,_,[not,a,real,error]))")).hasSolution();
//
int STUDENTSNUMBER = 5;
Masstest[] threads = new Masstest[STUDENTSNUMBER];
for (int i = 0; i < STUDENTSNUMBER; i++) {
threads[i] = new Masstest();
threads[i].start();
}
}
public void predQuery() {
String st = "diagnose_declaration(1,[(sp, 'prefix', [('arg1', '+', 'list', 'Liste1'), ('arg2', '+', 'list', 'Liste2')])], DecMap, ErrorList)";
Query stQuery = new Query(st);
String errString = stQuery.oneSolution().get("ErrorList").toString();
System.out.println("errString=" + errString);
}
public void run() {
try {
predQuery();
} catch (Exception e) {
System.err.println("ERROR: " + e);
}
}
}

View File

@ -0,0 +1,4 @@
package jpl.test;
public class MaxObjects {
}

View File

@ -0,0 +1,13 @@
/*
* Created on 22-Nov-2004
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package jpl.test;
public class ShadowA {
public int shadow = -1;
public static int fieldStaticInt;
}

View File

@ -0,0 +1,16 @@
/*
* Created on 22-Nov-2004
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package jpl.test;
public class ShadowB extends ShadowA {
public String shadow;
public ShadowB(String s) {
shadow = s;
}
public static int fieldStaticInt;
}

View File

@ -0,0 +1,10 @@
package jpl.test;
import jpl.Query;
public class SyntaxError {
public static void main(String argv[]) {
Query q = new Query("syntax)error");
System.err.println(q.hasSolution() ? "yes" : "no");
}
}

View File

@ -0,0 +1,283 @@
package jpl.test;
import jpl.Query;
import jpl.Term;
// This class contains members which support those tests which are performed from Prolog.
// See also TestJUnit
public class Test {
public Test() {
}
public Test(Term t) {
this.termFromConstructor = t;
}
public Term termFromConstructor;
//
public static boolean fieldStaticBoolean;
public static final boolean fieldStaticBoolean1 = false;
public static final boolean fieldStaticBoolean2 = true;
//
public static char fieldStaticChar;
public static final char fieldStaticChar1 = '\u0000';
public static final char fieldStaticChar2 = '\uFFFF';
//
public static byte fieldStaticByte;
public static final byte fieldStaticByte1 = -(1 << 7);
public static final byte fieldStaticByte2 = -1;
public static final byte fieldStaticByte3 = 0;
public static final byte fieldStaticByte4 = 1;
public static final byte fieldStaticByte5 = (1 << 7) - 1;
//
public static short fieldStaticShort;
public static final short fieldStaticShort1 = -(1 << 15);
public static final short fieldStaticShort2 = -(1 << 7);
public static final short fieldStaticShort3 = -1;
public static final short fieldStaticShort4 = 0;
public static final short fieldStaticShort5 = 1;
public static final short fieldStaticShort6 = (1 << 7) - 1;
public static final short fieldStaticShort7 = (1 << 15) - 1;
//
public static int fieldStaticInt;
public static final int fieldStaticInt1 = -(1 << 31);
public static final int fieldStaticInt2 = -(1 << 15);
public static final int fieldStaticInt3 = -(1 << 7);
public static final int fieldStaticInt4 = -1;
public static final int fieldStaticInt5 = 0;
public static final int fieldStaticInt6 = 1;
public static final int fieldStaticInt7 = (1 << 7) - 1;
public static final int fieldStaticInt8 = (1 << 15) - 1;
public static final int fieldStaticInt9 = (1 << 31) - 1;
//
public static long fieldStaticLong;
public static final long fieldStaticLong1 = -(1 << 63);
public static final long fieldStaticLong2 = -(1 << 31);
public static final long fieldStaticLong3 = -(1 << 15);
public static final long fieldStaticLong4 = -(1 << 7);
public static final long fieldStaticLong5 = -1;
public static final long fieldStaticLong6 = 0;
public static final long fieldStaticLong7 = 1;
public static final long fieldStaticLong8 = (1 << 7) - 1;
public static final long fieldStaticLong9 = (1 << 15) - 1;
public static final long fieldStaticLong10 = (1 << 31) - 1;
public static final long fieldStaticLong11 = (1 << 63) - 1;
//
public static float fieldStaticFloat;
public static final float fieldStaticFloat1 = 12345.6789F;
public static final float fieldStaticFloat2 = 3.4e+38F; // nearly MAX_VALUE
public static final float fieldStaticFloat3 = 1.4e-45F; // nearly MIN_VALUE
public static final float fieldStaticFloat4 = 0.0F;
public static final float fieldStaticFloat5 = java.lang.Float.MIN_VALUE;
public static final float fieldStaticFloat6 = java.lang.Float.MAX_VALUE;
public static final float fieldStaticFloat7 = java.lang.Float.NEGATIVE_INFINITY;
public static final float fieldStaticFloat8 = java.lang.Float.POSITIVE_INFINITY;
public static final float fieldStaticFloat9 = java.lang.Float.NaN;
//
public static double fieldStaticDouble;
public static final double fieldStaticDouble1 = 12345.6789D;
public static final double fieldStaticDouble2 = 2.3456789e+100D;
public static final double fieldStaticDouble3 = 3.456789e-100D;
public static final double fieldStaticDouble4 = 0.0D;
public static final double fieldStaticDouble5 = Double.MIN_VALUE;
public static final double fieldStaticDouble6 = Double.MAX_VALUE;
public static final double fieldStaticDouble7 = Double.NEGATIVE_INFINITY;
public static final double fieldStaticDouble8 = Double.POSITIVE_INFINITY;
public static final double fieldStaticDouble9 = Double.NaN;
//
public static Object[] fieldStaticObjectArray; // can assign e.g. String[]
public static long[] fieldStaticLongArray; // cannot assign e.g. int[]
//
public static long fac(long n) { // complements jpl:jpl_test_fac(+integer,-integer)
if (n == 1) {
return 1;
} else if (n > 1) {
// return n * ((Integer) new Query(new Compound("jpl_test_fac", new Term[] { new Integer(n - 1), new Variable("F") })).oneSolution().get("F")).intValue();
return n * ((jpl.Integer) Query.oneSolution("jpl_test_fac(?,F)", new Term[] {new jpl.Integer(n-1)}).get("F")).longValue();
} else {
return 0;
}
}
static void packageMethod() { // not callable via JPL
return;
}
public static void publicMethod() {
return;
}
protected static void protectedMethod() { // not callable via JPL
return;
}
private static void privateMethod() { // not callable via JPL
return;
}
public boolean fieldInstanceBoolean;
public final boolean fieldInstanceBoolean1 = false;
public final boolean fieldInstanceBoolean2 = true;
public byte fieldInstanceByte;
public final byte fieldInstanceByte1 = -(1 << 7);
public final byte fieldInstanceByte2 = -1;
public final byte fieldInstanceByte3 = 0;
public final byte fieldInstanceByte4 = 1;
public final byte fieldInstanceByte5 = (1 << 7) - 1;
public char fieldInstanceChar;
public final char fieldInstanceChar1 = '\u0000';
public final char fieldInstanceChar2 = '\uFFFF';
public double fieldInstanceDouble;
public final double fieldInstanceDouble1 = 12345.6789D;
public final double fieldInstanceDouble2 = 2.3456789e+100D;
public final double fieldInstanceDouble3 = 3.456789e-100D;
public final double fieldInstanceDouble4 = 0.0D;
public final double fieldInstanceDouble5 = Double.MIN_VALUE;
public final double fieldInstanceDouble6 = Double.MAX_VALUE;
public final double fieldInstanceDouble7 = Double.NEGATIVE_INFINITY;
public final double fieldInstanceDouble8 = Double.POSITIVE_INFINITY;
public final double fieldInstanceDouble9 = Double.NaN;
public float fieldInstanceFloat;
public final float fieldInstanceFloat1 = 12345.6789F;
public final float fieldInstanceFloat2 = 3.4e+38F;
public final float fieldInstanceFloat3 = 1.4e-45F;
public final float fieldInstanceFloat4 = 0.0F;
public final float fieldInstanceFloat5 = java.lang.Float.MIN_VALUE;
public final float fieldInstanceFloat6 = java.lang.Float.MAX_VALUE;
public final float fieldInstanceFloat7 = java.lang.Float.NEGATIVE_INFINITY;
public final float fieldInstanceFloat8 = java.lang.Float.POSITIVE_INFINITY;
public final float fieldInstanceFloat9 = java.lang.Float.NaN;
public int fieldInstanceInt;
public final int fieldInstanceInt1 = -(1 << 31);
public final int fieldInstanceInt2 = -(1 << 15);
public final int fieldInstanceInt3 = -(1 << 7);
public final int fieldInstanceInt4 = -1;
public final int fieldInstanceInt5 = 0;
public final int fieldInstanceInt6 = 1;
public final int fieldInstanceInt7 = (1 << 7) - 1;
public final int fieldInstanceInt8 = (1 << 15) - 1;
public final int fieldInstanceInt9 = (1 << 31) - 1;
public long fieldInstanceLong;
public final long fieldInstanceLong1 = -(1 << 63);
public final long fieldInstanceLong10 = (1 << 31) - 1;
public final long fieldInstanceLong11 = (1 << 63) - 1;
public final long fieldInstanceLong2 = -(1 << 31);
public final long fieldInstanceLong3 = -(1 << 15);
public final long fieldInstanceLong4 = -(1 << 7);
public final long fieldInstanceLong5 = -1;
public final long fieldInstanceLong6 = 0;
public final long fieldInstanceLong7 = 1;
public final long fieldInstanceLong8 = (1 << 7) - 1;
public final long fieldInstanceLong9 = (1 << 15) - 1;
public short fieldInstanceShort;
public final short fieldInstanceShort1 = -(1 << 15);
public final short fieldInstanceShort2 = -(1 << 7);
public final short fieldInstanceShort3 = -1;
public final short fieldInstanceShort4 = 0;
public final short fieldInstanceShort5 = 1;
public final short fieldInstanceShort6 = (1 << 7) - 1;
public final short fieldInstanceShort7 = (1 << 15) - 1;
//
public Term term; // obsolete
public static Term staticTerm;
public Term instanceTerm;
//
// for testing accessibility of non-public fields:
static boolean fieldPackageStaticBoolean;
protected static boolean fieldProtectedStaticBoolean;
private static boolean fieldPrivateStaticBoolean;
//
// for testing update of final field:
public static final int fieldStaticFinalInt = 7;
//
// for testing passing general terms in from Prolog:
public static Term fieldStaticTerm;
public Term fieldInstanceTerm;
public static boolean methodStaticTerm(Term t) {
return t != null;
}
public boolean methodInstanceTerm(Term t) {
return t != null;
}
public static Term methodStaticEchoTerm(Term t) {
return t;
}
public static boolean methodStaticEchoBoolean(boolean v) {
return v;
}
public static char methodStaticEchoChar(char v) {
return v;
}
public static byte methodStaticEchoByte(byte v) {
return v;
}
public static short methodStaticEchoShort(short v) {
return v;
}
public static int methodStaticEchoInt(int v) {
return v;
}
public static long methodStaticEchoLong(long v) {
return v;
}
public static float methodStaticEchoFloat(float v) {
return v;
}
public static double methodStaticEchoDouble(double v) {
return v;
}
public Term methodInstanceTermEcho(Term t) {
return t;
}
public static boolean methodStaticTermIsJNull(Term t) {
return t.hasFunctor("@", 1) && t.arg(1).hasFunctor("null", 0);
}
public boolean methodInstanceTermIsJNull(Term t) {
return t.hasFunctor("@", 1) && t.arg(1).hasFunctor("null", 0);
}
public static void hello() {
System.out.println("hello");
}
public static boolean[] newArrayBooleanFromValue(boolean v) {
boolean[] a = new boolean[1];
a[0] = v;
return a;
}
public static byte[] newArrayByteFromValue(byte v) {
byte[] a = new byte[1];
a[0] = v;
return a;
}
public static char[] newArrayCharFromValue(char v) {
char[] a = new char[1];
a[0] = v;
return a;
}
public static short[] newArrayShortFromValue(short v) {
short[] a = new short[1];
a[0] = v;
return a;
}
public static int[] newArrayIntFromValue(int v) {
int[] a = new int[1];
a[0] = v;
return a;
}
public static long[] newArrayLongFromValue(long v) {
long[] a = new long[1];
a[0] = v;
return a;
}
public static float[] newArrayFloatFromValue(float v) {
float[] a = new float[1];
a[0] = v;
return a;
}
public static double[] newArrayDoubleFromValue(double v) {
double[] a = new double[1];
a[0] = v;
return a;
}
public static String methodStaticArray(long[] a) {
return "long[]";
}
public static String methodStaticArray(int[] a) {
return "int[]";
}
public static String methodStaticArray(short[] a) {
return "short[]";
}
}

View File

@ -0,0 +1,532 @@
// Created on 25-Jul-2004
package jpl.test;
import java.util.Map;
import jpl.Atom;
import jpl.Compound;
import jpl.Integer;
import jpl.JPL;
import jpl.JRef;
import jpl.PrologException;
import jpl.Query;
import jpl.Term;
import jpl.Util;
import jpl.Variable;
import jpl.fli.Prolog;
import junit.framework.TestCase;
import junit.framework.TestSuite;
// This class defines all the tests which are run from Java.
// It needs junit.framework.TestCase and junit.framework.TestSuite, which are not supplied with JPL.
public class TestJUnit extends TestCase {
//
public static long fac(long n) { // complements jpl:jpl_test_fac(+integer,-integer)
if (n == 1) {
return 1;
} else if (n > 1) {
return n * ((jpl.Integer) Query.oneSolution("jpl_test_fac(?,F)", new Term[] { new jpl.Integer(n - 1) }).get("F")).longValue();
} else {
return 0;
}
}
public TestJUnit(String name) {
super(name);
}
public static junit.framework.Test suite() {
return new TestSuite(TestJUnit.class);
}
public static void main(String args[]) {
junit.textui.TestRunner.run(suite());
}
protected void setUp() {
// initialization code
// Prolog.set_default_init_args(new String[] { "libpl.dll", "-f", "none", "-g", "set_prolog_flag(debug_on_error,false)", "-q" });
Prolog.set_default_init_args(new String[] { "libpl.dll", "-f", "none", "-g", "true", "-q" });
assertTrue((new Query("consult(test_jpl)")).hasSolution());
}
protected void tearDown() {
// cleanup code
}
//
public void testMasstest() {
assertTrue((new Query("assert(diagnose_declaration(_,_,_,[not,a,real,error]))")).hasSolution());
}
public void testSameLibVersions1() {
String java_lib_version = JPL.version_string();
String c_lib_version = jpl.fli.Prolog.get_c_lib_version();
assertTrue("java_lib_version(" + java_lib_version + ") is same as c_lib_version(" + c_lib_version + ")", java_lib_version.equals(c_lib_version));
}
public void testSameLibVersions2() {
String java_lib_version = JPL.version_string();
String pl_lib_version = ((Term) (new Query(new Compound("jpl_pl_lib_version", new Term[] { new Variable("V") })).oneSolution().get("V"))).name();
assertTrue("java_lib_version(" + java_lib_version + ") is same as pl_lib_version(" + pl_lib_version + ")", java_lib_version.equals(pl_lib_version));
}
public void testAtomName1() {
String name = "fred";
Atom a = new Atom(name);
assertEquals("an Atom's name is that with which it was created", a.name(), name);
}
public void testAtomName2() {
String name = "ha ha";
Atom a = new Atom(name);
assertEquals("an Atom's name is that with which it was created", a.name(), name);
}
public void testAtomName3() {
String name = "3";
Atom a = new Atom(name);
assertEquals("an Atom's name is that with which it was created", a.name(), name);
}
public void testAtomToString1() {
String name = "fred";
String toString = "fred";
Atom a = new Atom(name);
assertEquals("an Atom's .toString() value is quoted iff appropriate", a.toString(), toString);
}
public void testAtomToString2() {
String name = "ha ha";
String toString = "'ha ha'";
Atom a = new Atom(name);
assertEquals("an Atom's .toString() value is quoted iff appropriate", a.toString(), toString);
}
public void testAtomToString3() {
String name = "3";
String toString = "'3'";
Atom a = new Atom(name);
assertEquals("an Atom's .toString() value is quoted iff appropriate", a.toString(), toString);
}
public void testAtomArity() {
Atom a = new Atom("willy");
assertEquals("an Atom has arity zero", a.arity(), 0);
}
public void testAtomEquality1() {
String name = "fred";
Atom a1 = new Atom(name);
Atom a2 = new Atom(name);
assertEquals("two Atoms created with the same name are equal", a1, a2);
}
public void testAtomIdentity() { // how could this fail?!
String name = "fred";
Atom a1 = new Atom(name);
Atom a2 = new Atom(name);
assertNotSame("two Atoms created with the same name are not identical", a1, a2);
}
public void testAtomHasFunctorNameZero() {
String name = "sam";
Atom a = new Atom(name);
assertTrue(a.hasFunctor(name, 0));
}
public void testAtomHasFunctorWrongName() {
assertFalse("an Atom does not have a functor whose name is other than that with which the Atom was created", new Atom("wally").hasFunctor("poo", 0));
}
public void testAtomHasFunctorWrongArity() {
String name = "ted";
assertFalse("an Atom does not have a functor whose arity is other than zero", new Atom(name).hasFunctor(name, 1));
}
public void testVariableBinding1() {
Term lhs = new Compound("p", new Term[] { new Variable("X"), new Variable("Y") });
Term rhs = new Compound("p", new Term[] { new Atom("a"), new Atom("b") });
Term goal = new Compound("=", new Term[] { lhs, rhs });
Map soln = new Query(goal).oneSolution();
assertTrue("two variables with different names can bind to distinct atoms", soln != null && ((Term) soln.get("X")).name().equals("a") && ((Term) soln.get("Y")).name().equals("b"));
}
public void testVariableBinding2() {
Term lhs = new Compound("p", new Term[] { new Variable("X"), new Variable("X") });
Term rhs = new Compound("p", new Term[] { new Atom("a"), new Atom("b") });
Term goal = new Compound("=", new Term[] { lhs, rhs });
assertFalse("two distinct Variables with same name cannot unify with distinct atoms", new Query(goal).hasSolution());
}
public void testVariableBinding3() {
Variable X = new Variable("X");
Term lhs = new Compound("p", new Term[] { X, X });
Term rhs = new Compound("p", new Term[] { new Atom("a"), new Atom("b") });
Term goal = new Compound("=", new Term[] { lhs, rhs });
assertFalse("two occurrences of same named Variable cannot unify with distinct atoms", new Query(goal).hasSolution());
}
public void testVariableBinding4() {
Term lhs = new Compound("p", new Term[] { new Variable("_"), new Variable("_") });
Term rhs = new Compound("p", new Term[] { new Atom("a"), new Atom("b") });
Term goal = new Compound("=", new Term[] { lhs, rhs });
assertTrue("two distinct anonymous Variables can unify with distinct atoms", new Query(goal).hasSolution());
}
public void testVariableBinding5() {
Variable Anon = new Variable("_");
Term lhs = new Compound("p", new Term[] { Anon, Anon });
Term rhs = new Compound("p", new Term[] { new Atom("a"), new Atom("b") });
Term goal = new Compound("=", new Term[] { lhs, rhs });
assertTrue("two occurrences of same anonymous Variable can unify with distinct atoms", new Query(goal).hasSolution());
}
public void testAtomEquality2() {
Atom a = new Atom("a");
assertTrue("two occurrences of same Atom are equal by .equals()", a.equals(a));
}
public void testAtomEquality3() {
assertTrue("two distinct Atoms with same names are equal by .equals()", (new Atom("a")).equals(new Atom("a")));
}
public void testTextToTerm1() {
String text = "fred(B,p(A),[A,B,C])";
Term t = Util.textToTerm(text);
assertTrue("Util.textToTerm() converts \"fred(B,p(A),[A,B,C])\" to a corresponding Term", t.hasFunctor("fred", 3) && t.arg(1).isVariable() && t.arg(1).name().equals("B")
&& t.arg(2).hasFunctor("p", 1) && t.arg(2).arg(1).isVariable() && t.arg(2).arg(1).name().equals("A"));
}
public void testArrayToList1() {
Term l2 = Util.termArrayToList(new Term[] { new Atom("a"), new Atom("b"), new Atom("c"), new Atom("d"), new Atom("e") });
Query q9 = new Query(new Compound("append", new Term[] { new Variable("Xs"), new Variable("Ys"), l2 }));
assertTrue("append(Xs,Ys,[a,b,c,d,e]) has 6 solutions", q9.allSolutions().length == 6);
}
public void testArrayToList2() {
String goal = "append(Xs,Ys,[a,b,c,d,e])";
assertTrue(goal + " has 6 solutions", Query.allSolutions(goal).length == 6);
}
public void testLength1() {
Query q5 = new Query(new Compound("length", new Term[] { new Variable("Zs"), new jpl.Integer(2) }));
Term zs = (Term) (q5.oneSolution().get("Zs"));
assertTrue("length(Zs,2) binds Zs to a list of two distinct variables " + zs.toString(), zs.hasFunctor(".", 2) && zs.arg(1).isVariable() && zs.arg(2).hasFunctor(".", 2)
&& zs.arg(2).arg(1).isVariable() && zs.arg(2).arg(2).hasFunctor("[]", 0) && !zs.arg(1).name().equals(zs.arg(2).arg(1).name()));
}
public void testGenerate1() { // we chickened out of verifying each solution :-)
String goal = "append(Xs,Ys,[_,_,_,_,_])";
assertTrue(goal + " has 6 solutions", Query.allSolutions(goal).length == 6);
}
public void testPrologException1() {
try {
new Query("p(]"); // writes junk to stderr and enters debugger unless flag debug_on_error = false
} catch (PrologException e) {
assertTrue("new Query(\"p(]\") throws a PrologException " + e.toString(), true);
return;
}
fail("new Query(\"p(]\") oughta throw a PrologException");
}
public void testAtom1() {
assertTrue("new Atom(\"3 3\")" + (new Atom("3 3")).toString(), true);
}
public void testTextToTerm2() {
String text1 = "fred(?,2,?)";
String text2 = "[first(x,y),A]";
Term plist = Util.textToTerm(text2);
Term[] ps = plist.toTermArray();
Term t = Util.textToTerm(text1).putParams(ps);
assertTrue("fred(?,2,?) .putParams( [first(x,y),A] )", t.hasFunctor("fred", 3) && t.arg(1).hasFunctor("first", 2) && t.arg(1).arg(1).hasFunctor("x", 0) && t.arg(1).arg(2).hasFunctor("y", 0)
&& t.arg(2).hasFunctor(2, 0) && t.arg(3).isVariable() && t.arg(3).name().equals("A"));
}
public void testDontTellMeMode1() {
final Query q = new Query("setof(_M,current_module(_M),_Ms),length(_Ms,N)");
JPL.setDTMMode(true);
assertTrue("in dont-tell-me mode, setof(_M,current_module(_M),_Ms),length(_Ms,N) returns binding for just one variable", q.oneSolution().keySet().size() == 1);
}
public void testDontTellMeMode2() {
final Query q = new Query("setof(_M,current_module(_M),_Ms),length(_Ms,N)");
JPL.setDTMMode(false);
assertTrue("not in dont-tell-me mode, setof(_M,current_module(_M),_Ms),length(_Ms,N) returns binding for three variables", q.oneSolution().keySet().size() == 3);
}
public void testModulePrefix1() {
assertTrue(Query.hasSolution("call(user:true)"));
}
private void testMutualRecursion(int n, long f) { // f is the expected result for fac(n)
try {
assertEquals("mutual recursive Java<->Prolog factorial: fac(" + n + ") = " + f, fac(n), f);
} catch (Exception e) {
fail("fac(" + n + ") threw " + e);
}
}
public void testMutualRecursion1() {
testMutualRecursion(1, 1);
}
public void testMutualRecursion2() {
testMutualRecursion(2, 2);
}
public void testMutualRecursion3() {
testMutualRecursion(3, 6);
}
public void testMutualRecursion10() {
testMutualRecursion(10, 3628800);
}
public void testIsJNull1() {
Term t = (Term) (new Query("X = @(null)")).oneSolution().get("X");
assertTrue("@(null) . isJNull() succeeds", t.isJNull());
}
public void testIsJNull2() {
Term t = (Term) (new Query("X = @(3)")).oneSolution().get("X");
assertFalse("@(3) . isJNull() fails", t.isJNull());
}
public void testIsJNull3() {
Term t = (Term) (new Query("X = _")).oneSolution().get("X");
assertFalse("_ . isJNull() fails", t.isJNull());
}
public void testIsJNull4() {
Term t = (Term) (new Query("X = @(true)")).oneSolution().get("X");
assertFalse("@(true) . isJNull() fails", t.isJNull());
}
public void testIsJNull5() {
Term t = (Term) (new Query("X = @(false)")).oneSolution().get("X");
assertFalse("@(false) . isJNull() fails", t.isJNull());
}
public void testIsJTrue1() {
Term t = (Term) (new Query("X = @(true)")).oneSolution().get("X");
assertTrue("@(true) . isJTrue() succeeds", t.isJTrue());
}
public void testIsJTrue2() {
Term t = (Term) (new Query("X = @(3)")).oneSolution().get("X");
assertFalse("@(3) . isJTrue() fails", t.isJTrue());
}
public void testIsJTrue3() {
Term t = (Term) (new Query("X = _")).oneSolution().get("X");
assertFalse("_ . isJTrue() fails", t.isJTrue());
}
public void testIsJTrue4() {
Term t = (Term) (new Query("X = @(false)")).oneSolution().get("X");
assertFalse("@(false) . isJTrue() fails", t.isJTrue());
}
public void testIsJVoid1() {
Term t = (Term) (new Query("X = @(void)")).oneSolution().get("X");
assertTrue("@(void) . isJVoid() succeeds", t.isJVoid());
}
public void testIsJVoid2() {
Term t = (Term) (new Query("X = @(3)")).oneSolution().get("X");
assertFalse("@(3) . isJVoid() fails", t.isJVoid());
}
public void testIsJVoid3() {
Term t = (Term) (new Query("X = _")).oneSolution().get("X");
assertFalse("_ . isJVoid() fails", t.isJVoid());
}
public void testTypeName1() {
assertEquals("Y = foo binds Y to an Atom", ((Term) Query.oneSolution("Y = foo").get("Y")).typeName(), "Atom");
}
public void testTypeName2() {
assertEquals("Y = 3.14159 binds Y to a Float", ((Term) Query.oneSolution("Y = 3.14159").get("Y")).typeName(), "Float");
}
public void testTypeName4() {
assertEquals("Y = 6 binds Y to an Integer", ((Term) Query.oneSolution("Y = 6").get("Y")).typeName(), "Integer");
}
public void testTypeName5() {
assertEquals("Y = _ binds Y to a Variable", ((Term) Query.oneSolution("Y = _").get("Y")).typeName(), "Variable");
}
public void testTypeName3() {
assertEquals("Y = f(x) binds Y to a Compound", ((Term) Query.oneSolution("Y = f(x)").get("Y")).typeName(), "Compound");
}
public void testGoalWithModulePrefix1() {
String goal = "jpl:jpl_modifier_bit(volatile,I)";
assertTrue(goal + " binds I to an integer", ((Term) Query.oneSolution(goal).get("I")).isInteger());
}
public void testGoalWithModulePrefix2() {
String goal = "user:length([],0)";
assertTrue(goal + " succeeds", Query.hasSolution(goal));
}
public void testGoalWithModulePrefix3() {
try {
(new Query("3:length([],0)")).hasSolution();
// shouldn't get to here
fail("(new Query(\"3:length([],0)\")).hasSolution() didn't throw exception");
} catch (jpl.PrologException e) {
// correct exception class, but is it correct in detail?
if (e.term().hasFunctor("error", 2) && e.term().arg(1).hasFunctor("type_error", 2) && e.term().arg(1).arg(1).hasFunctor("atom", 0)) {
// OK: an appropriate exception was thrown
} else {
fail("(new Query(\"3:length([],0)\")).hasSolution() threw incorrect PrologException: " + e);
}
} catch (Exception e) {
fail("(new Query(\"3:length([],0)\")).hasSolution() threw wrong class of exception: " + e);
}
}
public void testGoalWithModulePrefix4() {
try {
(new Query("_:length([],0)")).hasSolution();
// shouldn't get to here
fail("bad (unbound) module prefix");
} catch (jpl.PrologException e) {
// correct exception class, but is it correct in detail?
if (e.term().hasFunctor("error", 2) && e.term().arg(1).hasFunctor("instantiation_error", 0)) {
// OK: an appropriate exception was thrown
} else {
fail("(new Query(\"_:length([],0)\")).hasSolution() threw incorrect PrologException: " + e);
}
} catch (Exception e) {
fail("(new Query(\"_:length([],0)\")).hasSolution() threw wrong class of exception: " + e);
}
}
public void testGoalWithModulePrefix5() {
try {
(new Query("f(x):length([],0)")).hasSolution();
// shouldn't get to here
fail("bad (compound) module prefix");
} catch (jpl.PrologException e) {
// correct exception class, but is it correct in detail?
if (e.term().hasFunctor("error", 2) && e.term().arg(1).hasFunctor("type_error", 2) && e.term().arg(1).arg(1).hasFunctor("atom", 0)) {
// OK: an appropriate exception was thrown
} else {
fail("(new Query(\"f(x):length([],0)\")).hasSolution() threw incorrect PrologException: " + e);
}
} catch (Exception e) {
fail("(new Query(\"f(x):length([],0)\")).hasSolution() threw wrong class of exception: " + e);
}
}
public void testGoalWithModulePrefix6() {
try {
(new Query("no_such_module:no_such_predicate(0)")).hasSolution();
// shouldn't get to here
fail("bad (nonexistent) module prefix");
} catch (jpl.PrologException e) {
// correct exception class, but is it correct in detail?
if (e.term().hasFunctor("error", 2) && e.term().arg(1).hasFunctor("existence_error", 2) && e.term().arg(1).arg(1).hasFunctor("procedure", 0)) {
// OK: an appropriate exception was thrown
} else {
fail("(new Query(\"f(x):length([],0)\")).hasSolution() threw incorrect PrologException: " + e);
}
} catch (Exception e) {
fail("(new Query(\"f(x):length([],0)\")).hasSolution() threw wrong class of exception: " + e);
}
}
// public void testFetchCyclicTerm(){
// assertTrue((new Query("X=f(X)")).hasSolution());
// }
public void testFetchLongList0() {
assertTrue((new Query("findall(foo(N),between(0,10,N),L)")).hasSolution());
}
public void testFetchLongList1() {
assertTrue((new Query("findall(foo(N),between(0,100,N),L)")).hasSolution());
}
public void testFetchLongList2() {
assertTrue((new Query("findall(foo(N),between(0,1000,N),L)")).hasSolution());
}
public void testFetchLongList2c() {
assertTrue((new Query("findall(foo(N),between(0,1023,N),L)")).hasSolution());
}
public void testFetchLongList2a() {
assertTrue((new Query("findall(foo(N),between(0,2000,N),L)")).hasSolution());
}
// public void testFetchLongList2b() {
// assertTrue((new Query("findall(foo(N),between(0,3000,N),L)")).hasSolution());
// }
// public void testFetchLongList3() {
// assertTrue((new Query("findall(foo(N),between(0,10000,N),L)")).hasSolution());
// }
public void testUnicode0() {
assertTrue(Query.hasSolution("atom_codes(?,[32])", new Term[] { new Atom(" ") }));
}
public void testUnicode0a() {
assertTrue(Query.hasSolution("atom_codes(?,[32])", new Term[] { new Atom("\u0020") }));
}
public void testUnicode0b() {
assertTrue(Query.hasSolution("atom_codes(?,[0])", new Term[] { new Atom("\u0000") }));
}
public void testUnicode0c() {
assertTrue(Query.hasSolution("atom_codes(?,[1])", new Term[] { new Atom("\u0001") }));
}
public void testUnicode0d() {
assertTrue(Query.hasSolution("atom_codes(?,[127])", new Term[] { new Atom("\u007F") }));
}
public void testUnicode0e() {
assertTrue(Query.hasSolution("atom_codes(?,[128])", new Term[] { new Atom("\u0080") }));
}
public void testUnicode0f() {
assertTrue(Query.hasSolution("atom_codes(?,[255])", new Term[] { new Atom("\u00FF") }));
}
public void testUnicode0g() {
assertTrue(Query.hasSolution("atom_codes(?,[256])", new Term[] { new Atom("\u0100") }));
}
public void testUnicode1() {
assertTrue(Query.hasSolution("atom_codes(?,[0,127,128,255])", new Term[] { new Atom("\u0000\u007F\u0080\u00FF") }));
}
public void testUnicode2() {
assertTrue(Query.hasSolution("atom_codes(?,[256,32767,32768,65535])", new Term[] { new Atom("\u0100\u7FFF\u8000\uFFFF") }));
}
public void testStringXput1() {
Term a = (Term) (Query.oneSolution("string_concat(foo,bar,S)").get("S"));
assertTrue(a.name().equals("foobar"));
}
public void testStringXput2() {
String s1 = "\u0000\u007F\u0080\u00FF";
String s2 = "\u0100\u7FFF\u8000\uFFFF";
String s = s1 + s2;
Term a1 = new Atom(s1);
Term a2 = new Atom(s2);
Term a = (Term) (Query.oneSolution("string_concat(?,?,S)", new Term[] { a1, a2 }).get("S"));
assertEquals(a.name(), s);
}
// public void testMaxInteger1(){
// assertEquals(((Term)(Query.oneSolution("current_prolog_flag(max_integer,I)").get("I"))).longValue(), java.lang.Long.MAX_VALUE); // i.e. 9223372036854775807L
// }
// public void testSingleton1() {
// assertTrue(Query.hasSolution("style_check(-singleton),consult('test_singleton.pl')"));
// }
public void testStaticQueryInvalidSourceText2() {
String goal = "p(]";
try {
Query.hasSolution(goal);
} catch (jpl.PrologException e) {
if (e.term().hasFunctor("error", 2) && e.term().arg(1).hasFunctor("syntax_error", 1) && e.term().arg(1).arg(1).hasFunctor("cannot_start_term", 0)) {
// OK: an appropriate exception was thrown
} else {
fail("Query.hasSolution(" + goal + ") threw incorrect PrologException: " + e);
}
} catch (Exception e) {
fail("Query.hasSolution(" + goal + ") threw wrong class of exception: " + e);
}
}
public void testStaticQueryInvalidSourceText1() {
String goal = "bad goal";
try {
Query.hasSolution(goal);
} catch (jpl.PrologException e) {
if (e.term().hasFunctor("error", 2) && e.term().arg(1).hasFunctor("syntax_error", 1) && e.term().arg(1).arg(1).hasFunctor("operator_expected", 0)) {
// OK: an appropriate exception was thrown
} else {
fail("Query.hasSolution(" + goal + ") threw incorrect PrologException: " + e);
}
} catch (Exception e) {
fail("Query.hasSolution(" + goal + ") threw wrong class of exception: " + e);
}
}
public void testStaticQueryNSolutions1() {
String goal = "member(X, [0,1,2,3,4,5,6,7,8,9])";
int n = 5;
assertTrue("Query.nSolutions(" + goal + ", " + n + ") returns " + n + " solutions", Query.nSolutions(goal, n).length == n);
}
public void testStaticQueryNSolutions2() {
String goal = "member(X, [0,1,2,3,4,5,6,7,8,9])";
int n = 0;
assertTrue("Query.nSolutions(" + goal + ", " + n + ") returns " + n + " solutions", Query.nSolutions(goal, n).length == n);
}
public void testStaticQueryNSolutions3() {
String goal = "member(X, [0,1,2,3,4,5,6,7,8,9])";
int n = 20;
assertTrue("Query.nSolutions(" + goal + ", " + n + ") returns 10 solutions", Query.nSolutions(goal, n).length == 10);
}
public void testStaticQueryAllSolutions1() {
String goal = "member(X, [0,1,2,3,4,5,6,7,8,9])";
assertTrue("Query.allSolutions(" + goal + ") returns 10 solutions", Query.allSolutions(goal).length == 10);
}
public void testStaticQueryHasSolution1() {
String goal = "memberchk(13, [?,?,?])";
Term[] params = new Term[] { new Integer(12), new Integer(13), new Integer(14) };
assertTrue(Query.hasSolution(goal, params));
}
public void testStaticQueryHasSolution2() {
String goal = "memberchk(23, [?,?,?])";
Term[] params = new Term[] { new Integer(12), new Integer(13), new Integer(14) };
assertFalse(Query.hasSolution(goal, params));
}
public void testUtilListToTermArray1() {
String goal = "T = [a,b,c]";
Term list = (Term) Query.oneSolution(goal).get("T");
Term[] array = Util.listToTermArray(list);
assertTrue(array[2].isAtom() && array[2].name().equals("c"));
}
public void testTermToTermArray1() {
String goal = "T = [a,b,c]";
Term list = (Term) Query.oneSolution(goal).get("T");
Term[] array = list.toTermArray();
assertTrue(array[2].isAtom() && array[2].name().equals("c"));
}
public void testJRef1() {
// System.out.println("java.library.path=" + System.getProperties().get("java.library.path"));
// System.out.println("jpl.c version = " + jpl.fli.Prolog.get_c_lib_version());
int i = 76543;
Integer I = new Integer(i);
Query q = new Query("jpl_call(?,intValue,[],I2)", new Term[] { new JRef(I) });
Term I2 = (Term) q.oneSolution().get("I2");
assertTrue(I2.isInteger() && I2.intValue() == i);
}
public void testBerhhard1() {
assertTrue(Query.allSolutions( "consult(library('lists'))" ).length == 1);
}
}

View File

@ -0,0 +1,142 @@
package jpl.test;
import java.util.Map;
import jpl.Atom;
import jpl.Compound;
import jpl.Integer;
import jpl.JPL;
import jpl.PrologException;
import jpl.Query;
import jpl.Term;
import jpl.Util;
import jpl.Variable;
import jpl.fli.Prolog;
// This class is nearly obsolete; most of its tests have been migrated to TestJUnit.
public class TestOLD {
private static void test10() {
System.err.println("test10:");
System.err.println(" java_lib_version = " + JPL.version_string());
System.err.println(" c_lib_version = " + jpl.fli.Prolog.get_c_lib_version());
System.err.println(" pl_lib_version = " + new Query(new Compound("jpl_pl_lib_version", new Term[] { new Variable("V") })).oneSolution().get("V"));
System.err.println(" java.version = " + System.getProperty("java.version"));
System.err.println(" os.name = " + System.getProperty("os.name"));
System.err.println(" os.arch = " + System.getProperty("os.arch"));
System.err.println(" os.version = " + System.getProperty("os.version"));
System.err.println();
}
private static void test10j() {
Term l2 = Util.termArrayToList(new Term[] { new Atom("a"), new Atom("b"), new Atom("c"), new Atom("d"), new Atom("e") });
Query q9 = new Query(new Compound("append", new Term[] { new Variable("Xs"), new Variable("Ys"), l2 }));
Map[] s9s = q9.allSolutions();
System.err.println("test10j:");
for (int i = 0; i < s9s.length; i++) {
System.err.println(" append(Xs,Ys,[a,b,c,d,e]) -> " + Util.toString(s9s[i]));
}
System.err.println();
}
private static void test10k() {
String[] args = jpl.fli.Prolog.get_default_init_args();
String which;
String s = "";
System.err.println("test10k:");
if (args == null) {
args = jpl.fli.Prolog.get_actual_init_args();
which = "actual";
} else {
which = "default";
}
for (int i = 0; i < args.length; i++) {
s = s + args[i] + " ";
}
System.err.println(" " + which + "_init_args = " + s + '\n');
}
private static void test10l() {
Query q5 = new Query(new Compound("length", new Term[] { new Variable("Zs"), new jpl.Integer(5) }));
Map s5 = q5.oneSolution();
System.err.println("test10l:");
System.err.println(" length(Zs,5)");
System.err.println(" " + Util.toString(s5));
System.err.println(" Zs = " + (Term) s5.get("Zs"));
System.err.println();
}
private static void test10m() {
String text = "append(Xs,Ys,[_,_,_,_,_])";
Query q = new Query(text);
Map[] ss = q.allSolutions();
System.err.println("test10m:");
System.err.println(" all solutions of " + text);
for (int i = 0; i < ss.length; i++) {
System.err.println(" " + Util.toString(ss[i]));
}
System.err.println();
}
private static void test10o() {
System.err.println("test10o:");
Term l2b = Util.termArrayToList(new Term[] { new Variable("A"), new Variable("B"), new Variable("C"), new Variable("D"), new Variable("E") });
Query q9b = new Query(new Compound("append", new Term[] { new Variable("Xs"), new Variable("Ys"), l2b }));
Map[] s9bs = q9b.allSolutions();
for (int i = 0; i < s9bs.length; i++) {
System.err.println(" append(Xs,Ys,[A,B,C,D,E]) -> " + Util.toString(s9bs[i]));
}
System.err.println();
}
private static void test10q() {
System.err.println("test10q:");
System.err.println((new Compound("Bad Name", new Term[] { new Atom("3 3") })).toString());
System.err.println();
}
private static void test10s() {
final Query q = new Query("jpl_slow_goal"); // 10 successive sleep(1)
System.err.println("test10s:");
Thread t = new Thread(new Runnable() {
public void run() {
try {
System.err.println("q.hasSolution() ... ");
System.err.println(q.hasSolution() ? "finished" : "failed");
} catch (Exception e) {
System.err.println("q.hasSolution() threw " + e);
}
}
});
t.start(); // call the query in a separate thread
System.err.println("pausing for 2 secs...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
;
} // wait a coupla seconds for it to get started
// (new Query("set_prolog_flag(abort_with_exception, true)")).hasSolution();
System.err.println("calling q.abort()...");
q.abort();
System.err.println();
}
public static void main(String argv[]) {
Prolog.set_default_init_args(new String[] { "libpl.dll", "-f", "none", "-g", "set_prolog_flag(debug_on_error,false)", "-q" });
System.err.println("tag = " + Prolog.object_to_tag(new Query("hello")));
test10k();
test10();
// test10h();
// test10i();
test10j();
test10k();
test10l();
test10m();
// test10n();
test10o();
//test10p();
test10q();
// test10r();
// test10s();
// test10t();
// test10u();
// test10v();
String s = new String("" + '\0' + '\377');
System.err.println("s.length = " + s.length());
for (int i = 0; i < s.length(); i++) {
System.err.print((new Integer(s.charAt(i))).toString() + " ");
}
System.err.println();
System.err.println(new Query("atom_codes(A,[127,128,255,0])").oneSolution().toString());
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,41 @@
:- ensure_loaded(library(swi)).
jpl_java_home('@JAVA_HOME@').
yap.
load_jpl_lib :-
jpl_java_home(JavaHome),
fetch_arch(Arch),
gen_jvm_lib(JavaHome,Arch,JPL,JLibs),
load_foreign_files(JPL, JLibs, install), !.
fetch_arch(Arch) :-
current_prolog_flag(host_type,Name),
atom_codes(Name,Codes),
gen_arch(Codes,Arch).
gen_arch(L,mac) :-
append(_,[0'd,0'a,0'r,0'w,0'i,0'n|_],L), !.
gen_arch([0'x,0'8,0'6,0'_,0'6,0'4|_],amd64).
gen_arch([0'i,_,0'8,0'6|_],i386). % take all versions of X86
gen_arch([0's,0'p,0'a,0'r,0'c|_],sparc).
gen_arch([0'/,0'u,0's,0'r|_],mac).
gen_jvm_lib(_,mac,[jpl],[]) :- !.
gen_jvm_lib(JavaHome,Arch,[jpl], [JLib]) :-
atom_concat([JavaHome,'/jre/lib/',Arch,'/client/libjvm.so'],JLib),
exists(JLib), !.
gen_jvm_lib(JavaHome,Arch,[jpl], [JLib]) :-
atom_concat([JavaHome,'/jre/lib/',Arch,'/server/libjvm.so'],JLib),
exists(JLib), !.
gen_jvm_lib(JavaHome,Arch,[jpl], [JLib]) :-
atom_concat([JavaHome,'/jre/lib/',Arch,'/classic/libjvm.so'],JLib),
exists(JLib), !.
gen_jvm_lib(JavaHome,Arch,[jpl], [JLib]) :-
atom_concat([JavaHome,'/jre/lib/',Arch,'/libjvm.so'],JLib),
exists(JLib), !.

View File

@ -23,7 +23,7 @@ LIBDIR=$(EROOTDIR)/lib/Yap
#
#
CC=@CC@
CFLAGS= @CFLAGS@ $(YAP_EXTRAS) $(DEFS) -I$(srcdir) -I../../.. -I$(srcdir)/../../../include -I$(srcdir)/../../../library/yap2swi $(JVM_INC) -DIN_YAP=1 -DJAVA_HOME=\"$(JAVA_HOME)\"
CFLAGS= @CFLAGS@ $(YAP_EXTRAS) $(DEFS) -I$(srcdir) -I../../.. -I$(srcdir)/../../../include $(JVM_INC) -DIN_YAP=1 -DJAVA_HOME=\"$(JAVA_HOME)\"
#
#
# You shouldn't need to change what follows.
@ -45,7 +45,7 @@ SOBJS=jpl@SHLIB_SUFFIX@
all: $(SOBJS)
jpl.o: $(srcdir)/jpl.c
jpl.o: $(srcdir)/jpl.c $(srcdir)/hacks.c
$(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $(srcdir)/jpl.c -o jpl.o

73
LGPL/JPL/src/hacks.c Normal file
View File

@ -0,0 +1,73 @@
/*
%T jni_SetByteArrayElement(+term, +term, +term)
*/
static foreign_t
jni_SetByteArrayElement(
term_t ta1, // +Arg1
term_t ta2, // +Arg2
term_t ta3 // +Arg3
)
{
jboolean r; // Prolog exit/fail outcome
jbyteArray p1;
int i2;
jbyte p4;
JNIEnv *env;
atom_t a; /* " */
functor_t fn; /* temp for conversion macros */
term_t a1; /* " */
int i; /* " */
if ( !jni_ensure_jvm() )
{
return FALSE;
}
r =
JNI_term_to_byte_jarray(ta1,p1)
&& JNI_term_to_jint(ta2,i2)
&& JNI_term_to_jbyte(ta3,p4)
&& ( (*env)->SetByteArrayRegion(env,p1,(jsize)i2,1,&p4) , TRUE );
return jni_check_exception(env) && r;
}
/*
%T jni_SetByteArrayElement(+term, +term, +term)
*/
static foreign_t
jni_SetDoubleArrayElement(
term_t ta1, // +Arg1
term_t ta2, // +Arg2
term_t ta3 // +Arg3
)
{
jboolean r; // Prolog exit/fail outcome
void *p1;
jint i2;
jdouble p4;
JNIEnv *env;
atom_t a; /* " */
functor_t fn; /* temp for conversion macros */
term_t a1; /* " */
int i; /* " */
int64_t i64;
if ( !jni_ensure_jvm() )
{
return FALSE;
}
r =
JNI_term_to_double_jarray(ta1,p1)
&& JNI_term_to_jint(ta2,i2)
&& JNI_term_to_jdouble(ta3,p4)
&& ( (*env)->SetDoubleArrayRegion(env,(jdoubleArray)p1,(jsize)i2,1,&p4) , TRUE );
return jni_check_exception(env) && r;
}

View File

@ -1,4 +1,4 @@
/* $Id: jpl.c,v 1.12 2007-09-04 22:37:02 vsc Exp $
/* $Id: jpl.c,v 1.13 2007-09-27 15:25:33 vsc Exp $
Part of JPL -- SWI-Prolog/Java interface
@ -50,8 +50,9 @@ refactoring (trivial):
#define JPL_C_LIB_VERSION_PATCH 3
#define JPL_C_LIB_VERSION_STATUS "alpha"
#define DEBUG(n, g) ((void)0)
/*#define DEBUG(n, g) g */
/*#define DEBUG(n, g) ((void)0) */
#define DEBUG_LEVEL 3
#define DEBUG(n, g) ( n >= DEBUG_LEVEL ? g : (void)0 )
/* disable type-of-ref caching (at least until GC issues are resolved) */
#define JPL_CACHE_TYPE_OF_REF FALSE
@ -373,7 +374,7 @@ refactoring (trivial):
/* in the variable j, which must be dynamic (e.g. local) */
/* if this macro is to be re-entrant */
#define JNI_jobject_to_term(J,T) \
( ( j=(J), j==NULL ) \
( ( j=(J), j==NULL ) \
? PL_unify_term((T), \
PL_FUNCTOR, JNI_functor_at_1, \
PL_ATOM, JNI_atom_null \
@ -383,7 +384,7 @@ refactoring (trivial):
&& PL_unify_term((T), \
PL_ATOM, a \
) \
: jni_object_to_iref(j,&i) \
: jni_object_to_iref(env,j,&i) \
&& jni_iref_to_tag(i,&a) \
&& PL_unify_term((T), \
PL_FUNCTOR, JNI_functor_at_1, \
@ -423,7 +424,7 @@ refactoring (trivial):
#define jni_ensure_jvm() ( ( jvm != NULL \
|| jni_create_default_jvm() \
) \
&& (*jvm)->GetEnv(jvm,(void**)&env,JNI_VERSION_1_2)==JNI_OK \
&& (env=jni_env()) != NULL \
)
@ -570,6 +571,7 @@ static jfieldID jBooleanHolderValue_f;
const char *default_args[] = { "pl",
"-g", "true",
"-nosignals",
NULL
}; /* *must* have final NULL */
@ -577,8 +579,7 @@ const char *default_args[] = { "pl",
/*=== JNI global state (initialised by jni_create_jvm_c) =========================================== */
static JavaVM *jvm = NULL; /* non-null -> JVM successfully loaded & initialised */
static JNIEnv *env; /* if jvm is defined, then so will this be */
static char *jvm_ia[1] = {NULL};
static char *jvm_ia[2] = {"-Xrs", NULL};
static char **jvm_dia = jvm_ia; /* default JVM init args (after jpl init, until jvm init) */
static char **jvm_aia = NULL; /* actual JVM init args (after jvm init) */
@ -607,8 +608,24 @@ static pthread_mutex_t pvm_init_mutex = PTHREAD_MUTEX_INITIALIZER; /* for contro
/*=== common functions ============================================================================= */
JNIEnv*
jni_env(void) /* economically gets a JNIEnv pointer, valid for this thread */
{ JNIEnv *env;
switch( (*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_2) )
{ case JNI_OK:
return env;
case JNI_EDETACHED:
DEBUG(2, Sdprintf( "[JPL: jni_env() calls AttachCurrentThread]\n"));
return (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL) == 0 ? env : NULL;
default: /* error */
return NULL;
}
}
static char *
jpl_c_lib_version(void) // vsc
jpl_c_lib_version(void)
{
static char v[100]; /* version string */
static char *vp = NULL; /* set to v at first call */
@ -651,8 +668,8 @@ jpl_c_lib_version_4_plc(
/*=== JNI function prototypes (to resolve unavoidable forward references) ========================== */
static int jni_hr_add(jobject, long*);
static int jni_hr_del(long);
static int jni_hr_add(JNIEnv*, jobject, long*);
static int jni_hr_del(JNIEnv*, long);
/*=== JNI functions (NB first 6 are cited in macros used subsequently) ============================= */
@ -719,13 +736,14 @@ jni_iref_to_tag(
static bool
jni_object_to_iref(
JNIEnv *env,
jobject obj, /* a newly returned JNI local ref */
long *iref /* gets an integerised, canonical, global equivalent */
)
{
int r; /* temp for result code */
if ( (r=jni_hr_add(obj,iref)) == JNI_HR_ADD_NEW )
if ( (r=jni_hr_add(env, obj, iref)) == JNI_HR_ADD_NEW )
{
hr_add_count++; /* obj was novel, has been added to dict */
return TRUE;
@ -773,11 +791,12 @@ jni_tidy_iref_type_cache(
/* could merge this into jni_hr_del() ? */
static bool
jni_free_iref( /* called indirectly from agc hook when a possible iref is unreachable */
JNIEnv *env,
long iref
)
{
if ( jni_hr_del(iref) ) /* iref matched a hashedref table entry? (in which case, was deleted) */
if ( jni_hr_del(env,iref) ) /* iref matched a hashedref table entry? (in which case, was deleted) */
{
if ( !jni_tidy_iref_type_cache(iref) )
{
@ -818,7 +837,7 @@ static bool
pl_wchar_t *wp;
jsize i;
if ( (wp=(pl_wchar_t*)malloc(sizeof(pl_wchar_t)*len)) == NULL) {
if ( (wp=(pl_wchar_t*)malloc(sizeof(pl_wchar_t)*(len))) == NULL) {
(*env)->ReleaseStringChars(env,s,jcp);
return FALSE;
}
@ -846,10 +865,10 @@ static bool
size_t len;
pl_wchar_t *wp;
jchar *jcp;
char *cp;
unsigned char *cp;
unsigned int i;
if ( (cp=(char*)PL_atom_nchars(a,&len)) != NULL ) /* got 8-bit chars from trad atom */
if ( (cp=(unsigned char*)PL_atom_nchars(a,&len)) != NULL ) /* got 8-bit chars from trad atom */
{
jcp = (jchar*)malloc(sizeof(jchar)*len);
for ( i=0 ; i<len ; i++ )
@ -965,8 +984,11 @@ jni_atom_freed(
{
const char *cp = PL_atom_chars(a);
long iref;
char cs[11];
char cs[23]; /* was 11 until 24/Apr/2007 */
JNIEnv *env;
if ((env = jni_env()) == NULL)
return TRUE; /* oughta log an error, at least the first time... */
if ( jni_tag_to_iref( a, &iref) ) /* check format and convert digits to int if ok */
{
sprintf( cs, "%020lu", iref); /* reconstruct digits part of tag in cs */
@ -975,7 +997,7 @@ jni_atom_freed(
DEBUG(0, Sdprintf( "[JPL: garbage-collected tag '%s'=%u is bogus (not canonical)]\n", cp, iref));
}
else
if ( !jni_free_iref(iref) ) /* free it (iff it's in the hashedref table) */
if ( !jni_free_iref(env,iref) ) /* free it (iff it's in the hashedref table) */
{
DEBUG(0, Sdprintf( "[JPL: garbage-collected tag '%s' is bogus (not in HashedRefs)]\n", cp));
}
@ -1090,9 +1112,10 @@ jni_hr_create(
/* an empty table of some default length is successfully created, where none was before */
static bool
jni_hr_create_default(void)
{
return jni_hr_create( 101);
}
{
return jni_hr_create( 101);
}
/* ep must point to a chain of zero or more entries; they are freed */
@ -1150,7 +1173,7 @@ jni_hr_free_table(
/* the current table is replaced by an equivalent one with more free space */
static bool
jni_hr_rehash(void)
{
{
HrTable *t0; /* old table while building new one from it */
int i; /* for iterating through slots in old table */
HrEntry *ep1; /* for iterating through all entries in old table */
@ -1184,6 +1207,7 @@ jni_hr_rehash(void)
static bool
jni_hr_hash( /* renamed in v3.0.4 from jni_object_to_hash (it belongs with this hr stuff) */
JNIEnv *env,
jobject obj, /* MUST BE a valid non-null reference to a Java object */
int *hash /* gets obj's System.identityHashCode() */
)
@ -1202,6 +1226,7 @@ static bool
/* and, in *iref, an integerised canonical global ref to the object */
static int
jni_hr_add(
JNIEnv *env,
jobject lref, /* new JNI local ref from a regular JNI call */
long *iref /* for integerised canonical global ref */
)
@ -1215,7 +1240,7 @@ jni_hr_add(
{
return JNI_HR_ADD_FAIL; /* lazy table creation failed: oughta sort return codes */
}
if ( !jni_hr_hash(lref,&hash) ) /* renamed in v3.0.4 from jni_object_to_hash */
if ( !jni_hr_hash(env,lref,&hash) ) /* renamed in v3.0.4 from jni_object_to_hash */
{
return JNI_HR_ADD_FAIL; /* System.identityHashCode() failed (?) */
}
@ -1235,7 +1260,7 @@ jni_hr_add(
if ( hr_table->count >= hr_table->threshold )
{
(void)jni_hr_rehash(); /* oughta check for failure, and return it... */
return jni_hr_add(lref,iref); /* try again with new, larger table */
return jni_hr_add(env,lref,iref); /* try again with new, larger table */
}
/* referenced object is novel, and we can add it to table */
if ( (gref=(*env)->NewGlobalRef(env,lref)) == NULL ) /* derive a global ref */
@ -1259,6 +1284,7 @@ jni_hr_add(
/* called only from jni_free_iref() */
static bool
jni_hr_del(
JNIEnv *env,
long iref /* a possibly spurious canonical global iref */
)
{
@ -1291,9 +1317,13 @@ jni_hr_del(
/* called once: after successful PVM & JVM creation/discovery, before any JNI calls */
static int
jni_init(void)
jni_init()
{
jclass lref; /* temporary local ref, replaced by global */
JNIEnv *env = jni_env(); /* could pass this in, but this is easier here */
if (env == NULL)
return -8;
/* these initialisations require an active PVM: */
JNI_atom_false = PL_new_atom( "false");
@ -1398,7 +1428,9 @@ static term_t
/* test for a raised exception; clear and report it if found */
static bool
jni_check_exception(void)
jni_check_exception(
JNIEnv *env
)
{
jobject ej; /* the pending Java exception, if any */
jobject c; /* its class */
@ -1419,7 +1451,7 @@ jni_check_exception(void)
{
if ( (s=(*env)->CallObjectMethod(env,c,c_getName)) != NULL ) /* get name of class */
{
if ( jni_object_to_iref(ej,&i) )
if ( jni_object_to_iref(env,ej,&i) )
{
if ( jni_iref_to_tag(i,&tag) )
{
@ -1562,8 +1594,10 @@ jni_param_put_plc(
return JNI_term_to_jdouble(tt,jvp[n].d);
case JNI_XPUT_REF:
return JNI_term_to_ref(tt,jvp[n].l);
{ JNIEnv *env = jni_env();
return env == NULL ? FALSE : JNI_term_to_ref(tt,jvp[n].l); /* this macro needs a valid env */
}
default:
return FALSE; /* unknown or inappropriate JNI_XPUT_* code */
}
@ -1729,23 +1763,6 @@ jni_get_created_jvm_count()
}
#if 0 /* This function is no longer used, having been inlined */
static int /* really just a boolean */
jni_get_env()
{
JNIEnv *env0 = env;
int r;
r = (*jvm)->GetEnv(jvm,(void**)&env,JNI_VERSION_1_2) == JNI_OK;
if ( env != env0 )
{
DEBUG(1, Sdprintf( "[new env=%u]\n", (void*)env));
}
return r;
}
#endif /*0*/
#define MAX_JVM_OPTIONS 100
static int
@ -1760,6 +1777,7 @@ jni_create_jvm_c(
int r;
jint n;
int optn = 0;
JNIEnv *env;
DEBUG(1, Sdprintf( "[creating JVM with 'java.class.path=%s']\n", classpath));
vm_args.version = JNI_VERSION_1_2; /* "Java 1.2 please" */
@ -1798,12 +1816,11 @@ jni_create_jvm_c(
vm_args.nOptions = optn;
/* vm_args.ignoreUnrecognized = TRUE; */
return
( JNI_GetCreatedJavaVMs(&jvm,1,&n) == 0 /* what does the '1' arg mean? */
&& n == 1
&& (*jvm)->GetEnv(jvm,(void**)&env,JNI_VERSION_1_2) == JNI_OK
/* && jni_get_env((void**)&env) */
/* && (*jvm)->GetEnv(jvm,(void**)&env,JNI_VERSION_1_2) == JNI_OK */
&& (env = jni_env()) != NULL
? 2 /* success (JVM already available) */
: ( (r=JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args)) == 0
? 0 /* success (JVM created OK) */
@ -1836,7 +1853,7 @@ jni_create_jvm(
( jvm != NULL
? 1 /* already initialised */
: ( (r1=jni_create_jvm_c(cp)) < 0
? r1 /* err code from JVM-specific routine */
? r1 /* err code from JVM-specific routine */
: ( (r2=jni_init()) < 0
? r2 /* err code from jni_init() */
: ( r1 == 0 /* success code from JVM-specific routine */
@ -1856,7 +1873,7 @@ value at startup of Prolog.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int
jni_create_default_jvm()
jni_create_default_jvm(void)
{
int r;
#ifdef __WINDOWS__
@ -1884,13 +1901,19 @@ jni_create_default_jvm()
static foreign_t
jni_ensure_jvm_plc()
jni_ensure_jvm_plc(void)
{
JNIEnv *env; /* not used but perhaps initialised by the jni_ensure_jvm() macro */
return jni_ensure_jvm();
}
#if IN_YAP
#include "hacks.c"
#endif
/* NB after any JNI call which clearly indicates success, */
/* it is unnecessary to check for an exception */
/* (potential for slight economy here...) */
@ -1901,6 +1924,7 @@ jni_void_0_plc( /* C identifiers distinguished _0_ etc, Prolog name is overloade
{
int n; /* JNI function index */
jboolean r; /* Prolog exit/fail outcome */
JNIEnv *env;
if ( !jni_ensure_jvm() /* ought this either succeed or throw a JPL error? */
|| !PL_get_integer(tn,&n) /* ought this either succeed or throw a Prolog type error? */
@ -1919,7 +1943,7 @@ jni_void_0_plc( /* C identifiers distinguished _0_ etc, Prolog name is overloade
break;
}
return jni_check_exception() && r;
return jni_check_exception(env) && r;
}
@ -1946,6 +1970,7 @@ jni_void_1_plc(
/* jlong l1; // " */
/* double d1; // " */
jboolean r; /* Prolog exit/fail outcome */
JNIEnv *env;
if ( !jni_ensure_jvm()
|| !PL_get_integer(tn,&n)
@ -1965,7 +1990,7 @@ jni_void_1_plc(
break;
}
return jni_check_exception() && r;
return jni_check_exception(env) && r;
}
@ -1998,6 +2023,7 @@ jni_void_2_plc(
/* double d1; // " */
/* double d2; // " */
jboolean r; /* Prolog exit/fail outcome */
JNIEnv *env;
if ( !jni_ensure_jvm()
|| !PL_get_integer(tn,&n)
@ -2023,7 +2049,7 @@ jni_void_2_plc(
break;
}
return jni_check_exception() && r;
return jni_check_exception(env) && r;
}
@ -2068,6 +2094,7 @@ jni_void_3_plc(
double d3; /* " */
jvalue *jvp = NULL; /* if this is given a buffer, it will be freed after the call */
jboolean r; /* Prolog exit/fail outcome */
JNIEnv *env;
if ( !jni_ensure_jvm()
|| !PL_get_integer(tn,&n)
@ -2262,7 +2289,7 @@ jni_void_3_plc(
free( jvp);
}
return jni_check_exception() && r;
return jni_check_exception(env) && r;
}
@ -2308,6 +2335,7 @@ jni_void_4_plc(
/* double d4; // " */
jvalue *jvp = NULL; /* if this is given a buffer, it will be freed after the call */
jboolean r; /* Prolog exit/fail outcome */
JNIEnv *env;
if ( !jni_ensure_jvm()
|| !PL_get_integer(tn,&n)
@ -2447,7 +2475,7 @@ jni_void_4_plc(
free( jvp);
}
return jni_check_exception() && r;
return jni_check_exception(env) && r;
}
@ -2469,6 +2497,7 @@ jni_func_0_plc(
/* jobject j; // " */
/* jlong jl; // " */
jboolean r; /* Prolog exit/fail outcome */
JNIEnv *env;
if ( !jni_ensure_jvm()
|| !PL_get_integer(tn,&n)
@ -2490,7 +2519,7 @@ jni_func_0_plc(
break;
}
return jni_check_exception() && r; /* surely NEITHER of these throws an exception! */
return jni_check_exception(env) && r; /* surely NEITHER of these throws an exception! */
}
@ -2518,6 +2547,7 @@ jni_func_1_plc(
/* jlong l1; // " */
/* double d1; // " */
jboolean r; /* Prolog exit/fail outcome */
JNIEnv *env;
if ( !jni_ensure_jvm()
|| !PL_get_integer(tn,&n)
@ -2609,7 +2639,7 @@ jni_func_1_plc(
break;
}
return jni_check_exception() && r;
return jni_check_exception(env) && r;
}
@ -2643,6 +2673,7 @@ jni_func_2_plc(
/* double d1; // " */
/* double d2; // " */
jboolean r; /* Prolog exit/fail outcome */
JNIEnv *env;
if ( !jni_ensure_jvm()
|| !PL_get_integer(tn,&n)
@ -2833,7 +2864,7 @@ jni_func_2_plc(
break;
}
return jni_check_exception() && r;
return jni_check_exception(env) && r;
}
@ -2874,6 +2905,7 @@ jni_func_3_plc(
/* double d3; // " */
jvalue *jvp = NULL; /* if this is given a buffer, it will be freed after the call */
jboolean r; /* Prolog exit/fail outcome */
JNIEnv *env;
if ( !jni_ensure_jvm()
|| !PL_get_integer(tn,&n)
@ -3038,7 +3070,7 @@ jni_func_3_plc(
free( jvp);
}
return jni_check_exception() && r;
return jni_check_exception(env) && r;
}
@ -3085,6 +3117,7 @@ jni_func_4_plc(
/* double d4; // " */
jvalue *jvp = NULL; /* if this is given a buffer, it will be freed after the call */
jboolean r; /* Prolog exit/fail outcome */
JNIEnv *env;
if ( !jni_ensure_jvm()
|| !PL_get_integer(tn,&n)
@ -3175,17 +3208,17 @@ jni_func_4_plc(
free( jvp);
}
return jni_check_exception() && r;
return jni_check_exception(env) && r;
}
/*=== JPL functions ================================================================================ */
static int
create_pool_engines();
create_pool_engines(void);
static int
jpl_num_initial_default_args() /* used only once, by jpl_do_jpl_init() */
jpl_num_initial_default_args(void) /* used only once, by jpl_do_jpl_init() */
{
int i;
@ -3526,13 +3559,13 @@ err:
static bool
jpl_ensure_jpl_init_1(
JNIEnv *e
JNIEnv *env
)
{
bool r;
pthread_mutex_lock( &jvm_init_mutex);
r = jpl_do_jpl_init(e);
r = jpl_do_jpl_init(env);
pthread_mutex_unlock( &jvm_init_mutex);
return r;
}
@ -3540,15 +3573,15 @@ static bool
static bool
jpl_ensure_pvm_init_1(
JNIEnv *e
JNIEnv *env
)
{
bool r;
pthread_mutex_lock( &pvm_init_mutex);
if ( !jpl_ensure_jpl_init(e) )
if ( !jpl_ensure_jpl_init(env) )
return FALSE;
r = jpl_test_pvm_init(e) || jpl_do_pvm_init(e);
r = jpl_test_pvm_init(env) || jpl_do_pvm_init(env);
pthread_mutex_unlock( &pvm_init_mutex);
return r;
}
@ -4056,7 +4089,7 @@ updateAtomValue(
/*=== Java-wrapped SWI-Prolog FLI functions ======================================================== */
static int current_pool_engine_handle(PL_engine_t *e);
static int current_pool_engine();
static int current_pool_engine(void);
/*
@ -4313,29 +4346,6 @@ JNIEXPORT jboolean JNICALL
}
/*
* Class: jpl_fli_Prolog
* Method: discard_foreign_frame
* Signature: (Ljpl/fli/fid_t;)V
*/
JNIEXPORT void JNICALL
Java_jpl_fli_Prolog_discard_1foreign_1frame(
JNIEnv *env,
jclass jProlog,
jobject jfid
)
{
fid_t fid;
if ( jpl_ensure_pvm_init(env)
&& getLongValue(env,jfid,(long*)&fid) /* checks that jfid isn't null */
)
{
PL_discard_foreign_frame(fid);
}
}
/*
* Class: jpl_fli_Prolog
* Method: exception
@ -4731,7 +4741,7 @@ JNIEXPORT jobject JNICALL
)
{
long iref;
char abuf[13];
char abuf[23];
/* empirically, unless the two 'ensure' macros are called in this order, */
/* will crash if this is the first native method called */
@ -4750,7 +4760,7 @@ JNIEXPORT jobject JNICALL
}
/* Sdprintf("jni_ensure_jvm() ok\n"); */
if ( jobj!=NULL && jni_object_to_iref(jobj,&iref) ) {
if ( jobj!=NULL && jni_object_to_iref(env,jobj,&iref) ) {
/* Sdprintf("jni_object_to_iref() done\n"); */
sprintf( abuf, "J#%020lu", iref); /* oughta encapsulate this mapping... */
/* Sdprintf("sprintf() done\n"); */
@ -4761,33 +4771,6 @@ JNIEXPORT jobject JNICALL
}
/*
* Class: jpl_fli_Prolog
* Method: open_foreign_frame
* Signature: ()Ljpl/fli/fid_t;
*/
JNIEXPORT jobject JNICALL
Java_jpl_fli_Prolog_open_1foreign_1frame(
JNIEnv *env,
jclass jProlog
)
{
jobject rval;
if ( jpl_ensure_pvm_init(env)
&& (rval=(*env)->AllocObject(env,jFidT_c)) != NULL /* get a new fid_t object */
&& setLongValue(env,rval,(long)PL_open_foreign_frame()) /* open a frame only if alloc succeeds */
)
{
return rval;
}
else
{
return NULL;
}
}
/*
* Class: jpl_fli_Prolog
* Method: open_query
@ -4970,7 +4953,7 @@ JNIEXPORT void JNICALL
term_t term;
jobject j; // temp for JNI_jobject_to_term(+,-)
atom_t a; // "
int i; // "
long i; // "
if ( jpl_ensure_pvm_init(env)
&& jni_ensure_jvm()
@ -5296,31 +5279,32 @@ static foreign_t
atom_t a; /* " */
long i; /* " */
jobject j; /* " */
JNIEnv *env;
return jni_ensure_jvm() /* untypically... */
&& jpl_ensure_pvm_init(env) /* ...this requires both inits */
&& (term1=(*env)->AllocObject(env,termt_class)) != NULL
&& setLongValue(env,term1,(long)tref1) /* requires jLongHolderValue_f to be initialised */
&& JNI_jobject_to_term((*env)->CallStaticObjectMethod(env,term_class,term_getTerm,term1),tref2)
&& jni_check_exception();
&& jni_check_exception(env);
}
/* serves jni_jref_to_term_plc() */
static bool
jni_jobject_to_term_byval(
JNIEnv *env,
jobject jobj, /* this must be an instance of one of jpl.Term's subclasses */
term_t term /* a Prolog term, as represented by jobj, is *put* into this term ref */
)
{
jobject termt; /* a temporary instance of jpl.fli.term_t (i.e. a "term holder") */
return jni_ensure_jvm() /* untypically... */
&& jpl_ensure_pvm_init(env) /* ...this requires both inits */
&& (termt=(*env)->AllocObject(env,termt_class)) != NULL
return /* jni_ensure_jvm() && jpl_ensure_pvm_init(env) && */
(termt=(*env)->AllocObject(env,termt_class)) != NULL
&& setLongValue(env,termt,(long)term) /* requires jLongHolderValue_f to be initialised */
&& ( (*env)->CallStaticVoidMethod(env,term_class,term_putTerm,jobj,termt) , TRUE )
&& jni_check_exception()
&& jni_check_exception(env)
;
}
@ -5339,6 +5323,7 @@ static foreign_t
long iterm;
jobject jterm;
term_t term = PL_new_term_ref(); /* jni_jobject_to_term_byval() will *put* the constructed term in here */
JNIEnv *env;
return jni_ensure_jvm() /* untypically... */
&& jpl_ensure_pvm_init(env) /* ...this requires both inits */
@ -5348,7 +5333,7 @@ static foreign_t
&& PL_get_atom(arg,&a)
&& jni_tag_to_iref(a,&iterm)
&& (jterm = (jobject)iterm)
&& jni_jobject_to_term_byval(jterm,term) /* NB a bogus Tag could crash this... */
&& jni_jobject_to_term_byval(env,jterm,term) /* NB a bogus Tag could crash this... */
&& PL_unify( termIn, term) /* attempt to unify the 2nd arg with the newly constructed term */
;
}
@ -5476,7 +5461,6 @@ static foreign_t
return jni_get_jvm_opts(args,jvm_aia);
}
/*=== FLI metadata ================================================================================= */
static
@ -5502,6 +5486,10 @@ static
{ "jni_func", 4, jni_func_2_plc, 0 },
{ "jni_func", 5, jni_func_3_plc, 0 },
{ "jni_func", 6, jni_func_4_plc, 0 },
#if IN_YAP
{ "jni_SetByteArrayElement", 3, jni_SetByteArrayElement, 0 },
{ "jni_SetDoubleArrayElement", 3, jni_SetDoubleArrayElement, 0 },
#endif
{ "jpl_c_lib_version", 1, jpl_c_lib_version_1_plc, 0 },
{ "jpl_c_lib_version", 4, jpl_c_lib_version_4_plc, 0 },
{ "jni_term_to_jref", 2, jni_term_to_jref_plc, 0 },
@ -5514,9 +5502,8 @@ static
install_t
install()
install(void)
{
PL_register_extensions( predspecs);
}

View File

@ -8,6 +8,7 @@
<link rel=stylesheet href="changes.css" type="text/css">
</head>
<body>
<hr>
@ -16,6 +17,9 @@
<h2>Yap-5.1.3:</h2>
<ul>
<li> UPGRADED: to current JPL.</li>
<li> FIXED: incremental garbage collection conflicts with global variables (disable it for now).</li>
<li> FIXED: trail overflow from calling dynamic predicates (obs from Bernd Gutmann).</li>
<li> NEW: add nb_*arg versions.</li>
<li> FIXED: overflow in indexing code (obs from Jesse Davis).</li>
<li> NEW: improve nb_ routines with linkvar and set_shared_var.</li>

12319
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1361,6 +1361,7 @@ mkdir -p LGPL/JPL
mkdir -p LGPL/JPL/java
mkdir -p LGPL/JPL/java/jpl
mkdir -p LGPL/JPL/java/jpl/fli
mkdir -p LGPL/JPL/java/jpl/test
mkdir -p LGPL/JPL/src
mkdir -p LGPL/clp
mkdir -p LGPL/clpr

View File

@ -3609,6 +3609,66 @@ Closes the stream @var{S}, following options @var{O}.
The only valid options are @code{force(true)} and @code{force(false)}.
YAP currently ignores these options.
@item absolute_file_name(+@var{Name},+@var{Options}, -@var{FullPath})
@item absolute_file_name(+@var{Name}, -@var{FullPath},+@var{Options})
@findex absolute_file_name/3
@syindex absolute_file_name/3
@cnindex absolute_file_name/3
Converts the given file specification into an absolute path.
@var{Option} is a list of options to guide the conversion:
@table @code
@item extensions(+@var{ListOfExtensions})
List of file-extensions to try. Default is @samp{''}. For each
extension, @code{absolute_file_name/3} will first add the extension and then
verify the conditions imposed by the other options. If the condition
fails, the next extension of the list is tried. Extensions may be
specified both as @code{.ext} or plain @code{ext}.
@item relative_to(+@var{FileOrDir})
Resolve the path relative to the given directory or directory the
holding the given file. Without this option, paths are resolved
relative to the working directory (see working_directory/2) or,
if @var{Spec} is atomic and absolute_file_name/[2,3] is executed
in a directive, it uses the current source-file as reference.
@item access(+@var{Mode})
Imposes the condition access_file(@var{File}, @var{Mode}). @var{Mode}
is on of @code{read}, @code{write}, @code{append}, @code{exist} or @code{none}. See also access_file/2.
@item file_type(+@var{Type})
Defines extensions. Current mapping: @code{txt} implies @code{['']},
@code{prolog} implies @code{['.pl', '']}, @code{executable} implies
@code{['.so', '']}, @code{qlf} implies @code{['.qlf', '']} and
@code{directory} implies @code{['']}. The file-type @code{source}
is an alias for @code{prolog} for compatibility to SICStus Prolog.
See also prolog_file_type/2.
@item file_errors(@code{fail}/@code{error})
If @code{error} (default), throw and @code{existence_error} exception
if the file cannot be found. If @code{fail}, stay silent.
@item solutions(@code{first}/@code{all})
If @code{first} (default), the predicates leaves no choice-point.
Otherwise a choice-point will be left and backtracking may yield
more solutions.
@c @item expand(@code{true}/@code{false})
@c If @code{true} (default is @code{false}) and @var{Spec} is atomic,
@c call @code{expand_file_name/2} followed by @code{member/2} on @var{Spec} before
@c proceeding. This is a SWI-Prolog extension.
@end table
@c The Prolog flag @code{verbose_file_search} can be set to @code{true}
@c to help debugging Prolog's search for files.
Compatibility considerations to common argument-order in ISO as well
as SICStus @code{absolute_file_name/3} forced us to be flexible here.
If the last argument is a list and the 2nd not, the arguments are
swapped, making the call @code{absolute_file_name}(+@var{Spec}, -@var{Path},
+@var{Options}) valid as well.
@item absolute_file_name(+@var{Name},-@var{FullPath})
@findex absolute_file_name/2
@syindex absolute_file_name/2
@ -6815,6 +6875,13 @@ collection and stack shifts. Last, if @code{very_verbose} give detailed
information on data-structures found during the garbage collection
process, namely, on choice-points.
@item generate_debugging_info
@findex generate_debugging_info (yap_flag/2 option)
@* If @code{true} (default) generate debugging information for
procedures, including source mode. If @code{false} predicates no
information is generated, although debugging is still possible, and
source mode is disabled.
@item host_type
@findex host_type (yap_flag/2 option)
@* Return @code{configure} system information, including the machine-id
@ -6914,6 +6981,11 @@ in several different files are @code{on} or
and if it is bound to @code{off} disable them. The default for YAP is
@code{off}, unless we are in @code{sicstus} or @code{iso} mode.
@item shared_object_search_path
@findex shared_object_search_path (yap_flag/2 option)
Name of the environment variable used by the system to search for shared
objects.
@item single_var_warnings
@findex single_var_warnings (yap_flag/2 option)
@*
@ -7016,6 +7088,12 @@ If bound, set the current working or type-in module to the argument,
which must be an atom. If unbound, unify the argument with the current
working module.
@item unix
@findex unix (yap_flag/2 option)
@* Read-only boolean flag that unifies with tr @code{true} if YAP is
running on an Unix system. Defined if the C-compiler used to compile
this version of YAP either defines @code{__unix__} or @code{unix}.
@item unknown [ISO]
@findex unknown (yap_flag/2 option)
@*
@ -7089,6 +7167,12 @@ corresponding to the Unix @code{stdout} stream.
@*
Read-only flag that giving the current version of YAP.
@item windows
@findex windoes (yap_flag/2 option)
@*
Read-only boolean flag that unifies with tr @code{true} if YAP is
running on an Windows machine.
@item write_strings
@findex write_strings (yap_flag/2 option)
@* Writable flag telling whether the system should write lists of

258
include/SWI-Prolog.h Normal file
View File

@ -0,0 +1,258 @@
/* yap2swi.h */
/*
* Project: jpl for Yap Prolog
* Author: Steve Moyle and Vitor Santos Costa
* Email: steve.moyle@comlab.ox.ac.uk
* Date: 21 January 2002
* Copyright (c) 2002 Steve Moyle and Vitor Santos Costa. All rights reserved.
*/
//=== includes ===============================================================
#include "config.h"
#include <YapInterface.h>
#include <stdarg.h>
#include <wchar.h>
#if HAVE_TIME_H
#include <time.h>
#endif
#if defined(_MSC_VER) && defined(YAP_EXPORTS)
#define X_API __declspec(dllexport)
#else
#define X_API
#endif
typedef unsigned long fid_t;
typedef unsigned long term_t;
typedef void *module_t;
typedef unsigned long atom_t;
typedef YAP_Term *predicate_t;
typedef struct open_query_struct *qid_t;
typedef long functor_t;
typedef int (*PL_agc_hook_t)(atom_t);
typedef unsigned long foreign_t; /* return type of foreign functions */
typedef wchar_t pl_wchar_t; /* wide character support */
#ifdef WIN32
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <inttypes.h> /* more portable than stdint.h */
#endif
typedef void *function_t;
typedef struct _PL_extension
{ char *predicate_name; /* Name of the predicate */
short arity; /* Arity of the predicate */
function_t function; /* Implementing functions */
short flags; /* Or of PL_FA_... */
} PL_extension;
typedef struct
{ unsigned long local_size; /* Stack sizes */
unsigned long global_size;
unsigned long trail_size;
unsigned long argument_size;
char * alias; /* alias name */
int (*cancel)(int id); /* cancel function */
void * reserved[5]; /* reserved for extensions */
} PL_thread_attr_t;
typedef void *PL_engine_t;
#define PL_FA_NOTRACE (0x01) /* foreign cannot be traced */
#define PL_FA_TRANSPARENT (0x02) /* foreign is module transparent */
#define PL_FA_NONDETERMINISTIC (0x04) /* foreign is non-deterministic */
#define PL_FA_VARARGS (0x08) /* call using t0, ac, ctx */
/* begin from pl-itf.h */
#define PL_VARIABLE (1) /* nothing */
#define PL_ATOM (2) /* const char * */
#define PL_INTEGER (3) /* int */
#define PL_FLOAT (4) /* double */
#define PL_STRING (5) /* const char * */
#define PL_TERM (6)
/* PL_unify_term() */
#define PL_FUNCTOR (10) /* functor_t, arg ... */
#define PL_LIST (11) /* length, arg ... */
#define PL_CHARS (12) /* const char * */
#define PL_POINTER (13) /* void * */
/* PlArg::PlArg(text, type) */
#define PL_CODE_LIST (14) /* [ascii...] */
#define PL_CHAR_LIST (15) /* [h,e,l,l,o] */
#define PL_BOOL (16) /* PL_set_feature() */
#define PL_FUNCTOR_CHARS (17) /* PL_unify_term() */
#define PL_PREDICATE_INDICATOR (18) /* predicate_t (Procedure) */
#define PL_SHORT (19) /* short */
#define PL_INT (20) /* int */
#define PL_LONG (21) /* long */
#define PL_DOUBLE (22) /* double */
#define CVT_ATOM 0x0001
#define CVT_STRING 0x0002
#define CVT_LIST 0x0004
#define CVT_INTEGER 0x0008
#define CVT_FLOAT 0x0010
#define CVT_VARIABLE 0x0020
#define CVT_NUMBER (CVT_INTEGER|CVT_FLOAT)
#define CVT_ATOMIC (CVT_NUMBER|CVT_ATOM|CVT_STRING)
#define CVT_WRITE 0x0040 /* as of version 3.2.10 */
#define CVT_ALL (CVT_ATOMIC|CVT_LIST)
#define CVT_MASK 0x00ff
#define BUF_DISCARDABLE 0x0000
#define BUF_RING 0x0100
#define BUF_MALLOC 0x0200
#define PL_ENGINE_CURRENT ((PL_engine_t)-1)
#define PL_ENGINE_SET 0 /* engine set successfully */
#define PL_ENGINE_INVAL 2 /* engine doesn't exist */
#define PL_ENGINE_INUSE 3 /* engine is in use */
#define PL_ACTION_TRACE 1 /* switch to trace mode */
#define PL_ACTION_DEBUG 2 /* switch to debug mode */
#define PL_ACTION_BACKTRACE 3 /* show a backtrace (stack dump) */
#define PL_ACTION_BREAK 4 /* create a break environment */
#define PL_ACTION_HALT 5 /* halt Prolog execution */
#define PL_ACTION_ABORT 6 /* generate a Prolog abort */
/* 7: Obsolete PL_ACTION_SYMBOLFILE */
#define PL_ACTION_WRITE 8 /* write via Prolog i/o buffer */
#define PL_ACTION_FLUSH 9 /* Flush Prolog i/o buffer */
#define PL_ACTION_GUIAPP 10 /* Win32: set when this is a gui */
#define PL_ACTION_ATTACH_CONSOLE 11 /* MT: Attach a console */
/* end from pl-itf.h */
/* copied from old SICStus/SWI interface */
typedef void install_t;
extern X_API void PL_free(void *);
extern X_API PL_agc_hook_t PL_agc_hook(PL_agc_hook_t);
extern X_API char* PL_atom_chars(atom_t);
extern X_API term_t PL_copy_term_ref(term_t);
extern X_API term_t PL_new_term_ref(void);
extern X_API term_t PL_new_term_refs(int);
extern X_API void PL_reset_term_refs(term_t);
/* begin PL_get_* functions =============================*/
extern X_API int PL_get_arg(int, term_t, term_t);
extern X_API int PL_get_atom(term_t, atom_t *);
extern X_API int PL_get_atom_chars(term_t, char **);
extern X_API int PL_get_chars(term_t, char **, unsigned);
extern X_API int PL_get_nchars(term_t, size_t *, char **, unsigned);
extern X_API int PL_get_wchars(term_t, size_t *, wchar_t **, unsigned);
extern X_API int PL_get_functor(term_t, functor_t *);
extern X_API int PL_get_float(term_t, double *);
extern X_API int PL_get_head(term_t, term_t);
extern X_API int PL_get_int64(term_t, int64_t *);
extern X_API int PL_get_integer(term_t, int *);
extern X_API int PL_get_list(term_t, term_t, term_t);
extern X_API int PL_get_long(term_t, long *);
extern X_API int PL_get_list_chars(term_t, char **, unsigned);
extern X_API int PL_get_module(term_t, module_t *);
extern X_API atom_t PL_module_name(module_t);
extern X_API module_t PL_new_module(atom_t);
extern X_API int PL_get_name_arity(term_t, atom_t *, int *);
extern X_API int PL_get_nil(term_t);
extern X_API int PL_get_pointer(term_t, void **);
extern X_API int PL_get_string(term_t, char **, int *);
extern X_API int PL_get_tail(term_t, term_t);
/* end PL_get_* functions =============================*/
/* begin PL_new_* functions =============================*/
extern X_API atom_t PL_new_atom(const char *);
extern X_API atom_t PL_new_atom_wchars(int, const pl_wchar_t *);
extern X_API char *PL_atom_nchars(atom_t, size_t *);
extern X_API pl_wchar_t *PL_atom_wchars(atom_t, size_t *);
extern X_API functor_t PL_new_functor(atom_t, int);
extern X_API atom_t PL_functor_name(functor_t);
extern X_API int PL_functor_arity(functor_t);
/* end PL_new_* functions =============================*/
/* begin PL_put_* functions =============================*/
extern X_API void PL_cons_functor(term_t, functor_t,...);
extern X_API void PL_cons_functor_v(term_t, functor_t,term_t);
extern X_API void PL_cons_list(term_t, term_t, term_t);
extern X_API void PL_put_atom(term_t, atom_t);
extern X_API void PL_put_atom_chars(term_t, const char *);
extern X_API void PL_put_float(term_t, double);
extern X_API void PL_put_functor(term_t, functor_t t);
extern X_API void PL_put_int64(term_t, int64_t);
extern X_API void PL_put_integer(term_t, long);
extern X_API void PL_put_list(term_t);
extern X_API void PL_put_list_chars(term_t, const char *);
extern X_API void PL_put_nil(term_t);
extern X_API void PL_put_pointer(term_t, void *);
extern X_API void PL_put_string_chars(term_t, const char *);
extern X_API void PL_put_term(term_t, term_t);
extern X_API void PL_put_variable(term_t);
extern X_API int PL_compare(term_t, term_t);
/* end PL_put_* functions =============================*/
/* begin PL_unify_* functions =============================*/
extern X_API int PL_unify(term_t, term_t);
extern X_API int PL_unify_atom(term_t, atom_t);
extern X_API int PL_unify_atom_chars(term_t, const char *);
extern X_API int PL_unify_float(term_t, double);
extern X_API int PL_unify_int64(term_t, int64_t);
extern X_API int PL_unify_integer(term_t, long);
extern X_API int PL_unify_list(term_t, term_t, term_t);
extern X_API int PL_unify_list_chars(term_t, const char *);
extern X_API int PL_unify_nil(term_t);
extern X_API int PL_unify_pointer(term_t, void *);
extern X_API int PL_unify_string_chars(term_t, const char *);
extern X_API int PL_unify_term(term_t,...);
/* end PL_unify_* functions =============================*/
/* begin PL_is_* functions =============================*/
extern X_API int PL_is_atom(term_t);
extern X_API int PL_is_atomic(term_t);
extern X_API int PL_is_compound(term_t);
extern X_API int PL_is_float(term_t);
extern X_API int PL_is_functor(term_t, functor_t);
extern X_API int PL_is_integer(term_t);
extern X_API int PL_is_list(term_t);
extern X_API int PL_is_number(term_t);
extern X_API int PL_is_string(term_t);
extern X_API int PL_is_variable(term_t);
extern X_API int PL_term_type(term_t);
/* end PL_is_* functions =============================*/
extern X_API void PL_halt(int);
extern X_API int PL_initialise(int, char **);
extern X_API int PL_is_initialised(int *, char ***);
extern X_API void PL_close_foreign_frame(fid_t);
extern X_API void PL_discard_foreign_frame(fid_t);
extern X_API fid_t PL_open_foreign_frame(void);
extern X_API int PL_raise_exception(term_t);
extern X_API void PL_register_atom(atom_t);
extern X_API void PL_unregister_atom(atom_t);
extern X_API predicate_t PL_pred(functor_t, module_t);
extern X_API predicate_t PL_predicate(const char *, int, const char *);
extern X_API void PL_predicate_info(predicate_t, atom_t *, int *, module_t *);
extern X_API qid_t PL_open_query(module_t, int, predicate_t, term_t);
extern X_API int PL_next_solution(qid_t);
extern X_API void PL_cut_query(qid_t);
extern X_API void PL_close_query(qid_t);
extern X_API term_t PL_exception(qid_t);
extern X_API int PL_call_predicate(module_t, int, predicate_t, term_t);
extern X_API int PL_call(term_t, module_t);
extern X_API void PL_register_extensions(PL_extension *);
extern X_API void PL_load_extensions(PL_extension *);
extern X_API int PL_thread_self(void);
extern X_API int PL_thread_attach_engine(const PL_thread_attr_t *);
extern X_API int PL_thread_destroy_engine(void);
extern X_API int PL_thread_at_exit(void (*)(void *), void *, int);
extern X_API PL_engine_t PL_create_engine(const PL_thread_attr_t *);
extern X_API int PL_destroy_engine(PL_engine_t);
extern X_API int PL_set_engine(PL_engine_t,PL_engine_t *);
extern X_API int PL_get_string_chars(term_t, char **, int *);
extern X_API int PL_action(int,...);
extern X_API int Sprintf(char *,...);
extern X_API int Sdprintf(char *,...);
void swi_install(void);

0
include/SWI-Stream.h Normal file
View File

View File

@ -60,6 +60,13 @@ prolog:volatile((G1,G2)) :-
prolog:volatile(P) :-
do_volatile(P,_).
prolog:load_foreign_library(P,Command) :-
absolute_file_name(P,[file_type(executable),solutions(first),file_errors(fail)],Lib),
load_foreign_files([Lib],[],Command).
prolog:load_foreign_library(P) :-
prolog:load_foreign_library(P,install).
do_volatile(_,_).
:- meta_predicate prolog:forall(+,:).
@ -68,14 +75,6 @@ do_volatile(_,_).
:- use_module(library(lists)).
prolog:absolute_file_name(jar(File), _Opts, Path) :- !,
absolute_file_name(library(File), Path).
prolog:absolute_file_name(library(File), _Opts, Path) :- !,
absolute_file_name(library(File), Path).
prolog:absolute_file_name(File, _Opts, Path) :-
absolute_file_name(File, Path).
prolog:term_to_atom(Term,Atom) :-
nonvar(Atom), !,
atom_codes(Atom,S),
@ -84,6 +83,10 @@ prolog:term_to_atom(Term,Atom) :-
write_to_chars(Term,S),
atom_codes(Atom,S).
prolog:concat_atom([A|List], Separator, New) :- var(List), !,
atom_codes(Separator,[C]),
atom_codes(New, NewChars),
split_atom_by_chars(NewChars,C,L,L,A,List).
prolog:concat_atom(List, Separator, New) :-
add_separator_to_list(List, Separator, NewList),
atomic_concat(NewList, New).
@ -91,6 +94,14 @@ prolog:concat_atom(List, Separator, New) :-
prolog:concat_atom(List, New) :-
atomic_concat(List, New).
split_atom_by_chars([],_,[],L,A,[]):-
atom_codes(A,L).
split_atom_by_chars([C|NewChars],C,[],L,A,[NA|Atoms]) :- !,
atom_codes(A,L),
split_atom_by_chars(NewChars,C,NL,NL,NA,Atoms).
split_atom_by_chars([C1|NewChars],C,[C1|LF],LAtom,Atom,Atoms) :-
split_atom_by_chars(NewChars,C,LF,LAtom,Atom,Atoms).
add_separator_to_list([], _, []).
add_separator_to_list([T], _, [T]) :- !.
add_separator_to_list([H|T], Separator, [H,Separator|NT]) :-
@ -101,6 +112,8 @@ prolog:setenv(X,Y) :- unix(putenv(X,Y)).
prolog:nth1(I,L,A) :- nth(I,L,A).
prolog:prolog_to_os_filename(X,X).
prolog:forall(X,Y) :-
catch(do_forall(X,Y), fail_forall, fail).

View File

@ -509,7 +509,28 @@ X_API atom_t PL_new_atom(const char *c)
X_API atom_t PL_new_atom_wchars(int len, const wchar_t *c)
{
return (atom_t)YAP_LookupWideAtom((wchar_t *)c);
atom_t at;
int i;
for (i=0;i<len;i++) {
if (c[i] > 255) break;
}
if (i!=len) {
wchar_t *nbf = (wchar_t *)YAP_AllocSpaceFromYap((len+1)*sizeof(wchar_t));
for (i=0;i<len;i++)
nbf[i] = c[i];
nbf[len]='\0';
at = (atom_t)YAP_LookupWideAtom(nbf);
YAP_FreeSpaceFromYap(nbf);
} else {
char *nbf = (char *)YAP_AllocSpaceFromYap((len+1)*sizeof(char));
for (i=0;i<len;i++)
nbf[i] = c[i];
nbf[len]='\0';
at = (atom_t)YAP_LookupAtom(nbf);
YAP_FreeSpaceFromYap(nbf);
}
return at;
}
X_API char *PL_atom_nchars(atom_t name, size_t *sp)
@ -951,7 +972,7 @@ X_API int PL_unify_term(term_t l,...)
}
va_end (ap);
ptr = (arg_types *)buffers;
return YAP_Unify(YAP_GetFromSlot(l),get_term(&ptr));
return YAP_Unify(YAP_GetFromSlot(l),get_term(&ptr));
}
/* end PL_unify_* functions =============================*/

View File

@ -917,53 +917,18 @@ bootstrap(F) :-
% Path predicates
access_file(F,Mode) :-
'$exists'(F,Mode).
'$exists'(_,none) :- !.
'$exists'(F,exists) :-
'$access'(F), !.
'$exists'(F,Mode) :-
get_value(fileerrors,V),
set_value(fileerrors,0),
( '$open'(F,Mode,S,0,1) -> '$close'(S), set_value(fileerrors,V) ; set_value(fileerrors,V), fail).
% This sequence must be followed:
% user and user_input are special;
% library(F) must check library_directories
% T(F) must check file_search_path
% all must try search in path
'$find_in_path'(user,user_input, _) :- !.
'$find_in_path'(user_input,user_input, _) :- !.
'$find_in_path'(library(File),NewFile, _) :-
'$dir_separator'(D),
atom_codes(A,[D]),
user:library_directory(Dir),
'$extend_path'(Dir, A, File, NFile, compile(library(File))),
'$search_in_path'(NFile, NewFile), !.
'$find_in_path'(S,NewFile, _) :-
S =.. [Name,File], !,
'$dir_separator'(D),
atom_codes(A,[D]),
user:file_search_path(Name, Dir),
'$extend_path'(Dir, A, File, NFile, compile(S)),
'$search_in_path'(NFile, NewFile), !.
'$find_in_path'(File,NewFile,_) :- atom(File), !,
'$search_in_path'(File,NewFile),!.
'$find_in_path'(File,_,Call) :-
'$do_error'(domain_error(source_sink,File),Call).
'$search_in_path'(New,New) :-
'$exists'(New,'$csult'), !.
'$search_in_path'(File,New) :-
recorded('$path',Path,_),
atom_concat([Path,File],New),
'$exists'(New,'$csult').
'$extend_path'(Dir, A, File, NFile, _) :-
atom(Dir), !,
atom_concat([Dir,A,File],NFile).
'$extend_path'(Name, A, File, NFile, Goal) :-
nonvar(Name),
Name =.. [_,_],
'$find_in_path'(Name, Path, Goal),
'$extend_path'(Path, A, File, NFile, Goal).
% term expansion
%
% return two arguments: Expanded0 is the term after "USER" expansion.

View File

@ -19,7 +19,7 @@
% SWI options
% autoload(true,false)
% derived_from(File) -> make
% encoding(Enconding)
% encoding(Encoding)
% expand({true,false)
% if(changed,true,not_loaded)
% imports(all,List)
@ -544,6 +544,208 @@ remove_from_path(New) :- '$check_path'(New,Path),
).
absolute_file_name(V,Out) :- var(V), !,
'$do_error'(instantiation_error, absolute_file_name(V, Out)).
absolute_file_name(user,user) :- !.
absolute_file_name(File0,File) :-
'$absolute_file_name'(File0,[access(read),file_type(source),file_errors(fail),solutions(first)],File,absolute_file_name(File0,File)).
'$find_in_path'(F0,F,G) :-
'$absolute_file_name'(F0,[access(read),file_type(source),file_errors(fail),solutions(first)],F,G).
absolute_file_name(File,TrueFileName,Opts) :-
var(TrueFileName), !,
absolute_file_name(File,Opts,TrueFileName).
absolute_file_name(File,Opts,TrueFileName) :-
'$absolute_file_name'(File,Opts,TrueFileName,absolute_file_name(File,Opts,TrueFileName)).
'$absolute_file_name'(File,Opts,TrueFileName,G) :- var(File), !,
'$do_error'(instantiation_error, G).
'$absolute_file_name'(File,Opts,TrueFileName, G) :-
'$process_fn_opts'(Opts,Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,G),
FoundOne = a(false),
(
'$find_in_path'(File,opts(Extensions,RelTo,Type,Access,FErrors,Expand,Debug),TrueFileName,G),
(Solutions = first -> ! ; true),
nb_setarg(1, FoundOne, true)
;
FErrors = error, FoundOne = a(false) ->
'$do_error'(existence_error(file,File),G)
).
'$process_fn_opts'(V,_,_,_,_,_,_,_,_,G) :- var(V), !,
'$do_error'(instantiation_error, G).
'$process_fn_opts'([],[],CWD,source,read,error,first,false,false,_) :- !,
getcwd(CWD).
'$process_fn_opts'([Opt|Opts],Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,G) :- !,
'$process_fn_opt'(Opt,Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,Extensions0,RelTo0,Type0,Access0,FErrors0,Solutions0,Expand0,Debug0,G),
'$process_fn_opts'(Opts,Extensions0,RelTo0,Type0,Access0,FErrors0,Solutions0,Expand0,Debug0,G).
'$process_fn_opts'(Opts,Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,G) :- !,
'$do_error'(type_error(list,T),G).
'$process_fn_opt'(Opt,Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,G) :- var(Opt), !,
'$do_error'(instantiation_error, G).
'$process_fn_opt'(extensions(Extensions),Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,_,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,G) :- !,
'$check_fn_extensions'(L,G).
'$process_fn_opt'(relative_to(RelTo),Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,Extensions,_,Type,Access,FErrors,Solutions,Expand,Debug,G) :- !,
'$check_atom'(RelTo,G).
'$process_fn_opt'(access(Access),Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,Extensions,RelTo,Type,_,FErrors,Solutions,Expand,Debug,G) :- !,
'$check_atom'(Access,G).
'$process_fn_opt'(file_type(Type),Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,Extensions,RelTo,_,Access,FErrors,Solutions,Expand,Debug,G) :- !,
'$check_fn_type'(Type,G).
'$process_fn_opt'(file_errors(FErrors),Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,Extensions,RelTo,Type,Access,_,Solutions,Expand,Debug,G) :- !,
'$check_fn_errors'(FErrors,G).
'$process_fn_opt'(solutions(Solutions),Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,Extensions,RelTo,Type,Access,FErrors,_,Expand,Debug,G) :- !,
'$check_fn_solutions'(Solutions,G).
'$process_fn_opt'(expand(Expand),Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,Extensions,RelTo,Type,Access,FErrors,Solutions,_,Debug,G) :- !,
'$check_true_false'(Expand,G).
'$process_fn_opt'(verbose_file_search(Debug),Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,_,G) :- !,
'$check_true_false'(Debug,G).
'$process_fn_opt'(Opt,Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,Extensions,RelTo,Type,Access,FErrors,Solutions,Expand,Debug,G) :- !,
'$do_error'(domain_error(file_name_option,T),G).
'$check_fn_extensions'(V,G) :- var(V), !,
'$do_error'(instantiation_error, G).
'$check_fn_extensions'([],_) :- !.
'$check_fn_extensions'([A|L],G) :- !,
'$check_atom'(A,G),
'$check_fn_extensions'(L,G).
'$check_fn_extensions'(T,G) :- !,
'$do_error'(type_error(list,T),G).
'$check_atom'(V,G) :- var(V), !,
'$do_error'(instantiation_error, G).
'$check_atom'(A,G) :- atom(A), !.
'$check_atom'(T,G) :- !,
'$do_error'(type_error(atom,T),G).
'$check_fn_type'(V,G) :- var(V), !,
'$do_error'(instantiation_error, G).
'$check_fn_type'(txt,_) :- !.
'$check_fn_type'(prolog,_) :- !.
'$check_fn_type'(source,_) :- !.
'$check_fn_type'(executable,_) :- !.
'$check_fn_type'(qlf,_) :- !.
'$check_fn_type'(directory,_) :- !.
'$check_fn_type'(T,G) :- atom(T), !,
'$do_error'(domain_error(file_type,T),G).
'$check_fn_type'(T,G) :- !,
'$do_error'(type_error(atom,T),G).
'$check_fn_errors'(V,G) :- var(V), !,
'$do_error'(instantiation_error, G).
'$check_fn_errors'(fail,_) :- !.
'$check_fn_errors'(error,_) :- !.
'$check_fn_errors'(T,G) :- atom(T), !,
'$do_error'(domain_error(file_errors,T),G).
'$check_fn_errors'(T,G) :- !,
'$do_error'(type_error(atom,T),G).
'$check_fn_solutions'(V,G) :- var(V), !,
'$do_error'(instantiation_error, G).
'$check_fn_solutions'(first,_) :- !.
'$check_fn_solutions'(all,_) :- !.
'$check_fn_solutions'(T,G) :- atom(T), !,
'$do_error'(domain_error(solutions,T),G).
'$check_fn_solutions'(T,G) :- !,
'$do_error'(type_error(atom,T),G).
'$check_true_false'(V,G) :- var(V), !,
'$do_error'(instantiation_error, G).
'$check_true_false'(true,_) :- !.
'$check_true_false'(false,_) :- !.
'$check_true_false'(T,G) :- atom(T), !,
'$do_error'(domain_error(boolean,T),G).
'$check_true_false'(T,G) :- !,
'$do_error'(type_error(atom,T),G).
% This sequence must be followed:
% user and user_input are special;
% library(F) must check library_directories
% T(F) must check file_search_path
% all must try search in path
'$find_in_path'(user,_,user_input, _) :- !.
'$find_in_path'(user_input,_,user_input, _) :- !.
'$find_in_path'(library(File),Opts,NewFile, Call) :- !,
'$dir_separator'(D),
atom_codes(A,[D]),
'$extend_path_directory'(Name, A, File, Opts, NewFile, Call).
'$find_in_path'(S, Opts, NewFile, Call) :-
S =.. [Name,File], !,
'$dir_separator'(D),
atom_codes(A,[D]),
'$extend_path_directory'(Name, A, File, Opts, NewFile, Call).
'$find_in_path'(File,Opts,NewFile,_) :-
atom(File), !,
'$add_path'(File,PFile),
'$get_abs_file'(PFile,Opts,AbsFile),
'$search_in_path'(AbsFile,Opts,NewFile).
'$find_in_path'(File,_,_,Call) :-
'$do_error'(domain_error(source_sink,File),Call).
'$get_abs_file'(File,opts(_,D0,_,_,_,_,_),AbsFile) :-
'$dir_separator'(D),
atom_codes(A,[D]),
atom_concat([D0,A,File],File1),
system:true_file_name(File1,AbsFile).
'$search_in_path'(File,opts(Extensions,_,_,Access,_,_,_),F) :-
'$add_extensions'(Extensions,File,F),
access_file(F,Access).
'$search_in_path'(File,opts(_,_,Type,Access,_,_,_),F) :-
'$add_type_extensions'(Type,File,F),
access_file(F,Access).
'$add_extensions'([Ext|_],File,F) :-
'$mk_sure_true_ext'(Ext,NExt),
atom_concat([File,NExt],F).
'$add_extensions'([_|Extensions],File,F) :-
'$add_extensions'(Extensions,File,F).
'$mk_sure_true_ext'(Ext,NExt) :-
atom_codes(Ext,[C|L]),
C \= 0'.,
!,
atom_codes(NExt,[0'.,C|L]).
'$mk_sure_true_ext'(Ext,Ext).
'$add_type_extensions'(Type,File,F) :-
'$type_extension'(Type,Ext),
atom_concat([File,Ext],F).
'$type_extension'(txt,'').
'$type_extension'(prolog,'.yap').
'$type_extension'(prolog,'.pl').
'$type_extension'(prolog,'').
'$type_extension'(source,'.yap').
'$type_extension'(source,'.pl').
'$type_extension'(source,'').
'$type_extension'(executable,'.so').
'$type_extension'(executable,'').
'$type_extension'(qlf,'.qlf').
'$type_extension'(qlf,'').
'$type_extension'(directory,'').
'$add_path'(File,File).
'$add_path'(File,PFile) :-
recorded('$path',Path,_),
atom_concat([Path,File],PFile).
'$extend_path_directory'(Name, D, File, Opts, NewFile, Call) :-
user:file_search_path(Name, Dir),
'$extend_pathd'(Dir, D, File, Opts, NewFile, Call).
'$extend_pathd'(Dir, A, File, Opts, NFile, Call) :-
atom(Dir), !,
atom_concat([Dir,A,File],NFile),
'$search_in_path'(NFile, Opts, NewFile), !.
'$extend_pathd'(Name, A, File, Opts, OFile, Goal) :-
nonvar(Name),
Name =.. [N,P0],
atom_concat([P0,A,File],NFile),
NewName =.. [N,NFile],
'$find_in_path'(NewName, Opts, OFile, Goal).

View File

@ -193,15 +193,17 @@ yap_flag(enhanced,off) :- set_value('$enhanced',[]).
%
% SWI compatibility flag
%
yap_flag(generate_debug_info,X) :-
yap_flag(generate_debugging_info,X) :-
var(X), !,
'$access_yap_flags'(18,Options),
(Options =:= 0 -> X = false ; X = true ).
yap_flag(generate_debug_info,true) :- !,
'$set_yap_flags'(18,1).
yap_flag(generate_debug_info,false) :- !,
'$set_yap_flags'(18,0).
yap_flag(generate_debug_info,X) :-
yap_flag(generate_debugging_info,true) :- !,
'$set_yap_flags'(18,1),
source.
yap_flag(generate_debugging_info,false) :- !,
'$set_yap_flags'(18,0),
no_source.
yap_flag(generate_debugging_info,X) :-
'$do_error'(domain_error(flag_value,generate_debugging_info+X),yap_flag(generate_debugging_info,X)).
%
@ -557,6 +559,17 @@ yap_flag(toplevel_hook,X) :-
yap_flag(toplevel_hook,G) :- !,
'$set_toplevel_hook'(G).
yap_flag(unix,true) :-
'$unix', !.
yap_flag(unix,false).
yap_flag(windows,true) :-
'$win32', !.
yap_flag(windows,false).
yap_flag(shared_object_search_path,P) :-
'$ld_path'(P).
yap_flag(typein_module,X) :-
var(X), !,
'$current_module'(X).
@ -691,7 +704,7 @@ yap_flag(max_threads,X) :-
V = gc ;
V = gc_margin ;
V = gc_trace ;
V = generate_debug_info ;
V = generate_debugging_info ;
% V = hide ;
V = home ;
V = host_type ;
@ -703,11 +716,13 @@ yap_flag(max_threads,X) :-
V = max_arity ;
V = max_integer ;
V = max_tagged_integer ;
V = max_threads ;
V = min_integer ;
V = min_tagged_integer ;
V = n_of_integer_keys_in_db ;
V = profiling ;
V = redefine_warnings ;
V = shared_object_search_path ;
V = single_var_warnings ;
V = stack_dump_on_error ;
V = strict_iso ;
@ -717,6 +732,7 @@ yap_flag(max_threads,X) :-
V = toplevel_hook ;
V = toplevel_print_options ;
V = typein_module ;
V = unix ;
V = unknown ;
V = update_semantics ;
V = user_error ;
@ -724,8 +740,8 @@ yap_flag(max_threads,X) :-
V = user_output ;
V = verbose_auto_load ;
V = version ;
V = write_strings;
V = max_threads
V = windows ;
V = write_strings
),
yap_flag(V, Out).

View File

@ -11,8 +11,13 @@
* File: errors.yap *
* comments: error messages for YAP *
* *
* Last rev: $Date: 2007-01-24 14:20:04 $,$Author: vsc $ *
* Last rev: $Date: 2007-09-27 15:25:34 $,$Author: vsc $ *
* $Log: not supported by cvs2svn $
* Revision 1.80 2007/01/24 14:20:04 vsc
* Fix typos across code
* Change debugger to backtrack more alike byrd model
* Fix typo in debugger option f
*
* Revision 1.79 2006/12/13 16:10:26 vsc
* several debugger and CLP(BN) improvements.
*
@ -631,8 +636,8 @@ print_message(Level, Mss) :-
'$output_error_message'(existence_error(array,F), W) :-
format(user_error,'% EXISTENCE ERROR- ~w could not open array ~w~n',
[W,F]).
'$output_error_message'(existence_error(mutex,F), W) :-
format(user_error,'% EXISTENCE ERROR- ~w could not open mutex ~w~n',
'$output_error_message'(existence_error(file,F), W) :-
format(user_error,'% EXISTENCE ERROR- ~w could not open file ~w~n',
[W,F]).
'$output_error_message'(existence_error(library,F), W) :-
format(user_error,'% EXISTENCE ERROR- ~w could not open library ~w~n',
@ -640,6 +645,9 @@ print_message(Level, Mss) :-
'$output_error_message'(existence_error(message_queue,F), W) :-
format(user_error,'% EXISTENCE ERROR- ~w could not open message queue ~w~n',
[W,F]).
'$output_error_message'(existence_error(mutex,F), W) :-
format(user_error,'% EXISTENCE ERROR- ~w could not open mutex ~w~n',
[W,F]).
'$output_error_message'(existence_error(procedure,P), context(Call,Parent)) :-
format(user_error,'% EXISTENCE ERROR- procedure ~w is undefined, called from context ~w~n% Goal was ~w~n',
[P,Parent,Call]).

View File

@ -99,8 +99,14 @@ yap_hacks:cut_by(CP) :- '$$cut_by'(CP).
:- dynamic user:library_directory/1.
user:library_directory(D) :-
prolog:'$system_library_directories'(D).
:- (
prolog:'$system_library_directories'(D),
write(D),nl,
assert(user:library_directory(D)),
fail
;
true
).
%
% cleanup ensure loaded and recover some data-base space.
@ -135,8 +141,12 @@ user:library_directory(D) :-
:- dynamic file_search_path/2.
file_search_path(library, Dir) :-
library_directory(Dir).
library_directory(Dir).
file_search_path(swi, Home) :-
current_prolog_flag(home, Home).
file_search_path(yap, Home) :-
current_prolog_flag(home, Home).
file_search_path(system, Dir) :-
prolog_flag(host_type, Dir).
prolog_flag(host_type, Dir).
file_search_path(foreign, yap('lib/Yap')).

View File

@ -965,15 +965,6 @@ at_end_of_line(S) :-
consult_depth(LV) :- '$show_consult_level'(LV).
absolute_file_name(V,Out) :- var(V), !,
'$do_error'(instantiation_error, absolute_file_name(V, Out)).
absolute_file_name(user,user) :- !.
absolute_file_name(RelFile,AbsFile) :-
'$find_in_path'(RelFile,PathFile,absolute_file_name(RelFile,AbsFile)),
'$exists'(PathFile,'$csult', AbsFile), !.
absolute_file_name(RelFile, AbsFile) :-
'$file_expansion'(RelFile, AbsFile).
'$exists'(F,Mode,AbsFile) :-
get_value(fileerrors,V),
set_value(fileerrors,0),
@ -1053,3 +1044,5 @@ current_stream(File, Opts, Stream) :-
throw(Exception).
write_depth(T,L) :- write_depth(T,L,_).