                 University of Amsterdam

                    Dept.  of Social
                   Science Informatics
                         (SWI)
                  Herengracht 196, 1016
                     BS   Amsterdam
                     The Netherlands
                  Tel.  (+31) 20 5252073

                       SWI-Prolog 1.6

                      Reference Manual

                       Jan Wielemaker

                     jan@swi.psy.uva.nl

SWI-Prolog is a WAM (Warren Abstract Machine, ) based
implementation of Prolog.  SWI-Prolog has been designed and
implemented such that it can easily be modified for experiments
with logic programming and the relation between logic
programming and other programming paradigms (such as the object
oriented PCE environment, ).  SWI-Prolog has a rich set of
built-in predicates and reasonable performance, which makes it
possible to develop substantial applications in it.  The current
version offers a module system, garbage collection and an
interface to the C language.

This document gives an overview of the features, system limits
and built-in predicates.

Copyright (C) 1990 Jan Wielemaker


Chapter  1

Introduction

SWI-Prolog has been designed and implemented to get a Prolog
implementation which can be used for experiments with logic programming
and the relation to other programming paradigms.  The intention was to
build a Prolog environment which offers enough power and flexibility to
write substantial applications, but is straightforward enough to be
modified for experiments with debugging, optimisation or the introduction
of non-standard data types.  Performance optimisation is limited due to
the main objectives:  portability (SWI-Prolog is entirely written in C and
Prolog) and modifiability.

SWI-Prolog is based on a very restricted form of the WAM (Warren Abstract
Machine) described in  which defines only 7 instructions.  Prolog can
easily be compiled into this language and the abstract machine code is
easily decompiled back into Prolog.  As it is also possible to wire a
standard 4-port debugger in the WAM interpreter there is no need for a
distinction between compiled and interpreted code.  Besides simplifying
the design of the Prolog system itself this approach has advantages for
program development:  the compiler is simple and fast, the user does not
have to decide in advance whether debugging is required and the system
only runs slightly slower when in debug mode.  The price we have to pay is
some performance degradation (taking out the debugger from the WAM
interpreter improves performance by about 20%) and somewhat additional
memory usage to help the decompiler and debugger.

SWI-Prolog extends the minimal set of instructions described in  to
improve performance.  While extending this set care has been taken to
maintain the advantages of decompilation and tracing of compiled code.
The extensions include specialised instructions for unification, predicate
invocation, some frequently used built-in predicates, arithmetic, or (;/2,
|/2), if-then (->/2) and not (\+/1).

This manual does not describe the full syntax and semantics of SWI-Prolog,
nor how one should write a program in Prolog.  These subjects have been
described extensively in the literature.  See ,  and .  For more advanced
Prolog material see .  Syntax and standard operator declarations confirm
to the `Edinburgh standard'.  Most built in predicates are compatible with
those described in .  SWI-Prolog also offers a number of primitive
predicates compatible with Quintus Prolog,  and BIM_Prolog .

                                 1


1.1 Status

This manual describes version 1.6.0 of SWI-Prolog.  SWI-Prolog has been
used now for some years.  The application range includes Prolog course
material, meta-interpreters, simulation of parallel Prolog, learning
systems and a large workbench for knowledge engineering.  Although we
experienced rather obvious and critical bugs can remain unnoticed for a
remarkable long period, we can assume the basic Prolog system to be fairly
stable.  Bugs can be expected in unfrequently used builtin predicates.

Some bugs are known to the author.  They are described as footnotes in
this manual.


1.2 Should you be Using SWI-Prolog?

There are a number of reasons why you better choose a commercial Prolog
system, or another academic product:

    SWI-Prolog is not supported
    Although I usually fix bugs shortly after a bug report arrives, I
    cannot promise anything.  Now that the sources are provided, you can
    always dig into them yourself.

    Memory requirements and performance are your first concerns
    A number of commercial compilers are more keen on memory and
    performance than SWI-Prolog.  I do not wish to offer some of the nice
    features of the system, nor its portability to compete on raw
    performance.

    You need features not offered by SWI-Prolog
    In this case you may wish to give me suggestions for extensions.  If
    you have great plans, please contact me (you might have to implement
    them yourself however).

On the other hand, SWI-Prolog offers some nice facilities:

    Nice environment
    This includes `Do What I Mean', automatic completion of atom names,
    history mechanism and a tracer that operates on single key-strokes.
    Interfaces to standard Unix editors are provided, as well as a
    facility to maintain programs (see make/0).

    Very fast compiler
    The compiler handles about 5K bytes per second per MIPS (i.e.  35K
    bytes per second on SUN-4/110).

    Transparent compiled code
    SWI-Prolog compiled code can be treated just as interpreted code:
    you can list it, trace it, assert from or retract to it, etc.  This
    implies you do not have to decide beforehand whether a module should
    be loaded for debugging or not.  Also, performance is much better
    than the performance of most interpreters.

    Profiling
    SWI-Prolog offers tools for performance analysis, which can be very
    useful to optimise programs.  Unless you are very familiar with
    Prolog and Prolog performance considerations this might be more
    helpful than a better compiler without these facilities.

    Flexibility
    SWI-Prolog allows for easy and flexible integration with C, both
    Prolog calling C functions as C calling Prolog predicates.
    SWI-Prolog is provided in source form, which implies SWI-Prolog can
    be linked in with another package.  Command line options and
    predicates to obtain information from the system and feedback into
    the system are provided.

    Integration with PCE
    SWI-Prolog offers a tight integration to the Object Oriented Package
    for User Interface Development, called PCE ().  PCE is now also
    available for X-windows.


1.3 Version 1.5 Release Notes

There are not many changes between version 1.4 and 1.5.  The C-sources
have been cleaned and comments have been updated.  The stack memory
management based on using the MMU has been changed to run on a number of
system-V Unix systems offering shared memory.  Handling dates has been
changed.  All functions handling dates now return a floating point number,
expressing the time in seconds since january 1, 1970.  A predicate
convert_time/8 is available to get the year, month, etc.  The predicate
time/6 has been deleted.  get_time/1 and convert_time/8 together do the
same.

From version 1.5, the system is distributed in source form, rather than in
object form as used with previous releases.  This allows users to port
SWI-Prolog to new machines, extend and improve the system.  If you want
your changes to be incorporated in the next release, please indicate all
changes using a C-preprocessor flag and send complete source files back to
me.  Difference listings are of no use, as I generally won't have exactly
the same version around.


1.4 Version 1.6 Release Notes

Version 1.6 is completely compatible with version 1.5.  Some new features
have been added, the system has been ported to various new platforms and
there is a provisional interface to GNU-Emacs.  This interface will be
improved and documented later.

The WAM virtual-machine interpreter has been modified to use GCC-2's
support for threated code.

From version 1.6, the sources are now versioned using the CVS version
control system.


1.5 Portability

The table below shows which machine dependent features have been ported to
which architectures.  Some of the minus signs could be taken away by
spending more effort to the port, others are due to fundamental omisions
or bugs in the operating system.  Note that the column `C-interface'
implies object code can be linked dynamically from a running Prolog
environment.  For systems that have a minus here C-code can still be added
by relinking SWI-Prolog itself together with the C-extensions to form an
extended version of SWI-Prolog.

 Machine         OS          Dynamic      C        Saved   Profile
                             Stacks    Interface  States
 SUN-3 and 4     SunOs 4        +         +         +         +
 HP 9000s300     HP-UX 8.0     --         +         +         +
 DEC MIPS        Ultrix 3.1    --         --        +         +
 Gould PN        UTX-2.1        +         --        --        +
 IBM PS2         AIX 2.0       --         --        +         +
 IBM RISC-6000   AIX 3.1       --         +         +         +
 VAX             Ultrix        --         +         +         +
 ATARI           TOS 1.3       --         --        --       --
 PC              LINUX         --         --        --       --


1.6 Acknowledgements

Some small parts of the Prolog code of SWI-Prolog are modified versions of
the corresponding Edinburgh C-Prolog code:  grammar rule compilation and
writef/2.  Also some of the C-code originates from C-Prolog:  finding the
path of the currently running executable and the code underlying
absolute_file_name/2.  Ideas on programming style and techniques originate
from C-Prolog and Richard O'Keefe's thief editor.  An important source of
inspiration are the programming techniques introduced by Anjo Anjewierden
in PCE version 1 and 2.

I also would like to thank those who had the fade of using the early
versions of this system, suggested extensions or reported bugs.  Among
them are Anjo Anjewierden, Huub Knops, Bob Wielinga, Wouter Jansweijer,
Luc Peerdeman, Eric Nombden, Frank van Harmelen, Bert Rengel.


Chapter  2

Overview

                                 8


2.1 Starting SWI-Prolog from the Unix Shell

It is advised to install SWI-Prolog as `pl' in the local binary directory.
SWI-Prolog can then be started from the Unix shell by typing `pl'.  The
system will boot from the system's default boot file, perform the
necessary initialisations and then enter the interactive top level.

After the necessary system initialisation the system consults (see
consult/1) the user's initialisation file.  This initialisation file
should be named `.plrc' and reside either in the current directory or in
the user's home directory.  If both exist the initialisation file from the
current directory is loaded.  The name of the initialisation file can be
changed with the `-f file' option.  After loading the initialisation file
SWI-Prolog executes a user initialisation goal.  The default goal is a
system predicate that prints the banner message.  The default can be
modified with the `-g goal' option.  Next the toplevel goal is started.
Default is the interactive Prolog loop (see prolog/0).  The user can
overwrite this default with the `-t toplevel' option.


2.1.1 Command Line Options

The full set of command line options is given below:

    -Lsize
        Give local stack size in K bytes (200 K default).  Note that
        there is no space between the size option and its argument.
        For machines with dynamic stack allocation this flag sets
        the maximum value to which the stack is allowed to grow (2
        Mbytes default).  A maximum is useful to stop buggy programs
        from claiming all memory resources.  -L0 sets the limit to
        the highest possible value.
    -Gsize
        Give global stack size in K bytes (100 K default).  For
        machines with dynamic stack allocation the default is 4
        Mbytes.  See -L for more details.
    -Tsize
        Give trail stack size in K bytes (50 K default).  For
        machines with dynamic stack allocation the default is 4
        Mbytes.  See -L for more details.
    -Asize
        Give argument stack size in K bytes (5 K default).  For
        machines with dynamic stack allocation the default is 1
        Mbytes.  See -L for more details.
    -c file ...
        Compile files into an `intermediate code file'.  See
        section 2.6.
    -o output
        Used in combination with -c or -b to determine output file
        for compilation.
    -O
        Optimised compilation.  See please/3.
    -f file
        Use file as initialisation file instead of `.plrc'.
        `-f none' stops SWI-Prolog from searching for an
        initialisation file.
    -g goal
        Goal is executed just before entering the top level.
        Default is a predicate which prints the welcome message.
        The welcome message can thus be suppressed by giving
        -g true.  goal can be a complex term.  In this case quotes
        are normally needed to protect it from being expanded by the
        Unix shell.
    -t goal
        Use goal as interactive toplevel instead of the default goal
        prolog/0.  goal can be a complex term.  If the toplevel goal
        succeeds SWI-Prolog exits with status 0.  If it fails the
        exit status is 1.  This flag also determines the goal
        started by break/0 and abort/0.  If you want to stop the
        user from entering interactive mode start the application
        with `-g goal' and give `halt' as toplevel.
    +/-tty
        Switches tty control (using ioctl(2)) on (+tty) or off
        (-tty).  Normally tty control is switched on.  This default
        depends on the installation.  You may wish to switch tty
        control off if Prolog is used from an editor such as GNU
        EMACS. If switched off get_single_char/1 and the tracer will
        wait for a return.
    -x bootfile
        Boot from bootfile instead of the system's default boot
        file.  A bootfile is a file resulting from a Prolog
        compilation using the -b or -c option.

The following options are for system maintenance.  They are given for
reference only.

    -b initfile ...  -c file ...
        Boot compilation.  initfile ...are compiled by the
        C-written bootstrap compiler, file ...by the normal Prolog
        compiler.  System maintenance only.
    -d level
        Set debug level to level.  System maintenance only.


2.2 GNU Emacs Interface

A provisional interface to GNU-Emacs is delivered with version 1.6 of
SWI-Prolog.  The interface is based on the freely distributed interface
delivered with Quintus Prolog.  When running Prolog as an inferior process
under GNU-Emacs, there is support for finding predicate definitions,
completing atoms, finding the locations of compilation-warnings and many
more.  For details, see the files pl/lisp/README and
pl/lisp/swi-prolog.el.


2.3 Online Help

Online help provides a fast lookup and browsing facility to this manual.
The online manual can show predicate definitions as well as entire
sections of the manual.


help
    Equivalent to help(help/1).


help(+What)
    Show specified part of the manual.  What is one of:

         Name/Arity   give help on specified predicate

         Name         give help on named predicate with any arity
                      or C interface function with that name
         Section      display specified section.  section numbers
                      are dash-separated numbers:  2-3 refers to
                      section 2.3 of the manual.  Section numbers
                      are obtained using apropos/1.

    Examples

      ?- help(assert).     give help on predicate assert

      ?- help(3-4).        display section 3.4 of the manual

      ?- help('PL_retry'). give help on interface function PL_retry()


apropos(+Pattern)
    Display all predicates, functions and sections that have Pattern in
    their name or summary description.  Lowercase letters in Pattern also
    match a corresponding uppercase letter.  Example:

      ?- apropos(file).  Display predicates, functions and sections
                         that have `file' (or `File', etc.)  in their
                         summary description.


2.4 Query Substitutions

SWI-Prolog offers a query substitution mechanism similar to that of Unix
csh (csh(1)), called `history'.  It allows the user to compose new queries
from those typed before and remembered by the system.  It also allows to
correct queries and syntax errors.  SWI-Prolog does not offer the Unix csh
capabilities to include arguments.  This is omitted as it is unclear how
the first, second, etc. argument should be defined.

The available history commands are shown in table 2.1.  Figure 2.1 gives
some examples.

       !!.             Repeat last query
       !nr.            Repeat query numbered <nr>
       !str.           Repeat last query starting with <str>
       !?str.          Repeat last query holding <str>
       ^old^new.       Substitute <old> into <new> of last query
       !nr^old^new.    Substitute in query numbered <nr>
       !str^old^new.   Substitute in query starting with <str>
       !?str^old^new.  Substitute in query holding <str>
       h.              Show history list
       !h.             Show this list

                    Table 2.1:  History commands

    /u4/staff/jan/.plrc consulted, 0.066667 seconds, 591 bytes
    Welcome to SWI-Prolog (version 1.5.0, August 1990)
    Copyright (c) 1990, University of Amsterdam. All rights reserved.

    1 ?- append("Hello ", "World", L).

    L = [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

    Yes
    2 ?- !!, writef('L = %s\n', [L]).
    append("Hello ", "World", L), writef('L = %s\n', [L]).
    L = Hello World

    L = [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

    Yes
    3 ?- sublist(integer, [3, f, 3.4], L).

    L = [3]

    Yes
    4 ?- ^integer^number.
    sublist(number, [3, f, 3.4], L).

    L = [3, 3.400000]

    Yes
    5 ?- h.
        1   append("Hello ", "World", L).
        2   append("Hello ", "World", L), writef('L = %s\n', [L]).
        3   sublist(integer, [3, f, 3.4], L).
        4   sublist(number, [3, f, 3.4], L).

    5 ?- !2^World^Universe.
    append("Hello ", "Universe", L), writef('L = %s\n', [L]).
    L = Hello Universe

    L = [72, 101, 108, 108, 111, 32, 85, 110, 105, 118, 101, 114, 115,
    101]

    Yes
    6 ?- halt.

           Figure 2.1:  Some examples of the history facility


2.4.1 Limitations of the History System

When in top level SWI-Prolog reads the user's queries using history_read/6
rather than read/1.  This predicate first reads the current input stream
up to a full stop.  While doing so it maps all contiguous blank space onto
a single space and deletes /* ... */ and % ... <cr> comments.  Parts
between double quotes (") or single quotes (') are left unaltered.  Note
that a Prolog full stop consists of a `non-symbol' character, followed by
a period (.), followed by a blank character.  `Symbol' characters are:
#$&*+-./:<=>?@^`~.  A single quote immediately preceded by a digit (0-9)
considered part of the <digit>'<digit>... (e.g.  2'101; binary number 101)
sequence.

After this initial parsing the result is first checked for the special
^old^new. construction.  If this fails the string is checked for all
occurrences of the !, followed by a !, ?, a digit, a letter or an
underscore.  These special sequences are analysed and the appropriate
substitution from the history list is made.

From the above it follows that it is hard or impossible to correct
quotation with single or double quotes, comment delimiters and spacing.


2.5 Overview of the Debugger

SWI-Prolog has a standard 4-port tracer  with an optional fifth port.
This fifth port, called unify allows the user to inspect the result after
unification of the head.  The ports are called call, exit, redo, fail and
unify.  The tracer is started by the trace/0 command, when a spy point is
reached and the system is in debugging mode (see spy/1 and debug/1) or
when an error is detected at run time.  Note that in the interactive
toplevel goal trace/0 means ``trace the next query''.  The tracer shows
the port, displaying the port name, the current depth of the recursion and
the goal.  The goal is printed using the Prolog predicate print/1
(default), write/1 or display/1.  An example using all five ports is shown
in figure 2.2.

    Yes
    2 ?- visible(+all), leash(-exit).

    Yes
    3 ?- trace, min([3, 2], X).
      Call:  ( 3) min([3, 2], G235) ? creep
      Unify: ( 3) min([3, 2], G235)
      Call:  ( 4) min([2], G244) ? creep
      Unify: ( 4) min([2], 2)
      Exit:  ( 4) min([2], 2)
      Call:  ( 4) min(3, 2, G235) ? creep
      Unify: ( 4) min(3, 2, G235)
      Call:  ( 5) 3 < 2 ? creep
      Fail:  ( 5) 3 < 2 ? creep
      Redo:  ( 4) min(3, 2, G235) ? creep
      Exit:  ( 4) min(3, 2, 2)
      Exit:  ( 3) min([3, 2], 2)

                     Figure 2.2:  Example trace

On leashed ports (set with the predicate leash/1, default are call, exit,
redo and fail) the user is prompted for an action.  All actions are single
character commands which are executed without waiting for a return (Unix
`cbreak' mode), unless the command line option -tty is active.  Tracer
options:

+   Spy                all
    Set a spy point (see spy/1) on the current predicate.

    No spy             all
    Remove the spy point (see nospy/1) from the current predicate.

/   Find               all
    Search for a port.  After the `/', the user can enter a line to
    specify the port to search for.  This line consists of a set of
    letters indicating the port type, followed by an optional term, that
    should unify with the goal run by the port.  If no term is specified
    it is taken as a variable, searching for any port of the specified
    type.  If an atom is given, any goal whose functor has a name equal
    to that atom matches.  Examples:

          /f               Search for any fail port

          /fe solve        Search for a fail or exit port of any
                           goal with name solve

          /c solve(a, _)   Search for a call to solve/2 whose
                           first argument is a variable or the
                           atom a
          /a member(_, _)  Search for any port on member/2.
                           This is equivalent to setting a spy
                           point on member/2.

.   Repeat find        all
    Repeat the last find command (see `/')

A   Alternatives       all
    Show all goals that have alternatives.

C   Context            all
    Toggle `Show Context'.  If on the context module of the goal is
    displayed between square brackets (see section 4).  Default is off.

L   Listing            all
    List the current predicate with listing/1.

a   Abort              all
    Abort Prolog execution (see abort/0).

b   Break              all
    Enter a Prolog break environment (see break/0).

c   Creep              all
    Continue execution, stop at next port.  (Also return, space).

d   Display            all
    Write goals using the Prolog predicate display/1.

e   Exit               all
    Terminate Prolog (see halt/0).

f   Fail         call, redo, exit
    Force failure of the current goal

g   Goals              all
    Show the list of parent goals (the execution stack).  Note that due
    to tail recursion optimization a number of parent goals might not
    exist any more.

h   Help               all
    Show available options (also `?').

i   Ignore       call, redo, fail
    Ignore the current goal, pretending it succeeded.

l   Leap               all
    Continue execution, stop at next spy point.

n   No debug           all
    Continue execution in `no debug' mode.

p   Print              all
    Write goals using the Prolog predicate print/1 (default).

r   Retry        redo, exit, fail
    Undo all actions (except for database and i/o actions) back to the
    call port of the current goal and resume execution at the call port.

s   Skip            call, redo
    Continue execution, stop at the next port of this goal (thus skipping
    all calls to children of this goal).

u   Up                 all
    Continue execution, stop at the next port of the parent goal (thus
    skipping this goal and all calls to children of this goal).  This
    option is useful to stop tracing a failure driven loop.

w   Write              all
    Write goals using the Prolog predicate write/1.

The ideal 4 port model as described in many Prolog books  is not visible
in many Prolog implementations because code optimisation removes part of
the choice- and exit points.  Backtrack points are not shown if either the
goal succeeded deterministically or its alternatives were removed using
the cut.  When running in debug mode (debug/0) choice points are only
destroyed when removed by the cut.  In debug mode tail recursion
optimisation is switched off.


2.6 Compilation

Collections of SWI-Prolog source files can be compiled into an
intermediate code file.  An intermediate code file is a data file from
which SWI-Prolog can be started.  The command to compile a bundle of
source files is:

    pl [options] [-o output] -c file ...

The individual source files may include other files using the standard
list notation, consult/1, ensure_loaded/1 and use_module/[1,2].  When the
-o fileoption is omitted a file named a.out is created that holds the
intermediate code file.

Intermediate code files start with the BSD Unix magic code #! and are
executable.  This implies they can be started as a command:

    sun% pl -o my_program -c ...
    ...
    sun% my_program [options]

Alternatively, my_program can be started with

    sun% pl -x my_program [options]

The following restrictions apply to source files that are to be compiled
with `-c':

    term_expansion/2 should not use assert/1 and or retract/1 other than
    for local computational purposes.

    Files can only be included by the standard include directives:
    [...], consult/1, ensure_loaded/1 and use_module/[1,2].  User defined
    loading predicate invocations will not be compiled.

Directives are executed both when compiling the program and when loading
the intermediate code file.


2.7 Environment Control


please(+Key, -Old, +New)
    The predicate please/3 is a solution to avoid large numbers of
    environment control predicates.  Later versions will support other
    environment control as now provided via the predicates style_check/2,
    leash/1, unknown/2, the tracer predicates, etc.  These predicates are
    then moved into a library for backwards compatibility.  The currently
    available options are:

    optimise on/off (default:  off)
        Switch optimise mode for the compiler on or off (see also the
        command line option -O).  Currently optimised compilation only
        implies compilation of arithmetic, making it fast, but invisible
        to the tracer.  Later versions might imply various other
        optimisations such as incorporating a number of basic predicates
        in the virtual machine (var/1, fail/0, =/2, etc.)  to gain speed
        at the cost of crippling the debugger.  Also source level
        optimisations such as integrating small predicates into their
        callers, eliminating constant expressions and other predictable
        constructs.  Source code optimisation is never applied to
        predicates that are declared dynamic (see dynamic/1).

    autoload on/off (default:  on)
        If on autoloading of library functions is enabled.  If off
        autoloading is disabled.  See section 2.9.

    verbose_autoload on/off (default:  off)
        If on the normal consult message will be printed if a library is
        autoloaded.  By default this message is suppressed.  Intended to
        be used for debugging purposes (e.g. where does this predicate
        come from?).


2.8 Stand Alone Executables (Saved States)

The introduction of a foreign language interface raised the problem of
incorporating the compiled foreign code into SWI-Prolog to create a new
stand alone executable.  The current also allows one to create
applications that do not need any of the SWI-Prolog system files.


save_program(+NewProgram, +ListOfOptions)
    Create a new executable wich will be named NewProgram.  ListOfOptions
    is a list of Key = Valuepairs that specify the default command line
    options that will be saved into the new program.  If a default is not
    specified the default compiled into the currently running Prolog
    executable is used.  The available keys are given in table 2.2

    Key         Option     Type    Description
    local         -L     K-bytes   Size (Limit) of local stack
    global        -G     K-bytes   Size (Limit) of global stack
    trail         -T     K-bytes   Size (Limit) of trail stack
    argument      -A     K-bytes   Size (Limit) of argument stack
    goal          -g       atom    Initialisation goal
    toplevel      -t       atom    Prolog toplevel goal
    init_file     -f       atom    Personal initialisation file
    tty         +/--tty   on/off   Use ioctl(2) calls

            Table 2.2:  Key = Value pairs for save_program/2

    As the entire data image of the current process will be saved on the
    new executable it is desirable to keep this small.  Notably the
    Prolog machine stacks should be kept small.  The best way to do this
    is first to compile the program using the -c option.  If this is not
    possible try to find the smallest possible stack sizes to compile the
    program.  On machines with dynamic stack allocation the stacks are
    not written to file and so their size does not matter.  Figure 2.3
    shows a possible session.  Note the use of `initialise', which is
    supposed to be a predicate of the application doing time consuming
    initialisation.

   sun% pl -c load
   foreign file dbase loaded 0.066667 seconds, 1578 bytes.
   setup consulted, 0.500000 seconds, 5091 bytes.
   main consulted, 0.333333 seconds, 3352 bytes.
   load consulted, 1.000000 seconds, 9867 bytes.
   sun% a.out -f none -L10 -G10 -T5
   foreign file dbase loaded 0.066667 seconds, 1578 bytes.
   Welcome to SWI-Prolog (version 1.5.0, August 1990)
   Copyright (c) 1990, University of Amsterdam. All rights reserved.

   1 ?- initialise.

   Yes
   2 ?- save_program(my_program,
           [ local     = 500
           , goal      = go
           , init_file = none
           ]).
   Running executable: /usr/local/bin/pl
   Saving to my_program; text: 204800 ... data: 357000 ... symbols ...
   done.
   Yes
   2 ?- halt.
   sun%

             Figure 2.3:  Create a stand-alone executable

    The resulting program can be used for incremental compilation using
    -c or another save_program/2.


save_program(+NewProgram)
    Equivalent to `save_program(NewProgram, [])'.


2.9 Automatic loading of libraries

If ---at runtime--- an undefined predicate is trapped the system will
first try to import the predicate from the module's default module.  If
this fails the auto loader is activated.  On first activation an index to
all library files in all library directories is loaded in core (see
library_directory/1).  If the undefined predicate can be located in the
one of the libraries that library file is automatically loaded and the
call to the (previously undefined) predicate is resumed.  By default this
mechanism loads the file silently.  The please/3 option verbose_autoload
is provided to get verbose loading.  The please option autoloadcan be
used to enable/disable the entire auto load system.

Autoloading only handles (library) source files that use the module
mechanism described in chapter 4.  The files are loaded with use_module/2
and only the trapped undefined predicate will be imported to the module
where the undefined predicate was called.  Each library directory must
hold a file INDEX.plthat contains an index to all library files in the
directory.  This file consists of lines of the following format:

    index(Name, Arity, Module, File).

The predicate make/0 scans the autoload libraries and updates the index if
it exists, is writable and out-of-date.  It is adviced to create an empty
file called INDEX.plin a library directory meant for auto loading before
doing anything else.  This index file can then be updated by running the
prolog predicate make/0 (`%' is the Unix prompt):

    % mkdir ~/lib/prolog
    % cd !$
    % touch INDEX.pl
    %     <create library files>
    % pl -g true -t make
     index for library . ... ok.
    %

If there are more than one library files containing the desired predicate
the following search schema is followed:

 1. If a there is a library file that defines the module in which the
    undefined predicate is trapped, this file is used.

 2. Otherwise library files are considered in the order they appear in
    the library_directory/1 predicate and within the directory
    alphabetically.


2.9.1 Notes on Automatic Loading

The autoloader is a new feature to SWI-Prolog.  Its aim is to simplify
program development and program management.  Common lisp has a similar
feature, but here the user has to specify which library is to be loaded if
a specific function is called which is not defined.  The advantage of the
SWI-Prolog schema is that the user does not have to specify this.  The
disadvantage however is that the user might be wondering ``where the hell
this predicate comes from''.  Only experience can learn whether the
functionality of the autoloader is appropriate.  Comments are welcome.

The autoloader only works if the unknown flag (see unknown/2) is set to
trace(default).  A more appropriate interaction with this flag will be
considered.


2.10 Garbage Collection

SWI-Prolog version 1.4 was the first release to support garbage
collection.  Together with tail-recursion optimisation this guaranties
forward chaining programs do not waste indefinite amounts of memory.
Previous releases of this manual stressed on using failure-driven loops in
those cases that no information needed to be passed to the next iteration
via arguments.  This to avoid large amounts of garbage.  This is no longer
stricktly necessary, but it should be noticed that garbage collection is a
time consuming activity.  Failure driven loops tend to be faster for this
reason.

BUG: The garbage collector is deactivated when Prolog is called back from
a foreign language predicate.  This implies there is no garbage collection
within a break environment.  More seriously, there is no garbage
collection when handling call-backs from ---for example--- the PCE
package.


2.11 Syntax Notes

SWI-Prolog uses standard `Edinburgh' syntax.  A description of this syntax
can be found in the Prolog books referenced in the introduction.  Below
are some non-standard or non-common constructs that are accepted by
SWI-Prolog:

    0'<char>
    This construct is not accepted by all Prolog systems that claim to
    have Edinburgh compatible syntax.  It describes the ASCII value of
    <char>.  To test whether C is a lower case character one can use
    `between(0'a, 0'z, C)'.

    /* ... /* .... */ ... */
    The /* ... */ comment statement can be nested.  This is useful if
    some code with /* ... */ comment statements in it should be commented
    out.


2.12 System Limits


2.12.1 Limits on Memory Areas

SWI-Prolog has a number of memory areas which are not enlarged at run
time, unless you have a version with dynamic stack allocation.  The
default sizes for these areas should suffice for small applications, but
most serious application require larger ones.  They all can be modified by
command line options.  The table below shows these areas.  The first
column gives the option name to modify the size of the area.  This option
character should be followed immediately by a number and expresses the
number of kilo bytes to use for the area.  There are no other limits than
the available memory of the machine to the sizes of the areas.  The areas
are described in table 2.3.

The heap is a memory area to store atoms, clauses, records, flags, etc.
This area is dynamically enlarged at runtime on all versions of
SWI-Prolog.

 Option    Default    Area name       Description

   -L     200K (2M)   local stack     The local stack is used to store the
                                      execution environments of procedure
                                      invocations.  The space for an
                                      environment is reclaimed when it
                                      fails, exits without leaving choice
                                      points, the alternatives are cut of
                                      with the ! predicate or no choice
                                      points have been created since the
                                      invocation and the last subclause is
                                      started (tail recursion
                                      optimisation).

   -G     100K (4M)   global stack    The global stack is used to store
                                      terms created during Prolog's
                                      execution.  Terms on this stack will
                                      be reclaimed by backtracking to a
                                      point before the term was created or
                                      by garbage collection (provided the
                                      term is no longer referenced).

   -T      50K (4M)   trail stack     The trail stack is used to store
                                      assignments during execution.
                                      Entries on this stack remain alive
                                      until backtracking before the point
                                      of creation or the garbage collector
                                      determines they are nor needed any
                                      longer.

   -A      5K (1M)    argument stack  The argument stack is used to store
                                      one of the intermediate code
                                      interpreter's registers.  The amount
                                      of space needed on this stack is
                                      determined entirely by the depth in
                                      which terms are nested in the clauses
                                      that constitute the program.
                                      Overflow is most likely when using
                                      long strings in a clause.

                      Table 2.3:  Memory areas


2.12.2 Other Limits

ClausesCurrently the following limitations apply to clauses.  The arity
    may not be more than 128, the number of links to the `outside world'
    (predicates, atoms, (large) integers, etc) may not exceed 512 and the
    number of variables should be less than 256.

Atoms and StringsSWI-Prolog has no limits on the sizes of atoms and
    strings.  read/1 and its derivates however normally limit the number
    of newlines in an atom or string to 5 to improve error detection and
    recovery.  This can be switched off with style_check/1.

Address spaceSWI-Prolog uses tagged pointers internally.  This limits the
    number of available bits for addressing memory to 29 (512 Mb).

IntegersIntegers are tagged values.  Their value is limited between 226
    and 226 1.

FloatsFloating point numbers are C-doubles with a 12 bit reduction of the
    mantisse.  For machines using IEEE floating point format, this
    implies the range is about 10308and the accurracy about 10 digits.


2.12.3 Reserved Names

The boot compiler (see -b option) does not support the module system
(yet).  As large parts of the system are written in Prolog itself we need
some way to avoid name clashes with the user's predicates, database keys,
etc.  Like Edinburgh C-Prolog  all predicates, database keys, etc. that
should be hidden from the user start with a dollar ($) sign (see
style_check/2).

The compiler uses the special functor $VAR$/1 while analysing the clause
to compile.  Using this functor in a program causes unpredictable
behaviour of the compiler and resulting program.


Chapter  3

Built-In  Predicates

                                33


3.1 Notation of Predicate Descriptions

We have tried to keep the predicate descriptions clear and concise.  First
the predicate name is printed in bold face, followed by the arguments in
italics.  Arguments are preceded by a `+', `--' or `?'  sign.  `+'
indicates the argument is input to the predicate, `--' denotes output and
`?'  denotes `either input or output'.  Constructs like `op/3' refer to
the predicate `op' with arity `3'.


3.2 Consulting Prolog Source files

SWI-Prolog source files normally have a suffix `.pl'.  Specifying the
suffix is optional.  All predicates that handle source files first check
whether a file with suffix `.pl' exists.  If not the plain file name is
checked for existence.  Library files are specified by embedding the file
name using the functor library/1.  Thus `foo' refers to `foo.pl' or `foo'
in the current directory, `library(foo)' refers to `foo.pl' or `foo' in
one of the library directories specified by the dynamic predicate
library_directory/1.

SWI-Prolog recognises grammar rules as defined in .  The user may define
additional compilation of the source file by defining the dynamic
predicate term_expansion/2.  Transformations by this predicate overrule
the systems grammar rule transformations.  It is not allowed to use
assert/1, retract/1 or any other database predicate in term_expansion/2
other than for local computational purposes.

Directives may be placed anywhere in a source file, invoking any
predicate.  They are executed when encountered.  If the directive fails, a
warning is printed.  Directives are specified by :-/1 or ?-/1.  There is
no difference between the two.

SWI-Prolog does not have a separate reconsult/1 predicate.  Reconsulting
is implied automatically by the fact that a file is consulted which is
already loaded.


consult(+File)
    Read File as a Prolog source file.  File may be a list of files, in
    which case all members are consulted in turn.  File may start with
    the csh(1) special sequences ~, ~<user> and $<var>.  File may also be
    library(Name), in which case the libraries are searched for a file
    with the specified name.  See also library_directory/1.  consult/1
    may be abbreviated by just typing a number of file names in a list.
    Examples:

       ?- consult(load).       % consult `load' or `load.pl'
       ?- [library(quintus)].  % load Quintus compatibility library


ensure_loaded(+File)
    Equivalent to consult/1, but the file is consulted only if this was
    not done before.  This is the recommended way to load files from
    other files.


make
    Consult all source files that have been changed since they were
    consulted.  It checks all loaded source files:  files loaded into a
    compiled state using pl -c ...  and files loaded using consult or one
    of its derivates.  make/0 is normally invoked by the edit/[0,1] and
    ed/[0,1] predicates.  make/0 can be combined with the compiler to
    speed up the development of large packages.  In this case compile the
    package using

        sun% pl -g make -o my_program -c file ...

    If `my_program' is started it will first reconsult all source files
    that have changed since the compilation.


library_directory(-Atom)
    Dynamic predicate used to specify library directories.  Default .,
    ./lib, ~/lib/prolog and the system's library (in this order) are
    defined.  The user may add library directories using assert/1 or
    remove system defaults using retract/1.


source_file(-File)
    Succeeds if File was loaded using consult/1 or ensure_loaded/1.  File
    refers to the full path name of the file (see expand_file_name/2).
    Source_file/1 backtracks over all loaded source files.


source_file(?Pred, ?File)
    Is true if the predicate specified by Pred was loaded from file File,
    where File is an absolute path name (see expand_file_name/2).  Can be
    used with any instantiation pattern, but the database only maintains
    the source file for each predicate.  Predicates declared multifile
    (see multifile/1) cannot be found this way.


term_expansion(+Term1, -Term2)
    Dynamic predicate, normally not defined.  When defined by the user
    all terms read during consulting that are given to this predicate.
    If the predicate succeeds Prolog will assert Term2 in the database
    rather then the read term (Term1).  Term2 may be a term of a the form
    `?- Goal' or `:- Goal'.  Goal is then treated as a directive.  Term2
    may also be a list, in which case all terms of the list are stored in
    the database or called (for directives).


compiling
    Succeeds if the system is compiling source files with the -c option
    into an intermediate code file.  Can be used to perform code
    optimisations in expand_term/2 under this condition.


preprocessor(-Old, +New)
    Read the input file via a Unix process that acts as preprocessor.  A
    preprocessor is specified as an atom.  The first occurrence of the
    string `%f' is replaced by the name of the file to be loaded.  The
    resulting atom is called as a Unix command and the standard output of
    this command is loaded.  To use the Unix C preprocessor one should
    define:

        ?- preprocessor(Old, '/lib/cpp -C -P %f'), consult(...).

        Old = none


3.3 Listing Predicates and Editor Interface

SWI-Prolog offers an interface to the Unix vi editor (vi(1)), Richard
O'Keefe's top editor  and the GNU-EMACS invocations emacs and emacsclient.
Which editor is used is determined by the Unix environment variable
EDITOR, which should hold the full pathname of the editor.  If this
variable is not defined, vi(1) is used.

After the user quits the editor make/0 is invoked to reload all modified
source files using consult/1.  If the editor can be quit such that an exit
status non-equal to 0 is returned make/0 will not be invoked.  top can do
this by typing control-C, vi cannot do this.

A predicate specification is either a term with the same functor and arity
as the predicate wanted, a term of the form Functor/Arityor a single
atom.  In the latter case the database is searched for a predicate of this
name and arbitrary arity (see current_predicate/2).  When more than one
such predicate exists the system will prompt for confirmation on each of
the matched predicates.  Predicates specifications are given to the `Do
What I Mean' system (see dwim_predicate/2) if the requested predicate does
not exist.


ed(+Pred)
    Invoke the user's preferred editor on the source file of Pred,
    providing a search specification which searches for the predicate at
    the start of a line.


ed
    Invoke ed/1 on the predicate last edited using ed/1.  Asks the user
    to confirm before starting the editor.


edit(+File)
    Invoke the user's preferred editor on File.  File is a file
    specification as for consult/1 (but not a list).  Note that the file
    should exist.


edit
    Invoke edit/1 on the file last edited using edit/1.  Asks the user to
    confirm before starting the editor.


listing(+Pred)
    List specified predicates (when an atom is given all predicates with
    this name will be listed).  The listing is produced on the basis of
    the internal representation, thus loosing user's layout and variable
    name information.  See also portray_clause/1.


listing
    List all predicates of the database using listing/1.


portray_clause(+Clause)
    Pretty print a clause as good as we can.  A clause should be
    specified as a term `Head :- Body' (put brackets around it to avoid
    operator precedence problems).  Facts are represented as
    `Head :- true'.


3.4 Verify Type of a Term


var(+Term)
    Succeeds if Term currently is a free variable.


nonvar(+Term)
    Succeeds if Term currently is not a free variable.


integer(+Term)
    Succeeds if Term is bound to an integer.


float(+Term)
    Succeeds if Term is bound to a floating point number.


number(+Term)
    Succeeds if Term is bound to an integer or a floating point number.


atom(+Term)
    Succeeds if Term is bound to an atom.


string(+Term)
    Succeeds if Term is bound to a string.


atomic(+Term)
    Succeeds if Term is bound to an atom, string, integer or floating
    point number.


ground(+Term)
    Succeeds if Term holds no free variables.


3.5 Comparison and Unification or Terms


3.5.1 Standard Order of Terms

Comparison and unification of arbitrary terms.  Terms are ordered in the
so called ``standard order''.  This order is defined as follows:

 1. Variables< Atoms< Strings< Numbers< Terms

 2. Old Variable < New Variable

 3. Atoms are compared alphabetically.

 4. Strings are compared alphabetically.

 5. Numbers are compared by value.  Integers and floats are treated
    identically.

 6. Terms are first checked on their functor (alphabetically), then on
    their arity and finally recursively on their arguments, left most
    argument first.


+Term1 == +Term2
    Succeeds if Term1 is equivalent to Term2.  A variable is only
    identical to a sharing variable.


+Term1 \== +Term2
    Equivalent to `\+ Term1 == Term2'.


+Term1 = +Term2
    Unify Term1 with Term2.  Succeeds if the unification succeeds.


+Term1 \= +Term2
    Equivalent to `\+ Term1 = Term2'.


+Term1 =@= +Term2
    Succeeds if Term1 is `structurally equal' to Term2.  Structural
    equivalence is weaker than equivalence (==/2), but stronger than
    unification (=/2).  Two terms are structurally equal if their tree
    representation is identical and they have the same `pattern' of
    variables.  Examples:

              a =@=A        false
              A =@=B         true
         x(A,A) =@=x(B,C)   false
         x(A,A) =@=x(B,B)    true
         x(A,B) =@=x(C,D)    true


+Term1 \=@= +Term2
    Equivalent to `\+ Term1 =@= Term2'.


+Term1 @< +Term2
    Succeeds if Term1 is before Term2 in the standard order of terms.


+Term1 @=< +Term2
    Succeeds if both terms are equal (==) or Term1 is before Term2 in the
    standard order of terms.


+Term1 @> +Term2
    Succeeds if Term1 is after Term2 in the standard order of terms.


+Term1 @>= +Term2
    Succeeds if both terms are equal (==) or Term1 is after Term2 in the
    standard order of terms.


3.6 Control Predicates

The predicates of this section implement control structures.  Normally
these constructs are translated into virtual machine instructions by the
compiler.  It is still necessary to implement these constructs as true
predicates to support meta-calls, as demonstrated in the example below.
The predicate finds all currently defined atoms of 1 character long.  Note
that the cut has no effect when called via one of these predicates (see
!/0).

    one_character_atoms(As) :-
           findall(A, (current_atom(A), atom_length(A, 1)), As).


fail
    Always fail.


true
    Always succeed.


repeat
    Always succeed, provide an infinite number of choice points.


!
    Cut.  Discard choice points of parent frame and frames created after
    the parent frame.  Note that the control structures ;/2, |/2 ->/2 and
    \+/1 are normally handled by the compiler and do not create a frame,
    which implies the cut operates through these predicates.  Some
    examples are given below.  Note the difference between t3/1 and t4/1.
    Also note the effect of call/1 in t5/0.  As the argument of call/1 is
    evaluated by predicates rather than the compiler the cut has no
    effect.

       t1 :- (a, !, fail ; b).      % cuts a/0 and t1/0
       t2 :- (a -> b, !  ; c).      % cuts b/0 and t2/0
       t3(G) :- a, G, fail.         % if `G = !'  cuts a/0 and t1/1
       t4(G) :- a, call(G), fail.   % if `G = !'  cut has no effect
       t5 :- call((a, !, fail ; b)).% Cut has no effect
       t6 :- \+ (a, !, fail ; b).   % cuts a/0 and t6/0


+Goal1 , +Goal2
    Conjunction.  Succeeds if both `Goal1' and `Goal2' can be proved.  It
    is defined as (this definition does not lead to a loop as the second
    comma is handled by the compiler):

        Goal1, Goal2 :- Goal1, Goal2.


+Goal1 ; +Goal2
    The `or' predicate is defined as:

        Goal1 ; _Goal2 :- Goal1.
        _Goal1 ; Goal2 :- Goal2.


+Goal1 | +Goal2
    Equivalent to ;/2.  Retained for compatibility only.  New code should
    use ;/2.


+Condition -> +Action
    If-then and If-Then-Else.  Implemented as:

        If -> Then; _Else :- If, !, Then.
        If -> _Then; Else :- !, Else.
        If -> Then :- If, !, Then.


\+ +Goal
    Succeeds if `Goal' cannot be proven (mnemnonic:  + refers to provable
    and the backslash is normally used to indicate negation).


3.7 Meta-Call Predicates

Meta call predicates are used to call terms constructed at run time.  The
basic meta-call mechanism offered by SWI-Prolog is to use variables as a
subclause (which should of course be bound to a valid goal at runtime).  A
meta-call is slower than a normal call as it involves actually searching
the database at runtime for the predicate, while for normal calls this
search is done at compile time.


call(+Goal)
    Invoke Goal as a goal.  Note that clauses may have variables as
    subclauses, which is identical to call/1, except when the argument is
    bound to the cut.  See !/0.


apply(+Term, +List)
    Append the members of List to the arguments of Term and call the
    resulting term.  For example:  `apply(plus(1), [2, X])' will call
    `plus(1, 2, X)'.  Apply/2 is incorporated in the virtual machine of
    SWI-Prolog.  This implies that the overhead can be compared to the
    overhead of call/1.


not +Goal
    Succeeds when Goal cannot be proven.  Retained for compatibility
    only.  New code should use \+/1.


once(+Goal)
    Defined as:

        once(Goal) :-
               Goal, !.

    Once/1 can in many cases be replaced with ->/2.  The only difference
    is how the cut behaves (see !/0).  The following two clauses are
    identical:

        1) a :- once((b, c)), d.
        2) a :- b, c -> d.


ignore(+Goal)
    Calls Goal as once/1, but succeeds, regardless of whether Goal
    succeeded or not.  Defined as:

        ignore(Goal) :-
               Goal, !.
        ignore(_).


3.8 Database

SWI-Prolog offers three different database mechanisms.  The first one is
the common assert/retract mechanism for manipulating the clause database.
As facts and clauses asserted using assert/1 or one of it's derivates
become part of the program these predicates compile the term given to
them.  Retract/1 and retractall/1 have to unify a term and therefore have
to decompile the program.  For these reasons the assert/retract mechanism
is expensive.  On the other hand, once compiled, queries to the database
are faster than querying the recorded database discussed below.  See also
dynamic/1.

The second way of storing arbitrary terms in the database is using the
``recorded database''.  In this database terms are associated with a key.
A key can be an atom, integer or term.  In the last case only the functor
and arity determine the key.  Each key has a chain of terms associated
with it.  New terms can be added either at the head or at the tail of this
chain.  This mechanism is considerably faster than the assert/retract
mechanism as terms are not compiled, but just copied into the heap.

The third mechanism is a special purpose one.  It associates an integer or
atom with a key, which is an atom, integer or term.  Each key can only
have one atom or integer associated with it.  It again is considerably
faster than the mechanisms described above, but can only be used to store
simple status information like counters, etc.


abolish(+Functor, +Arity)
    Removes all clauses of a predicate with functor Functor and arity
    Arity from the database.  Unlike version 1.2, all predicate
    attributes (dynamic, multifile, index, etc.)  are reset to their
    defaults.  Abolishing an imported predicate only removes the import
    link; the predicate will keep its old definition in its definition
    module.  For `cleanup' of the dynamic database, one should use
    retractall/1 rather than abolish/2.


retract(+Term)
    When Term is an atom or a term it is unified with the first unifying
    fact or clause in the database.  The fact or clause is removed from
    the database.


retractall(+Term)
    All facts or clauses in the database that unify with Term are
    removed.


assert(+Term)
    Assert a fact or clause in the database.  Term is asserted as the
    last fact or clause of the corresponding predicate.


asserta(+Term)
    Equivalent to assert/1, but Term is asserted as first clause or fact
    of the predicate.


assertz(+Term)
    Equivalent to assert/1.


assert(+Term, -Reference)
    Equivalent to assert/1, but Reference is unified with a unique
    reference to the asserted clause.  This key can later be used with
    clause/3 or erase/1.


asserta(+Term, -Reference)
    Equivalent to assert/2, but Term is asserted as first clause or fact
    of the predicate.


assertz(+Term, -Reference)
    Equivalent to assert/2.


recorda(+Key, +Term, -Reference)
    Assert Term in the recorded database under key Key.  Key is an
    integer, atom or term.  Reference is unified with a unique reference
    to the record (see erase/1).


recorda(+Key, +Term)
    Equivalent to recorda(Key, Value, _).


recordz(+Key, +Term, -Reference)
    Equivalent to recorda/3, but puts the Term at the tail of the terms
    recorded under Key.


recordz(+Key, +Term)
    Equivalent to recordz(Key, Value, _).


recorded(+Key, -Value, -Reference)
    Unify Value with the first term recorded under Key which does unify.
    Reference is unified with the memory location of the record.


recorded(+Key, -Value)
    Equivalent to recorded(Key, Value, _).


erase(+Reference)
    Erase a record or clause from the database.  Reference is an integer
    returned by recorda/3 or recorded/3, clause/3, assert/2, asserta/2 or
    assertz/2.  Other integers might conflict with the internal
    consistency of the system.  Erase can only be called once on a record
    or clause.  A second call also might conflict with the internal
    consistency of the system.

    BUG: The system should have a special type for pointers, thus
    avoiding the Prolog user having to worry about consistency matters.
    Currently some simple heuristics are used to determine whether a
    reference is valid.


flag(+Key, -Old, +New)
    Key is an atom, integer or term.  Unify Old with the old value
    associated with Key.  If the key is used for the first time Old is
    unified with the integer 0.  Then store the value of New, which
    should be an integer, atom or arithmetic integer expression, under
    Key.  flag/3 is a very fast mechanism for storing simple facts in the
    database.  Example:

        :- module_transparent succeeds_n_times/2.

        succeeds_n_times(Goal, Times) :-
               flag(succeeds_n_times, _, 0),
               Goal,
               flag(succeeds_n_times, N, N+1),
               fail ; flag(succeeds_n_times, Times, Times).


3.9 Declaring Properties of Predicates

This section describes directives which manipulate attributes of predicate
definitions.  The functors dynamic/1, multifile/1 and discontiguous/1 are
operators of priority 1150 (see op/3), which implies the list of
predicates they involve can just be a comma separated list:

    :- dynamic
           foo/0,
           baz/2.

On SWI-Prolog all these directives are just predicates.  This implies they
can also be called by a program.  Do not rely on this feature if you want
to maintain portability to other Prolog implementations.


dynamic +Functor/+Arity, ...
    Informs the interpreter that the definition of the predicate(s) may
    change during execution (using assert/1 and/or retract/1).  Currently
    dynamic/1 only stops the interpreter from complaining about undefined
    predicates (see unknown/2).  Future releases might prohibit assert/1
    and retract/1 for not-dynamic declared procedures.


multifile +Functor/+Arity, ...
    Informs the system that the specified predicate(s) may be defined
    over more than one file.  This stops consult/1 from redefining a
    predicate when a new definition is found.


discontiguous +Functor/+Arity, ...
    Informs the system that the clauses of the specified predicate(s)
    might not be together in the source file.  See also style_check/1.


index(+Head)
    Index the clauses of the predicate with the same name and arity as
    Head on the specified arguments.  Head is a term of which all
    arguments are either `1' (denoting `index this argument') or `0'
    (denoting `do not index this argument').  Indexing has no
    implications for the semantics of a predicate, only on its
    performance.  If indexing is enabled on a predicate a special purpose
    algorithm is used to select candidate clauses based on the actual
    arguments of the goal.  This algorithm checks whether indexed
    arguments might unify in the clause head.  Only atoms, integers and
    functors (e.g.  name and arity of a term) are considered.  Indexing
    is very useful for predicates with many clauses representing facts.

    Due to the representation technique used at most 4 arguments can be
    indexed.  All indexed arguments should be in the first 32 arguments
    of the predicate.  If more than 4 arguments are specified for
    indexing only the first 4 will be accepted.  Arguments above 32 are
    ignored for indexing.

    By default all predicates with arity 1 are indexed on their first
    argument.  It is possible to redefine indexing on predicates that
    already have clauses attached to them.  This will initiate a scan
    through the predicate's clause list to update the index summary
    information stored with each clause.

    If --for example-- one wants to represents sub-types using a fact
    list `sub_type(Sub, Super)'that should be used both to determine
    sub- and super types one should declare sub_type/2 as follows:

        :- index(sub_type(1, 1)).

        sub_type(horse, animal).
        ...
        ...


3.10 Examining the Program


current_atom(-Atom)
    Successively unifies Atom with all atoms known to the system.  Note
    that current_atom/1 always succeeds if Atom is intantiated to an
    atom.


current_functor(?Name, ?Arity)
    Successively unifies Name with the name and Arity with the arity of
    functors known to the system.


current_flag(-FlagKey)
    Successively unifies FlagKey with all keys used for flags (see
    flag/3).


current_key(-Key)
    Successively unifies Key with all keys used for records (see
    recorda/3, etc.).


current_predicate(?Name, ?Head)
    Successively unifies Name with the name of predicates currently
    defined and Head with the most general term built from Name and the
    arity of the predicate.  This predicate succeeds for all predicates
    defined in the specified module, imported to it, or in one of the
    modules from which the predicate will be imported if it is called.


predicate_property(?Head, ?Property)
    Succeeds if Head refers to a predicate that has property Property.
    Can be used to test whether a predicate has a certain property,
    obtain all properties known for Head, find all predicates having
    property or even obtaining all information available about the
    current program.  Property is one of:

    interpreted
        Is true if the predicate is defined in Prolog.  We return true on
        this because, although the code is actually compiled, it is
        completely transparent, just like interpreted code.

    built_in
        Is true if the predicate is locked as a built-in predicate.  This
        implies it cannot be redefined in it's definition module and it
        can normally not be seen in the tracer.

    foreign
        Is true if the predicate is defined in the C language.

    dynamic
        Is true if the predicate is declared dynamic using the dynamic/1
        declaration.

    multifile
        Is true if the predicate is declared multifile using the
        multifile/1 declaration.

    undefined
        Is true if a procedure definition block for the predicate exists,
        but there are no clauses in it and it is not declared dynamic.
        This is true if the predicate occurs in the body of a loaded
        predicate, an attempt to call it has been made via one of the
        meta-call predicates or the predicate had a definition in the
        past.  See the library package check for example usage.

    transparent
        Is true if the predicate is declared transparent using the
        module_transparent/1 declaration.

    exported
        Is true if the predicate is in the public list of the context
        module.

    imported_from(Module)
        Is true if the predicate is imported into the context module from
        module Module.

    indexed(Head)
        Predicate is indexed (see index/1) according to Head.  Head is a
        term whose name and arity are identical to the predicate.  The
        arguments are unified with `1' for indexed arguments, `0'
        otherwise.


dwim_predicate(+Term, -Dwim)
    `Do What I Mean' (`dwim') support predicate.  Term is a term, which
    name and arity are used as a predicate specification.  Dwim is
    instantiated with the most general term built from Name and the arity
    of a defined predicate that matches the predicate specified by Term
    in the `Do What I Mean' sence.  See dwim_match/2 for `Do What I Mean'
    string matching.  Internal system predicates are not generated,
    unless style_check(+dollar)is active.  Backtracking provides all
    alternative matches.


clause(?Head, ?Body)
    Succeeds when Head can be unified with a clause head and Body with
    the corresponding clause body.  Gives alternative clauses on
    backtracking.  For facts Body is unified with the atom true.
    Normally clause/2 is used to find clause definitions for a predicate,
    but it can also be used to find clause heads for some body template.


clause(?Head, ?Body, ?Reference)
    Equivalent to clause/2, but unifies Reference with a unique reference
    to the clause (see also assert/2, erase/1).  If Reference is
    instantiated to a reference the clause's head and body will be
    unified with Head and Body.


3.11 Input and Output

SWI-Prolog provides two different packages for input and output.  One
confirms to the Edinburgh standard.  This package has a notion of
`current-input' and `current-output'.  The reading and writing predicates
implicitely refer to these streams.  In the second package, streams are
opened explicitely and the resulting handle is used as an argument to the
reading and writing predicate to specify the source or destination.  Both
packages are fully integrated; the user may switch freely between them.


3.11.1 Input and Output Using Implicit Source and Destination

The package for implicit input and output destination is upwards
compatible to DEC-10 and C-Prolog.  The reading and writing predicates
refer to resp.  the current input- and output stream.  Initially these
streams are connected to the terminal.  The current output stream is
changed using tell/1 or append/1.  The current input stream is changed
using see/1.  The stream's current value can be obtained using telling/1
for output- and seeing/1 for input streams.  The table below shows the
valid stream specifications.  The reserved names user_input, user_output
and user_errorare for neat integration with the explicit streams.

     user                  This reserved name refers to the
                           terminal
     user_input            Input from the terminal

     user_output           Output to the terminal

     stderr or user_error  Unix error stream (output only)

     Atom                  Name of a Unix file
     pipe(Atom)            Name of a Unix command

Source and destination are either a file, one of the reserved words above,
or a term `pipe(Command)'.  In the predicate descriptions below we will
call the source/destination argument `SrcDest'.  Below are some examples
of source/destination specifications.

       ?- see(data).       % Start reading from file `data'.
       ?- tell(stderr).    % Start writing on the error stream.
       ?- tell(pipe(lpr)). % Start writing to the printer.

Another example of using the pipe/1 construct is shown on in figure 3.1.
Note that the pipe/1 construct is not part of Prolog's standard I/O
reportoire.

    getwd(Wd) :-
           seeing(Old), see(pipe(pwd)),
           collect_wd(String),
           seen, see(Old),
           name(Wd, String).

    collect_wd([C|R]) :-
           get0(C), C \== -1, !,
           collect_wd(R).
    collect_wd([]).

                Figure 3.1:  Get the working directory


see(+SrcDest)
    Make SrcDest the current input stream.  If SrcDest was already opened
    for reading with see/1 and has not been closed since, reading will be
    resumed.  Otherwise SrcDest will be opened and the file pointer is
    positioned at the start of the file.


tell(+SrcDest)
    Make SrcDest the current output stream.  If SrcDest was already
    opened for writing with tell/1 or append/1 and has not been closed
    since, writing will be resumed.  Otherwise the file is created or
    --when existing-- truncated.  See also append/1.


append(+File)
    Similar to tell/1, but positions the file pointer at the end of File
    rather than truncating an existing file.  The pipe construct is not
    accepted by this predicate.


seeing(-SrcDest)
    Unify the name of the current input stream with SrcDest.


telling(-SrcDest)
    Unify the name of the current output stream with SrcDest.


seen
    Close the current input stream.  The new input stream becomes user.


told
    Close the current output stream.  The new output stream becomes user.


3.11.2 Explicit Input and Output Streams

The predicates below are part of the Quintus compatible stream-based I/O
package.  In this package streams are explicitely created using the
predicate open/3.  The resulting stream identifier is then passed as a
parameter to the reading and writing predicates to specify the source or
destination of the data.


open(+SrcDest, +Mode, ?Stream)
    SrcDest is either an atom, specifying a Unix file, or a term
    `pipe(Command)', just like see/1 and tell/1.  Mode is one of read,
    writeor append.  Stream is either a variable, in which case it is
    bound to a small integer identifying the stream, or an atom, in which
    case this atom will be the stream indentifier.  In the latter case
    the atom cannot be an already existing stream identifier.  Examples:

      ?- open(data, read, Stream).       % Open `data' for reading.
      ?- open(pipe(lpr), write, printer).% `printer' is a stream to `lpr'.


open_null_stream(?Stream)
    On Unix systems, this is equivalent to
    open('/dev/null', write, Stream).  Characters written to this stream
    are lost, but the stream information (see character_count/2, etc.)
    is maintained.


close(+Stream)
    Close the specified stream.  If Stream is not open an error message
    is displayed.  If the closed stream is the current input or output
    stream the terminal is made the current input or output.


current_stream(?File, ?Mode, ?Stream)
    Is true if a stream with file specification File, mode Mode and
    stream identifier Stream is open.  The reserved streams user and
    user_error are not generated by this predicate.  If a stream has been
    opened with mode appendthis predicate will generate mode write.


stream_position(+Stream, -Old, +New)
    Unify the position parameters of Stream with Old and set them to New.
    A position is represented by the following term:

        '$stream_position'(CharNo, LineNo, LinePos).

    It is only possible to change the position parameters if the stream
    is connected to a disk file.


3.11.3 Switching Between Implicit and Explicit I/O

The predicates below can be used for switching between the implicit- and
the explicit stream based I/O predicates.


set_input(+Stream)
    Set the current input stream to become Stream.  Thus, open(file,
    read, Stream), set_input(Stream) is equivalent to see(file).


set_output(+Stream)
    Set the current output stream to become Stream.


current_input(-Stream)
    Get the current input stream.  Useful to get access to the status
    predicates associated with streams.


current_output(-Stream)
    Get the current output stream.


3.12 Status of Input and Output Streams


wait_for_input(+ListOfStreams, -ReadyList, +TimeOut)
    Wait for input on one of the streams in ListOfStreams and return a
    list of streams on which input is available in ReadyList.
    wait_for_input/3 waits for at most TimeOut seconds.  Timeout may be
    specified as a floating point number to specify fractions of a
    second.  If Timeout equals 0, wait_for_input/3 waits indefinetely.
    This predicate can be used to implement timeout while reading and to
    handle input from multiple sources.  The following example will wait
    for input from the user and an explicitely opened second terminal.
    On return, Inputs may hold user or P4 or both.

        ?- open('/dev/ttyp4', read, P4),
          wait_for_input([user, P4], Inputs, 0).


character_count(+Stream, -Count)
    Unify Count with the current character index.  For input streams this
    is the number of characters read since the open, for output streams
    this is the number of characters written.  Counting starts at 0.


line_count(+Stream, -Count)
    Unify Count with the number of lines read or written.  Counting
    starts at 1.


line_position(+Stream, -Count)
    Unify Count with the position on the current line.  Note that this
    assumes the position is 0 after the open.  Tabs are assumed to be
    defined on each 8-th character and backspaces are assumed to reduce
    the count by one, provided it is positive.


fileerrors(-Old, +New)
    Define error behaviour on errors when opening a file for reading or
    writing.  Valid values are the atoms on (default) and off.  First Old
    is unified with the current value.  Then the new value is set to New.


tty_fold(-OldColumn, +NewColumn)
    Fold Prolog output to stream user on column NewColumn.  If Column is
    0 or less no folding is performed (default).  OldColumn is first
    unified with the current folding column.  To be used on terminals
    that do not support line folding.


3.13 Primitive Character Input and Output


nl
    Write a newline character to the current output stream.  On Unix
    systems nl/0 is equivalent to put(10).


nl(+Stream)
    Write a newline to Stream.


put(+Char)
    Write Char to the current output stream, Char is either an
    integer-expression evaluating to an ASCII value (0  Char 255) or an
    atom of one character.


put(+Stream, +Char)
    Write Char to Stream.


tab(+Amount)
    Writes Amount spaces on the current output stream.  Amount should be
    an expression that evaluates to a positive integer (see
    section 3.19).


tab(+Stream, +Amount)
    Writes Amount spaces to Stream.


flush
    Flush pending output on current output stream.  flush/0 is
    automatically generated by read/1 and derivates if the current input
    stream is user and the cursor is not at the left margin.


flush_output(+Stream)
    Flush output on the specified stream.  The stream must be open for
    writing.


ttyflush
    Flush pending output on stream user.  See also flush/0.


get0(-Char)
    Read the current input stream and unify the next character with Char.
    Char is unified with -1 on end of file.


get0(+Stream, -Char)
    Read the next character from Stream.


get(-Char)
    Read the current input stream and unify the next non-blank character
    with Char.  Char is unified with -1 on end of file.


get(+Stream, -Char)
    Read the next non-blank character from Stream.


get_single_char(-Char)
    Get a single character from input stream `user' (regardless of the
    current input stream).  Unlike get0/1 this predicate does not wait
    for a return.  The character is not echoed to the user's terminal.
    This predicate is meant for keyboard menu selection etc..  If
    SWI-Prolog was started with the -tty flag this predicate reads an
    entire line of input and returns the first non-blank character on
    this line, or the ASCII code of the newline (10) if the entire line
    consisted of blank characters.


3.14 Term Reading and Writing


display(+Term)
    Write Term on the current output stream using standard parenthesised
    prefix notation (i.e.  ignoring operator declarations).  Display is
    normally used to examine the internal representation for terms
    holding operators.


display(+Stream, +Term)
    Display Term on Stream.


displayq(+Term)
    Write Term on the current output stream using standard parenthesised
    prefix notation (i.e.  ignoring operator declarations).  Atoms that
    need quotes are quoted.  Terms written with this predicate can always
    be read back, regardless of current operator declarations.


displayq(+Stream, +Term)
    Display Term on Stream.  Equivalent to Quintus write_canonical/2.


write(+Term)
    Write Term to the current output, using brackets and operators where
    appropriate.


write(+Stream, +Term)
    Write Term to Stream.


writeq(+Term)
    Write Term to the current output, using brackets and operators where
    appropriate.  Atoms that need quotes are quoted.  Terms written with
    this predicate can be read back with read/1 provided the currently
    active operator declarations are identical.


writeq(+Stream, +Term)
    Write Term to Stream, inserting quotes.


print(+Term)
    Prints Term on the current output stream similar to write/1, but for
    each (sub)term of Term first the dynamic predicate portray/1 is
    called.  If this predicate succeeds print assumes the (sub)term has
    been written.  This allows for user defined term writing.


print(+Stream, +Term)
    Print Term to Stream.


portray(+Term)
    A dynamic predicate, which can be defined by the user to change the
    behaviour of print/1 on (sub)terms.  For each subterm encountered
    that is not a variable print/1 first calls portray/1 using the term
    as argument.  For lists only the list as a whole is given to
    portray/1.  If portray succeeds print/1 assumes the term has been
    written.


read(-Term)
    Read the next Prolog term from the current input stream and unify it
    with Term.  On a syntax error read/1 displays an error message,
    attempts to skip the erroneous term and fails.  On reaching
    end-of-file Term is unified with the atom end_of_file.


read(+Stream, -Term)
    Read Term from Stream.


read_clause(-Term)
    Equivalent to read/1, but warns the user for variables only occurring
    once in a term (singleton variables) which do not start with an
    underscore if style_check(singleton)is active (default).  Used to
    read Prolog source files (see consult/1).


read_clause(+Stream, -Term)
    Read a clause from Stream.


read_variables(-Term, -Bindings)
    Similar to read/1, but Bindings is unified with a list of
    `Name= Var' tuples, thus providing access to the actual variable
    names.


read_variables(+Stream, -Term, -Bindings)
    Read, returning term and bindings from Stream.


read_history(+Show, +Help, +Special, +Prompt, -Term, -Bindings)
    Similar to read_variables/2, but allows for history substitutions.
    history_read/6 is used by the top level to read the user's actions.
    Show is the command the user should type to show the saved events.
    Help is the command to get an overview of the capabilities.  Special
    is a list of commands that are not saved in the history.  Prompt is
    the first prompt given.  Continuation prompts for more lines are
    determined by prompt/2.  A %w in the prompt is substituted by the
    event number.  See section 2.4 for available substitutions.

    SWI-Prolog calls history_read/6 as follows:

        read_history(h, '!h', [trace], '%w ?- ', Goal, Bindings)


history_depth(-Int)
    Dynamic predicate, normally not defined.  The user can define this
    predicate to set the history depth.  It should unify the argument
    with a positive integer.  When not defined 15 is used as the default.


prompt(-Old, +New)
    Set prompt associated with read/1 and its derivates.  Old is first
    unified with the current prompt.  On success the prompt will be set
    to New if this is an atom.  Otherwise an error message is displayed.
    A prompt is printed if one of the read predicates is called and the
    cursor is at the left margin.  It is also printed whenever a newline
    is given and the term has not been terminated.  Prompts are only
    printed when the current input stream is user.


3.15 Analysing and Constructing Terms


functor(?Term, ?Functor, ?Arity)
    Succeeds if Term is a term with functor Functor and arity Arity.  If
    Term is a variable it is unified with a new term holding only
    variables.  functor/3 silently fails on instantiation faults


arg(+Arg, +Term, ?Value)
    Term should be instantiated to a term, Arg to an integer between 1
    and the arity of Term.  Value is unified with the Arg-th argument of
    Term.


?Term =..  ?List
    List is a list which head is the functor of Term and the remaining
    arguments are the arguments of the term.  Each of the arguments may
    be a variable, but not both.  This predicate is called `Univ'.
    Examples:

        ?- foo(hello, X) =.. List.

        List = [foo, hello, X]

        ?- Term =.. [baz, foo(1)]

        Term = baz(foo(1))


numbervars(+Term, +Functor, +Start, -End)
    Unify the free variables of Term with a term constructed from the
    atom Functor with one argument.  The argument is the number of the
    variable.  Counting starts at Start.  End is unified with the number
    that should be given to the next variable.  Example:

        ?- numbervars(foo(A, B, A), this_is_a_variable, 0, End).

        A = this_is_a_variable(0)
        B = this_is_a_variable(1)
        End = 2

    In Edinburgh Prolog the second argument is missing.  It is fixed to
    be '$VAR'.


free_variables(+Term, -List)
    Unify List with a list of variables, each sharing with a unique
    variable of Term.  For example:

        ?- free_variables(a(X, b(Y, X), Z), L).

        L = [G367, G366, G371]
        X = G367
        Y = G366
        Z = G371


copy_term(+In, -Out)
    Make a copy of term In and unify the result with Out.  Ground parts
    of In are shared by Out.  Provided In and Out have no sharing
    variables before this call they will have no sharing variables
    afterwards.  copy_term/2 is semantically equivalent to:

        copy_term(In, Out) :-
               recorda(copy_key, In, Ref),
               recorded(copy_key, Out, Ref),
               erase(Ref).


3.16 Analysing and Constructing Atoms


name(?Atom, ?String)
    String is a list of ASCII values describing Atom.  Each of the
    arguments may be a variable, but not both.  When String is bound to
    an ASCII value list describing an integer and Atom is a variable Atom
    will be unified with the integer value described by String (e.g.
    `name(N, "300"), 400 is N + 100' succeeds).


int_to_atom(+Int, +Base, -Atom)
    Convert Int to an ascii representation using base Base and unify the
    result with Atom.  If Base6= 10 the base will be prepended to Atom.
    Base= 0 will try to interpret Int as an ASCII value and return 0'c.
    Otherwise 2  Base 36.  Some examples are given below.

                int_to_atom(45, 2, A)     !  A = 20101101
                int_to_atom(97, 0, A)     !  A = 00a
                int_to_atom(56, 10, A)    !  A = 56


int_to_atom(+Int, -Atom)
    Equivalent to int_to_atom(Int, 10, Atom).


term_to_atom(?Term, ?Atom)
    Succeeds if Atom describes a term that unifies with Term.  When Atom
    is instantiated Atom is converted and then unified with Term.
    Otherwise Term is ``written'' on Atom using write/1.


atom_to_term(+Atom, -Term, -Bindings)
    Use Atom as input to read_variables/2 and return the read term in
    Term and the variable bindings in Bindings.  Bindings is a list of
    Name= Varcouples, thus providing access to the actual variable
    names.  See also read_variables/2.


concat(?Atom1, ?Atom2, ?Atom3)
    Atom3 forms the concatenation of Atom1 and Atom2.  At least two of
    the arguments must be instantiated to atoms, intergers or floating
    point numbers.


concat_atom(+List, -Atom)
    List is a list of atoms, integers or floating point numbers.
    Succeeds if Atom can be unified with the concatenated elements of
    List.  If List has exactly 2 elements it is equivalent to concat/3,
    allowing for variables in the list.


atom_length(+Atom, -Length)
    Succeeds if Atom is an atom of Length characters long.  This
    predicate also works for integers and floats, expressing the number
    of characters output when given to write/1.


3.17 Representing Text in Strings

SWI-Prolog supports the data type string.  Strings are a time and space
efficient mechanism to handle text in Prolog.  Atoms are under some
circumstances not suitable because garbage collection on them is next to
impossible (Although it is possible:  BIM_prolog does it).  Representing
text as a list of ASCII values is, from the logical point of view, the
cleanest solution.  It however has two drawbacks:  1) they cannot be
distinguished from a list of (small) integers; and 2) they consume (in
SWI-Prolog) 12 bytes for each character stored.

Within strings each character only requires 1 byte storage.  Strings live
on the global stack and their storage is thus reclaimed on backtracking.
Garbage collection can easily deal with strings.

The ISO standard proposes "..." is transformed into a string object by
read/1 and derivates.  This poses problems as in the old convention "..."
is transformed into a list of ascii characters.  For this reason the style
check option `string' is available (see style_check/2).

The set of predicates associated with strings is incomplete and tentative.
Names and definitions might change in the future to confirm to the
emerging standard.


string_to_atom(?String, ?Atom)
    Logical conversion between a string and an atom.  At least one of the
    two arguments must be instantiated.  Atom can also be an integer or
    floating point number.


string_to_list(?String, ?List)
    Logical conversion between a string and a list of ASCII characters.
    At least one of the two arguments must be instantiated.


string_length(+String, -Length)
    Unify Length with the number of characters in String.  This predicate
    is functonally equivalent to atom_length/2 and also accepts atoms,
    integers and floats as its first argument.


substring(+String, +Start, +Length, -Sub)
    Create a substring of String that starts at character Start (1 base)
    and has Length characters.  Unify this substring with Sub.


3.18 Operators


op(+Precedence, +Type, +Name)
    Declare Name to be an operator of type Type with precedence
    Precedence.  Name can also be a list of names, in which case all
    elements of the list are declared to be identical operators.
    Precedence is an integer between 0 and 1200.  Precedence 0 removes
    the declaration.  Type is one of:  xf, yf, xfx, xfy, yfx, yfy, fy or
    fx.  The `f' indicates the position of the functor, while x and y
    indicate the position of the arguments.  `y' should be interpreted as
    ``on this position a term with precedence lower or equal to the
    precedence of the functor should occur''.  For `x' the precedence of
    the argument must be strictly lower.  The precedence of a term is 0,
    unless its principal functor is an operator, in which case the
    precedence is the precedence of this operator.  A term enclosed in
    brackets ((...)) has precedence 0.

    The predefined operators are shown in table 3.1.  Note that all
    operators can be redefined by the user.

          1200   xfx   -->, :-

          1200   fx    :-, ?-

          1150   fx    dynamic, multifile,
                       module_transparent, discontiguous

          1100   xfy   ;, |

          1050   xfy   ->
          1000   xfy   ,

          954    xfy   \\

          900    fy    \+, not

          700    xfx   <, =, =.., =@=, =:=, =<, ==, =\=, >,
                       >=, @<, @=<, @>, @>=, \=, \==, is

          600    xfy   :
          500    yfx   +, -, /\, \/, xor

          500    fx    +, -, ?, \

          400    yfx   *, /, //, <<, >>

          300    xfx   mod
          200    xfy   ^

                    Table 3.1:  System operators


current_op(?Precedence, ?Type, ?Name)
    Succeeds when Name is currently defined as an operator of type Type
    with precedence Precedence.  See also op/3.


3.19 Arithmetic

Arithmetic can be divided into some special purpose integer predicates and
a series of general predicates for floating point and integer arithmetic
as appropriate.  The integer predicates are as ``logical'' as possible.
Their usage is recommended whenever applicable, resulting in faster and
more ``logical'' programs.

The general arithmic predicates are optionaly compiled now (see please/3
and the -O command line option).  Compiled arithmetic reduces global stack
requirements and improves performance.  Unfortunately compiled arithmetic
cannot be traced, which is why it is optional.

The general arithmetic predicates all handle expressions.  An expression
is either a simple number or a function.  The arguments of a function are
expressions.  The functions are described in section 3.20.


between(+Low, +High, ?Value)
    Low and High are integers, High Low.  If Value is an integer,
    Low Value High.  When Value is a variable it is successively bound
    to all integers between Low and High.


succ(?Int1, ?Int2)
    Succeeds if Int2= Int1+ 1.  At least one of the arguments must be
    instantiated to an integer.


plus(?Int1, ?Int2, ?Int3)
    Succeeds if Int3= Int1+ Int2.  At least two of the three arguments
    must be instantiated to integers.


+Expr1 > +Expr2
    Succeeds when expression Expr1 evaluates to a larger number than
    Expr2.


+Expr1 < +Expr2
    Succeeds when expression Expr1 evaluates to a smaller number than
    Expr2.


+Expr1 =< +Expr2
    Succeeds when expression Expr1 evaluates to a smaller or equal number
    to Expr2.


+Expr1 >= +Expr2
    Succeeds when expression Expr1 evaluates to a larger or equal number
    to Expr2.


+Expr1 =\= +Expr2
    Succeeds when expression Expr1 evaluates to a number non-equal to
    Expr2.


+Expr1 =:= +Expr2
    Succeeds when expression Expr1 evaluates to a number equal to Expr2.


-Number is +Expr
    Succeeds when Number has successfully been unified with the number
    Expr evaluates to.


3.20 Arithmetic Functions

Arithmetic functions are terms which are evaluated by the arithmetic
predicates described above.  SWI-Prolog tries to hide the difference
between integer arithmetic and floating point arithmetic from the Prolog
user.  Arithmetic is done as integer arithmetic as long as possible and
converted to floating point arithmetic whenever one of the arguments or
the combination of them requires it.  If a function returns a floating
point value which is whole it is automatically transformed into an
integer.  There are three types of arguments to functions:

      Expr     Arbitrary expression, returning either a floating
               point value or an integer.

      IntExpr  Arbitrary expression that should evaluate into an
               integer.

      Int      An integer.

In case integer addition, subtraction and multiplication would lead to an
integer overflow the operands are automatically converted to floating
point numbers.  The floating point functions (sin/1, exp/1, etc.)  form a
direct interface to the corresponding C library functions used to compile
SWI-Prolog.  Please refer to the C library documentation for details on
percision, error handling, etc.


- +Expr
    Result= Expr


+Expr1 + +Expr2
    Result= Expr1+ Expr2


+Expr1 - +Expr2
    Result= Expr1 Expr2


+Expr1 * +Expr2
    Result= Expr1Expr2times


+Expr1 / +Expr2
    Result= Expr1=Expr2


+IntExpr1 mod +IntExpr2
    Result= Expr1mod Expr2 (remainder of division).


+IntExpr1 // +IntExpr2
    Result= Expr1div Expr2 (integer division).


abs(+Expr)
    Evaluate Expr and return the absolute value of it.


max(+Expr1, +Expr2)
    Evaluates to the largest of both Expr1 and Expr2.


min(+Expr1, +Expr2)
    Evaluates to the smallest of both Expr1 and Expr2.


.(+Int, [])
    A list of one element evaluates to the element.  This implies "a"
    evaluates to the ASCII value of the letter a (97).  This option is
    available for compatibility only.  It will not work if
    `style_check(+string)' is active as "a" will then be tranformed into
    a string object.  The recommended way to specify the ASCII value of
    the letter `a' is 0'a.


random(+Int)
    Evaluates to a random integer i for which 0  i < Int.  The seed of
    this random generator is determined by the system clock when
    SWI-Prolog was started.


integer(+Expr)
    Evaluates Expr and rounds the result to the nearest integer.


floor(+Expr)
    Evaluates Expr and returns the largest integer smaller or equal to
    the result of the evaluation.


ceil(+Expr)
    Evaluates Expr and returns the smallest integer larger or equal to
    the result of the evaluation.


+IntExpr >> +IntExpr
    Bitwise shift IntExpr1 by IntExpr2 bits to the right.  Note that
    integers are only 27 bits.


+IntExpr << +IntExpr
    Bitwise shift IntExpr1 by IntExpr2 bits to the left.


+IntExpr \/ +IntExpr
    Bitwise `or' IntExpr1 and IntExpr2.


+IntExpr /\ +IntExpr
    Bitwise `and' IntExpr1 and IntExpr2.


+IntExpr xor +IntExpr
    Bitwise `exclusive or' IntExpr1 and IntExpr2.


\ +IntExpr
    Bitwise negation.


sqrt(+Expr)
    Result= square root of Expr


sin(+Expr)
    Result= sine of Expr.  Expr is the angle in radials.


cos(+Expr)
    Result= cosine of Expr.  Expr is the angle in radials.


tan(+Expr)
    Result= tangus of Expr.  Expr is the angle in radials.


asin(+Expr)
    Result= inverse sine of Expr.  Result is the angle in radials.


acos(+Expr)
    Result= inverse cosine of Expr.  Result is the angle in radials.


atan(+Expr)
    Result= inverse tangus of Expr.  Result is the angle in radials.


atan(+YExpr, +XExpr)
    Result= inverse tangus of YExpr / XExpr.  Result is the angle in
    radials.  The return value is in the range pi:::pi.  Used to convert
    between rectangular and polar coordinate system.


log(+Expr)
    Result= natural logarithm of Expr


log10(+Expr)
    Result= 10 base logarithm of Expr


exp(+Expr)
    Result= e to the power Expr


+Expr1 ^ +Expr2
    Result= Expr1 to the power Expr2


pi
    Evaluates to the mathematical constant pi (3.141593...).


e
    Evaluates to the mathematical constant e (2.718282...).


cputime
    Evaluates to a floating point number expressing the cpu time (in
    seconds) used by Prolog up till now.  See also statistics/2 and
    time/1.


3.21 Adding Arithmetic Functions

Prolog predicates can be given the role of arithmetic function.  The last
argument is used to return the result, the arguments before the last are
the inputs.  Arithmetic functions are added using the predicate
arithmetic_function/1, which takes the head as its argument.  Arithmetic
functions are module sensitive, that is they are only visible from the
module in which the function is defined and delared.  Global arithmetic
functions should be defined and registered from module user.  Global
definitions can be overruled locally in modules.  The builtin functions
described above can be redefined as well.


arithmetic_function(+Head)
    Register a Prolog predicate as an arithmetic function (see is/2, >/2,
    etc.).  The Prolog predicate should have one more argument than
    specified by Head, which it either a term Name/Arity, an atom or a
    complex term.  This last argument is an unbound variable at call time
    and should be instantiated to an integer or floating point number.
    The other arguments are the parameters.  This predicate is module
    sensitive and will declare the arithmetic function only for the
    context module, unless declared from module user.  Example:

        1 ?- [user].
        :- arithmetic_function(mean/2).

        mean(A, B, C) :-
               C is (A+B)/2.
        user compiled, 0.07 sec, 440 bytes.

        Yes
        2 ?- A is mean(4, 5).

        A = 4.500000


current_arithmetic_function(?Head)
    Succesively unifies all arithmetic functions that are visible from
    the context module with Head.


3.22 List Manipulation


is_list(+Term)
    Succeeds if Term is bound to the empty list ([]) or a term with
    functor `.' and arity 2.


proper_list(+Term)
    Equivalent to is_list/1, but also requires the tail of the list to be
    a list (recursively).  Examples:

        is_list([x|A])         % true
        proper_list([x|A])      % false


append(?List1, ?List2, ?List3)
    Succeeds when List3 unifies with the concatenation of List1 and
    List2.  The predicate can be used with any instantiation pattern
    (even three variables).


member(?Elem, ?List)
    Succeeds when Elem can be unified with one of the members of List.
    The predicate can be used with any instantiation pattern.


memberchk(?Elem, +List)
    Equivalent to member/2, but leaves no choice point.


delete(+List1, ?Elem, ?List2)
    Delete all members of List1 that simultaneously unify with Elem and
    unify the result with List2.


select(?List1, ?Elem, ?List2)
    Select an element of List1 that unifies with Elem.  List2 is unified
    with the list remaining from List1 after deleting the selected
    element.  Normally used with the instantiation pattern +List1, -Elem,
    -List2, but can also be used to insert an element in a list using
    -List1, +Elem, +List2.


nth0(?Index, ?List, ?Elem)
    Succeeds when the Index-th element of List unifies with Elem.
    Counting starts at 0.


nth1(?Index, ?List, ?Elem)
    Succeeds when the Index-th element of List unifies with Elem.
    Counting starts at 1.


last(?Elem, ?List)
    Succeeds if Elem unifies with the last element of List.


reverse(+List1, -List2)
    Reverse the order of the elements in List1 and unify the result with
    the elements of List2.


flatten(+List1, -List2)
    Transform List1, possibly holding lists as elements into a `flat'
    list by replacing each list with its elements (recursively).  Unify
    the resulting flat list with List2.  Example:

        ?- flatten([a, [b, [c, d], e]], X).

        X = [a, b, c, d, e]


length(?List, ?Int)
    Succeeds if Int represents the number of elements of list List.  Can
    be used to create a list holding only variables.


merge(+List1, +List2, -List3)
    List1 and List2 are lists, sorted to the standard order of terms (see
    section 3.5).  List3 will be unified with an ordered list holding the
    both the elements of List1 and List2.  Duplicates are not removed.


3.23 Set Manipulation


is_set(+Set)
    Succeeds if set is a proper list (see proper_list/1) without
    duplicates.


list_to_set(+List, -Set)
    Succeeds if Set holds the same elements as List in the same order,
    but has no duplicates.  See also sort/1.


intersection(+Set1, +Set2, -Set3)
    Succeeds if Set3 unifies with the intersection of Set1 and Set2.
    Set1 and Set2 are lists without duplicates.  They need not be
    ordered.


subtract(+Set, +Delete, -Result)
    Delete all elements of set `Delete' from `Set' and unify the
    resulting set with `Result'.


union(+Set1, +Set2, -Set3)
    Succeeds if Set3 unifies with the union of Set1 and Set2.  Set1 and
    Set2 are lists without duplicates.  They need not be ordered.


subset(+Subset, +Set)
    Succeeds if all elements of Subset are elements of Set as well.


merge_set(+Set1, +Set2, -Set3)
    Set1 and Set2 are lists without duplicates, sorted to the standard
    order of terms.  Set3 is unified with an ordered list without
    duplicates holding the union of the elements of Set1 and Set2.


3.24 Sorting Lists


sort(+List, -Sorted)
    Succeeds if Sorted can be unified with a list holding the elements of
    List, sorted to the standard order of terms (see section 3.5).
    Duplicates are removed.


msort(+List, -Sorted)
    Equivalent to sort/2, but does not remove duplicates.


keysort(+List, -Sorted)
    List is a list of Key-Valuepairs (e.g.  terms of the functor `-'
    with arity 2).  keysort/2 sorts List like msort/2, but only compares
    the keys.  Can be used to sort terms not on standard order, but on
    any criterion that can be expressed on a multi-dimensional scale.
    Sorting on more than one criterion can be done using terms as keys,
    putting the first criterion as argument 1, the second as argument 2,
    etc.


predsort(+Pred, +List, -Sorted)
    Sorts similar to msort/2, but determines the order of two terms by
    applying Pred to pairs of elements from List (see apply/2).  The
    predicate should succeed if the first element should be before the
    second.


3.25 Finding all Solutions to a Goal


findall(+Var, +Goal, -Bag)
    Creates a list of the instantiations Var gets successively on
    backtracking over Goal and unifies the result with Bag.  Succeeds
    with an empty list if Goal has no solutions.  findall/3 is equivalent
    to bagof/3 with all free variables bound with the existence operator
    (^), except that bagof/3 fails when goal has no solutions.


bagof(+Var, +Goal, -Bag)
    Unify Bag with the alternatives of Var, if Goal has free variables
    besides the one sharing with Var bagof will backtrack over the
    alternatives of these free variables, unifying Bag with the
    corresponding alternatives of Var.  The construct Var^Goal tells
    bagof not to bind Var in Goal.  Bagof/3 fails if Goal has no
    solutions.

    The example below illustrates bagof/3 and the ^ operator.  The
    variable bindings are printed together on one line to save paper.

        2 ?- listing(foo).

        foo(a, b, c).
        foo(a, b, d).
        foo(b, c, e).
        foo(b, c, f).
        foo(c, c, g).

        Yes
        3 ?- bagof(C, foo(A, B, C), Cs).

        A = a, B = b, C = G308, Cs = [c, d] ;
        A = b, B = c, C = G308, Cs = [e, f] ;
        A = c, B = c, C = G308, Cs = [g] ;

        No
        4 ?- bagof(C, A^foo(A, B, C), Cs).

        A = G324, B = b, C = G326, Cs = [c, d] ;
        A = G324, B = c, C = G326, Cs = [e, f, g] ;

        No
        5 ?-


setof(+Var, +Goal, -Set)
    Equivalent to bagof/3, but sorts the result using sort/2 to get a
    sorted list of alternatives without duplicates.


3.26 Invoking Predicates on all Members of a List

All the predicates in this section call a predicate on all members of a
list or until the predicate called fails.  The predicate is called via
apply/2, which implies common arguments can be put in front of the
arguments obtained from the list(s).  For example:

    ?- maplist(plus(1), [0, 1, 2], X).

    X = [1, 2, 3]

we will phrase this as ``Predicate is applied on ...''


checklist(+Pred, +List)
    Pred is applied successively on each element of List until the end of
    the list or Pred fails.  In the latter case the checklist/2 fails.


maplist(+Pred, ?List1, ?List2)
    Apply Pred on all successive pairs of elements from List1 and List2.
    Fails if Pred can not be applied to a pair.  See the example above.


sublist(+Pred, +List1, ?List2)
    Unify List2 with a list of all elements of List1 to which Pred
    applies.


3.27 Forall


forall(+Cond, +Action)
    For all alternative bindings of Cond Action can be proven.  The
    example verifies that all arithmic statements in the list L are
    correct.  It does not say which is wrong if one proves wrong.

        ?- forall(member(Result = Formula, [2 = 1 + 1, 4 = 2 * 2]),
                       Result =:= Formula).


3.28 Formatted Write

The current version of SWI-Prolog provides two formatted write predicates.
The first is writef/[1,2], which is compatible with Edinburgh C-Prolog.
The second is format/[1,2], which is compatible with Quintus Prolog.  We
hope the Prolog community will once define a standard formatted write
predicate.  If you want performance use format/[1,2] as this predicate is
defined in C. Otherwise compatibility reasons might tell you which
predicate to use.


3.28.1 Writef


write_ln(+Term)
    Equivalent to write(Term), nl.


writef(+Atom)
    Equivalent to writef(Atom, []).


writef(+Format, +Arguments)
    Formatted write.  Format is an atom whose characters will be printed.
    Format may contain certain special character sequences which specify
    certain formatting and substitution actions.  Arguments then provides
    all the terms required to be output.

    Escape sequences to generate a single special character:

            \n     <NL> is output

            \l     <LF> is output

            \r     <CR> is output

            \t     <TAB> is output

            \\     The character `\' is output

            \%     The character `%' is output

            \nnn   where nnn is an integer (1-3 digits) the
                   character with ASCII code nnn is output (NB
                   : nnn is read as DECIMAL)

    Escape sequences to include arguments from Arguments.  Each time a %
    escape sequence is found in Format the next argument from Arguments
    is formatted according to the specification.

            %t     print/1 the next item (mnemonic:  term)

            %w     write/1 the next item

            %q     writeq/1 the next item

            %d     display/1 the next item

            %p     print/1 the next item (identical to %t)

            %n     put the next item as a character (i.e.  it
                   is an ASCII value)

            %r     write the next item N times where N is the
                   second item (an integer)

            %s     write the next item as a String (so it must
                   be a list of characters)

            %f     perform a ttyflush/0 (no items used)

            %Nc    write the next item Centered in N columns.
            %Nl    write the next item Left justified in N
                   columns.
            %Nr    write the next item Right justified in N
                   columns.  N is a decimal number with at
                   least one digit.  The item must be an atom,
                   integer, float or string.


swritef(-String, +Format, +Arguments)
    Equivalent to writef/3, but ``writes'' the result on String instead
    of the current output stream.  Example:

        ?- swritef(S, '%15L%w', ['Hello', 'World']).

        S = "Hello         World"


swritef(-String, +Format)
    Equivalent to swritef(String, Format, []).


3.28.2 Format


format(+Format)
    Defined as `format(Format) :- format(Format, []).'


format(+Format, +Arguments)
    Format is an atom, list of ASCII values, or a Prolog string.
    Arguments provides the arguments required by the format
    specification.  If only one argument is required and this is not a
    list of ASCII values the argument need not be put in a list.
    Otherwise the arguments are put in a list.

    Special sequences start with the tilde (~), followed by an optional
    numeric argument, followed by a character describing the action to be
    undertaken.  A numeric argument is either a sequence of digits,
    representing a positive decimal number, a sequence `<character>,
    representing the ASCII value of the character (only useful for ~t) or
    a asterisk (*), in when the numeric argument is taken from the next
    argument of the argument list, which should be a positive integer.
    Actions are:

      ~ Output the tilde itself.
      a Output the next argument, which should be an atom.  This option
        is equivalent to w.  Compatibility reasons only.

      c Output the next argument as an ASCII value.  This argument should
        be an integer in the range [0, ..., 255] (including 0 and 255).

      d Output next argument as a decimal number.  It should be an
        integer.  If a numeric argument is specified a dot is inserted
        argument positions from the right (useful for doing fixed point
        arithmetic with integers, such as handling amounts of money).

      D Same as d, but makes large values easier to read by inserting a
        comma every three digits left to the dot or right.

      e Output next argument as a floating point number in exponentional
        notation.  The numeric argument specifies the precission.
        Default is 6 digits.  Exact representation depends on the C
        library function printf().  This function is invoked with the
        format %.<percission>e.

      E Equivalent to e, but outputs a capital E to indicate the
        exponent.

      f Floating point in non-exponentional notation.  See C library
        function printf().

      g Floating point in e or f notation, whichever is shorter.

      G Floating point in E or f notation, whichever is shorter.

      i Ignore next argument of the argument list.  Produces no output.

      k Give the next argument to displayq/1 (canonical write).

      n Output a newline character.

      N Only output a newline if the last character output on this stream
        was not a newline.  Not properly implemented yet.

      p Give the next argument to print/1.

      q Give the next argument to writeq/1.

      r Print integer in radix the numeric argument notation.  Thus ~16r
        prints its argument hexadecimal.  The argument should be in the
        range [2, ...  36].  Lower case letters are used for digits above
        9.

      R Same as r, but uses upper case letters for digits above 9.

      s Output a string of ASCII characters from the next argument.

      t All remaining space between 2 tabstops is distributed equaly over
        ~t statements between the tabstops.  This space is padded with
        spaces by default.  If an argument is supplied this is taken to
        be the ASCII value of the character used for padding.  This can
        be used to do left or right alignment, centering, distributing,
        etc.  See also ~| and ~+ to set tab stops.  A tabstop is assumed
        at the start of each line.

       __Set a tabstop on the current position.  If an argument is
        supplied set a tabstop on the position of that argument.  This
        will cause all ~t's to be distributed between the previous and
        this tabstop.

      + Set a tabstop relative to the current position.  Further the same
        as ~|.

      w Give the next argument to write/1.

    Example:

        simple_statistics :-
           <obtain statistics>        % left to the user
           format('~tStatistics~t~72|~n~n'),
           format('Runtime: ~`.t ~2f~34|  Inferences: ~`.t ~D~72|~n',
                                               [RunT, Inf]),
           ....

    Will output

                                  Statistics

        Runtime: .................. 3.45  Inferences: .......... 60,345


sformat(-String, +Format, +Arguments)
    Equivalent to format/3, but ``writes'' the result on String instead
    of the current output stream.  Example:

        ?- sformat(S, '~w~t~15|~w', ['Hello', 'World']).

        S = "Hello         World"


sformat(-String, +Format)
    Equivalent to `sformat(String, Format, []).'


3.28.3 Programming Format


format_predicate(+Char, +Head)
    If a sequence ~c (tilde, followed by some character) is found, the
    format derivates will first check whether the user has defined a
    predicate to handle the format.  If not, the built in formatting
    rules described above are used.  Char is either an ascii value, or a
    one character atom, specifying the letter to be (re)defined.  Head is
    a term, whose name and arity are used to determine the predicate to
    call for the redefined formatting character.  The first argument to
    the predicate is the numeric argument of the format command, or the
    atom defaultif no argument is specified.  The remaining arguments
    are filled from the argument list.  The example below redefines ~n to
    produce  Arg times return followed by linefeed (so a (Grr.)  DOS
    machine is happy with the output).

        :- format_predicate(n, dos_newline(_Arg)).

        dos_newline(Arg) :-
               between(1, Ar, _), put(13), put(10), fail ; true.


3.29 Terminal Control

The following predicates form a simple access mechanism to the Unix
termcap library to provide terminal independant I/O for screen terminals.
The library package tty builds on top of these predicates.


tty_get_capability(+Name, +Type, -Result)
    Get the capability named Name from the termcap library.  See
    termcap(5) for the capability names.  Type specifies the type of the
    expected result, and is one of string, numberor bool.  String
    results are returned as an atom, number result as an integer and bool
    results as the atom on or off.  If an option cannot be found this
    predicate fails silently.  The results are only computed once.
    Succesive queries on the same capability are fast.


tty_goto(+X, +Y)
    Goto position (X, Y) on the screen.  Note that the predicates
    line_count/2 and line_position/2 will not have a well defined
    behaviour while using this predicate.


tty_put(+Atom, +Lines)
    Put an atom via the termcap library function tputs().  This function
    decodes padding information in the strings returned by
    tty_get_capability/3 and should be used to output these strings.
    Lines is the number of lines affected by the operation, or 1 if not
    applicable (as in almost all cases).


set_tty(-OldStream, +NewStream)
    Set the output stream, used by tty_put/2 and tty_goto/2 to a specific
    stream.  Default is user_output.


3.30 Unix Interaction


shell(+Command, -Status)
    Execute Command on the operating system.  Command is given to the
    bourne shell (/bin/sh).  Status is unified with the exit status of
    the command.


shell(+Command)
    Equivalent to `shell(Command, 0)'.


shell
    Start an interactive Unix shell.  Default is /bin/sh, the environment
    variable SHELL overrides this default.


getenv(+Name, -Value)
    Get Unix environment variable (see csh(1) and sh(1)).  Fails if the
    variable does not exist.


setenv(+Name, +Value)
    Set Unix environment variable.  Name and Value should be instantiated
    to atoms or integers.  The environment variable will be passed to
    shell/[0-2] and can be requested using getenv/2.


unsetenv(+Name)
    Remove Unix environment variable from the environment.


get_time(-Time)
    Return the number of seconds that elapsed since the epoch of Unix, 1
    January 1970, 0 hours.  Time is a floating point number.  Its
    granularity is system dependant.  On SUN, this is 1/60 of a second.


convert_time(+Time, -Year, -Month, -Day, -Hour, -Minute, -Second, -MilliSeconds)

    Convert a time stamp, provided by get_time/1, file_time/2, etc.  Year
    is unified with the year, Month with the month number (January is 1),
    Day with the day of the month (starting with 1), Hour with the hour
    of the day (0--23), Minute with the minute (0--59).  Second with the
    second (0--59) and MilliSecond with the milli seconds (0--999).  Note
    that the latter might not be acurate or might always be 0, depending
    on the timing capabilities of the system.


3.31 Unix File System Interaction


access_file(+File, +Mode)
    Succeeds when File exists and can be accessed by this prolog process
    under mode Mode.  Mode is one of the atoms read, write or execute.
    File may also be the name of a directory.  Fails silently otherwise.


exists_file(+File)
    Succeeds when File exists.  This does not imply the user has read
    and/or write permission for the file.


same_file(+File1, +File2)
    Succeeds if both filenames refer to the same physical file.  That is,
    if File1 and File2 are the same string or both names exist and point
    to the same file (due to hard or symbolic links and/or relative vs.
    absolute paths).


exists_directory(+Directory)
    Succeeds if Directory exists.  This does not imply the user has read,
    search and or write permission for the directory.


delete_file(+File)
    Unlink File from the Unix file system.


rename_file(+File1, +File2)
    Rename File1 into File2.  Currently files cannot be moved across
    devices.


size_file(+File, -Size)
    Unify Size with the size of File in characters.


time_file(+File, -Time)
    Unify the last modification time of File with Time.  Time is a
    floating point number expressing the seconds ellapsed since Jan 1,
    1970.


absolute_file_name(+File, -Absolute)
    Expand Unix file specification into an absolute path.  User home
    directory expansion (~ and ~user) and variable expansion is done.
    The absolute path is canonised:  references to `.'  and `..'  are
    deleted.  SWI-Prolog uses absolute file names to register source
    files independant of the current working directory.


expand_file_name(+WildChart, -List)
    Unify List with a sorted list of files or directories matching
    WildChart.  The normal Unix wildchart constructs `?', `*', `[...]'
    and `{...}' are recognised.  The interpretation of `{...}' is
    interpreted slightly different from the C shell (csh(1)).  The comma
    separated argument can be arbitrary patterns, including `{...}'
    patterns.  The empty pattern is legal as well:  `{.pl,}' matches
    either `.pl' or the empty string.


chdir(+Path)
    Change working directory to Path.


3.32 User Toplevel Manipulation


break
    Recursively start a new Prolog top level.  This Prolog top level has
    it's own stacks, but shares the heap with all break environments and
    the top level.  Debugging is switched off on entering a break and
    restored on leaving one.  The break environment is terminated by
    typing the system's end-of-filecharacter (control-D). If the
    -t toplevelcommand line option is given this goal is started instead
    of entering the default interactive top level (prolog/0).


abort
    Abort the Prolog execution and start a new top level.  If the
    -t toplevelcommand line options is given this goal is started
    instead of entering the default interactive top level.  Break
    environments are aborted as well.  All open files except for the
    terminal related files are closed.  The input- and output stream
    again refers to user.

    BUG: Erased clauses which could not actually be removed from the
    database, because they are active in the interpreter, will never be
    garbage collected after an abort.


halt
    Terminate Prolog execution.  Open files are closed and if the command
    line option -tty is not active the terminal status (see Unix stty(1))
    is restored.


prolog
    This goal starts the default interactive top level.  prolog/0 is
    terminated (succeeds) by typing control-D.


3.33 Creating a Protocol of the Unser Interaction

SWI-Prolog offers the possibility to log the interaction with the user on
a file.  All Prolog interaction, including warnings and tracer output, are
written on the protocol file.


protocol(+File)
    Start protocolling on file File.  If there is already a protocol file
    open then close it first.  If File exists it is truncated.


protocola(+File)
    Equivalent to protocol/1, but does not truncate the File if it
    exists.


noprotocol
    Stop making a protocol of the user interaction.  Pending output is
    flushed on the file.


protocolling(-File)
    Succeeds if a protocol was started with protocol/1 or protocola/1 and
    unifies File with the current protocol output file.


3.34 Debugging and Tracing Programs


trace
    Start the tracer.  trace/0 itself cannot be seen in the tracer.  Note
    that the Prolog toplevel treats trace/0 special; it means `trace the
    next goal'.


tracing
    Succeeds when the tracer is currently switched on.  tracing/0 itself
    can not be seen in the tracer.


notrace
    Stop the tracer.  notrace/0 itself cannot be seen in the tracer.


debug
    Start debugger (stop at spy points).


nodebug
    Stop debugger (do not trace, nor stop at spy points).


debugging
    Print debug status and spy points on current output stream.


spy(+Pred)
    Put a spy point on all predicates meeting the predicate specification
    Pred.  See section 3.3.


nospy(+Pred)
    Remove spy point from all predicates meeting the predicate
    specification Pred.


nospyall
    Remove all spy points from the entire program.


leash(?Ports)
    Set/query leashing (ports which allow for user interaction).  Ports
    is one of +Name, -Name, ?Name or a list of these.  +Nameenables
    leashing on that port, -Name disables it and ?Name succeeds or fails
    according to the current setting.  Recognised ports are:  call, redo,
    exit, fail and unify.  The special shorthand all refers to all ports,
    fullrefers to all ports except for the unify port (default).  half
    refers to the call, redo and fail port.


visible(+Ports)
    Set the ports shown by the debugger.  See leash/1 for a description
    of the port specification.  Default is full.


unknown(-Old, +New)
    Unify Old with the current value of the unknown system flag.  On
    success New will be used to specify the new value.  New should be
    instantiated to either fail or trace and determines the interpreter's
    action when an undefined predicate which is not declared dynamic is
    encountered (see dynamic/1).  fail implies the predicate just fails
    silently.  traceimplies the tracer is started.  Default is trace.
    The unknown flag is local to each module and unknown/2 is module
    transparent.  Using it as a directive in a module file will only
    change the unknown flag for that module.  Using the :/2 construct the
    behaviour on trapping an undefined predicate can be changed for any
    module.  Note that if the unknown flag for a module equals fail the
    system will not call exception/3 and will not try to resolve the
    predicate via the dynamic library system.  The system will still try
    to import the predicate from the public module.


style_check(+Spec)
    Set style checking options.  Spec is either +<option>, -<option>,
    ?<option> or a list of such options.  +<option> sets a style checking
    option, -<option> clears it and ?<option> succeeds or fails according
    to the current setting.  consult/1 and derivates resets the style
    checking options to their value before loading the file.  If --for
    example-- a file containing long atoms should be loaded the user can
    start the file with:

        :- style_check(-atom).

    Currently available options are:

      Name           Default   Description

      singleton        on      read_clause/1 (used by consult/1) warns on
                               variables only appearing once in a term
                               (clause) which have a name not starting with
                               an underscore.
      atom             on      read/1 and derivates will produce an error
                               message on quoted atoms or strings longer
                               than 5 lines.
      dollar           off     Accept dollar as a lower case character,
                               thus avoiding the need for quoting atoms
                               with dollar signs.  System maintenance use
                               only.

      discontiguous    on      Warn if the clauses for a predicate are not
                               together in the same source file.

      string           off     Read and derivates transform "..." into a
                               prolog string instead of a list of ASCII
                               characters.


3.35 Obtaining Runtime Statistics


statistics(+Key, -Value)
    Unify system statistics determined by Key with Value.  The possible
    keys are given in the table 3.2.

    cputime      (User) cpu time since Prolog was started in
                 seconds
    inferences   Total number of passes via the call and redo ports
                 since Prolog was started.

    heapused     Bytes heap in use.

    local        Allocated size of the local stack in bytes.

    localused    Number of bytes in use on the local stack.

    locallimit   Size to which the local stack is allowed to grow

    global       Allocated size of the global stack in bytes.

    globalused   Number of bytes in use on the global stack.

    globallimit  Size to which the global stack is allowed to grow

    trail        Allocated size of the trail stack in bytes.

    trailused    Number of bytes in use on the trail stack.

    traillimit   Size to which the trail stack is allowed to grow

    atoms        Total number of defined atoms.
    functors     Total number of defined name/arity pairs.

    predicates   Total number of predicate definitions.

    modules      Total number of module definitions.
    externals    Total number of external references in all
                 clauses.
    codes        Total amount of byte codes in all clauses.

                  Table 3.2:  Keys for statistics/2


statistics
    Display a table of system statistics on the current output stream.


time(+Goal)
    Execute Goal just like once/1 (i.e.  leaving no choice points), but
    print used time, number of logical inferences and the average number
    of lips (logical inferences per second).  Note that SWI-Prolog counts
    the actual executed number of inferences rather than the number of
    passes through the call- and redo ports of the theoretical 4-port
    model.


3.36 Finding Performance Bottlenecks

SWI-Prolog offers a statistical program profiler similar to Unix prof(1)
for C and some other languages.  A profiler is used as an aid to find
performance pigs in programs.  It provides information on the time spent
in the various Prolog predicates.

The profiler is based on the assumption that if we monitor the functions
on the execution stack on time intervals not correlated to the program's
execution the number of times we find a procedure on the environment stack
is a measure of the time spent in this procedure.  It is implemented by
calling a procedure each time slice Prolog is active.  This procedure
scans the local stack and either just counts the procedure on top of this
stack (plain profiling) or all procedures on the stack (cummulative
profiling).  To get accurate results each procedure one is interested in
should have a reasonable number of counts.  Typically a minute runtime
will suffice to get a rough overview of the most expensive procedures.


profile(+Goal, +Style, +Number)
    Execute Goal just like time/1.  Collect profiling statistics
    according to style (see profiler/2) and show the top Number
    procedures on the current output stream (see show_profile/1).  The
    results are kept in the database until reset_profiler/0 or profile/3
    is called and can be displayed again with show_profile/1.  profile/3
    is the normal way to invoke the profiler.  The predicates below are
    low-level predicates that can be used for special cases.


show_profile(+Number)
    Show the collected results of the profiler.  Stops the profiler first
    to avoid interference from show_profile/1.  It shows the top Number
    predicates according the percentage cpu-time used.


profiler(-Old, +New)
    Query or change the status of the profiler.  The status is one of
    off, plain or cummulative.  plainimplies the time used by childs of
    a predicate is not added to the time of the predicate.  For status
    cummulativethe time of childs is added (except for recursive calls).
    Cummulative profiling implies the stack is scanned upto the top on
    each time slice to find all active predicates.  This implies the
    overhead grows with the number of active frames on the stack.
    Cummulative profiling starts debuggin mode to disable tail recursion
    optimisation, which would otherwise remove the necessary parent
    environments.  Switching status from plain to cummulativeresets the
    profiler.  Switching to and from status off does not reset the
    collected statistics, thus allowing to suspend profiling for certain
    parts of the program.


reset_profiler
    Swiches the profiler to off and clears all collected statistics.


profile_count(+Head, -Calls, -Promilage)
    Obtain profile statistics of the predicate specified by Head.  Head
    is an atom for predicates with arity 0 or a term with the same name
    and arity as the predicate required (see current_predicate/2).  Calls
    is unified with the number of `calls' and `redos' while the profiler
    was active.  Promilage is unified with the relative number of counts
    the predicate was active (cummulative) or on top of the stack
    (plain).  Promilage is an integer between 0 and 1000.


3.37 Memory Management

Note:  limit_stack/2 and trim_stacks/0 have no effect on machines that do
not offer dynamic stack expansion.  On these machines these predicates
simply succeed to improve portability.


garbage_collect
    Invoke the global- and trail stack garbage collector.  Normally the
    garbage collector is invoked automatically if necessary.  Explicit
    invokation might be useful to reduce the need for garbage collections
    in time critical segments of the code.  After the garbage collection
    trim_stacks/0 is invoked to release the collected memory resources.


limit_stack(+Key, +Kbytes)
    Limit one of the stack areas to the specified value.  Key is one of
    local, globalor trail.  The limit is an integer, expressing the
    desired stack limit in K bytes.  If the desired limit is smaller than
    the currently used value, the limit is set to the nearest legal value
    above the currently used value.  If the desired value is larger than
    the maximum, the maximum is taken.  Finally, if the desired value is
    either 0 or the atom unlimitedthe limit is set to its maximum.  The
    maximum and initial limit is determined by the command line options
    -L, -G and -T.


trim_stacks
    Release stack memory resources that are not in use at this moment,
    returning them to the operating system.  Trim stack is a relatively
    cheap call.  It can be used to release memory resources in a
    backtracking loop, where the iterations require typically seconds of
    execution time and very different, potentionally large, amounts of
    stack space.  Such a loop should be written as follows:

        loop :-
               generator,
                   trim_stacks,
                   potentionally_expensive_operation,
               stop_condition, !.

    The prolog top level loop is written this way, reclaiming memory
    resources after every user query.


3.38 Miscellaneous


dwim_match(+Atom1, +Atom2)
    Succeeds if Atom1 matches Atom2 in `Do What I Mean' sence.  Both
    Atom1 and Atom2 may also be integers or floats.  The two atoms match
    if:

        They are identical

        They differ by one character (spy == spu)

        One character is insterted/deleted (debug == deug)

        Two characters are transposed (trace == tarce)

        `Sub-words' are glued differently (existsfile == existsFile ==
        exists_file)

        Two adjacent sub words are transposed (existsFile == fileExists)


dwim_match(+Atom1, +Atom2, -Difference)
    Equivalent to dwim_match/2, but unifies Difference with an atom
    identifying the the difference between Atom1 and Atom2.  The return
    values are (in the same order as above):  equal, mismatched_char,
    inserted_char, transposed_char, separatedand transposed_word.


wildcard_match(+Pattern, +String)
    Succeeds if String matches the wildcart pattern Pattern.  Pattern is
    very simular the the Unix csh pattern matcher.  The patterns are
    given below:

      ?       Matches one arbitrary character
      *       Matches any number of arbitrary characters
      [...]   Matches one of the characters specified at ... <char>-<char> indi*
 *cates a range.
      f...g   Matches any of the patterns of the comma separated list between t*
 *he brackets.

    Example:

        ?- wildcard_match('[a-z]*.{pro,pl}[%~]', 'a_hello.pl%').

        Yes.


gensym(+Base, -Unique)
    Generate a unique atom from base Base and unify it with Unique.  Base
    should be an atom.  The first call will return <base>1, the next
    <base>2, etc.  Note that this is no warant that the atom is unique in
    the system.

    BUG: I plan to supply a real gensym/2 which does give this warrant
    for future versions.


sleep(+Time)
    Suspend execution Time seconds.  Time is either a floating point
    number or an integer.  Granularity is dependent on the system's timer
    granularity (1/60 seconds on most Unix systems).  A negative time
    causes the timer to return immediately.  As Unix is a multi-tasking
    environment we can only ensure execution is suspended for at least
    Time seconds.


Chapter  4

Using  Modules

                                384


4.1 Why Using Modules?

In traditional Prolog systems the predicate space was flat.  This approach
is not very suitable for the development of large applications, certainly
not if these applications are developed by more than one programmer.  In
many cases, the definition of a Prolog predicate requires sub-predicates
that are intented only to complete the definition of the main predicate.
With a flat and global predicate space these support predicates will be
visible from the entire program.

For this reason, it is desirable that each source module has it's own
predicate space.  A module consists of a declaration for it's name, it's
public predicates and the predicates themselves.  This approach allow the
programmer to use short (local) names for support predicates without
worrying about name conflicts with the support predicates of other
modules.  The module declaration also makes explicit which predicates are
meant for public usage and which for private purposes.  Finally, using the
module information, cross reference programs can indicate possible
problems much better.


4.2 Name-based versus Predicate-based Modules

Two approaches to realise a module system are commonly used in Prolog and
other languages.  The first one is the name based module system.  In these
systems, each atom read is tagged (normally prefixed) with the module
name, with the exception of those atoms that are defined public.  In the
second approach, each module actually implements its own predicate space.

A critical problem with using modules in Prolog is introduced by the
meta-predicates that transform between Prolog data and Prolog predicates.
Consider the case where we write:

    :- module(extend, [add_extension/3]).

    add_extension(Extension, Plain, Extended) :-
           maplist(extend_atom(Extension), Plain, Extended).

    extend_atom(Extension, Plain, Extended) :-
           concat(Plain, Extension, Extended).

In this case we would like maplist to call extend_atom/3 in the module
extend.  A name based module system will do this correctly.  It will tag
the atom extend_atom with the module and maplist will use this to
construct the tagged term extend_atom/3.  A name based module however,
will not only tag the atoms that will eventually be used to refer to a
predicate, but all atoms that are not declared public.  So, with a name
based module system also data is local to the module.  This introduces
another serious problem:

    :- module(action, [action/3]).

    action(Object, sleep, Arg) :- ....
    action(Object, awake, Arg) :- ....

    :- module(process, [awake_process/2]).

    awake_process(Process, Arg) :-
           action(Process, awake, Arg).

This code uses a simple object-oriented implementation technique were
atoms are used as method selectors.  Using a name based module system,
this code will not work, unless we declare the selectors puclic atoms in
all modules that use them.  Predicate based module systems do not require
particular precautions for handling this case.

It appears we have to choose either to have local data, or to have trouble
with meta-predicates.  Probably it is best to choose for the predicate
based approach as novice users will not often write generic
meta-predicates that have to be used across multiple modules, but are
likely to write programs that pass data around across modules.
Experienced Prolog programmers should be able to deal with the
complexities of meta-predicates in a predicate based module system.


4.3 Defining a Module

Modules normally are created by loading a module file.  A module file is a
file holding a module/2 directive as its first term.  The module/2
directive declares the name and the public (i.e. externally visible)
predicates of the module.  The rest of the file is loaded into the module.
Below is an example of a module file, defining reverse/2.

    :- module(reverse, [reverse/2]).

    reverse(List1, List2) :-
           rev(List1, [], List2).

    rev([], List, List).
    rev([Head|List1], List2, List3) :-
           rev(List1, [Head|List2], List3).


4.4 Importing Predicates into a Module

As explained before, in the predicate based approach ad<apted by
SWI-Prolog, each module has it's own predicate space.  In SWI-Prolog, a
module initially is completely empty.  Predicates can be added to a module
by loading a module file as demonstrated in the previous section, using
assert or by importing them from another module.

Two mechanisms for importing predicates explicitely from another module
exist.  The use_module/[1,2] predicates load a module file and import
(part of the) public predicates of the file.  The import/1 predicate
imports any predicate from any module.


use_module(+File)
    Load the file(s) specified with File just like ensure_loaded/1.  The
    files should all be module files.  All exported predicates from the
    loaded files are imported into the context module.  The difference
    between this predicate and ensure_loaded/1 becomes apparent if the
    file is already loaded into another module.  In this case
    ensure_loaded/1 does nothing; use_module will import all public
    predicates of the module into the current context module.


use_module(+File, +ImportList)
    Load the file specified with File (only one file is accepted).  File
    should be a module file.  ImportList is a list of name/arity pairs
    specifying the predicates that should be imported from the loaded
    module.  If a predicate is specified that is not exported from the
    loaded module a warning will be printed.  The predicate will
    nevertheless be imported to simplify debugging.


import(+Head)
    Import predicate Head into the current context module.  Head should
    specify the source module using the <module>:<term> construct.
    Note that predicates are normally imported using one of the
    directives use_module/[1,2].  import/1 is meant for handling imports
    into dynamically created modules.


It would be rather inconvient to have to import each predicate refered to
by the module, including the system predicates.  For this reason each
module is assigned a default module.  All predicates in the default module
are available without extra declarations.  Their definition however can be
overruled in the local module.  This schedule is implemented by the
exception handling mechanism of SWI-Prolog:  if an undefined predicate
exception is raised for a predicate in some module, the exception handler
first tries to import the predicate from the module's default module.  On
success, normal execution is resumed.


4.4.1 Reserved Modules

SWI-Prolog contains two special modules.  The first one is the module
system.  This module contains all built-in predicates described in this
manual.  Module system has no default module assigned to it.  The second
special module is the module user.  This module forms the initial working
space of the user.  Initially it is empty.  The default module of module
user is system, making all built-in predicate definitions available as
defaults.  Built-in predicates thus can be overruled by defining them in
module user before they are used.

All other modules default to module user.  This implies they can use all
predicates imported into user without explicitely importing them.


4.5 Using the Module System

The current structure of the module system has been designed with some
specific organisations for large programs in mind.  Many large programs
define a basic library layer on top of which the actual program itself is
defined.  The module user, acting as the default module for all other
modules of the program can be used to distribute these definitions over
all program module without introducing the need to import this common
layer each time explicitely.  It can also be used to redefine built-in
predicates if this is required to maintain compatibility to some other
Prolog implementation.  Typically, the loadfile of a large application
looks like this:

    :- use_module(compatibility).   % load XYZ prolog compatibility

    :- use_module(                % load generic parts
           [ error                % errors and warnings
           , goodies              % general goodies (library
    extensions)
           , debug                % application specific debugging
           , virtual_machine       % virtual machine of application
           , ...                 % more generic stuff
           ]).

    :- ensure_loaded(
           [ ...                 % the application itself
           ]).

The `use_module' declarations will import the public predicates from the
generic modules into the user module.  The `ensure_loaded' directive loads
the modules that constitute the actual application.  It is assumed these
modules import predicates from each other using use_module/[1,2] as far as
necessary.

In combination with the object-oriented schema described below it is
possible to define a neat modular architecture.  The generic code defines
general utilities and the message passing predicates (invoke/3 in the
example below).  The application modules define classes that communicate
using the message passint predicates.


4.5.1 Object Oriented Programming

Another typical way to use the module system is for defining classes
within an object oriented paradigm.  The class structure and the methods
of a class can be defined in a module and the explicit module-boundary
overruling describes in section ??  can by used by the message passing
code to invoke the behaviour.  An outline of this mechanism is given
below.

    %       Define class point

    :- module(point, []).          % class point, no exports

    %       name          type,          default access
    %                                   value

    variable(x,            integer,       0,      both).
    variable(y,            integer,       0,      both).

    %        method name   predicate name  arguments

    behaviour(mirror,       mirror,        []).

    mirror(P) :-
           fetch(P, x, X),
           fetch(P, y, Y),
           store(P, y, X),
           store(P, x, Y).

The predicates fetch/3 and store/3 are predicates that change instance
variables of instances.  The figure below indicates how message passing
can easily be implemented:

    %       invoke(+Instance, +Selector, ?ArgumentList)
    %       send a message to an instance

    invoke(I, S, Args) :-
           class_of_instance(I, Class),
           Class:behaviour(S, P, ArgCheck), !,
           convert_arguments(ArgCheck, Args, ConvArgs),
           Goal =.. [P|ConvArgs],
           Class:Goal.

The construct `Module:Goal' explicitely calls Goal in module Module.  It
is discussed in more detail in section ??.


4.6 Meta-Predicates in Modules

As indicated in the introduction, the problem with a predicate based
module system lies in the difficulty to find the correct predicate from a
Prolog term.  The predicate `solution(Solution)' can exist in more than
one module, but `assert(solution(4))' in some module is supposed to refer
to the correct version of solution/1.

Various approaches are possible to solve this problem.  One is to add an
extra argument to all predicates (e.g. `assert(Module, Term)').  Another
is to tag the term somehow to indicate which module is desired (e.g.
`assert(Module:Term)').  Both approaches are not very attractive as they
make the user responsible for chosing the correct module, inviting unclear
programming by asserting in other modules.  The predicate assert/1 is
supposed to assert in the module it is called from and should do so
without being told explicitely.  For this reason, the notion context
module has been introduced.


4.6.1 Definition and Context Module

Each predicate of the program is assigned a module, called it's definition
module.  The definition module of a predicate is always the module in
which the predicate was originally defined.  Each active goal in the
Prolog system has a context module assigned to it.

The context module is used to find predicates from a Prolog term.  By
default, this module is the definition module of the predicate running the
goal.  For meta-predicates however, this is the context module of the goal
that invoked them.  We call this module_transparent in SWI-Prolog.  In the
`using maplist' example above, the predicate maplist/3 is declared
module_transparent.  This implies the context module remains extend, the
context module of add_extension/3.  This way maplist/3 can decide to call
extend_atom in module extend rather than in it's own definition module.

All built-in predicates that refer to predicates via a Prolog term are
declared module_transparent.  Below is the code defining maplist.

    :- module(maplist, maplist/3).

    :- module_transparent maplist/3.

    %       maplist(+Goal, +List1, ?List2)
    %       True if Goal can succesfully be applied to all succesive
    pairs
    %       of elements of List1 and List2.

    maplist(_, [], []).
    maplist(Goal, [Elem1|Tail1], [Elem2|Tail2]) :-
           apply(Goal, [Elem1, Elem2]),
           maplist(Goal, Tail1, Tail2).


4.6.2 Overruling Module Boundaries

The mechanism above is sufficient to create an acceptable module system.
There are however cases in which we would like to be able to overrule this
schema and explicitely call a predicate in some module or assert
explicitly in some module.  The first is useful to invoke goals in some
module from the user's toplevel or to implement a object-oriented system
(see above).  The latter is useful to create and modify dynamic modules
(see section 4.7).

For this purpose, the reserved term :/2 has been introduced.  All built-in
predicates that transform a term into a predicate reference will check
whether this term is of the form `<Module>:<Term>'.  If so, the
predicate is searched for in Module instead of the goal's context module.
The :/2 operator may be nested, in which case the inner-most module is
used.

The special calling construct <Module>:<Goal> pretends Goal is called
from Module instead of the context module.  Examples:

    ?- assert(world:done).  % asserts done/0 into module world
    ?- world:assert(done).  % the same
    ?- world:done.         % calls done/0 in module world


4.7 Dynamic Modules

Sofar, we discussed modules that were created by loading a module-file.
These modules have been introduced on facilitate the development of large
applications.  The modules are fully defined at load-time of the
application and normally will not change during execution.  Having the
notion of a set of predicates as a self-contained world can be attractive
for other purposes as well.  For example, assume an application that can
reason about multiple worlds.  It is attractive to store the data of a
particular world in a module, so we extract information from a world
simply by invoking goals in this world.

Dynamic modules can easily be created.  Any built-in predicate that tries
to locate a predicate in a specific module will create this module as a
side-effect if it did not yet exist.  Example:

    ?- assert(world_1, consistent),
       world_1:unkown(_, fail).

These calls create a module called world and make the call
`world:consistent' succeed.  Undefined predicates will not start the
tracer or autoloader for this module (see unknown/2).

Import and export from dynamically created world is arranged via the
predicates import/1 and export/1:

    ?- world_5:export(solve(_,_)).         % exports solve/2 from
    world_5
    ?- world_3:import(world_5:solve(_,_)).  % and import it to world_3


4.8 Module Handling Predicates

This section gives the predicate definitions for the remaining built-in
predicates that handle modules.


:- module(+Module, +PublicList)
    This directive can only be used as the first term of a source file.
    It declares the file to be a module file, defining Module and
    exporting the predicates of PublicList.  PublicList is a list of
    name/arity pairs.


module_transparent +Name/+Arity, ...
    Preds is a comma separated list of name/arity pairs (like dynamic/1).
    Each goal associated with a transparent declared predicate will
    inherit the context module from its parent goal.


context_module(-Module)
    Unify Module with the context module of the current goal.
    context_module/1 itself is transparent.


export(+Head)
    Add a predicate to the public list of the context module.  This
    implies the predicate will be imported into another module if this
    module is imported with use_module/[1,2].  Note that predicates are
    normally exported using the directive module/2.  export/1 is meant to
    handle export from dynamically created modules.


4.9 Compatibility of the Module System

The principles behind the module system of SWI-Prolog differ in a number
of aspects from the Quintus Prolog module system.

    The SWI-Prolog module system allows the user to redefine system
    predicates.

    All predicates that are available in the system and user modules are
    visible in all other modules as well.

    Quintus has the `meta_predicate/1' declaration were SWI-Prolog has
    the module_transparent/1 declaration.

The meta_predicate/1 declaration causes the compiler to tag arguments that
pass module sensitive information with the module using the :/2 operator.
This approach has some disadvantages:

    Changing a meta_predicate declaration implies all predicates calling
    the predicate need to be reloaded.  This can cause serious
    consistency problems.

    It does not help for dynamically defined predicates calling module
    sensitive predicates.

    It slows down the compiler (at least in the SWI-Prolog architecture).

    At least within the SWI-Prolog architecture the run-time overhead is
    larger than the overhead introduced by the transparent mechanism.

Unfortunately the transparent predicate approach also has some
disadvantages.  If a predicate A passes module sensitive information to a
predicate B, passing the same information to a module sensitive system
predicate both A and B should be declared transparent.  Using the Quintus
approach only A needs to be treated special (i.e.  declared with
meta_predicate/1).  A second problem arises if the body of a transparent
predicate uses module sensitive predicates for which it wants to refer to
its own module.  Suppose we want to define findall/3 using assert/1 and
retract/1.  The example in figure 4.1 gives the solution.

    :- module(findall, [findall/3]).

    :- dynamic
           solution/1.

    :- module_transparent
           findall/3,
           store/2.

    findall(Var, Goal, Bag) :-
           assert(findall:solution('$mark')),
           store(Var, Goal),
           collect(Bag).

    store(Var, Goal) :-
           Goal,                 % refers to context module of
                                 % caller of findall/3
           assert(findall:solution(Var)),
           fail.
    store(_, _).

    collect(Bag) :-
           ...,

                  Figure 4.1:  Findall using modules

The Quintus meta_predicate/1 directive can in many cases be replaced by
the transparent declaration.  Figure 4.2 gives a definition of
meta_predicate/1 as available from the `quintus' library package.

    :- op(1150, fx, (meta_predicate)).

    meta_predicate((Head, More)) :- !,
           meta_predicate1(Head),
           meta_predicate(More).
    meta_predicate(Head) :-
           meta_predicate1(Head).

    meta_predicate1(Head) :-
           Head =.. [Name|Arguments],
           member(Arg, Arguments),
           module_expansion_argument(Arg), !,
           functor(Head, Name, Arity),
           module_transparent(Name/Arity).
    meta_predicate1(_).            % just a mode declaration

    module_expansion_argument(:).
    module_expansion_argument(N) :- integer(N).

              Figure 4.2:  Definition of meta_predicate/1

The discussion above about the problems with the transparent mechanism
show the two cases in which this simple transformation does not work.


Chapter  5

Foreign  Language  Interface

SWI-Prolog offers a powerful interface to C . The main design objectives
of the foreign language interface are flexibility and performance.  Most
Prolog foreign language interfaces allow the user only to pass primitive
data via the interface.  The user should normally specify for each
argument whether it is an input or output argument as well as the type of
the argument.  Because type checking and conversion to/from C data types
is done by Prolog the actual foreign code is usually short if something
simple is wanted.  The SWI-Prolog interface does not offer these
primitives.  Instead Prolog terms in their internal representation are
passed via the interface.  This allows the user to write `logical'
predicates and pass arbitrary Prolog data over the interface.  As a
trade-off the user is responsible for type checking and should be careful
not to violate consistency rules as Prolog provides access to its internal
data structures.

                                406


5.1 Portability of the Foreign Interface

The foreign language interface is highly system dependent.  It can easily
be ported to machines for which the C linker allows you to link an object
file using the symbol table of a (running) executable and use BSD Unix
format a.out files.  On many Unix systems such an object file can be
created using the -A option of ld(1).  See the introduction section for a
list of systems to which the foreign interface is available.


5.2 Overview of the Interface

A special include file called ``SWI-prolog.h'' should be included with
each C-source file that is to be loaded via the foreign interface.  This
C-header file defines various data types, macros and functions that can be
used to communicate with SWI-Prolog.  Functions and macros can be divided
into the following categories:

    Analysing arbitrary Prolog terms

    Constructing new terms or instantiating existing ones

    Returning control information to Prolog

    Registering foreign predicates with Prolog

    Calling Prolog from C

    Communicating about modules

    Printing standard Prolog warning/error messages

    Global actions on Prolog (halt, break, abort, etc.)

    Querying the status of Prolog

A C-file to be included normally defines a number of functions that
implement foreign language Prolog predicates, private support functions
and an installation function.  The user should compile this file into a
`.o' file using `cc -c file ...', after which Prolog can be asked to load
the file using the simplified load_foreign/2 predicate or the more
flexible load_foreign/5 predicate.  Prolog will call the Unix loader ld(1)
to create an executable.  It will then determine the actual size of the
executable, allocate memory for it and call the loader again to create an
executable that can be loaded in the allocated memory.  After the
executable is loaded the entry point of the new executable is called.
This function should register all defined foreign predicates with Prolog.


5.3 Loading Foreign Modules


load_foreign(+File, +Entry)
    Load a foreign file or list of files specified by File.  The files
    are searched for similar to consult/1.  Except that the `.o'
    extension is used rather than `.pl'.  Thus `test' is a valid
    specification for `test.o' in the current directory,
    `[test, library(basics)]' specifies `test.o' in the current directory
    and `basics.o' in one of the library directories.  To simplify
    maintenance of packages in heterogeneous networks the system first
    tries whether the object file is available from a subdirectory whose
    name depends on the system used.  The names of the subdirectories is
    shown below.

                  Directory   Machine
                  sun4        Sparc Station 1 and SUN-4
                  sun3        SUN-3
                  hpux        HP9000 running HPUX

    Entry defines the entry point of the resulting executable.  The entry
    point will be called by Prolog to install the foreign predicates.


load_foreign(+File, +Entry, +Options, +Libraries, +Size)
    The first two arguments are identical to those of load_foreign/2.
    Options is (a list of) additional option to be given to the loader.
    The default command is:

        ld -N -A <symbolfile> -T <offset> -e <entry> -o <executable>
          <files> -lc

    The options are inserted just before the files.  Libraries is (a list
    of) libraries to be passed to the loader.  They are inserted just
    after the files.

    If Size is specified Prolog first assumes that the resulting
    executable will fit in Size bytes and do the loading in one pass.  If
    the executable turns out to be larger than Size bytes the loading
    sequence is started again, using the calculated size.  To determine
    the size of an executable specify a size that is too small.  Prolog
    will then print the actual size on the current output stream.


foreign_file(?File)
    Is true if File is the absolute path name of a file loaded as foreign
    file.


5.4 Interface Data types

The interface functions can be divided into two groups.  The first group
are functions to obtain data from Prolog or pass data to Prolog.  These
functions use Prolog internal data types.  The second group consists of
type conversion functions convert between Prolog internal data and C
primitive types.  Below is a description of the Prolog data types used in
the interface.

termTerms represent arbitrary Prolog data (variables, atoms, integers,
    floats and compound terms).  Terms live either until backtracking
    takes us back to a point before the term was created or the garbage
    collector has collected the term.

atomicAtomics are Prologs primitive data types (integers, atoms and
    floats).  They can be transformed to C data types (int, char * resp.
    double).  The Prolog representation for an integer is a tagged
    version of that integer.  The mapping between C ints and Prolog
    integers can only be different over different releases of SWI-Prolog.
    Atoms are represented by a pointer to a data structure on the Prolog
    heap.  Each such data structure is a unique representation of a
    string (e.g.  to verify that two atoms represent the same string
    comparing the atoms suffices).  The mapping between atoms and string
    are likely to vary over different sessions of Prolog.  Floats are
    represented as (tagged) pointers to a float living on the global
    stack.  For their life time the same rules apply as for terms.
    Whether two floats represent the same number can only be discovered
    by transforming both to C floats and then comparing them.  Strings
    are represented as a tagged pointer to a char * on the global stack
    or heap.  The rules for their lifetime and comparison equal those for
    floats and terms.

functorA functor is the internal representation of a name/arity pair.
    They are used to find the name and arity of a compound term as well
    as to construct new compound terms.  Like atoms they live for the
    whole Prolog session and are unique.

moduleA module is a unique handle to a Prolog module.  Modules are used
    only to call predicates in a specific module.


5.5 The Foreign Include File


5.5.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a
function specified in the predicate definition of the foreign predicate.
The arguments (1, ..., arity) pass the Prolog arguments to the goal as
Prolog terms.  Foreign functions should be declared of type foreign_t.
Deterministic foreign functions have two alternatives to return control
back to Prolog:


void PL_succeed
     Succeed deterministically.  PL_succeed is defined as ``return TRUE''.


void PL_fail
     Fail and start Prolog backtracking.  PL_fail is defined as ``return
     FALSE''.


5.5.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic.  Using the
PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is
possible to register a predicate as a non-deterministic predicate.
Writing non-deterministic foreign predicates is slightly more complicated
as the foreign function needs context information for generating the next
solution.  Note that the same foreign function should be prepared to be
simultaneously active in more than one goal.  Suppose the
natural_number_below_n/2 is a non-deterministic foreign predicate,
backtracking over all natural numbers lower than the first argument.  Now
consider the following predicate:

    quotient_below_n(Q, N) :-
           natural_number_below_n(N, N1),
           natural_number_below_n(N, N2),
           Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously
generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three
different calls from Prolog:

Initial call (PL_FIRST_CALL)
    Prolog has just created a frame for the foreign function and asks it
    to produce the first answer.

Redo call (PL_REDO)
    The previous invocation of the foreign function associated with the
    current goal indicated it was possible to backtrack.  The foreign
    function should produce the next solution.

Terminate call (PL_CUTTED)
    The choice point left by the foreign function has been destroyed by a
    cut.  The foreign function is given the opportunity to clean the
    environment.

Both the context information and the type of call is provided by an
argument of type foreign_t appended to the argument list for deterministic
foreign functions.  The macro PL_foreign_control() extracts the type of
call from the control argument.  The foreign function can pass a context
handle using the PL_retry() macro and extract the handle from the extra
argument using the PL_foreign_context() macro.


void PL_retry(handle)
     The foreign function succeeds while leaving a choice point.  On
     backtracking over this goal the foreign function will be called
     again, but the control argument now indicates it is a `Redo' call and
     the macro PL_foreign_context() will return the handle passed via
     PL_retry().  This handle is a 30 bits signed value (two bits are used
     for status indication).


int PL_foreign_control(control_argument)
    Extracts the type of call from the control argument.  The return
    values are described above.  Note that the function should be
    prepared to handle the PL_CUTTED case and should be aware that the
    other arguments are not valid in this case.


long PL_foreign_context(control_argument)
     Extracts the context from the context argument.  In the call type is
     PL_FIRST_CALL the context value is 0L. Otherwise it is the value
     returned by the last PL_retry() associated with this goal (both if
     the call type is PL_REDO as PL_CUTTED).


Note:  If a non-deterministic foreign function returns using PL_succeed or
PL_fail, Prolog assumes the foreign function has cleaned its environment.
No call with control argument PL_CUTTED will follow.

The code of figure 5.1 shows a skeleton for a non-deterministic foreign
predicate definition.

    typedef struct                /* define a context structure */
    { ...
    } context;

    foreign_t
    my_function(a0, a1, handle)
    term a0, a1;
    foreign_t handle;
    { struct context * ctxt;

      switch( PL_foreign_control(handle) )
      { case PL_FIRST_CALL:
           ctxt = (struct context *) malloc(sizeof(struct context));
           ...
           PL_retry(ctxt);
        case PL_REDO:
           ctxt = (struct context *) PL_foreign_context(handle);
           ...
           PL_retry(ctxt);
        case PL_CUTTED:
           free(ctxt);
           PL_succeed;
      }
    }

      Figure 5.1:  Skeleton for non-deterministic foreign functions


5.5.2 Analysing Terms via the Foreign Interface

Each argument of a foreign function (except for the control argument) is
of type term.  To analyse a term one should first obtain the type of the
term.  Primitive terms can then be transformed into atomic data in
internal Prolog representation.  This atomic data can be transformed into
C-data types.  Complex terms are analysed in terms on their functor and
arguments.  The arguments themselves are terms, allowing the same
procedure to be repeated recursively.


int PL_type(term)
    Obtain the type of term, which should be a term returned by one of
    the other interface predicates or passed as an argument.  The
    function returns the type of the Prolog term.  The type identifiers
    are listed below.

      PL_VARIABLE            An unbound variable.  The value of term as
                             such is a unique identifier for the
                             variable.
      PL_ATOM                A Prolog atom.

      PL_STRING              A Prolog string.

      PL_INTEGER             A Prolog integer.

      PL_FLOAT               A Prolog floating point number.

      PL_TERM                A compound term.  Note that a list is a
                             compound term with name `.'  and arity 2.


atomic PL_atomic(term)
       Return the atomic value of term in Prolog internal representation.
       Term should be atomic (e.g.  atom, integer, float or string).


long PL_integer_value(atomic)
     Transforms an integer from Prolog internal representation into a C
     long.


double PL_float_value(atomic)
       Transforms a float from Prolog internal representation into a C
       double.


char * PL_atom_value(atomic)
       Transforms an atom from Prolog internal representation into a
       0-terminated C char *.  The pointer points directly into the Prolog
       heap and can assumed to be static.  The contents of the character
       string however should under NO circumstances be modified.


char * PL_string_value(string)
       Transform a string from Prolog internal representation into a C char
       *.  The pointer points directly into the Prolog data area.  Unlike
       the pointer returned by PL_atom_value() the C user should copy the
       value to a private data area if its value should survive the current
       foreign language call.  Like PL_atom_value(), changing the contents
       of the character string is NOT allowed.


functor PL_functor(term)
        term should be a complex term.  The return value is a unique
        identifier of the term's name and arity.  The following example
        demonstrates this:

            pl_same_functor(t1, t2)
            term t1, t2;
            { if ( PL_type(t1) != PL_TERM || PL_type(t2) != PL_TERM )
               PL_fail;
              if ( PL_functor(t1) == PL_functor(t2) )
               PL_succeed;
              PL_fail;
            }


atomic PL_functor_name(functor)
       Return an atom representing the name of functor.  To get the functor
       name as char * of a term which is known to be compound:

       #define functor_name(term) PL_atom_value(PL_functor_name(PL_functor(term*
 *)))


int PL_functor_arity(functor)
    Return a C integer representing the arity of functor.


term PL_arg(term, int)
     Return the int-th argument of term.  Argument counting starts at 1
     and is valid up to and including the arity of term.  No checks on
     these boundaries are performed.


Figure 5.2 shows a definition of display/1 to illustrate the described
functions.

    pl_display(t)
    term t;
    { functor functor;
      int arity, n;

      switch( PL_type(t) )
      { case PL_VARIABLE:
           printf("_%d", t);
           break;
        case PL_ATOM:
           printf("%s", PL_atom_value(PL_atomic(t)));
           break;
        case PL_STRING:
           printf("\"%s\"", PL_string_value(PL_atomic(t)));
           break;
        case PL_INTEGER:
           printf("%d", PL_integer_value(PL_atomic(t)));
           break;
        case PL_FLOAT:
           printf("%f", PL_float_value(PL_atomic(t)));
           break;
        case PL_TERM:
           functor = PL_functor(t);
           arity = PL_functor_arity(functor);
           printf("%s", PL_atom_value(PL_functor_name(functor)));
           printf("(");
           pl_display(PL_arg(t, 1));
           for( n = 2; n <= arity; n++)
           { printf(", ");
             pl_display(PL_arg(t, n));
           }
           printf(")");
           break;
        default:
           PL_fatal_error("Illegal type in pl_display(): %d",
                                               PL_type(t));
      }

      PL_succeed;
    }

             Figure 5.2:  Foreign definition of display/1


5.5.3 Instantiating and Constructing Terms

Terms are instantiated as in Prolog itself by unification.  Variables can
be unified with atomic data, with a functor and with other terms.  New
terms are first constructed as a single unbound variable.


term PL_new_term()
     Create a new term.  The term is an unbound variable living on the
     global stack.  In the current implementation it lives until Prolog
     backtracks to before this call.  Garbage collection might change this
     in the future.


atomic PL_new_atom(char *)
       Create a Prolog atom from a C char *.  The contents of the char * are
       copied to the Prolog heap.


atomic PL_new_string(char *)
       Create a Prolog string, living on the global stack.  The contents of
       the char * are copied into Prolog's data area.


atomic PL_new_integer(long)
       Create a Prolog integer from a C long.  Note that the integer is
       truncated to 28 bits.  No checks on this are performed.


atomic PL_new_float(double)
       Create a Prolog float living on the global stack from double.


functor PL_new_functor(atomic, int)
        Create a Prolog functor identifier form atomic (which should be an
        atom) and int, the arity.  Arity is valid for any arity  0.  Arity = 0
        is used internally, but none of the interface functions use it.


bool PL_unify(term, term)
     Unify two terms.  Return value is TRUE or FALSE.


bool PL_unify_atomic(term, atomic)
     Unify a term with an atomic value.


bool PL_unify_functor(term, functor)
     Unify a term with a functor.  The unification simply succeeds if term
     is already instantiated to a term with functor functor.  If term is
     variable it will be instantiated to the most general term of functor
     (e.g.  a term with all arguments unbound variables).  Otherwise FALSE
     is returned.

     If this call succeeds the arguments can be further instantiated by
     calling PL_arg() and recursively unifying the returned terms.


An example of using these functions is shown in figure 5.3.


5.5.4 Calling Prolog from C

The Prolog system can be called back from C. This is done by constructing
a term with the functions described above and then calling PL_call().
PL_call() executes the goal and returns TRUE or FALSE depending on success
or failure of the called predicate.  There are no means to backtrack over
the Prolog predicate.  If alternatives are wanted call findall/3 and read
the result from the third argument.


bool PL_call(term, module)
     Call term just like the Prolog predicate once/1.  Term is called in
     the specified module, or in the context module if module = NULL.
     Returns TRUE if the call succeeds, FALSE otherwise.  Figure 5.3 shows
     an example to obtain the number of defined atoms.  All checks are
     omitted to improve readability.


5.5.5 Discarding Data

The Prolog data created during setting up the call and calling Prolog can
in most cases be discarded right after the call.  See figure 5.3 for an
example.


void PL_mark(bktrk_buf)
     Mark the global and trail stacks in bktrk_buf.


void PL_bktrk(bktrk_buf)
     Undo all changes in the runtime stacks since a snapshot has been made
     in buffer using PL_mark().  Changes to the heap are not affected.


It is not necessary to call PL_bktrk() for each PL_mark().  The user
should ensure that PL_bktrk() is never called with a buffer that is
created after a buffer to which PL_bktrk() has been called.  Thus
PL_mark(b1) ...  PL_mark(b2) ...  PL_bktrk(b1) is valid, but it is not
allowed to call PL_bktrk(b2) after this sequence.

    int
    count_atoms()
    { term t;
      int atoms;
      bktrk_buf buf;

      PL_mark(&buf);           /* mark the global stack */

      t = PL_new_term();       /* create `statistics(atoms, Var)' */
      PL_unify_functor(t, PL_new_functor(PL_new_atom("statistics"), 2));
      PL_unify_atomic(PL_arg(t,1), PL_new_atom("atoms"));

      PL_call(t);              /* call it */

                             /* extract the value from the 2nd arg */
      atoms = PL_integer_value(PL_atomic(PL_arg(t, 2)));

      PL_bktrk(&buf);          /* discard global stack data created */

      return atoms;
    }

                     Figure 5.3:  Calling Prolog


5.5.6 Foreign Code and Modules

Modules are identified via a unique handle.  The following functions are
available to query and manipulate modules.


module PL_context()
       Return the module identifier of the context module of the currently
       active foreign predicate.


term PL_strip_module(term, module *)
     Utility function.  If term is a term, possibly holding the module
     construct module:rest this function will return rest and fill module
     * with module.  For further nested module constructs the inner most
     module is returned via module *.  If term is not a module construct
     term will simply be returned.  If module * is NULL it will be set to
     the context module.  Otherwise it will be left untouched.  The
     following example shows how to obtain the plain term and module if
     the default module is the user module:

         { module m = PL_new_module(PL_new_atom("user"));

           if ( (term = PL_strip_module(term, &m)) == NULL )
            return PL_warning("Illegal module specification");

           ...


atomic PL_module_name(module)
       Return the name of module as an atom.


module PL_new_module(atomic)
       Find an existing or create a new module with name specified by the
       atom atomic.


5.5.7 Catching Unix Signals

SWI-Prolog catches the Unix signals SIGINT, SIGFPE and SIGSEGV. To avoid
problems with foreign code attempting to catch these signals foreign code
should call PL_signal() to install signal handlers rather than the Unix
library function signal().  SWI-Prolog will always handle SIGINT itself.
SIGFPE and SIGSEGV are passed to the foreign code handlers if Prolog did
not expect that signal.


void (*PL_signal(sig, func))()
     This function should be used to install signal handlers rather than
     the Unix library function signal().  It ensures consistent signal
     handling between SWI-Prolog and the foreign code and reinstalls
     signal handlers if a state created with save_program/1 is restarted.


5.5.8 Errors and warnings

Two standard functions are available to print standard Prolog errors to
the standard error stream.


bool PL_warning(format, a1, ...)
     Print an error message starting with `[WARNING:', followed by the
     output from format, followed by a `]' and a newline.  Then start the
     tracer.  format and the arguments are the same as for printf(2).  No
     more than 10 arguments can be provided.


void PL_fatal_error(format, a1, ...)
     Print a message like PL_warning(), but starting with `FATAL ERROR:'
     and then exits Prolog.


5.5.9 Environment Control from Foreign Code


bool PL_action(int, C_type)
     Perform some action on the Prolog system.  int describes the action,
     C_type provides the argument if necessary.  The actions are listed in
     table 5.1.

      PL_ACTION_TRACE        Start Prolog tracer

      PL_ACTION_DEBUG        Switch on Prolog debug mode

      PL_ACTION_BACKTRACE    Print backtrace on current output stream

      PL_ACTION_HALT         Halt Prolog execution.  This action should
                             be called rather than Unix exit() to give
                             Prolog the opportunity to clean up.  This
                             call does not return.
      PL_ACTION_ABORT        Generate a Prolog abort.  This call does not
                             return.
      PL_ACTION_BREAK        Create a standard Prolog break environment.
                             Returns after the user types control-D.

      PL_ACTION_SYMBOLFILE   The argument (a char *) is considered to be
                             hold the symbolfile for further incremental
                             loading.  Should be called by user
                             applications that perform incremental
                             loading as well and want to inform Prolog of
                             the new symbol table.

                    Table 5.1:  PL_action() options


5.5.10 Querying Prolog


C_type PL_query(int)
       Obtain status information on the Prolog system.  The actual argument
       type depends on the information required.  int describes what
       information is wanted.  The options are given in table 5.2.

        PL_QUERY_ARGC          Return an integer holding the number of
                               arguments given to Prolog from Unix.

        PL_QUERY_ARGV          Return a char ** holding the argument vector
                               given to Prolog from Unix.

        PL_QUERY_SYMBOLFILE    Return a char * holding the current symbol
                               file of the running process.

        PL_QUERY_ORGSYMBOLFILE Return the initial symbol file (before
                               loading) of Prolog.  By setting the symbol
                               file to this value no name clashes can occur
                               with previously loaded foreign files (but no
                               symbols can be shared with earlier loaded
                               modules as well).

                       Table 5.2:  PL_query() options


5.5.11 Registering Foreign Predicates


bool PL_register_foreign(name, arity, function, [...option...]  0)
     Register a C-function to implement a Prolog predicate.  After this
     call returns successfully a predicate with name name (a char *) and
     arity arity (a C int) is created.  When called in Prolog, Prolog will
     call function.  [...option...]  forms a 0-terminated list of options
     for the installation.  These are:

          PL_FA_NOTRACE           Predicate cannot be seen in the
                                  tracer
          PL_FA_TRANSPARENT       Predicate is module transparent

          PL_FA_NONDETERMINISTIC  Predicate is non-deterministic.  This
                                  attribute is currently ignored, but
                                  will probably be used in future
                                  versions.


5.6 Example of Using the Foreign Interface

Below is an example showing all stages of the declaration of a foreign
predicate that transforms atoms possibly holding uppercase letters into an
atom only holding lower case letters.  Figure 5.4 shows the C-source file.


5.6.1 C-Source file (lowercase.c)

    /*  Include file depends on local installation */
    #include "/usr/local/lib/pl/library/SWI-prolog.h"
    #include <ctype.h>

    long
    pl_lowercase(u, l)
    term u, l;
    { char *copy;
      char *s, *q;
      atomic la;

      if ( PL_type(u) != PL_ATOM )
        return PL_warning("lowercase/2: instantiation fault");
      s = PL_atom_value(PL_atomic(u));
      copy = (char *) malloc(strlen(s)+1);

      for( q=copy; *s; q++, s++)
        *q = (isupper(*s) ? tolower(*s) : *s);
      *q = '\0';

      la = PL_new_atom(copy);
      free(copy);

      return PL_unify_atomic(l, la);
    }

    init_lowercase()
    { PL_register_foreign("lowercase", 2, pl_lowercase, 0);
    }

                  Figure 5.4:  Lowercase source file


5.6.2 Compiling and Loading Foreign Code

    sun% cc -O -c lowercase.c
    sun% pl
    /staff/jan/.plrc consulted, 0.166667 seconds, 2256 bytes.
    Welcome to SWI-Prolog (version 1.5.0, August 1990)
    Copyright (c) 1990, University of Amsterdam

    1 ?- load_foreign(lowercase, init_lowercase).
    foreign file(s) lowercase loaded, 0.016667 seconds, 464 bytes.

    Yes
    2 ?- lowercase('Hello World!', L).

    L = 'hello world!'

    Yes


5.7 Notes on Using Foreign Code


5.7.1 Garbage Collection and Foreign Code

Currently no interface between foreign code and the garbage collector has
been defined.  The garbage collector is disabled during execution of
foreign code.  Future versions might define such an interface.  This
probably will introduce incompatible changes to the current interface
definition.


5.7.2 Memory Allocation

SWI-Prolog's memory allocation is based on the malloc() library routines.
Foreign applications can savely use malloc(), realloc() and free().
Memory allocation using brk() or sbrk() is not allowed as these calls
conflict with malloc().


5.7.3 Debugging Foreign Code

NOTE: this section is highly machine dependent.  The tricks described here
are tested on SUN-3 and SUN-4.  They might work on other BSD variants of
Unix.

Debugging incrementally loaded executables is a bit more difficult than
debugging normal executables.  The oldest way of debugging (putting print
statements in your code at critical points) of course still works.
`Post-crash' debugging however is not possible.  For adb/dbx to work they
need (besides the core) the text segment and the symbol table.  The symbol
table lives somewhere on /tmp (called `/tmp/pl_ld_..._.', where `...'  is
the process id and `.'  is an additional number to make sure the temporary
file is unique.  The text segment lives partly in the core (the
incremental loaded bit) and partly in the SWI-Prolog executable.

The only way to debug foreign language code using a debugger is by
starting the debugger on the running core image.  Dbx(1) can do this.
First compile the source files to be debugged with the `-g' option to
include dbx debugging information.  Then load them into SWI-Prolog.  Now
obtain the name of the current symbol table and the process id of Prolog.
Then start dbx (or dbxtool) using

    sun% dbx[tool] <symbol file> <pid>

Should this be done often then the following foreign predicate definition
might help:

    pl_dbx()
    { char *symbolfile = PL_query(PL_QUERY_SYMBOLFILE);
      char cmd[256];

      sprintf(cmd, "dbxtool %s %d &", symbolfile, getpid());
      if ( system(cmd) == 0 )
        PL_succeed;
      else
        PL_fail;
    }

Register this predicate as dbx/0 using the following call in your
initialisation function:

    PL_register_foreign("dbx", 0, pl_dbx, 0);


5.7.4 Name Conflicts in C modules

In the current version of the system all public C functions of SWI-Prolog
are in the symbol table.  This can lead to name clashes with foreign code.
Someday I should write a program to strip all these symbols from the
symbol table (why does Unix not have that?).  For now I can only suggest
to give your function another name.  You can do this using the C
preprocessor.  If --for example-- your foreign package uses a function
warning(), which happens to exist in SWI-Prolog as well, the following
macro should fix the problem.

    #define warning warning_


5.7.5 Compatibility of the Foreign Interface

As far as I' aware of, there is no standard for foreign language
interfaces in Prolog.  The SWI-Prolog interface is no attempt to propose
such a standard.  It is (in part) tailored to the possibilities of the
SWI-Prolog machinery.  BIM-Prolog has a similar interface to analyse and
construct terms.  The major difference is that they have garbage
collection and calls are made available to lock and unlock terms for
garbage collection.  I built a similar interface to Edinburgh C-Prolog
(although less clean).  This at least tells us that the interface can work
for various forms of the WAM as well as a structure sharing Prolog.

As no standard exists nor emerges, users of the foreign language interface
should carefully design the interface if the C-code should be portable to
other Prolog implementation.  The best advice to give is to define a small
interface layer around the C-application and interface this to Prolog.


Chapter  6

Hackers  corner

This appendix describes a number of predicates which enable the Prolog
user to inspect the Prolog environment and manipulate (or even redefine)
the debugger.  They can be used as entry points for experiments with
debugging tools for Prolog.  The predicates described here should be
handled with some care as it is easy to corrupt the consistency of the
Prolog system by misusing them.

                                477


6.1 Examining the Environment Stack


prolog_current_frame(-Frame)
    Unify Frame with an integer providing a reference to the parent of
    the current local stack frame.  A pointer to the current local frame
    cannot be provided as the predicate succeeds deterministically and
    therefore its frame is destroyed immediately after succeeding.


prolog_frame_attribute(+Frame, +Key, -Value)
    Obtain information about the local stack frame Frame.  Frame is a
    frame reference as obtained through prolog_current_frame/1,
    prolog_trace_interception/3 or this predicate.  The key values are
    described in table 6.1.

    Key               Value
    alternative       Value is unified with an integer reference
                      to the local stack frame in which execution
                      is resumed if the goal associated with Frame
                      fails.  Fails if the frame has no
                      alternative frame.
    has_alternatives  Value is unified with `1' if Frame still is
                      a candidate for backtracking.  `0'
                      otherwise.
    goal              Value is unified with the goal associated
                      with Frame.  If the definition module of the
                      active predicate is not user the goal is
                      represented as module:goal.  Do not
                      instantiate variables in this goal unless
                      you know what you are doing!

    level             Value is unified with the recursion level of
                      Frame.  The top level frame is at level `0'.

    parent            Value is unified with an integer reference
                      to the parent local stack frame of Frame.
                      Fails if Frame is the top frame.

    context_module    Value is unified with the name of the
                      context module of the environment.
    top               Value is unified with `1' if Frame is the
                      top Prolog goal from a recursive call back
                      from the foreign language.  `0' otherwise.

            Table 6.1:  Key values of prolog_current_frame/1


6.2 Intercepting the Tracer


prolog_trace_interception(+Port, +Frame, -Action)
    Dynamic predicate, normally not defined.  This predicate is called
    from the SWI-Prolog debugger just before it would show a port.  If
    this predicate succeeds the debugger assumes the trace action has
    been taken care of and continues execution as described by Action.
    Otherwise the normal Prolog debugger actions are performed.

    Port is one of call, redo, exit, fail or unify.  Frame is an integer
    reference to the current local stack frame.  Action should be unified
    with one of the atoms continue(just continue execution), retry
    (retry the current goal) or fail (force the current goal to fail).
    Leaving it a variable is identical to continue.

    Together with the predicates described in section 3.34 and the other
    predicates of this chapter this predicate enables the Prolog user to
    define a complete new debugger in Prolog.  Besides this it enables
    the Prolog programmer monitor the execution of a program.  The
    example shown in figure 6.1 records all goals trapped by the tracer
    in the database.  To trace the execution of `go' this way the
    following query should be given:

        ?- trace, go, notrace.

       prolog_trace_interception(Port, Frame, continue) :-
              prolog_frame_attribute(Frame, goal, Goal),
              prolog_frame_attribute(Frame, level, Level),
              recordz(trace, trace(Port, Level, Goal)).

              Figure 6.1:  Record a trace in the database


prolog_skip_level(-Old, +New)
    Unify Old with the old value of `skip level' and than set this level
    according to New.  New is an integer, or the special atom very_deep
    (meaning don't skip).  The `skip level' is a global variable of the
    Prolog system that disables the debugger on all recursion levels
    deeper than the level of the variable.  Used to implement the trace
    options `skip' (sets skip level to the level of the frame) and `up'
    (sets skip level to the level of the parent frame (i.e. the level of
    this frame minus 1).


6.3 Exception Handling

A start has been made to make exception handling available to the Prolog
user.  On exceptions a dynamic and multifile defined predicate exception/3
is called.  If this user defined predicate succeeds Prolog assumes the
exception has been taken care of.  Otherwise the system default exception
handler is called.


exception(+Exception, +Context, -Action)
    Dynamic predicate, normally not defined.  Called by the Prolog system
    on run-time exceptions.  Currently exception/3 is only used for
    trapping undefined predicates.  Future versions might handle signal
    handling, floating exceptions and other runtime errors via this
    mechanism.  The values for Exception are described below.

    undefined_predicate
        If Exception is undefined_predicateContext is instantiated to a
        term Name/Arity.  Name refers to the name and Arity to the arity
        of the undefined predicate.  If the definition module of the
        predicate is not user Context will be of the form
        Module:Name/Arity.  If the predicate fails Prolog will print the
        default error warning and start the tracer.  If the predicate
        succeeds it should instantiate the last argument either to the
        atom fail to tell Prolog to fail the predicate or the atom retry
        to tell Prolog to retry the predicate.  This only makes sense if
        the exception handler has defined the predicate.  Otherwise it
        will lead to a loop.

    warning
        If prolog wants to give a warning while reading a file, it will
        first raise the exception warning.  The context argument is a
        term of the form warning(Path, LineNo, Message), where Path is
        the absolute filename of the file prolog is reading; LineNo is an
        extimate of the line number where the error occurred and Message
        is a Prolog string indicating the message.  The Action argument
        is ignored.  The error is supposed to be presented to the user if
        the exception handler succeeds.  Otherwise the standard Prolog
        warning message is printed.

        This exception is used by the library emacs_interface, that
        integrates error handling with GNU-Emacs.


Chapter  7

Predicate  Summary

!/0                         Cut.  Discard choicepoints
*/2                         Arithmetic:  multiplication
+/2                         Arithmetic:  addition
,/2                         Conjuction of goals
-/1                         Arithmetic:  unary minus
-/2                         Arithmetic:  subtraction
->/2                        If-then-else
./2                         List operator.  Also consult
///2                        Arithmetic:  Integer division
//2                         Arithmetic:  division
/\/2                        Arithmetic:  bitwise and
;/2                         Disjunction of goals
</2                         Arithmetic smaller
<</2                        Arithmetic:  bitwise left shift
=../2                       Univ.  Term to list conversion
=/2                         Unification
=:=/2                       Arithmetic equal
=</2                        Arithmetic smaller or equal
==/2                        Identical
=@=/2                       Structural identical
=\=/2                       Arithmetic not equal
>/2                         Arithmetic larger
>=/2                        Arithmetic larger or equal
>>/2                        Arithmetic:  bitwise right shift
@</2                        Standard order smaller
@=</2                       Standard order smaller or equal
@>/2                        Standard order larger
@>=/2                       Standard order larger or equal
\/1                         Bitwise negation
\//2                        Arithmetic:  bitwise or
\+/1                        Negation by failure (not provable)
\=/2                        Not unifyable
\==/2                       Not identical
\=@=/2                      Not structural identical
^/2                         Existential quantification (bagof/3, setof/3)
abolish/2                   Remove predicate definition from the database
abort/0                     Abort execution, return to top level
abs/1                       Arithmetic:  absolute value
absolute_file_name/2         Get absolute Unix path name
access_file/2                Check access permissions of a file
acos/1                      Arithmetic:  inverse (arc) cosine
append/1                    Append to a file
append/3                    Concatenate lists
apply/2                     Call goal with additional arguments
apropos/1                   Show related predicates and manual sections
arithmetic_function/1        Register an evaluable function
arg/3                       Access argument of a term
asin/1                      Arithmetic:  inverse (arc) sine
assert/1                    Add a clause to the database
assert/2                    Add a clause to the database, give reference
asserta/1                   Add a clause to the database (first)
asserta/2                   Add a clause to the database (first)
assertz/1                   Add a clause to the database (last)
assertz/2                   Add a clause to the database (last)
atan/1                      Arithmetic:  inverse (arc) tangent
atan/2                      Arithmetic:  rectangular to polar conversion
atom/1                      Type check for an atom
atom_length/2                Determine length of an atom
atom_to_term/3               Convert between atom and term
atomic/1                    Type check for primitive
bagof/3                     Find all solutions to a goal
between/3                   Integer range checking/generating
break/0                     Start interactive toplevel
call/1                      Call a goal
ceil/1                      Arithmetic:  smallest integer larger than argument
character_count/2            Get character index on a stream
chdir/1                     Change working directory
checklist/2                 Invoke goal on all members of a list
clause/2                    Get clauses of a predicate
clause/3                    Get clauses of a predicate
close/1                     Close stream
compiling/0                 Is this a compilation run?
concat/3                    Append two atoms
concat_atom/2                Append a list of atoms
consult/1                   Read (compile) a Prolog source file
context_module/1             Get context module of current goal
convert_time/8               Convert time stamp
copy_term/2                 Make a copy of a term
cos/1                       Arithmetic:  cosine
cputime/0                   Arithmetic:  get CPU time
current_atom/1               Examine existing atoms
current_arithmetic_function/1 Examine evaluable functions
current_flag/1               Examine existing flags
current_functor/2            Examine existing name/arity pairs
current_input/1              Get current input stream
current_key/1                Examine existing database keys
current_op/3                Examine current operator declaractions
current_output/1             Get the current output stream
current_predicate/2          Examine existing predicates
current_stream/3             Examine open streams
debug/0                     Test for debugging mode
debugging/0                 Show debugger status
delete/3                    Delete all matching members from a list
delete_file/1                Unlink a file from the Unix file system
discontiguous/1              Indicate distributed definition of a predicate
display/1                   Write a term, ignore operators
display/2                   Write a term, ignore operators on a stream
displayq/1                  Write a term with quotes, ignore operators
displayq/2                  Write a term with quotes, ignore operators on a str*
 *eam
dwim_match/2                Atoms match in ``Do What I Mean'' sense
dwim_match/3                Atoms match in ``Do What I Mean'' sense
dwim_predicate/2             Find predicate in ``Do What I Mean'' sense
dynamic/1                   Indicate predicate definition may change
e/0                         Arithmetic:  mathematical constant
ed/0                        Edit last edited predicate
ed/1                        Edit a predicate
edit/0                      Edit last edited file
edit/1                      Edit a file
ensure_loaded/1              Consult a file if that has not yet been done
erase/1                     Erase a database record or clause
exception/3                 Handle runtime exceptions
exists_directory/1           Check existence of Unix directory
exists_file/1                Check existence of Unix file
exp/1                       Arithmetic:  exponent (base e)
expand_file_name/2           Wildcard expansion of file names
export/1                    Export a predicate from a module
fail/0                      Always false
fileerrors/2                Do/Don't warn on file errors
findall/3                   Find all solutions to a goal
flag/3                      Simple global variable system
flatten/2                   Transform nested list into flat list
float/1                     Type check for a floating point number
floor/1                     Arithmetic:  largest integer below argument
flush/0                     Output pending characters on current stream
flush_output/1               Output pending characters on specified stream
forall/2                    Prove goal for all solutions of another goal
foreign_file/1               Examine loaded foreign files
format/1                    Produce formatted output
format/2                    Produce formatted output on a stream
format_predicate/2           Program format/[1,2]
free_variables/2             Find unbound variables in a term
functor/3                   Get name and arity of a term or construct a term
garbage_collect/0            Invoke the garbage collector
gensym/2                    Generate unique atoms from a base
get/1                       Read first non-blank character
get/2                       Read first non-blank character from a stream
get0/1                      Read next character
get0/2                      Read next character from a stream
get_single_char/1            Read next character from the terminal
get_time/1                  Get current time
getenv/2                    Get Unix environment variable
ground/1                    Verify term holds no unbound variables
halt/0                      Exit from Prolog
help/0                      Give help on help
help/1                      Give help on predicates and show parts of manual
history_depth/1              Number of remembered queries
read_history/6               Read using history substitution
ignore/1                    Call the argument, but always succeed
import/1                    Import a predicate from a module
index/1                     Change clause indexing
int_to_atom/2                Convert from integer to atom
int_to_atom/3                Convert from integer to atom (non-decimal)
integer/1                   Arithmetic:  round to nearest integer
integer/1                   Type check for integer
intersection/3               Set intersection
is/2                        Evaluate arithmetic expression
is_list/1                   Type check for a list
is_set/1                    Type check for a set
keysort/2                   Sort, using a key
last/2                      Last element of a list
leash/1                     Change ports visited by the tracer
length/2                    Length of a list
library_directory/1          Directories holding Prolog libraries
limit_stack/2                Limit stack expansion
line_count/2                Line number on stream
line_position/2              Character position in line on stream
list_to_set/2                Remove duplicates
listing/0                   List program in current module
listing/1                   List predicate
load_foreign/2               Load foreign (C) module
load_foreign/5               Load foreign (C) module
log/1                       Arithmetic:  natural logarithm
log10/1                     Arithmetic:  10 base logarithm
make/0                      Reconsult all changed source files
maplist/3                   Transform all elements of a list
max/2                       Arithmetic:  Maximum of two numbers
member/2                    Element is member of a list
memberchk/2                 Deterministic member/2
merge/3                     Merge two sorted lists
merge_set/3                 Merge two sorted sets
min/2                       Arithmetic:  Minimum of two numbers
mod/2                       Arithmetic:  remainder of division
module/2                    Declare a module
module_transparent/1         Indicate module based meta predicate
msort/2                     Sort, do not remove duplicates
multifile/1                 Indicate distributed definition of predicate
name/2                      Convert between atom and list of ASCII characters
nl/0                        Generate a newline
nl/1                        Generate a newline on a stream
nodebug/0                   Disable debugging
nonvar/1                    Type check for bound term
noprotocol/0                Disable logging of user interaction
nospy/1                     Remove spy point
nospyall/0                  Remove all spy points
not/1                       Negation by failure (not provable)
notrace/0                   Stop tracing
nth0/3                      N-th element of a list (0-based)
nth1/3                      N-th element of a list (1-based)
number/1                    Type check for integer or float
numbervars/4                Enumerate unbound variables of a term
once/1                      Call a goal deterministicaly
op/3                        Declare an operator
open/3                      Open a file (creating a stream)
open_null_stream/1           Open a stream to discard output
pi/0                        Arithmetic:  mathematical constant
please/3                    Query/change environment parameters
plus/3                      Logical integer addition
portray/1                   Modify behaviour of print/1
portray_clause/1             Pretty print a clause
predicate_property/2         Query predicate attributes
predsort/3                  Sort, using a predicate to determine the order
preprocessor/2               Install a preprocessor before the compiler
print/1                     Print a term
print/2                     Print a term on a stream
profile/3                   Obtain execution statistics
profile_count/3              Obtain profile results on a predicate
profiler/2                  Obtain/change status of the profiler
prolog/0                    Run interactive toplevel
prolog_current_frame/1       Reference to goal's environment stack
prolog_frame_attribute/3      Obtain information on a goal environment
prolog_skip_level/2          Indicate deepest recursion to trace
prolog_trace_interception/3   Intercept the Prolog tracer
prompt/2                    Change the prompt used by read/1
proper_list/1                Type check for list
protocol/1                  Make a log of the user interaction
protocola/1                 Append log of the user interaction to file
protocolling/1               On what file is user interaction logged
put/1                       Write a character
put/2                       Write a character on a stream
random/1                    Arithmetic:  generate random number
read/1                      Read Prolog term
read/2                      Read Prolog term from stream
read_clause/1                Read clause
read_clause/2                Read clause from stream
read_variables/2             Read clause including variable names
read_variables/3             Read clause including variable names from stream
recorda/2                   Record term in the database (first)
recorda/3                   Record term in the database (first)
recorded/2                  Obtain term from the database
recorded/3                  Obtain term from the database
recordz/2                   Record term in the database (last)
recordz/3                   Record term in the database (last)
rename_file/2                Change name of Unix file
repeat/0                    Succeed, leaving infinite backtrackpoints
reset_profiler/0             Clear statistics obtained by the profiler
retract/1                   Remove clause from the database
retractall/1                Remove unifying clauses from the database
reverse/2                   Inverse the order of the elements in a list
same_file/2                 Succeeds if arguments refer to same file
save_program/1               Save the current program on a file
save_program/2               Save the current program on a file
see/1                       Change the current input stream
seeing/1                    Query the current input stream
seen/0                      Close the current input stream
select/3                    Select element of a list
set_input/1                 Set current input stream from a stream
set_output/1                Set current output stream from a stream
set_tty/2                   Set `tty' stream
setenv/2                    Set Unix environment variable
setof/3                     Find all unique solutions to a goal
sformat/2                   Format on a string
sformat/3                   Format on a string
shell/0                     Execute interactive Unix subshell
shell/1                     Execute Unix command
shell/2                     Execute Unix command
show_profile/1               Show results of the profiler
sin/1                       Arithmetic:  sine
size_file/2                 Get size of a file in characters
sleep/1                     Suspend execution for specified time
sort/2                      Sort elements in a list
source_file/1                Examine currently loaded source files
source_file/2                Obtain source file of predicate
spy/1                       Force tracer on specified predicate
sqrt/1                      Arithmetic:  square root
statistics/0                Show execution statistics
statistics/2                Obtain collected statistics
stream_position/3            Get/seek to position in file
string/1                    Type check for string
string_length/2              Determine length of a string
string_to_atom/2             Conversion between string and atom
string_to_list/2             Conversion between string and list of ASCII
style_check/1                Change level of warnings
sublist/3                   Determine elements that meet condition
subset/2                    Generate/check subset relation
substring/4                 Get part of a string
subtract/3                  Delete elements that do not meet condition
succ/2                      Logical integer successor relation
swritef/2                   Formatted write on a string
swritef/3                   Formatted write on a string
tab/1                       Output number of spaces
tab/2                       Output number of spaces on a stream
tan/1                       Arithmetic:  tangent
tell/1                      Change current output stream
telling/1                   Query current output stream
term_expansion/2             Convert term before compilation
term_to_atom/2               Convert between term and atom
time/1                      Determine time needed to execute goal
time_file/2                 Get last modification time of file
told/0                      Close current output
trace/0                     Start the tracer
tracing/0                   Query status of the tracer
trim_stacks/0                Release unused memory resources
true/0                      Succeed
tty_fold/2                  Make terminal fold long lines in output
tty_get_capability/3         Get terminal parameter
tty_goto/2                  Goto position on screen
tty_put/2                   Write control string to terminal
ttyflush/0                  Flush output on terminal
union/3                     Union of two sets
unknown/2                   Trap undefined predicates
unsetenv/1                  Delete Unix environment variable
use_module/1                Import a module
use_module/2                Import predicates from a module
var/1                       Type check for unbound variable
visible/1                   Set ports that are visible in the tracer
wait_for_input/3             Wait for input with optional timeout
wildcard_match/2             Csh(1) style wildcard match
write/1                     Write term
write/2                     Write term to stream
write_ln/1                  Write term, followed by a newline
writef/1                    Formatted write
writef/2                    Formatted write
writeq/1                    Write term, insert quotes
writeq/2                    Write term, insert quotes on stream
xor/2                       Arithmetic:  exclusive or
|/2                         Disjunction of goals

                                486
