upgrade JPL
git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1936 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
@@ -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
|
||||
*
|
||||
|
Reference in New Issue
Block a user