jpl
Class Query

java.lang.Object
  extended byjpl.Query
All Implemented Interfaces:
java.util.Enumeration

public class Query
extends java.lang.Object
implements java.util.Enumeration

A Query instance is created by an application in order to query the Prolog engine. 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 in which the goal is to be called.

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

The Query class implements the Enumeration interface, and it is through this interface that one obtains 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. For example, if p(a) and p(b) are facts in the Prolog database, then the following is equivalent to printing all the solutions to the Prolog query p(X):

 Variable X = new Variable();
 Term arg[] = { X };
 Query    q = new Query( "p", arg );
 
 while ( q.hasMoreElements() ){
     Term bound_to_x = ((Hashtable)q.nextElement()).get( X );
     System.out.println( bound_to_x );
 }
 
Make sure to close the Query (using the rewind() 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. To obtain just one solution from a Query, use the oneSolution() method. To obtain all solutions, use the allSolutions() method. To determine merely whether the Query is provable, use the query() method (soon to be deprecated in favour of hasSolution()). (i.e. has at least one solution).
Copyright (C) 2004 Paul Singleton

Copyright (C) 1998 Fred Dushin

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.

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.


Version:
$Revision: 1.2 $

Constructor Summary
Query(java.lang.String text)
          This constructor builds a Query from the given Prolog source text
Query(java.lang.String text, Term arg)
           
Query(java.lang.String text, Term[] args)
          If text denotes an atom, this constructor is shorthand for new Query(new Compound(name,args)), 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.
Query(Term t)
          This constructor creates a Query whose goal is the specified Term.
 
Method Summary
 int abort()
           
 java.util.Hashtable[] allSolutions()
          calls the Query's goal to exhaustion and returns an array containing every solution (in the order in which they were found).
 Term[] args()
          Deprecated. Use .goal().args() instead.
 void 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.
 java.lang.String debugString()
          Deprecated.  
 java.util.Hashtable 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.
 java.util.Hashtable getSubstWithNameVars()
           
 Compound goal()
          Returns the Compound (hence perhaps an Atom) which is the goal of this Query
 boolean hasMoreElements()
          This method is completes the java.util.Enumeration interface.
 boolean hasMoreSolutions()
          This method returns true if JPL was able to initiate a "call" of this Query within the Prolog engine.
 boolean hasSolution()
          JPL will attempt to call this Query's goal within the attached Prolog engine.
 java.lang.String name()
          Deprecated. Use .goal().name() instead.
 java.lang.Object nextElement()
          This method completes the java.util.Enumeration interface.
 java.util.Hashtable nextSolution()
          This method returns a java.util.Hashtable, which represents a binding from the names of query variables to terms within the solution.
 java.util.Hashtable oneSolution()
          Returns the first solution, if any, as a (possibly empty) Hashtable.
 void open()
          This method returns true if JPL was able to initiate a "call" of this Query within the Prolog engine.
 boolean query()
          Deprecated. Use .hasSolution() instead. JPL will attempt to call this Query's goal within the attached Prolog engine.
 void rewind()
           
 java.lang.String toString()
          Returns the String representation of a Query.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

Query

public Query(Term t)
This constructor creates a Query whose goal is the specified Term. The Query is initially closed. NB Creating an instance of the Query class does not result in a call to a Prolog engine. NB The goal can be an Atom (Atom extends Compound), but cannot be an instance of jpl.Float, jpl.Integer or jpl.Variable.

Parameters:
t - the goal of this Query

Query

public Query(java.lang.String text,
             Term[] args)
If text denotes an atom, this constructor is shorthand for new Query(new Compound(name,args)), 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.

Parameters:
text - the name of the principal functor of this Query's goal
args - the arguments of this Query's goal

Query

public Query(java.lang.String text,
             Term arg)

Query

public Query(java.lang.String text)
This constructor builds a Query from the given Prolog source text

Parameters:
text - the Prolog source text of this Query
Method Detail

name

public final java.lang.String name()
Deprecated. Use .goal().name() instead.

Returns:
the name of this Query's goal (redundant, deprecated)

args

public final Term[] args()
Deprecated. Use .goal().args() instead.

Returns:
the arguments of this Query's goal (redundant, deprecated)

goal

public final Compound goal()
Returns the Compound (hence perhaps an Atom) which is the goal of this Query

Returns:
a Term representing the goal of this Query

hasMoreSolutions

public final boolean 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 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
 Query q = // obtain Query reference
 while ( q.hasMoreSolutions() ){
     Hashtable solution = q.nextSolution();
     // process solution...
 }
 
To ensure thread-safety, you should wrap sequential calls to this method in a synchronized block, using the static lock method to obtain the monitor.
 Query q = // obtain Query reference
 synchronized ( jpl.Query.lock() ){
     while ( q.hasMoreElements() ){
          Hashtable solution = q.nextSolution();
          // process solution...
     }
 }
 

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.

Returns:
true if the Prolog query succeeds; otherwise false.

open

public final void open()
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 with the getSolution() and close() methods to retrieve one or more substitutions in the form of Hashtables. To ensure thread-safety, you should wrap sequential calls to this method in a synchronized block, using the static lock method to obtain the monitor.
 Query q = // obtain Query reference
 synchronized ( jpl.Query.lock() ){
     while ( q.hasMoreElements() ){
          Hashtable solution = q.nextSolution();
          // process solution...
     }
 }
 

If this method is called on an already-open Query, or if the query cannot be set up for whatever reason, then a JPLException will be thrown.


getSolution

public final java.util.Hashtable 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.

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.

 Variable X = new Variable();
 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 );
     // ...
 }
 
Programmers should obey the following rules when using this method.
  • 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.
  • The nextSolution() and hasMoreSolutions() should be called in the same thread of execution, at least for a given Query instance.
  • 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.
  • 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.

    Returns:
    A Hashtable representing a substitution, or null

    getSubstWithNameVars

    public final java.util.Hashtable getSubstWithNameVars()

    nextSolution

    public final java.util.Hashtable 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.

    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.

     Variable X = new Variable();
     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 );
         // ...
     }
     
    Programmers should obey the following rules when using this method.
  • 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.
  • The nextSolution() and hasMoreSolutions() should be called in the same thread of execution, at least for a given Query instance.
  • 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.
  • 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.

    Returns:
    A Hashtable representing a substitution.

    hasMoreElements

    public final boolean hasMoreElements()
    This method is completes the java.util.Enumeration interface. It is a wrapper for hasMoreSolutions.

    Specified by:
    hasMoreElements in interface java.util.Enumeration
    Returns:
    true if the Prolog query succeeds; false, o/w.

    nextElement

    public final java.lang.Object nextElement()
    This method completes the java.util.Enumeration interface. It is a wrapper for nextSolution.

    This method will throw a QueryInProgressException if another Query (besides this one) is in progress while this method is called.

    Specified by:
    nextElement in interface java.util.Enumeration
    Returns:
    A Hashtable representing a substitution.

    rewind

    public final void rewind()

    close

    public final void 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.

    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:

     Query q = new Query( predicate, args );
     int i = 0;
     for ( int i = 0; i < 3 && q.hasMoreSolutions();  ++i ){
         Hasthable sub = (Hashtable) q.nextSolution();
         ...
     }
     q.close();
     


    allSolutions

    public final java.util.Hashtable[] allSolutions()
    calls the Query's goal to exhaustion and returns an array containing every solution (in the order in which they were found).

    Returns:
    an array of Hashtables (possibly none), each of which is a solution (in the order in which they were found) of the Query. NB 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, the quantity of solutions).

    This method will throw a QueryInProgressException if this or another Query is already open.

    See Also:
    hasMoreElements(), nextElement(), hasMoreSolutions(), nextSolution(), rewind(), oneSolution(), allSolutions(), query()

    oneSolution

    public final java.util.Hashtable oneSolution()
    Returns the first solution, if any, as a (possibly empty) Hashtable. 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.

    Returns:
    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.

    See Also:
    hasMoreElements(), nextElement(), hasMoreSolutions(), nextSolution(), rewind(), oneSolution(), allSolutions(), query()

    query

    public final boolean query()
    Deprecated. Use .hasSolution() instead. JPL will attempt to call this Query's goal within the attached Prolog engine.

    Returns:
    the provability of the Query, i.e. 'true' if it has at least one solution, 'false' if the call fails without finding a solution.

    Only the first solution (if there is one) will be found; any bindings will be discarded, and the Query will be closed.

    This method will throw a QueryInProgressException if this or another Query is already open.

    See Also:
    hasMoreElements(), nextElement(), hasMoreSolutions(), nextSolution(), rewind(), oneSolution(), allSolutions(), query()

    hasSolution

    public final boolean hasSolution()
    JPL will attempt to call this Query's goal within the attached Prolog engine.

    Returns:
    the provability of the Query, i.e. 'true' if it has at least one solution, 'false' if the call fails without finding a solution.

    Only the first solution (if there is one) will be found; any bindings will be discarded, and the Query will be closed.

    This method will throw a QueryInProgressException if this or another Query is already open.

    See Also:
    hasMoreElements(), nextElement(), hasMoreSolutions(), nextSolution(), rewind(), oneSolution(), allSolutions(), query()

    abort

    public final int abort()

    toString

    public java.lang.String toString()
    Returns the String representation of a Query.

    Returns:
    the String representation of a Query

    debugString

    public java.lang.String debugString()
    Deprecated.  

    Returns a debug-friendly representation of a Query

    Returns:
    a debug-friendly representation of a Query