\chapter{Standard Predicates} \label{standard}
%=============================================

This chapter describes standard predicates, which are always available
to the Prolog interpreter, and do not need to be imported or loaded
explicitly as do other Prolog predicates.  By default, it is a
compiler error to redefine standard predicates.  This behavior can be
overridden by allowing explicit redefinition of standard predicates
(see Section~\ref{}); or alternatively the set of standard predicates
can be easily reconfigured (Section~\ref{}).

In the description below, certain standard predicates depend on HiLog
semantics; the description of such predicates have the token {\sf
HiLog} at the right of the page.  Similarly predicates that depend on
SLG evaluation are marked as {\sf Tabling}, and predicates whose
semantics is defined by the ISO standard (or whose implementation is
reasonably close to that definition) are marked as {\tt ISO}.
Occasionally, however, we include in this section predicates that are
not standard.  In such cases we denote their module in {\tt text} font
towards the middle of the page.

\paragraph*{A Note on Types} \label{sec:types}

Numerous proposals have been made concerning typing systems for Prolog
for the purposes of program analysis, correctness checking, etc.
Analysis-based typing systems are typically lattice-based, following
from their need to compare types to understand whether one type
includes another, or from the need to determine the most specific type
that is more general than two types.  In addition the ISO standard
specifies various types of allowable input or output arguments for
various predicates.

\version{} of XSB has the following approach to program typing.
Typing in an XSB program is done through a {\em type lattice},
generated by {\em primitive type elements}.  How a promitive type is
defined is somewhat separate from how it is used by a type lattice.
For our purposes we assume that each 1-ary type element is defined by
a predicate of arity 1 that is written in a pure enough style so that
its success or failure does not depend on the state of XSB or of any
external state.  Whether these types are recursive or not has no
bearing on the type lattice.  For instance, {\tt integer} or {\tt
listOfAtoms} are primitive type elements.  Similarly, {\tt variable},
{\tt ground} are also type elements.  We say that a given term {\tt
Term} satisfies a primitive type element {\tt t} if {\tt t(Term)}
succeeds.  Given primitive type elements, complex type elements can be
formed using the boolean operations, {\tt and}, {\tt or} and {\tt
not}.  As an example, {\tt integer or not(listOfAtoms)} is a
non-primitive type element.  There is also a product operation ({\tt
,}) on type elements, so that {\tt variable, integer or
not(listOfAtoms)} is a product of the above two types.  
Satisfiability is extended to complex type elements in the obvious
manner, and an n-ary typle of terms satisfies a n-ary product type if
each argument in the tuple satisfies the corresponding argument of the
product type.

The above description is not yet suitable for a type system as it
could not determine, for instance, that {\tt integer} is a subtype of
{\tt number}.  To determine this, an explicit {\em inclusion
statement} can be made indicating that one type is included in
another.  Thus given two elements in a type lattice with inclusion
statements, determining whether one element is more specific than
another can be done using techniques for propositional satisfiability
or stable model generation.

From an implementational level, types can be defined using the Cold
Dead Fish (CDF) package and inclusion can be detected using the CDF
theorem prover or XSB's Smodels inteterface.  However, for the
purposes in this section we use type elements to define inputs and
outputs of predicates, via {\tt usage statements}.  A usage statement
for an n-ary predicate {\tt p/n} consists of an n-ary product of
primitive types that should be satisfied on a call to {\tt p/n} along
with a n-ary product of primitive types that should hold on success of
{\tt p/n} given the types that hold at call.  If both the the product
types hold, the usage statement is satisfied.  Each successful call to
{\tt p/n} should satisfy one of the usage statements.

As defined, usage statements are very general: they can check not only
traditional Prolog types ({\tt atom}, {\tt integer}, etc), but also
non-Prolog types, such as the fact that the input to a given argument
should be a positive integer, and even instantiation patterns.  For
the various predicates defined in this section, we use the following
conventions for usages and error reporting.  {\bf domain}, {\bf type}
and {\bf instantiation} errors arise from the failure of an argument
of a predicate to satisfy the corresponding type element in the input
term of the usage statements.  All of these could be called type
errors given the system described above.  However to conform to other
Prologs we reserve the {\bf instantiation error} to mean failure that
occurs when an argument does not satisfy a type in a boolean lattice
generated by {\tt var} and {\tt ground}.  A {\bf type error} occurs
when an argument does not satisfy a type in a boolean lattice
generated by other ISO types, such as {\tt integer}, {\tt atom}, etc.
A {\bf domain error} arises from other such errors.  We note that in
certain cases, our designation of an error type may differ from the
ISO standard.

%--------------------------------------------------------------------------------------------------
\section{Input and Output}

XSB's I/O is based on ISO-style streams, although it also supports
older DEC-10 style file handling.  The use of streams provides a
unified interface to a number of different classes of sources and
sinks.  Currently these classes include textual and binary files,
console input and output, pipes, and atoms; in the future sockets and
urls may be handled under the stream interface.  When streams are
opened, certain actions may occur depending on the class of the source
or sink and on the wishes of the user.  For instance when a file {\tt
F} is opened for output mode, an existing file {\tt F} may be
truncated (in write mode) or not (in append mode).  In addition,
various operations may or may not be valid depending on the class of
stream.  For instance, repositioning is valid for an atom or file but
not a pipe or console.

XSB provides several default I/O streams, which make it easier for a
user to embed XSB in other applications.  These streams include the
default input and output streams.  They also include the standard
error stream, to which XSB writes all error messages.  By default the
standard error stream is the same as the standard output stream, but
it can be redirected either by UNIX shell-style I/O redirection or by
the predicates {\tt file\_reopen/4} and {\tt file\_clone/3}.
Similarly there is the standard warning stream (to which all system
warnings are written), the standard debugging stream (to which
debugging information is written), and the standard feedback stream
(for interpreter prompts, yes/no answers, etc).  All of these streams
are aliased by default to standard output, and can be redirected by
the predicates the predicates {\tt file\_reopen/4} and {\tt
file\_clone/3}.

Streams may also be aliased: the default input and output streams can
be denoted by {\tt user\_in} and {\tt user\_out} and they refer to the
process'es standard input and standard output streams. \footnote{For
backwards compatability, the default input stream can also be aliased
by {\tt user} or {\tt userin}, and the default output stream by {\tt
user} or {\tt userout}.}.

Streams are distinguished by their {\tt class} -- whether they are
file or atom, etc.; as well as by various properties.  These
properties include whether a stream is positionable or not and whether
a (file) stream is textual or binary.

\bi
\item {\tt Console} The default streams mentioned above are
console streams, which are textual and not repositionable.
%
\item {\tt File}  A file stream corresponds to an operating system
file and is repositionable.  On Windows, binary files and textual
files differ, while on UNIX they are the same.  
%
\item {\tt Atom} XSB can read from an atom, just as it can from a file.
Atoms are considered to be textual and repositionable.  Writing to
atoms via streams is not currently available in XSB, although 
the predicate {\tt term\_to\_atom/2} contains some of the
functionality that such streams would provide.
%
\item {\tt Pipe} XSB can also open pipes either directly, or as part
of its ability to spawn processes.  When made into streams, pipes are
textual and not repositionable.
\ei

%------------------------------------------------------------------------------------------------
\subsection{I/O Stream Implementation}

A user may note that XSB's I/O streams are small integers, but they
should not be confused with the file descriptors used by the OS.  The
OS file descriptors are objects returned by the C {\tt open} function;
XSB I/O streams indices into the internal XSB table of open files and
associated information. The OS does not know about XSB I/O streams,
while XSB (obviously) does know about the OS file descriptors. An OS
file descriptor may be returned by certain predicates (e.g.  {\tt
pipe\_open/2} or user-defined I/O).  In the former case, a file
descriptor can be promoted to XSB stream by {\tt open/\{3,4\}} and in
the latter by using the predicate {\tt fd2iostream/2}.

When it starts, XSB opens a number of standard I/O streams that it
uses to print results, errors, debugging info, etc. The descriptors
are described in the file {\tt prolog\_includes/standard.h}. This file
provides the following symbolic definitions:
%%
\begin{verbatim}
    #define STDIN            0
    #define STDOUT           1
    #define STDERR           2
    #define STDWARN          3    /* output stream for xsb warnings  */
    #define STDMSG           4    /* output for regular xsb messages */
    #define STDDBG           5    /* output for debugging info       */
    #define STDFDBK          6    /* output for XSB feedback
                                     (prompt/yes/no/Aborting/answers) */

    #define AF_INET     0     /* XSB-side socket request for Internet domain */
    #define AF_UNIX     1     /* XSB-side socket request for UNIX domain */
\end{verbatim}
%%
%------------------------------------------------------------------------------------------
\comment{
In addition, the file \verb|emu/file_modes_xsb.h| provides the definitions
for the file opening modes:
%%
\begin{verbatim}
    #define OREAD          0    /* open for read           */
    #define OWRITE         1    /* open for write          */
    #define OAPPEND        2    /* open for append         */
    #define OSTRINGR       3    /* open string for reading */
    #define OSTRINGW       4    /* open string for writing (not implemented) */
\end{verbatim}
%%
}
%------------------------------------------------------------------------------------------
These definitions can be used in user programs, if the following is
provided at the top of the source file:
%%
\begin{verbatim}
    compiler_options([xpp_on]).
    #include "standard.h"
\end{verbatim}
%%
(Note: the XSB preprocessor is not invoked on clauses typed into an
interactive XSB session, so the above applies only to programs loaded from
a file using {\tt consult} and such.)

\subsection{ISO Streams}

\begin{description}

\ournewitem{open(+SourceSink,+Mode,-Stream)}{ISO}\index{\texttt{open/3}}
%
{\tt open/1} creates a stream for the source or sink designated in
{\tt SourceSink}, and binds {\tt Stream} to a structure representing
that stream.  
%
\bi
\item If {\tt SourceSink} is an atom, or the term {\tt file(File)}
where {\tt File} is an atom, the stream is a file stream.  In this
case {\tt Mode} can be 
\bi
\item {\tt read} to create an input stream.  In Windows, whether the
file is textual or binary is determined by the file's properties.
%
\item {\tt write} to create an output stream.  Any previous file with
a similar path is removed and a (textual) file is created which becomes
a record of the output stream.  
%
\item {\tt write\_binary} to create an output stream.  Any previous file with
a similar path is removed and a file is created which becomes
a record of the output stream.  The file created is binary in Windows,
while in UNIX {\tt write\_binary} has the same effect as {\tt write}.
%
\item {\tt append} to create an output stream.  In this case the
output stream is appended to the contents of the file, if it exists,
and otherwise a new file is created for (textual) ouput
%
\item {\tt append\_binary} to create an output stream.  In this case the
output stream is appended to the contents of the file, if it exists,
and otherwise a new file is created for (binary) ouput
\ei
\item If {\tt SourceSink} is the term {\tt atom(Atom)} where {\tt
Atom} is an atom, the stream is an atom stream.  In this case {\tt
Mode} currently can only be {\tt read}.  This stream class, which
reads from interned atoms, is analogous to C's {\tt sscanf()}
function.
%
\item If {\tt SourceSink} is the term {\tt pipe(FIleDescriptor)}
where {\tt FileDescriptor} is an integer, then a pipe stream is opened
in the mode for {\tt FileDescriptor}.
\ei

\compatability This predicate extends the ISO definition of {\tt
open/3} to include strings and pipes as well as the file modes {\tt
write\_binary} and {\tt append\_binary}.

{\bf Error Cases}
\bi
\item 	{\tt SourceSink} or {\tt Mode} is not instantiated
\bi
\item 	{\tt instantiation\_error}
\ei
%
\item 	{\tt Mode} is not a valid I/O mode
\bi
\item 	{\tt domain\_error(io\_mode,Mode)}
\ei
%
\item 	{\tt SourceSink} is a file and cannot be opened, or opened in
the desired mode 
\bi
\item 	{\tt permission\_error(open,file,SourceSink)}
\ei
\ei

\ournewitem{open(+File,+Mode,-Stream.+Options)}{ISO}\index{\texttt{open/4}}
%
{\tt open/4} behaves as does {\tt open/3}, but allows a list of
options to be given.  The option {\tt alias(A)} allows the stream to
be aliased to an atom {\tt A}.  The ISO option {\tt type(T)} has no
effect on file streams in UNIX, which are always textual, but in
Windows if {\tt T} is {\tt binary} a binary file is opened.  The ISO
option {\tt reposition(Boolean)} currently has no effect on streams,
because whether or not the stream is repositionable or not depends on
the stream class.  And finally, the ISO option {\tt
eof\_action(Action)} currently has no effect on file streams.
Appropriate warnings are given if an option list includes these option
types.

{\bf Error Cases}  Error cases are the same as {\tt open/3} but with
the addition: 
\bi
\item {\tt Option\_list} contains an option {\tt O} that is not a stream
option.
\bi
\item {\tt domain\_error(stream\_option,O)}
\ei
\ei

\ournewitem{close(+Stream\_or\_alias.+OptionsList)}{ISO}\index{\texttt{close/2}}
%
{\tt close/2} closes the stream or alias {\tt Stream\_or\_alias}.
{\tt OptionsList} allows the user to declare whether a permission
error will be raised in XSB upon a resource or system error from the
closing function (e.g. {\tt fclose()} or other system function).  If
{\tt OptionsList} is non-empty and contains only terms unifying with
{\tt force(true)} then such an error will be ignored (possibly leading
to unacknowledged loss of data).  Otherwise, a permission error is
thrown if {\tt fclose()} or other system function returns an error
condition.  If the stream class of {\tt Stream\_or\_alias} is an atom,
then the only action taken is to close the stream itself -- the
interned atom itself is not affected.

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\item {\tt OptionList} contains an option {\tt O} that is not a closing
option.
\bi
\item {\tt domain\_error(close\_option,O)}
\ei
\item {\tt OptionList} contains conflicting options
\bi
\item {\tt domain\_error(close\_option,OptionList)}
\ei
\item 	Closing the stream produces an error (and {\tt OptionsList} is
	a non-empty list containing terms of the form {\tt force(true)}).
\bi
\item 	{\tt permission\_error(close,file,Stream\_or\_alias)}
\ei
\ei

\ournewitem{close(+Stream\_or\_alias)}{ISO}\index{\texttt{close/1}}
%
{\tt close/1} closes the stream or alias {\tt Stream\_or\_alias}.
Behaves as  {\tt close(Stream\_or\_alias,[force(false)])}.

\ournewitem{set\_input(+Stream\_or\_alias)}{ISO}\index{\texttt{set\_input/1}}
    Makes file {\tt Stream\_or\_alias} the current input stream. 

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term
or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not an open input stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei

\ournewitem{set\_output(+Stream\_or\_alias)}{ISO}\index{\texttt{set\_output/1}}
    Makes file {\tt Stream\_or\_alias} the current output stream. 

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term
or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open output stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei

\ournewitem{stream\_property(?Stream,?Property)}{ISO}
\index{\texttt{stream\_property/2}}
%
This predicate backtracks through the various stream properties that
unifiy with {\tt Property} for the stream {\tt Stream}.  Currently,
the following properties are defined.

\bi
\item {\tt stream\_class(C)} gives the stream class for a file:
i.e. {\tt file}, {\tt atom}, {\tt console} or {\tt pipe}.

\item {\tt file\_name(F)} is a property of {\tt Stream}, if
{\tt Stream} is a file stream and {\tt F} is the file name
associate with {\tt Stream}.  The full operating system
path is used.
%
\item {\tt type(T)} is a property of {\tt Stream}, if
{\tt Stream} is a file stream and {\tt T} is the file type
of {\tt Stream}: {\tt text} or {\tt binary}.
%
\item {\tt mode(M)} is a property of {\tt Stream}, if {\tt
M} represents the I/O mode with which {\tt Stream} was
opened: i.e. {\tt read}, {\tt write}, {\tt append}, {\tt
write\_binary}, etc., as appropriate for the class of {\tt
Stream}.
%
\item {\tt alias(A)}  is a property of {\tt Stream}, if
{\tt Stream} was opened with alias {\tt A}.
%
\item {\tt input}  is a property of {\tt Stream}, if {\tt
Stream} was opened in the I/O mode: {\tt read}.
% 
\item {\tt output}  is a property of {\tt Stream}, if {\tt
Stream} was opened in the I/O mode: {\tt write}, {\tt
append}, {\tt write\_binary}, or {\tt append\_binary}.
%
\item {\tt reposition(Bool)} is true, if {\tt Stream} is
repositionable, and false otherwise. 
%
\item {\tt end\_of\_stream(E)} returns {\tt at} if the end of stream
condition for {\tt Stream} is true, and {\tt not} otherwise.
%
\item {\tt position(Pos)} returns the current position of the stream
as determined by {\tt fseek{}} or the byte-offset of the current
stream within an atom.  In either case, if an end-of-strem condition
occurs, the token {\tt end\_of\_file} is returned.
%

%
\item {\tt eof\_action(Action)} is {\tt reposition} if the stream class
is {\tt console}, {\tt eof\_code} if the stream class is {\tt file},
and {\tt error} is the stream class is {\tt pipe} or {\tt atom}.
\end{itemize}

\ournewitem{flush\_output(+Stream\_or\_alias)}{ISO}
\index{\texttt{flush\_output/1}}
%
Any buffered data in {\tt Stream\_or\_aias}  gets flushed.  If
{\tt Stream} is not buffered (i.e. if it is of class {\tt
atom}), no action is taken.

{\bf Error Cases}
\bi
\item 	{\tt Stream} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream,Stream)}
\ei
\item 	{\tt Stream} is not associated with an open output stream 
\bi
\item 	{\tt existence\_error(stream,Stream)}
\ei
\item 	Flushing (i.e. {\tt fflush()}) returns an error.
\bi
\item 	{\tt permission\_error(flush,stream,Stream)}
\ei
\ei

\ournewitem{flush\_output}{ISO}
\index{\texttt{flush\_output/0}}
%
Any buffered data in the current output stream gets flushed.

\ournewitem{set\_stream\_position(+Stream\_or\_alias,+Position)}{ISO}
\index{\texttt{set\_stream\_position/2}}
%
If the stream associated with {\tt Stream\_or\_alias} is
repositionable (i.e. is a file or atom), sets the stream position
indicator for the next input or output operation. Position is a
positive integer, taken to be the number of bytes the stream is to be
placed from the origin.

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term
or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Position} is not instantiated to a positive integer.
\bi
\item 	{\tt domain\_error(stream\_position,Position)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not repositionable, or
	repositioning returns an error. 
\bi
\item 	{\tt permission\_error(resposition,stream,Stream\_or\_alias)}
\ei
\ei

\ournewitem{at\_end\_of\_stream(+Stream\_or\_alias)}{ISO}
\index{\texttt{at\_end\_of\_stream/1}}
%
Succeeds if {\tt Stream\_or\_alias} has position at or past the end of
stream.

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term
or aliasl
\bi
\item 	{\tt domain\_error(stream,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not an open stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei
%

\ournewitem{at\_end\_of\_stream}{ISO}
\index{\texttt{at\_end\_of\_stream/0}}
%
Acts as {\tt at\_end\_of\_stream/1} but using the current input
stream.

\end{description}

\subsubsection{Other Predicates using ISO Streams}

\begin{description}

\ouritem{file\_reopen(+FileName,+Mode,+Stream,-RetCode)}
\index{\texttt{file\_reopen/1}}
    Takes an existing I/O stream, closes it, then opens it and
    attaches it to a file. This can be used to redirect I/O from any of the
    standard streams to a file. For instance, 
%%
\begin{verbatim}
    | ?- file_reopen('/dev/null', w, 3, Error).
\end{verbatim}
%%
    redirects all warnings to the Unix black hole. 

    On success, {\tt RetCode} is 0; on error, the return code is negative.

%-----------------------------------------------------------------------------
\comment{
% will be superceded by stream_property.
\ournewitem{file\_pos(+Stream, -Position)}{file\_io}
\index{\texttt{file\_pos/2}}
    Unifies {\tt Position} with the position inside the file indicated by
    {\tt IOport}.
}
%-----------------------------------------------------------------------------

\ouritem{file\_clone(+SrcStream,?DestStream,-RetCode)}
\index{\texttt{file\_clone/1}}
This is yet another way to redirect I/O. It is a Prolog interface to
the C {\tt dup} and {\tt dup2} system calls. If {\tt DestStream} is a
variable, then this call creates a new XSB I/O stream that is a clone
of {\tt SrcStream}. This means that I/O sent to either stream goes
to the same place. If {\tt DestStream} is not a variable, then it must
be a number corresponding to a valid I/O stream. In this case, XSB
closes {\tt DestStream} and makes it into a clone of {\tt
SrcStream}. 

For instance, suppose that 10 is a I/O Stream that is currently open
for writing to file {\tt foo.bar}.  Then 
%%
\begin{verbatim} 
| ?- file_clone(10,3,_).  
\end{verbatim} 
%% 
causes all messages sent to XSB standard warnings stream to go to file
{\tt foo.bar}. While this could be also done with {\tt file\_reopen},
there are things that only {\tt file\_clone} can do: 
%%
\begin{verbatim} 
| ?- file_clone(1,10,_). 
 \end{verbatim} 
%% 
This means that I/O stream 10 now becomes clone of standard
output. So, all subsequent I/O will now go to standard output instead
of {\tt foo.bar}.

On success, {\tt RetCode} is 0; on error, the return code is negative.

%-----------------------------------------------------------------------------

\ourmoditem{file\_truncate(+Stream, +Length, -Return)}{file\_io}
\index{\texttt{file\_truncate/3}}
    The regular file  referenced by the Stream{\tt Stream}
    is chopped to have the size of {\tt Length} bytes. Upon successful
    completion {\tt Return} is set to zero.

\portability This predicate is not defined on Windows unless compiled
using Cygwin.

\ouritem{tmpfile\_open(-Stream)}\index{\texttt{tmpfile\_open/1}}
    Opens a temporary file with a unique filename. The file is deleted when
    it is closed or when the program terminates.

\end{description}

\subsection{DEC-IO Style File Handling}

\begin{description}
\ouritem{see(+F)}\index{\texttt{see/1}}
    Makes file {\tt F} the current input stream. 
    \begin{itemize}
    \item If there is an open input stream associated with the file that 
          has {\tt F} as its file name, and that stream was opened previously
	  by {\tt see/1}, then it is made the current input stream.
    \item Otherwise, the specified file is opened for input and made the
          current input stream. If the file does not exist, {\tt see/1} 
	  fails.
    \end{itemize}
    Also note that different file names (that is, names which do not unify) 
    represent different input streams (even if these different file names 
    correspond to the same file).

    Exceptions:
    \begin{description}
    \item[{\tt permission\_error}]
    	File {\tt F} is directory or file is not readable. 
    \item[{\tt instantiation\_error}]
    	{\tt F} is not instantiated at the time of call. 
    \item[{\tt existence\_error}]
    	File {\tt F} does not exist. 
    \item[{\tt domain\_error}]
    	{\tt F} is not an atomic file identifier
    \end{description}

\ouritem{seeing(?F)}\index{\texttt{seeing/1}}
    {\tt F} is unified with the name of the current input stream.
    This is exactly the same with predicate {\tt current\_input/1}
    described in Section~\ref{State}, and it is only provided for
    upwards compatibility reasons.

\ouritem{seen}\index{\texttt{seen/0}}
    Closes the current input stream. 
    Current input reverts to {\tt ``userin''} (the standard input stream).

\ouritem{tell(+F)}\index{\texttt{tell/1}}
    Makes file {\tt F} the current output stream. 
    \begin{itemize}
    \item If there is an open output stream associated with {\em F}  
          and that was opened previously 
          by {\tt tell/1}, then that stream is made the current output 
	  stream. 
    \item Otherwise, the specified file is opened for output and made the
          current output stream. If the file does not exist, it is created.
    \end{itemize}

    Also note that different file names (that is, names which do not unify) 
    represent different output streams (even if these different file names 
    correspond to the same file).

    The implementation of the ISO preducate {\tt set\_output/1}, is
    essentially that of {\tt tell/1}.

    Exceptions:
    \begin {description}
    \item[{\tt permission\_error}]
	File {\tt F} does not have write permission, or is a directory.
    \item[{\tt instantiation\_error}]
	{\tt F} is uninstantiated.
    \item[{\tt domain\_error}]
    	{\tt F} is not an atomic file identifier
    \end{description}

\ouritem{telling(?F)}\index{\texttt{telling/1}}
    {\tt F} is unified with the name of the current output stream.
    This predicate is exactly the same with predicate {\tt current\_output/1}
    described in Section~\ref{State}, and it is only provided for
    upwards compatibility reasons.

\ouritem{told}\index{\texttt{told/0}}
    Closes the current output stream. 
    Current output stream reverts to ``userout'' (the standard output stream).

\ouritem{file\_exists(+F)}\index{\texttt{file\_exists/1}}
    Succeeds if file {\tt F} exists. {\tt F} must be instantiated to
    an atom at the time of the call, or an error message is displayed on
    the standard error stream and the predicate aborts.

    Exceptions:
    \begin {description}
    \item[{\tt instantiation\_error}]
	{\tt F} is uninstantiated.
    \end{description}

\end{description}


\subsection{Character I/O}
\begin{description}

\ournewitem{nl}{ISO}\index{\texttt{nl/0}}
A new line character is sent to the current output stream.

\ournewitem{nl(+Stream)}{ISO}\index{\texttt{nl/1}}
A new line character is sent to the designated output stream.

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei

%-----------------------------
% Gets

\ournewitem{get\_char(+Stream\_or\_alias,?Char)}{ISO}
\index{\texttt{get\_char/2}}
   Unifies {\tt Char} with the next ASCII character from {\tt
   Stream\_or\_alias}, advancing the position of the stream.  {\tt
   Char} is unified with -1 if an end of file condition is detected.

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open input stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\item 	{\tt Char} is not a variable or character.
\bi
\item 	{\tt domain\_error(character\_or\_variable,Char)}
\ei
\ei

\ournewitem{get\_char(?Char)}{ISO}
\index{\texttt{get\_char/1}}
%
Behaves as {\tt get\_char/2}, but reads from the current input stream.

{\bf Error Cases}
\bi
\item 	{\tt Char} is not a variable or character.
\bi
\item 	{\tt domain\_error(character\_or\_variable,Char)}
\ei
\ei

\ournewitem{get\_code(+Stream\_or\_alias,?Code)}{ISO}
\index{\texttt{get\_code/2}}
   {\tt Code} unifies with the ASCII code of the next character from
   {\tt Stream\_or\_alias}.  The position of the stream is advanced.

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open input stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\item 	{\tt Code} is not a variable or character code
\bi
\item 	{\tt domain\_error(characterCode\_or\_variable,Code)}
\ei
\ei

\ournewitem{get\_code(?Code)}{ISO}
\index{\texttt{get\_code/1}}
Behaves as {\tt get\_code/2}, but reads from the current input stream.

{\bf Error Cases}
\bi
\item 	{\tt Code} is not a variable or character code
\bi
\item 	{\tt domain\_error(characterCode\_or\_variable,Code)}
\ei
\ei

\ouritem{get0(?N)}\index{\texttt{get0/1}} 
    {\tt N} is the ASCII code of the next character read from the
    current input stream (regarded as a text stream). If the current
    input stream reaches its end of file, a {\tt -1} is returned.
    This predicate does not check for errors, so that it is faster
    (and less safe) than, e.g. {\tt get\_code/1}.

\ouritem{get(?N)}\index{\texttt{get/1}} 
    {\tt N} is the ASCII code of the next non-blank printable
    character from the current input stream (regarded as a text
    stream).  If the current input stream reaches its end of file, a
    {\tt -1} is returned.

%------------------------------------
% Peeks

\ournewitem{peek\_char(+Stream\_or\_alias,?Char)}{ISO} 
\index{\texttt{peek\_char/2}}
{\tt Char} is the next ASCII character from {\tt Stream\_or\_alias}.
The position in {\tt Stream\_or\_alias} is unchanged.  {\tt Char} is
unified with -1 if an end of file condition is detected.

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open input stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\item 	{\tt Char} is not a variable or character.
\bi
\item 	{\tt domain\_error(character\_or\_variable,Char)}
\ei
\ei

\ournewitem{peek\_char(?Char)}{ISO} 
\index{\texttt{peek\_char/1}}
{\tt Char} is the next ASCII character from the current input stream.
The position in the current input stream is unchanged.  {\tt Char} is
unified with -1 if an end of file condition is detected.

{\bf Error Cases}
\bi
\item 	{\tt Char} is not a variable or character.
\bi
\item 	{\tt domain\_error(character\_or\_variable,Char)}
\ei
\ei

\ournewitem{peek\_code(+Stream\_or\_alias,?Code)}{ISO} 
\index{\texttt{peek\_code/2}}
{\tt Code} is the next ASCII coder from {\tt Stream\_or\_alias}.
The position in {\tt Stream\_or\_alias} is unchanged.  {\tt Code} is
unified with -1 if an end of file condition is detected.

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open input stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\item 	{\tt Code} is not a variable or character.
\bi
\item 	{\tt domain\_error(characterCode\_or\_variable,Code)}
\ei
\ei

\ournewitem{peek\_code(?Code)}{ISO} 
\index{\texttt{peek\_code/1}}
Behaves as {\tt peek\_code/1}, but the current input stream is used.

{\bf Error Cases}
\bi
\item 	{\tt Char} is not a variable or character.
\bi
\item 	{\tt domain\_error(characterCode\_or\_variable,Code)}
\ei
\ei

%----------------------------------------------
% Puts
%----------------------------------------------

\ournewitem{put\_char(+Stream,+Char)}{ISO}
\index{\texttt{put\_char/2}}
Puts the ASCII character {\tt Char} to {\tt Stream\_or\_alias}.

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open input stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\item 	{\tt Char} is a not a character
\bi
\item 	{\tt type\_error(character,Char)}
\ei
\ei

\ournewitem{put\_char(+Char)}{ISO}
\index{\texttt{put\_char/1}}
Puts the ASCII code of the character {\tt Char} to the current output
stream.

{\bf Error Cases}
\bi
\item 	{\tt Code} is a not a character.
\bi
\item 	{\tt type\_error(character,Char)}
\ei
\ei

\ournewitem{put\_code(+Stream,+Code)}{ISO}
\index{\texttt{put\_code/2}}
Puts the ASCII code of the character {\tt Char} to {\tt
Stream\_or\_alias}.

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open input stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\item 	{\tt Code} is a not a character code
\bi
\item 	{\tt type\_error(characterCode,Code)}
\ei
\ei


\ournewitem{put\_code(+Code)}{ISO}
\index{\texttt{put\_code/1}}
Puts the ASCII code {\tt Code} to the current output stream.
{\bf Error Cases}
\bi
\item 	{\tt Code} is a not a character code.
\bi
\item 	{\tt type\_error(characterCode,Code)}
\ei
\ei

\ouritem{put(+Code)}\index{\texttt{put/1}}
    Puts the ASCII character code {\tt N} to the current output stream.

{\bf Error Cases}
\bi
\item 	{\tt Code} is a not a character code.
\bi
\item 	{\tt type\_error(characterCode,Code)}
\ei
\ei

\ouritem{tab(+N)}\index{\texttt{tab/1}}
    Puts {\tt N} spaces to the current output stream. 

{\bf Error Cases}
\bi
\item 	{\tt Code} is a not a positiveInteger
\bi
\item 	{\tt type\_error(positiveInteger,Code)}
\ei
\ei

\end{description}

%---------------------------------------------------------------------------------------------------------
\subsection{Term I/O}
\begin{description}
\ournewitem{read(?Term)}{ISO}\index{\texttt{read/1}}
    A HiLog term is read from the current or designated input stream,
    and unified with {\tt Term} according to the operator declarations
    in force.  (See Section~\ref{TermSyntax} for the definition and
    syntax of HiLog terms). The term must be delimited by a full stop
    (i.e. a ``.'' followed by a carriage-return, space or tab).
    Predicate {\tt read/1} does not return until a valid HiLog term is
    successfully read; that is, in the presense of syntax errors {\tt
    read/1} does not fail but continues reading terms until a term
    with no syntax errors is encountered.  If a call to {\tt
    read(Term)} causes the end of the current input stream to be
    reached, variable {\tt Term} is unified with the term {\tt
    end\_of\_file}.  In that case, further calls to {\tt read/1} for
    the same input stream will cause an error failure.

%TLS: This doesn't actually seem to be the behavior.  Exceptions:
% \begin{description} 
% \item[{\tt existence\_error}] {\tt end\_of\_file}
%  is reached before the current term is read.  
%\end{description} 
%
In \version, {\tt read/\{1,2\}} are non ISO-compliant in how they
handle syntax errors or their behavior when encountering an end of
file indicator.

%--------

\ournewitem{read(+Stream\_or\_alias, ?Term)}{ISO}\index{\texttt{read/2}}
	{\tt read/2} has the same behavior as {\tt read/1} but the
	input stream is explicitly designated by {\tt
	Stream\_or\_alias}.

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei

%--------
\ournewitem{read\_canonical(-Term)}{ISO} 
\index{\texttt{read\_canonical/1}} 
Reads a term that is in canonical format from the current input stream
and returns it in {\tt Term}. On end-of-file, it returns the atom {\tt
end\_of\_file}.  If it encounters an error, it prints an error message
on stderr and returns the atom {\tt read\_canonical\_error}. This is
significantly faster than {\tt read/1}, but requires the input to be
in canonical form.

In \version, {\tt read\_canonical/\{1,2\}} are non ISO-compliant in how they
handle syntax errors or their behavior when encountering an end of
file indicator.

\ournewitem{read\_canonical(+Stream\_or\_alias)-Term)}{ISO} 
\index{\texttt{read\_canonical/2}} 
Behaves as {\tt read\_canonical/1}, but reads from {\tt Stream\_or\_alias}.

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open input stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei
%--------
\ournewitem{read\_term(?Term,?OptionsList)}{ISO}
\index{\texttt{read\_term/2}}
%
A term is read from the current input stream as in {\tt read/1}; but
{\tt OptionsList} is a (possibly empty) list of {\em read options}
that specifie additional behavior.  The read options include
\begin{itemize}
\item {\tt variables(Vars)}: once a term has been read, {\tt Vars} is a
list of the variables in the term, in left-to-right order. 
\item {\tt variable\_names(VN\_List)}: once a term has been read {\tt
VN\_List} is a list of non-anonymous variables in the term.  The
elements of the list have the form {\tt A = V} where {\tt V} is a
non-anonymous variable of the term, and {\tt A} is the string used to
denote the variable in the input stream.
\item {\tt singletons(VS\_List)}: once a term has been read {\tt
VN\_List} is a list of the non-anonymous {\tt singleton} varables in
the term.  The elements of the list have the form {\tt A = V} where
{\tt V} is a non-anonymous variable of the term, and {\tt A} is the
string used to denote the variable in the input stream.
\end{itemize}

{\bf Error Cases}
\bi
\item 	{\tt OptionsList} is a variable, or is a list containing a
	variable element. 
\bi 
\item instantiation\_error(OptionsList)
\ei
\item     {\tt OptionsList} contains a non-variable element {\tt O} that is not
	a read option.
\bi
\item 	{\tt domain\_error(readOption,O)}
\ei
\ei

%--------

\ournewitem{read\_term(+Stream\_or\_alias, ?Term,?OptionsList)}{ISO}
\index{\texttt{read\_term/3}}
%
{\tt read\_term/3} has the same behavior as {\tt read\_term/2} but
the input stream is explicitly designated using the first argument.

{\bf Error Cases} are the same as {\tt read\_term/2}, but with the
additional errors that may arise in stream checking.
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei

\ournewitem{write(?Term)}{ISO}\index{\texttt{write/1}}
    The HiLog term {\tt Term} is written to the current output stream, 
    according to the operator declarations in force.  Any uninstantiated 
    subterm of term {\tt Term} is written as an anonymous variable (an 
    underscore followed by a token).

    All {\em proper HiLog terms} (HiLog terms which are not also Prolog terms) 
    are not written in their internal Prolog representation.  Predicate 
    {\tt write/1} always succeeds without producing an error.

    HiLog (or Prolog) terms that are output by {\tt write/1} cannot in general be 
    read back using {\tt read/1}.  This happens for two reasons:
    \begin{itemize}
    \item The atoms appearing in term {\tt Term} are not quoted. In that case 
          the user must use {\tt writeq/1} or 
          {\tt write\_canonical/1} described below, which quote around atoms 
          whenever necessary.
    \item The output of {\tt write/1} is not terminated by a full-stop;
          therefore, if the user wants the term to be accepted as input to
          {\tt read/1}, the terminating full-stop must be explicitly sent 
          to the current output stream. 
    \end{itemize}

    Predicate {\tt write/1} treats terms of the form \verb|'$VAR'(N)|
    specially: it writes {\tt 'A'} if {\tt N}=0, {\tt 'B'} if {\tt
    N}=1, $\ldots$, {\tt 'Z'} if {\tt N}=25, {\tt 'A1'} if {\tt N}=26,
    etc.  Terms of this form are generated by {\tt numbervars/[1,3]}
    described in the section {\it Library Utilities} in Volume 2.
    \verb|'$VAR'(-1)| is written as the anonymous variable \verb|'_'|.

\ournewitem{write(+Stream\_or\_alias, ?Term)}{ISO}\index{\texttt{write/2}}
	{\tt write/2} has the same behavior as {\tt write/1} but the
	output stream is explicitly designated using the first argument.

{\bf Error Cases} are the same as {\tt read\_term/2}, but with the
additional errors that may arise in stream checking.
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open output stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei

\ournewitem{writeq(?Term)}{ISO}\index{\texttt{writeq/1}}
    Acts as {\tt write(Term)}, but atoms and functors are quoted
    whenever necessary to make the result acceptable as input to {\tt
    read/1}\@. {\tt writeq/1} treats treats terms of the form
    \verb|'\VAR'(N)| the same way as {\tt write/1}, writing {\tt A} if
    {\tt N}= 0, etc. In addition, output is in accordance with current
    operator definitions.  {\tt writeq/1} always succeeds without
    producing an error.

\ournewitem{writeq(+Stream\_or\_alias, ?Term)}{ISO}
\index{\texttt{writeq/2}}
	{\tt writeq/2} has the same behavior as {\tt writeq/1} but the
	output stream is explicitly designated using the first argument.

{\bf Error Cases} 
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open output stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei

\ournewitem{write\_canonical(?Term)}{ISO}\index{\texttt{write\_canonical/1}}
    This predicate is provided so that the HiLog term {\tt Term}, 
    if written to a file, can be read back using {\tt read/1} regardless of 
    special characters appearing in {\tt Term} or prevailing operator 
    declarations. Like {\tt write\_prolog/1}, {\tt write\_canonical/1} 
    writes all proper HiLog terms to the current output stream using the 
    standard Prolog syntax (see Section~\ref{TermSyntax} on the standard 
    syntax of HiLog terms). {\tt write\_canonical/1} also quotes atoms and 
    functors as {\tt writeq/1} does, to make them acceptable as input of 
    {\tt read/1}\@.  Operator declarations are not taken into consideration,
    and compound terms are therefore always written in the form:

		\[ \langle predicate\ name \rangle
			(\langle arg_1 \rangle, \ldots,
			 \langle arg_n \rangle) \]

    Unlike {\tt writeq/1}, {\tt write\_canonical/1} does not treat terms 
    of the form \verb|'$VAR'(N)| specially. It writes square bracket lists 
    using {\tt '.'/2} and {\tt []} (that is, {\tt [foo, bar]} is written 
    as \verb|'.'(foo,'.'(bar,[]))|).
%% $

\ournewitem{write\_canonical(+Stream\_or\_alias, ?Term)}{ISO}
\index{\texttt{write\_canonical/2}}
{\tt write\_canonical/2} has the same behavior as {\tt
write\_canonical/1} but the output stream is explicitly designated
using the first argument.

{\bf Error Cases} 
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open output stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei


\ournewitem{write\_term(?Term,+Options)}{ISO}
\index{\texttt{write\_term/2}}
%
Outputs {\tt +Term} to the current output stream.
{\tt Stream} ({\tt write\_term/3}) according to the list of write
options, {\tt Options}.  The current set of write options which form a
superset of the ISO-standard write options, are as follows:
%
\begin{itemize}
%
\item {\tt quoted(+Bool)}.  If {\tt Bool = true}, then atoms and
    functors that can't be read back by {\tt read/1} are quoted, if
    {\tt Bool = false}, each atom and functor is written as its
    unquoted name. Default value is {\tt false}.
%
\item {\tt ignore\_ops(+Bool)}. If {\tt Bool = true} each compound term
is output in functional notation; curly brackets and list braces are
ignored, as are all explicitly defined operators.  If {\tt Bool =
false}, curly bracketed notation and list notation is enabled when
outputing compound terms, and all other operator notation is
enabed.  Default value is {\tt false}.
%
 \item {\tt numbervars(+Bool)}.  If {\tt Bool = true}, a term of the
form {\tt '\$VAR'(N)} where {\tt N} is an integer, is output as a
variable name consisting of a capital letter possibly followed by an
integer.  A term of the form {\tt '\$VAR'(Atom)} where {\tt Atom} is an
atom, is output as itself (without quotes).  Finally, a term of the
form {\tt '\$VAR'(String)} where {\tt String} is a character string, is
output as the atom corresponding to this character string.  If
{\tt bool} is {\tt false} this cases are not treated in any special
way.  Default value is {\tt false}.
%
% TLS: need predicate portray attribute, if we dont have it.
%
\comment{
\item {\tt portrayed(+Bool)}. If {\tt Bool = true}, then a call is made
to the predicate @pred{portray/1}, to
provide the user handlers for pretty printing some terms.  {\tt
portray_attribute/1} is called whenever an attributed variable is to
be printed, {\tt portray/1} is called whenever a non-variable term is
to be printed.  If either call succeeds, then it is assumed that the
term has been output, else it is printed as usual.  If {\tt bool} is
{\tt false}, these predicates are not called. Default value is {\tt
false}.  This option is set by the toplevel when writting the final
values of variables, and by the debugging package when writting the
goals in the tracing messages.  Thus you can vary the forms of these
messages if you wish.
}
\item {\tt max\_depth(+Depth)}. {\tt Depth} is a positive integer or
zero. If positive, it denotes the depth limit on printing compound
terms. If {\tt Depth} is zero, there is no limit. Default value is
{\tt 0} (no limit).
%
\item {\tt priority(+Prio)} {\tt Prio} is an integer between 1 and
1200.  If the term to be printed has higher priority than {\tt Prio},
it will be printed parenthesized.  Default value is 1200 (no term
parenthesized).
\end{itemize}

From the following examples it can be seen that {\tt
write\_term/\{2,3\}} can duplicate the behavior of a number of other
I/O predicates such as {\tt write/\{1,2\}}, {\tt writeq/\{1,2\}}, {\tt
write\_canonical/\{1,2\}}, etc.
{\small
\begin{verbatim}

| ?- write_term(f(1+2,'A',"string",'$VAR'(3),'$VAR'('Temp'),(multifile foo)),[]).
f(1 + 2,A,"string",$VAR(3),$VAR(Temp),(multifile foo))
yes

| ?- write_term(f(1+2,'A',"string",'$VAR'(3),'$VAR'('Temp'),(multifile foo)),
                [quoted(true)]).
f(1 + 2,'A',"string",'$VAR'(3),'$VAR'('Temp'),(multifile foo))
yes

| ?- write_term(f(1+2,'A',"string",'$VAR'(3),'$VAR'('Temp'),(multifile foo)),
                [quoted(true),ignore_ops(true),numbervars(true)]).
f(+(1,2),'A','.'(115,'.'(116,'.'(114,'.'(105,'.'(110,'.'(103,[])))))),D,Temp,(multifile foo))
yes

| ?- write_term(f(1+2,'A',"string",'$VAR'(3),'$VAR'('Temp'),(multifile foo)),
                [quoted(true),ignore_ops(true),numbervars(true),priority(1000)]).
f(+(1,2),'A','.'(115,'.'(116,'.'(114,'.'(105,'.'(110,'.'(103,[])))))),D,Temp,multifile(foo))
yes
\end{verbatim}
}

{\bf Error Cases} 
\bi
\item 	{\tt Options} is a variable
\bi
\item    {\tt instantiation\_error(Options)}
\ei
\item 	{\tt Options} neither a variable nor a list
\bi
\item    {\tt type\_error(list,Options)}
\ei
\item 	{\tt Options} contains a variable element, {\tt O}
\bi
\item    {\tt instantiation\_error(O)}
\ei
\item 	{\tt Options} contains an element {\tt O} that is neither a variable
nor a write option.
\bi
\item    {\tt domain\_error(write\_option,O)}
\ei
\ei

\ournewitem{write\_term(+Stream\_or\_alias,?Term,+Options)}{ISO}
\index{\texttt{write\_term/3}}
% 
Behaves as {\tt write\_term/2}, but writes to {\tt Stream\_or\_alias}.

{\bf Error Cases} are the same as {\tt write\_term/2} but with these
additions.
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term
or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open output stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei


\ouritem{writeln(?Term)}\index{\texttt{writeln/1}}
    {\tt writeln(Term)} can be defined as {\tt write(Term), nl}.

\ouritem{writeln(+Stream,?Term)}\index{\texttt{writeln/2}}
    {\tt writeln(Term)} can be defined as {\tt write(Stream,Term),
    nl(Stream)}.

\ouritem{display(?Term)}\index{\texttt{display/1}}
    The HiLog term {\tt Term} is displayed on the terminal (standard output 
    stream), according to the operator declarations in force. In other words,
    {\tt display/1} is similar to {\tt write/1} but the result is always
    written on {\tt ``userout''}\@.  Like {\tt write/1}, {\tt display/1} 
    always succeeds without producing an error. After returning from a call 
    to this predicate, the current output stream remains unchanged.

\ournewitem{write\_prolog(?Term)}{HiLog}\index{\texttt{write\_prolog/1}}
    This predicate acts as does {\tt write/1} except that any HiLog
    term {\tt Term} is written as a Prolog term.  {\tt
    write\_prolog/1} outputs {\tt Term} according to the operator
    declarations in force.  Because of this, it differs from {\tt
    write\_canonical/1} described above, despite the fact that both
    predicates write HiLog terms as Prolog terms.

\ournewitem{write\_prolog(+Stream\_or\_alias,?Term)}{HiLog}
\index{\texttt{write\_prolog/2}}
	{\tt write\_prolog/2} has the same behavior as {\tt
	write\_prolog/1} but the output stream is explicitly
	designated using the first argument.

{\bf Error Cases} are the same as {\tt write\_term/2} but with these
additions.
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term
or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open output stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei

\end{description}

\subsection{Special I/O}

\begin{description}
\ouritem{fmt\_read(+Fmt,-Term,-Ret)}\index{\texttt{fmt\_read/3}}
\vspace{-7mm}
\ouritem{fmt\_read(+Stream,+Fmt,-Term,-Ret)}\index{\texttt{fmt\_read/4}}
%
    These predicates provides a routine for reading data from the
    current input file (which must have been already opened by using
    {\tt see/1}) according to a C format, as used in the C function
    {\tt scanf}. {\tt Fmt} must be a string of characters (enclosed in
    ") representing the format that will be passed to the C call to
    {\tt scanf}.  See the C documentation for {\tt scanf} for the
    meaning of this string.  The usual alphabetical C escape
    characters ({\it e.g.}, $\backslash n$) are recognized, but not
    the octal or the hexadecimal ones.  Another difference with C is
    that, unlike most C compilers, XSB insists that a single {\tt \%}
    in the format string signifies format conversion
    specification. (Some C compilers might output {\tt \%} if it is
    not followed by a valid type conversion spec.) So, to output {\tt
    \%} you must type {\tt \%\%}.  Format can also be an atom enclosed
    in single quotes. However, in that case, escape sequences are not
    recognized and are printed as is.

    {\tt Term} is a term ({\it e.g.}, {\tt args(X,Y,Z)})  whose arguments
    will be unified with the field values read in.  (The functor symbol of {\tt
    Term} is ignored.)  Special syntactic sugar is provided for the case
    when the format string contains only one format specifier: If {\tt
    Term} is a variable, {\tt X}, then the predicate behaves as if {\tt
    Term} were {\tt arg(X)}.

  If the number of arguments exceeds the number of format specifiers, a
  warning is produced and the extra arguments remain uninstantiated.
  If the number of format specifiers exceeds the number of arguments, then
  the remainder of the format string (after the last matching specifier) is
  ignored.
  
  Note that floats do not unify with anything.  {\tt Ret} must be a
  variable and it will be assigned a return value by the predicate: a
  negative integer if end-of-file is encountered; otherwise the number of
  fields read (as returned by {\tt scanf}.)
  
  {\tt fmt\_read} cannot read strings (that correspond to the {\tt \%s}
  format specifier) that are longer than 16K. Attempting to read longer
  strings will cause buffer overflow. It is therefore recommended that one
  should use size modifiers in format strings ({\it e.g.}, {\tt \%2000s}),
  if such long strings might occur in the input.

\ouritem{fmt\_write(+Fmt,+Term)}\index{\texttt{fmt\_write/2}}
\vspace{-7mm}
\ouritem{fmt\_write(+Stream,+Fmt,+Term)}\index{\texttt{fmt\_write/3}}
    This predicate provides a routine for writing data to the current
    output file (which must have been already opened by using {\tt
    tell/1}) according to a C format, as used in the C function {\tt
    printf}.  {\tt Fmt} must be a string of characters (enclosed in ")
    representing the format that will be passed to the C call to {\tt
    printf}.  See the C documentation for {\tt printf} for the meaning
    of this string.  The usual alphabetical C escape characters ({\it
    e.g.}, $\backslash n$) are recognized, but not the octal or the
    hexadecimal ones.

    In addition to the usual C conversion specifiers, {\tt \%S} is also
    allowed. The corresponding argument can be any Prolog term. This
    provides an easy way to print the values of Prolog variables, etc.  
    Also {\tt \%!} is supported and indicates that the corresponding argument
    is to be ignored and will generate nothing in the output.

    Another difference with C is that, unlike most C compilers, XSB insists
    that a single {\tt \%} in the format string signifies format conversion
    specification. (Some C compilers might output {\tt \%} if it is not
    followed by a valid type conversion spec.) So, to output {\tt \%}
    you must type {\tt \%\%}.
    
    Format can also be an atom, but then escape sequences are not
    recognized.

    {\tt Term} is a term ({\it e.g.}, {\tt args(X,Y,Z)}) whose arguments
    will be output. The functor symbol of {\tt Term} is ignored.
    
    Special syntactic sugar is provided for the following cases: If {\tt
      Term} is a variable, {\tt X}, then it is ignored and only the format
    string is printed. If {\tt Term} is a string, integer or a float, then
    it is assumed that this is the only argument to be printed, {\it i.e.},
    it is equivalent to specifying {\tt arg(Term)}.

    If the number of format specifiers is greater than the number of
    arguments to be printed, an error is issued. If the number of arguments
    is greater, then a warning is issued.

\ouritem{fmt\_write\_string(-String,+Fmt,+Term)}
\index{\texttt{fmt\_write\_string/3}}
    This predicate works like the C function {\tt sprintf}. It takes the
    format string and substitutes the values from the arguments of {\tt
      Term} ({\it e.g.}, {\tt args(X,Y,Z)}) for the formatting instructions
    \%s, \%d, etc. Additional syntactic sugar, as in \verb|fmt_write|, is
    recognized. The result is available in {\tt String}. {\tt Fmt} is a
    string or an atom that represents the format, as in
    {\tt fmt\_write}.
    
    If the number of format specifiers is greater than the number of
    arguments to be printed, an error is issued. If the number of arguments
    is greater, then a warning is issued.

    {\tt fmt\_write\_string} requires that the printed size of each
    argument ({\it e.g.}, X,Y,and Z above) must be less than 16K. Longer
    arguments are cut to that size, so some loss of information is possible.
    However, there is no limit on the total size of the output (apart from
    the maximum atom size imposed by XSB).

\ouritem{file\_read\_line\_list(-String)}
\index{\texttt{file\_read\_line\_list/1}}
A line read from the current input stream is converted into a list of
character codes.  This predicate 
%is \emph{much} more efficient than
%{{\tt fget\_line/3}} (see below), and 
avoids interning an atom as does {\tt file\_read\_line\_atom/3}, and so is
recommended when speed is important.  This predicate fails on reaching
the end of file.

\ouritem{file\_read\_line\_list(Stream\_or\_alias,-CharList)}
\index{\texttt{file\_read\_line\_list/2}}
Acts as does {\tt file\_read\_line\_list}, but uses {\tt Stream\_or\_atom}.

{\bf Error Cases} 
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term
or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open input stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei

\ouritem{file\_read\_line\_atom(-Atom)}
\index{\texttt{file\_read\_line\_atom/1}}
%
Reads a line from the current (textual) input stream, returning it as
{\tt Atom}.  This predicate fails on reaching the end of file.

\ouritem{file\_read\_line\_atom(+Stream\_or\_alias,-Atom)}
\index{\texttt{file\_read\_line\_atom/2}}
Like {\tt file\_read\_line\_atom/1} but reads from {\tt Stream\_or\_alias}.
%
{\bf Error Cases} 
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term
or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open input stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei

\comment{
\ournewitem{file\_read\_line(+IOport,-String)}{file\_io}
\index{\texttt{file\_read\_line/2}}
} 

\ournewitem{file\_write\_line(+String, +Offset)}{file\_io}
\index{\texttt{file\_write\_line/2}}
   Write {\tt String} beginning with character {\tt Offset} to the
   current output strean. {\tt String} can be an atom or a list of
   ASCII character codes. This does \emph{not} put the newline
   character at the end of the string (unless {\tt String} already had
   this character). Note that escape sequences, like \verb|\n|, are
   recognized if {\tt String} is a character list, but are output as
   is if {\tt String} is an atom.

\ournewitem{file\_write\_line(+Stream\_or\_alias, +String, +Offset)}{file\_io}
\index{\texttt{file\_write\_line/3}}
Like \verb|file_write_line/2|, but output goes to {\tt
Stream\_or\_alias}.  

{\bf Error Cases}
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term
or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open input stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei



%----------------------------------------------------------------------------------------------
\comment{ TLS: isnt this file_getbuf_list?
\ournewitem{file\_getbuf(+Stream\_or\_alias, +BytesRequested, -String, -BytesRead)}{file\_io}
\index{\texttt{file\_getbuf/4}}
Read {\tt BytesRequested} bytes from file represented by {\tt
Stream\_or\_alias} (which must already be open for reading) into
variable {\tt String}. This is analogous to {\tt fread} in C.  This
predicate always succeeds. It does not distinguish between a file
error and end of file.  You can determine if either of these
conditions has happened by verifying that $\tt BytesRead <
BytesRequested$.
}
%----------------------------------------------------------------------------------------------

\ournewitem{file\_getbuf\_list(+Stream\_or\_alias, +BytesRequested, -CharList, -BytesRead)}{file\_io}
\index{\texttt{file\_getbuf\_list/4}}
Read {\tt BytesRequested} bytes from file represented by {\tt
Stream\_or\_alias} (which must already be open for reading) into
variable {\tt String} as a list of character codes. This is analogous
to {\tt fread} in C.  This predicate always succeeds. It does not
distinguish between a file error and end of file.  You can determine
if either of these conditions has happened by verifying that $\tt
BytesRead < BytesRequested$.

\ournewitem{file\_getbuf\_list(+BytesRequested, -String, -BytesRead)}{file\_io}
\index{\texttt{file\_getbuf\_list/3}}

Like \verb|file_getbuf_list/3|, but reads from the currently open input stream
({\it i.e.}, with {\tt see/1}).


\ournewitem{file\_getbuf\_atom(+Stream\_or\_alias, +BytesRequested, -String, -BytesRead)}{file\_io}
\index{\texttt{file\_file\_getbuf\_atom/4}}
Read {\tt BytesRequested} bytes from file represented by {\tt
Stream\_or\_alias} (which must already be open for reading) into
variable {\tt String}. This is analogous to {\tt fread} in C.  This
predicate always succeeds. It does not distinguish between a file
error and end of file.  You can determine if either of these
conditions has happened by verifying that $\tt BytesRead <
BytesRequested$.

Note: because XSB does not have an atom table garbage collector yet,
this predicate should not be used to read large files.  Use {\tt
read\_getbuf\_list} or another predicate in this case.

{\bf Error Cases} 
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term
or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open input stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei

\ournewitem{file\_getbuf\_atom(+BytesRequested, -String, -BytesRead)}{file\_io}
\index{\texttt{file\_getbuf\_atom/3}}
Like \verb|file_getbuf_atom/4|, but reads from the currently open input stream.

\ournewitem{file\_putbuf(+Stream\_or\_alias, +BytesRequested, +String, +Offset, -BytesWritten)}{file\_io}
\index{\texttt{file\_putbuf/5}}
Write {\tt BytesRequested} bytes into file represented by I/O port
{\tt Stream\_or\_alias} (which must already be open for writing) from
variable {\tt String} at position {\tt Offset}. This is analogous to C
{\tt fwrite}.  The value of {\tt String} can be an atom or a list of
ASCII characters.

{\bf Error Cases} 
\bi
\item 	{\tt Stream\_or\_alias} is not instantiated to a stream term
or alias.
\bi
\item 	{\tt domain\_error(stream\_or\_alias,Stream\_or\_alias)}
\ei
\item 	{\tt Stream\_or\_alias} is not associated with an open input stream
\bi
\item 	{\tt existence\_error(stream,Stream\_or\_alias)}
\ei
\ei

\ournewitem{file\_putbuf(+BytesRequested, +String, +Offset, -BytesWritten)}{file\_io}
\index{\texttt{file\_putbuf/4}}
Like \verb|file_putbuf/3|, but output goes to the currently open output stream.


\end{description}

%-------------------------------------------------------------------
\comment{
\ouritem{fmt\_read(+Format, types(+T1,+T2,...), args(-A1,-A2,...), -RetCode)}\index{\texttt{fmt\_read/4}} 
 This predicate implements C-style formatted input. It reads the current
 input according to the {\tt Format} string.  {\tt Format} has the
 same syntax as the input format in C. The term {\tt types(...)} lists the
 types of the arguments; they must match the types specified in {\tt
 Format}. Here, 1 means string, 2 means integer, and 3 means float.
 The term {\tt args()} specifies the variables for the input. {\tt RetCode}
 specifies the return code: 0 -- ok; -1 -- end of file.

\ouritem{read\_line(-Line, -Status)}\index{\texttt{read\_line/2}} 
 Reads the next line from the current input and puts it in {\tt Line}.
 If the line is larger than the available buffer, then {\tt Status} is 0.
 If the line was read in full, up to and including the newline character,
 then {\tt Status} is 1. 

\ouritem{fmt\_write(+Format, args(-A1,-A2,...))}\index{\texttt{fmt\_write/2}} 
 Similar to formatted write in C. The semantics of the arguments is the
 same as for {\tt fmt\_read/4}.

\ouritem{fmt\_write\_string(-String, +Format, args(-A1,-A2,...))}\index{\texttt{fmt\_write/2}} 
 Like {\tt fmt\_write/2}, but the output string is placed in {\tt String}.
}

%--------------------------------------------------------------------------------------------------

\section{Interactions with the Operating System}

XSB provides a number of facilities for interacting with the UNIX and
Windows operating systems.  This section describes basic facilities
for invoking shell commands and file manipulation.  Chapter 1 of
Volume 2 discusses more advanced commands for process spawning and
control, along with interprocess communication.

\begin{description}

\ouritem{shell(+SystemCall)}\index{\texttt{shell/1}}
    Calls the operating system with the atom {\tt SystemCall} as argument.
    It succeeds if {\tt SystemCall} is executed successfully, otherwise it
    fails.  As a notational convenience, the user can supply {\tt SystemCall} 
    in the form of a list (something currently not possible for {\tt shell/2}).

    For example, the call:

    \demo{{\tt $|$ ?- shell('echo \$HOME').}}

    \noindent
    will output in the current output stream of \ourprolog\ the name of
    the user's home directory; while the call:

    \demo{{\tt $|$ ?- File = 'test.c', shell(['cc -c ', File]).}}

    \noindent
    will call the C compiler to compile the file {\tt test.c}.

    Note that in UNIX systems, since {\tt shell/1} is executed by
    forking off a shell process, it cannot be used, for example, to
    change the working directory of the interpreter.  For that reason
    the standard predicate {\tt cd/1} described below should be used.

%    {\em Note to DOS users.} \index{DOS}  The {\tt shell/1} command works
%    for DOS through the underlying GNU djgpp mechanism used to stream \ourprolog.

\ouritem{shell(+SystemCall, -Result)}\index{\texttt{shell/2}}
    Calls the operating system with the atom {\tt SystemCall} as argument
    and returns the result of the call in {\tt Result}.  In comparison with
    {\tt shell/1} this predicate always succeeds, even if the {\tt SystemCall} 
    cannot be successfully executed.

\ournewitem{datime(?Date)}{standard}
\index{\texttt{datime/1}}

Unifies {\tt Date} to the current date, returned as a Prolog term,
suitable for term comparison.  Note that {\tt datime/1} must be
explicitly imported from the module {\tt standard}.

Example:
{\footnotesize
\begin{verbatim}
                > date
                Mon Aug  9 16:19:44 EDT 2004
                > nxsb1
                XSB Version 2.6 (Duff) of June 24, 2003
                [i686-pc-cygwin; mode: optimal; engine: slg-wam; gc: indirection; scheduling: local]

                | ?- import datime/1 from standard

                yes
                | ?- datime(F).
                F = datime(2004,8,9,20,20,23)

                yes
\end{verbatim}}

\end{description}

\subsection{The {\tt path\_sysop/2} interface}
%
In addition, XSB provides the following unified interface to the
operations on files. All these calls succeed iff the corresponding
system call succeeds.  These calls work on both Windows and Unixes
unless otherwise noted.
%%
\begin{description}
  \ouritem{path\_sysop(isplain, +Path)}
  \index{\texttt{path\_sysop/2}}
  Succeeds, if {\tt Path} is a plain file.
  \ouritem{path\_sysop(isdir, +Path)}
  Succeeds, if {\tt Path} is a directory.
  \ouritem{path\_sysop(rename, +OldPath, +NewPath)}
  \index{\texttt{path\_sysop/3}}
  Renames {\tt OldPath} into {\tt NewPath}.
  \ouritem{path\_sysop(copy, +FromPath, +ToPath)}
  \index{\texttt{path\_sysop/3}}
  Copies {\tt FromPath} into {\tt ToPath}.
  \ouritem{path\_sysop(rm, +Path)}
  Removes the plain file {\tt Path}.
  \ouritem{path\_sysop(rmdir, +Path)}
  Deletes the directory {\tt Path}, succeeding only if the directory is empty.
  \ouritem{path\_sysop(rmdir\_rec, +Path)}
  Deletes the directory {\tt Path} along with any of its contents.
%  \ouritem{path\_sysop(unlink, +Path)}
%  Same as {\tt rm}.
  \ouritem{path\_sysop(link, +SrsPath, +DestPath)}
  Creates a hard link from {\tt SrsPath} to {\tt DestPath}. UNIX only.
  \ouritem{path\_sysop(cwd, -Path)}
  Binds {\tt Path} to the current working directory.
  \ouritem{path\_sysop(chdir, +Path)}
  Changes the current working directory to {\tt Path}.
  \ouritem{path\_sysop(mkdir, +Path)}
  Creates a new directory, {\tt Path}.
  \ouritem{path\_sysop(exists, +Path)}
  Succeeds if the file {\tt Path} exists.
  \ouritem{path\_sysop(readable, +Path)}
  Succeeds if {\tt Path} is a readable file.
  \ouritem{path\_sysop(writable, +Path)}
  Succeeds if {\tt Path} is a writable file.
  \ouritem{path\_sysop(executable, +Path)}
  Succeeds if {\tt Path} is an executable file.
  \ouritem{path\_sysop(modtime, +Path, -Time)}
  Returns a list that represents the last modification time of the file.
  Succeeds if file exists. In this case, {\tt Time} is bound to a list
  {\tt [high,low]} where {\tt low} is the least significant 24 bits of the
  modification time and {\tt high} is the most significant bits (25th) and up.
  {\tt Time} represents the last modification time of the file.
  The actual value is thus $\tt high*2^{24} + low$, which represents the
  number of seconds elapsed since 00:00:00 on
       January 1, 1970, Coordinated Universal Time (UTC).
  \ouritem{path\_sysop(newerthan, +Path1, +Path2)}
  Succeeds is the last modification time of {\tt Path1} is higher than that
  of {\tt Path2}. Also succeeds if {\tt Path1} exists but {\tt Path2} does
  not.
  \ouritem{path\_sysop(size, +Path, -Size)}
  Returns a list that represents the byte size of {\tt Path}.
  Succeeds if the file exists. In this case {\tt Size} is bound to the list
  of the form {\tt [high,low]} where {\tt low} is the least significant 24
  bits of the byte-size and {\tt high} is the most significant bits (25th)
  and up. The actual value is thus $\tt high*2^{24} + low$.
  \ouritem{path\_sysop(tmpfilename, -Name)}
  Returns the name of a new temporary file. This is useful when the
  application needs to open a completely new temporary file.
  \ouritem{path\_sysop(extension, +Name, -Ext)}
  Returns file name extension.
  \ouritem{path\_sysop(basename, +Name, -Base)}
  Returns the base name of the file name ({\it i.e.}, the name sans the
  directory and the extension).
  \ouritem{path\_sysop(dirname, +Name, -Dir)}
  Returns the directory portion of the filename. The directory is slash or
  backslash terminated.
  \ouritem{path\_sysop(isabsolute, +Name)}
  Succeeds if {\tt Name} is an absolute path name. File does not need to exist.
  \ouritem{path\_sysop(expand, +Name, -ExpandedName)}
  Binds {\tt ExpandedName} to the expanded absolute path name of {\tt Name}.
  The file does not need to exist. Duplicate slashes, references to the
  current and parent directories are factored out.
\end{description}
%%

%--------------------------------------------------------------------------------------------------
\section{Evaluating Arithmetic Expressions through {\tt is/2}}
\label{Arithmetic} 

As do most Prologs, XSB supports evaluation of arithmetic expressions
in two ways.  First, XSB supports evaluation of ground arithmetic
expressions throught the {\tt is/2} operator.  Support of comparisons
of non-ground arithmetic expressions is provided through the port to
XSB of the CLPQR constraint handling interface.  In this section we
describe how arithmetic expressions can be evaluated through {\tt
is/2}, while the CLPQR interface is described in Volume 2 of this
manual.

Before describing {\tt is/2} and the expressions that it can evaluate,
we note that in \version{} of XSB, integers and floats in XSB are
represented using a single word of 32 or 64 bits, depending on the
machine architecture.  Since type tags constitute part of this word,
this means that there may be as little as 28 bits available to
represent a floating point number.  In addition, evaluation of
arithmetic expressions through {\tt is/2} does not check for overflow
or underflow.  As a result, XSB's floating point operations do not
conform to IEEE floating point standards, and deviates in this regard
from the ISO Prolog standard (see \cite{ISO-Prolog} Section 9).  We
hope to fix these problems in a future release \footnote{We also note
that the ISO Prolog evaluable functors {\tt sign/1}, {\tt
float\_round/1}, {\tt float\_truncate/1}, {\tt float\_integer\_part/1}
and {\tt float\_fractional\_part/1} are not implemented in \version .}

All of the evaluable functors describe below throw a type error if
their evaluated input is not numeric.  We describe below only their
behavior on correctly typed input.

\begin{description}
\ouritem{is(?Result,+Expression)}\index{\texttt{is/2}} 
{\tt is(Result,Expression)} is true iff the result of evaluating {\tt
Expression} as a sequence of evaluable functors unifies with {\tt
Result}.  As mentioned in Section~\ref{inline_predicates}, {\tt is/2}
is an inline predicate, so calls to {\tt is/2} within compiled code
will not be visible during a trace of program execution.
\end{description}

\subsection{Evaluable Functors for Arithmetic Expressions}

\begin{description}
\ournewitem{+(+Expr1,+Expr2)}{Evaluable Functor}\index{\texttt{+/2}} 
If {\tt +Expr1} evaluates to {\tt Number1}, and {\tt Expr2} evaluates
to {\tt Number2}, returns {\tt Number1 + Number2}, performing any
necessary type conversions.

\ournewitem{-(+Expr1,+Expr2)}{Evaluable Functor}\index{\texttt{-/2}} 
If {\tt +Expr1} evaluates to {\tt Number1}, and {\tt Expr2} evaluates
to {\tt Number2}, returns {\tt Number1 - Number2}, performing any
necessary type conversions.

\ournewitem{*(+Expr1,+Expr2)}{Evaluable Functor}\index{\texttt{*/2}} 
If {\tt +Expr1} evaluates to {\tt Number1}, and {\tt Expr2} evaluates
to {\tt Number2}, returns {\tt Number1 * Number2} (i.e. multiplies
them), performing any necessary type conversions.

\ournewitem{/(+Expr1,Expr2)}{Evaluable Functor}\index{\texttt{'/'/2}}
If {\tt +Expr1} evaluates to {\tt Number1}, and {\tt Expr2} evaluates
to {\tt Number2}, returns {\tt Number1 / Number2} (i.e. divides
them), performing any necessary type conversions.

\ournewitem{//(+Expr1,Expr2)}{Evaluable Functor}\index{\texttt{'//'/2}}
If {\tt +Expr1} evaluates to {\tt Number1}, and {\tt Expr2} evaluates
to {\tt Number2}, returns {\tt Number1 // Number2} (i.e. integer
division), performing any necessary type conversions, and rounding to
0 if necessary.  

    Example:
    {\footnotesize
     \begin{verbatim}
                | ?- X is 3/2.

                X = 1.5000

                yes
                | ?- X is 3 // 2.

                X = 1

                yes
                | ?- X is -3 // 2.

                X = -1

                yes
  \end{verbatim}}

\ournewitem{-(+Expr1)}{Evaluable Functor}\index{\texttt{-/1}} If {\tt
+Expr} evaluates to {\tt Number}, returns {\tt -Number1},
performing any necessary type conversions.

\ournewitem{'$\wedge$'(+Expr1,+Expr2)}{Evaluable Functor}
\index{\texttt{'/\'/2}} If {\tt +Expr1} evaluates to {\tt Number1}, and {\tt Expr2}
evaluates to {\tt Number2}, returns the bitwise conjunction of {\tt
Number1} and {\tt Number2}.

\ournewitem{'$\vee$'(+Expr1,+Expr2)}{Evaluable Functor}
\index{\texttt{'\/'/2}} If {\tt +Expr1} evaluates to {\tt Number1}, and {\tt Expr2}
evaluates to {\tt Number2}, returns the bitwise disjunction {\tt
Number1} and {\tt Number2}.

\ournewitem{'>>'(+Expr1,+Expr2)}{Evaluable Functor}
\index{\texttt{'>>'/2}} If {\tt +Expr1} evaluates to {\tt Number1}, and {\tt Expr2}
evaluates to {\tt Number2}, returns the logical shift right of 
{\tt Number1}, {\tt Number2} places.

\ournewitem{'<<'(+Expr1,+Expr2)}{Evaluable Functor}
\index{\texttt{'>>'/2}} If {\tt +Expr1} evaluates to {\tt Number1}, and {\tt Expr2}
evaluates to {\tt Number2}, returns the logical shift left of 
{\tt Number1}, {\tt Number2} places.

\ournewitem{ceiling(+Expr)}{Evaluable Functor}\index{\texttt{ceiling/1}}
If {\tt +Expr} evaluates to {\tt Number}, {\tt ceiling(Number)}
returns the integer ceiling of {\tt Number} if {\tt Number} is a
float, and {\tt Number} itself if {\tt Number} is an integer.

\ournewitem{float(+Expr)}{Evaluable Functor}\index{\texttt{float/1}} If
{\tt +Expr} evaluates to {\tt Number}, {\tt float(Number)} converts 
{\tt Number} to a float if {\tt Number} is an integer, and returns {\tt
Number} itself if {\tt Number} is a float.

\ournewitem{floor(+Expr)}{Evaluable Functor}\index{\texttt{floor/1}} If
{\tt +Expr} evaluates to {\tt Number}, {\tt floor(Number)} returns the
integer floor of {\tt Number} if {\tt Number} is a float, and {\tt
Number} itself if {\tt Number} is an integer.

\ournewitem{mod(+Expr1,+Expr2)}{Evaluable Functor}\index{\texttt{mod/2}}
If {\tt +Expr1} evaluates to {\tt Number1} and {\tt Expr2} evaluates
to {\tt Number2} where {\tt Number2} is not 0, {\tt
mod(Number1,Number2)} returns
\[
	Number1 - (\lfloor (Number1 / Number2) \rfloor) \times Number2)
\]

\ournewitem{rem(+Expr1,+Expr2)}{Evaluable Functor}\index{\texttt{rem/2}}
If {\tt +Expr1} evaluates to {\tt Number1} and {\tt Expr2} evaluates
to {\tt Number2} where {\tt Number2} is not 0, {\tt
rem(Number1,Number2)} returns
\[
	Number1 - ({Number1} // {Number2}) \times Number2)
\]

    Example:
    {\footnotesize
     \begin{verbatim}
                | ?- X is 5 mod 2.

                X = 1

                yes
                | ?- X is 5 rem 2.

                X = 1

                yes
                | ?- X is 5 mod -2.

                X = -1

                yes
                | ?- X is 5 rem -2.

                X = 1

                yes
  \end{verbatim}}

\ournewitem{round(+Expr)}{Evaluable Functor}\index{\texttt{round/1}} If
{\tt +Expr} evaluates to {\tt Number}, {\tt round(Number)} returns the
nearest integer to {\tt Number} if {\tt Number} is a float, and {\tt
Number} itself if {\tt Number} is an integer.

\ournewitem{sqrt(+Expr)}{Evaluable Functor}\index{\texttt{sqrt/1}}
If {\tt +Expr} evaluates to {\tt Number}, {\tt sqrt(Number)}
returns the square root of {\tt Number}.

\ournewitem{truncate(+Expr)}{Evaluable Functor}
\index{\texttt{truncate/1}} If {\tt +Expr} evaluates to {\tt Number}, {\tt
truncate(Number)} truncates {\tt Number} if {\tt Number} is a float,
and returns {\tt Number} itself if {\tt Number} is an integer.
\end{description}

\subsubsection{Mathematical Functions from {\tt math.h}}
\index{\texttt{cos/1}} \index{\texttt{sin/1}} \index{\texttt{tan/1}}
\index{\texttt{acos/1}} \index{\texttt{asin/1}} \index{\texttt{atan/1}}
\index{\texttt{log/1}} \index{\texttt{log10/1}}

XSB also allows as evaluable functors, many of the functions form the
C library {\tt math.h}.  Functions included in XSB \version{} are {\tt
cos/1}, {\tt sin/1}, {\tt tan/1}, {\tt acos/1}, {\tt asin/1}, {\tt
atan/1}. {\tt log/1}, and {\tt log10/1}.  For their semantics, see
documentation to {\tt math.h}.

\section{Convenience} \label{Convenience}
These predicates are standard and often self-explanatory, so they are 
described only briefly.
\begin{description}

\ouritem{true}\index{\texttt{true/0}} 
%\predindex{true/0~(I)}
    Always succeeds.

\ouritem{otherwise}\index{\texttt{otherwise/0}} 
%\predindex{otherwise/0~(B)}
    Same as {\tt true/0}.

\ouritem{fail}\index{\texttt{fail/0}}
%\predindex{fail/0~(I)}
    Always fails.

\ouritem{X = Y}\index{\texttt{=/2}} 
%\predindex{=/2~(I)}
    Defined as if by the clause ``Z=Z'', i.e.~{\tt X} and~{\tt Y} are unified.

\ouritem{X $\backslash$\,= Y}\index{\texttt{$\backslash$=/2}}
    Succeeds if~{\tt X} and~{\tt Y} are not unifiable,
    fails if~{\tt X} and~{\tt Y} are unifiable.
    It is thus equivalent to {\tt $\backslash$+}\/{\tt (X = Y)}.
\end{description}

%-----------------------------------------------------------------------------------------
\section{Negation and Control}\label{sec:control}
\index{control}

\begin{description}
\ouritem{\cut}\index{\texttt{"!/0}}  \index{cut} 
    Cut (discard) all choice points made since the parent goal
    started execution.
    Cuts across tabled predicates are not valid.  The compiler checks for
    such cuts, although whether the scope of a cut includes a tabled 
    predicate is undecidable in the presence of meta-predicates like
    {\tt call/1}.
    Further discussion of conditions allowing cuts and of their actions 
    can be found in Section~\ref{tabling_env}.

\ouritem{fail\_if(+P)}\index{\texttt{fail\_if/1}}
    If the goal {\tt P} has a solution, fails, otherwise it succeeds.
    Equivalently, it is true iff {\tt call(P)} 
    (see Section~\ref{meta_predicates}) is false. Argument {\tt P} 
    must be ground for sound negation as failure, although no runtime 
    checks are made by the system.

    The standard predicate {\tt fail\_if/1} is compiled by the 
    XSB compiler.

    Exceptions:
    \begin{description}
    \item[{\tt instantiation\_error}]
	{\tt P} is not instantiated.
    \item[{\tt type\_error}]
	{\tt P} is not a callable term.
    \end{description}


\ouritem{$\backslash$+ +P}\index{$\backslash$\texttt{+/1}}
    Exactly the same as {\tt fail\_if/1}.  Its existence is only 
    for compatibility with other Prolog systems.

\ouritem{not +P}\index{\texttt{not/1}} 
    If the goal {\tt P} has a solution, fails, otherwise it succeeds.
    It is defined by:
    \begin{center}
    \begin{minipage}{2.40in}
    \begin{verbatim}
	not(P) :- call(P), !, fail.
	not(_).
    \end{verbatim}
    \end{minipage}
    \end{center}

    Argument {\tt P} must be ground for sound negation, although no 
    runtime checks are made by the system.

    Note that in contrast to the other two kinds of negation as failure
    (\not\ and {\tt fail\_if/1}), predicate {\tt not/1} is not compiled
    by the compiler but the above definition is used.

    Exceptions: The same as {\tt call/1} 
		(see Section~\ref{meta_predicates}).

\ournewitem{tnot(+P)}{Tabling}\index{\texttt{tnot/1}}\label{tnot/1}
    The semantics of {\tt tnot/1} allows for correct execution of
    programs with according to the well-founded semantics.  {\tt P}
    must be a tabled predicate, 
% tls: need to provide an example.
%and the actions of {\tt tnot/1} are
%presented in Figure~\ref{fig:tnot}. 
%
%\input{tnot} 
%
    For a detailed description of the actions of tabled negation for
    in XSB \version\ see~\cite{SaSw98, SaSW96}.
    Chapter~\ref{chap:TablingOverview} contains further discussion of the
    functionality of {\tt tnot/1}.

    Exceptions:
    \begin{description}
    \item[{\tt instantiation\_error}]
	{\tt P} is not ground (floundering occurs).
    \item[{\tt type\_error}]
	{\tt P} is not a callable term.
    \item[{\tt table\_error}]
	{\tt P} is not a call to a tabled predicate.
    \end{description}


    \ournewitem{sk\_not(+P)}{Tabling}\index{\texttt{sk\_not/1}} 
%% 
If {\tt +P} is a tabled predicate, {\tt sk\_not/1} acts as {\tt tnot/1}
    but permits variables in its subgoal argument.  This replaces the
    {\tt 't not'/1} predicate of earlier XSB versions whose
    implementation and semantics were dubious. The semantics in the
    case of unbound variables is as follows: 
%% 
\begin{quote} 
\tt ... :- ...,~sk\_not(p(X)),~...  \end{quote} 
%% 
is equivalent to 
%%
\begin{quote}
 \tt ... :- ..., tnot(pp),~...\\ pp :- p(X).
\end{quote} 
%% 
where {\tt pp} is a new proposition. Thus, the unbound variable $X$ is
treated as $\tt tnot(\exists X (p(X)))$.

If {\tt +P} is a non-tabled predicate ensures that {\tt +P} is ground
and called via a tabled predicate so that {\tt sk\_not/1} can be used
with non-tabled predicates as well, regardless of whether {\tt +P} is
ground or not.

\ouritem{P -> Q ; R}\index{\texttt{->/2}} 
    Analogous to if {\tt P} then {\tt Q} else {\tt R}, i.e.\ defined as 
    if by
	\begin{center}
	\begin{minipage}{2.10in}
	\begin{verbatim}
	(P -> Q ; R) :- P, !, Q.
	(P -> Q ; R) :- R.
	\end{verbatim}
	\end{minipage}
	\end{center}

\ouritem{P -> Q} \index{\texttt{->/2}} 
    When occurring other than as one of the alternatives of a disjunction,
    is equivalent to:
	\begin{center}
	{\tt P -> Q ; fail.}
	\end{center}

\ouritem{repeat} \index{\texttt{repeat/2}} 
    Generates an infinite sequence of choice points (in other words it 
    provides a very convenient way of executing a loop). It is defined 
    by the clauses:
    \begin{center}
    \begin{minipage}{1.5in}
    \begin{verbatim}
	repeat.
	repeat :- repeat.
    \end{verbatim}
    \end{minipage}
    \end{center}

\end{description}

%-------------------------------------------------------------------------
\section{Comparison and Sorting} \label{Comparison}
\input{comparison}

%------------------------------------------------------------------------------------------------
\section{Meta-Logical}\label{MetaLogical}

To facilitate manipulation of terms as objects in themselves,
XSB provides a number meta-logical predicates.  These
predicates include the standard meta-logical predicates of Prolog,
along with their usual semantics.  In addition are provided predicates
which provide special operations on HiLog terms.  For a full
discussion of Prolog and HiLog terms see Section~\ref{TermSyntax}.

\begin{description}
\ouritem{var(?X)}\index{\texttt{var/1}} 
    Succeeds if {\tt X} is currently uninstantiated (i.e.\ is still a 
    variable); otherwise it fails.  

    Term {\tt X} is uninstantiated if it has not been bound to anything, 
    except possibly another uninstantiated variable. Note in particular,
    that the HiLog term X(Y,Z) is considered to be instantiated.  There 
    is no distinction between a Prolog and a HiLog variable.

    Examples:
    {\footnotesize
     \begin{verbatim}
                | ?- var(X).
                yes
                | ?- var([X]).
                no
                | ?- var(X(Y,Z)).
                no
                | ?- var((X)).
                yes
                | ?- var((X)(Y)).
                no
     \end{verbatim}}


\ouritem{nonvar(?X)}\index{\texttt{nonvar/1}} 
    Succeeds if {\tt X} is currently instantiated to a non-variable term;
    otherwise it fails. This has exactly the opposite behaviour of 
    {\tt var/1}\@.

\ouritem{atom(?X)}\index{\texttt{atom/1}} 
    Succeeds only if the {\tt X} is currently instantiated to an atom, that
    is to a Prolog or HiLog non-numeric constant.

    Examples:
    {\footnotesize
     \begin{verbatim}
                | ?- atom(HiLog).
                no
                | ?- atom(10).
                no
                | ?- atom('HiLog').
                yes
                | ?- atom(X(a,b)).
                no
                | ?- atom(h).
                yes
                | ?- atom(+).
                yes
                | ?- atom([]).
                yes
     \end{verbatim}}

\ouritem{integer(?X)}\index{\texttt{integer/1}}
    Succeeds if {\tt X} is currently instantiated to an integer; 
    otherwise it fails. 

\ouritem{real(?X)}\index{\texttt{real/1}} 
    Succeeds if {\tt X} is currently instantiated to a floating point number;
    otherwise it fails. 

\ouritem{float(?X)}\index{\texttt{float/1}} 
    Same as {\tt real/1}. Succeeds if {\tt X} is currently instantiated 
    to a floating point number; otherwise it fails.  This predicate is 
    included for compatibility with earlier versions of SBProlog.
	
\ouritem{number(?X)}\index{\texttt{number/1}} 
    Succeeds if {\tt X} is currently instantiated to either an integer or 
    a floating point number (real); otherwise it fails.

\ouritem{atomic(?X)}\index{\texttt{atomic/1}} 
    Succeeds if {\tt X} is currently instantiated to an atom or a number;
    otherwise it fails.

    Examples:
    {\footnotesize
     \begin{verbatim}
                | ?- atomic(10).
                yes
                | ?- atomic(p).
                yes
                | ?- atomic(h).
                yes
                | ?- atomic(h(X)).
                no
                | ?- atomic("foo").
                no
                | ?- atomic('foo').
                yes
                | ?- atomic(X).
                no
                | ?- atomic(X((Y))).
                no
     \end{verbatim}}

\ouritem{compound(?X)}\index{\texttt{compound/1}} 
    Succeeds if {\tt X} is currently instantiated to a compound term (with 
    arity greater that zero), i.e.\ to a nonvariable term that is not atomic;
    otherwise it fails.

    Examples:
    {\footnotesize
     \begin{verbatim}
                | ?- compound(1).
                no
                | ?- compound(foo(1,2,3)).
                yes
                | ?- compound([foo, bar]).
                yes
                | ?- compound("foo").
                yes
                | ?- compound('foo').
                no
                | ?- compound(X(a,b)).
                yes
                | ?- compound((a,b)).
                yes	
     \end{verbatim}}

\ouritem{structure(?X)}\index{\texttt{structure/1}} 
    Same as {\tt compound/1}\@. Its existence is only for compatibility 
    with SB-Prolog version 3.1.

\ouritem{is\_list(?X)}\index{\texttt{is\_list/1}}
    Succeeds if {\tt X} is a {\em proper list}. In other words if it is 
    either the atom {\tt []} or {\tt [H|T]} where H is any Prolog or HiLog
    term and T is a proper list; otherwise it fails.

    Examples:
    {\footnotesize
     \begin{verbatim}
                | ?- is_list([p(a,b,c), h(a,b)]).
                yes
                | ?- is_list([_,_]).
                yes
                | ?- is_list([a,b|X]).
                no
                | ?- is_list([a|b]).
                no
     \end{verbatim}}

\ouritem{is\_charlist(+X)}\index{\texttt{is\_charlist/1}}
    Succeeds if {\tt X} is a Prolog string, {\it i.e.}, a list of
    characters.
    Examples:
    {\footnotesize
     \begin{verbatim}
                | ?- is_charlist("abc").
                yes
                | ?- is_charlist(abc).
                no
     \end{verbatim}}

\ouritem{is\_charlist(+X,-Size)}\index{\texttt{is\_charlist/2}}
    Works as above, but also returns the length of that string in the second
    argument, which must be a variable.

\ouritem{is\_attv(+Term)}\index{\texttt{is\_attv/1}}
    Succeeds is {\tt Term} is an attributed variable, and fails otherwise.

\ouritem{is\_most\_general\_term(?X)}
\index{\texttt{is\_most\_general\_term/1}}
    Succeeds if {\tt X} is compound term with all distinct variables
as arguments, or if {\tt X} is an atom. (It fails if X is a cons node.)
    {\footnotesize
     \begin{verbatim}
                | ?- is_most_general_term(f(_,_,_,_)).
                yes
                | ?- is_most_general_term(abc).
                yes
                | ?- is_most_general_term(f(X,Y,Z,X)).
                no
                | ?- is_most_general_term(f(X,Y,Z,a)).
                no
                | ?- is_most_general_term([_|_]).
                no
     \end{verbatim}}

\ouritem{callable(?X)}\index{\texttt{callable/1}}
    Succeeds if {\tt X} is currently instantiated to a term that standard
    predicate {\tt call/1} could take as an argument and not give an 
    instantiation or type error.  Note that it only checks for errors of
    predicate {\tt call/1}.  In other words it succeeds if {\tt X}
    is an atom or a compound term; otherwise it fails.  Predicate
    {\tt callable/1} has no associated error conditions.

    Examples:
    {\footnotesize
     \begin{verbatim}
                | ?- callable(p).
                yes
                | ?- callable(p(1,2,3)).
                yes
                | ?- callable([_,_]).
                yes
                | ?- callable(_(a)).
                yes
                | ?- callable(3.14).
                no
     \end{verbatim}}

\ournewitem{proper\_hilog(?X)}{HiLog}\index{\texttt{proper\_hilog/1}}
    Succeeds if {\tt X} is a proper HiLog term; otherwise it fails.

    Examples:
    (In this example and the rest of the examples of this section we assume
     that {\tt h} is the only parameter symbol that has been declared a HiLog
     symbol).

    {\footnotesize
     \begin{verbatim}
                | ?- proper_hilog(X).
                no
                | ?- proper_hilog(foo(a,f(b),[A])).
                no
                | ?- proper_hilog(X(a,b,c)).
                yes
                | ?- proper_hilog(3.6(2,4)).
                yes
                | ?- proper_hilog(h).
                no
                | ?- proper_hilog([a, [d, e, X(a)], c]).
                yes
                | ?- proper_hilog(a(a(X(a)))).
                yes
     \end{verbatim}}

\ouritem{functor(?Term, ?Functor, ?Arity)}\index{\texttt{functor/3}}
    Succeeds if the {\em functor} of the Prolog term {\tt Term} is 
    {\tt Functor} and the {\em arity} (number of arguments) of {\tt Term} is
    {\tt Arity}\@.  {\tt Functor} can be used in either the following two 
    ways:
    \begin{enumerate}
    \item If {\tt Term} is initially instantiated, then
          \begin{itemize}
          \item If {\tt Term} is a compound term, {\tt Functor} and 
                {\tt Arity} are unified with the name and arity of 
                its principal functor, respectively. 
          \item If {\tt Term} is an atom or a number, {\tt Functor} is 
                unified with {\tt Term}, and {\tt Arity} is unified with 0.
          \end{itemize}
    \item If {\tt Term} is initially uninstantiated, then either both 
          {\tt Functor} and {\tt Arity} must be instantiated, or {\tt Functor}
          is instantiated to a number, and
          \begin{itemize}
          \item If {\tt Arity} is an integer in the range 1..255, then
                {\tt Term} becomes instantiated to {\em the most general 
                Prolog term} having the specified {\tt Functor} and 
                {\tt Arity} as principal functor and number of arguments,
                respectively. The variables appearing as arguments of 
                {\tt Term} are all distinct.
          \item If {\tt Arity} is 0, then {\tt Functor} must be either an 
                atom or a number and it is unified with {\tt Term}. 
          \item If {\tt Arity} is anything else, then {\tt functor/3} aborts.
          \end{itemize}
    \end{enumerate}

    Exceptions:
    \begin{description}
    \item[{\tt domain\_error}]
	{\tt Functor} is instantiated to a compound term.
    \item[{\tt instantiation\_error}]
	Both {\tt Term}, and either {\tt Functor}, or {\tt Arity} are 
	uninstantiated.
    \end{description}

    Examples:
    {\footnotesize
     \begin{verbatim}
                | ?- functor(p(f(a),b,t), F, A).
                F = p
                A = 3

                | ?- functor(T, foo, 3).
                T = foo(_595708,_595712,_595716)

                | ?- functor(T, 1.3, A).
                T = 1.3
                A = 0

                | ?- functor(foo, F, 0).
                F = foo

                | ?- functor("foo", F, A).
                F = .
                A = 2

                | ?- functor([], [], A).
                A = 0

                | ?- functor([2,3,4], F, A).
                F = .
                A = 2

                | ?- functor(a+b, F, A).
                F = +
                A = 2

                | ?- functor(f(a,b,c), F, A).
                F = f
                A = 3

                | ?- functor(X(a,b,c), F, A).
                F = apply
                A = 4

                | ?- functor(map(P)(a,b), F, A).
                F = apply
                A = 3

                | ?- functor(T, foo(a), 1).
                ++Error: Wrong type in argument 2 of functor/3
                Aborting...

                | ?- functor(T, F, 3).
                ++Error: Uninstantiated argument 2 of functor/3
                Aborting...

                | ?- functor(T, foo, A).
                ++Error: Uninstantiated argument 3 of functor/3
                Aborting...
     \end{verbatim}}

\ournewitem{hilog\_functor(?Term, ?F, ?Arity)}{HiLog}
\index{\texttt{hilog\_functor/3}}
    The XSB standard predicate {\tt hilog\_functor/3} succeeds 
    \begin{itemize}
    \item when {\tt Term} is a Prolog term and the principal function 
          symbol ({\em functor}) of {\tt Term} is {\tt F} and the
          {\em arity} (number of arguments) of {\tt Term} is 
          {\tt Arity}, or
    \item when {\tt Term} is a HiLog term, having {\em name} {\tt F} 
          and the number of arguments {\tt F} is applied to, in the 
          HiLog term, is {\tt Arity}.
    \end{itemize}
    The first of these cases corresponds to the ``usual'' behaviour of
    Prolog's {\tt functor/3}, while the second is the extension of
    {\tt functor/3} to handle HiLog terms. Like the Prolog's {\tt
    functor/3} predicate, {\tt hilog\_functor/3} can be used in either
    of the following two ways:
    \begin{enumerate}
    \item If {\tt Term} is initially instantiated, then
          \begin{itemize}
          \item If {\tt Term} is a Prolog compound term, {\tt F} and 
                {\tt Arity} are unified with the name and arity of 
                its principal functor, respectively.
          \item If {\tt Term} is an atom or a number, {\tt F} is unified 
                with {\tt Term}, and {\tt Arity} is unified with 0.
          \item If {\tt Term} is any other HiLog term, {\tt F} and {\tt Arity} 
                are unified with the name and the number of arguments 
                that {\tt F} is applied to. Note that in this case {\tt F}
                may still be uninstantiated.
          \end{itemize}
    \item If {\tt Term} is initially uninstantiated, then at least
          {\tt Arity} must be instantiated, and
          \begin{itemize}
          \item If {\tt Arity} is an integer in the range 1..255, then
                {\tt Term} becomes instantiated to {\em the most general 
                Prolog or HiLog term} having the specified {\tt F} and 
                {\tt Arity} as name and number of arguments {\tt F} is 
                applied to, respectively. The variables appearing as 
                arguments are all unique.
          \item If {\tt Arity} is 0, then {\tt F} must be a Prolog or
                HiLog constant, and it is unified with {\tt Term}\@. Note
                that in this case {\tt F} cannot be a compound term.
          \item If {\tt Arity} is anything else, then {\tt hilog\_functor/3}
                aborts.
          \end{itemize}
    \end{enumerate}
    In other words, the standard predicate {\tt hilog\_functor/3} either
    decomposes a given HiLog term into its {\em name} and {\em arity}, or
    given an arity ---and possibly a name--- constructs the corresponding 
    HiLog term creating new uninstantiated variables for its arguments. 
    As happens with {\tt functor/3} all constants can be their own 
    principal function symbols.

    Examples:
    {\footnotesize
     \begin{verbatim}
               | ?- hilog_functor(f(a,b,c), F, A).
               F = f
               A = 3

               | ?- hilog_functor(X(a,b,c), F, A).
               X = _595836
               F = _595836
               A = 3

               | ?- hilog_functor(map(P)(a,b), F, A).
               P = _595828
               F = map(_595828)
               A = 2

               | ?- hilog_functor(T, p, 2).
               T = p(_595708,_595712)

               | ?- hilog_functor(T, h, 2).
               T = apply(h,_595712,_595716)

               | ?- hilog_functor(T, X, 3).
               T = apply(_595592,_595736,_595740,_595744)
               X = _595592

               | ?- hilog_functor(T, p(f(a)), 2).
               T = apply(p(f(a)),_595792,_595796)

               | ?- hilog_functor(T, h(p(a))(L1,L2), 1).
               T = apply(apply(apply(h,p(a)),_595984,_595776),_596128)
               L1 = _595984
               L2 = _595776

               | ?- hilog_functor(T, a+b, 3).
               T = apply(a+b,_595820,_595824,_595828)
     \end{verbatim}}

\ouritem{arg(+Index, +Term, ?Argument)}\index{\texttt{arg/3}}
    Unifies {\tt Argument} with the ${\tt Index}^{th}$ argument of 
    {\tt Term}\@, where the index is taken to start at $1$.
    Initially, {\tt Index} must be instantiated to any integer and {\tt Term} 
    to any non-variable Prolog or HiLog term.
    The arguments of the {\tt Term} are numbered from~1 upwards. An atomic term
    has $0$ arguments. If the initial conditions are not satisfied or~$I$ is 
    out of range, the call quietly fails.

    Examples:
    {\footnotesize
     \begin{verbatim}
                   | ?- arg(2, p(a,b), A).
                   A = b

                   | ?- arg(2, h(a,b), A).
                   A = a

                   | ?- arg(0, foo, A).
                   no

                   | ?- arg(2, [a,b,c], A).
                   A = [b,c]

                   | ?- arg(2, "HiLog", A).
                   A = [105,108,111,103]

                   | ?- arg(2, a+b+c, A).
                   A = c

                   | ?- arg(3, X(a,b,c), A).
                   X = _595820 
                   A = b 

                   | ?- arg(2, map(f)(a,b), A).
                   A = a

                   | ?- arg(1, map(f)(a,b), A). 
                   A = map(f)

                   | ?- arg(1, (a+b)(foo,bar), A).
                   A = a+b
     \end{verbatim}}

\ouritem{arg0(+Index, +Term, ?Argument)}\index{\texttt{arg0/3}}
    Unifies {\tt Argument} with the ${\tt Index}^{th}$ argument of {\tt Term}
    if {\tt Index} $>$ 0, or with the functor of {\tt Term} if {\tt Index} = 0.

\ournewitem{hilog\_arg(+Index, +Term, ?Argument)}{HiLog}\index{\texttt{hilog\_arg/3}}
    If {\tt Term} is a Prolog term, it has the same behaviour as {\tt arg/3},
    but if {\tt Term} is a proper HiLog term, {\tt hilog\_arg/3} unifies 
    {\tt Argument} with the 
    $({\tt Index}+1)^{th}$ argument of the Prolog representation of 
    {\tt Term}\@.  Semantically, {\tt Argument} is the ${\tt Index}^{th}$ 
    argument to which the {\em HiLog functor} of {\tt Term} is applied.
    The arguments of the {\tt Term} are numbered from~1 upwards. An atomic term 
    is taken to have $0$ arguments.  
    
    Initially, {\tt Index} must be instantiated to a positive integer and 
    {\tt Term} to any non-variable Prolog or HiLog term.
    If the initial conditions are not satisfied or~$I$ is 
    out of range, the call quietly fails. Note that like {\tt arg/3}
    this predicate does not succeed for {\tt Index}=0.

    Examples:
    {\footnotesize
     \begin{verbatim}
                   | ?- hilog_arg(2, p(a,b), A).
                   A = b

                   | ?- hilog_arg(2, h(a,b), A).
                   A = b

                   | ?- hilog_arg(3, X(a,b,c), A).
                   X = _595820
                   A = c

                   | ?- hilog_arg(1, map(f)(a,b), A).
                   A = a

                   | ?- hilog_arg(2, map(f)(a,b), A).
                   A = b

                   | ?- hilog_arg(1, (a+b)(foo,bar), A).
                   A = foo

                   | ?- hilog_arg(1, apply(foo), A). 
                   A = foo

                   | ?- hilog_arg(1, apply(foo,bar), A).
                   A = bar
     \end{verbatim}}

    Note the difference between the last two examples. The difference is 
    due to the fact that {\tt apply/1} is a Prolog term, while 
    {\tt apply/2} is a proper HiLog term.

\ouritem{?Term =.. [?Functor |?ArgList]}\index{\texttt{=../2}} 
    Succeeds when {\tt Term} is any (Prolog or) HiLog term, {\tt Functor} is 
    its Prolog functor and {\tt ArgList} is the list of its arguments. 
    The use of {\tt =../2} (pronounced {\em univ}) although convenient, 
    can nearly always be avoided.
    Whenever efficiency is critical, it is advisable to use the
    predicates {\tt functor/3} and {\tt arg/3}, since {\tt =../2} is 
    implemented by calls to these predicates.  The behaviour of 
    {\tt =../2} is as follows:
    \begin{itemize}
    \item If initially {\tt Term} is uninstantiated, then the list in the 
          second argument of {\tt =../2} must be instantiated either to a
          {\em proper list} (list of determinate length) whose head is an 
          atom, or to a list of length 1 whose head is a number.
    \item If the arguments of {\tt =../2} are both uninstantiated, or if 
          either of them is not what is expected, {\tt =../2} aborts, 
          producing an appropriate error message.
    \end{itemize}

    Examples:
    {\footnotesize
     \begin{verbatim}
                   | ?- X - 1 =.. L.
                   X = _595692
                   L = [-,_595692,1]

                   | ?- p(a,b,c) =.. L.
                   L = [p,a,b,c]

                   | ?- h(a,b,c) =.. L.
                   L = [apply,h,a,b,c]

                   | ?- map(p)(a,b) =.. L.
                   L = [apply,map(p),a,b]

                   | ?- T =.. [foo].
                   T = foo

                   | ?- T =.. [3|X].
                   T = 3
                   X = []

                   | ?- T =.. [apply,X,a,b].
                   T = apply(X,a,b)

                   | ?- T =.. [1,2].
                   ++Error: Wrong type(s) in argument 2 of =../2
                   Aborting...

                   | ?- T =.. [a+b,2].
                   ++Error: Wrong type(s) in argument 2 of =../2
                   Aborting..

                   | ?- X =.. [foo|Y].
                   ++Error: Argument 2 of =../2 is not a proper list
                   Aborting...
     \end{verbatim}}

     Exceptions:
     \begin{description}
     \item[{\tt instantiation\_error}]
	Argument 2 of {\tt =../2} is not a proper list.
     \item[{\tt type\_error}]
	Head of argument 2 of {\tt =../2} is not an atom or number.
     \end{description}

%in the following line I used a very ``dirty'' LaTeX hack! -- Kostis.

\ournewitem{?Term \^{ }=.. [?F |?ArgList]}{HiLog}\index{\texttt{\^{ }=../2}} 
    When {\tt Term} is a Prolog term, this predicate behaves exactly like
    the Prolog {\tt =../2}. However when {\tt Term} is a proper HiLog term, 
    {\tt \verb|^|=../2} 
    succeeds unifying {\tt F} to its HiLog functor and {\tt ArgList} to the 
    list of the arguments to which this HiLog functor is applied. Like 
    {\tt =../2}, the use of {\tt \verb|^|=../2} can nearly always be avoided
    by using the more efficient predicates {\tt hilog\_functor/3} and 
    {\tt hilog\_arg/3}. The behaviour of {\tt \verb|^|=../2}, on HiLog terms 
    is as follows:
    \begin{itemize}
    \item If initially {\tt Term} is uninstantiated, then the list in the 
          second argument of {\tt \verb|^|=../2} must be instantiated to 
          a {\em proper list} (list of determinate length) whose head can 
          be any Prolog or HiLog term.
    \item If the arguments of {\tt \verb|^|=../2} are both uninstantiated, 
          or if the second of them is not what is expected, 
          {\tt \verb|^|=../2} aborts, producing an appropriate error message.
    \end{itemize}
    Examples:
    {\footnotesize
     \begin{verbatim}
                   | ?- p(a,b,c) ^=.. L.
                   L = [p,a,b,c]

                   | ?- h(a,b,c) ^=.. L.
                   L = [h,a,b,c]

                   | ?- map(p)(a,b) ^=.. L.
                   L = [map(p),a,b]

                   | ?- T ^=.. [X,a,b].
                   T = apply(X,a,b)

                   | ?- T ^=.. [2,2].
                   T = apply(2,2)

                   | ?- T ^=.. [a+b,2].
                   T = apply(a+b,2)

                   | ?- T ^=.. [3|X].
                   ++Error: Argument 2 of ^=../2 is not a proper list
                   Aborting...
     \end{verbatim}}

     Exceptions:
     \begin{description}
     \item[{\tt instantiation\_error}]
	Argument 2 of {\tt \verb|^|=../2} is not a proper list.
     \end{description}

\ouritem{copy\_term(+Term, -Copy)}\index{\texttt{copy\_term/2}}
    Makes a {\tt Copy} of {\tt Term} in which all variables have been
    replaced by brand new variables which occur nowhere else. It can
    be very handy when writing (meta-)interpreters for logic-based
    languages.  The version of {\tt copy\_term/2} provided is {\em space
    efficient} in the sense that it never copies ground terms. 
    Predicate {\tt copy\_term/2} has no associated errors or exceptions.

    Examples:
    {\footnotesize
     \begin{verbatim}
                   | ?- copy_term(X, Y).

                   X = _598948
                   Y = _598904

                   | ?- copy_term(f(a,X), Y).

                   X = _598892
                   Y = f(a,_599112)
     \end{verbatim}}

\end{description}

%-----------------------------------------------------------------------------------------------
\section{Manipulation of Atomic Terms}

\begin{description}

\ouritem{name(?Constant, ?CharList)}\index{\texttt{name/2}} 
    The standard predicate {\tt name/2} performs the conversion 
    between a constant and its character list representation. 
    If {\tt Constant} is supplied (and is any atom or number), {\tt CharList} 
    is unified with a list of ASCII codes representing the {\em ``name''} 
    of the constant.  In that case, {\tt CharList} is exactly the list of 
    ASCII character codes that appear in the printed representation of 
    {\tt Constant}\@.  If on the other hand {\tt Constant} is a variable, 
    then {\tt CharList} must be a proper list of ASCII character codes. 
    In that case, {\tt name/2} will convert a list of ASCII characters 
    that can represent a number to a number rather than to a character string.
    As a consequence of this, there are some atoms (for example \verb|'18'|)
    which cannot be constructed by using {\tt name/2}\@. 
    If conversion to an atom is preferred in these cases, the 
    standard predicate {\tt atom\_codes/2} should be used instead. The 
    syntax for numbers that is accepted by {\tt name/2} is exactly the one 
    which {\tt read/1} accepts.  Predicate {\tt name/2} is provided for 
    backwards compatibility.  It is advisable that new programs use
    the predicates {\tt atom\_codes/2} and {\tt number\_codes/2} described
    below.

    In \version\ predicate {\tt name/2} is not yet implemented for 
    converting from a real number to its character list representation, 
    and if the representation of a real is provided as {\tt CharList}, 
    it will be converted to an atom.

    If both of the arguments of {\tt name/2} are uninstantiated or 
    {\tt CharList} is not a proper list of ASCII characters, {\tt name/2} 
    will abort and an error message will be sent to the standard error stream.

    Examples:
    {\footnotesize
     \begin{verbatim}
                   | ?- name('Foo', L).
                   L = [70,111,111]

                   | ?- name([], L).
                   L = [91,93]

                   | ?- name(431, L).
                   L = [52,51,49]

                   | ?- name(X, [102,111,111]).
                   X = foo
 
                   | ?- name(X, []).
                   X = ''

                   | ?- name(X, "Foo").
                   X = 'Foo'

                   | ?- name(X, [52,51,49]).
                   X = 431

                   | ?- name(X, [45,48,50,49,51]), integer(X).
                   X = -213

                   | ?- name(3.14, L).
                   ++Error: Predicate name/2 for reals is not implemented yet
                   Aborting...
     \end{verbatim}}

     Exceptions:
     \begin{description}
     \item[{\tt instantiation\_error}]
	Both arguments are uninstantiated, or argument 2 of {\tt name/2} 
	contains a variable or is not a proper list.
     \item[{\tt type\_error}]
	{\tt Constant} is not a variable, an atom or a number.
     \item[{\tt range\_error}]
	{\tt CharList} is not a list of ASCII characters.
     \item[{\tt implementation\_error}]
	{\tt Constant} is a real number (conversion from a real to its 
	character list representation is not implemented yet).
     \end{description}

\ouritem{atom\_codes(?Atom, ?CharCodeList)}\index{\texttt{atom\_codes/2}} 
    The standard predicate {\tt atom\_codes/2} performs the conversion 
    between an atom and its character list representation. 
    If {\tt Atom} is supplied (and is an atom), {\tt CharList} 
    is unified with a list of ASCII codes representing the {\em ``name''} 
    of that atom.  In that case, {\tt CharList} is exactly the list of 
    ASCII character codes that appear in the printed representation of 
    {\tt Atom}.  If on the other hand {\tt Atom} is a variable, 
    then {\tt CharList} must be a proper list of ASCII character codes. 
    In that case, {\tt Atom} is instantiated to an atom containing
    exactly those characters, even if the characters look like the
    printed representation of a number.

    If both of the arguments of {\tt atom\_codes/2} are uninstantiated or
    {\tt CharList} is not a proper list of ASCII characters, {\tt
    atom\_codes/2} aborts, and an error message will be sent to
    the standard error stream.

    Examples:
    {\footnotesize
     \begin{verbatim}
                   | ?- atom_codes('Foo', L).
                   L = [70,111,111]

                   | ?- atom_codes([], L).
                   L = [91,93]

                   | ?- atom_codes(X, [102,111,111]).
                   X = foo
 
                   | ?- atom_codes(X, []).
                   X = ''

                   | ?- atom_codes(X, "Foo").
                   X = 'Foo'

                   | ?- atom_codes(X, [52,51,49]).
                   X = '431'

                   | ?- atom_codes(X, [52,51,49]), integer(X).
                   no

                   | ?- atom_codes(X, [52,Y,49]).
                   ! Instantiation error in argument 2 of atom_codes/2
                   ! Aborting...

                   | ?- atom_codes(431, L).
                   ! Type error: in argument 1 of atom_codes/2
                   ! atom expected, but something else found
                   ! Aborting...

                   | ?- atom_codes(X, [52,300,49]).
                   ! Range error: in argument 2 of atom_codes/2
                   ! ASCII code expected, but 300 found
                   ! Aborting...
     \end{verbatim}}

    Exceptions:
    \begin{description}
    \item[{\tt instantiation\_error}]
	Both arguments are uninstantiated, or argument 2
	is not a proper list, or it contains a variable.
    \item[{\tt type\_error}]
	{\tt Atom} is not a variable or an atom.
    \item[{\tt range\_error}]
	{\tt CharList} is not a list of ASCII characters.
    \end{description}

\ouritem{atom\_chars(?Number, ?CharAtomList)}\index{\texttt{atom\_chars/2}} 
    Like \verb|atom_codes|, but the list returned (or input) is a list of
    characters \emph{as atoms} rather than ASCII codes. For instance, 
    \verb|atom_chars(abc,X)| binds {\tt X} to the list {\tt [a,b,c]}
    instead of {\tt [97,98,99]}.

\ouritem{number\_codes(?Number, ?CharCodeList)}\index{\texttt{number\_codes/2}} 
    The standard predicate {\tt number\_codes/2} performs the conversion 
    between a number and its character list representation. 
    If {\tt Number} is supplied (and is a number), {\tt CharList} is
    unified with a list of ASCII codes comprising the printed representation
    of that {\tt Number}.  If on the other hand {\tt Number} is a variable, 
    then {\tt CharList} must be a proper list of ASCII character codes that
    corresponds to the correct syntax of a number (either integer or float)
    In that case, {\tt Number} is instantiated to that number, otherwise
    {\tt number\_codes/2} will simply fail.

    If both of the arguments of {\tt number\_codes/2} are uninstantiated or
    {\tt CharList} is not a proper list of ASCII characters, {\tt
    number\_codes/2} aborts, and an error message will be sent to
    the standard error stream.

    Examples:
    {\footnotesize
     \begin{verbatim}
                   | ?- number_codes(123, L).
                   L = [49,50,51];

                   | ?- number_codes(N, [49,50,51]), integer(N).
                   N = 123

                   | ?- number_codes(31.4e+10, L).
                   L = [51,46,49,51,57,57,57,55,69,43,49,48]

                   | ?- number_codes(N, "314e+8").
                   N = 3.14e+10

                   | ?- number_codes(foo, L).
                   ! Type error: in argument 1 of number_codes/2
                   ! number expected, but something else found
                   ! Aborting...
     \end{verbatim}}

    Exceptions:
    \begin{description}
    \item[{\tt instantiation\_error}]
	Both arguments are uninstantiated, or argument 2
	is not a proper list, or it contains a variable.
    \item[{\tt type\_error}]
	{\tt Number} is not a variable or a number.
    \item[{\tt range\_error}]
	{\tt CharList} is not a list of ASCII characters.
    \end{description}

\ouritem{number\_chars(?Number, ?CharAtomList)}\index{\texttt{number\_chars/2}} 
    Like \verb|number_codes|, but the list returned (or input) is a list of
    characters \emph{as atoms} rather than ASCII codes. For instance, 
    \verb|number_chars(123,X)| binds {\tt X} to the list {\tt ['1','2','3']}
    instead of {\tt [49,50,51]}.

\ouritem{number\_digits(?Number, ?DigitList)}\index{\texttt{number\_digits/2}} 
    Like \verb|number_chars|, but the list returned (or input) is a list of
    digits \emph{as numbers} rather than ASCII codes (for floats, the atom
    '.', '+' or '-', and 'e' will also be present in the list). For instance, 
    \verb|number_digits(123,X)| binds {\tt X} to the list {\tt [1,2,3]}
    instead of {\tt ['1','2','3']}, and \verb|number_digits(123.45,X)|
    binds {\tt X} to {\tt [1,.,2,3,4,5,0,0,e,+,0,2]}.

\ourisousageitem{atom\_concat(Atom1,Atom2,Atom3)}\index{\texttt{atom\_concat/3}}
\ourusage{atom\_concat(?Atom,?Atom,+Atom)}
\ourusage{atom\_concat(+Atom,+Atom,-Atom)}

\ournewitem{term\_to\_atom(+Term,-Atom)}{string}
\index{\texttt{term\_to\_atom/2 }}

This predicate converts an arbitrary Prolog term {\tt Term} into an
atom, putting the result in {\tt Atom}.  It uses a format similar to
the canonical format of {\tt write\_canonical}, but uses a standard
list format for lists.  An atom created from a term using this
predicate can be reconverted back to the original term by using {\tt
atom\_to\_term/2}.

\ournewitem{term\_to\_codes(+Term,-CodeList)}{string}
\index{\texttt{term\_to\_codes/2 }}

This predicate is used in the definition of {\tt term\_to\_atom/2} and 
converts a term into a list of ascii codes.

\end{description}


\section{All Solutions and Aggregate Predicates}
\index{sets, bags} \index{aggregate predicates!prolog}
%-----------------------------------------------------
Often there are many solutions to a problem and it is necessary
somehow to compare these solutions with one another.  The most general
way of doing this is to collect all the solutions into a list, which
may then be processed in any way desired.  So XSB provides
ISO-standard predicates such as {\tt setof/3}, {\tt bagof/3}, and {\tt
findall/3} to collect solutions into lists.  Sometimes however, one
wants simply to perform some aggregate operation over the set of
solutions, for example to find the maximum or minimum of the set of
solutions.  XSB uses tabling and HiLog to provide a general and
powerful aggregation facility as discussed in Section
\ref{tabling_aggregate_predicates}.

\begin{description}
\ouritem{setof(?X, +Goal, ?Set)}\index{\texttt{setof/3}}
    This predicate may be read as ``{\tt Set} is the set of all instances 
    of {\tt X} such that {\tt Goal} is provable''.
    If~{\tt Goal} is not provable, {\tt setof/3} fails.
    The term {\tt Goal} specifies a goal or goals as in {\tt call(Goal)}.
    {\tt Set} is a set of terms represented as a list of those terms,
    without duplicates, in the standard order for terms 
    (see Section~\ref{Comparison}).
    If there are uninstantiated variables in {\tt Goal} which do not also 
    appear in {\tt X}, then a call to this evaluable predicate may backtrack,
    generating alternative values for~{\tt Set} corresponding to different
    instantiations of the free variables of~{\tt Goal}.
    Variables occurring in {\tt Goal} will not be treated as free if they 
    are explicitly bound within~{\tt Goal} by an existential quantifier.
    An existential quantification can be specified as:
    \begin{center}
    {\tt Y \^\ G}\index{\^}
    \end{center}
    meaning there exists a {\tt Y} such that {\tt G} is true,
    where {\tt Y} is some Prolog term (usually, a variable).
  
    Exceptions: Same as predicate {\tt call/1}
		(see Section~\ref{meta_predicates}).

\ouritem{bagof(?X, +Goal, ?Bag)} \index{\texttt{bagof/3}}
    This predicate has the same semantics as {\tt setof/3} except that the 
    third argument returns an unordered list that may contain duplicates.

    Exceptions: Same as predicate {\tt call/1}
		(see Section~\ref{meta_predicates}).

\ouritem{findall(?X, +Goal, ?List)} \index{\texttt{findall/3}}
    Similar to predicate {\tt bagof/3}, except that variables in {\tt Goal}
    that do not occur in {\tt X} are treated as existential, and alternative
    lists are not returned for different bindings of such variables.  This
    makes {\tt findall/3} deterministic (non-backtrackable).  Unlike
    {\tt setof/3} and {\tt bagof/3}, if {\tt Goal} is unsatisfiable,
    {\tt findall/3} succeeds binding {\tt List} to the empty list.

    Exceptions: Same as predicate {\tt call/1}
		(see Section~\ref{meta_predicates}).

\ournewitem{tfindall(?X, +Goal, ?List)}{Tabling}
\index{\texttt{tfindall/3}}
%\predindex{tfindall/3~(L)}
\label{tfindall/3}

    {\em Note: {\tt tfindall/3} may be deprecated in current versions.
    Please use the predicates described in
    Section~\ref{tabling_aggregate_predicates} if possible}.

    Like {\tt findall/3}, {\tt tfindall/3} treats all variables in
    {\tt Goal} that do not occur in {\tt X} as existential.  However,
    in {\tt tfindall/3}, the {\tt Goal} must be a call to a single
    tabled predicate.
	
    {\tt tfindall/3} allows the user to build programs that use
    stratified aggregation.  If the table to {\tt Goal} is incomplete,
    {\tt tfindall/3} suspends until the table has been completed, and
    only then computes {\tt List}.  See Chapter~\ref{chap:TablingOverview}
    for further discussion of {\tt tfindall/3}.  Like {\tt findall/3},
    if {\tt Goal} is unsatisfiable, {\tt tfindall/3} succeeds binding
    {\tt List} to the empty list.

    Some of the differences between predicates {\tt findall/3} and
    {\tt tfindall/3} can be seen from the following example:

    {\footnotesize
    \begin{verbatim}
            | ?- [user].
            [Compiling user]
            :- table p/1.
            p(a).
            p(b).
            [user compiled, cpu time used: 0.639 seconds]
            [user loaded]

            yes
            | ?- p(X), findall(Y, p(Y), L).

            X = a
            Y = _922928
            L = [a];

            X = b
            Y = _922820
            L = [a,b];

            no
            | ?- abolish_all_tables.

            yes
            | ?- p(X), tfindall(Y, p(Y), L).

            X = b
            Y = _922820
            L = [b,a];

            X = a
            Y = _922820
            L = [b,a];

            no
    \end{verbatim}
    }

    Exceptions: Same as predicate {\tt findall/3} (see above).  Also:
    \begin{description}
    \item[{\tt table\_error}]
	Upon execution {\tt Goal} is not a subgoal of a tabled predicate.
    \end{description}

\ournewitem{tbagof(?X, +Goal, ?List) / tsetof(?X, +Goal, ?List)}{Tabling}
\index{\texttt{tsetof/3}}
\index{\texttt{tbagof/3}}

    {\em Note: {\tt tbagof/3} and {\tt tsetof/3} may be deprecated in
    current versions.  Please use the predicates described in
    Section~\ref{tabling_aggregate_predicates} if possible.}

The standard predicates {\tt tbagof/3} and {\tt tsetof/3} provide
tabled versions of {\tt bagof/3} and {\tt setof/3} in a similar manner
to the way in which {\tt tfindall/3} provides a tabled version of {\tt
findall/3}.

\ouritem{X \^\ Goal}
%\predindex{$\wedge/2$~(L)}\index{$\wedge/2$|bold}
    The system recognises this as meaning there exists an {\tt X} such
    that {\tt Goal} is true, and treats it as equivalent to {\tt call(Goal)}.
    The use of this explicit existential quantifier outside predicates
    {\tt setof/3} and {\tt bagof/3} constructs is superfluous.
\end{description}

\subsection{Tabling Aggregate Predicates}\label{tabling_aggregate_predicates}
%-------------------------------------------------------------------------
\index{aggregate predicates!tabling} \index{tabling!aggregate predicates}
%-------------------------------------------------------------------------

HiLog provides an elegant way to introduce aggregate operations into
XSB.  HiLog allows a user to define named (and parameterized) sets (or
bags).  For example, say we have a simple database-like predicate,
\verb|employee(Name,Dept,Sal)|, which contains a tuple for each
employee in our concern and contains the employee's name, department,
and salary.  From this predicate we can construct a set, or bag
really, that contains all the salaries of employees in the relation:
\begin{verbatim}
    :- hilog salaries.
    salaries(Sal) :- employee(_Name,_Dept,Sal).
\end{verbatim}
So \verb|salaries| is the name of a unary predicate that is true of
all salaries, or rather is the name of a {\em bag} of all salaries.
It is a bag since it may contain the same salary multiple times.
XSB provides a predicate \verb|bagSum| which can be used to
sum up the elements in a named bag.  So given the definition of the
HiLog predicate \verb|salaries/1| above, we can get the sum of all the
salaries with:
\begin{verbatim}
    :- bagSum(salaries,TotalSals).
\end{verbatim}
The first argument to \verb|bagSum| is the name of a bag, and the
second is bound to the sum of the elements in the bag.

We can also do a ``group by'' to get total salaries within departments
as follows.  We define a parameterized predicate, \verb|sals(Dept)|,
to be the bag of salaries of employees in department \verb|Dept|, as
follows:
\begin{verbatim}
    sals(Dept)(Sal) :- employee(_Name,Dept,Sal).
\end{verbatim}
This rule says that \verb|Sal| is in the bag named \verb|sals(Dept)|
if there is an employee with some name who works in department
\verb|Dept| and has salary \verb|Sal|.

Now with this definition, we can define a predicate,
\verb|deptPayroll/2|, that associates with each department the sum of
all the salaries of employees in that department:
\begin{verbatim}
    deptPayroll(Dept,Payroll) :- bagSum(sals(Dept),Payroll).
\end{verbatim}

XSB provides analogous aggregate operators, described below, to
compute the minimum, maximum, count, and average, of a bag,
respectively.  These predicates are all defined using a more basic
predicate \verb|bagReduce/4|.

\begin{description}

\ournewitem{bagReduce(?SetPred,?Arg,+Op,+Id)}{HiLog,Tabling}
\ournewitem{filterReduce(?SetPred,?Arg,+Op,+Id)}{Tabling}
\index{\texttt{bagReduce/4}} 
\index{\texttt{filterReduce/4}} 
{\tt SetPred} must be a HiLog set specification, i.e., a unary HiLog
predicate.  {\tt Op} must be a Hilog operation, i.e., a 3-ary HiLog
predicate that defines an associative operator.  The predicate must
define a binary function in which the first two arguments determine
the third.  {\tt Id} must be the identity of the operator.  {\tt
bagReduce} returns with {\tt Arg} bound to the ``reduce'' of the
elements of the bag determined by {\tt SetPred} under the operation
{\tt Op}.  I.e., {\tt Arg} becomes the result of applying the operator
to all the elements in the bag that unify with {\tt SetPred}.  See the
{\tt bagSum} operator below to see an example of {\tt bagReduce}'s
use.

{\tt filterReduce/4} acts as {\tt bagReduce/4} with two differences.
First, it does not depend on HiLog, so that {\tt filterReduce/4} will
be more robust especially when XSB's module system is used.  In
addition, {\tt filterReduce/4} aggregates solutions to {\tt Pred}
using a variance rather than unification.  An example of the use of
{\tt filterReduce/4} is given in Chapter \ref{chap:TablingOverview}.

\ournewitem{bagPO(?SetPred,?Arg,+Order)}{HiLog,Tabling}
\ournewitem{filterPO(?SetPred,?Arg,+Order)}{Tabling}
\index{\texttt{bagPO/3}}
\index{\texttt{filterPO/3}}
    {\tt SetPred} must be a HiLog set specification, i.e., a unary
    HiLog predicate.  {\tt Order} must be a binary Hilog relation that
    defines a partial order.  {\tt bagPO} returns nondeterministically
    with {\tt Arg} bound to the maximal elements, under {\tt Order}, of
    the bag {\tt SetPred}.  {\tt bagPO/3} can be used with {\tt Order}
    being subsumption to reduce a set of answers and keep only the most
    general answers.

    See the {\tt bagMax} operator below to see an example of {\tt
    bagPO}'s use.

{\tt filterPO/3} acts as {\tt bagPO/3} with the single difference that
it does not depend on HiLog, so that {\tt filterPO/3} will be more
robust especially when XSB's module system is used.

\ournewitem{filterPO(\#Pred,+Order)}{Tabling} 
\index{\texttt{filterPO/2}} 

{\tt filterPO(\#Pred,+Order)} succeds only for a solution $Pred\theta$
of {\tt Pred} for which there is no solution $Pred\eta$ to {\tt Pred}
such that {\tt Order($Pred\eta$,$Pred\theta$)}.

Example:

For the following program
     \begin{center}
     {\tt
     \begin{tabular}{l}
          :- table p/2.	\\
          b(1,2).       \\
          p(1,3).       \\
          b(1,1).       \\
\\
	  prefer(b(X,X),b(X,Y)):- X \== Y. 
     \end{tabular}
     }
     \end{center}
the query 
\begin{center}
{\tt ?- filterPO(b(X,Y)}
\end{center}
will succeed only with the binding {\em X = 1,Y = 1}.

\ournewitem{bagMax(?SetPred,?Arg)}{HiLog,Tabling}
\index{\texttt{bagMax/2}}
    {\tt SetPred} must be a HiLog set specification, i.e., a unary
    HiLog predicate.  {\tt bagMax} returns with {\tt Arg} bound to the
    maximum element (under the Prolog term ordering) of the set {\tt
    SetPred}.  To use this predicate, it must be imported from aggregs,
    and you must give the following definitions in the main module {\tt
    usermod}:
\begin{verbatim}
:- hilog maximum.
maximum(X,Y,Z) :- X @< Y -> Z=Y ; Z=X.
\end{verbatim}
    (These decarations are necessary because of a current limitation in
    how HiLog predicates can be used.  This requirement will be lifted in
    a future release.)  With this definition, {\tt bagMax/2} can be (and
    is) defined as follows:
\begin{verbatim}
bagMax(Call,Var) :- bagReduce(Call,Var,maximum,_).
\end{verbatim}
    (Where variables are minimal in the term ordering.)

Another possible definition of {\tt bagMax/2} would be:
\begin{verbatim}
:- hilog lt.
lt(X,Y) :- X @< Y.

bagMax(Call,Var) :- bagPO(Call,Var,lt).
\end{verbatim}
This definition would work, but it is slightly less efficient than the
previous definition since it is known that {\tt bagMax} is
deterministic.

\ournewitem{bagMin(?SetPred,?Arg)}{HiLog,Tabling}
\index{\texttt{bagMin/2}}

    {\tt SetPred} must be a HiLog set specification, i.e., a unary
    HiLog predicate.  {\tt bagMin} returns with {\tt Arg} bound to the
    minimum element (under the Prolog term ordering) of the set {\tt
    SetPred}.  To use this predicate, it must be imported from aggregs,
    and you must give the following definitions in the main module {\tt
    usermod}:
\begin{verbatim}
:- hilog minimum.  
minimum(X,Y,Z) :- X @< Y -> Z=X ; Z=Y.
\end{verbatim}
    (These decarations are necessary because of a current limitation in
    how HiLog predicates can be used.  This requirement will be lifted in
    a future release.)  With this definition, {\tt bagMin/2} can be (and
    is) defined as:
\begin{verbatim}
bagMin(Call,Var) :- bagReduce(Call,Var,minimum,zz(zz)).
\end{verbatim}
    (where structures are the largest elements in the term ordering.)

\ournewitem{bagSum(?SetPred,?Arg)}{HiLog,Tabling}
\index{\texttt{bagSum/2}}
    {\tt SetPred} must be a HiLog set specification, i.e., a unary
    HiLog predicate.  {\tt bagSum} returns with {\tt Arg} bound to the sum
    of the elements of the set {\tt SetPred}.  To use this predicate, it
    must be imported from aggregs, and you must give the following
    definitions in the main module {\tt usermod}:
\begin{verbatim}
:- hilog sum.
sum(X,Y,Z) :- Z is X+Y.
\end{verbatim}
    (These decarations are necessary because of a current limitation in
    how HiLog predicates can be used.  This requirement will be lifted in
    a future release.)  With this definition, {\tt bagSum/2} can be (and
    is) defined as:
\begin{verbatim}
bagSum(Call,Var) :- bagReduce(Call,Var,sum,0).
\end{verbatim}

\ouritem{bagCount(?SetPred,?Arg)}{HiLog,Tabling}
\index{\texttt{bagCount/2}}
    {\tt SetPred} must be a HiLog set specification, i.e., a unary
    HiLog predicate.  {\tt bagCount} returns with {\tt Arg} bound to the
    count (i.e., number) of elements of the set {\tt SetPred}.  To use
    this predicate, it must be imported from aggregs, and you must give
    the following definitions in the main module {\tt usermod}:
\begin{verbatim}
:- hilog successor.
successor(X,_Y,Z) :- Z is X+1.
\end{verbatim}
    (These decarations are necessary because of a current limitation in
    how HiLog predicates can be used.  This requirement will be lifted in
    a future release.)  With this definition, {\tt bagCount/2} can be (and
    is) defined as:
\begin{verbatim}
bagCount(Call,Var) :- bagReduce(Call,Var,successor,0).
\end{verbatim}

\ournewitem{bagAvg(?SetPred,?Arg)}{HiLog,Tabling}
\index{\texttt{bagAvg/2}}
    {\tt SetPred} must be a HiLog set specification, i.e., a unary
    HiLog predicate.  {\tt bagAvg} returns with {\tt Arg} bound to the
    average (i.e., mean) of elements of the set {\tt SetPred}.  To use
    this predicate, it must be imported from aggregs, and you must give
    the following definitions in the main module {\tt usermod}:
\begin{verbatim}
:- hilog sumcount.
sumcount([S|C],X,[S1|C1]) :- S1 is S+X, C1 is C+1.
\end{verbatim}
    (These decarations are necessary because of a current limitation in
    how HiLog predicates can be used.  This requirement will be lifted in
    a future release.)  With this definition, {\tt bagAvg/2} can be (and
    is) defined as:
\begin{verbatim}
bagAvg(Call,Avg) :- 
    bagReduce(Call,[Sum|Count],sumcount,[0|0]),
    Avg is Sum/Count.
\end{verbatim}

\end{description}

%-------------------------------------------------------------------------

\section{Meta-Predicates} \label{meta_predicates}
\begin{description}
\ouritem{call(\#X)}\index{\texttt{call/1}} 
%\predindex{call/1~(P)}
    If {\tt X} is a nonvariable term in the program text, then it is 
    executed exactly as if {\tt X} appeared in the program text instead 
    of {\tt call(X)},
    e.g.
    \begin{center}
        {\tt $\ldots$, p(a), call( (q(X), r(Y)) ), s(X), $\ldots$}
    \end{center}
    is equivalent to
    \begin{center}
        {\tt $\ldots$, p(a), q(X), r(Y), s(X), $\ldots$}
    \end{center}
    However, if {\tt X} is a variable in the program text,
    then if at runtime {\tt X} is instantiated to a term which 
    would be acceptable as the body of a clause, the goal 
    {\tt call(X)} is executed as if that
    term appeared textually in place of the {\tt call(X)},
    {\em except that} any cut (`!')\index{\texttt{"!/0}}\index{cut}
    occurring in {\tt X} will remove only those choice points in~{\tt X}.
    If~{\tt X} is not instantiated as described above,
    an error message is printed and {\tt call/1} fails.

    Exceptions:
    \begin{description}
    \item[{\tt instantiation\_error}]
	Argument 1 of {\tt call/1} is not instantiated.
     \item[{\tt type\_error}]
	Argument 1 of {\tt call/1} is not a callable term.
    \end{description}

\ouritem{\#X}					      
    (where {\tt X} is a variable) executes exactly the same as 
    {\tt call(X)}.
    However, the explicit use of {\tt call/1} is considered better
    programming practice.  The use of a top level variable subgoal
    elicits a warning from the compiler.

\ouritem{once(\#X)}
\index{\texttt{once/1}} 
    {\tt once/1} is defined as {\tt once(X):- call(X),!.}  {\tt
    once/1} should be used with care in tabled programs.  The compiler
    can not determine whether a tabled predicate is called in the
    scope of {\tt once/1}, and such a call may lead to runtime errors.
    If a tabled predicate may occur in the scope of {\tt once/1}, use
    {\tt table\_once/1} instead.

    Exceptions: The same as {\tt call/1}.

\ouritem{table\_once(\#X)}
\index{\texttt{table\_once/1}} 
    {\tt table\_once/1} is a weaker form of {\tt once/1}, suitable for
    situations in which a single solution is desired for a
    subcomputation that may involve a call to a tabled predicate.  {\tt
    table\_once(?Pred)} succeeds only once even if there are many
    solutions to the subgoal {\tt Pred}.  However, it does not ``cut
    over'' the subcomputation started by the subgoal {\tt Pred},
    thereby ensuring the correct evaluation of tabled subgoals.

\end{description}


%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "manual1"
%%% End: 
