
                                              University of Amsterdam

                                                 Dept.  of Social
                                                Science Informatics

                                                       (SWI)
                                               Roeterstraat 15, 1018
                                                   WB  Amsterdam
                                                  The Netherlands
                                              Tel.  (+31) 20 5256121

                         SSWWII--PPrroolloogg 55..22
                        RReeffeerreennccee MMaannuuaall

           _U_p_d_a_t_e_d _f_o_r _v_e_r_s_i_o_n _5_._2_._1_1_, _N_o_v_e_m_b_e_r _2_0_0_3

                         _J_a_n _W_i_e_l_e_m_a_k_e_r
                       jan@swi.psy.uva.nl
                   http://www.swi-prolog.org

SWI-Prolog  is  a Prolog  implementation based  on a  subset of
the  WAM (Warren Abstract  Machine).   SWI-Prolog was developed
as  an  _o_p_e_n  Prolog  environment,  providing  a  powerful  and
bi-directional  interface  to  C in  an  era  this was  unknown
to   other  Prolog  implementations.      This  environment  is
required  to  deal  with XPCE,  an  object-oriented  GUI system
developed  at SWI. XPCE is  used at SWI for  the development of
knowledge-intensive graphical applications.

As  SWI-Prolog  became  more  popular,  a large  user-community
provided  requirements that  guided its  development.   Compat-
ibility,  portability,   scalability,  stability and  providing
a   powerful  development   environment  have  been   the  most
important  requirements.     Edinburgh,  Quintus,  SICStus  and
the  ISO-standard  guide  the  development  of  the  SWI-Prolog
primitives.

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

Copyright Oc 1990{2003,University of Amsterdam


CChhaapptteerr 11..  IINNTTRROODDUUCCTTIIOONN


11..11 SSWWII--PPrroolloogg

SWI-Prolog started back in  1986 with the requirement for a  Prolog that
could handle recursive interaction with the C-language:   Prolog calling
C and  C calling  Prolog recursively.   Those  days Prolog systems  were
very aware  of its environment  and we needed such  a system to  support
interactive  applications.   Since  then,  SWI-Prolog's development  has
been guided  by requests from the  user community, especially  focussing
on (in arbitrary  order) interaction with the environment,  scalability,
(I/O)  performance,  standard  compliance,   teaching  and  the  program
development environment.

SWI-Prolog  is based  on  a very  restricted  form  of the  WAM  (Warren
Abstract Machine) described  in [Bowen & Byrd, 1983] 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
[Bowen & Byrd, 1983]  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, and  control (;/2, |/2),  if-then
(->/2) and negation-by-failure (\+/1).


11..11..11 BBooookkss aabboouutt PPrroolloogg

This manual does not  describe the full syntax and semantics  of Prolog,
nor how  one should  write a  program in Prolog.    These subjects  have
been  described extensively  in  the literature.    See  [Bratko, 1986],
[Sterling & Shapiro, 1986],   and   [Clocksin & Melish, 1987].       For
more  advanced  Prolog   material  see  [OKeefe, 1990].     Syntax   and
standard  operator declarations  confirm  to the  `Edinburgh  standard'.
Most  built  in  predicates  are  compatible  with  those  described  in
[Clocksin & Melish, 1987].      SWI-Prolog  also  offers  a  number   of
primitive  predicates compatible  with  Quintus Prolog  [Qui, 1997]  and
BIM_Prolog [BIM, 1989].

ISO  compliant  predicates  are based  on  ``Prolog:    The  Standard'',
[Deransart _e_t _a_l_., 1996], validated using [??].


11..22 SSttaattuuss

This manual describes  version 5.2 of SWI-Prolog.   SWI-Prolog has  been
used now for many  years.  The application range includes  Prolog course
material,  meta-interpreters, simulation  of parallel  Prolog,  learning
systems,  natural  language  processing,  complex  interactive  systems,
web-server and  web-server components.   Although we experienced  rather
obvious and  critical bugs can  remain unnoticed  for a remarkable  long
period, we assume  the basic Prolog system is  fairly stable.  Bugs  can
be expected in infrequently used built-in predicates.

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

11..33 CCoommpplliiaannccee ttoo tthhee IISSOO ssttaannddaarrdd

SWI-Prolog 3.3.0 implements  all predicates described in ``Prolog:   The
Standard'' [Deransart _e_t _a_l_., 1996].

Exceptions  and warning  are still  weak.    Some SWI-Prolog  predicates
silently  fail on  conditions where  the ISO  specification requires  an
exception  (functor/3 for  example).    Some predicates  print  warnings
rather than raising an  exception.  All predicates where  exceptions may
be  caused due  to a  correct program  operating in  an imperfect  world
(I/O, arithmetic,  resource overflows)  should behave  according to  the
ISO standard.   In other  words:  SWI-Prolog  should be able to  execute
any program  conforming to [Deransart _e_t _a_l_., 1996]  that does not  rely
on exceptions generated by errors in the program.


11..44 SShhoouulldd yyoouu bbee uussiinngg SSWWII--PPrroolloogg??

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

  o _S_W_I_-_P_r_o_l_o_g _i_s _n_o_t _s_u_p_p_o_r_t_e_d
    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.

  o _M_e_m_o_r_y _r_e_q_u_i_r_e_m_e_n_t_s _a_n_d _p_e_r_f_o_r_m_a_n_c_e _a_r_e _y_o_u_r _f_i_r_s_t _c_o_n_c_e_r_n_s
    A  number  of  commercial compilers  are  more  keen on  memory  and
    performance  than SWI-Prolog.   I do not  wish to sacrifice some  of
    the  nice features of the system, nor its portability to  compete on
    raw performance.

  o _Y_o_u _n_e_e_d _f_e_a_t_u_r_e_s _n_o_t _o_f_f_e_r_e_d _b_y _S_W_I_-_P_r_o_l_o_g
    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:

  o _N_i_c_e _e_n_v_i_r_o_n_m_e_n_t
    This includes `Do  What I Mean', automatic completion of atom names,
    history mechanism and  a tracer that operates on single key-strokes.
    Interfaces  to  some  standard  editors are  provided  (and  can  be
    extended), as well as a facility to maintain programs (see make/0).

  o _V_e_r_y _f_a_s_t _c_o_m_p_i_l_e_r
    Even  very  large applications  can  be loaded  in seconds  on  most
    machines.  If  this is not enough, there is a Quick Load Format that
    is slightly more compact and loading is almost always I/O bound.

  o _T_r_a_n_s_p_a_r_e_n_t _c_o_m_p_i_l_e_d _c_o_d_e
    SWI-Prolog  compiled code can be  treated just as interpreted  code:
    you  can list it, trace  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.

  o _P_r_o_f_i_l_i_n_g
    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.

  o _F_l_e_x_i_b_i_l_i_t_y
    SWI-Prolog  can  easily   be  integrated  with  C,  supporting  non-
    determinism  in Prolog calling  C as well  as C calling Prolog  (see
    section  7.  It can  also be _e_m_b_e_d_d_e_d embedded in external  programs
    (see  section 7.7).  System  predicates can be redefined locally  to
    provide compatibility with other Prolog systems.

  o _I_n_t_e_g_r_a_t_i_o_n _w_i_t_h _X_P_C_E
    SWI-Prolog   offers  a   tight  integration  to   the  Object   Ori-
    ented   Package  for   User  Interface   Development,  called   XPCE
    [Anjewierden & Wielemaker, 1989].    XPCE  allows you  to  implement
    graphical  user  interfaces  that are  source-code  compatible  over
    Unix/X11,  Win32  (Windows  95/98/ME  and NT/2000/XP)  and  MacOS  X
    (darwin).


11..55 TThhee XXPPCCEE GGUUII ssyysstteemm ffoorr PPrroolloogg

The  XPCE GUI  system  for dynamically  typed  languages has  been  with
SWI-Prolog for  a long time.   It is  developed by Anjo Anjewierden  and
Jan  Wielemaker from  the department  of SWI,  University of  Amsterdam.
It  aims at  a  high-productive  development environment  for  graphical
applications based on Prolog.

Object  oriented  technology has  proven  to  be a  suitable  model  for
implementing GUIs, which  typically deal with things Prolog is  not very
good  at:   event-driven  control  and global  state.    With  XPCE,  we
designed  a system  that has  similar characteristics  that make  Prolog
such  a powerful  tool:   dynamic typing,  meta-programming and  dynamic
modification of the running system.

XPCE is  an object-system written  in the C-language.   It provides  for
the implementation of methods  in multiple languages.  New  XPCE classes
may be defined from Prolog using a simple, natural syntax.   The body of
the method is executed  by Prolog itself, providing a  natural interface
between the two systems.  Below is a very simple class definition.

:- pce_begin_class(prolog_lister, frame,
                   "List Prolog predicates").

initialise(Self) :->
        "As the C++ constructor"::
        send_super(Self, initialise, 'Prolog Lister'),
        send(Self, append, new(D, dialog)),
        send(D, append,
             text_item(predicate, message(Self, list, @arg1))),
        send(new(view), below, D).

list(Self, From:name) :->
        "List predicates from specification"::
        (   catch(term_to_atom(Term, From), _, fail)
        ->  get(Self, member, view, V),
            current_output(Old),
            pce_open(V, write, Fd),
            set_output(Fd),
            listing(Term),
            close(Fd),
            set_output(Old)
        ;   send(Self, report, error, 'Syntax error')
        ).

:- pce_end_class.

test :- send(new(prolog_lister), open).

Its  165  built-in   classes  deal  with  the  meta-environment,   data-
representation  and---of  course---graphics.     The   graphics  classes
concentrate on direct-manipulation of diagrammatic representations.

AAvvaaiillaabbiilliittyy.. XPCE  runs on  most  Unixtm platforms,  Windows  95/98/ME,
Windows NT/2000/XP and MacOS  X (using X11).  In the past,  versions for
Quintus- and SICStus Prolog as well as some Lisp  dialects have existed.
After discontinuing  active Lisp  development at SWI  the Lisp  versions
have  died.   Active  development on  the Quintus  and SICStus  versions
has  been stopped  due to  lack  of standardisation  in the  the  Prolog
community.    If adequate  standards  emerge we  are happy  to  actively
support other Prolog implementations.

IInnffoo.. further    information   is    available   from    http://www.swi-
prolog.org/packages/xpce/ or by E-mail to info@www.swi-prolog.org.


11..66 RReelleeaassee NNootteess

Collected release-notes.   This section  only contains some  highlights.
Smaller changes to especially  older releases have been removed.   For a
complete log, see the file ChangeLog from the distribution.


11..66..11 VVeerrssiioonn 11..88 RReelleeaassee NNootteess

Version  1.8 offers  a stack-shifter  to  provide dynamically  expanding
stacks  on machines  that  do  not offer  operating-system  support  for
implementing dynamic stacks.


11..66..22 VVeerrssiioonn 11..99 RReelleeaassee NNootteess

Version  1.9  offers  better portability  including  an  MS-Windows  3.1
version.  Changes to the Prolog system include:

  o _R_e_d_e_f_i_n_i_t_i_o_n _o_f _s_y_s_t_e_m _p_r_e_d_i_c_a_t_e_s
    Redefinition  of system  predicates  was allowed  silently in  older
    versions.    Version 1.9  only allows it  if the  new definition  is
    headed by a :- redefine_system_predicate/1 directive.

  o _`_A_n_s_w_e_r_' _r_e_u_s_e
    The  toplevel maintains  a table  of bindings  returned by  toplevel
    goals  and  allows for  reuse  of these  bindings by  prefixing  the
    variables with the $ sign.  See section 2.8.

  o _B_e_t_t_e_r _s_o_u_r_c_e _c_o_d_e _a_d_m_i_n_i_s_t_r_a_t_i_o_n
    Allows  for proper updating of multifile predicates and  finding the
    sources of individual clauses.


11..66..33 VVeerrssiioonn 22..00 RReelleeaassee NNootteess

New features offered:

  o _3_2_-_b_i_t _V_i_r_t_u_a_l _M_a_c_h_i_n_e
    Removes various limits and improves performance.

  o _I_n_l_i_n_e _f_o_r_e_i_g_n _f_u_n_c_t_i_o_n_s
    `Simple'  foreign predicates no  longer build a Prolog  stack-frame,
    but are directly  called from the VM. Notably provides a speedup for
    the test predicates such as var/1, etc.

  o _V_a_r_i_o_u_s _c_o_m_p_a_t_i_b_i_l_i_t_y _i_m_p_r_o_v_e_m_e_n_t_s

  o _S_t_r_e_a_m _b_a_s_e_d _I_/_O _l_i_b_r_a_r_y
    All  SWI-Prolog's I/O is now  handled by the stream-package  defined
    in  the foreign include file SWI-Stream.h.   Physical I/O of  Prolog
    streams  may be  redefined through the  foreign language  interface,
    facilitating much simpler integration in window environments.


11..66..44 VVeerrssiioonn 22..55 RReelleeaassee NNootteess

Version  2.5  is  an  intermediate release  on  the  path  from  2.1  to
3.0.    All  changes are  to  the foreign-language  interface,  both  to
user- and system-predicates implemented  in the C-language.  The  aim is
twofold.   First of all  to make garbage-collection and  stack-expansion
(stack-shifts)  possible  while  foreign  code  is  active  without  the
C-programmer having  to worry  about locking  and unlocking  C-variables
pointing  to Prolog  terms.    The new  approach is  closely  compatible
to the  Quintus and  SICStus Prolog  foreign interface  using the  +term
argument specification (see their respective manuals).   This allows for
writing foreign  interfaces that  are easily portable  over these  three
Prolog platforms.

Apart from  various bug fixes  listed in the  Changelog file, these  are
the main changes since 2.1.0:

  o _I_S_O _c_o_m_p_a_t_i_b_i_l_i_t_y
    Many   ISO  compatibility  features   have  been  added:     open/4,
    arithmetic functions, syntax, etc.

  o _W_i_n_3_2
    Many  fixes for the Win32 (NT,  '95 and win32s) platforms.   Notably
    many  problems related  to pathnames  and a problem  in the  garbage
    collector.

  o _P_e_r_f_o_r_m_a_n_c_e
    Many  changes to  the clause  indexing system:   added  hash-tables,
    lazy computation of the index information, etc.

  o _P_o_r_t_a_b_l_e _s_a_v_e_d_-_s_t_a_t_e_s
    The   predicate  qsave_program/[1,2] allows  for   the  creating  of
    machine independent saved-states that load very quickly.


11..66..55 VVeerrssiioonn 22..66 RReelleeaassee NNootteess

Version 2.6  provides a stable implementation  of the features added  in
the 2.5.x  releases, but  at the same  time implements  a number of  new
features that may have impact on the system stability.

  o _3_2_-_b_i_t _i_n_t_e_g_e_r _a_n_d _d_o_u_b_l_e _f_l_o_a_t _a_r_i_t_h_m_e_t_i_c
    The  biggest change is the  support for full 32-bit signed  integers
    and  raw  machine-format  double precision  floats.    The  internal
    data  representation as well as  the arithmetic instruction set  and
    interface to the arithmetic functions has been changed for this.

  o _E_m_b_e_d_d_i_n_g _f_o_r _W_i_n_3_2 _a_p_p_l_i_c_a_t_i_o_n_s
    The  Win32 version has been reorganised.   The Prolog kernel is  now
    implemented  as Win32  DLL that may  be embedded in  C-applications.
    Two front ends  are provided, one for window-based operation and one
    to run as a Win32 console application.

  o _C_r_e_a_t_i_n_g _s_t_a_n_d_-_a_l_o_n_e _e_x_e_c_u_t_a_b_l_e_s
    Version  2.6.0 can create  stand-alone executables by attaching  the
    saved-state to the emulator.  See qsave_program/2.


11..66..66 VVeerrssiioonn 22..77 RReelleeaassee NNootteess

Version 2.7  reorganises the  entire data-representation  of the  Prolog
data  itself.   The  aim is  to remove  most of  the  assumption on  the
machine's memory  layout to  improve portability in  general and  enable
embedding on  systems where the memory  layout may depend on  invocation
or on how the executable is linked.  The latter  is notably a problem on
the Win32 platforms.  Porting to 64-bit architectures is feasible now.

Furthermore, 2.7 lifts the  limits on arity of predicates and  number of
variables in  a clause considerably and  allow for further expansion  at
minimal cost.


11..66..77 VVeerrssiioonn 22..88 RReelleeaassee NNootteess

With version  2.8, we declare  the data-representation changes of  2.7.x
stable.   Version  2.8 exploits  the changes  of 2.7  to support  64-bit
processors like the DEC Alpha.  As of  version 2.8.5, the representation
of  recorded  terms  has  changed,  and  terms   on  the  heap  are  now
represented  in a  compiled format.    SWI-Prolog no  longer limits  the
use of malloc()  or uses assumptions on  the addresses returned by  this
function.


11..66..88 VVeerrssiioonn 22..99 RReelleeaassee NNootteess

Version  2.9  is  the next  step  towards  version  3.0,  improving  ISO
compliance  and introducing  ISO  compliant  exception handling.     New
are catch/3, throw/1, abolish/1, write_term/[2,3], write_canonical/[1,2]
and  the C-functions  PL_exception() and  PL_throw().    The  predicates
display/[1,2] and  displayq/[1,2] have  been moved to  backcomp, so  old
code referring to them will autoload them.

The interface  to PL_open_query() has changed.    The _d_e_b_u_g argument  is
replaced  by a  bitwise or'ed  _f_l_a_g_s argument.    The  values FALSE  and
TRUE have their familiar meaning, making old code  using these constants
compatible.   Non-zero values  other than TRUE  (1) will be  interpreted
different.


11..66..99 VVeerrssiioonn 33..00 RReelleeaassee NNootteess

Complete  redesign   of  the   saved-state  mechanism,   providing   the
possibility of  `program resources'.   See  resource/3, open_resource/3,
and qsave_program/[1,2].


11..66..1100 VVeerrssiioonn 33..11 RReelleeaassee NNootteess

Improvements   on  exception-handling.       Allows  relating   software
interrupts (signals)  to exceptions,  handling signals in  Prolog and  C
(see on_signal/3  and PL_signal()).   Prolog stack  overflows now  raise
the resource_error  exception and thus  can be handled  in Prolog  using
catch/3.


11..66..1111 VVeerrssiioonn 33..33 RReelleeaassee NNootteess

Version 3.3  is a  major release,  changing many  things internally  and
externally.   The highlights are a  complete redesign of the  high-level
I/O system, which is  now based on explicit streams rather  then current
input/output.  The  old Edinburgh predicates (see/1, tell/1, etc.)   are
now defined on top of this layer instead of the other  way around.  This
fixes various internal problems and removes Prolog limits  on the number
of streams.

Much  progress  has been  made  to  improve ISO  compliance:    handling
strings  as  lists  of  one-character  atoms  is   now  supported  (next
to  character   codes  as  integers).      Many  more  exceptions   have
been  added and  printing  of exceptions  and messages  is  rationalised
using   Quintus   and   SICStus   Prolog   compatible   print_message/2,
message_hook/3 and print_message_lines/3.   All predicates descriped  in
[Deransart _e_t _a_l_., 1996] are now implemented.

As of version  3.3, SWI-Prolog adheres the  ISO _l_o_g_i_c_a_l _u_p_d_a_t_e _v_i_e_w  for
dynamic predicates.  See section 4.13.1 for details.

SWI-Prolog  3.3  includes garbage  collection  on  atoms,  removing  the
last serious memory  leak especially in text-manipulation  applications.
See  section 7.6.2.1.    In addition,  both the  user-level and  foreign
interface supports atoms holding _0_-_b_y_t_e_s.

Finally, an  alpha version of a  multi-threaded SWI-Prolog for Linux  is
added.    This version  is still  much slower  than the  single-threaded
version due  to frequent access to  `thread-local-data' as well as  some
too detailed  mutex locks.   The basic thread  API is ready for  serious
use and testing however.  See section 6.


11..66..1111..11 IInnccoommppaattiibbllee cchhaannggeess

A number  of incompatible changes  result from this upgrade.   They  are
all easily fixed however.

  o !/0_, call/1
    The  cut now behaves  according to the ISO  standard.  This  implies
    it  works in compound  goals passed  to call/1 and  is local to  the
    _c_o_n_d_i_t_i_o_n part of if-then-else as well as the argument of \+/1.

  o atom_chars/2
    This  predicate  is now  ISO  compliant and  thus generates  a  list
    of  one-character atoms.    The behaviour  of the  old predicate  is
    available  in the  ---also ISO compliant---  atom_codes/2 predicate.
    Safest  repair is a  replacement of all  atom_chars  into atom_codes.
    If you do not want to change any souce-code, you might want to use

    user:goal_expansion(atom_chars(A,B), atom_codes(A,B)).

  o number_chars/2
    Same applies for number_chars/2 and number_codes/2.

  o feature/2_, set_feature/2
    These  are replaced by  the ISO  compliant current_prolog_flag/2 and
    set_prolog_flag/2.   The library  backcomp provides definitions  for
    feature/2 and set_feature/2, so no source hhaass to be updated.

  o _A_c_c_e_s_s_i_n_g _c_o_m_m_a_n_d_-_l_i_n_e _a_r_g_u_m_e_n_t_s
    This  used  to   be  provided  by  the  undocumented  '$argv'/1  and
    Quintus  compatible library unix/1.   Now  there is also  documented
    current_prolog_flag(_a_r_g_v_, _A_r_g_v).

  o dup_stream/2
    Has  been deleted.   New  stream-aliases can deal  with most of  the
    problems  for which  dup_stream/2 was  designed and  dup/2 from  the
    _c_l_i_b package can with most others.

  o op/3
    Operators  are now llooccaall ttoo mmoodduulleess.  This implies  any modification
    of  the operator-table does  not influence other  modules.  This  is
    consistent  with the proposed ISO behaviour and a necessity  to have
    any usable handling of operators in a multi-threaded environment.

  o _s_e_t___p_r_o_l_o_g___f_l_a_g_(_c_h_a_r_a_c_t_e_r___e_s_c_a_p_e_s_, _B_o_o_l_)
    This  prolog flag is now an interface to changing attributes  on the
    current source-module,  effectively making this flag module-local as
    well.   This is required for consistent handling of  sources written
    with  ISO (obligatory) character-escape sequences together  with old
    Edinburgh code.

  o current_stream/3 _a_n_d _s_t_r_e_a_m___p_o_s_i_t_i_o_n
    These predicates have been moved to quintus.


11..66..1122 VVeerrssiioonn 33..44 RReelleeaassee NNootteess

The  3.4 release  is  a consolidation  release.    It  consolidates  the
improvements  and  standard conformance  of  the  3.3 releases.     This
version  is closely  compatible  with the  3.3  version except  for  one
important change:

  o _A_r_g_u_m_e_n_t _o_r_d_e_r _i_n select/3
    The  list-processing  predicate select/3  somehow  got into  a  very
    early  version of SWI-Prolog  with the wrong  argument order.   This
    has been fixed in  3.4.0.  The correct order is select(?Elem, ?List,
    ?Rest).

    As  select/3 has  no error  conditions, runtime  checking cannot  be
    done.   To simplify  debugging, the library module checkselect  will
    print  references to  select/3  in your  source code  and install  a
    version  of select that enters the debugger if select is  called and
    the second argument is not a list.

    This   library   can   be   loaded   explicitely   or   by   calling
    check_old_select/0.


11..66..1133 VVeerrssiioonn 44..00 RReelleeaassee NNootteess

As of  version 4.0 the  standard distribution  of SWI-Prolog is  bundled
with a  number of its  popular extension packages,  among which the  now
open source XPCE GUI toolkit (see section 1.5).   No significant changes
have been made to the basic SWI-Prolog engine.

Some useful tricks in the integrated environment:

  o _R_e_g_i_s_t_e_r _t_h_e _G_U_I _t_r_a_c_e_r
    Using  a call to guitracer/0,  hooks are installed that replace  the
    normal command-line driven tracer with a graphical forntend.

  o _R_e_g_i_s_t_e_r _P_c_e_E_m_a_c_s _f_o_r _e_d_i_t_i_n_g _f_i_l_e_s
    From  your initialisation file.  you  can load emacs/swi_prolog that
    cause edit/1 to use the built-in PceEmacs editor.


11..66..1144 VVeerrssiioonn 55..00 RReelleeaassee NNootteess

Version  5.0 marks  a breakpoint  in  the phylosophy,  where  SWI-Prolog
moves  from  a  dual GPL/proprietary  to  a  uniform  LGPL  (Lesser  GNU
Public Licence)  schema, providing  a widely usable  Free Source  Prolog
implementation.

On  the  technical  site  the  development  environment,  consisting  of
source-level  debugger,  integrated  editor  and  various  analysis  and
navigation tools progress steadily towards a mature set of tools.

Many portability issues have been improved, including a  port to MacOS X
(Darwin).

For details, please visit the new website at http://www.swi-prolog.org


11..66..1155 VVeerrssiioonn 55..11 RReelleeaassee NNootteess

Version 5.1 is  a beta-serie introducing portable multi-threading.   See
chapter 6.   In  addition it introduces many  new facilities to  support
server applications,  such as  the new  rlimit library  to limit  system
resources and the possibility to set timeouts on input streams.


11..66..1166 VVeerrssiioonn 55..22 RReelleeaassee NNootteess

Version  5.2  consolidates   the  5.1.x  beta  series  that   introduced
threading and many related modifications to the kernel.


11..77 DDoonnaattee ttoo tthhee SSWWII--PPrroolloogg pprroojjeecctt

If you  are happy with  SWI-Prolog, you  care it to  be around for  much
longer while it becomes  faster, more stable and with more  features you
should consider to  donate to the SWI-Prolog  foundation.  Please  visit
the page below.

    http://www.swi-prolog.org/donate.html


11..88 AAcckknnoowwlleeddggeemmeennttss

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 _t_h_i_e_f  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.

Martin Jansche  (jansche@novell1.gs.uni-heidelberg.de) has been so  kind
to reorganise the sources for version 2.1.3 of this manual.

Horst  von Brand  has been  so  kind to  fix many  typos  in the  2.7.14
manual.  Thanks!


CChhaapptteerr 22..  OOVVEERRVVIIEEWW


22..11 GGeettttiinngg ssttaarrtteedd qquuiicckkllyy


22..11..11 SSttaarrttiinngg SSWWII--PPrroolloogg


22..11..11..11 SSttaarrttiinngg SSWWII--PPrroolloogg oonn UUnniixx

By default, SWI-Prolog is installed as `pl',  though some administrators
call  it  `swipl'  or `swi-prolog'.     The  command-line  arguments  of
SWI-Prolog  itself  and  its  utility  programs   are  documented  using
standard  Unix  man pages.     SWI-Prolog  is normally  operated  as  an
interactive application simply by starting the program:

machine% pl
Welcome to SWI-Prolog (Version 5.2.0)
Copyright (c) 1990-2003 University of Amsterdam.
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.

For help, use ?- help(Topic). or ?- apropos(Word).

1 ?-

After  starting Prolog,  one  normally loads  a  program into  it  using
consult/1,  which---for  historical  reasons---may   be  abbreviated  by
putting the  name of  the program  file between  square brackets.    The
following  goal loads  the  file  likes.pl containing  clauses  for  the
predicates likes/2:

?- [likes].
% likes compiled, 0.00 sec, 596 bytes.

Yes
?-

After this  point, Unix  and Windows users  unite, so  if you are  using
Unix please continue at section 2.1.2.


22..11..11..22 SSttaarrttiinngg SSWWII--PPrroolloogg oonn WWiinnddoowwss

After SWI-Prolog has been  installed on a Windows system,  the following
important new things are available to the user:

  o A  folder  (called  _d_i_r_e_c_t_o_r_y in  the  remainder of  this  document)
    called  pl  containing the  executables,  libraries, etc.    of  the
    system.  No files are installed outside this directory.

  o A  program  plwin.exe,  providing  a  window  for  interaction  with
    Prolog.  The  program plcon.exe is a version of SWI-Prolog that runs
    in a DOS-box.

  o The  file-extension .pl  is associated with  the program  plwin.exe.
    Opening  a .pl file will cause plwin.exe to start,  change directory
    to  the directory in  which the file-to-open  resides and load  this
    file.

The  normal   way  to  start  with   the  likes.pl  file  mentioned   in
section 2.1.1.1  is by simply double-clicking  this file in the  Windows
explorer.


22..11..22 EExxeeccuuttiinngg aa qquueerryy

After loading a program,  one can ask Prolog queries about  the program.
The query below asks Prolog what food `sam' likes.   The system responds
with X = <_v_a_l_u_e> if it can prove the goal for a certain _X. The  user can
type the semi-colon  (;) if (s)he wants  another solution, or return  if
(s)he is satisfied, after which Prolog will say YYeess.   If Prolog answers
NNoo,  it  indicates it  cannot  find any  (more)  answers to  the  query.
Finally, Prolog can answer using an error message  to indicate the query
or program contains an error.

?- likes(sam, X).

X = dahl ;

X = tandoori ;

...

X = chips ;

No
?-


22..22 TThhee uusseerr''ss iinniittiiaalliissaattiioonn ffiillee

After  the necessary  system  initialisation  the system  consults  (see
consult/1) the user's startup file.  The base-name  of this file follows
conventions of  the operating  system.   On MS-Windows,  it is the  file
pl.ini  and on  Unix systems  .plrc.   The  file is  searched using  the
file_search_path/2 clauses for user_profile.  The table below  shows the
default value for this search-path.

     _______________________________________________________________
     |________________|UUnniixx__||WWiinnddoowwss________________________________________________________________________________||
     || llooccaall  ||.    |.                                              |

     | hhoommee   ||~    |%HOME% or %HOMEDRIVE%\%HOMEPATH%               |
     |_global_|____|SWI-Home_directory_or_%WINDIR%_or_%SYSTEMROOT%_|_

After the  first startup  file is found  it is  loaded and Prolog  stops
looking for further startup files.  The name of the  startup file can be
changed with the  `-f file' option.   If _F_i_l_e denotes an absolute  path,
this file is loaded,  otherwise the file is searched for using  the same
conventions as for the default startup file.  Finally,  if _f_i_l_e is none,
no file is loaded.


22..33 IInniittiiaalliissaattiioonn ffiilleess aanndd ggooaallss

Using  commandline  arguments  (see  section  2.4),  SWI-Prolog  can  be
forced to  load files  and execute queries  for initialisation  purposes
or  non-interactive operation.    The  most  commonly used  options  are
-f file or  -s file to  make Prolog load  a file,  -g goal to define  an
initialisation  goal and  -t goal to  define  the _t_o_p_l_e_v_e_l  _g_o_a_l.    The
following  is a  typical example  for starting  an application  directly
from the commandline.

machine% pl -s load.pl -g go -t halt

It tells  SWI-Prolog to load  load.pl, start  the application using  the
_e_n_t_r_y_-_p_o_i_n_t go/0 and ---instead of entering  the interactive toplevel---
exit  after completing  go/0.    The  -q  may  be used  to  supress  all
informational messages.

In  MS-Windows,  the  same  can  be  achieved  using  a  short-cut  with
appropriately  defined  commandline   arguments.     A  typically   seen
alternative  is to  write  a file  run.pl  with content  as  illustrated
below.  Double-clicking run.pl will start the application.

:- [load].                      % load program
:- go.                          % run it
:- halt.                        % and exit

Section  2.10.2.1 discusses  further  scripting  options and  chapter  8
discusses the  generation of runtime executables.   Runtime  executables
are  a mean  to  deliver executables  that  do  not require  the  Prolog
system.


22..44 CCoommmmaanndd lliinnee ooppttiioonnss

The full set of command line options is given below:

--hheellpp
    When  given as  the only  option, it summarises  the most  important
    options.

--vv
    When  given as the  only option, it  summarises the version and  the
    architecture identifier.

--aarrcchh
    When   given  as  the  only  option,  it  prints   the  architecture
    identifier  (see  current_prolog_flag(arch,  Arch)) and  exits.    See
    also -dump-runtime-variables.

--dduummpp--rruunnttiimmee--vvaarriiaabblleess
    When  given as  the only option,  it prints  a sequence of  variable
    settings  that can  be  used in  shell-scripts to  deal with  Prolog
    parameters.   This feature is  also used by plld (see section  7.7).
    Below is a typical example of using this feature.

    eval `pl -dump-runtime-variables`
    cc -I$PLBASE/include -L$PLBASE/runtime/$PLARCH ...

--qq
    Set the prolog-flag  verbose to silent, supressing informational and
    banner messages.

--LL_s_i_z_e_[_k_m_]
    Give  local stack limit (2 Mbytes default).   Note that there  is no
    space  between the size option  and its argument.   By default,  the
    argument  is interpreted in  Kbytes.   Postfixing the argument  with
    m  causes the argument to be  interpreted in Mbytes.  The  following
    example specifies 32 Mbytes local stack.

    % pl -L32m

    A maximum is  useful to stop buggy programs from claiming all memory
    resources.   -L0 sets the limit to the highest possible value.   See
    section 2.16.

--GG_s_i_z_e_[_k_m_]
    Give  global  stack limit  (4 Mbytes  default).    See -L  for  more
    details.

--TT_s_i_z_e_[_k_m_]
    Give  trail  stack  limit  (4  Mbytes  default).     This  limit  is
    relatively  high because trail-stack overflows are not  often caused
    by program bugs.  See -L for more details.

--AA_s_i_z_e_[_k_m_]
    Give  argument stack limit (1 Mbytes  default).  The argument  stack
    limits  the  maximum  nesting of  terms  that  can be  compiled  and
    executed.    SWI-Prolog does `last-argument  optimisation' to  avoid
    many  deeply nested  structure  using this  stack.   Enlarging  this
    limit is only necessary in extreme cases.  See -L for more details.

--cc _f_i_l_e _._._.
    Compile files into an `intermediate code file'.  See section 2.10.

--oo _o_u_t_p_u_t
    Used  in combination  with -c  or -b  to determine  output file  for
    compilation.

--OO
    Optimised compilation.  See current_prolog_flag/2.

--ss _f_i_l_e
    Use  _f_i_l_e as a  script-file.   The script file  is loaded after  the
    initialisation  file  specified with  the -f file  option.    Unlike
    -f file,  using -s does  not stop Prolog  from loading the  personal
    initialisation file.

--ff _f_i_l_e
    Use _f_i_l_e as  initialisation file instead of the default .plrc (Unix)
    or pl.ini (Windows).   `-f none' stops SWI-Prolog from searching for
    a  startup file.    This option  can be  used as  an alternative  to
    -s file  that stops Prolog from loading the  personal initialisation
    file.  See also section 2.2.

--FF _s_c_r_i_p_t
    Selects  a startup-script from the  SWI-Prolog home directory.   The
    script-file  is  named <_s_c_r_i_p_t>.rc.    The  default _s_c_r_i_p_t  name  is
    deduced  from  the  executable,  taking the  leading  alphanumerical
    characters  (letters, digits and underscore) from  the program-name.
    -F none stops looking  for a script.  Intended for simple management
    of  slightly  different  versions.    One  could for  example  write
    a  script  iso.rc  and  then select  ISO  compatibility  mode  using
    pl -F iso or make a link from iso-pl to pl.

--gg _g_o_a_l
    _G_o_a_l  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.   _g_o_a_l can be a  complex
    term.   In this case quotes  are normally needed to protect  it from
    being expanded by the Unix shell.

--tt _g_o_a_l
    Use  _g_o_a_l  as  interactive  toplevel instead  of  the  default  goal
    prolog/0.    _g_o_a_l  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.

--ttttyy
    Unix  only.      Switches  controlling  the  terminal  for  allowing
    single-character  commands to the tracer and  get_single_char/1.   By
    default  manipulating  the terminal  is  enabled unless  the  system
    detects  it is not  connected to a  terminal or it  is running as  a
    GNU-Emacs  inferior process.   This flag  is sometimes required  for
    smooth interaction with other applications.

--nnoossiiggnnaallss
    Inhibit any signal  handling by Prolog, a property that is sometimes
    desirable  for embedded  applications.   This option  sets the  flag
    signals to false.  See section 7.6.18.1 for defails.

--xx _b_o_o_t_f_i_l_e
    Boot  from _b_o_o_t_f_i_l_e instead  of the system's default  boot file.   A
    bootfile is a  file resulting from a Prolog compilation using the -b
    or -c option or a program saved using qsave_program/[1,2].

--pp _a_l_i_a_s_=_p_a_t_h_1_[_:_p_a_t_h_2 _._._._]
    Define  a path alias for file_search_path.  _a_l_i_a_s is the name  of the
    alias,  _p_a_t_h_1 _._._.  is  a list of values for  the alias.  On  Windows
    the  list-seperator is ;.   On other  systems it is :.   A value  is
    either  a term of the form  alias(value) or pathname.  The  computed
    aliases  are added  to file_search_path/2 using  asserta/1, so  they
    precede  predefined values  for the  alias.   See file_search_path/2
    for details on using this file-location mechanism.

--
    Stops  scanning for more  arguments, so you  can pass arguments  for
    your  application after this  one.   See current_prolog_flag/2 using
    the flag argv for obtaining the commandline arguments.

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

--bb _i_n_i_t_f_i_l_e _._._.-c _f_i_l_e _._._.
    Boot  compilation.   _i_n_i_t_f_i_l_e  _._._.   are compiled  by the  C-written
    bootstrap  compiler,  _f_i_l_e  _._._.    by  the normal  Prolog  compiler.
    System maintenance only.

--dd _l_e_v_e_l
    Set  debug  level to  _l_e_v_e_l.    Only  has effect  if the  system  is
    compiled with the -DO_DEBUG flag.  System maintenance only.


22..55 GGNNUU EEmmaaccss IInntteerrffaaccee

The default  Prolog mode for  GNU-Emacs can be  activated by adding  the
following rules to your Emacs initialisation file:

(setq auto-mode-alist
      (append
       '(("\\.pl" . prolog-mode))
       auto-mode-alist))
(setq prolog-program-name "pl")
(setq prolog-consult-string "[user].\n")
;If you want this.  Indentation is either poor or I don't use
;it as intended.
;(setq prolog-indent-width 8)

Unfortunately the  default Prolog mode  of GNU-Emacs  is not very  good.
An  alternative  prolog.el  file for  GNU-Emacs  20  is  available  from
http://www.freesoft.cz/ pdm/software/emacs/prolog-mode/  and  for   GNU-
Emacs 19 from http://w1.858.telia.com/ u85810764/Prolog-mode/index.html


22..66 OOnnlliinnee HHeellpp

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.

The online help  is displayed from the  file 'MANUAL'. The file  helpidx
provides  an index  into  this  file.    'MANUAL'  is created  from  the
LaTeX sources  with a modified version  of dvitty, using overstrike  for
printing bold  text and  underlining for  rendering italic text.    XPCE
is shipped  with swi_help,  presenting the information  from the  online
help in a  hypertext window.  The prolog-flag  write_help_with_overstrike
controls whether  or not help/1  writes its  output using overstrike  to
realise bold  and underlined  output or  not.   If  this prolog-flag  is
not  set it  is initialised  by the  help library  to true  if the  TERM
variable equals  xterm and false  otherwise.  If  this default does  not
satisfy you, add the  following line to your personal startup  file (see
section 2.2):

:- set_prolog_flag(write_help_with_overstrike, true).


hheellpp
    Equivalent to help(help/1).


hheellpp((_+_W_h_a_t))
    Show specified part of the manual.  _W_h_a_t is one of:

          <_N_a_m_e>/<_A_r_i_t_y> Give help on specified predicate
          <_N_a_m_e>         Give  help on  named  predicate with  any
                         arity or  C interface function  with that
                         name
          <_S_e_c_t_i_o_n>      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()

    See also apropos/1,  and the SWI-Prolog home page at http://www.swi-
    prolog.org,  which provides  a FAQ,  an HTML version  of manual  for
    online browsing and HTML and PDF versions for downloading.


aapprrooppooss((_+_P_a_t_t_e_r_n))
    Display all predicates,  functions and sections that have _P_a_t_t_e_r_n in
    their  name or summary  description.   Lowercase letters in  _P_a_t_t_e_r_n
    also match a corresponding uppercase letter.  Example:

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

eexxppllaaiinn((_+_T_o_E_x_p_l_a_i_n))
    Give an explanation on  the given `object'.  The argument may be any
    Prolog data object.   If the argument is an atom, a term of the form
    _N_a_m_e_/_A_r_i_t_y  or a term  of the  form _M_o_d_u_l_e_:_N_a_m_e_/_A_r_i_t_y, explain  will
    try to explain the predicate as well as possible references to it.


eexxppllaaiinn((_+_T_o_E_x_p_l_a_i_n_, _-_E_x_p_l_a_n_a_t_i_o_n))
    Unify  _E_x_p_l_a_n_a_t_i_o_n with an explanation for _T_o_E_x_p_l_a_i_n.   Backtracking
    yields further explanations.


22..77 QQuueerryy SSuubbssttiittuuttiioonnss

SWI-Prolog  offers a  query substitution  mechanism similar  to that  of
Unix csh (csh(1)), called  `history'.  The availability of  this feature
is controlled by  set_prolog_flag/2, using  the history prolog-flag.   By
default,  history is  available if  the prolog-flag  readline is  false.
To  enable this  feature,  remembering the  last  50 commands,  put  the
following into your startup file (see section 2.2:

:- set_prolog_flag(history, 50).

The history  system 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.
       __________________________________________________________
       | !!.            |Repeat last query                        |

       | !nr.           |Repeat query numbered <_n_r>               |
       | !str.          |Repeat last query starting with <_s_t_r>    |
       | !?str.         |Repeat last query holding <_s_t_r>          |
       | ^old^new.      |Substitute <_o_l_d> into <_n_e_w> in last query |
       | !nr^old^new.   |Substitute in query numbered <_n_r>        |
       | !str^old^new.  |Substitute in query starting with <_s_t_r>  |
       | !?str^old^new. |Substitute in query holding <_s_t_r>        |
       | h.             |Show history list                        |

       |_!h.____________|Show_this_list__________________________ |

                      Table 2.1:  History commands


22..77..11 LLiimmiittaattiioonnss ooff tthhee HHiissttoorryy SSyysstteemm

History expansion  is executed  after _r_a_w_-_r_e_a_d_i_n_g.   This  is the  first
stage of read_term/2 and friends,  reading the term into a  string while
deleting comment  and canonising blank.   This makes  it hard to use  it
for correcting  syntax errors.   Command-line editing as provided  using
the GNU-readline library is  more suitable for this.   History expansion
is first  of all useful  for executing or  combining commands from  long
ago.


22..88 RReeuussee ooff ttoopplleevveell bbiinnddiinnggss

Bindings resulting from the successful execution of a  toplevel goal are
asserted in a database.  These values may be  reused in further toplevel
queries as $Var.  Only the latest binding is available.  Example:
1 ?- maplist(plus(1), "hello", X).

X = [105,102,109,109,112]

Yes
2 ?- format('~s~n', [$X]).
ifmmp

Yes

3 ?-

                 Figure 2.1:  Reusing toplevel bindings

Note that variables may be set by executing =/2:

6 ?- X = statistics.

X = statistics

Yes
7 ?- $X.
28.00 seconds cpu time for 183,128 inferences
4,016 atoms, 1,904 functors, 2,042 predicates, 52 modules
55,915 byte codes; 11,239 external references

                      Limit    Allocated       In use
Heap         :                                624,820 Bytes
Local  stack :    2,048,000        8,192          404 Bytes
Global stack :    4,096,000       16,384          968 Bytes
Trail  stack :    4,096,000        8,192          432 Bytes

Yes
8 ?-


22..99 OOvveerrvviieeww ooff tthhee DDeebbuuggggeerr

SWI-Prolog has  a 6-port  tracer, extending the  standard 4-port  tracer
[Clocksin & Melish, 1987]  with two  additional  ports.    The  optional
_u_n_i_f_y port allows  the user to inspect  the result after unification  of
the head.  The _e_x_c_e_p_t_i_o_n port shows exceptions raised  by throw/1 or one
of the built-in predicates.  See section 4.9.

The standard  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/0) or  when an
exception is raised.

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 write_term/2.  The style is defined  by the prolog-flag
debugger_print_options  and can be modified using this flag or  using the
w, p and d commands of the tracer.
1 ?- visible(+all), leash(-exit).

Yes
2 ?- 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)

Yes
[trace] 3 ?-

                       Figure 2.2:  Example trace

On _l_e_a_s_h_e_d  _p_o_r_t_s (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 wwiitthhoouutt waiting  for a
return, unless the command line option -tty is active.  Tracer options:

+ ((SSppyy))
    Set a spy point (see spy/1) on the current predicate.

- ((NNoo ssppyy))
    Remove the spy point (see nospy/1) from the current predicate.

/ ((FFiinndd))
    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.

. ((RReeppeeaatt ffiinndd))
    Repeat the last find command (see `/').

A ((AAlltteerrnnaattiivveess))
    Show all goals that have alternatives.

C ((CCoonntteexxtt))
    Toggle  `Show Context'.   If on  the context module  of the goal  is
    displayed between square brackets (see section 5).  Default is off.

L ((LLiissttiinngg))
    List the current predicate with listing/1.

a ((AAbboorrtt))
    Abort Prolog execution (see abort/0).

b ((BBrreeaakk))
    Enter a Prolog break environment (see break/0).

c ((CCrreeeepp))
    Continue execution, stop at next port.  (Also return, space).

d ((DDiissppllaayy))
    Set  the max_depth(_D_e_p_t_h) option of debugger_print_options,  limiting
    the  depth  to which  terms are  printed.    See also  the  w and  p
    options.

e ((EExxiitt))
    Terminate Prolog (see halt/0).

f ((FFaaiill))
    Force failure of the current goal.

g ((GGooaallss))
    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 ((HHeellpp))
    Show available options (also `?').

i ((IIggnnoorree))
    Ignore the current goal, pretending it succeeded.

l ((LLeeaapp))
    Continue execution, stop at next spy point.

n ((NNoo ddeebbuugg))
    Continue execution in `no debug' mode.

p ((PPrriinntt))
    Set   the   prolog-flag  debugger_print_options  to   [quoted(true),
    portray(true), max_depth(10)].  This is the default.

r ((RReettrryy))
    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 ((SSkkiipp))
    Continue  execution,  stop  at the  next  port  of tthhiiss  goal  (thus
    skipping all calls to children of this goal).

u ((UUpp))
    Continue  execution, stop at the next port of tthhee ppaarreenntt  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 ((WWrriittee))
    Set   the  prolog-flag   debugger_print_options  to   [quoted(true)],
    bypassing portray/1, etc.

The   ideal  4   port  model   as  described   in   many  Prolog   books
[Clocksin & Melish, 1987] 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.

Reference information to  all predicates available for manipulating  the
debugger is in section 4.39.


22..1100 CCoommppiillaattiioonn


22..1100..11 DDuurriinngg pprrooggrraamm ddeevveellooppmmeenntt

During  program   development,  programs   are  normally  loaded   using
consult/1, or the list abbreviation.  It is  common practice to organise
a project  as a  collection of source-files  and a  _l_o_a_d_-_f_i_l_e, a  Prolog
file  containing only  use_module/[1,2]  or ensure_loaded/1  directives,
possibly  with a  definition  of the  _e_n_t_r_y_-_p_o_i_n_t  of the  program,  the
predicate that  is normally used  to start  the program.   This file  is
often  called load.pl.    If the  entry-point is  called _g_o,  a  typical
session starts as:

% pl
<banner>

1 ?- [load].
<compilation messages>

Yes
2 ?- go.
<program interaction>

When  using  Windows,  the  user  may  open  load.pl  from  the  Windows
explorer,  which will cause  plwin.exe to  be started  in the  directory
holding load.pl.  Prolog loads load.pl before entering the toplevel.


22..1100..22 FFoorr rruunnnniinngg tthhee rreessuulltt

There are  various options if  you want to make  your program ready  for
real usage.   The best  choice depends on whether  the program is to  be
used only  on machines  holding the SWI-Prolog  development system,  the
size of the program and the operating system (Unix vs. Windows).


22..1100..22..11 UUssiinngg PPrroollooggSSccrriipptt

New in  version 4.0.5  is the possibility  to use  a Prolog source  file
directly  as a  Unix  script-file.   the  same  mechanism is  useful  to
specify additional parameters for running a Prolog file on Windows.

If the  first letter of a  Prolog file is #,  the first line is  treated
as comment.  To  create a Prolog script, make the first line  start like
this:

    #!/path/to/pl <_o_p_t_i_o_n_s> -s

Prolog recognises this  starting sequence and causes the interpreter  to
receive the following argument-list:

    /path/to/pl <_o_p_t_i_o_n_s> -s <_s_c_r_i_p_t> -- <_S_c_r_i_p_t_A_r_g_u_m_e_n_t_s>

Instead of  -s, the user may  use -f to stop  Prolog from looking for  a
personal initialisation file.

Here is a simple script doing expression evaluation:

#!/usr/bin/pl -q -t main -f

eval :-
        current_prolog_flag(argv, Argv),
        append(_, [--|Args], Argv),
        concat_atom(Args, ' ', SingleArg),
        term_to_atom(Term, SingleArg),
        Val is Term,
        format('~w~n', [Val]).

main :-
        catch(eval, E, (print_message(error, E), fail)),
        halt.
main :-
        halt(1).

And here are two example runs:

% eval 1+2
3
% eval foo
ERROR: Arithmetic: `foo/0' is not a function
%

TThhee  WWiinnddoowwss  vveerrssiioonn supports  the  #!  construct  too,   but  here  it
serves  a rather  different role.    The  Windows shell  already  allows
the  user to  start  Prolog source-files  directly through  the  Windows
file-type  association.   Windows  however makes  it rather  complicated
to  provide  additional parameters,  such  as  the  required  stack-size
for  an  individual Prolog  file.     The #!  line  provides  for  this,
providing a  more flexible approach then  changing the global  defaults.
The  following starts  Prolog  with unlimited  stack-size on  the  given
source-file:

#!/usr/bin/pl -L0 -T0 -G0 -s

....

Note the  use of  /usr/bin/pl, which  specifies the interpreter.    This
argument is ignored in the Windows version, but  required to ensure best
cross-platform compatibility.


22..1100..22..22 CCrreeaattiinngg aa sshheellll--ssccrriipptt

With  the introduction  of _P_r_o_l_o_g_S_c_r_i_p_t  (see section  2.10.2.1),  using
shell-scripts  as explained  in this  section has  become redundant  for
most applications.

Especially  on  Unix systems  and  not-too-large  applications,  writing
a  shell-script  that  simply  loads  your  application  and  calls  the
entry-point is often a good choice.  A skeleton for  the script is given
below, followed by the Prolog code to obtain the program arguments.

#!/bin/sh

base=<absolute-path-to-source>
PL=pl

exec $PL -f none -g "load_files(['$base/load'],[silent(true)])" \
         -t go -- $*

go :-
        current_prolog_flag(argv, Arguments),
        append(_SytemArgs, [--|Args], Arguments), !,
        go(Args).

go(Args) :-
        ...

On Windows  systems, similar  behaviour can  be achieved  by creating  a
shortcut to Prolog, passing the proper options or writing a .bat file.


22..1100..22..33 CCrreeaattiinngg aa ssaavveedd--ssttaattee

For  larger programs,  as  well as  for programs  that are  required  to
run  on systems  that  do not  have  the SWI-Prolog  development  system
installed, creating a saved  state is the best solution.  A  saved state
is created  using qsave_program/[1,2] or  using the linker  plld(1).   A
saved state is  a file containing machine-independent intermediate  code
in  a format  dedicated for  fast  loading.   Optionally,  the  emulator
may  be integrated  in  the saved  state,  creating a  single-file,  but
machine-dependent, executable.  This process is described in chapter 8.


22..1100..22..44 CCoommppiillaattiioonn uussiinngg tthhee --cc ccoommmmaannddlliinnee ooppttiioonn

This mechanism loads a series of Prolog source files  and then creates a
saved-state as qsave_program/2 does.  The command syntax is:

% pl [option ...] [-o output] -c file ...

The  _o_p_t_i_o_n_s argument  are  options to  qsave_program/2 written  in  the
format below.    The option-names  and their values  are described  with
qsave_program/2.

    --_o_p_t_i_o_n_-_n_a_m_e=_o_p_t_i_o_n_-_v_a_l_u_e

For  example,  to  create  a  stand-alone   executable  that  starts  by
executing main/0  and for which  the source  is loaded through  load.pl,
use the command

% pl --goal=main --stand_alone=true -o myprog -c load.pl

This performs exactly the same as executing

% pl
<banner>
?- [load].
?- qsave_program(myprog,
                 [ goal(main),
                   stand_alone(true)
                 ]).
?- halt.


22..1111 EEnnvviirroonnmmeenntt CCoonnttrrooll ((PPrroolloogg ffllaaggss))

The  predicates  current_prolog_flag/2 and  set_prolog_flag/2 allow  the
user  to examine  and modify  the execution  environment.   It  provides
access  to whether  optional  features are  available on  this  version,
operating  system,  foreign-code  environment,  command-line  arguments,
version,  as well  as runtime  flags to  control  the runtime  behaviour
of  certain  predicates  to  achieve  compatibility  with  other  Prolog
environments.


ccuurrrreenntt__pprroolloogg__ffllaagg((_?_K_e_y_, _-_V_a_l_u_e))
    The   predicate  current_prolog_flag/2  defines   an  interface   to
    installation   features:    options  compiled  in,  version,   home,
    etc.    With both arguments  unbound, it  will generate all  defined
    prolog-flags.    With  the  `Key' instantiated  it unify  the  value
    of  the  prolog-flag.    Features  come  in three  types:    boolean
    prolog-flags,  prolog-flags  with  an  atom value  and  prolog-flags
    with  an integer  value.    A boolean  prolog-flag is  true iff  the
    prolog-flag  is present aanndd the _V_a_l_u_e  is the atom true.   Currently
    defined keys in alphabetical order:

    aabboorrtt__wwiitthh__eexxcceeppttiioonn _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         Determines how  abort/0 is realised.    See the description  of
         abort/0 for details.

    aaggcc__mmaarrggiinn _(_i_n_t_e_g_e_r_, _c_h_a_n_g_e_a_b_l_e_)
         If  this amount  of  atoms  has  been created  since  the  last
         atom-garbage collection,  perform  atom garbage  collection  at
         the  first  opportunity.    Initial  value  is  10,000.     May
         be  changed.    A  value  of 0  (zero)  disables  atom  garbage
         collection.  See also PL_register_atom().

    aallllooww__vvaarriiaabbllee__nnaammee__aass__ffuunnccttoorr _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If true  (default  is false),  Functor(arg) is  read  as if  it
         was written 'Functor'(arg).   Some applications use the  Prolog
         read/1  predicate for  reading  an application  defined  script
         language.   In these  cases, it is  often difficult to  explain
         to  non-Prolog users  of  the  application that  constants  and
         functions can only  start with a  lowercase letter.   Variables
         can be  turned into atoms  starting with  an uppercase atom  by
         calling read_term/2 using the option variable_names and binding
         the variables to their name.   Using this feature, F(x)  can be
         turned into valid syntax for such script languages.   Suggested
         by Robert van Engelen.  SWI-Prolog specific.

    aarrggvv _(_l_i_s_t_)
         List  is  a   list  of  atoms  representing  the   command-line
         arguments used  to invoke  SWI-Prolog.   Please  note that  aallll
         arguments are included in the list returned.

    aarrcchh _(_a_t_o_m_)
         Identifier for  the  hardware and  operating system  SWI-Prolog
         is running  on.   Used to  select foreign files  for the  right
         architecture.  See also section 7.4 and file_search_path/2.

    aassssoocciiaattee _(_a_t_o_m_, _c_h_a_n_g_e_a_b_l_e_)
         On  Windows systems,  this  is  set to  the  filename-extension
         (e.g. pl or pro associated with plwin.exe.

    aauuttoollooaadd _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If true (default) autoloading of library functions  is enabled.
         See section 2.13.

    bbaacckkqquuootteedd__ssttrriinngg _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If  true   (default  false),   read  translates  text   between
         backquotes into a string object (see section 4.23).   This flag
         is mainly for compatibility to LPA Prolog.

    bboouunnddeedd _(_t_r_u_e_)
         ISO prolog-flag describing  integer representation is bound  by
         min_integer and min_integer.

    cc__cccc _(_a_t_o_m_)
         Name of the  C-compiler used to  compile SWI-Prolog.   Normally
         either gcc or cc.  See section 7.7.

    cc__llddffllaaggss _(_a_t_o_m_)
         Special  linker  flags  passed   to  link  SWI-Prolog.      See
         section 7.7.

    cc__lliibbss _(_a_t_o_m_)
         Libraries passed  to the C-linker  when SWI-Prolog was  linked.
         May  be  used to  determine  the  libraries  needed  to  create
         statically linked extensions for SWI-Prolog.  See section 7.7.

    cchhaarr__ccoonnvveerrssiioonn _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         Determines  whether  character-conversion  takes   place  while
         reading terms.  See also char_conversion/2.

    cchhaarraacctteerr__eessccaappeess _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If true  (default),  read/1 interprets  \  escape sequences  in
         quoted atoms and strings.  May be changed.   This flag is local
         to the module in which it is changed.

    ccoommppiilleedd__aatt _(_a_t_o_m_)
         Describes when the  system has been  compiled.  Only  available
         if  the C-compiler  used  to  compile SWI-Prolog  provides  the
         __DATE__and __TIME__macros.

    ccoonnssoollee__mmeennuu _(_b_o_o_l_)
         Set  to true  in plwin.exe  to  indicate the  console  supports
         menus.  See also section 4.35.2.

    ddddee _(_b_o_o_l_)
         Set  to  true  if this  instance  of  Prolog  supports  DDE  as
         described in section 4.43.

    ddeebbuugg _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         Switch debugging  mode  on/off.   If  debug  mode is  activated
         the  system  traps  encountered  spy-points  (see   spy/1)  and
         trace-points  (see  trace/1).     In  addition,  tail-recursion
         optimisation is  disabled and the  system is more  conservative
         in destroying choice-points to simplify debugging.

         Disabling these optimisations can  cause the system to run  out
         of memory on  programs that behave  correctly if debug mode  is
         off.

    ddeebbuugg__oonn__eerrrroorr _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If  true,  start  the  tracer  after   an  error  is  detected.
         Otherwise just continue  execution.   The goal that raised  the
         error  will normally  fail.    See  also fileerrors/2  and  the
         prolog-flag report_error.   May be changed.   Default is  true,
         except for the runtime version.

    ddeebbuuggggeerr__pprriinntt__ooppttiioonnss _(_t_e_r_m_, _c_h_a_n_g_e_a_b_l_e_)
         This  argument is  given  as  option-list to  write_term/2  for
         printing  goals  by  the  debugger.     Modified  by  the  `w',
         `p'  and  `<_N>  d'  commands  of  the  debugger.    Default  is
         [quoted(true), portray(true), max_depth(10)].

    ddeebbuuggggeerr__sshhooww__ccoonntteexxtt _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If true, show  the context module while printing a  stack-frame
         in the  tracer.   Normally controlled using  the `C' option  of
         the tracer.

    ddoouubbllee__qquuootteess _(_c_o_d_e_s_,_c_h_a_r_s_,_a_t_o_m_,_s_t_r_i_n_g_, _c_h_a_n_g_e_a_b_l_e_)
         This flag  determines  how double-quotes  strings are  read  by
         Prolog and is ---like  character_escapes--- maintained for  each
         module.    If codes  (default), a  list  of character-codes  is
         returned,  if chars  a list  of  one-character atoms,  if  atom
         double  quotes  are the  same  as  single-quotes  and  finally,
         string reads the text into a Prolog string  (see section 4.23).
         See also atom_chars/2 and atom_codes/2.

    ddyynnaammiicc__ssttaacckkss _(_b_o_o_l_)
         If true,  the system uses some  form of `sparse-memory  manage-
         ment' to realise the stacks.  If  false, malloc()/realloc() are
         used for  the stacks.   In earlier  days this had  consequenses
         for foreign code.   As  of version 2.5,  this is no longer  the
         case.

         Systems using  `sparse-memory management' are  a bit faster  as
         there is no  stack-shifter, and checking the stack-boundary  is
         often realised  by the hardware  using a  `guard-page'.   Also,
         memory  is actually  returned to  the  system after  a  garbage
         collection or call  to trim_stacks/0 (called by prolog/0  after
         finishing a user-query).

    eeddiittoorr _(_a_t_o_m_, _c_h_a_n_g_e_a_b_l_e_)
         Determines the  editor used  by edit/1.   See  section 4.4  for
         details on selecting the editor used.

    eemmaaccss__iinnffeerriioorr__pprroocceessss _(_b_o_o_l_)
         If  true,  SWI-Prolog is  running  as an  _i_n_f_e_r_i_o_r  _p_r_o_c_e_s_s  of
         (GNU/X-)Emacs.   SWI-Prolog  assumes this  is the  case if  the
         environment variable EMACS is t and INFERIOR is yes.

    eexxeeccuuttaabbllee _(_a_t_o_m_)
         Path-name of the  running executable.  Used  by qsave_program/2
         as default emulator.

    ffiillee__nnaammee__vvaarriiaabblleess _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If   true  (default   false),   expand   $varname  and   ~   in
         arguments  of  builtin-predicates  that  accept  a   file  name
         (open/3, exists_file/1,  access_file/2,  etc.).   The  predicate
         expand_file_name/2  should  be  used   to  expand   environment
         variables and wildcard patterns.  This  prolog-flag is intended
         for backward compatibility with older versions of SWI-Prolog.

    ffllooaatt__ffoorrmmaatt _(_a_t_o_m_, _c_h_a_n_g_e_a_b_l_e_)
         C-library printf()  format  specification used  by write/1  and
         friends to  determine how floating  point numbers are  printed.
         The default is %g.   The specified value is passed  to printf()
         without  further checking.    For  example,  if you  want  more
         digits printed,  %.12g will  print all floats  using 12  digits
         instead of the default 6.

         When using  quoted-write, the output  is guaranteed to  contain
         a decimal  dot or exponent,  so read/1  reads a floating  point
         number.  See also format/[1,2], write_term/[2,3].

    ggcc _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If true (default), the garbage collector is active.   If false,
         neither garbage-collection,  nor stack-shifts will take  place,
         even not on explicit request.  May be changed.

    gguuii _(_b_o_o_l_)
         Set to true if XPCE is around and can be used for graphics.

    hhiissttoorryy _(_i_n_t_e_g_e_r_, _c_h_a_n_g_e_a_b_l_e_)
         If _i_n_t_e_g_e_r >0,  support Unix csh(1)  like history as described
         in section  2.7.    Otherwise,  only support  reusing  commands
         through the  commandline editor.   The default  is to set  this
         prolog-flag  to 0  if a  commandline  editor is  provided  (see
         prolog-flag readline) and 15 otherwise.

    hhoommee _(_a_t_o_m_)
         SWI-Prolog's  notion  of   the  home-directory.      SWI-Prolog
         uses  it's  home  directory   to  find  its  startup  file   as
         <_h_o_m_e>/boot32.prc(32-bit machines) or <_h_o_m_e>/boot64.prc (64-bit
         machines) and to find its library as <_h_o_m_e>/library.

    hhwwnndd _(_i_n_t_e_g_e_r_)
         In plwin.exe,  this refers to  the MS-Windows window-handle  of
         the console window.

    iinntteeggeerr__rroouunnddiinngg__ffuunnccttiioonn _(_d_o_w_n_,_t_o_w_a_r_d___z_e_r_o_)
         ISO prolog-flag  describing rounding by  // and rem  arithmetic
         functions.  Value depends on the C-compiler used.

    iissoo _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         Include some  weird ISO compatibility  that is incompatible  to
         normal SWI-Prolog behaviour.   Currently  it has the  following
         effect:

           o is/2  and  evaluation  under flag/3  do  not  automatically
             convert  floats  to integers  if  the float  represents  an
             integer.

           o The  //2 (float division)  _a_l_w_a_y_s return a  float, even  if
             applied to integers that can be divided.

           o In  the standard order  of terms (see  section 4.6.1),  all
             floats are before all integers.

           o atom_length/2 yields  an instantiation  error if the  first
             argument is a number.

           o clause/[2,3]  raises  a  permission  error  when  accessing
             static predicates.

           o abolish/[1,2]  raises  a permission  error  when  accessing
             static predicates.

    mmaaxx__aarriittyy _(_u_n_b_o_u_n_d_e_d_)
         ISO  prolog-flag  describing  there  is  no  maximum  arity  to
         compound terms.

    mmaaxx__iinntteeggeerr _(_i_n_t_e_g_e_r_)
         Maximum  integer  value.     Most  arithmetic  operations  will
         automatically convert  to floats if  integer values above  this
         are returned.

    mmaaxx__ttaaggggeedd__iinntteeggeerr _(_i_n_t_e_g_e_r_)
         Maximum integer value represented as a `tagged' value.   Tagged
         integers require  4-bytes storage  and are  used for  indexing.
         Larger integers are represented as `indirect data'  and require
         16-bytes  on  the  stacks  (though  a  copy   requires  only  4
         additional bytes).

    mmiinn__iinntteeggeerr _(_i_n_t_e_g_e_r_)
         Minimum integer value.

    mmiinn__ttaaggggeedd__iinntteeggeerr _(_i_n_t_e_g_e_r_)
         Start of the tagged-integer value range.

    ooppeenn__sshhaarreedd__oobbjjeecctt _(_b_o_o_l_)
         If  true,  open_shared_object/2 and  friends  are  implemented,
         providing access  to shared  libraries (.so  files) or  dynamic
         link libraries (.DLL files).

    ooppttiimmiissee _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If true, compile in optimised mode.  The initial  value is true
         if Prolog was started with the -O commandline option.

         Currently   optimise   compilation   implies   compilation   of
         arithmetic, and  deletion of redundant  true/0 that may  result
         from expand_goal/2.

         Later versions might imply various other 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).

    ppiidd _(_i_n_t_)
         Process identifier of  the running Prolog  process.   Existence
         of this flag is implementation dependent.

    ppiippee _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If  true,  open(pipe(command), mode, Stream),   etc.  are  sup-
         ported.    Can  be  changed to  disable  the use  of  pipes  in
         applications testing this feature.  Not recommended.

    llaarrggee__ffiilleess _(_b_o_o_l_)
         If true, SWI-Prolog  has been compiled with _l_a_r_g_e _f_i_l_e  _s_u_p_p_o_r_t
         (LFS) and is capable to access files larger than  2GB on 32-bit
         hardware.    Large  file-support  is default  on  installations
         built using configure that  support it and may be  switched off
         using the configure option --disable-largefile.

    rreeaaddlliinnee _(_b_o_o_l_)
         If  true,  SWI-Prolog  is linked  with  the  readline  library.
         This is  done by  default if  you have  this library  installed
         on your  system.    It is  also true  for  the Win32  plwin.exe
         version of SWI-Prolog, which realises a subset  of the readline
         functionality.

    rreessoouurrccee__ddaattaabbaassee _(_a_t_o_m_)
         Set to the absolute-filename of the attached state.   Typically
         this is the file boot32.prc, the file specified with  -x or the
         running executable.  See also resource/3.

    rreeppoorrtt__eerrrroorr _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If true, print  error messages, otherwise  suppress them.   May
         be changed.  See also  the debug_on_error prolog-flag.   Default
         is true, except for the runtime version.

    rruunnttiimmee _(_b_o_o_l_)
         If true,  SWI-Prolog  is compiled  with  -DO_RUNTIME,  disabling
         various useful development  features (currently the tracer  and
         profiler).

    ssaavveedd__pprrooggrraamm _(_b_o_o_l_)
         If  true,   Prolog  is   started  from   a  state  saved   with
         qsave_program/[1,2].

    sshhaarreedd__oobbjjeecctt__eexxtteennssiioonn _(_a_t_o_m_)
         Extension used  by  the operating  system for  shared  objects.
         .so for  most Unix  systems and  .dll for  Windows.   Used  for
         locating  files using  the  file_type  executable.    See  also
         absolute_file_name/3.

    ssiiggnnaallss _(_b_o_o_l_)
         Determine  whether   Prolog  is   handling  signals   (software
         interrupts).   This flag is  false if the  hosting OS does  not
         support signal handling  or the command-line option  -nosignals
         is active.  See section 7.6.18.1 for details.

    ssyysstteemm__tthhrreeaadd__iidd _(_i_n_t_)
         On MT systems (section 6, refers to  the thread-identifier used
         by the system for the calling thread.  See also thread_self/1.

    ttaaiill__rreeccuurrssiioonn__ooppttiimmiissaattiioonn _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         Determines  whether  or  not  tail-recursion   optimisation  is
         enabled.     Normally the  value  of  this  flag  is  equal  to
         the  debug  flag.      As  programs   may  run  out  of   stack
         if  tail-recursion optimisation  is  omitted, it  is  sometimes
         necessary to enable it during debugging.

    ttoopplleevveell__pprriinntt__aannoonn _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If true, toplevel variables starting with an underscore (_) are
         printed normally.  If false they are hidden.   This may be used
         to hide bindings in complex queries from the toplevel.

    ttoopplleevveell__pprriinntt__ooppttiioonnss _(_t_e_r_m_, _c_h_a_n_g_e_a_b_l_e_)
         This  argument   is  given   as  option-list   to  write_term/2
         for   printing    results   of   queries.         Default    is
         [quoted(true), portray(true), max_depth(10)].

    ttoopplleevveell__vvaarr__ssiizzee _(_i_n_t_, _c_h_a_n_g_e_a_b_l_e_)
         Maximum  size counted  in  literals of  a  term returned  as  a
         binding for a  variable in a toplevel  query that is saved  for
         re-use using the $ variable reference.  See section 2.8.

    ttrraaccee__ggcc _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If  true  (false  is  the  default),  garbage  collections  and
         stack-shifts  will  be  reported on  the  terminal.     May  be
         changed.

    ttttyy__ccoonnttrrooll _(_b_o_o_l_)
         Determines whether  the terminal  is switched to  raw mode  for
         get_single_char/1,  which also  reads the  user-actions for  the
         trace.  May be set.  See also the +/-tty command-line option.

    uunniixx _(_b_o_o_l_)
         If  true,  the  operating  system  is  some  version  of  Unix.
         Defined  if the  C-compiler used  to  compile this  version  of
         SWI-Prolog either defines __unix__ or unix.

    uunnkknnoowwnn _(_f_a_i_l_,_w_a_r_n_i_n_g_,_e_r_r_o_r_, _c_h_a_n_g_e_a_b_l_e_)
         Determines  the   behaviour  if  an   undefined  procedure   is
         encountered.   If  fail,  the predicates  fails silently.    If
         warn,  a warning  is printed,  and  execution continues  as  if
         the  predicate was  not  defined  and if  error  (default),  an
         existence_error exception is  raised.   This flag  is local  to
         each module.

    vveerrbboossee _(_A_t_o_m_, _c_h_a_n_g_e_a_b_l_e_)
         This flags is used by print_message/2.  If its value is silent,
         messages of type informational  and banner are supressed.   The
         -q switches the value from the initial normal to silent.

    vveerrbboossee__aauuttoollooaadd _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If  true 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.

    vveerrbboossee__ffiillee__sseeaarrcchh _(_b_o_o_l_, _c_h_a_n_g_e_a_b_l_e_)
         If  true  (default   false),  print  messages  indicating   the
         progress   of  absolute_file_name/[2,3]  in   locating   files.
         Intended for  debugging  complicated file-search  paths.    See
         also file_search_path/2.

    vveerrssiioonn _(_i_n_t_e_g_e_r_)
         The version identifier is an integer with value:

                          10000_*Major+ 100_*Minor+_P_a_t_c_h

         Note that  in releases  up to 2.7.10  this prolog-flag  yielded
         an  atom   holding  the  three   numbers  separated  by   dots.
         The  current representation  is  much easier  for  implementing
         version-conditional statements.

    wwiinnddoowwss _(_b_o_o_l_)
         If  true,   the  operating  system  is  an  implementation   of
         Microsoft Windows (3.1, 95/98/ME, NT/2000/XP, etc.).

    wwrriittee__hheellpp__wwiitthh__oovveerrssttrriikkee _(_b_o_o_l_)
         Internal flag used  by help/1 when writing  to a terminal.   If
         true it prints bold and underlined text using _o_v_e_r_s_t_r_i_k_e.

    xxppccee _(_b_o_o_l_)
         Set to true if the XPCE graphics system is loaded.

    xxppccee__vveerrssiioonn _(_a_t_o_m_)
         Set to the version of the loaded XPCE system.


sseett__pprroolloogg__ffllaagg((_+_K_e_y_, _+_V_a_l_u_e))
    Define  a new prolog-flag or change its value.  _K_e_y is an atom.   If
    the  flag is  a system-defined  flag that is  not marked  _c_h_a_n_g_e_a_b_l_e
    above,  an  attempt to  modify the flag  yields a  permission_error.
    If  the  provided _V_a_l_u_e  does not  match  the type  of the  flag,  a
    type_error is raised.

    In  addition  to  ISO,  SWI-Prolog allows  for  user-defined  prolog
    flags.   The type of the  flag is determined from the  initial value
    and cannot be changed afterwards.


22..1122 AAnn oovveerrvviieeww ooff hhooookk pprreeddiiccaatteess

SWI-Prolog provides a large number of hooks, mainly  to control handling
messages, debugging,  startup, shut-down, macro-expansion,  etc.   Below
is  a  summary  of  all  defined  hooks  with  an  indication  of  their
portability.

  o portray/1
    Hook into write_term/3 to alter the way terms are printed (ISO).

  o message_hook/3
    Hook  into  print_message/2 to  alter the  way system  messages  are
    printed (Quintus/SICStus).

  o library_directory/1
    Hook  into absolute_file_name/3 to define  new library  directories.
    (most Prolog system).

  o file_search_path/2
    Hook   into   absolute_file_name/3  to   define   new   search-paths
    (Quintus/SICStus).

  o term_expansion/2
    Hook  into  load_files/1  to  modify  read  terms  before  they  are
    compiled (macro-processing) (most Prolog system).

  o goal_expansion/2
    Same as term_expansion/2 for individual goals (SICStus).

  o prolog_load_file/2
    Hook  into  load_files/2  to  load  other  data-formats  for  Prolog
    sources  from `non-file' resources.   The load_files/2 predicate  is
    the ancestor of consult/1, use_module/1, etc.

  o prolog_edit:locate/3
    Hook into edit/1 to locate objects (SWI).

  o prolog_edit:edit_source/1
    Hook into edit/1 to call some internal editor (SWI).

  o prolog_edit:edit_command/2
    Hook into edit/1 to define the external editor to use (SWI).

  o prolog_list_goal/1
    Hook  into the tracer  to list the  code associated to a  particular
    goal (SWI).

  o prolog_trace_interception/4
    Hook into the tracer to handle trace-events (SWI).

  o prolog:debug_control_hook/1
    Hook  in spy/1, nospy/1, nospyall/0 and debugging/0 to  extend these
    control-predicates to higher-level libraries.

  o prolog:help_hook/1
    Hook in help/0, help/1 and apropos/1 to extend the help-system.

  o resource/3
    Defines a new resource (not really a hook, but similar) (SWI).

  o exception/3
    Old  attempt  to  a  generic  hook mechanism.     Handles  undefined
    predicates (SWI).


22..1133 AAuuttoommaattiicc llooaaddiinngg ooff lliibbrraarriieess

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  _a_u_t_o _l_o_a_d_e_r  is activated.    On  first  activation
an  index to  all library  files in  all library  directories is  loaded
in  core  (see  library_directory/1 and  file_search_path/2).     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 restarted.  By default this  mechanism loads the
file silently.   The  current_prolog_flag/2verbose_autoload is  provided
to  get verbose  loading.    The prolog-flag  autoload  can be  used  to
enable/disable the entire auto load system.

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

Autoloading  only handles  (library) source  files that  use the  module
mechanism  described  in  chapter  5.     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.pl  that 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  updates the  autoload  index.   It  searches  for
all library directories (see library_directory/1 and file_search_path/2)
holding the file MKINDEX.pl or INDEX.pl.  If the  current user can write
or create  the file  INDEX.pl and  it does not  exist or  is older  than
the directory  or one  of its  files, the  index for  this directory  is
updated.  If the file MKINDEX.pl exists updating  is achieved by loading
this file, normally containing a directive calling make_library_index/2.
Otherwise make_library_index/1is  called, creating an index for all *.pl
files containing a module.

Below is an example creating a completely indexed library directory.

% mkdir ~/lib/prolog
% cd !$
% pl -g true -t 'make_library_index(.)'

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

 1. If  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.


mmaakkee__lliibbrraarryy__iinnddeexx((_+_D_i_r_e_c_t_o_r_y))
    Create  an index for this  directory.  The  index is written to  the
    file  'INDEX.pl' in the specified directory.   Fails with a  warning
    if the directory does not exist or is write protected.


mmaakkee__lliibbrraarryy__iinnddeexx((_+_D_i_r_e_c_t_o_r_y_, _+_L_i_s_t_O_f_P_a_t_t_e_r_n_s))
    Normally  used in  MKINDEX.pl, this  predicate creates INDEX.pl  for
    _D_i_r_e_c_t_o_r_y,  indexing all files that  match one of the  file-patterns
    in _L_i_s_t_O_f_P_a_t_t_e_r_n_s.

    Sometimes  library packages consist  of one public  load file and  a
    number  of files used by  this load-file, exporting predicates  that
    should not be used  directly by the end-user.  Such a library can be
    placed  in a sub-directory of  the library and the files  containing
    public  functionality can  be  added to  the index  of the  library.
    As  an  example we  give the  XPCE library's  MKINDEX.pl,  including
    the  public  functionality of  trace/browse.pl to  the  autoloadable
    predicates for the XPCE package.

    :- make_library_index('.',
                          [ '*.pl',
                            'trace/browse.pl'
                          ]).


rreellooaadd__lliibbrraarryy__iinnddeexx
    Force  reloading  the  index  after modifying  the  set  of  library
    directories   by   changing  the   rules  for   library_directory/2,
    file_search_path/2,  adding  or  deleting  INDEX.pl  files.     This
    predicate   does   _n_o_t   update  the   INDEX.pl   files.       Check
    make_library_index/[1,2] and make/0 for updating the index files.

    Normally, the index  is reloaded automatically if a predicate cannot
    be  found  in the  index  and the  set  of library  directories  has
    changed.   Using reload_library_index/0 is necessary if  directories
    are removed or the order of the library directories is changed.


22..1144 GGaarrbbaaggee CCoolllleeccttiioonn

SWI-Prolog provides garbage-collection, last-call optimization  and atom
garbage collection.   These features  are controlled using prolog  flags
(see current_prolog_flag/2).


22..1155 SSyynnttaaxx NNootteess

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:

  o 0'<_c_h_a_r>
    This  construct is not accepted by all Prolog systems that  claim to
    have  Edinburgh compatible syntax.  It describes the  character code
    of <_c_h_a_r>.   To test whether C is a lower case character one can use
    between(0'a, 0'z, C).

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

22..1155..11 IISSOO SSyynnttaaxx SSuuppppoorrtt

SWI-Prolog offers ISO compatible extensions to the Edinburgh syntax.


22..1155..11..11 CChhaarraacctteerr EEssccaappee SSyynnttaaxx

Within quoted  atoms (using single quotes:   '<_a_t_o_m>'special  characters
are represented  using escape-sequences.    An escape  sequence is  lead
in  by the  backslash  (\) character.    The  list of  escape  sequences
is compatible  with the  ISO standard,  but contains  one extension  and
the interpretation of numerically specified characters  is slightly more
flexible to improve compatibility.

\a
    Alert character.  Normally the ASCII character 7 (beep).

\b
    Backspace character.

\c
    No  output.    All input  characters  up to  but not  including  the
    first  non-layout  character  are skipped.     This allows  for  the
    specification of pretty-looking  long lines.  For compatibility with
    Quintus Prolog.  Not supported by ISO. Example:

    format('This is a long line that would look better if it was \c
           split across multiple physical lines in the input')

\<RETURN>
    No  output.   Skips input till the  next non-layout character or  to
    the end of the next line.  Same intention as \c but ISO compatible.

\f
    Form-feed character.

\n
    Next-line character.

\r
    Carriage-return only (i.e. go back to the start of the line).

\t
    Horizontal tab-character.

\v
    Vertical tab-character (ASCII 11).

\x23
    Hexadecimal  specification of a character.   23 is just an  example.
    The  `x'  may be  followed by  a maximum  of  2 hexadecimal  digits.
    The  closing \  is optional.   The  code \xa\3  emits the  character
    10  (hexadecimal `a')  followed by  `3'.   The code  \x201 emits  32
    (hexadecimal  `20') followed by `1'.  According to ISO,  the closing
    \  is  obligatory and  the  number  of digits  is  unlimited.    The
    SWI-Prolog  definition allows for ISO compatible specification,  but
    is compatible with other implementations.

\40
    Octal   character  specification.     The  rules  and   remarks  for
    hexadecimal  specifications apply to  octal specifications too,  but
    the maximum allowed number of octal digits is 3.

\<_c_h_a_r_a_c_t_e_r>
    Any  character immediately preceded  by a \  and not covered by  the
    above  escape sequences is copied verbatim.   Thus, '\\' is  an atom
    consisting  of a single \ and  '\'' and '''' both describe the  atom
    with a single '.

Character      escaping      is     only      available      if      the
current_prolog_flag(character_escapes, true) is active (default).    See
current_prolog_flag/2.   Character escapes conflict with writef/2  in two
ways:   \40  is interpreted  as decimal  40 by  writef/2, but  character
escapes  handling by  read has  already interpreted  as  32 (40  octal).
Also, \l is translated to  a single `l'.  It is advised to use  the more
widely supported  format/[2,3] predicate instead.    If you insist  upon
using writef/2, either switch character_escapes to false, or  use double
\\, as in writef('\\l').


22..1155..11..22 SSyynnttaaxx ffoorr nnoonn--ddeecciimmaall nnuummbbeerrss

SWI-Prolog  implements  both  Edinburgh  and  ISO   representations  for
non-decimal numbers.   According to  Edinburgh syntax, such numbers  are
written as <_r_a_d_i_x>'<_n_u_m_b_e_r>, where <_r_a_d_i_x> is  a number between 2 and 36.
ISO defines binary,  octal and hexadecimal numbers using 0[bxo]<_n_u_m_b_e_r>.
For example:  A is 0b100 \/ 0xf00  is a valid expression.   Such numbers
are always unsigned.


22..1166 SSyysstteemm lliimmiittss


22..1166..11 LLiimmiittss oonn mmeemmoorryy aarreeaass

SWI-Prolog has  a number of  memory areas which are  only enlarged to  a
certain limit.   The  default sizes for these  areas should suffice  for
most applications, but big  applications may require larger ones.   They
are 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.  The option character is immediately followed  by a number and
optionally by  a k or  m.   With k or  no unit  indicator, the value  is
interpreted in Kbytes (1024 bytes), with m, the  value is interpreted in
Mbytes (10241* 024 bytes).

The local-,  global- and  trail-stack are  limited to 128  Mbytes on  32
bit processors,  or more  generally to  2 to the power bits-per-long - 5
bytes.

The  PrologScript facility  described  in  section 2.10.2.1  provides  a
mechanism for  specifying options with  the load-file.   On Windows  the
default stack-sizes  are controlled  using the Windows  registry on  the
key  HKEY_CURRENT_USER\Software\SWI\Prolog using  the  names  localSize,
globalSize and trailSize.   The value is a DWORD expressing  the default
stack size  in Kbytes.   A  GUI for modifying  these values is  provided
using the XPCE package.  To use this, start the  XPCE manual tools using
manpce/0, after which you find _P_r_e_f_e_r_e_n_c_e_s in the _F_i_l_e menu.
       ___________________________________________________________
       |_Option_|Default_|Area_name______|Description____________|_||-L||2Mllooccaa||llTssttaacckkhe|l||||ocal|stack is used

       |        |                        to  store   the  execu- |             |            ||
       |        |                        tion  environments   of |             |            ||
       |        |                        procedure  invocations. |             |            ||
       |        |                        The  space for  an  en- |             |            ||
       |        |                        vironment is  reclaimed |             |            ||
       |        |                        when  it  fails,  exits |             |            ||
       |        |                        without leaving  choice |             |            ||
       |        |                        points,   the  alterna- |             |            ||
       |        |                        tives are  cut of  with |             |            ||
       |        |                                                |             |            ||

       |        |                        the  !/0  predicate  or |             |            ||
       |        |                        no  choice points  have |             |            ||
       |        |                        been created  since the |             |            ||
       |        |                        invocation and the last |             |            ||
       |        |                        subclause  is   started |             |            ||
       |        |                        (tail recursion optimi- |             |            ||
       ||       ||      |               ||sation).                ||            |            ||

       |   -G   | 4M    |gglloobbaall ssttaacckk   ||Theusglobaled stacktois store| terms
       |        |       |               ||created during Prolog's |
       |        |       |               ||execution.    Terms  on |
       |        |       |               ||                        |
       |        |       |               ||this stack will  be re- |
       |        |       |               ||claimed by backtracking |
       |        |       |               ||to a  point before  the |
       |        |       |               ||term  was   created  or |
       |        |       |               ||by  garbage  collection |

       |        |       |               ||(provided  the term  is |
       ||       ||      ||              ||no||longer referenced).  ||
       |   -T   | 4M    |ttrraaiill ssttaacckk    ||Theusetraild stackto isstore|  as-
       |        |       |               ||signments during execu- |
       |        |       |               ||                        |
       |        |       |               ||tion.   Entries on this |
       |        |       |               ||stack remain  alive un- |

       |        |       |               ||til backtracking before |
       |        |       |               ||the  point of  creation |
       |        |       |               ||or the  garbage collec- |
       |        |       |               ||tor determines they are |
       ||       ||      ||              ||nor||needed any longer.  ||

       |   -A   | 1M    |aarrgguummeenntt ssttaacckk ||Theusargumentestackd isto|  store   one
       |        |       |               ||of   the   intermediate |
       |        |       |               ||code interpreter's reg- |
       |        |       |               ||isters.     The  amount |
       |        |       |               ||of space needed on this |
       |        |       |               ||stack is determined en- |
       |        |       |               ||                        |
       |        |       |               ||tirely 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.2:  Memory areas


22..1166..11..11 TThhee hheeaapp

With  the heap,  we  refer  to the  memory  area  used by  malloc()  and
friends.  SWI-Prolog uses the area to store  atoms, functors, predicates
and their  clauses, records and  other dynamic data.   As of  SWI-Prolog
2.8.5, no limits are  imposed on the addresses returned by  malloc() and
friends.

On  some machines,  the  runtime stacks  described above  are  allocated
using `sparse  allocation'.   Virtual space up to  the limit is  claimed
at startup and committed and released while the area  grows and shrinks.
On Win32  platform this  is realised using  VirtualAlloc() and  friends.
On Unix systems this is realised using mmap().


22..1166..22 OOtthheerr LLiimmiittss

CCllaauusseess  The only  limit  on  clauses  is their  arity  (the  number  of
    arguments  to the head),  which is  limited to 1024.   Raising  this
    limit is easy and relatively cheap, removing it is harder.

AAttoommss aanndd SSttrriinnggss  SWI-Prolog  has no  limits  on  the  sizes  of  atoms
    and  strings.   read/1  and its derivatives  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.

    The  number  of  atoms  is  limited  to  16777216  (16M)  on  32-bit
    machines.   On  64-bit machines  this is virtually  unlimited.   See
    also section 7.6.2.1.

AAddddrreessss ssppaaccee  SWI-Prolog  data  is  packed  in  a 32-bit  word,   which
    contains  both type and value information.  The size of  the various
    memory areas is limited  to 128 Mb for each of the areas, except for
    the program heap, which is not limited.

IInntteeggeerrss  Integers are 32-bit (64 on  64-bit machines) to the user,  but
    integers  up to the value of  the max_tagged_integer prolog-flag  are
    represented more efficiently.

FFllooaattss  Floating  point  numbers  are  represented  as  C-native  double
    precision floats, 64 bit IEEE on most machines.


22..1166..33 RReesseerrvveedd NNaammeess

The boot compiler  (see -b option) does  not support the module  system.
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 [Pereira, 1986] all predicates,  database
keys, etc. that should  be hidden from the user start with a  dollar ($)
sign (see style_check/1).


CChhaapptteerr 33..  IINNIITTIIAALLIISSIINNGG AANNDD MMAANNAAGGIINNGG AA PPRROOLLOOGG PPRROOJJEECCTT

Prolog text-books  give you  an overview of  the Prolog  language.   The
manual tells  you what predicates  are provided in  the system and  what
they do.  This chapter wants to explain how to run a  project.  There is
no ultimate `right'  way to do this.   Over the years we developed  some
practice in  this area and  SWI-Prolog's commands  are there to  support
this practice.   This chapter  describes the conventions and  supporting
commands.

The first two sections  (section 3.1 and section 3.2 only  require plain
Prolog.    The remainder  discusses the  use of  the built-in  graphical
tools that require the XPCE graphical library installed on your system.


33..11 TThhee pprroojjeecctt ssoouurrccee--ffiilleess

Organisation  of  source-files  depends largely  on  the  size  of  your
project.    If  you  are doing  exercises  for  a Prolog  course  you'll
normally use one  file for each exercise.   If you have a small  project
you'll work work with  one directory holding a couple of files  and some
files to link it  all together.  Even bigger projects will  be organised
in sub-projects each using their own directory.


33..11..11 FFiillee NNaammeess aanndd LLooccaattiioonnss


33..11..11..11 FFiillee NNaammee EExxtteennssiioonnss

The first consideration  is what extension to use for  the source-files.
Tradition  calls for  .pl,  but conflicts  with Perl  force the  use  of
another extension on systems where extensions have  global meaning, such
as MS-Windows.  On such systems .pro is the common alternative.

All versions of SWI-Prolog load files with the extension  .pl as well as
with the registered alternative extension without  explicitly specifying
the  extension.    For  portability  reasons we  propose  the  following
convention:

IIff tthheerree iiss nnoo ccoonnfflliicctt  because  you   do   not   use   a   conflicting
    application  or the system does not force a unique  relation between
    extension and application, use .pl.

WWiitthh aa ccoonnfflliicctt  choose .pro and  use this extension  for the files  you
    want  to load  through your  file-manager.   Use .pl  for all  other
    files for maximal portability.


33..11..11..22 PPrroojjeecctt DDiirreeccttoorriieess

Large projects are generally composed of sub-projects,  each using their
own directory or  directory-structure.  If  nobody else will ever  touch
your  files and  you use  only one  computer there  is  little to  worry
about, but this is rarely the case with a large project.

To  improve  portability,   SWI-Prolog  uses  the  POSIX   notation  for
filenames, which  uses the  forward slash (/)  to separate  directories.
Just before  hitting the file-system  it uses prolog_to_os_filename/2 to
convert the  filename to the conventions  used by the hosting  operating
system.  It  is _s_t_r_o_n_g_l_y advised to write paths using the  /, especially
on systems using the \ for this purpose (MS-Windows).   Using \ violates
the  portability rules  and requires  you to  _d_o_u_b_l_e the  \  due to  the
Prolog quoted-atom escape rules.

Portable  code should  use  prolog_to_os_filename/2to  convert  computed
paths  into system-paths  when  constructing  commands for  shell/1  and
friends.


33..11..11..33 SSuubb--pprroojjeeccttss uussiinngg sseeaarrcchh--ppaatthhss

Thanks to Quintus, Prolog adapted an extensible  mechanism for searching
files using file_search_path/2.   This mechanism allows for  comfortable
and readable specifications.

Suppose  you  have  extensive  library  packages   on  graph-algorithms,
set-operations  and  ui-primitives.     These  sub-projects  are  likely
candidates for re-use in future projects.  A good choice  is to create a
directory with sub-directories for each of these sub-projects.

Next,  there are  three options.    One is  to add  the sub-projects  to
the  directory-hierarchy of  the current  project.   Another  is to  use
a completely  dislocated directory  and finally the  sub-project can  be
added to the SWI-Prolog hierarchy.  Using local  installation, a typical
file_search_path/2is:

:- prolog_load_context(directory, Dir),
   asserta(user:file_search_path(myapp, Dir)).

user:file_search_path(graph, myapp(graph)).
user:file_search_path(ui,    myapp(ui)).

For  using sub-projects  in  the  SWI-Prolog hierarchy  one  should  use
the path-alias  swi as  basis.   For a  system-wide installation use  an
absolute-path.

Extensive  sub-projects with  a  small  well-defined API  should  define
a   load-file  using   use_module/1   calls  to   import   the   various
library-components and export the API.


33..11..22 PPrroojjeecctt SSppeecciiaall FFiilleess

There are  a number of  tasks you typically carry  out on your  project,
such as  loading it, creating  a saved-state, debugging it,  etc.   Good
practice  on large  projects is  to  define small  files that  hold  the
commands to execute such a task, name this file after  the task and give
it  a file-extension  that makes  starting easy  (see section  3.1.1.1).
The task _l_o_a_d is generally central to these tasks.   Here is a tentative
list.

  o load.pl
    Use  this file  to set  up the  environment (prolog  flags and  file
    search  paths) and load the sources.  Quite commonly this  file also
    provides  convenient predicates  to parse  command-line options  and
    start the application.

  o run.pl
    Use  this file to start the application.  Normally it  loads load.pl
    in  silent-mode,  and  calls one  of  the starting  predicates  from
    load.pl.

  o save.pl
    Use this file  to create a saved-state of the application by loading
    load.pl and  call qsave_program/2to generate  a saved-state with the
    proper options.

  o debug.pl
    Loads  the program for  debugging.   In addition to loading  load.pl
    this  file defines rules for portray/1 to modify printing  rules for
    complex  terms and customisation rules for the debugger  and editing
    environment.  It may start some of these tools.


33..22 UUssiinngg mmoodduulleess

Modules have  been debated fiercely  in the Prolog world.   Despite  all
counter-arguments we feel they are extremely useful because

  o _T_h_e_y _h_i_d_e _l_o_c_a_l _p_r_e_d_i_c_a_t_e_s
    This  is the  reason they  have been  invented in  the first  place.
    Hiding  provides  two features.    They  allow for  short  predicate
    names  without worrying about conflicts.  Given the  flat name-space
    introduced  by modules, they  still require meaningful module  names
    as well as meaningful names for exported predicates.

  o _T_h_e_y _d_o_c_u_m_e_n_t _t_h_e _i_n_t_e_r_f_a_c_e
    Possibly  more important then avoiding name-conflicts is  their role
    in  documenting  which part  of the  file is  for  public usage  and
    which  is private.   When editing  a module you  may assume you  can
    reorganise  anything  but the  name and  semantics  of the  exported
    predicates without worrying.

  o _T_h_e_y _h_e_l_p _t_h_e _e_d_i_t_o_r
    The  PceEmacs built-in editor  does on-the-fly cross-referencing  of
    the  current module, colouring predicates based on their  origin and
    usage.    Using modules,  the editor  can quickly find  out what  is
    provided  by the imported  modules by reading  just the first  term.
    This  allows it to indicate real-time which predicates are  not used
    or not defined.

Using modules  is generally  easy.   Only if  you write  meta-predicates
(predicates reasoning about  other predicates) that are exported from  a
module good understanding of resolution of terms to  predicates inside a
module is required.  Here is a typical example from readutil.

:- module(read_util,
          [ read_line_to_codes/2,       % +Fd, -Codes
            read_line_to_codes/3,       % +Fd, -Codes, ?Tail
            read_stream_to_codes/2,     % +Fd, -Codes
            read_stream_to_codes/3,     % +Fd, -Codes, ?Tail
            read_file_to_codes/3,       % +File, -Codes, +Options
            read_file_to_terms/3        % +File, -Terms, +Options
          ]).


33..33 TThhee tteesstt--eeddiitt--rreellooaadd ccyyccllee

SWI-Prolog does not enforce  the use of a particular editor  for writing
down  Prolog  source  code.    Editors  are  complicated  programs  that
must  be mastered  in  detail for  real  productive programming  and  if
you  are familiar  with  a specific  editor  you  should not  be  forced
to change.    You may  specify your  favourite editor  using the  prolog
flag editor,  the environment variable EDITOR  or by defining rules  for
prolog_edit:edit_source/1(see section 4.4).

The  use  of  a built-in  editor,  which  is  selected  by  setting  the
prolog-flag  editor to  pce_emacs,  has advantages.    The  XPCE  _e_d_i_t_o_r
object around  which the  built-in PceEmacs  is built can  be opened  as
a Prolog  stream allowing  analysis of  your source by  the real  Prolog
system.


33..33..11 LLooccaattiinngg tthhiinnggss ttoo eeddiitt

The central  predicate for  editing something is  edit/1, an  extensible
front-end that searches for objects (files, predicates,  modules as well
as  XPCE classes  and methods)  in the  Prolog database.    If  multiple
matches are  found it  provides a choice.    Together with the  built-in
completion on atoms  bound to the TAB key  this provides a quick way  to
edit objects:

?- edit(country).
Please select item to edit:

  1 chat:country/10      '/staff/jan/lib/prolog/chat/countr.pl':16
  2 chat:country/1       '/staff/jan/lib/prolog/chat/world0.pl':72

Your choice?


33..33..22 EEddiittiinngg aanndd iinnccrreemmeennttaall ccoommppiillaattiioonn

One of  the nice features  of Prolog  is that the  code can be  modified
while  the program  is running.    Using  pure Prolog  you  can trace  a
program,  find it  is misbehaving,  enter  a _b_r_e_a_k  _e_n_v_i_r_o_n_m_e_n_t,  modify
the  source code,  reload it  and finally  do _r_e_t_r_y  on the  misbehaving
predicate  and  try  again.      This  sequence  is  not   uncommon  for
long-running programs.   For faster  programs one normally aborts  after
understanding  the misbehaviour,  edit  the source,  reload it  and  try
again.

One of the nice features of SWI-Prolog is the  availability of make/0, a
simple predicate that checks  all loaded source files to see  which ones
you have modified.  It then reloads these  files, considering the module
from which the file was loaded originally.   This greatly simplifies the
trace-edit-verify development cycle.  After the tracer  reveals there is
something wrong with prove/3, you do:

?- edit(prove).

Now  edit the  source,  possibly switching  to  other files  and  making
multiple changes.   After  finishing invoke  make/0, either through  the
editor UI  (Compile/Make (Control-C Control-M)) or  on the toplevel  and
watch the files being reloaded.

?- make.
% show compiled into photo_gallery 0.03 sec, 3,360 bytes


33..44 UUssiinngg tthhee PPcceeEEmmaaccss bbuuiilltt--iinn eeddiittoorr


33..44..11 AAccttiivvaattiinngg PPcceeEEmmaaccss

Initially edit/1  uses the  editor specified in  the EDITOR  environment
variable.   There are two ways to  force it to use the built-in  editor.
One is to  set the prolog-flag editor  to pce_emacs and the other is  by
starting the editor explictely using the emacs/[0,1] predicates.


33..44..22 BBlluuffffiinngg tthhrroouugghh PPcceeEEmmaaccss

PceEmacs closely  mimics Richard Stallman's  GNU-Emacs commands,  adding
features from  modern window-based  editors to make  it more  acceptable
for beginners.

At the  basis, PceEmacs  maps keyboard sequences  to methods defined  on
the extended  _e_d_i_t_o_r object.   Some frequently  used commands are,  with
their key-binding, presented  in the menu-bar above each  editor window.
A complete  overview of the  bindings for the  current _m_o_d_e is  provided
through Help/Show key bindings (Control-h Control-b).


33..44..22..11 EEddiitt mmooddeess

Modes  are the  heart of  (Pce)Emacs.   Modes  define dedicated  editing
support for  a particular  kind of (source-)text.    For our purpose  we
want _P_r_o_l_o_g _m_o_d_e.   Their are various  ways to make PceEmacs use  Prolog
mode for a file.

  o _U_s_i_n_g _t_h_e _p_r_o_p_e_r _e_x_t_e_n_s_i_o_n
    If  the file  ends in .pl  or the  selected alternative (e.g.  .pro)
    extension, Prolog mode is selected.

  o _U_s_i_n_g #!/path/to/pl
    If  the  file  is a  _P_r_o_l_o_g  _S_c_r_i_p_t  file, starting  with  the  line
    #!/path/to/pl options -s, Prolog  mode is selected regardless of the
    extension

  o _U_s_i_n_g -*- Prolog -*-
    If the above sequence  appears in the first line of the file (inside
    a Prolog comment) Prolog mode is sequence

  o _E_x_p_l_i_c_i_t _s_e_l_e_c_t_i_o_n
    Finally,  using  File/Mode/Prolog (y)ou  can switch  to Prolog  mode
    explicitly.


33..44..22..22 FFrreeqquueennttllyy uusseedd eeddiittoorr ccoommmmaannddss

Below we list a few important commands and how to activate them.

  o _C_u_t_/_C_o_p_y_/_P_a_s_t_e
    These  commands  follow Unix/X11  traditions.    You're best  suited
    with  a three-button mouse.   After  selecting using the  left-mouse
    (double-click  uses word-mode  and triple  line-mode), the  selected
    text   is  _a_u_t_o_m_a_t_i_c_a_l_l_y  copied  to  the  clipboard   (X11  primary
    selection  on  Unix).   _C_u_t  is achieved  using the  DEL  key or  by
    typing  something else  at the location.    _P_a_s_t_e is achieved  using
    the  middle-mouse (or wheel)  button.   If you  don't have a  middle
    mouse-button,  pressing the left- and right-button at the  same time
    is interpreted as a  middle-button click.  If nothing helps there is
    the Edit/Paste menu-entry.  Text is pasted at the caret-location.

  o _U_n_d_o
    Undo  is bound to the GNU-Emacs Control-_ as well as  the MS-Windows
    Control-Z sequence.

  o _A_b_o_r_t
    Multi-key sequences can be aborted at any stage using Control-G.

  o _F_i_n_d
    Find  (Search) is  started  using Control-S  (forward) or  Control-R
    (backward).      PceEmacs  implements  _i_n_c_r_e_m_e_n_t_a_l  _s_e_a_r_c_h.     This
    is  difficult  to  use  for novices,  but  very  powerful  once  you
    get  the  clue.    After  one of  the  above start-keys  the  system
    indicates  search mode in the  status line.   As you are typing  the
    search-string,  the  system searches  for it,  extending the  search
    with  every character you  type.   It illustrates the current  match
    using a green background.

    If  the target  cannot be found,  PceEmacs warns  you and no  longer
    extends  the  search-string.   During  search  some characters  have
    special  meaning.  Typing anything but these characters  commits the
    search, re-starting normal edit mode.  Special commands are:

    Control-S
         Search for next forwards.

    Control-R
         Search for next backwards.

    Control-W
         Extend search to next word-boundary.

    Control-G
         Cancel search, go back to where it started.

    ESC
         Commit search, leaving caret at found location.

    Backspace
         Remove a character from the search string.

  o _D_y_n_a_m_i_c _A_b_b_r_e_v_i_a_t_i_o_n
    Also  called _d_a_b_b_r_e_v  is  an important  feature of  Emacs clones  to
    support  programming.   After  typing the  first few  letters of  an
    identifier  you may hit Alt-/, causing PceEmacs to  search backwards
    for  identifiers that start  the same and  using it to complete  the
    text  you typed.   A second  Alt-/ searches further  backwards.   If
    there  are no hits  before the caret  it starts searching  forwards.
    With  some practice, this system allows for very fast  entering code
    with nice and readable identifiers (or other difficult long words).

  o _O_p_e_n _(_a _f_i_l_e_)
    Is  called File/Find  file (Control-x Control-f).    By default  the
    file  is loaded into the current window.   If you want to  keep this
    window,  Hit Alt-s or  click the little  icon at the bottom-left  to
    make the window _s_t_i_c_k_y.

  o _S_p_l_i_t _v_i_e_w
    Sometimes  you want to look at two places  of the same file.   To do
    this,  use Control-x 2 to create  a new window pointing to  the same
    file.   Do not worry, you  can edit as well as move around  in both.
    Control-x 1 kills all other windows running on the same file.

These were the  most commonly used commands.   In section section  3.4.3
we discuss specific support for dealing with Prolog source code.


33..44..33 PPrroolloogg MMooddee

In  the previous  section (section  3.4.2) we  explained  the basics  of
PceEmacs.     Here  we  continue  with  Prolog  specific  functionality.
Possibly  the most  interesting is  _S_y_n_t_a_x _h_i_g_h_l_i_g_h_t_i_n_g.    Unlike  most
editors  where  this  is  based  on  simple  patterns,  PceEmacs  syntax
highlighting  is  achieved   by  Prolog  itself  actually  reading   and
interpreting the  source as you  type it.   There  are three moments  at
which PceEmacs checks (part of) the syntax.

  o _A_f_t_e_r _t_y_p_i_n_g _a .
    After  typing a .  that is not preceeded  by a _s_y_m_b_o_l character  the
    system  assumes you completed a clause,  tries to find the start  of
    this  clause and verifies the syntax.   If this process succeeds  it
    colours  the elements  of the  clause according to  the rules  given
    below.    Colouring is  done using  information from  the last  full
    check  on this file.  If it fails, the syntax error  is displayed in
    the status line and the clause is not coloured.

  o _A_f_t_e_r _t_h_e _c_o_m_m_a_n_d Control-c Control-s
    Acronym  for CCcheck SSyntax it performs the same checks as  above for
    the  clause surrounding the caret.   On a syntax error however,  the
    caret is moved to the expected location of the error.

  o _A_f_t_e_r _p_a_u_s_i_n_g _f_o_r _t_w_o _s_e_c_o_n_d_s
    After  a short  pause (2  seconds), PceEmacs  opens the  edit-buffer
    and  reads it  as a  whole, creating  an index  of defined,  called,
    dynamic,  imported and exported predicates.  After  completing this,
    it  re-reads the file and colours  all clauses and calls with  valid
    syntax.

  o _A_f_t_e_r _t_y_p_i_n_g Control-l Control-l
    The Control-l commands  re-centers the window (scrolls the window to
    make  the caret the  center of  the window).   Hitting this  command
    twice starts the same process as above.

TThhee ccoolloouurr sscchheemmaa

itself  is  defined  in  emacs/prolog_colour.     The  colouring  can  be
extended and  modified using multifile  predicates.   Please check  this
source-file for details.   In general,  underlined objects have a  popup
(right-mouse button) associated for common commands such  as viewing the
documentation or source.   BBoolldd text is used to indicate  the definition
of  objects (typically  predicates  when using  plain  Prolog).    Other
colours follow intuitive conventions.  See table 3.4.3.
          _____________________________________________________
          |______________________Clauses_______________________|
          | Blue bold  |Head of an exported predicate          |
          | Red bold   |Head of a predicate that is not called |

          |_Black_Bold_|Head_of_remaining_predicates___________|
          |______________Calls_in_the_clause-body______________|
          | Blue       |Call to built-in or imported predicate |
          | Red        |Call to not-defined predicate          |
          |_Purple_____|Call_to_dynamic_predicate______________|
          |___________________Other_entities___________________|

          | Dark green |Comment                                |
          | Dark blue  |Quoted atom or string                  |
          |_Brown______|Variable_______________________________|

                     Table 3.1:  Colour conventions

LLaayyoouutt ssuuppppoorrtt Layout  is not `just nice',  it is _e_s_s_e_n_t_i_a_l for  writing
readable code.   There is  much debate on  the proper layout of  Prolog.
PceEmacs,  being a  rather small  project supports  only one  particular
style for layout.  Below are examples of typical constructs.

head(arg1, arg2).

head(arg1, arg2) :- !.

head(Arg1, arg2) :- !,
        call1(Arg1).

head(Arg1, arg2) :-
        (   if(Arg1)
        ->  then
        ;   else
        ).

head(Arg1) :-
        (   a
        ;   b
        ).

head :-
        a(many,
          long,
          arguments(with,
                    many,
                    more),
          and([ a,
                long,
                list,
                with,
                a,
              | tail
              ])).

PceEmacs uses the  same conventions as GNU-Emacs.   The TAB key  indents
the current  line according  to the  syntax rules.    Alt-q indents  all
lines  of the  current clause.    It provides  support for  head,  calls
(indented 1  tab), if-then-else,  disjunction and argument-lists  broken
across multiple lines as illustrated above.


33..44..33..11 FFiinnddiinngg yyoouurr wwaayy aarroouunndd

The command Alt-.   extracts name and arity from the caret  location and
jumps (after conformation  or edit) to the definition of  the predicate.
It does  so based on the  source-location database of loaded  predicates
also used  by edit/1.   This makes locating  predicates reliable if  all
sources are loaded and up-to-date (see make/0).

In addition,  references to files  in use_module/[1,2], consult/1,  etc.
are red if the file cannot be found and underlined blue  if the file can
be loaded.  A popup allows for opening the referenced file.


33..55 TThhee GGrraapphhiiccaall DDeebbuuggggeerr

SWI-Prolog offers  two debuggers.   One is the traditional  text-console
based 4-port Prolog tracer and the other is  a window-based source-level
debugger.    The window-based  debugger  requires XPCE  installed.    It
operates  based  on   the  prolog_trace_interception/4 hook   and  other
low-level functionality described in chapter 10.

Window-based tracing  provides much better overview  due to the  eminent
relation to your source-code, a clear list of  named variables and their
bindings as well  as a graphical overview  of the call and  choice-point
stack.  There are  some drawbacks though.  Using a textual trace  on the
console one can  scroll back and examine  the past, while the  graphical
debugger just presents a (much better) overview of the current state.


33..55..11 IInnvvookkiinngg tthhee wwiinnddooww--bbaasseedd ddeebbuuggggeerr

Whether the  text-based or window-based debugger  is used is  controlled
using  the predicates  guitracer/0 and  noguitracer/0.   Entering  debug
mode  is controlled  using  the normal  predicates  for this:    trace/0
and  spy/1.   In  addition, PceEmacs  prolog mode  provides the  command
Prolog/Break  at (Control-c b)  to insert  a break-point  at a  specific
location in the source-code.


gguuiittrraacceerr
    This  predicate  installs the  above-mentioned hooks  that  redirect
    tracing  to  the  window-based  environment.    No  window  appears.
    The  debugger window  appears as actual  tracing is started  through
    trace/0,  by hitting a spy-point  defined by spy/1 or a  break-point
    defined using PceEmacs command Prolog/Break at (Control-c b).


nnoogguuiittrraacceerr
    Disable  the hooks  installed by  guitracer/0,  reverting to  normal
    text-console based tracing.


33..66 TThhee PPrroolloogg NNaavviiggaattoorr

Another  tool is  the  _P_r_o_l_o_g  _N_a_v_i_g_a_t_o_r.    This  tool can  be  started
from  PceEmacs  using the  command  Browse/Prolog  navigator,  from  the
GUI  debugger or  using  the  programmatic IDE  interface  described  in
section 3.7.


33..77 AAcccceessssiinngg tthhee IIDDEE ffrroomm yyoouurr pprrooggrraamm

Over  the years  a collection  of IDE  components  have been  developed,
each with their  own interface.   In addition, some of these  components
require  each other  and loading  IDE components  must be  on demand  to
avoid the IDE  being part of a  saved-state (see qsave_program/2).   For
this  reason,  access  to the  IDE  will  be concentrated  on  a  single
interface called prolog_ide/1:


pprroolloogg__iiddee((_+_A_c_t_i_o_n))
    This  predicate ensures the IDE  enabling XPCE component is  loaded,
    creates  the XPCE class  _p_r_o_l_o_g___i_d_e  and sends _A_t_i_o_n  to its one  and
    only  instance \index{@prolog_ide}\objectname{prolog_ide}.    _A_c_t_i_o_n
    is one of the following:

    ooppeenn__nnaavviiggaattoorr((_+_D_i_r_e_c_t_o_r_y))
         Open  the Prolog  Navigator  (see  section 3.6)  in  the  given
         _D_i_r_e_c_t_o_r_y.

    ooppeenn__ddeebbuugg__ssttaattuuss
         Open a window to edit spy- and trace-points.

    ooppeenn__qquueerryy__wwiinnddooww
         Opens  a  little  window to  run  Prolog  queries  from  a  GUI
         component.


33..88 SSuummmmaarryy ooff tthhee iiDDEE

The  SWI-Prolog  development   environment  consists  of  a  number   of
interrelated but  not (yet) integrated  tools.   Here is  a list of  the
most important features and tips.

  o _A_t_o_m _c_o_m_p_l_e_t_i_o_n
    The  console  completes a  partial atom  on the  TAB  key and  shows
    alternatives on the command Alt-?.

  o _U_s_e edit/1 _t_o _f_i_n_d_i_n_g _l_o_c_a_t_i_o_n_s
    The  command edit/1 takes the name  of a file, module, predicate  or
    other  entity registered  through  extensions and  starts the  users
    preferred editor at the right location.

  o _S_e_l_e_c_t _e_d_i_t_o_r
    External   editors  are  selected   using  the  EDITOR   environment
    variable, by setting  the prolog flag editor or by defining the hook
    prolog_edit:edit_source/1.

  o _U_p_d_a_t_e _P_r_o_l_o_g _a_f_t_e_r _e_d_i_t_i_n_g
    Using make/0, all files you have edited are re-loaded.

  o _P_c_e_E_m_a_c_s
    Offers  syntax-highlighting and checking based on  real-time parsing
    of the editor's buffer, layout-support and navigation support.

  o _U_s_i_n_g _t_h_e _g_r_a_p_h_i_c_a_l _d_e_b_u_g_g_e_r
    The   predicates  guitracer/0   and  noguitracer/0  switch   between
    traditional  text-based and window-based debugging.   The tracer  is
    activated  using the trace/0, spy/1  or menu-items from PceEmacs  or
    the PrologNavigator.

  o _T_h_e _P_r_o_l_o_g _N_a_v_i_g_a_t_o_r
    Shows  the file-structure and structure inside the file.   It allows
    for loading files, editing, setting spy-points, etc.


CChhaapptteerr 44..  BBUUIILLTT--IINN PPRREEDDIICCAATTEESS


44..11 NNoottaattiioonn ooff PPrreeddiiccaattee DDeessccrriippttiioonnss

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'.    Finally,
arguments may  have the `:'   specifier, which  implies the argument  is
module-sensitive.  Normally the argument is a _c_a_l_l_a_b_l_e  term refering to
a predicate in  a specific module.   See section 5 for more  information
on module-handing.


44..22 CChhaarraacctteerr rreepprreesseennttaattiioonn

In  traditional (Edinburgh-)  Prolog, characters  are represented  using
_c_h_a_r_a_c_t_e_r_-_c_o_d_e_s.   Character codes are  integer indices into a  specific
character set.   Traditionally  the character  set was 7-bits  US-ASCII.
8-bit  character sets  have  been allowed  for  a long  time,  providing
support for national  character sets, of which iso-latin-1  (ISO 8859-1)
is applicable  to many western  languages.   Text-files are supposed  to
represent a sequence of character-codes.

ISO Prolog introduces three types, two of which  are used for characters
and one for accessing binary streams (see open/4).  These types are:

  o _c_o_d_e
    A  _c_h_a_r_a_c_t_e_r_-_c_o_d_e is  an  integer representing  a single  character.
    As  files  may  use  multi-byte encoding  for  supporting  different
    character  sets (utf-8 encoding for example), reading a code  from a
    text-file is in general not the same as reading a byte.

  o _c_h_a_r
    Alternatively,  characters  may  be  represented  as  _o_n_e_-_c_h_a_r_a_c_t_e_r_-
    _a_t_o_m_s.    This is  a  very natural  representation, hiding  encoding
    problems  from  the  programmer as  well  as providing  much  easier
    debugging.

  o _b_y_t_e
    Bytes are used for accessing binary-streams.

The  current  version  of  SWI-Prolog  does  not   provide  support  for
multi-byte character encoding.  This implies for example  that it is not
capable of  breaking a  multi-byte encoded  atom into characters.    For
SWI-Prolog, bytes  and codes  are the same  and one-character-atoms  are
simple atoms containing one byte.

To  ease  the  pain  of  these  multiple  representations,  SWI-Prolog's
built-in  predicates dealing  with character-data  work  as flexible  as
possible:   they accept  data in  any of these  formats as  long as  the
interpretation  is unambiguous.     In addition,  for  output  arguments
that are  instantiated, the character  is extracted before  unification.
This implies  that the following two  calls are identical, both  testing
whether the next input characters is an a.

peek_code(Stream, a).
peek_code(Stream, 97).

These  multiple-representations  are  handled  by  a   large  number  of
built-in  predicates,   all   of  which   are  ISO-compatible.       For
converting  betweem  code and  character  there  is  char_code/2.     For
breaking  atoms  and  numbers  into  characters  are  are  atom_chars/2,
atom_codes/2,  number_codes/2 and  number_chars/2.    For  character  I/O
on  streams  there  is get_char/[1,2],  get_code/[1,2],  get_byte/[1,2],
peek_char/[1,2],   peek_code/[1,2],   peek_byte/[1,2],   put_code/[1,2],
put_char/[1,2]  and  put_byte/[1,2].     The  prolog-flag  double_quotes
(see current_prolog_flag/2) controls how  text between double-quotes  is
interpreted.


44..33 LLooaaddiinngg PPrroolloogg ssoouurrccee ffiilleess

This section deals  with loading Prolog source-files.   A Prolog  source
file is a plain  text file containing a Prolog program or  part thereof.
Prolog source files come in three flavours:

 AA ttrraaddiittiioonnaall   Prolog  source  file  contains  a  Prolog  clauses  and
    directives,  but no  _m_o_d_u_l_e_-_d_e_c_l_a_r_a_t_i_o_n.   They are normally  loaded
    using consult/1 or ensure_loaded/1.

 AA mmoodduullee   Prolog source file  starts with a module  declaration.   The
    subsequent Prolog code  is loaded into the specified module and only
    the _p_u_b_l_i_c predicates  are made available to the context loading the
    module.   Module  files are normally loaded  using use_module/[1,2].
    See chapter 5 for details.

 AAnn iinncclluuddee   Prolog source file is loaded using the include/1 directive
    and normally contains only directives.

Prolog  source-files are  located  using  absolute_file_name/3 with  the
following options:

locate_prolog_file(Spec, Path) :-
        absolute_file_name(Spec,
                           [ file_type(prolog),
                             access(read)
                           ],
                           Path).

The file_type(_p_r_o_l_o_g) option is  used to determine the extension of  the
file using  prolog_file_type/2.    The default extension  is .pl.    _S_p_e_c
allows  for the  _p_a_t_h_-_a_l_i_a_s construct  defined  by absolute_file_name/3.
The  most  commonly  used  path-alias  is  library(_L_i_b_r_a_r_y_F_i_l_e).     The
example below loads the library file oset.pl  (containing predicates for
manipulating ordered sets).

:- use_module(library(oset)).

SWI-Prolog   recognises    grammar   rules    (DCG)   as   defined    in
[Clocksin & Melish, 1987].   The user may define additional  compilation
of the source  file by defining the  dynamic predicates term_expansion/2
and  goal_expansion/2.     Transformations by  term_expansion/2  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.


llooaadd__ffiilleess((_+_F_i_l_e_s_, _+_O_p_t_i_o_n_s))
    The  predicate load_files/2 is the parent  of all the other  loading
    predicates  except for include/2.   It  currently supports a  subset
    of  the options of Quintus load_files/2.  _F_i_l_e_s is  either specifies
    a  single,  or a  list of  source-files.   The  specification for  a
    source-file  is handled  absolute_file_name/2.    See this  predicate
    for  the supported expansions.   _O_p_t_i_o_n_s is a list of options  using
    the format

         _O_p_t_i_o_n_N_a_m_e(_O_p_t_i_o_n_V_a_l_u_e)

    The following options are currently supported:

    iiff((_C_o_n_d_i_t_i_o_n))
         Load the  file only  if the specified  condition is  satisfied.
         The value  true loads the  file unconditionally, changed  loads
         the file  if it  was not loaded  before, or  has been  modified
         since it was loaded the last time, not_loaded loads the file if
         it was not loaded before.

    mmuusstt__bbee__mmoodduullee((_B_o_o_l))
         If true,  raise an  error if  the file  is not  a module  file.
         Used by use_module/[1,2].

    iimmppoorrttss((_L_i_s_t_O_r_A_l_l))
         If  all and  the  file is  a  module file,  import  all  public
         predicates.  Otherwise import only the named predicates.   Each
         predicate is refered to  as <_n_a_m_e>/<_a_r_i_t_y>.  This  option has no
         effect if the file is not a module file.

    ssiilleenntt((_B_o_o_l))
         If  true, load  the  file  without printing  a  message.    The
         specified  value is  the  default for  all  files loaded  as  a
         result of loading the specified files.

    aauuttoollooaadd((_B_o_o_l))
         If  true  (default false),  indicate  this  load  is  a  _d_e_m_a_n_d
         load.   This  implies that,  depending  on the  setting of  the
         prolog-flag  verbose_autoload  the  load-action  is  printed  at
         level informational  or silent.   See also  print_message/2 and
         current_prolog_flag/2.

    qqccoommppiillee((_B_o_o_l))
         If this call appears in a directive of a file  that is compiled
         into Quick Load Format using qcompile/1 and this  flag is true,
         the contents  of the argument  files are  included in the  .qlf
         file instead of the loading directive.

    ssttrreeaamm((_I_n_p_u_t))
         This SWI-Prolog  extension compiles  the data  from the  stream
         _I_n_p_u_t.    If  this option  is  used,  _F_i_l_e_s  must be  a  single
         atom  which is  used to  identify  the source-location  of  the
         loaded clauses  as well as  remove all clauses  if the data  is
         re-consulted.

         This  option  is   added  to  allow  compiling  from   non-file
         locations such as databases, the web, the  _u_s_e_r (see consult/1)
         or other servers.

    The  load_files/2 predicate  can be  hooked to  load  other data  or
    data  from other objects than  files.  See  prolog_load_file/2for  a
    description and http_load for an example.


ccoonnssuulltt((_+_F_i_l_e))
    Read _F_i_l_e as a Prolog  source file.  _F_i_l_e may be a list of files, in
    which  case all members are consulted in turn.  _F_i_l_e may  start with
    the  Unix shell special  sequences ~,  <_u_s_e_r> and $<_v_a_r>.  _F_i_l_e  may
    also be library(Name),  in which case the libraries are searched for
    a  file with the specified  name.  See  also library_directory/1 and
    file_search_path/2.  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
        ?- [user].

    Consult/1  is   equivalent  to  load_files(Files,  []),   except  for
    handling  the  special  file  user,  which reads  clauses  from  the
    terminal.  See also the stream(_I_n_p_u_t) option of load_files/2.


eennssuurree__llooaaddeedd((_+_F_i_l_e))
    If the file  is not already loaded, this is equivalent to consult/1.
    Otherwise,   if  the  file  defines  a  module,  import  all  public
    predicates.    Finally,  if the  file is  already loaded,  is not  a
    module  file and the context module  is not the global user  module,
    ensure_loaded/1 will call consult/1.

    With the semantics, we  hope to get as closely possible to the clear
    semantics  without the presence  of a module  system.   Applications
    using modules should consider using use_module/[1,2].

    Equivalent to load_files(Files, [if(changed)]).


iinncclluuddee((_+_F_i_l_e))
    Pretend  the  terms   in  _F_i_l_e  are  in  the  source-file  in  which
    :- include(File)  appears.  The include construct is  only honnoured
    if  it appears  as  a directive  in a  source-file.   Normally  _F_i_l_e
    contains a sequence of directives.


rreeqquuiirree((_+_L_i_s_t_O_f_N_a_m_e_A_n_d_A_r_i_t_y))
    Declare  that  this file/module  requires the  specified  predicates
    to  be defined ``with  their commonly accepted  definition''.   This
    predicate originates from  the Prolog portability layer for XPCE. It
    is  intended to  provide a  portable mechanism  for specifying  that
    this module requires the specified predicates.

    The implementation normally  first verifies whether the predicate is
    already defined.   If not, it will search the libraries and load the
    required library.

    SWI-Prolog, having autoloading,  does nnoott load the library.  Instead
    it  creates a  procedure header  for the  predicate if  it does  not
    exist.    This will flag  the predicate  as `undefined'.   See  also
    check/0 and autoload/0.


mmaakkee
    Consult  all source  files that  have been changed  since they  were
    consulted.   It checks _a_l_l  loaded source files:  files loaded  into
    a  compiled state  using pl -c ...  and files  loaded using  consult
    or  one  of  its  derivatives.    The  predicate  make/0  is  called
    after  edit/1, automatically reloading all  modified files.  It  the
    user  uses an  external editor  (in  a separate  window), make/0  is
    normally  used to update  the program after  editing.  In  addition,
    make/0  updates the  autoload indices  (see section  2.13) and  runs
    list_undefined/0  from  the check  library  to report  on  undefined
    predicates.


lliibbrraarryy__ddiirreeccttoorryy((_?_A_t_o_m))
    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,
    asserta/1 or remove system defaults using retract/1.


ffiillee__sseeaarrcchh__ppaatthh((_+_A_l_i_a_s_, _?_P_a_t_h))
    Dynamic  predicate used to specify `path-aliases'.  This  feature is
    best described using an example.  Given the definition

    file_search_path(demo, '/usr/lib/prolog/demo').

    the  file specification demo(myfile)  will be expanded to  /usr/lib/
    prolog/demo/myfile.   The second  argument of file_search_path/2 may
    be another alias.

    Below  is the  initial definition  of the file  search path.    This
    path  implies  swi(<_P_a_t_h>)  refers  to  a  file  in  the  SWI-Prolog
    home   directory.     The  alias  foreign(<_P_a_t_h>) is   intended  for
    storing   shared  libraries  (.so  or   .DLL  files).     See   also
    load_foreign_library/[1,2].

    user:file_search_path(library, X) :-
            library_directory(X).
    user:file_search_path(swi, Home) :-
            current_prolog_flag(home, Home).
    user:file_search_path(foreign, swi(ArchLib)) :-
            current_prolog_flag(arch, Arch),
            atom_concat('lib/', Arch, ArchLib).
    user:file_search_path(foreign, swi(lib)).

    The  file_search_path/2expansion  is used by all loading  predicates
    as well as by absolute_file_name/[2,3].

    The  prolog-flag  verbose_file_search  can be  set  to true  to  help
    debugging Prolog's search for files.


eexxppaanndd__ffiillee__sseeaarrcchh__ppaatthh((_+_S_p_e_c_, _-_P_a_t_h))
    Unifies  _P_a_t_h  with   all  possible  expansions  of  the  file  name
    specification _S_p_e_c.  See also absolute_file_name/3.


pprroolloogg__ffiillee__ttyyppee((_?_E_x_t_e_n_s_i_o_n_, _?_T_y_p_e))
    This  dynamic multifile predicate defined in module  user determines
    the  extensions considered by file_search_path/2.  _E_x_t_e_n_s_i_o_n is  the
    filename  extension without the leading  dot, _T_y_p_e denotes the  type
    as  used by the file_type(_T_y_p_e) option of  file_search_path/2.   Here
    is the initial definition of prolog_file_type/2:

    user:prolog_file_type(pl,       prolog).
    user:prolog_file_type(Ext,      prolog) :-
            current_prolog_flag(associate, Ext),
            Ext \== pl.
    user:prolog_file_type(qlf,      qlf).
    user:prolog_file_type(Ext,      executable) :-
            current_prolog_flag(shared_object_extension, Ext).

    Users  may  wish to  change  the extension  used for  Prolog  source
    files  to avoid  conflicts (for  example with  perl) as  well as  to
    be  compatible with  some specific  implementation.   The  preferred
    alternative extension is .pro.


ssoouurrccee__ffiillee((_?_F_i_l_e))
    Succeeds  if _F_i_l_e  is a  loaded Prolog  source file.    _F_i_l_e is  the
    absolute and canonical path to the source-file.


ssoouurrccee__ffiillee((_?_P_r_e_d_, _?_F_i_l_e))
    Is   true   if  the   predicate  specified   by   _P_r_e_d  was   loaded
    from   file  _F_i_l_e,  where  _F_i_l_e  is  an  absolute  path   name  (see
    absolute_file_name/2).  Can be used with  any instantiation pattern,
    but the database  only maintains the source file for each predicate.
    See also clause_property/2.


pprroolloogg__llooaadd__ccoonntteexxtt((_?_K_e_y_, _?_V_a_l_u_e))
    Determine loading context.  The following keys are defined:

      ________________________________________________________________
      |__KKeeyy______________________||DDeessccrriippttiioonn________________________________________________________________________||
      || module        |Module into which file is loaded               |
      | file          |File loaded                                    |
      | stream        |Stream identifier (see current_input/1)        |

      | directory     |Directory in which _F_i_l_e lives.                 |
      | term_position |Position of last  term read.  Term of  the form|
      |_______________|'$stream_position'(0,<_L_i_n_e>,0,0,0)_____________|

    Quintus compatibility predicate.  See also source_location/2.


ssoouurrccee__llooccaattiioonn((_-_F_i_l_e_, _-_L_i_n_e))
    If the last term  has been read from a physical file (i.e., not from
    the file user or  a string), unify _F_i_l_e with an absolute path to the
    file  and _L_i_n_e with the  line-number in the file.   New code  should
    use prolog_load_context/2.


tteerrmm__eexxppaannssiioonn((_+_T_e_r_m_1_, _-_T_e_r_m_2))
    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 _T_e_r_m_2 in  the database
    rather  then the read term  (_T_e_r_m_1).  _T_e_r_m_2 may  be a term of a  the
    form  `?- _G_o_a_l' or `:- _G_o_a_l'.  _G_o_a_l is then treated  as a directive.
    If _T_e_r_m_2 is a  list all terms of the list are stored in the database
    or  called (for directives).   If  _T_e_r_m_2 is of  the form below,  the
    system  will assert _C_l_a_u_s_e and record the  indicated source-location
    with it.

         '$source_location'(<_F_i_l_e>, <_L_i_n_e>):<_C_l_a_u_s_e>

    When compiling a  module (see chapter 5 and the directive module/2),
    expand_term/2  will first try  term_expansion/2 in the module  being
    compiled  to  allow  for  term-expansion rules  that  are  local  to
    a  module.     If  there  is  no  local  definition,  or  the  local
    definition  fails  to translate  the  term,  expand_term/2 will  try
    term_expansion/2  in module user.    For compatibility with  SICStus
    and  Quintus Prolog,  this feature  should not  be used.   See  also
    expand_term/2, goal_expansion/2 and expand_goal/2.


eexxppaanndd__tteerrmm((_+_T_e_r_m_1_, _-_T_e_r_m_2))
    This  predicate  is  normally  called by  the  compiler  to  perform
    preprocessing.   First it calls term_expansion/2.   If this predicate
    fails  it performs  a grammar-rule translation.    If this fails  it
    returns the first argument.


ggooaall__eexxppaannssiioonn((_+_G_o_a_l_1_, _-_G_o_a_l_2))
    Like   term_expansion/2,   goal_expansion/2  provides   for   macro-
    expansion  of Prolog  source-code.   Between  expand_term/2 and  the
    actual  compilation, the body of clauses analysed and the  goals are
    handed  to expand_goal/2, which  uses the goal_expansion/2 hook to do
    user-defined expansion.

    The  predicate goal_expansion/2 is first  called in the module  that
    is being compiled, and then on the user module.

    Only  goals  apearing   in  the  body  of  clauses  when  reading  a
    source-file  are expanded using mechanism,  and only if they  appear
    literally  in the clause, or  as an argument to the  meta-predicates
    not/1,  call/1,  once/1, ignore/1,  findall/3,  bagof/3, setof/3  or
    forall/2.    A real predicate  definition is  required to deal  with
    dynamically constructed calls.


eexxppaanndd__ggooaall((_+_G_o_a_l_1_, _-_G_o_a_l_2))
    This  predicate  is  normally  called by  the  compiler  to  perform
    preprocessing.   First it calls goal_expansion/2.  If this  fails it
    returns the first argument.


aatt__iinniittiiaalliizzaattiioonn((_+_G_o_a_l))
    Register   _G_o_a_l   to   be   run   when   the   system   initialises.
    Initialisation  takes place after  reloading a .qlf (formerly  .wic)
    file  as well as after reloading a  saved-state.  The hooks  are run
    in  the order they were registered.  A warning message is  issued if
    _G_o_a_l fails, but execution continues.  See also at_halt/1


aatt__hhaalltt((_+_G_o_a_l))
    Register  _G_o_a_l to  be run  from PL_cleanup(), which  is called  when
    the  system halts.   The  hooks are  run in the  reverse order  they
    were  registered  (FIFO). Success  or failure  executing  a hook  is
    ignored.   If  the hook  raises an exception  this is printed  using
    print_message/2.    An attempt  to call  halt/[0,1] from  a hook  is
    ignored.


iinniittiiaalliizzaattiioonn((_+_G_o_a_l))
    Call  _G_o_a_l and  register it using  at_initialization/1.   Directives
    that  do  other things  than  creating clauses,  records,  flags  or
    setting  predicate attributes should normally be written  using this
    tag  to ensure the  initialisation is executed  when a saved  system
    starts.  See also qsave_program/[1,2].


ccoommppiilliinngg
    Succeeds  if  the  system is  compiling  source  files with  the  -c
    option  or qcompile/1 into an intermediate  code file.  Can be  used
    to  perform conditional code optimisations  in term_expansion/2 (see
    also  the  -O option)  or  to omit  execution of  directives  during
    compilation.


pprreepprroocceessssoorr((_-_O_l_d_, _+_N_e_w))
    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


44..33..11 QQuuiicckk llooaadd ffiilleess

SWI-Prolog supports compilation of individual or  multiple Prolog source
files into `Quick Load Files'.  A `Quick Load  Files' (.qlf file) stores
the contents of the file in a precompiled format.

These files load considerably faster than source files  and are normally
more compact.    They are  machine independent  and may  thus be  loaded
on any  implementation of  SWI-Prolog.   Note however  that clauses  are
stored as virtual  machine instructions.   Changes to the compiler  will
generally make old compiled files unusable.

Quick Load Files  are created using qcompile/1.   They are loaded  using
consult/1  or one  of  the other  file-loading predicates  described  in
section 4.3.   If consult is given  the explicit .pl file, it will  load
the Prolog  source.  When  given the .qlf file,  it will load the  file.
When no extension is specified, it will load the  .qlf file when present
and the .pl file otherwise.


qqccoommppiillee((_+_F_i_l_e))
    Takes  a single  file specification  like  consult/1 (i.e.,  accepts
    constructs like library(LibFile)  and creates a Quick Load File from
    _F_i_l_e.   The file-extension of this file  is .qlf.  The base  name of
    the Quick Load File is the same as the input file.

    If   the   file  contains   `:- consult(+File)',   `:- [+File]'   or
    :- load_files(+File, [qcompile(true), ...])   statements,  the   re-
    ferred  files  are  compiled  into  the  same  .qlf  file.     Other
    directives will be stored  in the .qlf file and executed in the same
    fashion as when loading the .pl file.

    For  term_expansion/2,  the same rules  as described in section  2.10
    apply.

    Conditional  execution   or  optimisation  may  test  the  predicate
    compiling/0.

    Source  references (source_file/2) in the  Quick Load File refer  to
    the Prolog source file from which the compiled code originates.


44..44 LLiissttiinngg aanndd EEddiittoorr IInntteerrffaaccee

SWI-Prolog  offers an  extensible  interface which  allows the  user  to
edit objects  of the program:   predicates,  modules, files,  etc.   The
editor interface is  implemented by edit/1 and consists of  three parts:
_l_o_c_a_t_i_n_g, _s_e_l_e_c_t_i_n_g and _s_t_a_r_t_i_n_g _t_h_e _e_d_i_t_o_r.

Any of  these parts may  be extended or redefined  by adding clauses  to
various multi-file  (see multifile/1) predicates  defined in the  module
prolog_edit.

The built-in  edit specifications for edit/1  (see prolog_edit:locate/3)
are described below.

   ___________________________________________________________________
   |__________________________________________FFuullllyy__ssppeecciiffiieedd__oobbjjeeccttss____________________________________________||
   || <_M_o_d_u_l_e>:<_N_a_m_e>/<_A_r_i_t_y>R|efers a predicate                      |
   | module(<_M_o_d_u_l_e>)      |Refers to a module                       |
   | file(<_P_a_t_h>)          |Refers to a file                         |

   |_source_file(<_P_a_t_h>)___R|efers_to_a_loaded_source-file___________|_
   |__________________________________________AAmmbbiigguuoouuss__ssppeecciiffiiccaattiioonnss__________________________________________||
   || <_N_a_m_e>/<_A_r_i_t_y>        R|efers this predicate in any module      |
   | <_N_a_m_e>                |Refers  to  (1) named  predicate  in  any|
   |                       |module  with any  arity,  (2) a  (source)|
   |_______________________|file_or_(3)_a_module.____________________|_


eeddiitt((_+_S_p_e_c_i_f_i_c_a_t_i_o_n))
    First  exploits prolog_edit:locate/3to  translate _S_p_e_c_i_f_i_c_a_t_i_o_n into
    a  list  of  _L_o_c_a_t_i_o_n_s.    If there  is  more than  one  `hit',  the
    user  is  asked  to select  from  the  locations found.     Finally,
    prolog_edit:edit_source/1 is  used  to invoke  the user's  preferred
    editor.   Typically, edit/1 can  be handed the name of  a predicate,
    module, basename of a file, XPCE class, XPCE method, etc.


eeddiitt
    Edit  the `default'  file using  edit/1.   The default  file is  the
    file loaded with the  commandline option -s or, in windows, the file
    loaded by double-clicking from the Windows shell.


pprroolloogg__eeddiitt::llooccaattee((_+_S_p_e_c_, _-_F_u_l_l_S_p_e_c_, _-_L_o_c_a_t_i_o_n))
    Where  _S_p_e_c is  the  specification provided  through edit/1.    This
    multifile  predicate  is  used to  enumerate  locations at  with  an
    object satisfying the given  _S_p_e_c can be found.  _F_u_l_l_S_p_e_c is unified
    with  the complete specification for  the object.  This  distinction
    is  used to  allow for ambiguous  specifications.   For example,  if
    _S_p_e_c  is  an  atom,  which appears  as  the base-name  of  a  loaded
    file  and as  the name  of a predicate,  _F_u_l_l_S_p_e_c will  be bound  to
    file(_P_a_t_h) or _N_a_m_e/_A_r_i_t_y.

    _L_o_c_a_t_i_o_n  is a list of attributes  of the location.  Normally,  this
    list  will contain  the term file(_F_i_l_e)  and ---if available---  the
    term line(_L_i_n_e).


pprroolloogg__eeddiitt::llooccaattee((_+_S_p_e_c_, _-_L_o_c_a_t_i_o_n))
    Same  as prolog_edit:locate/3, but only deals with  fully-sepecified
    objects.


pprroolloogg__eeddiitt::eeddiitt__ssoouurrccee((_+_L_o_c_a_t_i_o_n))
    Start  editor on _L_o_c_a_t_i_o_n.  See  prolog_edit:locate/3for  the format
    of  a location  term.   This  multi-file predicate  is normally  not
    defined.  If it succeeds, edit/1 assumes the editor is started.

    If  it fails, edit/1 uses  its internal defaults, which are  defined
    by  the prolog-flag editor  and/or the environment variable  EDITOR.
    The  following  rules  apply.    If  the prolog-flag  editor  is  of
    the  format $<_n_a_m_e>,  the  editor is  determined by  the environment
    variable  <_n_a_m_e>.   Else, if this flag  is pce_emacs or built_in _a_n_d
    XPCE  is  loaded or  can  be loaded,  the  built-in Emacs  clone  is
    used.  Else,  if the environment EDITOR is set, this editor is used.
    Finally,  vi  is used  as default  on Unix  systems  and notepad  on
    Windows.

    See   the  default  user   preferences  file  dotfiles/dotplrc   for
    examples.


pprroolloogg__eeddiitt::eeddiitt__ccoommmmaanndd((_+_E_d_i_t_o_r_, _-_C_o_m_m_a_n_d))
    Determines  how _E_d_i_t_o_r is  to be invoked using  shell/1.  _E_d_i_t_o_r  is
    the  determined editor  (see edit_source/1), without  the full  path
    specification,  and without  possible (exe) extension.   _C_o_m_m_a_n_d  is
    an  atom describing  the command.   The  pattern %f  is replaced  by
    the  full file-name  of the  location, and  %d by  the line  number.
    If  the  editor can  deal with  starting at  a specified  line,  two
    clauses  should be provided,  one holding only  the %f pattern,  and
    one holding both patterns.

    The  default contains  definitions for vi,  emacs, emacsclient,  vim
    and notepad (latter without line-number version).

    Please contribute your specifications to jan@swi.psy.uva.nl.


pprroolloogg__eeddiitt::llooaadd
    Normally  not-defined  multifile  predicate.    This  predicate  may
    be  defined  to provide  loading hooks  for  user-extensions to  the
    edit  module.   For example,  XPCE provides the  code below to  load
    swi_edit,  containing definitions to locate  classes and methods  as
    well as to bind this package to the PceEmacs built-in editor.

    :- multifile prolog_edit:load/0.

    prolog_edit:load :-
            ensure_loaded(library(swi_edit)).


lliissttiinngg((_+_P_r_e_d))
    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 losing user's layout and
    variable name information.  See also portray_clause/1.


lliissttiinngg
    List all predicates of the database using listing/1.


ppoorrttrraayy__ccllaauussee((_+_C_l_a_u_s_e))
    Pretty  print a  clause.   A clause  should be specified  as a  term
    `<_H_e_a_d> :- <_B_o_d_y>'.    Facts are  represented as  `<_H_e_a_d> :- true'  or
    simply <_H_e_a_d>.  See also portray_clause/2.


ppoorrttrraayy__ccllaauussee((_+_S_t_r_e_a_m_, _+_C_l_a_u_s_e))
    Pretty print a clause to _S_t_r_e_a_m.  See portray_clause/1 for details.


44..55 VVeerriiffyy TTyyppee ooff aa TTeerrmm


vvaarr((_+_T_e_r_m))
    Succeeds if _T_e_r_m currently is a free variable.


nnoonnvvaarr((_+_T_e_r_m))
    Succeeds if _T_e_r_m currently is not a free variable.


iinntteeggeerr((_+_T_e_r_m))
    Succeeds if _T_e_r_m is bound to an integer.


ffllooaatt((_+_T_e_r_m))
    Succeeds if _T_e_r_m is bound to a floating point number.


nnuummbbeerr((_+_T_e_r_m))
    Succeeds if _T_e_r_m is bound to an integer or a floating point number.


aattoomm((_+_T_e_r_m))
    Succeeds if _T_e_r_m is bound to an atom.


ssttrriinngg((_+_T_e_r_m))
    Succeeds if _T_e_r_m is bound to a string.


aattoommiicc((_+_T_e_r_m))
    Succeeds  if _T_e_r_m is bound to  an atom, string, integer or  floating
    point number.


ccoommppoouunndd((_+_T_e_r_m))
    Succeeds  if _T_e_r_m is bound to a  compound term.  See  also functor/3
    and =../2.


ccaallllaabbllee((_+_T_e_r_m))
    Succeeds  if _T_e_r_m is bound to an atom or a compound term,  so it can
    be handed without type-error to call/1, functor/3 and =../2.


ggrroouunndd((_+_T_e_r_m))
    Succeeds if _T_e_r_m holds no free variables.


44..66 CCoommppaarriissoonn aanndd UUnniiffiiccaattiioonn oorr TTeerrmmss


44..66..11 SSttaannddaarrdd OOrrddeerr ooff TTeerrmmss

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

 1. _V_a_r_i_a_b_l_e_s <_A_t_o_m_s <_S_t_r_i_n_g_s <_N_u_m_b_e_r_s <_T_e_r_m_s

 2. _O_l_d _V_a_r_i_a_b_l_e <_N_e_w _V_a_r_i_a_b_l_e

 3. _A_t_o_m_s are compared alphabetically.

 4. _S_t_r_i_n_g_s are compared alphabetically.

 5. _N_u_m_b_e_r_s  are compared  by value.   Integers  and floats are  treated
    identically.

 6. _C_o_m_p_o_u_n_d  terms are  first checked  on  their arity,  then on  their
    functor-name  (alphabetically)  and  finally  recursively  on  their
    arguments, leftmost argument first.

If  the  prolog_flag  (see  current_prolog_flag/2)  iso  is  defined,  all
floating point numbers precede all integers.


_+_T_e_r_m_1 == _+_T_e_r_m_2
    Succeeds  if _T_e_r_m_1  is  equivalent to  _T_e_r_m_2.   A  variable is  only
    identical to a sharing variable.


_+_T_e_r_m_1 \== _+_T_e_r_m_2
    Equivalent to \+Term1 == Term2.


_+_T_e_r_m_1 = _+_T_e_r_m_2
    Unify _T_e_r_m_1 with _T_e_r_m_2.  Succeeds if the unification succeeds.


uunniiffyy__wwiitthh__ooccccuurrss__cchheecckk((_+_T_e_r_m_1_, _+_T_e_r_m_2))
    As  =/2, but  using _s_o_u_n_d_-_u_n_i_f_i_c_a_t_i_o_n.    That is,  a variable  only
    unifies  to  a term  if  this term  does  not contain  the  variable
    itself.  To illustrate this, consider the two goals below:

    1 ?- A = f(A).

    A = f(f(f(f(f(f(f(f(f(f(...))))))))))
    2 ?- unify_with_occurs_check(A, f(A)).

    No

    I.e.   the  first  creates  a  _c_y_c_l_i_c_-_t_e_r_m,  which  is   printed  as
    an  infinitely   nested  f/1  term  (see  the  max_depth  option  of
    write_term/2).  The second executes  logically sound unification and
    thus fails.


_+_T_e_r_m_1 \= _+_T_e_r_m_2
    Equivalent to \+Term1 = Term2.


_+_T_e_r_m_1 =@= _+_T_e_r_m_2
    Succeeds  if _T_e_r_m_1  is `structurally  equal' to _T_e_r_m_2.    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


_+_T_e_r_m_1 \=@= _+_T_e_r_m_2
    Equivalent to `\+Term1 =@= Term2'.


_+_T_e_r_m_1 @< _+_T_e_r_m_2
    Succeeds if _T_e_r_m_1 is before _T_e_r_m_2 in the standard order of terms.


_+_T_e_r_m_1 @=< _+_T_e_r_m_2
    Succeeds if both terms  are equal (==/2) or _T_e_r_m_1 is before _T_e_r_m_2 in
    the standard order of terms.


_+_T_e_r_m_1 @> _+_T_e_r_m_2
    Succeeds if _T_e_r_m_1 is after _T_e_r_m_2 in the standard order of terms.


_+_T_e_r_m_1 @>= _+_T_e_r_m_2
    Succeeds  if both terms are equal (==/2) or _T_e_r_m_1 is after  _T_e_r_m_2 in
    the standard order of terms.


ccoommppaarree((_?_O_r_d_e_r_, _+_T_e_r_m_1_, _+_T_e_r_m_2))
    Determine or test  the _O_r_d_e_r between two terms in the standard order
    of terms.  _O_r_d_e_r is one of <, >  or =, with the obvious meaning.


44..77 CCoonnttrrooll PPrreeddiiccaatteess

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).


ffaaiill
    Always  fail.   The  predicate fail/0  is translated  into a  single
    virtual machine instruction.


ttrruuee
    Always  succeed.  The predicate  true/0 is translated into a  single
    virtual machine instruction.


rreeppeeaatt
    Always succeed, provide an infinite number of choice points.


!
    Cut.    Discard choice  points of  parent frame  and frames  created
    after the parent frame.   As of SWI-Prolog 3.3, the semantics of the
    cut are compliant with  the ISO standard.  This implies that the cut
    is  transparent to  ;/2, ->/2  and  *->/2.   Cuts  appearing in  the
    _c_o_n_d_i_t_i_o_n  part of ->/2 and  *->/2 as well  as in \+/1 are local  to
    the condition.

             t1 :- (a, !, fail ; b).        % cuts a/0 and t1/0
             t2 :- (a -> b, !  ; c).        % cuts b/0 and t2/0
             t3 :- call((a, !, fail ; b)).  % cuts a/0
             t4 :- \+(a, !, fail ; b).      % cuts a/0


_+_G_o_a_l_1 , _+_G_o_a_l_2
    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.


_+_G_o_a_l_1 ; _+_G_o_a_l_2
    The `or' predicate is defined as:

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

_+_G_o_a_l_1 | _+_G_o_a_l_2
    Equivalent  to ;/2.    Retained for compatibility  only.   New  code
    should use ;/2.


_+_C_o_n_d_i_t_i_o_n -> _+_A_c_t_i_o_n
    If-then  and  If-Then-Else.    The  ->/2  construct commits  to  the
    choices  made  at  its  left-hand  side,   destroying  choice-points
    created  inside the  clause (by  ;/2), or  by goals  called by  this
    clause.   Unlike !/0,  the choicepoint of  the predicate as a  whole
    (due  to multiple clauses)  is nnoott destroyed.   The combination  ;/2
    and ->/2  acts as if defines by:

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

    Please  note that (If -> Then) acts  as (If -> Then ; ffaaiill),  making
    the  construct _f_a_i_l if the condition fails.  This  unusual semantics
    is part of the ISO and all de-facto Prolog standards.


_+_C_o_n_d_i_t_i_o_n *-> _+_A_c_t_i_o_n _; _+_E_l_s_e
    This  construct implements  the so-called `soft-cut'.   The  control
    is  defined as follows:   If _C_o_n_d_i_t_i_o_n succeeds  at least once,  the
    semantics  is the same  as (_C_o_n_d_i_t_i_o_n, _A_c_t_i_o_n).   If _C_o_n_d_i_t_i_o_n  does
    not  succeed, the  semantics is that  of (\+ _C_o_n_d_i_t_i_o_n,  _E_l_s_e).   In
    other  words, If _C_o_n_d_i_t_i_o_n succeeds at least once, simply  behave as
    the conjunction of _C_o_n_d_i_t_i_o_n and _A_c_t_i_o_n, otherwise execute _E_l_s_e.

    The  construct _A *-> _B, i.e. without an _E_l_s_e branche,  is translated
    as the normal conjunction _A, _B.


\+ _+_G_o_a_l
    Succeeds  if  `Goal'  cannot  be  proven (mnemonic:    +  refers  to
    _p_r_o_v_a_b_l_e  and  the  backslash  (\)  is  normally  used  to  indicate
    negation in Prolog).


44..88 MMeettaa--CCaallll PPrreeddiiccaatteess

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.


ccaallll((_+_G_o_a_l))
    Invoke  _G_o_a_l as a  goal.   Note that clauses  may have variables  as
    subclauses, which is identical to call/1.


ccaallll((_+_G_o_a_l_, _+_E_x_t_r_a_A_r_g_1_, _._._.))
    Append  _E_x_t_r_a_A_r_g_1_, _E_x_t_r_a_A_r_g_2_,  _._._.   to  the argument  list of  _G_o_a_l
    and  call the result.   For  example, call(plus(1), 2, X) will  call
    plus/3, binding _X to 3.

    The call/[2..]   construct is handled by the compiler, which implies
    that  redefinition as  a predicate has  no effect.   The  predicates
    call/[2-6]  are defined as true  predicates, so they can be  handled
    by interpreted code.


aappppllyy((_+_T_e_r_m_, _+_L_i_s_t))
    Append  the members of  _L_i_s_t to the arguments  of _T_e_r_m 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.  New code should use call/[2..]   if the length
    of _L_i_s_t is  fixed, which is more widely supported and faster because
    there is no need to build and examine the argument list.


nnoott((_+_G_o_a_l))
    Succeeds  when _G_o_a_l cannot  be proven.   Retained for  compatibility
    only.  New code should use \+/1.


oonnccee((_+_G_o_a_l))
    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.


iiggnnoorree((_+_G_o_a_l))
    Calls  _G_o_a_l  as once/1,  but succeeds,  regardless  of whether  _G_o_a_l
    succeeded or not.  Defined as:

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

ccaallll__wwiitthh__ddeepptthh__lliimmiitt((_+_G_o_a_l_, _+_L_i_m_i_t_, _-_R_e_s_u_l_t))
    If  _G_o_a_l can be proven  without recursion deeper than _L_i_m_i_t  levels,
    call_with_depth_limit/3 succeeds,  binding  _R_e_s_u_l_t  to  the  deepest
    recursion  level  used  during the  proof.    Otherwise,  _R_e_s_u_l_t  is
    unified  with depth_limit_exceeded  if the limit was exceeded  during
    the  proof,  or the  entire predicate  fails if  _G_o_a_l fails  without
    exceeding _L_i_m_i_t.

    The  depth-limit is  guarded by the  internal machinery.   This  may
    differ  from the depth computed based  on a theoretical model.   For
    example,  true/0  is  translated  into an  inlined  virtual  machine
    instruction.   Also, repeat/0 is not implemented as below, but  as a
    non-deterministic foreign predicate.

    repeat.
    repeat :-
            repeat.

    As  a  result, call_with_depth_limit/3 may  still loop  inifitly  on
    programs  that should  theoretically finish  in finite time.    This
    problem  can be cured by  using Prolog equivalents to such  built-in
    predicates.

    This   predicate  may  be   used  for  theorem-provers  to   realise
    techniques  like _i_t_e_r_r_a_t_i_v_e  _d_e_e_p_e_n_i_n_g.   It  was implemented  after
    discussion with Steve Moyle smoyle@ermine.ox.ac.uk.


ccaallll__cclleeaannuupp((_:_G_o_a_l_, _+_C_a_t_c_h_e_r_, _:_C_l_e_a_n_u_p))
    Calls   _G_o_a_l.      If  _G_o_a_l  is  completely   finished,  either   by
    deterministic  success,   failure,  its  choicepoint  being  cut  or
    raising  an exception  and _C_a_t_c_h_e_r unifies  to the termination  code
    (see  below), _C_l_e_a_n_u_p  is called.    Success or  failure of  _C_l_e_a_n_u_p
    is  ignored and possibly choicepoints  it created are destroyed  (as
    once/1).    If  cleanup  throws an  exception  this is  executed  as
    normal.

    _C_a_t_c_h_e_r  is  unified  with  a  term  describing  how  the  call  has
    finished.  If this unification fails, _C_l_e_a_n_u_p is _n_o_t called.

    eexxiitt
         _G_o_a_l succeeded without leaving any choicepoints.

    ffaaiill
         _G_o_a_l failed.

    !
         _G_o_a_l succeeded  with choicepoints and  these are now  discarded
         by the  execution of  a cut (or  orther pruning  of the  search
         tree such as if-then-else).

    eexxcceeppttiioonn((_E_x_c_e_p_t_i_o_n))
         _G_o_a_l raised the given _E_x_c_e_p_t_i_o_n.

    Typical  use of this predicate is cleanup of permanent  data storage
    required to execute  _G_o_a_l, close file-descriptors, etc.  The example
    below  provides a  non-deterministic search  for a term  in a  file,
    closing the stream as needed.

    term_in_file(Term, File) :-
            open(File, read, In),
            call_cleanup(term_in_stream(Term, In), _, close(In)).

    term_in_stream(Term, In) :-
            repeat,
            read(In, T),
            (   T == end_of_file
            ->  !, fail
            ;   T = Term
            ).

    Note  that  this  predicate is  impossible  to implement  in  Prolog
    other  then reading all terms into  a list, close the file  and call
    member/2  because without  call_cleanup/3 there  is no  way to  gain
    control if the choicepoint left by repeat is killed by a cut.

    This  predicate is a SWI-Prolog extension.   See also call_cleanup/2
    for compatibility to other Prolog implementations.


ccaallll__cclleeaannuupp((_:_G_o_a_l_, _:_C_l_e_a_n_u_p))
    This  predicate  is  equivalent to  call_cleanup(_G_o_a_l_,  ___,  _C_l_e_a_n_u_p),
    calling   _C_l_e_a_n_u_p   regardless  of   the  reason   for   termination
    and  without  providing   information.     This  predicate  provides
    compatibility to a number of other Prolog implementations.


44..99 IISSOO ccoommpplliiaanntt EExxcceeppttiioonn hhaannddlliinngg

SWI-Prolog defines the predicates catch/3 and throw/1  for ISO compliant
raising  and catching  of exceptions.    In  the current  implementation
(4.0.6), most of  the built-in predicates generate exceptions,  but some
obscure predicates merely print a message, start the  debugger and fail,
which was the normal behaviour before the introduction of exceptions.


ccaattcchh((_:_G_o_a_l_, _+_C_a_t_c_h_e_r_, _:_R_e_c_o_v_e_r))
    Behaves  as call/1 if  no exception is  raised when executing  _G_o_a_l.
    If  a exception  is raised  using throw/1 while  _G_o_a_l executes,  and
    the  _G_o_a_l is the innermost goal  for which _C_a_t_c_h_e_r unifies with  the
    argument  of throw/1,  all choicepoints generated  by _G_o_a_l are  cut,
    the  system backtracks to the start of catch/3 while  preserving the
    thrown exception term and _R_e_c_o_v_e_r is called as in call/1.

    The  overhead of calling a  goal through catch/3 is very  comparable
    to  call/1.  Recovery from  an exception is much slower,  especially
    if the exception-term is large due to the copying thereof.


tthhrrooww((_+_E_x_c_e_p_t_i_o_n))
    Raise  an exception.   The  system looks  for the innermost  catch/3
    ancestor  for which _E_x_c_e_p_t_i_o_n unifies  with the _C_a_t_c_h_e_r argument  of
    the catch/3 call.  See catch/3 for details.

    ISO  demands throw/1 to make a copy of _E_x_c_e_p_t_i_o_n, walk up  the stack
    to a catch/3 call,  backtrack and try to unify the copy of _E_x_c_e_p_t_i_o_n
    with  _C_a_t_c_h_e_r.   SWI-Prolog delays  making a  copy of _E_x_c_e_p_t_i_o_n  and
    backtracking  until it actually found a matching catch/3 goal.   The
    advantage  is that we can start  the debugger at the first  possible
    location  while preserving the entire exception context if  there is
    no  matching  catch/3 goal.    This aproach  can  lead to  different
    behaviour  if _G_o_a_l and _C_a_t_c_h_e_r of catch/3 call share variables.   We
    assume this to be  highly unlikely and could not think of a scenario
    where this is useful.

    If  an exception is raised in a callback from C (see chapter  7) and
    not  caught in the same call-back,  PL_next_solution()fails and  the
    exception context can be retrieved using PL_exception().


44..99..11 DDeebbuuggggiinngg aanndd eexxcceeppttiioonnss

Before  the introduction  of exceptions  in SWI-Prolog  a runtime  error
was handled  by printing  an error  message, after  which the  predicate
failed.   If  the prolog_flag (see current_prolog_flag/2) debug_on_error
was in effect  (default), the tracer was  switched on.  The  combination
of the  error message and trace  information is generally sufficient  to
locate the error.

With exception handling,  things are different.   A programmer may  wish
to trap an  exception using catch/3 to avoid  it reaching the user.   If
the  exception is  not handled  by user-code,  the interactive  toplevel
will trap it to prevent termination.

If  we  do  not  take  special  precautions,   the  context  information
associated with  an unexpected exception (i.e,  a programming error)  is
lost.  Therefore,  if an exception is raised, which is not  caught using
catch/3 and the toplevel is running, the error will  be printed, and the
system will enter trace mode.

If the system  is in an non-interactive  callback from foreign code  and
there is no catch/3  active in the current context, it  cannot determine
whether or  not the  exception will  be caught by  the external  routine
calling Prolog.    It will  then base  its behaviour on  the prolog_flag
debug_on_error:

  o _c_u_r_r_e_n_t___p_r_o_l_o_g___f_l_a_g_(_d_e_b_u_g___o_n___e_r_r_o_r_, _f_a_l_s_e_)
    The  exception does  not trap the  debugger and  is returned to  the
    foreign  routine  calling Prolog,  where it  can  be accessed  using
    PL_exception().  This is the default.

  o _c_u_r_r_e_n_t___p_r_o_l_o_g___f_l_a_g_(_d_e_b_u_g___o_n___e_r_r_o_r_, _t_r_u_e_)
    If the exception is  not caught by Prolog in the current context, it
    will trap the tracer to help analysing the context of the error.

While looking for the  context in which an exception takes place,  it is
advised to switch on debug mode using the predicate debug/0.


44..99..22 TThhee eexxcceeppttiioonn tteerrmm

Builtin  predicates  generates exceptions  using  a  term  error(_F_o_r_m_a_l_,
_C_o_n_t_e_x_t).    The  first argument  is  the  `formal' description  of  the
error,  specifying the class  and generic  defined context  information.
When applicable,  the ISO  error-term definition  is used.   The  second
part  describes some  additional context  to help  the programmer  while
debugging.    In its  most  generic form  this  is a  term of  the  form
context(_N_a_m_e_/_A_r_i_t_y_,  _M_e_s_s_a_g_e), where _N_a_m_e/_A_r_i_t_y  describes the  built-in
predicate  that raised  the error,  and _M_e_s_s_a_g_e  provides an  additional
description of the error.  Any part of this structure  may be a variable
if no information was present.


44..99..33 PPrriinnttiinngg mmeessssaaggeess

The predicate print_message/2 may be  used to print a message term  in a
human readable  format.   The other predicates  from this section  allow
the user  to refine  and extend  the message system.    The most  common
usage of  print_message/2 is to  print error  messages from  exceptions.
The code below  prints errors encountered during the execution  of _G_o_a_l,
without  further propagating  the  exception  and without  starting  the
debugger.

        ...,
        catch(Goal, E,
              ( print_message(error, E),
                fail
              )),
        ...

Another common  use is to  defined message_hook/3 for printing  messages
that are normally _s_i_l_e_n_t, suppressing messages,  redirecting messages or
make something happen in addition to printing the message.


pprriinntt__mmeessssaaggee((_+_K_i_n_d_, _+_T_e_r_m))
    The  predicate print_message/2 is  used to  print messages,  notably
    from  exceptions  in  a human-readable  format.    _K_i_n_d  is  one  of
    informational,   banner,  warning,  error,   help  or  silent.     A
    human-readable message is printed to the stream user_error.

    If  the prolog flag  (see current_prolog_flag/2) verbose is  silent,
    messages  with _K_i_n_d informational, or banner are treated  as silent.
    See -q.

    This  predicate first translates  the _T_e_r_m into  a list of  `message
    lines'  (see print_message_lines/3for  details).  Next it  will call
    the hook  message_hook/3to allow the  user intercepting the message.
    If  message_hook/3 fails it  will print the  message unless _K_i_n_d  is
    silent.

    The  print_message/2  predicate  and  its  rules  are  in  the  file
    <_p_l_h_o_m_e>/boot/messages.pl,   which  may   be   inspected  for   more
    information on the error messages and related error terms.

    See also message_to_string/2.


pprriinntt__mmeessssaaggee__lliinneess((_+_S_t_r_e_a_m_, _+_P_r_e_f_i_x_, _+_L_i_n_e_s))
    Print a  message (see print_message/2) that has  been translated to a
    list of message elements.  The elements of this list are:

    <_F_o_r_m_a_t>--<_A_r_g_s>
         Where _F_o_r_m_a_t is an atom and _A_r_g_s is a list  of format argument.
         Handed to format/3.

    flush
         If this  appears as the  last element,  _S_t_r_e_a_m is flushed  (see
         flush_output/1) and no final newline is generated.

    at_same_line
         If this  appears as  first element,  no prefix  is printed  for
         the first line  and the line-position is  not forced to 0  (see
         format/1, ~N).

    <_F_o_r_m_a_t>
         Handed to format/3 as format(Stream, Format, []).

    nnll
         A new line  is started and if  the message is not complete  the
         _P_r_e_f_i_x is printed too.

    See also print_message/2 and message_hook/3.


mmeessssaaggee__hhooookk((_+_T_e_r_m_, _+_K_i_n_d_, _+_L_i_n_e_s))
    Hook  predicate that may be define  in the module user to  intercept
    messages  from  print_message/2.    _T_e_r_m  and _K_i_n_d  are the  same  as
    passed to  print_message/2.  _L_i_n_e_s is a  list of format statements as
    described with print_message_lines/3.  See also message_to_string/2.

    This  predicate should  be defined  dynamic and  multifile to  allow
    other modules defining clauses for it too.


mmeessssaaggee__ttoo__ssttrriinngg((_+_T_e_r_m_, _-_S_t_r_i_n_g))
    Translates  a message-term into a  string object (see section  4.23.
    Primarily  intended  to  write  messages to  Windows  in  XPCE  (see
    section 1.5) or other GUI environments.


44..1100 HHaannddlliinngg ssiiggnnaallss

As  of  version  3.1.0,   SWI-Prolog  is  capable  to   handle  software
interrupts  (signals) in  Prolog as  well as  in foreign  (C) code  (see
section 7.6.10).

Signals are used to handle internal errors (execution  of a non-existing
CPU  intruction,  arithmetic  domain  errors,   illegal  memory  access,
resource  overflow,   etc.),  as   well  as  for  dealing   asynchronous
inter-process communication.

Signals  are  defined  by  the POSIX  standard  and  part  of  all  Unix
machines.    The  MS-Windows  Win32  provides  a subset  of  the  signal
handling  routines, lacking  the vital  funtionality to  raise a  signal
in  another   thread  for   achieving  asynchronous  inter-process   (or
inter-thread) communication (Unix kill() function).


oonn__ssiiggnnaall((_+_S_i_g_n_a_l_, _-_O_l_d_, _:_N_e_w))
    Determines  the reaction on  _S_i_g_n_a_l.   _O_l_d is  unified with the  old
    behaviour, while the behaviour  is switched to _N_e_w.  As with similar
    environment-control  predicates,  the  current  value  is  retrieved
    using on_signal(Signal, Current, Current).

    The  action  description  is  an  atom  denoting  the  name  of  the
    predicate  that  will be  called  if _S_i_g_n_a_l  arrives.    on_signal/3
    is  a meta predicate,  which implies that <_M_o_d_u_l_e>:<_N_a_m_e>  refers the
    <_N_a_m_e>/1 in the module <_M_o_d_u_l_e>.

    Two  predicate-names have  special meaning.    throw implies  Prolog
    will  map  the  signal  onto  a Prolog  exception  as  described  in
    section  4.9.   default resets  the handler  to the settings  active
    before SWI-Prolog manipulated the handler.

    Signals  bound   to  a  foreign  function  through  PL_signal()  are
    reported using the term $foreign_function(_A_d_d_r_e_s_s).

    After  receiving a signal mapped to throw, the exception  raised has
    the structure

         error(signal(<_S_i_g_N_a_m_e>, <_S_i_g_N_u_m>), <_C_o_n_t_e_x_t>)

    One possible usage of  this is, for example, to limit the time spent
    on  proving a goal.  This  requires a little C-code for  setting the
    alarm timer (see chapter 7):

    #include <SWI-Prolog.h>
    #include <unistd.h>

    foreign_t
    pl_alarm(term_t time)
    { double t;

      if ( PL_get_float(time, &t) )
      { alarm((long)(t+0.5));

        PL_succeed;
      }

      PL_fail;
    }

    install_t
    install()
    { PL_register_foreign("alarm", 1, pl_alarm, 0);
    }

    Next,  we can  define the  Prolog below.   This will  run _G_o_a_l  just
    as  once/1, throwing  the exception  error(_s_i_g_n_a_l_(_a_l_r_m_,  ___)_, __) if  a
    timeout occurs.

    :- load_foreign_library(alarm).

    :- on_signal(alrm, _, throw).

    :- module_transparent
            call_with_time_limit/2.

    call_with_time_limit(Goal, MaxTime) :-
            alarm(MaxTime),
            call_cleanup(Goal, _, alarm(0)), !.

    The  signal names are  defined by the  C-Posix standards as  symbols
    of  the form  SIG_<_S_I_G_N_A_M_E>.    The Prolog name  for a  signal is the
    lowercase  version of <_S_I_G_N_A_M_E>.  The predicate current_signal/3 may
    be used to map between names and signals.

    Initially,  some  signals  are  mapped to  throw,  while  all  other
    signals  are default.    The following signals  throw an  exception:
    ill, fpe, segv, pipe, alrm, bus, xcpu, xfsz and vtalrm.


ccuurrrreenntt__ssiiggnnaall((_?_N_a_m_e_, _?_I_d_, _?_H_a_n_d_l_e_r))
    Enumerate  the  currently defined  signal  handling.   _N_a_m_e  is  the
    signal  name,  _I_d is  the numerical  identifier and  _H_a_n_d_l_e_r is  the
    currently defined handler (see on_signal/3).


44..1100..11 NNootteess oonn ssiiggnnaall hhaannddlliinngg

Before  deciding  to deal  with  signals  in  your  application,  please
consider the following:

  o _P_o_r_t_i_b_i_l_i_t_y
    On MS-Windows, the  signal interface is severely limited.  Different
    Unix  brands support  different sets  of signals,  and the  relation
    between signal name and number may vary.

  o _S_a_f_e_t_y
    Signal   handling   is   not   completely  safe   in   the   current
    implementation,  especially  if throw  is used  in combination  with
    external  foreign  code.    The  system  will use  the  C  longjmp()
    construct  to  direct control  to the  innermost PL_next_solution(),
    thus  forcing an external procedure to be abandoned at  an arbitrary
    moment.   Most likely not all SWI-Prologs own foreign code  is (yet)
    safe  too.   For  the multi-threaded  versions this  is even  worse:
    signals can easily violate thread synchronisation consistency.

    The  C-interface described  in  section 7.6.10  provides the  option
    PL_SIGSYNC for registering a signal handler  that delays delivery of
    signals  to a safe point.   Unfortunately this may cause signals  to
    be delayed for a long time if Prolog is executing foreign code.

  o _G_a_r_b_a_g_e _C_o_l_l_e_c_t_i_o_n
    The  garbage  collector  will block  all  signals that  are  handled
    by  Prolog.    While handling  a  signal, the  garbage-collector  is
    disabled.

  o _T_i_m_e _o_f _d_e_l_i_v_e_r_y
    Normally  delivery  is immediate  (or as  defined  by the  operating
    system  used).   Signals are blocked  when the garbage collector  is
    active,  and internally delayed if they occur within in  a `critical
    section'.  The critical sections are generally very short.


44..1111 TThhee ``bblloocckk'' ccoonnttrrooll--ssttrruuccttuurree

The  block/3 predicate  and  friends  have been  introduced  before  ISO
compatible  catch/3  exception  handling  for  compatibility  with  some
Prolog implementation.    The only  feature not covered  by catch/3  and
throw/1 is the posibility  to execute global cuts.  New code  should use
catch/3 and throw/1 to deal with exceptions.


bblloocckk((_+_L_a_b_e_l_, _+_G_o_a_l_, _-_E_x_i_t_V_a_l_u_e))
    Execute  _G_o_a_l in a _b_l_o_c_k.   _L_a_b_e_l is the name  of the block.   _L_a_b_e_l
    is  normally an  atom, but  the system imposes  no type  constraints
    and  may even be a variable.   _E_x_i_t_V_a_l_u_e is normally unified  to the
    second argument of an exit/2 call invoked by _G_o_a_l.


eexxiitt((_+_L_a_b_e_l_, _+_V_a_l_u_e))
    Calling  exit/2 makes the innermost _b_l_o_c_k which _L_a_b_e_l  unifies exit.
    The  block's _E_x_i_t_V_a_l_u_e is unified with  _V_a_l_u_e.  If this  unification
    fails the block fails.


ffaaiill((_+_L_a_b_e_l))
    Calling  fail/1 makes the innermost  _b_l_o_c_k which _L_a_b_e_l unifies  fail
    immediately.  Implemented as

    fail(Label) :- !(Label), fail.


!((_+_L_a_b_e_l))
    Cut  all  choice-points created  since the  entry  of the  innermost
    _b_l_o_c_k which _L_a_b_e_l unifies.


44..1122 DDCCGG GGrraammmmaarr rruulleess

Grammar rules  form a comfortable interface  to _d_i_f_f_e_r_e_n_c_e_-_l_i_s_t_s.   They
are designed  both to support  writing parsers  that build a  parse-tree
from a list as for  generating a flat list from a term.   Unfortunately,
Definite  Clause  Grammar (DCG)  handling  is  not part  of  the  Prolog
standard.   Most Prolog  engines implement DCG,  but the details  differ
slightly.

Grammar rules  look like  ordinary clauses  using -->/2  for  separating
the head  and body rather then  :-/2.   Expanding grammar rules is  done
by expand_term/2, which  adds two additional  argument to each term  for
representing the difference list.   We will illustrate the  behaviour by
defining a rule-set for parsing an integer.

integer(I) -->
        digit(D0),
        digits(D),
        { number_chars(I, [D0|D])
        }.

digits([D|T]) -->
        digit(D), !,
        digits(T).
digits([]) -->
        [].

digit(D) -->
        [D],
        { code_type(D, digit)
        }.

The  body of  a grammar  rule  can contain  three  types of  terms.    A
compound  term interpreted  as a  reference  to a  grammar-rule.    Code
between {...}  is interpreted  as a  reference to  ordinary Prolog  code
and finally,  a list  is interpreted  as a  sequence of literals.    The
Prolog control-constructs (\+/1,  ->/2, ;//2, ,/2  and !/0) can be  used
in grammar rules.

Grammar rule-sets are  called using the builtin predicates phrase/2  and
phrase/3:


pphhrraassee((_+_R_u_l_e_S_e_t_, _+_I_n_p_u_t_L_i_s_t))
    Equivalent to phrase(RuleSet, InputList, []).


pphhrraassee((_+_R_u_l_e_S_e_t_, _+_I_n_p_u_t_L_i_s_t_, _-_R_e_s_t))
    Activate  the rule-set with given name.  `InputList' is the  list of
    tokens to parse,  `Rest' is unified with the remaining tokens if the
    sentence is parsed  correctly.  The example below calls the rule-set
    `integer' defined above.

    ?- phrase(integer(X), "42 times", Rest).

    X = 42
    Rest = [32, 116, 105, 109, 101, 115]


44..1133 DDaattaabbaassee

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
its  derivatives 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
_k_e_y.  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 is faster  than
the mechanisms  described above, but  can only be  used to store  simple
status information like counters, etc.


aabboolliisshh((_:_P_r_e_d_i_c_a_t_e_I_n_d_i_c_a_t_o_r))
    Removes  all clauses of a  predicate with functor _F_u_n_c_t_o_r and  arity
    _A_r_i_t_y  from  the  database.    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.

    According  to the  ISO standard,  abolish/1 can only  be applied  to
    dynamic  procedures.    This is  odd, as  for  dealing with  dynamic
    procedures  there  is  already  retract/1 and  retractall/1.     The
    abolish/1  predicate has been introduced in DEC-10  Prolog precisely
    for dealing with  static procedures.  In SWI-Prolog, abolish/1 works
    on static procedures, unless the prolog flag iso is set to true.

    It  is advised  to use  retractall/1 for  erasing all  clauses of  a
    dynamic predicate.


aabboolliisshh((_+_N_a_m_e_, _+_A_r_i_t_y))
    Same  as abolish(Name/Arity).   The predicate abolish/2 conforms  to
    the Edinburgh standard, while abolish/1 is ISO compliant.


rreeddeeffiinnee__ssyysstteemm__pprreeddiiccaattee((_+_H_e_a_d))
    This  directive  may be  used  both in  module  user and  in  normal
    modules to redefine  any system predicate.  If the system definition
    is  redefined in  module user,  the  new definition  is the  default
    definition  for  all sub-modules.    Otherwise  the redefinition  is
    local  to the module.   The system definition remains in the  module
    system.

    Redefining   system   predicate   facilitates  the   definition   of
    compatibility packages.  Use in other context is discouraged.


rreettrraacctt((_+_T_e_r_m))
    When  _T_e_r_m  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.


rreettrraaccttaallll((_+_H_e_a_d))
    All  facts or  clauses in the  database for  which the _h_e_a_d  unifies
    with _H_e_a_d are removed.


aasssseerrtt((_+_T_e_r_m))
    Assert  a fact or clause in the  database.  _T_e_r_m is asserted  as the
    last fact or clause of the corresponding predicate.


aasssseerrttaa((_+_T_e_r_m))
    Equivalent  to assert/1,  but _T_e_r_m  is asserted as  first clause  or
    fact of the predicate.


aasssseerrttzz((_+_T_e_r_m))
    Equivalent to assert/1.


aasssseerrtt((_+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e))
    Equivalent  to  assert/1, but  _R_e_f_e_r_e_n_c_e is  unified  with a  unique
    reference  to the asserted clause.  This key can later be  used with
    clause/3 or erase/1.


aasssseerrttaa((_+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e))
    Equivalent  to assert/2,  but _T_e_r_m  is asserted as  first clause  or
    fact of the predicate.


aasssseerrttzz((_+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e))
    Equivalent to assert/2.


rreeccoorrddaa((_+_K_e_y_, _+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e))
    Assert  _T_e_r_m  in the  recorded  database  under key  _K_e_y.    _K_e_y  is
    an  integer,  atom or  term.   _R_e_f_e_r_e_n_c_e  is unified  with a  unique
    reference to the record (see erase/1).


rreeccoorrddaa((_+_K_e_y_, _+_T_e_r_m))
    Equivalent to recorda(Key, Value,  _).


rreeccoorrddzz((_+_K_e_y_, _+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e))
    Equivalent to recorda/3, but  puts the _T_e_r_m at the tail of the terms
    recorded under _K_e_y.


rreeccoorrddzz((_+_K_e_y_, _+_T_e_r_m))
    Equivalent to recordz(Key, Value,  _).


rreeccoorrddeedd((_+_K_e_y_, _-_V_a_l_u_e_, _-_R_e_f_e_r_e_n_c_e))
    Unify  _V_a_l_u_e  with the  first  term recorded  under _K_e_y  which  does
    unify.    _R_e_f_e_r_e_n_c_e  is  unified with  the  memory location  of  the
    record.


rreeccoorrddeedd((_+_K_e_y_, _-_V_a_l_u_e))
    Equivalent to recorded(Key, Value,  _).


eerraassee((_+_R_e_f_e_r_e_n_c_e))
    Erase  a  record or  clause from  the  database.   _R_e_f_e_r_e_n_c_e  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.


ffllaagg((_+_K_e_y_, _-_O_l_d_, _+_N_e_w))
    _K_e_y  is an  atom, integer or  term.   Unify _O_l_d  with the old  value
    associated  with _K_e_y.  If the key is used for the first  time _O_l_d is
    unified  with the integer  0.   Then store the  value of _N_e_w,  which
    should  be an integer, float,  atom or arithmetic expression,  under
    _K_e_y.   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, Old, 0),
                Goal,
                   flag(succeeds_n_times, N, N+1),
                fail
            ;   flag(succeeds_n_times, Times, Old)
            ).


44..1133..11 UUppddaattee vviieeww

Traditionally,  Prolog systems  used  the _i_m_m_e_d_i_a_t_e  _u_p_d_a_t_e _v_i_e_w:    new
clauses  became   visible  to   predicates  backtracking  over   dynamic
predicates   immediately   and  retracted   clauses   became   invisible
immediately.

Starting  with SWI-Prolog  3.3.0  we  adhere the  _l_o_g_i_c_a_l  _u_p_d_a_t_e  _v_i_e_w,
where backtrackable predicates that enter the definition  of a predicate
will not  see any changes  (either caused by  assert/1 or retract/1)  to
the  predicate.    This view  is the  ISO  standard, the  most  commonly
used and  the most  `safe'.   Logical  updates are  realised by  keeping
reference-counts on  predicates and  _g_e_n_e_r_a_t_i_o_n information on  clauses.
Each change  to the database  causes an increment  of the generation  of
the database.  Each  goal is tagged with the generation in which  it was
started.  Each  clause is flagged with the generation it was  created as
well as  the generation  it was  erased.   Only  clauses with  `created'
...`erased' interval  that encloses the generation  of the current  goal
are considered visible.


44..1133..22 IInnddeexxiinngg ddaattaabbaasseess

By  default,   SWI-Prolog,  as   most  other  implementations,   indexes
predicates  on their  first argument.    SWI-Prolog  allows indexing  on
other and multiple arguments using the declaration index/1.

For advanced database indexing, it defines hash_term/2:


hhaasshh__tteerrmm((_+_T_e_r_m_, _-_H_a_s_h_K_e_y))
    If  _T_e_r_m is a ground term (see ground/1), _H_a_s_h_K_e_y is unified  with a
    positive integer value that  may be used as a hash-key to the value.
    If  _T_e_r_m is not ground, the predicate succeeds  immediately, leaving
    _H_a_s_h_K_e_y an unbound variable.

    This  predicate  may be  used to  build hash-tables  as  well as  to
    exploit argument-indexing to find complex terms more quickly.

    The  hash-key does not rely on temporary information  like addresses
    of  atoms and may be assumed constant over different  invocations of
    SWI-Prolog.


44..1144 DDeeccllaarriinngg pprreeddiiccaatteess pprrooppeerrttiieess

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.


ddyynnaammiicc _+_N_a_m_e_/_+_A_r_i_t_y_, _._._.
    Informs the interpreter  that the definition of the predicate(s) may
    change  during  execution (using  assert/1 and/or  retract/1).    In
    the  multi-threaded version, the  clauses of dynamic predicates  are
    shared  between the threads.  The  directive thread_local/1 provides
    an  alternative where each threads  has its own clause-list for  the
    predicate.   Dynamic predicates can be turned into static ones using
    compile_predicates/1.


ccoommppiillee__pprreeddiiccaatteess((_:_L_i_s_t_O_f_N_a_m_e_A_r_i_t_y))
    Compile  a list of specified  dynamic predicates (see dynamic/1  and
    assert/1)  into  normal static  predicates.    This call  tells  the
    Prolog  environment  the  definition  will not  change  anymore  and
    further  calls  to assert/1  or retract/1  on  the named  predicates
    raise  a permission error.  This predicate is designed to  deal with
    parts  of the  program that  is generated  at runtime  but does  not
    change during the remainder of the program execution.


mmuullttiiffiillee _+_N_a_m_e_/_+_A_r_i_t_y_, _._._.
    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.


ddiissccoonnttiigguuoouuss _+_N_a_m_e_/_+_A_r_i_t_y_, _._._.
    Informs  the system that the  clauses of the specified  predicate(s)
    might not be together in the source file.  See also style_check/1.


iinnddeexx((_+_H_e_a_d))
    Index  the clauses  of the predicate  with the  same name and  arity
    as  _H_e_a_d  on the  specified arguments.    _H_e_a_d 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 compound  terms are  considered.   Compound terms  are
    indexed  on the combination  of their name and  arity.  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 <_a_r_i_t_y>>= 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  predicates 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).
    ...
    ...


44..1155 EExxaammiinniinngg tthhee pprrooggrraamm


ccuurrrreenntt__aattoomm((_-_A_t_o_m))
    Successively unifies _A_t_o_m with  all atoms known to the system.  Note
    that  current_atom/1 always succeeds if  _A_t_o_m is instantiated to  an
    atom.


ccuurrrreenntt__ffuunnccttoorr((_?_N_a_m_e_, _?_A_r_i_t_y))
    Successively unifies _N_a_m_e  with the name and _A_r_i_t_y with the arity of
    functors known to the system.


ccuurrrreenntt__ffllaagg((_-_F_l_a_g_K_e_y))
    Successively  unifies  _F_l_a_g_K_e_y with  all keys  used  for flags  (see
    flag/3).


ccuurrrreenntt__kkeeyy((_-_K_e_y))
    Successively  unifies  _K_e_y  with  all keys  used  for  records  (see
    recorda/3, etc.).


ccuurrrreenntt__pprreeddiiccaattee((_?_N_a_m_e_, _?_H_e_a_d))
    Successively  unifies _N_a_m_e  with  the name  of predicates  currently
    defined and _H_e_a_d with  the most general term built from _N_a_m_e 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.


ccuurrrreenntt__pprreeddiiccaattee((_:_N_a_m_e_/_A_r_i_t_y))
    ISO   compliant  implementation   of  current_predicate/2.       Un-
    like    current_predicate/2,    the   current   implementation    of
    current_predicate/1  does  not  consider  predicates   that  can  be
    autoloaded `current'.


pprreeddiiccaattee__pprrooppeerrttyy((_?_H_e_a_d_, _?_P_r_o_p_e_r_t_y))
    Succeeds  if _H_e_a_d refers to a predicate that has  property _P_r_o_p_e_r_t_y.
    Can  be used  to test whether  a predicate  has a certain  property,
    obtain  all properties known  for _H_e_a_d,  find all predicates  having
    _p_r_o_p_e_r_t_y  or  even obtaining  all  information available  about  the
    current program.  _P_r_o_p_e_r_t_y is one of:

    iinntteerrpprreetteedd
         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.

    bbuuiilltt__iinn
         Is true  if the predicate  is locked  as a built-in  predicate.
         This implies it  cannot be redefined  in its definition  module
         and it can normally not be seen in the tracer.

    ffoorreeiiggnn
         Is true if the predicate is defined in the C language.

    ddyynnaammiicc
         Is true  if assert/1 and  retract/1 may be  used to modify  the
         predicate.  This property is set using dynamic/1.

    vvoollaattiillee
         If  true, the  clauses  are not  saved  into a  saved-state  by
         qsave_program/[1,2].  This property is set using volatile/1.

    tthhrreeaadd__llooccaall
         If true  (only  possible on  the multi-threaded  version)  each
         thread has its  own clauses for the  predicate.  This  property
         is set using thread_local/1.

    mmuullttiiffiillee
         Is true there  may be multiple  (or no) file providing  clauses
         for the predicate.  This property is set using multifile/1.

    uunnddeeffiinneedd
         Is  true if  a procedure  definition  block for  the  predicate
         exists, but there are no clauses for it and it  is not declared
         dynamic or multifile.  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.

    ttrraannssppaarreenntt
         Is true  if the  predicate  is declared  transparent using  the
         module_transparent/1 declaration.

    eexxppoorrtteedd
         Is true if the predicate  is in the public list of  the context
         module.

    iimmppoorrtteedd__ffrroomm((_M_o_d_u_l_e))
         Is true if  the predicate is  imported into the context  module
         from module _M_o_d_u_l_e.

    iinnddeexxeedd((_H_e_a_d))
         Predicate is indexed (see index/1) according to _H_e_a_d.   _H_e_a_d is
         a term  whose name and  arity are  identical to the  predicate.
         The arguments are unified  with `1' for indexed arguments,  `0'
         otherwise.

    ffiillee((_F_i_l_e_N_a_m_e))
         Unify _F_i_l_e_N_a_m_e with  the name of the  source file in which  the
         predicate is defined.  See also source_file/2.

    lliinnee__ccoouunntt((_L_i_n_e_N_u_m_b_e_r))
         Unify _L_i_n_e_N_u_m_b_e_r with  the line number  of the first clause  of
         the predicate.   Fails if the predicate is not  associated with
         a file.  See also source_file/2.

    nnuummbbeerr__ooff__ccllaauusseess((_C_l_a_u_s_e_C_o_u_n_t))
         Unify _C_l_a_u_s_e_C_o_u_n_t to the number of clauses  associated with the
         predicate.  Fails for foreign predicates.


ddwwiimm__pprreeddiiccaattee((_+_T_e_r_m_, _-_D_w_i_m))
    `Do What I Mean'  (`dwim') support predicate.  _T_e_r_m is a term, which
    name  and arity  are used  as a predicate  specification.   _D_w_i_m  is
    instantiated  with the  most general  term built from  _N_a_m_e and  the
    arity  of a defined predicate  that matches the predicate  specified
    by  _T_e_r_m  in the  `Do What  I Mean'  sense.    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.


ccllaauussee((_?_H_e_a_d_, _?_B_o_d_y))
    Succeeds  when  _H_e_a_d can  be unified  with a  clause  head and  _B_o_d_y
    with  the  corresponding clause  body.    Gives alternative  clauses
    on  backtracking.     For  facts  _B_o_d_y  is  unified  with  the  atom
    _t_r_u_e.   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.


ccllaauussee((_?_H_e_a_d_, _?_B_o_d_y_, _?_R_e_f_e_r_e_n_c_e))
    Equivalent  to  clause/2,   but  unifies  _R_e_f_e_r_e_n_c_e  with  a  unique
    reference to the  clause (see also assert/2, erase/1).  If _R_e_f_e_r_e_n_c_e
    is  instantiated to a reference the  clause's head and body will  be
    unified with  _H_e_a_d and _B_o_d_y.


nntthh__ccllaauussee((_?_P_r_e_d_, _?_I_n_d_e_x_, _?_R_e_f_e_r_e_n_c_e))
    Provides  access to  the clauses  of a predicate  using their  index
    number.    Counting  starts at  1.   If  _R_e_f_e_r_e_n_c_e  is specified  it
    unifies  _P_r_e_d with the  most general term  with the same  name/arity
    as  the predicate  and _I_n_d_e_x  with the index-number  of the  clause.
    Otherwise  the name  and arity  of _P_r_e_d  are used  to determine  the
    predicate.    If _I_n_d_e_x is  provided _R_e_f_e_r_e_n_c_e  will be unified  with
    the  clause  reference.   If  _I_n_d_e_x  is unbound,  backtracking  will
    yield  both the  indices and the  references of  all clauses of  the
    predicate.  The following example finds the 2nd clause of member/2:

    ?- nth_clause(member(_,_), 2, Ref), clause(Head, Body, Ref).

    Ref = 160088
    Head = system : member(G575, [G578|G579])
    Body = member(G575, G579)


ccllaauussee__pprrooppeerrttyy((_+_C_l_a_u_s_e_R_e_f_, _-_P_r_o_p_e_r_t_y))
    Queries  properties  of   a  clause.     _C_l_a_u_s_e_R_e_f  is  a  reference
    to   a   clause   as   produced   by   clause/3,   nth_clause/3   or
    prolog_frame_attribute/3.  _P_r_o_p_e_r_t_y is one of the following:

    ffiillee((_F_i_l_e_N_a_m_e))
         Unify _F_i_l_e_N_a_m_e with  the name of the  source file in which  the
         clause is defined.  Fails if the clause is not  associated to a
         file.

    lliinnee__ccoouunntt((_L_i_n_e_N_u_m_b_e_r))
         Unify _L_i_n_e_N_u_m_b_e_r with the line number of the clause.   Fails if
         the clause is not associated to a file.

    ffaacctt
         True if the clause has no body.

    eerraasseedd
         True if  the  clause has  been erased,  but  not yet  reclaimed
         because it is referenced.


44..1166 IInnppuutt aanndd oouuttppuutt

SWI-Prolog provides two  different packages for input  and output.   The
native  I/O system  is  based on  the  ISO standard  predicates  open/3,
close/1 and  friends.   Being more  widely portable  and equiped with  a
clearer and  more robust specification,  new code  is encouraged to  use
these predicates for manipulation of I/O streams.

Section 4.16.2  describes tell/1,  see/1 and friends,  providing I/O  in
the spirit  of the outdated  Edinburgh standard.   These predicates  are
layered  on  top of  the  ISO  predicates.    Both  packages  are  fully
integrated; the user may switch freely between them.


44..1166..11 IISSOO IInnppuutt aanndd OOuuttppuutt SSttrreeaammss

The  predicates described  in this  section provide  ISO compliant  I/O,
where streams are  explicitly 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.

This schema  is not  vulnerable to  filename and  stream ambiguities  as
well as changes  to the working directory.   New code is adviced to  use
these predicates to manage input and output streams.


ooppeenn((_+_S_r_c_D_e_s_t_, _+_M_o_d_e_, _-_S_t_r_e_a_m_, _+_O_p_t_i_o_n_s))
    ISO  compliant predicate  to open  a stream.   _S_r_c_D_e_s  is either  an
    atom, specifying a  Unix file, or a term `pipe(Command)', like see/1
    and  tell/1.  _M_o_d_e is  one of read, write,  append or update.   Mode
    append  opens the file for writing, positioning the  file-pointer at
    the  end.  Mode update  opens the file for writing,  positioning the
    file-pointer  at the  beginning of the  file without truncating  the
    file.  _S_t_r_e_a_m is  either a variable, in which case it is bound to an
    integer identifying the stream,  or an atom, in which case this atom
    will  be the stream  identifier.  The  _O_p_t_i_o_n_s list can contain  the
    following options:

    ttyyppee((_T_y_p_e))
         Using type text (default), Prolog will write a  text-file in an
         operating-system compatible way.   Using type binary the  bytes
         will be read  or written without any  translation.  Note  there
         is no difference between the two on Unix systems.

    aalliiaass((_A_t_o_m))
         Gives the  stream a name.   Below  is an example.   Be  careful
         with  this  option  as stream-names  are  global.     See  also
         set_stream/2.

         ?- open(data, read, Fd, [alias(input)]).

                 ...,
                 read(input, Term),
                 ...

    eeooff__aaccttiioonn((_A_c_t_i_o_n))
         Defines  what  happens  if the  end  of  the  input  stream  is
         reached.   Action eof_code makes get0/1  and friends return  -1
         and read/1 and friends return the atom end_of_file.  Repetitive
         reading keeps yielding the  same result.  Action error  is like
         eof_code, but repetitive  reading will  raise an error.    With
         action reset,  Prolog will  examine the file  again and  return
         more data if the file has grown.

    bbuuffffeerr((_B_u_f_f_e_r_i_n_g))
         Defines output  buffering.    The atom  full (default)  defines
         full buffering, line buffering  by line, and false implies  the
         stream is  fully unbuffered.   Smaller  buffering is useful  if
         another process or the user is waiting for the output  as it is
         being produced.   See also flush_output/[0,1].  This option  is
         not an ISO option.

    cclloossee__oonn__aabboorrtt((_B_o_o_l))
         If  true (default),  the  stream is  closed  on an  abort  (see
         abort/0).   If  false, the  stream is  not closed.    If it  is
         an output  stream,  it will  be flushed  however.   Useful  for
         logfiles and if  the stream is  associated to a process  (using
         the pipe/1 construct).

    lloocckk((_L_o_c_k_i_n_g_M_o_d_e))
         Try to obtain a lock on the open file.  Default  is none, which
         does not lock the file.   The value read or shared  means other
         processes may  read the  file, but  not write  it.   The  value
         write or  exclusive means no  other process  may read or  write
         the file.

         Locks are  acquired through  the POSIX  function fcntl()  using
         the command F_SETLKW, which makes  a blocked call wait for  the
         lock to  be  released.    Please note  that fcntl()  locks  are
         _a_d_v_i_s_o_r_y and therefore  only other applications using the  same
         advisory locks  honour your  lock.   As there  are many  issues
         around locking  in  Unix, expecially  related  to NFS  (network
         file  system), please  study  the  fcntl() manual  page  before
         trusting your locks!

         The lock option is a SWI-Prolog extension.

    The  option reposition is not supported in SWI-Prolog.   All streams
    connected to a file may be repositioned.


ooppeenn((_+_S_r_c_D_e_s_t_, _+_M_o_d_e_, _?_S_t_r_e_a_m))
    Equivalent to open/4 with an empty option-list.


ooppeenn__nnuullll__ssttrreeaamm((_?_S_t_r_e_a_m))
    Open  a stream that produces no output.  All counting  functions are
    enabled  on such a stream.   An attempt  to read from a  null-stream
    will  immediately signal  end-of-file.   Similar to Unix  /dev/null.
    _S_t_r_e_a_m can be an atom, giving the null-stream an alias name.


cclloossee((_+_S_t_r_e_a_m))
    Close the specified stream.   If _S_t_r_e_a_m 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.


cclloossee((_+_S_t_r_e_a_m_, _+_O_p_t_i_o_n_s))
    Provides  close(_S_t_r_e_a_m_, _[_f_o_r_c_e_(_t_r_u_e_)_]) as the  only option.   Called
    this  way, any resource error  (such as write-errors while  flushing
    the output buffer) are ignored.


ssttrreeaamm__pprrooppeerrttyy((_?_S_t_r_e_a_m_, _?_S_t_r_e_a_m_P_r_o_p_e_r_t_y))
    ISO  compatible predicate for querying  status of open I/O  streams.
    _S_t_r_e_a_m_P_r_o_p_e_r_t_y is one of:

    ffiillee__nnaammee((_A_t_o_m))
         If _S_t_r_e_a_m is  associated to a file,  unify _A_t_o_m to the name  of
         this file.

    mmooddee((_I_O_M_o_d_e))
         Unify  _I_O_M_o_d_e to  the  mode given  to  open/4 for  opening  the
         stream.   Values are:  read,  write, append and the  SWI-Prolog
         extension update.

    iinnppuutt
         True if _S_t_r_e_a_m has mode read.

    oouuttppuutt
         True if _S_t_r_e_a_m has mode write, append or update.

    aalliiaass((_A_t_o_m))
         If _A_t_o_m is bound,  test of the stream has the  specified alias.
         Otherwise unify _A_t_o_m with the first alias of the stream.

    ppoossiittiioonn((_T_e_r_m))
         Unify  _T_e_r_m  with the  current  stream-position.     A  stream-
         position  is  a  term   of  format  $stream_position(_C_h_a_r_I_n_d_e_x_,
         _L_i_n_e_N_o_, _L_i_n_e_P_o_s).  See also set_stream_position/2.

    eenndd__ooff__ssttrreeaamm((_E))
         If _S_t_r_e_a_m is  an input stream,  unify _E with  one of the  atoms
         not, at or past.  See also at_end_of_stream/[0,1].

    eeooff__aaccttiioonn((_A))
         Unify _A with one of  eof_code,  reset or error.  See  open/4 for
         details.

    rreeppoossiittiioonn((_B_o_o_l))
         Unify _B_o_o_l  with _t_r_u_e  if  the position  of the  stream can  be
         set (see seek/4).   It  is assumed the  position can be set  if
         the stream  has a  _s_e_e_k_-_f_u_n_c_t_i_o_n and is  not based  on a  POSIX
         file-descriptor that is not associated to a regular file.

    ttyyppee((_T))
         Unify _B_o_o_l with text or binary.

    ffiillee__nnoo((_I_n_t_e_g_e_r))
         If  the stream  is  associated  with a  POSIX  file-descriptor,
         unify  _I_n_t_e_g_e_r  with   the  descriptor  number.      SWI-Prolog
         extension used  primarily  for integration  with foreign  code.
         See also Sfileno() from SWI-Stream.h.

    bbuuffffeerr((_B_u_f_f_e_r_i_n_g))
         SWI-Prolog  extension  to query  the  buffering  mode  of  this
         stream.   _B_u_f_f_e_r_i_n_g is one of  full, line or  false.  See  also
         open/4.


ccuurrrreenntt__ssttrreeaamm((_?_O_b_j_e_c_t_, _?_M_o_d_e_, _?_S_t_r_e_a_m))
    The  predicate current_stream/3 is  used to access  the status of  a
    stream as well as  to generate all open streams.  _O_b_j_e_c_t is the name
    of the file opened  if the stream refers to an open file, an integer
    file-descriptor  if  the  stream  encapsulates  an  operating-system
    stream  or the atom  [] if the stream  refers to some other  object.
    _M_o_d_e is one of read or write.


sseett__ssttrreeaamm__ppoossiittiioonn((_+_S_t_r_e_a_m_, _+_P_o_s))
    Set  the  current  position  of _S_t_r_e_a_m  to  _P_o_s.    _P_o_s  is  a  term
    as  returned by stream_property/2 using the position(_P_o_s)  property.
    See also seek/4.


sseeeekk((_+_S_t_r_e_a_m_, _+_O_f_f_s_e_t_, _+_M_e_t_h_o_d_, _-_N_e_w_L_o_c_a_t_i_o_n))
    Reposition the current point  of the given _S_t_r_e_a_m.  _M_e_t_h_o_d is one of
    bof,  _c_u_r_r_e_n_t or _e_o_f, indicating positioning relative to  the start,
    current  point or  end of  the underlying  object.   _N_e_w_L_o_c_a_t_i_o_n  is
    unified with the new offset, relative to the start of the stream.

    If  the seek  modifies the  current  location, the  line number  and
    character position in the line are set to 0.

    If  the stream cannot be repostioned, a reposition error  is raised.
    The  predicate seek/4 is  compatible to  Quintus Prolog, though  the
    error  conditions  and  signalling  is  ISO compliant.     See  also
    stream_property/2 and set_stream_position/2.


sseett__ssttrreeaamm((_+_S_t_r_e_a_m_, _+_A_t_t_r_i_b_u_t_e))
    Modify an attribute  of an existing stream.  _A_t_t_r_i_b_u_t_e specifies the
    stream property to set.  See also stream_property/2 and open/4.

    aalliiaass((_A_l_i_a_s_N_a_m_e))
         Set the alias  of an already created  stream.  If _A_l_i_a_s_N_a_m_e  is
         the name of  one of the standard  streams is used, this  stream
         is rebound.  Thus,  set_stream(S, current_input)is the  same as
         set_input/1 and by setting the alias of a stream to user_input,
         etc. all  user terminal input is  read from this  stream.   See
         also interactor/0.

    bbuuffffeerr((_B_u_f_f_e_r_i_n_g))
         Set  the   buffering  mode  of   an  already  created   stream.
         Buffering is one of full, line or false.

    eeooff__aaccttiioonn((_A_c_t_i_o_n))
         Set end-of-file handling to one of eof_code, reset or error.

    cclloossee__oonn__aabboorrtt((_B_o_o_l))
         Determine whether or not the  stream is closed by abort/0.   By
         default streams are closed.

    ttiimmeeoouutt((_S_e_c_o_n_d_s))
         This option can be  used to make streams generate  an exception
         if it  takes longer than  _S_e_c_o_n_d_s before  any new data  arrives
         at  the  stream.    The  value  _i_n_f_i_n_i_t_e  (default)  makes  the
         stream block  indefinitely.   Like wait_for_input/3, this  call
         only  applies  to streams  that  support  the  select()  system
         call.   For  further information  about  timeout handling,  see
         wait_for_input/3.  The exception is of the form

             error(timeout_error_(_r_e_a_d_, _S_t_r_e_a_m_)_, __)

    rreeccoorrdd__ppoossiittiioonn((_B_o_o_l))
         Do/do  not  record   the  line-count  and  line-position   (see
         line_count/2 and line_position/2).

    ffiillee__nnaammee((_F_i_l_e_N_a_m_e))
         Set the file name associated to this stream.  This  call can be
         used to set the file for error-locations  if _S_t_r_e_a_m corresponds
         to _F_i_l_e_N_a_m_e and  is not optained  by opening the file  directly
         but, for example, through a network service.


44..1166..22 EEddiinnbbuurrgghh--ssttyyllee II//OO

The  package for  implicit  input  and output  destination  is  (almost)
compatible to Edinburgh  DEC-10 and C-Prolog.   The reading and  writing
predicates  refer to  resp.    the  _c_u_r_r_e_n_t  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  streams  current value  can  be
obtained using telling/1 for output- and seeing/1 for input streams.

Source  and   destination  are   either  a  file,   user,   or  a   term
`pipe(_C_o_m_m_a_n_d)'.  The reserved stream name user refers  to the terminal.
In the predicate descriptions below we will  call the source/destination
argument  `_S_r_c_D_e_s_t'.    Below are  some examples  of  source/destination
specifications.

         ?- see(data).        % Start reading from file `data'.
         ?- tell(user).       % Start writing to the terminal.
         ?- tell(pipe(lpr)).  % Start writing to the printer.

Another example  of using  the pipe/1 construct  is shown  below.   Note
that  the  pipe/1  construct  is  not  part  of  Prolog's  standard  I/O
repertoire.

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

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

CCoommppaattiibbiilliittyy nnootteess

Unlike Edinburgh  Prolog systems, telling/1  and seeing/1 do not  return
the filename of the current input/output, but  the stream-identifier, to
ensure the design pattern below works under all circumstances.

        ...,
        telling(Old), tell(x),
        ...,
        told, tell(Old),
        ...,

The predicates tell/1 and see/1 first check for  user, the pipe(_c_o_m_m_a_n_d)
and  a stream-handle.    Otherwise, if  the argument  is an  atom it  is
first compared  to open streams  associated to a  file with _e_x_a_c_t_l_y  the
same name.   If  such a stream,  created using  tell/1 or see/1  exists,
output (input) is switch to the open stream.  Otherwise  a file with the
specified name is opened.

The  behaviour  is  compatible  to  Edinburgh  Prolog.     This  is  not
without problems.  Changing directory, non-file  streams, multiple names
referring to  the same file  easily lead to unexpected  behaviour.   New
code,  especially when managing  multiple I/O  channals should  consider
using the ISO I/O predicates defined in section 4.16.1.


sseeee((_+_S_r_c_D_e_s_t))
    Open  _S_r_c_D_e_s_t  for  reading  and  make it  the  current  input  (see
    set_input/1).    If  _S_r_c_D_e_s_t is  a  stream-handle, just  makes  this
    stream  the current input.   See the introduction of section  4.16.2
    for details.


tteellll((_+_S_r_c_D_e_s_t))
    Open  _S_r_c_D_e_s_t  for  writing and  make  it  the current  output  (see
    set_output/1).    If _S_r_c_D_e_s_t  is a  stream-handle,  just makes  this
    stream  the current output.  See the introduction of  section 4.16.2
    for details.


aappppeenndd((_+_F_i_l_e))
    Similar  to tell/1,  but positions the  file pointer  at the end  of
    _F_i_l_e  rather than truncating an existing  file.  The pipe  construct
    is not accepted by this predicate.


sseeeeiinngg((_?_S_r_c_D_e_s_t))
    Same  as  current_input/1,  except  that user  is  returned  if  the
    current  input  is the  stream user_input  to improve  compatibility
    with   traditional   Edinburgh   I/O.  See   the   introduction   of
    section 4.16.2 for details.


tteelllliinngg((_?_S_r_c_D_e_s_t))
    Same   as  current_output/1,  except   that  user  is  returned   if
    the   current   output  is   the  stream   user_output  to   improve
    compatibility  with traditional Edinburgh I/O. See  the introduction
    of section 4.16.2 for details.


sseeeenn
    Close  the  current input  stream.   The  new  input stream  becomes
    _u_s_e_r___i_n_p_u_t.


ttoolldd
    Close  the current  output stream.   The  new output stream  becomes
    _u_s_e_r___o_u_t_p_u_t.


44..1166..33 SSwwiittcchhiinngg BBeettwweeeenn EEddiinnbbuurrgghh aanndd IISSOO II//OO

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

sseett__iinnppuutt((_+_S_t_r_e_a_m))
    Set  the current input  stream to become _S_t_r_e_a_m.   Thus,  open(file,
    read, Stream), set_input(Stream) is equivalent to see(file).


sseett__oouuttppuutt((_+_S_t_r_e_a_m))
    Set the current output stream to become _S_t_r_e_a_m.


ccuurrrreenntt__iinnppuutt((_-_S_t_r_e_a_m))
    Get  the current input stream.   Useful to get access to  the status
    predicates associated with streams.


ccuurrrreenntt__oouuttppuutt((_-_S_t_r_e_a_m))
    Get the current output stream.


44..1177 SSttaattuuss ooff ssttrreeaammss


wwaaiitt__ffoorr__iinnppuutt((_+_L_i_s_t_O_f_S_t_r_e_a_m_s_, _-_R_e_a_d_y_L_i_s_t_, _+_T_i_m_e_O_u_t))
    Wait  for input on  one of the  streams in _L_i_s_t_O_f_S_t_r_e_a_m_s and  return
    a  list  of  streams  on  which input  is  available  in  _R_e_a_d_y_L_i_s_t.
    wait_for_input/3 waits  for at most  _T_i_m_e_O_u_t seconds.   _T_i_m_e_o_u_t  may
    be  specified as  a floating  point number to  specify fractions  of
    a  second.    If  _T_i_m_e_o_u_t  equals  infinite,  wait_for_input/3 waits
    indefinitely.

    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 explicitly opened  second
    terminal.  On return, _I_n_p_u_t_s may hold user or _P_4 or both.

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

    This  predicate  relies  on  the select()  call  on  most  operating
    systems.  On  Unix this call is implemented for any stream referring
    to  a file-handle,  which implies  all OS-based  streams:   sockets,
    terminals,  pipes, etc.   On non-Unix systems select() is  generally
    only  implemented for socket-based  streams.   See also socket  from
    the clib package.

    Note  that wait_for_input/3 returns streams that have data  waiting.
    This  does not mean you can, for example, call read/2 on  the stream
    without  blocking as the stream might hold an incomplete term.   The
    predicate  set_stream/2 using  the  option timeout(_S_e_c_o_n_d_s)  can  be
    used  to  make the  stream  generate an  exception  if no  new  data
    arrives  for within the timeout.  Suppose two  processes communicate
    by  exchanging Prolog terms.   The  following code makes the  server
    immune for clients that write an incomplete term:

            ...,
            tcp_accept(Server, Socket, _Peer),
            tcp_open(Socket, In, Out),
            set_stream(In, timeout(10)),
            catch(read(In, Term), _, (close(Out), close(In), fail)),
            ...,


cchhaarraacctteerr__ccoouunntt((_+_S_t_r_e_a_m_, _-_C_o_u_n_t))
    Unify  _C_o_u_n_t 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.


lliinnee__ccoouunntt((_+_S_t_r_e_a_m_, _-_C_o_u_n_t))
    Unify  _C_o_u_n_t with the  number of  lines read or  written.   Counting
    starts at 1.


lliinnee__ppoossiittiioonn((_+_S_t_r_e_a_m_, _-_C_o_u_n_t))
    Unify  _C_o_u_n_t 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.


ffiilleeeerrrroorrss((_-_O_l_d_, _+_N_e_w))
    Define error behaviour  on errors when opening a file for reading or
    writing.   Valid values are the  atoms on (default) and off.   First
    _O_l_d  is unified with the current value.   Then the new value  is set
    to _N_e_w.

    With  the introduction of exception-handling,  it is adviced to  use
    catch/3  to catch possibly  file-errors and act  accordingly.   Note
    that if _f_i_l_e_e_r_r_o_r_s is off, _n_o exception is generated.


44..1188 PPrriimmiittiivvee cchhaarraacctteerr II//OO

See section 4.2 for an overview of supported character representations.


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

nnll((_+_S_t_r_e_a_m))
    Write a newline to _S_t_r_e_a_m.


ppuutt((_+_C_h_a_r))
    Write  _C_h_a_r  to  the  current  output  stream,  _C_h_a_r  is  either  an
    integer-expression  evaluating to  a character code  (0=<_C_h_a_r=< 255)
    or an atom of one character.


ppuutt((_+_S_t_r_e_a_m_, _+_C_h_a_r))
    Write _C_h_a_r to _S_t_r_e_a_m.


ppuutt__bbyyttee((_+_B_y_t_e))
    Alias for put/1.


ppuutt__bbyyttee((_+_S_t_r_e_a_m_, _+_B_y_t_e))
    Alias for put/2


ppuutt__cchhaarr((_+_C_h_a_r))
    Alias for put/1.


ppuutt__cchhaarr((_+_S_t_r_e_a_m_, _+_C_h_a_r))
    Alias for put/2


ppuutt__ccooddee((_+_C_o_d_e))
    Alias for put/1.


ppuutt__ccooddee((_+_S_t_r_e_a_m_, _+_C_o_d_e))
    Alias for put/2


ttaabb((_+_A_m_o_u_n_t))
    Writes  _A_m_o_u_n_t  spaces  on  the  current  output  stream.     _A_m_o_u_n_t
    should  be an expression that  evaluates to a positive integer  (see
    section 4.26).


ttaabb((_+_S_t_r_e_a_m_, _+_A_m_o_u_n_t))
    Writes _A_m_o_u_n_t spaces to _S_t_r_e_a_m.


fflluusshh__oouuttppuutt
    Flush  pending output on current  output stream.   flush_output/0 is
    automatically  generated by  read/1 and derivatives  if the  current
    input stream is user and the cursor is not at the left margin.


fflluusshh__oouuttppuutt((_+_S_t_r_e_a_m))
    Flush  output on the specified stream.  The stream must be  open for
    writing.


ttttyyfflluusshh
    Flush pending output on stream _u_s_e_r.  See also flush_output/[0,1].


ggeett__bbyyttee((_-_B_y_t_e))
    Read the current input  stream and unify the next byte with _B_y_t_e (an
    integer between 0 and 255.  _B_y_t_e is unified with -1 on end of file.


ggeett__bbyyttee((_+_S_t_r_e_a_m_, _-_B_y_t_e))
    Read the next byte from _S_t_r_e_a_m.


ggeett__ccooddee((_-_C_o_d_e))
    Read  the current  input stream  and unify _C_o_d_e  with the  character
    code  of the  next character.   _C_o_d_e is  unified with  -1 on end  of
    file.  See also get_char/1.


ggeett__ccooddee((_+_S_t_r_e_a_m_, _-_C_o_d_e))
    Read the next character-code from _S_t_r_e_a_m.


ggeett__cchhaarr((_-_C_h_a_r))
    Read  the  current  input  stream  and  unify  _C_h_a_r  with  the  next
    character  as a  one-character-atom.   See  also atom_chars/2.    On
    end-of-file, _C_h_a_r is unified to the atom end_of_file.


ggeett__cchhaarr((_+_S_t_r_e_a_m_, _-_C_h_a_r))
    Unify   _C_h_a_r   with   the   next  character   from   _S_t_r_e_a_m   as   a
    one-character-atom.  See also get_char/2, get_byte/2 and get_code/2.


ggeett00((_-_C_h_a_r))
    Edinburgh version of the ISO get_byte/1 predicate.


ggeett00((_+_S_t_r_e_a_m_, _-_C_h_a_r))
    Edinburgh version of the ISO get_byte/2 predicate.


ggeett((_-_C_h_a_r))
    Read  the  current   input  stream  and  unify  the  next  non-blank
    character with _C_h_a_r.  _C_h_a_r is unified with -1 on end of file.


ggeett((_+_S_t_r_e_a_m_, _-_C_h_a_r))
    Read the next non-blank character from _S_t_r_e_a_m.


ppeeeekk__bbyyttee((_-_B_y_t_e))
    Reads  the next input byte  like get_byte/1, but does not remove  it
    from the input stream.


ppeeeekk__bbyyttee((_+_S_t_r_e_a_m_, _-_B_y_t_e))
    Reads  the next input byte  like get_byte/2, but does not remove  it
    from the stream.


ppeeeekk__ccooddee((_-_C_o_d_e))
    Reads  the next input code  like get_code/1, but does not remove  it
    from the input stream.


ppeeeekk__ccooddee((_+_S_t_r_e_a_m_, _-_C_o_d_e))
    Reads  the next input code  like get_code/2, but does not remove  it
    from the stream.


ppeeeekk__cchhaarr((_-_C_h_a_r))
    Reads the  next input character like get_char/1,  but does not remove
    it from the input stream.


ppeeeekk__cchhaarr((_+_S_t_r_e_a_m_, _-_C_h_a_r))
    Reads the  next input character like get_char/2,  but does not remove
    it from the stream.


sskkiipp((_+_C_h_a_r))
    Read the input until  _C_h_a_r or the end of the file is encountered.  A
    subsequent call to get0/1 will read the first character after _C_h_a_r.


sskkiipp((_+_S_t_r_e_a_m_, _+_C_h_a_r))
    Skip input (as skip/1) on _S_t_r_e_a_m.


ggeett__ssiinnggllee__cchhaarr((_-_C_h_a_r))
    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 option this predicate reads an
    entire  line of input and  returns the first non-blank character  on
    this  line, or the character code of the newline (10) if  the entire
    line consisted of blank characters.


aatt__eenndd__ooff__ssttrreeaamm
    Succeeds  after the last character  of the current input stream  has
    been  read.    Also succeeds  if  there is  no valid  current  input
    stream.


aatt__eenndd__ooff__ssttrreeaamm((_+_S_t_r_e_a_m))
    Succeeds  after the last character of  the named stream is read,  or
    _S_t_r_e_a_m is not a  valid input stream.  The end-of-stream test is only
    available  on buffered  input stream (unbuffered  input streams  are
    rarely used, see open/4).


ccooppyy__ssttrreeaamm__ddaattaa((_+_S_t_r_e_a_m_I_n_, _+_S_t_r_e_a_m_O_u_t_, _+_L_e_n))
    Copy _L_e_n bytes from stream _S_t_r_e_a_m_I_n to _S_t_r_e_a_m_O_u_t.


ccooppyy__ssttrreeaamm__ddaattaa((_+_S_t_r_e_a_m_I_n_, _+_S_t_r_e_a_m_O_u_t))
    Copy data all (remaining) data from stream _S_t_r_e_a_m_I_n to _S_t_r_e_a_m_O_u_t.


44..1199 TTeerrmm rreeaaddiinngg aanndd wwrriittiinngg

This section  describes the basic term  reading and writing  predicates.
The  predicates  term_to_atom/2,  atom_to_term/3  and  sformat/3  provide
means  for translating  atoms and  strings  to terms.    The  predicates
format/[1,2] and writef/2 provide formatted output.

There are  two ways  to manipulate  the output  format.   The  predicate
print/[1,2]  may  be  programmed  using  portray/1.      The  format  of
floating point  numbers may  be manipulated  using the  prolog_flag  (see
current_prolog_flag/2) float_format.

Reading  is  sensitive   to  the  prolog_flag  character_escapes,   which
controls  the interpretation  of the  \ character  in  quoted atoms  and
strings.


wwrriittee__tteerrmm((_+_T_e_r_m_, _+_O_p_t_i_o_n_s))
    The  predicate  write_term/2  is  the generic  form  of  all  Prolog
    term-write predicates.  Valid options are:

    qquuootteedd((_B_o_o_l))
         If true, atoms and  functors that needs quotes will  be quoted.
         The default is false.

    bbaacckkqquuootteedd__ssttrriinngg((_B_o_o_l))
         If true,  write a string  object (see  section 4.23) as  `...`.
         The default depends on the prolog flag with the same name.

    cchhaarraacctteerr__eessccaappeess((_B_o_o_l))
         If true,  and  quoted(_t_r_u_e) is  active,  special characters  in
         quoted atoms and  strings are emitted as ISO  escape-sequences.
         Default is taken from the reference module (see below).

    iiggnnoorree__ooppss((_B_o_o_l))
         If true, the generic term-representation (<_f_u_n_c_t_o_r>(<_a_r_g_s> ...))
         will be  used for  all terms,  Otherwise (default),  operators,
         list-notation and  {}/1  will be  written using  their  special
         syntax.

    mmoodduullee((_M_o_d_u_l_e))
         Define the reference module  (default user).  This  defines the
         default value for  the character_escapes option as well as  the
         operator definitions to use.  See also op/3.

    nnuummbbeerrvvaarrss((_B_o_o_l))
         If true, terms  of the format $VAR(N), where  <_N> is a positive
         integer, will be  written as a variable  name.  The default  is
         false.

    ppoorrttrraayy((_B_o_o_l))
         If true, the  hook portray/1 is  called before printing a  term
         that is not  a variable.   If portray/1  succeeds, the term  is
         considered printed.  See  also print/1.  The default  is false.
         This option is an extension to the ISO write_term options.

    mmaaxx__ddeepptthh((_I_n_t_e_g_e_r))
         If the term is nested deeper than _I_n_t_e_g_e_r,  print the remainder
         as eclipse (...).  A 0 (zero) value (default)  imposes no depth
         limit.  This option  also delimits the number of printed  for a
         list.  Example:

         ?- write_term(a(s(s(s(s(0)))), [a,b,c,d,e,f]), [max_depth(3)]).
         a(s(s(...)), [a, b|...])

         Yes

         Used   by  the   toplevel   and   debugger  to   limit   screen
         output.   See also the  prolog-flags toplevel_print_options  and
         debugger_print_options.


wwrriittee__tteerrmm((_+_S_t_r_e_a_m_, _+_T_e_r_m_, _+_O_p_t_i_o_n_s))
    As  write_term/2,  but output  is sent  to  _S_t_r_e_a_m rather  than  the
    current output.


wwrriittee__ccaannoonniiccaall((_+_T_e_r_m))
    Write  _T_e_r_m  on  the current  output  stream using  standard  paren-
    thesised  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.      Equivalent  to  write_term/2  using  the  options
    ignore_ops and quoted.


wwrriittee__ccaannoonniiccaall((_+_S_t_r_e_a_m_, _+_T_e_r_m))
    Write _T_e_r_m in canonical form on _S_t_r_e_a_m.


wwrriittee((_+_T_e_r_m))
    Write  _T_e_r_m  to the  current output,  using  brackets and  operators
    where  appropriate.     See  current_prolog_flag/2  for  controlling
    floating point output format.


wwrriittee((_+_S_t_r_e_a_m_, _+_T_e_r_m))
    Write _T_e_r_m to _S_t_r_e_a_m.


wwrriitteeqq((_+_T_e_r_m))
    Write  _T_e_r_m  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.


wwrriitteeqq((_+_S_t_r_e_a_m_, _+_T_e_r_m))
    Write _T_e_r_m to _S_t_r_e_a_m, inserting quotes.


pprriinntt((_+_T_e_r_m))
    Prints  _T_e_r_m on the  current output stream  similar to write/1,  but
    for each (sub)term  of _T_e_r_m first the dynamic predicate portray/1 is
    called.   If this predicate succeeds _p_r_i_n_t assumes the (sub)term has
    been written.  This allows for user defined term writing.


pprriinntt((_+_S_t_r_e_a_m_, _+_T_e_r_m))
    Print _T_e_r_m to _S_t_r_e_a_m.


ppoorrttrraayy((_+_T_e_r_m))
    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.


rreeaadd((_-_T_e_r_m))
    Read  the next Prolog term from  the current input stream and  unify
    it  with _T_e_r_m.  On a syntax error read/1 displays an  error message,
    attempts  to  skip  the erroneous  term  and  fails.    On  reaching
    end-of-file _T_e_r_m is unified with the atom end_of_file.


rreeaadd((_+_S_t_r_e_a_m_, _-_T_e_r_m))
    Read _T_e_r_m from _S_t_r_e_a_m.


rreeaadd__ccllaauussee((_-_T_e_r_m))
    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).  New  code should
    use read_term/2 with the option singletons(warning).


rreeaadd__ccllaauussee((_+_S_t_r_e_a_m_, _-_T_e_r_m))
    Read a clause from _S_t_r_e_a_m.  See read_clause/1.


rreeaadd__tteerrmm((_-_T_e_r_m_, _+_O_p_t_i_o_n_s))
    Read  a term from the current  input stream and unify the term  with
    _T_e_r_m.    The  reading is  controlled  by options  from the  list  of
    _O_p_t_i_o_n_s.   If this list is  empty, the behaviour is the same  as for
    read/1.   The options are upward compatible to Quintus Prolog.   The
    argument order is  according to the ISO standard.  Syntax-errors are
    always reported using exception-handling (see catch/3).  Options:

    vvaarriiaabblleess((_V_a_r_s))
         Unify  _V_a_r_s  with a  list  of  variables  in the  term.     The
         variables appear in  the order they have  been read.  See  also
         free_variables/2.  (ISO).

    vvaarriiaabbllee__nnaammeess((_V_a_r_s))
         Unify _V_a_r_s with a list  of `_N_a_m_e = _V_a_r', where _N_a_m_e is  an atom
         describing the variable name and _V_a_r is a  variable that shares
         with the corresponding variable in _T_e_r_m.  (ISO).

    ssiinngglleettoonnss((_V_a_r_s))
         As variable_names,  but only  reports  the variables  occurring
         only  once in  the  _T_e_r_m read.     Variables starting  with  an
         underscore (`_') are not included in this list.  (ISO).

    ssyynnttaaxx__eerrrroorrss((_A_t_o_m))
         If error  (default),  throw and  exception on  a syntax  error.
         Other values  are fail, which  causes a  message to be  printed
         using print_message/2, after which  the predicate fails,  quiet
         which causes  the predicate  to fail silently  and dec10  which
         causes syntax errors to be printed, after which read_term/[2,3]
         continues reading the next term.   Using dec10, read_term/[2,3]
         never fails.  (Quintus, SICStus).

    mmoodduullee((_M_o_d_u_l_e))
         Specify  _M_o_d_u_l_e  for  operators,   character_escapes   flag  and
         double_quotes flag.  The  value of the latter two is  overruled
         if  the corresponding  read_term/3  option  is provided.     If
         no module  is specified, the  current `source-module' is  used.
         (SWI-Prolog).

    cchhaarraacctteerr__eessccaappeess((_B_o_o_l))
         Defines  how  to  read  \  escape-sequences  in  quoted  atoms.
         See the  prolog-flags character_escapes, current_prolog_flag/2.
         (SWI-Prolog).

    ddoouubbllee__qquuootteess((_B_o_o_l))
         Defines  how to  read  "..." strings.    See  the  prolog-flags
         double_quotes, current_prolog_flag/2.  (SWI-Prolog).

    bbaacckkqquuootteedd__ssttrriinngg((_B_o_o_l))
         If true,  read `...`  to a  string object  (see section  4.23).
         The default depends on the prolog flag with the same name.

    tteerrmm__ppoossiittiioonn((_P_o_s))
         Unifies _P_o_s with the starting  position of the term read.   _P_o_s
         if of the same format as use by stream_property/2.

    ssuubbtteerrmm__ppoossiittiioonnss((_T_e_r_m_P_o_s))
         Describes the  detailed layout of  the term.   The formats  for
         the various types of terms  if given below.  All  positions are
         character positions.    If  the input  is related  to a  normal
         stream,  these  positions are  relative  to the  start  of  the
         input, when  reading from  the terminal, they  are relative  to
         the start of the term.

         FFrroomm--TToo
             Used for primitive types (atoms, numbers, variables).

         ssttrriinngg__ppoossiittiioonn((_F_r_o_m_, _T_o))
             Used  to indicate  the  position of  a string  enclosed  in
             double quotes (").

         bbrraaccee__tteerrmm__ppoossiittiioonn((_F_r_o_m_, _T_o_, _A_r_g))
             Term  of  the form  {...},  as used  in  DCG  rules.    _A_r_g
             describes the argument.

         lliisstt__ppoossiittiioonn((_F_r_o_m_, _T_o_, _E_l_m_s_, _T_a_i_l))
             A list.  _E_l_m_s describes the  positions of the elements.  If
             the list specifies the tail as |<_T_a_i_l_T_e_r_m>, _T_a_i_l is unified
             with  the term-position  of the  tail,  otherwise with  the
             atom none.

         tteerrmm__ppoossiittiioonn((_F_r_o_m_, _T_o_, _F_F_r_o_m_, _F_T_o_, _S_u_b_P_o_s))
             Used  for a compound  term not matching  one of the  above.
             _F_F_r_o_m  and  _F_T_o  describe  the  position  of  the  functor.
             _S_u_b_P_o_s  is a  list,  each element  of  which describes  the
             term-position of the corresponding subterm.


rreeaadd__tteerrmm((_+_S_t_r_e_a_m_, _-_T_e_r_m_, _+_O_p_t_i_o_n_s))
    Read term with options from _S_t_r_e_a_m.  See read_term/2.


rreeaadd__hhiissttoorryy((_+_S_h_o_w_, _+_H_e_l_p_, _+_S_p_e_c_i_a_l_, _+_P_r_o_m_p_t_, _-_T_e_r_m_, _-_B_i_n_d_i_n_g_s))
    Similar  to read_term/2 using the option variable_names, but  allows
    for history  substitutions.  read_history/6is used  by the top level
    to  read the user's actions.   _S_h_o_w is  the command the user  should
    type  to show  the saved  events.   _H_e_l_p is  the command  to get  an
    overview  of the capabilities.   _S_p_e_c_i_a_l is a list of commands  that
    are  not saved in the  history.  _P_r_o_m_p_t  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.7 for available substitutions.

    SWI-Prolog calls read_history/6 as follows:

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

pprroommpptt((_-_O_l_d_, _+_N_e_w))
    Set  prompt associated  with read/1  and its  derivatives.   _O_l_d  is
    first  unified with the current prompt.  On success the  prompt will
    be  set to _N_e_w 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 _u_s_e_r.


pprroommpptt11((_+_P_r_o_m_p_t))
    Sets  the prompt for the next line  to be read.   Continuation lines
    will be read using the prompt defined by prompt/2.


44..2200 AAnnaallyyssiinngg aanndd CCoonnssttrruuccttiinngg TTeerrmmss


ffuunnccttoorr((_?_T_e_r_m_, _?_F_u_n_c_t_o_r_, _?_A_r_i_t_y))
    Succeeds  if _T_e_r_m is  a term with  functor _F_u_n_c_t_o_r and arity  _A_r_i_t_y.
    If  _T_e_r_m is a variable  it is unified with  a new term holding  only
    variables.    functor/3 silently  fails on  instantiation faults  If
    _T_e_r_m  is an atom or  number, _F_u_n_c_t_o_r will  be unified with _T_e_r_m  and
    arity will be unified with the integer 0 (zero).


aarrgg((_?_A_r_g_, _?_T_e_r_m_, _?_V_a_l_u_e))
    _T_e_r_m  should be instantiated  to a term,  _A_r_g to an integer  between
    1  and  the  arity of  _T_e_r_m.    _V_a_l_u_e  is  unified with  the  _A_r_g-th
    argument  of _T_e_r_m.   _A_r_g may also  be unbound.   In this case  _V_a_l_u_e
    will  be unified  with the  successive arguments of  the term.    On
    successful  unification, _A_r_g  is unified  with the argument  number.
    Backtracking  yields alternative  solutions.    The predicate  arg/3
    fails  silently if  _A_r_g= 0 or _A_r_g > _a_r_i_t_y and raises  the exception
    domain_error(not_less_then_zero, Arg)if _A_r_g <0.


sseettaarrgg((_+_A_r_g_, _+_T_e_r_m_, _+_V_a_l_u_e))
    Extra-logical  predicate.     Assigns the  _A_r_g-th  argument  of  the
    compound  term _T_e_r_m with the given _V_a_l_u_e.  The assignment  is undone
    if  backtracking brings the  state back into  a position before  the
    setarg/3 call.

    This  predicate may  be used  for destructive  assignment to  terms,
    using  them as and  extra-logical storage bin.   Always try hard  to
    avoid  the use of  setarg/3 as  it is not  supported by many  Prolog
    systems  and one has to be very careful about unexpected  copying as
    well as unexpected not copying of terms.


_?_T_e_r_m =.. _?_L_i_s_t
    _L_i_s_t  is a list which head is the functor of _T_e_r_m 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))


nnuummbbeerrvvaarrss((_+_T_e_r_m_, _+_S_t_a_r_t_, _-_E_n_d))
    Unify  the free variables  of _T_e_r_m with a  term $VAR(_N), where _N  is
    the  number of  the variable.   Counting starts  at _S_t_a_r_t.   _E_n_d  is
    unified  with the number that should be given to the  next variable.
    Example:

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

    A = '$VAR'(0)
    B = '$VAR'(1)
    End = 2

    See also the numbervars option to write_term/3 and numbervars/4.


nnuummbbeerrvvaarrss((_+_T_e_r_m_, _+_F_u_n_c_t_i_o_n_S_y_m_b_o_l_, _+_S_t_a_r_t_, _-_E_n_d))
    As  numbervars/3, but instead of  using the fixed $VAR the  function
    symbol is determined by extra _F_u_n_c_t_i_o_n_S_y_m_b_o_l argument.


ffrreeee__vvaarriiaabblleess((_+_T_e_r_m_, _-_L_i_s_t))
    Unify  _L_i_s_t with  a list of  variables, each  sharing with a  unique
    variable of _T_e_r_m.  For example:

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

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

ccooppyy__tteerrmm((_+_I_n_, _-_O_u_t))
    Make a copy of  term _I_n and unify the result with _O_u_t.  Ground parts
    of  _I_n are  shared by  _O_u_t.   Provided _I_n  and _O_u_t  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).

    Note  that as copy_term/2  does not create  copies for ground  terms
    setarg/3 affects both the copy and original.


44..2211 AAnnaallyyssiinngg aanndd CCoonnssttrruuccttiinngg AAttoommss

These  predicates  convert   between  Prolog  constants  and  lists   of
character codes.  The predicates atom_codes/2, number_codes/2 and name/2
behave the same when  converting from a constant to a list  of character
codes.     When converting  the  other  way  around,  atom_codes/2  will
generate an  atom, number_codes/2  will generate a  number or  exception
and name/2 will return a number if possible and an atom otherwise.

The  ISO  standard  defines atom_chars/2  to  describe  the  `broken-up'
atom  as a  list of  one-character atoms  instead of  a  list of  codes.
Upto  version 3.2.x,  SWI-Prolog's atom_chars/2 behaved,  compatible  to
Quintus and  SICStus Prolog,  like atom_codes.    As of 3.3.x  SWI-Prolog
atom_codes/2 and atom_chars/2are compliant to the ISO standard.

To  ease  the pain  of  all  variations in  the  Prolog  community,  all
SWI-Prolog predicates  behave as  flexible as  possible.   This  implies
the  `list-side' accepts  either  a code-list  or  a char-list  and  the
`atom-side' accept all atomic types (atom, number and string).


aattoomm__ccooddeess((_?_A_t_o_m_, _?_S_t_r_i_n_g))
    Convert  between an atom and a list of character codes.   If _A_t_o_m is
    instantiated,  if will be translated into a list of  character codes
    and  the result  is unified with  _S_t_r_i_n_g.   If _A_t_o_m  is unbound  and
    _S_t_r_i_n_g  is a list of character  codes, it will _A_t_o_m will  be unified
    with an atom constructed from this list.


aattoomm__cchhaarrss((_?_A_t_o_m_, _?_C_h_a_r_L_i_s_t))
    As  atom_codes/2, but  _C_h_a_r_L_i_s_t  is a  list of  one-character  atoms
    rather than a list of character codes.

    ?- atom_chars(hello, X).

    X = [h, e, l, l, o]


cchhaarr__ccooddee((_?_A_t_o_m_, _?_C_o_d_e))
    Convert   between  character  and   character  code  for  a   single
    character.


nnuummbbeerr__cchhaarrss((_?_N_u_m_b_e_r_, _?_C_h_a_r_L_i_s_t))
    Similar  to  atom_chars/2,  but  converts between  a number  and  its
    representation  as a  list of  one-character atoms.    Fails with  a
    representation_error  if _N_u_m_b_e_r  is unbound  and  _C_h_a_r_L_i_s_t does  not
    describe a number.


nnuummbbeerr__ccooddeess((_?_N_u_m_b_e_r_, _?_C_o_d_e_L_i_s_t))
    As number_chars/2, but converts to a list  of character codes rather
    than one-character atoms.   In the mode -, +, both predicates behave
    identically to improve handling of non-ISO source.


aattoomm__nnuummbbeerr((_?_A_t_o_m_, _?_N_u_m_b_e_r))
    Realises  the popular combination of atom_codes/2 and number_codes/2
    to  convert  between  atom and  number  (integer  or float)  in  one
    predicate, avoiding the intermediate list.


nnaammee((_?_A_t_o_m_O_r_I_n_t_, _?_S_t_r_i_n_g))
    _S_t_r_i_n_g  is a list of character  codes representing the same text  as
    _A_t_o_m.  Each of  the arguments may be a variable, but not both.  When
    _S_t_r_i_n_g  is bound  to an  character code list  describing an  integer
    and  _A_t_o_m  is a  variable  _A_t_o_m will  be  unified with  the  integer
    value  described by _S_t_r_i_n_g  (e.g.   `name(N, "300"), 400 is N + 100'
    succeeds).


iinntt__ttoo__aattoomm((_+_I_n_t_, _+_B_a_s_e_, _-_A_t_o_m))
    Convert  _I_n_t to an textual representation using base _B_a_s_e  and unify
    the  result with _A_t_o_m.   If _B_a_s_e 6=10 the  base will be prepended  to
    _A_t_o_m.   _B_a_s_e= 0 will try to interpret _I_n_t as an character codes and
    return  0'<_c>.   Otherwise  2=<_B_a_s_e=< 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


iinntt__ttoo__aattoomm((_+_I_n_t_, _-_A_t_o_m))
    Equivalent to int_to_atom(Int, 10, Atom).


tteerrmm__ttoo__aattoomm((_?_T_e_r_m_, _?_A_t_o_m))
    Succeeds  if _A_t_o_m describes  a term  that unifies with  _T_e_r_m.   When
    _A_t_o_m  is instantiated _A_t_o_m is converted and then unified  with _T_e_r_m.
    If  _A_t_o_m has no  valid syntax,  a syntax_error exception is  raised.
    Otherwise _T_e_r_m is ``written'' on _A_t_o_m using write/1.


aattoomm__ttoo__tteerrmm((_+_A_t_o_m_, _-_T_e_r_m_, _-_B_i_n_d_i_n_g_s))
    Use  _A_t_o_m as  input to  read_term/2 using the  option variable_names
    and  return  the read  term in  _T_e_r_m and  the  variable bindings  in
    _B_i_n_d_i_n_g_s.   _B_i_n_d_i_n_g_s is a list of _N_a_m_e =_V_a_r couples, thus providing
    access  to the actual  variable names.   See  also read_term/2.   If
    _A_t_o_m has no valid syntax, a syntax_error exception is raised.


aattoomm__ccoonnccaatt((_?_A_t_o_m_1_, _?_A_t_o_m_2_, _?_A_t_o_m_3))
    _A_t_o_m_3  forms the concatenation of _A_t_o_m_1 and _A_t_o_m_2.  At least  two of
    the  arguments must be instantiated  to atoms, integers or  floating
    point  numbers.    For  ISO  compliance,  the  instantiation-pattern
    -, -, +  is allowed  too, non-deterministically  splitting the  3-th
    argument  into two parts  (as append/3  does for lists).   See  also
    string_concat/3.


ccoonnccaatt__aattoomm((_+_L_i_s_t_, _-_A_t_o_m))
    _L_i_s_t  is  a  list of  atoms,  integers  or floating  point  numbers.
    Succeeds  if  _A_t_o_m can  be unified  with  the concatenated  elements
    of  _L_i_s_t.    If _L_i_s_t  has exactly  2 elements  it  is equivalent  to
    atom_concat/3, allowing for variables in the list.


ccoonnccaatt__aattoomm((_?_L_i_s_t_, _+_S_e_p_a_r_a_t_o_r_, _?_A_t_o_m))
    Creates  an  atom just  like  concat_atom/2, but  inserts  _S_e_p_a_r_a_t_o_r
    between each pair of atoms.  For example:

    ?- concat_atom([gnu, gnat], ', ', A).

    A = 'gnu, gnat'

    This  predicate can  also be  used to split  atoms by  instantiating
    _S_e_p_a_r_a_t_o_r and _A_t_o_m:

    ?- concat_atom(L, -, 'gnu-gnat').

    L = [gnu, gnat]


aattoomm__lleennggtthh((_+_A_t_o_m_, _-_L_e_n_g_t_h))
    Succeeds  if  _A_t_o_m is  an atom  of  _L_e_n_g_t_h characters  long.    This
    predicate  also  works for  strings  (see section  4.23).    If  the
    prolog  flag iso is  _n_o_t set, it  also accepts integers and  floats,
    expressing the number  of characters output when given to write/1 as
    well  as code-lists  and character-lists,  expressing the length  of
    the list.


aattoomm__pprreeffiixx((_+_A_t_o_m_, _+_P_r_e_f_i_x))
    Succeeds  if  _A_t_o_m starts  with the  characters from  _P_r_e_f_i_x.    Its
    behaviour  is equivalent  to ?- concat(Prefix, _, Atom), but  avoids
    the construction of an atom for the `remainder'.


ssuubb__aattoomm((_+_A_t_o_m_, _?_B_e_f_o_r_e_, _?_L_e_n_, _?_A_f_t_e_r_, _?_S_u_b))
    ISO  predicate  for breaking  atoms.    It maintains  the  following
    relation:  _S_u_b is  a sub-atom of _A_t_o_m that starts at _B_e_f_o_r_e, has _L_e_n
    characters and _A_t_o_m contains _A_f_t_e_r characters after the match.

    ?- sub_atom(abc, 1, 1, A, S).

    A = 1, S = b

    The  implementation  minimalises  non-determinism  and  creation  of
    atoms.    This  is a  very flexible  predicate that  can do  search,
    prefix- and suffix-matching, etc.


44..2222 CCllaassssiiffyyiinngg cchhaarraacctteerrss

SWI-Prolog   offers  two   comprehensive  predicates   for   classifying
characters and character-codes.  These predicates are  defined as built-
in predicates  to exploit the  C-character classification's handling  of
_l_o_c_a_l_e (handling of  local character-sets).  These predicates  are fast,
logical and deterministic if applicable.

In addition, there is the library ctype providing  compatibility to some
other Prolog  systems.   The predicates of this  library are defined  in
terms of code_type/2.


cchhaarr__ttyyppee((_?_C_h_a_r_, _?_T_y_p_e))
    Tests or generates  alternative _T_y_p_es or _C_h_a_rs.  The character-types
    are inspired by the standard C <ctype.h>  primitives.

    aallnnuumm
         _C_h_a_r is a letter (upper- or lowercase) or digit.

    aallpphhaa
         _C_h_a_r is a letter (upper- or lowercase).

    ccssyymm
         _C_h_a_r  is  a  letter   (upper-  or  lowercase),  digit   or  the
         underscore  (_).     These  are  valid  C-  and  Prolog  symbol
         characters.

    ccssyymmff
         _C_h_a_r is a letter  (upper- or lowercase) or the  underscore (_).
         These are valid first characters for C- and Prolog symbols

    aasscciiii
         _C_h_a_r is a 7-bits ASCII character (0..127).

    wwhhiittee
         _C_h_a_r is a space or tab.  E.i. white space inside a line.

    ccnnttrrll
         _C_h_a_r is an ASCII control-character (0..31).

    ddiiggiitt
         _C_h_a_r is a digit.

    ddiiggiitt((_W_e_i_g_t_h))
         _C_h_a_r is a digit with value  _W_e_i_g_t_h.  I.e. char_type(X, digit(6)
         yields _X = '6'.  Useful for parsing numbers.

    xxddiiggiitt((_W_e_i_g_t_h))
         _C_h_a_r  is  a  haxe-decimal  digit  with  value  _W_e_i_g_t_h.     I.e.
         char_type(a, xdigit(X) yields _X  = '10'.    Useful for  parsing
         numbers.

    ggrraapphh
         _C_h_a_r produces  a visible mark  on a  page when printed.    Note
         that the space is not included!

    lloowweerr
         _C_h_a_r is a lower-case letter.

    lloowweerr((_U_p_p_e_r))
         _C_h_a_r is a  lower-case version of _U_p_p_e_r.   Only true if _C_h_a_r  is
         lowercase and _U_p_p_e_r uppercase.

    ttoo__lloowweerr((_U_p_p_e_r))
         _C_h_a_r is  a lower-case version  of _U_p_p_e_r.   For non-letters,  or
         letter without case,  _C_h_a_r and  _L_o_w_e_r are the same.   See  also
         upcase_atom/2 and downcase_atom/2.

    uuppppeerr
         _C_h_a_r is an upper-case letter.

    uuppppeerr((_L_o_w_e_r))
         _C_h_a_r is an upper-case version  of _L_o_w_e_r.  Only true if  _C_h_a_r is
         uppercase and _L_o_w_e_r lowercase.

    ttoo__uuppppeerr((_L_o_w_e_r))
         _C_h_a_r is an  upper-case version of _L_o_w_e_r.   For non-letters,  or
         letter without case,  _C_h_a_r and  _L_o_w_e_r are the same.   See  also
         upcase_atom/2 and downcase_atom/2.

    ppuunncctt
         _C_h_a_r is  a punctuation character.   This  is a graph  character
         that is not a letter or digit.

    ssppaaccee
         _C_h_a_r  is some  form  of layout  character  (tab,  vertical-tab,
         newline, etc.).

    eenndd__ooff__ffiillee
         _C_h_a_r is -1.

    eenndd__ooff__lliinnee
         _C_h_a_r ends a line (ASCII: 10..13).

    nneewwlliinnee
         _C_h_a_r is a the newline character (10).

    ppeerriioodd
         _C_h_a_r counts as the end of a sentence (.,!,?).

    qquuoottee
         _C_h_a_r is a quote-character (", ', `).

    ppaarreenn((_C_l_o_s_e))
         _C_h_a_r is  an  open-parenthesis and  _C_l_o_s_e is  the  corresponding
         close-parenthesis.


ccooddee__ttyyppee((_?_C_o_d_e_, _?_T_y_p_e))
    As  char_type/2,  but uses character-codes rather than  one-character
    atoms.     Please note  that  both  predicates are  as  flexible  as
    possible.    They handle  either representation if  the argument  is
    instantiated  and  only will  instantiate with  an  integer code  or
    one-character  atom depending  of the version  used.   See also  the
    prolog-flag double_quotes, atom_chars/2 and atom_codes/2.


44..2222..11 CCaassee ccoonnvveerrssiioonn

There is nothing in  the Prolog standard for converting case  in textual
data.    The SWI-Prolog  predicates code_type/2 and  char_type/2 can  be
used to test  and convert individual characters.   We have started  some
additional support:


ddoowwnnccaassee__aattoomm((_+_A_n_y_C_a_s_e_, _-_L_o_w_e_r_C_a_s_e))
    Converts  the characters  of _A_n_y_C_a_s_e  into lowercase  as char_type/2
    does  (i.e. based on  the defined _l_o_c_a_l_e  if Prolog provides  locale
    support  on the  hosting platform)  and unifies  the lowercase  atom
    with _L_o_w_e_r_C_a_s_e.


uuppccaassee__aattoomm((_+_A_n_y_C_a_s_e_, _-_U_p_p_e_r_C_a_s_e))
    Converts, similar to downcase_atom/2, an atom to upper-case.


44..2233 RReepprreesseennttiinngg tteexxtt iinn ssttrriinnggss

SWI-Prolog  supports the  data type  _s_t_r_i_n_g.   Strings  are  a time  and
space efficient mechanism to handle text in Prolog.   Strings are stored
as  a byte  array  on the  global (term)  stack  and thus  destroyed  on
backtracking and reclaimed by the garbage collector.

Strings were  added to  SWI-Prolog based on  an early  draft of the  ISO
standard, offerring  a mechanism to  represent temporary character  data
efficiently.    As  SWI-Prolog  strings can  handle  0-bytes,  they  are
frequently used through  the foreign language interface (section 7)  for
storing arbitrary byte-sequences.

Starting with version  3.3, SWI-Prolog offers garbage collection  on the
atom-space as well as  representing 0-bytes in atoms.   Although strings
and  atoms still  have  different  features,  new code  should  consider
using atoms to  avoid too many representations  for text as well as  for
compatibility to other  Prolog implementations.   Below are some of  the
differences:

  o _c_r_e_a_t_i_o_n
    Creating  strings  is fast,  as the  data is  simply  copied to  the
    global  stack.   Atoms are  unique and  therefore more expensive  in
    terms  of memory  and time to  create.   On the other  hand, if  the
    same  text has  to be  represented  multiple times,  atoms are  more
    efficient.

  o _d_e_s_t_r_u_c_t_i_o_n
    Backtracking destroys strings at  no cost.  They are cheap to handle
    by  the garbage  collector, but  it should be  noted that  extensive
    use  of strings will cause many  garbage collections.  Atom  garbage
    collection is generally faster.

String objects  by default have no  lexical representation and thus  can
only  be created  using  the predicates  below  or through  the  foreign
language interface (See  chapter 7.  There  are two ways to make  read/1
read text into  strings, both controlled through  Prolog flags.  One  is
by setting the double_quotes flag to string and the other  is by setting
the backquoted_string flag  to true.   In latter case, `Hello world`  is
read into  a string and  write_term/2 prints strings between  backquotes
if quoted  is true.    This flag  provides compatibility  to LPA  Prolog
string handling.


ssttrriinngg__ttoo__aattoomm((_?_S_t_r_i_n_g_, _?_A_t_o_m))
    Logical  conversion between  a string  and an atom.    At least  one
    of  the two arguments  must be instantiated.   _A_t_o_m  can also be  an
    integer or floating point number.


ssttrriinngg__ttoo__lliisstt((_?_S_t_r_i_n_g_, _?_L_i_s_t))
    Logical  conversion  between  a  string  and  a  list  of  character
    codes  characters.    At least  one  of the  two arguments  must  be
    instantiated.


ssttrriinngg__lleennggtthh((_+_S_t_r_i_n_g_, _-_L_e_n_g_t_h))
    Unify  _L_e_n_g_t_h  with  the number  of  characters  in _S_t_r_i_n_g.     This
    predicate  is  functionally  equivalent  to atom_length/2  and  also
    accepts atoms, integers and floats as its first argument.


ssttrriinngg__ccoonnccaatt((_?_S_t_r_i_n_g_1_, _?_S_t_r_i_n_g_2_, _?_S_t_r_i_n_g_3))
    Similar  to atom_concat/3,  but the unbound argument will  be unified
    with  a string object rather  than an atom.   Also, if both  _S_t_r_i_n_g_1
    and  _S_t_r_i_n_g_2 are  unbound and _S_t_r_i_n_g_3  is bound to  text, it  breaks
    _S_t_r_i_n_g_3,  unifying the start with  _S_t_r_i_n_g_1 and the end with  _S_t_r_i_n_g_2
    as  append does  with lists.   Note  that this  is not  particularly
    fast  on long  strings as  for each redo  the system  has to  create
    two  entirely new strings, while the list equivalent only  creates a
    single new list-cell and moves some pointers around.


ssuubb__ssttrriinngg((_+_S_t_r_i_n_g_, _?_S_t_a_r_t_, _?_L_e_n_g_t_h_, _?_A_f_t_e_r_, _?_S_u_b))
    _S_u_b  is a substring of _S_t_r_i_n_g starting at _S_t_a_r_t, with  length _L_e_n_g_t_h
    and  _S_t_r_i_n_g has _A_f_t_e_r  characters left  after the match.   See  also
    sub_atom/5.


44..2244 OOppeerraattoorrss

Operators  are  defined  to  improve  the  readibility  of  source-code.
For  example, without  operators, to  write  2*3+4*5 one  would have  to
write +(*(2,3),*(4,5)).    In Prolog,  a number of  operators have  been
predefined.   All operators, except for  the comma (,) can be  redefined
by the user.

Some care  has to  be taken  before defining  new operators.    Defining
too many  operators might  make your  source `natural'  looking, but  at
the same  time lead  to hard to  understand the  limits of your  syntax.
To ease  the pain, as  of SWI-Prolog 3.3.0,  operators are local to  the
module  in which  they are  defined.   The  module-table  of the  module
user acts as  default table for all modules.   This global table can  be
modified explictly from inside a module:

:- module(prove,
          [ prove/1
          ]).

:- op(900, xfx, user:(=>)).

Unlike  what many  users  think,  operators  and quoted  atoms  have  no
relation:   defining a atom  as an operator  does nnoott influence  parsing
characters into atoms and  quoting an atom does nnoott stop it  from acting
as an operator.   To stop an atom  acting as an operator, enclose  it in
braces like this:  (myop).


oopp((_+_P_r_e_c_e_d_e_n_c_e_, _+_T_y_p_e_, _:_N_a_m_e))
    Declare  _N_a_m_e  to  be  an  operator of  type  _T_y_p_e  with  precedence
    _P_r_e_c_e_d_e_n_c_e.    _N_a_m_e  can also  be a  list of  names,  in which  case
    all  elements of the  list are declared  to be identical  operators.
    _P_r_e_c_e_d_e_n_c_e  is an integer between 0 and 1200.  Precedence  0 removes
    the  declaration.   _T_y_p_e 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 4.1.   Note that  all
    operators can be redefined by the user.
     ______________________________________________________________
     | 1200 |xfx  |-->, :-                                        |
     | 1200 | fx  |:-, ?-                                         |
     | 1150 | fx  |dynamic, multifile, module_transparent, discon-|
     |      |     |tiguous, volatile, initialization              |
     | 1100 |xfy  |;, |                                           |

     | 1050 |xfy  |->                                             |
     | 1000 |xfy  |,                                              |
     |  954 |xfy  |\                                              |
     |  900 | fy  |\+                                             |
     |  900 | fx  |~                                              |
     |  700 |xfx  |<, =, =.., =@=,  =:=, =<, ==, =\=,  >, >=, @<, |
     |      |     |@=<, @>, @>=, \=, \==, is                      |
     |  600 |xfy  |:                                              |

     |  500 | yfx |+, -, /\, \/, xor                              |
     |  500 | fx  |+, -, ?, \                                     |
     |  400 | yfx |*, /, //, <<, >>, mod, rem                     |
     |  200 |xfx  |**                                             |
     |__200_|xfy__|^______________________________________________|_

                      Table 4.1:  System operators


ccuurrrreenntt__oopp((_?_P_r_e_c_e_d_e_n_c_e_, _?_T_y_p_e_, _?_:_N_a_m_e))
    Succeeds when _N_a_m_e  is currently defined as an operator of type _T_y_p_e
    with precedence _P_r_e_c_e_d_e_n_c_e.  See also op/3.


44..2255 CChhaarraacctteerr CCoonnvveerrssiioonn

Although I  wouldn't really know  for what you would  like to use  these
features, they are provided for ISO complicancy.


cchhaarr__ccoonnvveerrssiioonn((_+_C_h_a_r_I_n_, _+_C_h_a_r_O_u_t))
    Define  that term-input (see  read_term/3)  maps each character  read
    as  _C_h_a_r_I_n to the character _C_h_a_r_O_u_t.   Character conversion is  only
    executed  if the prolog-flag char_conversion is set to true  and not
    inside  quoted  atoms or  strings.    The  initial table  maps  each
    character onto itself.  See also current_char_conversion/2.


ccuurrrreenntt__cchhaarr__ccoonnvveerrssiioonn((_?_C_h_a_r_I_n_, _?_C_h_a_r_O_u_t))
    Queries    the   current   character   conversion-table.         See
    char_conversion/2 for details.


44..2266 AArriitthhmmeettiicc

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 arithmetic  predicates  are  optionally compiled  now  (see
set_prolog_flag/2  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  _e_x_p_r_e_s_s_i_o_n_s.      An
expression is either a simple number or a _f_u_n_c_t_i_o_n.   The arguments of a
function are expressions.  The functions are described in section 4.27.


bbeettwweeeenn((_+_L_o_w_, _+_H_i_g_h_, _?_V_a_l_u_e))
    _L_o_w  and _H_i_g_h  are integers, _H_i_g_h>= _L_o_w.   If  _V_a_l_u_e is an  integer,
    _L_o_w=< _V_a_l_u_e=< _H_i_g_h.   When _V_a_l_u_e  is a  variable it is  successively
    bound to all integers between _L_o_w and _H_i_g_h.


ssuucccc((_?_I_n_t_1_, _?_I_n_t_2))
    Succeeds  if  _I_n_t_2= _I_n_t_1+ 1 and  _I_n_t_1>= 0.    At least  one  of the
    arguments must be  instantiated to a natural number.  This predicate
    raises the domain-error not_less_than_zero if called with a negative
    integer.   E.g. succ(_X_, _0)  fails silently and succ(_X_, _-_1) raises  a
    domain-error.


pplluuss((_?_I_n_t_1_, _?_I_n_t_2_, _?_I_n_t_3))
    Succeeds if  _I_n_t_3= _I_n_t_1+_I_n_t_2.   At least two of the three arguments
    must be instantiated to integers.


_+_E_x_p_r_1 > _+_E_x_p_r_2
    Succeeds  when expression  _E_x_p_r_1 evaluates to  a larger number  than
    _E_x_p_r_2.


_+_E_x_p_r_1 < _+_E_x_p_r_2
    Succeeds  when expression _E_x_p_r_1 evaluates  to a smaller number  than
    _E_x_p_r_2.


_+_E_x_p_r_1 =< _+_E_x_p_r_2
    Succeeds  when  expression _E_x_p_r_1  evaluates to  a  smaller or  equal
    number to _E_x_p_r_2.


_+_E_x_p_r_1 >= _+_E_x_p_r_2
    Succeeds  when  expression  _E_x_p_r_1 evaluates  to  a larger  or  equal
    number to _E_x_p_r_2.


_+_E_x_p_r_1 =\= _+_E_x_p_r_2
    Succeeds  when expression _E_x_p_r_1 evaluates  to a number non-equal  to
    _E_x_p_r_2.


_+_E_x_p_r_1 =:= _+_E_x_p_r_2
    Succeeds  when  expression  _E_x_p_r_1 evaluates  to  a number  equal  to
    _E_x_p_r_2.


_-_N_u_m_b_e_r iiss _+_E_x_p_r
    Succeeds  when  _N_u_m_b_e_r   has  successfully  been  unified  with  the
    number  _E_x_p_r  evaluates to.    If  _E_x_p_r evaluates  to a  float  that
    can  be represented  using an  integer  (i.e, the  value is  integer
    and  within the  range  that can  be described  by Prolog's  integer
    representation),  _E_x_p_r is unified with the integer value.

    Note  that normally, is/2  will be used  with unbound left  operand.
    If equality is to be tested, =:=/2 should be used.  For example:

         ?- 1.0 is sin(pi/2).         Fails!.   sin(pi/2) evaluates
                                      to   1.0,   but   is/2   will
                                      represent this as the integer
                                      1,  after  which  unify  will
                                      fail.

         ?- 1.0 is float(sin(pi/2)).  Succeeds,   as   the  float/1
                                      function forces the result to
                                      be float.
         ?- 1.0 =:= sin(pi/2).        Succeeds as expected.


44..2277 AArriitthhmmeettiicc FFuunnccttiioonnss

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:

        _E_x_p_r     Arbitrary   expression,   returning  either   a
                 floating point value or an integer.
        _I_n_t_E_x_p_r  Arbitrary expression that should  evaluate into
                 an integer.
        _I_n_t      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 precision, error handling, etc.


- _+_E_x_p_r
    _R_e_s_u_l_t =-_E_x_p_r


_+_E_x_p_r_1 + _+_E_x_p_r_2
    _R_e_s_u_l_t =_E_x_p_r_1 +_E_x_p_r_2


_+_E_x_p_r_1 - _+_E_x_p_r_2
    _R_e_s_u_l_t =_E_x_p_r_1 -_E_x_p_r_2


_+_E_x_p_r_1 * _+_E_x_p_r_2
    _R_e_s_u_l_t =_E_x_p_r_1_*Expr2


_+_E_x_p_r_1 / _+_E_x_p_r_2
    _R_e_s_u_l_t =_E_x_p_r_1=_E_x_p_r_2


_+_I_n_t_E_x_p_r_1 mmoodd _+_I_n_t_E_x_p_r_2
    Modulo:   _R_e_s_u_l_t = _I_n_t_E_x_p_r_1 - (_I_n_t_E_x_p_r_1 // _I_n_t_E_x_p_r_2)  * _I_n_t_E_x_p_r_2 The
    function  mod/2  is  implemented using  the  C  % operator.     It's
    behaviour with negtive values is illustrated in the table below.

                              2  =   17  mod   5
                              2  =   17  mod  -5
                             -2  =  -17  mod   5
                             -2  =  -17  mod   5


_+_I_n_t_E_x_p_r_1 rreemm _+_I_n_t_E_x_p_r_2
    Remainder of division:  _R_e_s_u_l_t = float_fractional_part(_I_n_t_E_x_p_r_1/_I_n_t_E_x_p_r_2)


_+_I_n_t_E_x_p_r_1 // _+_I_n_t_E_x_p_r_2
    Integer division:  _R_e_s_u_l_t = truncate(_E_x_p_r_1/_E_x_p_r_2)


aabbss((_+_E_x_p_r))
    Evaluate _E_x_p_r and return the absolute value of it.


ssiiggnn((_+_E_x_p_r))
    Evaluate to -1 if _E_x_p_r <0, 1 if _E_x_p_r >0 and 0 if _E_x_p_r =0.


mmaaxx((_+_E_x_p_r_1_, _+_E_x_p_r_2))
    Evaluates to the largest of both _E_x_p_r_1 and _E_x_p_r_2.


mmiinn((_+_E_x_p_r_1_, _+_E_x_p_r_2))
    Evaluates to the smallest of both _E_x_p_r_1 and _E_x_p_r_2.


.((_+_I_n_t_, _[_]))
    A  list of one element evaluates to  the element.  This  implies "a"
    evaluates  to the  character  code 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  transformed
    into a string object.   The recommended way to specify the character
    code of the letter `a' is 0'a.


rraannddoomm((_+_I_n_t))
    Evaluates  to a  random integer _i  for which 0=< i <_I_n_t.   The  seed
    of  this random  generator is  determined by the  system clock  when
    SWI-Prolog was started.


rroouunndd((_+_E_x_p_r))
    Evaluates _E_x_p_r and rounds the result to the nearest integer.


iinntteeggeerr((_+_E_x_p_r))
    Same as round/1 (backward compatibility).


ffllooaatt((_+_E_x_p_r))
    Translate  the result to a floating point number.   Normally, Prolog
    will  use integers  whenever possible.    When used  around the  2nd
    argument  of is/2, the result will  be returned as a floating  point
    number.  In other contexts, the operation has no effect.


ffllooaatt__ffrraaccttiioonnaall__ppaarrtt((_+_E_x_p_r))
    Fractional  part of a  floating-point number.   Negative if _E_x_p_r  is
    negative, 0 if _E_x_p_r is integer.


ffllooaatt__iinntteeggeerr__ppaarrtt((_+_E_x_p_r))
    Integer  part  of  floating-point  number.    Negative  if  _E_x_p_r  is
    negative, _E_x_p_r if _E_x_p_r is integer.


ttrruunnccaattee((_+_E_x_p_r))
    Truncate _E_x_p_r to an integer.  Same as float_integer_part/1.


fflloooorr((_+_E_x_p_r))
    Evaluates  _E_x_p_r and returns the largest integer smaller or  equal to
    the result of the evaluation.


cceeiilliinngg((_+_E_x_p_r))
    Evaluates  _E_x_p_r and returns the smallest integer larger or  equal to
    the result of the evaluation.


cceeiill((_+_E_x_p_r))
    Same as ceiling/1 (backward compatibility).


_+_I_n_t_E_x_p_r >> _+_I_n_t_E_x_p_r
    Bitwise shift _I_n_t_E_x_p_r_1 by _I_n_t_E_x_p_r_2 bits to the right.


_+_I_n_t_E_x_p_r << _+_I_n_t_E_x_p_r
    Bitwise shift _I_n_t_E_x_p_r_1 by _I_n_t_E_x_p_r_2 bits to the left.


_+_I_n_t_E_x_p_r \/ _+_I_n_t_E_x_p_r
    Bitwise `or' _I_n_t_E_x_p_r_1 and _I_n_t_E_x_p_r_2.


_+_I_n_t_E_x_p_r /\ _+_I_n_t_E_x_p_r
    Bitwise `and' _I_n_t_E_x_p_r_1 and _I_n_t_E_x_p_r_2.


_+_I_n_t_E_x_p_r xxoorr _+_I_n_t_E_x_p_r
    Bitwise `exclusive or' _I_n_t_E_x_p_r_1 and _I_n_t_E_x_p_r_2.


\ _+_I_n_t_E_x_p_r
    Bitwise negation.


ssqqrrtt((_+_E_x_p_r))
    _R_e_s_u_l_t =square root of _E_x_p_r


ssiinn((_+_E_x_p_r))
    _R_e_s_u_l_t =sine of _E_x_p_r.  _E_x_p_r is the angle in radians.


ccooss((_+_E_x_p_r))
    _R_e_s_u_l_t =cosine of _E_x_p_r.  _E_x_p_r is the angle in radians.


ttaann((_+_E_x_p_r))
    _R_e_s_u_l_t =tangus of _E_x_p_r.  _E_x_p_r is the angle in radians.


aassiinn((_+_E_x_p_r))
    _R_e_s_u_l_t =inverse sine of _E_x_p_r.  _R_e_s_u_l_t is the angle in radians.


aaccooss((_+_E_x_p_r))
    _R_e_s_u_l_t =inverse cosine of _E_x_p_r.  _R_e_s_u_l_t is the angle in radians.


aattaann((_+_E_x_p_r))
    _R_e_s_u_l_t =inverse tangus of _E_x_p_r.  _R_e_s_u_l_t is the angle in radians.


aattaann((_+_Y_E_x_p_r_, _+_X_E_x_p_r))
    _R_e_s_u_l_t = inverse tangus of _Y_E_x_p_r / _X_E_x_p_r.   _R_e_s_u_l_t is  the angle in
    radians.    The return  value is  in the  range [-pi:::pi].   Used  to
    convert between rectangular and polar coordinate system.


lloogg((_+_E_x_p_r))
    _R_e_s_u_l_t =natural logarithm of _E_x_p_r


lloogg1100((_+_E_x_p_r))
    _R_e_s_u_l_t =10 base logarithm of _E_x_p_r


eexxpp((_+_E_x_p_r))
    _R_e_s_u_l_t =e to the power _E_x_p_r


_+_E_x_p_r_1 ** _+_E_x_p_r_2
    _R_e_s_u_l_t =_E_x_p_r_1 to the power _E_x_p_r_2


_+_E_x_p_r_1 ^ _+_E_x_p_r_2
    Same as **/2.  (backward compatibility).


ppii
    Evaluates to the mathematical constant pi (3.141593).


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

ccppuuttiimmee
    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.


44..2288 AAddddiinngg AArriitthhmmeettiicc FFuunnccttiioonnss

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 declared.
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.


aarriitthhmmeettiicc__ffuunnccttiioonn((_+_H_e_a_d))
    Register  a Prolog  predicate as an  arithmetic function (see  is/2,
    >/2 , etc.).   The Prolog  predicate should  have one more  argument
    than  specified by _H_e_a_d, which it either a term _N_a_m_e_/_A_r_i_t_y,  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


ccuurrrreenntt__aarriitthhmmeettiicc__ffuunnccttiioonn((_?_H_e_a_d))
    Successively unifies all  arithmetic functions that are visible from
    the context module with _H_e_a_d.


44..2299 BBuuiilltt--iinn lliisstt ooppeerraattiioonnss

Most  list operations  are defined  in the  library  lists described  in
section 9.1.   Some that are implemented with more  low-level primitives
are built-in and described here.


iiss__lliisstt((_+_T_e_r_m))
    Succeeds  if _T_e_r_m is  bound to the  empty list ([])  or a term  with
    functor  `.' and arity 2  and the second argument  is a list.   This
    predicate acts as if defined by the following definition:

    is_list(X) :-
            var(X), !,
            fail.
    is_list([]).
    is_list([_|T]) :-
            is_list(T).


mmeemmbbeerrcchhkk((_?_E_l_e_m_, _+_L_i_s_t))
    Equivalent to member/2, but leaves no choice point.


lleennggtthh((_?_L_i_s_t_, _?_I_n_t))
    Succeeds  if _I_n_t  represents the  number of elements  of list  _L_i_s_t.
    Can be used to create a list holding only variables.


ssoorrtt((_+_L_i_s_t_, _-_S_o_r_t_e_d))
    Succeeds  if _S_o_r_t_e_d can be unified with a list holding  the elements
    of  _L_i_s_t, sorted to the standard  order of terms (see section  4.6).
    Duplicates  are removed.  The implementation is in C,  using _n_a_t_u_r_a_l
    _m_e_r_g_e _s_o_r_t


mmssoorrtt((_+_L_i_s_t_, _-_S_o_r_t_e_d))
    Equivalent to sort/2, but does not remove duplicates.


kkeeyyssoorrtt((_+_L_i_s_t_, _-_S_o_r_t_e_d))
    List  is a proper list whose elements are Key-Value, that  is, terms
    whose  principal  functor is  (-)/2,  whose  first argument  is  the
    sorting  key, and whose second argument is the satellite data  to be
    carried  along with  the key.   keysort/2  sorts _L_i_s_t like  msort/2,
    but  only compares  the  keys.   It  is 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.  The order of  multiple elements
    that have the same  _K_e_y is not changed.  The implementation is in C,
    using _n_a_t_u_r_a_l _m_e_r_g_e _s_o_r_t.


pprreeddssoorrtt((_+_P_r_e_d_, _+_L_i_s_t_, _-_S_o_r_t_e_d))
    Sorts  similar to sort/2, but determines  the order of two terms  by
    calling  _P_r_e_d(-_D_e_l_t_a, +_E_1, +_E_2).   This call  must unify _D_e_l_t_a  with
    one  of <, const>  or =.  If  built-in predicate compare/3 is  used,
    the result is the same as sort/2.  See also keysort/2.


mmeerrggee((_+_L_i_s_t_1_, _+_L_i_s_t_2_, _-_L_i_s_t_3))
    _L_i_s_t_1  and _L_i_s_t_2 are  lists, sorted to  the standard order of  terms
    (see  section 4.6).    _L_i_s_t_3 will be  unified with  an ordered  list
    holding  both the elements of _L_i_s_t_1  and _L_i_s_t_2.  Duplicates are  nnoott
    removed.


mmeerrggee__sseett((_+_S_e_t_1_, _+_S_e_t_2_, _-_S_e_t_3))
    _S_e_t_1  and _S_e_t_2 are lists without duplicates, sorted to  the standard
    order  of terms.    _S_e_t_3  is unified  with an  ordered list  without
    duplicates holding the union of the elements of _S_e_t_1 and _S_e_t_2.


44..3300 FFiinnddiinngg aallll SSoolluuttiioonnss ttoo aa GGooaall


ffiinnddaallll((_+_T_e_m_p_l_a_t_e_, _+_G_o_a_l_, _-_B_a_g))
    Creates  a list of the instantiations _T_e_m_p_l_a_t_e gets  successively on
    backtracking  over _G_o_a_l and unifies the  result with _B_a_g.   Succeeds
    with  an  empty  list  if _G_o_a_l  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.


bbaaggooff((_+_T_e_m_p_l_a_t_e_, _+_G_o_a_l_, _-_B_a_g))
    Unify  _B_a_g  with the  alternatives of  _T_e_m_p_l_a_t_e,  if _G_o_a_l  has  free
    variables   besides  the  one  sharing  with  _T_e_m_p_l_a_t_e   bagof  will
    backtrack  over the alternatives  of these free variables,  unifying
    _B_a_g with the  corresponding alternatives of _T_e_m_p_l_a_t_e.  The construct
    +Var^Goal  tells bagof not to  bind _V_a_r in _G_o_a_l.   bagof/3 fails  if
    _G_o_a_l 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 ?-


sseettooff((_+_T_e_m_p_l_a_t_e_, _+_G_o_a_l_, _-_S_e_t))
    Equivalent  to bagof/3, but sorts the  result using sort/2 to get  a
    sorted list of alternatives without duplicates.


44..3311 IInnvvookkiinngg PPrreeddiiccaatteess oonn aallll MMeemmbbeerrss ooff aa LLiisstt

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
call/[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 ``_P_r_e_d_i_c_a_t_e is applied on ...''


cchheecckklliisstt((_+_P_r_e_d_, _+_L_i_s_t))
    _P_r_e_d  is applied successively on each element of _L_i_s_t until  the end
    of  the list  or _P_r_e_d fails.    In the latter  case the  checklist/2
    fails.


mmaapplliisstt((_+_P_r_e_d_, _?_L_i_s_t_1_, _?_L_i_s_t_2))
    Apply  _P_r_e_d  on all  successive  pairs of  elements from  _L_i_s_t_1  and
    _L_i_s_t_2.    Fails if  _P_r_e_d can  not be  applied to a  pair.   See  the
    example above.


ssuubblliisstt((_+_P_r_e_d_, _+_L_i_s_t_1_, _?_L_i_s_t_2))
    Unify  _L_i_s_t_2 with  a list  of all elements  of _L_i_s_t_1  to which  _P_r_e_d
    applies.


44..3322 FFoorraallll


ffoorraallll((_+_C_o_n_d_, _+_A_c_t_i_o_n))
    For  all alternative bindings  of _C_o_n_d  _A_c_t_i_o_n can be  proven.   The
    example  verifies that all arithmetic  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).


44..3333 FFoorrmmaatttteedd WWrriittee

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.


44..3333..11 WWrriitteeff


wwrriitteellnn((_+_T_e_r_m))
    Equivalent to write(Term), nl.


wwrriitteeff((_+_A_t_o_m))
    Equivalent to writef(Atom, []).


wwrriitteeff((_+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s))
    Formatted  write.      _F_o_r_m_a_t  is  an  atom  whose  characters  will
    be   printed.     _F_o_r_m_a_t  may  contain  certain   special  character
    sequences   which  specify   certain  formatting  and   substitution
    actions.    _A_r_g_u_m_e_n_t_s then  provides all  the terms  required to  be
    output.

    Escape sequences to generate a single special character:

             __________________________________________________
             | \n   |Output  a  nemline  character  (see  also |
             |      |nl/[0,1])                                 |
             | \l   |Output a line separator (same as \n)      |

             | \r   |Output   a   carriage-return    character |
             |      |(ASCII 13)                                |
             | \t   |Output the ASCII character TAB (9)        |
             | \\   |The character \ is output                 |
             | \%   |The character % is output                 |
             | \nnn |where <_n_n_n>  is an  integer  (1-3 digits) |
             |      |the character  with character  code <_n_n_n> |

             |______|is_output_(NB_:_<_n_n_n>_is_read_as_ddeecciimmaall)_|

    Note  that  \l,   \nnn  and  \\  are  interpreted  differently  when
    character-escapes are in effect.  See section 2.15.1.1.

    Escape  sequences to include  arguments from _A_r_g_u_m_e_n_t_s.   Each  time
    a  %  escape sequence  is found  in _F_o_r_m_a_t  the  next argument  from
    _A_r_g_u_m_e_n_t_s is formatted according to the specification.

              _________________________________________________%t

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

              | %q  |write/1the next item                     |

              |     |writeq/1the next item                    |
              | %d  |Write the term,  ignoring operators.  See|
              |     |also  write_term/2.      Mnemonic:    old|
              | %p  |Edinburgh display/1.                     |

              |     |print/1the next item (identical to %t)   |
              | %n  |Put the  next item as  a character (i.e.,|

              |     |it is a character code)                  |
              | %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.__________|_


sswwrriitteeff((_-_S_t_r_i_n_g_, _+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s))
    Equivalent to writef/2,  but ``writes'' the result on _S_t_r_i_n_g instead
    of the current output stream.  Example:

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

    S = "Hello          World"


sswwrriitteeff((_-_S_t_r_i_n_g_, _+_F_o_r_m_a_t))
    Equivalent to swritef(String, Format, []).


44..3333..22 FFoorrmmaatt


ffoorrmmaatt((_+_F_o_r_m_a_t))
    Defined as `format(Format) :- format(Format, []).'


ffoorrmmaatt((_+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s))
    _F_o_r_m_a_t   is  an  atom,  list   of  character  codes,  or   a  Prolog
    string.   _A_r_g_u_m_e_n_t_s  provides the arguments  required by the  format
    specification.   If  only one argument is  required and this is  not
    a  list of character codes 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 `<_c_h_a_r_a_c_t_e_r>,
    representing the character  code 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w.  Compatibility reasons only.

      c  Interpret the next argument as an character code and  add it to
         the output.   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 _a_r_g_u_m_e_n_t  positions from the  right (useful for  doing
         fixed point arithmetic with integers, such as  handling amounts
         of money).

      D  Same as d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 exponential
         notation.    The  numeric  argument  specifies  the  precision.
         Default is  6 digits.   Exact representation  depends on the  C
         library function printf().   This function is invoked  with the
         format %.<_p_r_e_c_i_s_i_o_n>e.

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

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

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

      G  Floating point in EE or f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r, but uses upper case letters for digits above 9.

      s  Output text  from a list  of character codes  or a string  (see
         string/1 and section 4.23) from the next argument.

      t  All remaining space between 2 tabs tops  is distributed equally
         over ~t  statements  between the  tabs  tops.   This  space  is
         padded with  spaces by  default.   If an  argument is  supplied
         this is taken  to be the character  code 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 tabs top is assumed at the start of each line.

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

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

      w  Give the next argument to write/1.

      W  Give the  next two argument  to write_term/2.   This option  is
         SWI-Prolog specific.

    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


ffoorrmmaatt((_+_S_t_r_e_a_m_, _+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s))
    As format/2, but write the output on the given _S_t_r_e_a_m.


ssffoorrmmaatt((_-_S_t_r_i_n_g_, _+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s))
    Equivalent to format/2,  but ``writes'' the result on _S_t_r_i_n_g instead
    of the current output stream.  Example:

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

    S = "Hello          World"


ssffoorrmmaatt((_-_S_t_r_i_n_g_, _+_F_o_r_m_a_t))
    Equivalent to `sformat(String, Format, []).'


44..3333..33 PPrrooggrraammmmiinngg FFoorrmmaatt


ffoorrmmaatt__pprreeddiiccaattee((_+_C_h_a_r_, _+_H_e_a_d))
    If  a sequence ~c (tilde, followed by some character) is  found, the
    format  derivatives 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.   _C_h_a_r is  either an ascii  value,
    or  a one character atom,  specifying the letter to be  (re)defined.
    _H_e_a_d  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 default if  no argument is  specified.
    The  remaining arguments  are filled from  the argument  list.   The
    example  below redefines ~n to produce _A_r_g 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.


ccuurrrreenntt__ffoorrmmaatt__pprreeddiiccaattee((_?_C_o_d_e_, _?_:_H_e_a_d))
    Enumerates  all  user-defined  format  predicates.     _C_o_d_e  is  the
    character  code  of the  format character.    _H_e_a_d  is unified  with
    a  term with  the same  name and  arity as the  predicate.   If  the
    predicate  does not reside  in module user,  _H_e_a_d is qualified  with
    the definition module of the predicate.


44..3344 TTeerrmmiinnaall CCoonnttrrooll

The  following  predicates  form  a  simple  access   mechanism  to  the
Unix  termcap library  to provide  terminal independent  I/O for  screen
terminals.  These  predicates are only available on Unix machines.   The
SWI-Prolog Windows consoles accepts the ANSI escape sequences.


ttttyy__ggeett__ccaappaabbiilliittyy((_+_N_a_m_e_, _+_T_y_p_e_, _-_R_e_s_u_l_t))
    Get  the  capability named  _N_a_m_e  from the  termcap  library.    See
    termcap(5)  for the capability  names.   _T_y_p_e specifies the type  of
    the  expected result, and is one of string, number or 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.
    Successive queries on the same capability are fast.


ttttyy__ggoottoo((_+_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.


ttttyy__ppuutt((_+_A_t_o_m_, _+_L_i_n_e_s))
    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.
    _L_i_n_e_s is the number  of lines affected by the operation, or 1 if not
    applicable (as in almost all cases).


sseett__ttttyy((_-_O_l_d_S_t_r_e_a_m_, _+_N_e_w_S_t_r_e_a_m))
    Set  the  output  stream,  used by  tty_put/2  and tty_goto/2  to  a
    specific stream.  Default is user_output.


ttttyy__ssiizzee((_-_R_o_w_s_, _-_C_o_l_u_m_n_s))
    Determine the size of the terminal.  Platforms:

    UUnniixx  If  the  system  provides _i_o_c_t_l  calls  for  this,  these  are
         used and tty_size/2 properly  reflects the actual size after  a
         user resize  of the window.    As a fallback,  the system  uses
         tty_get_capability/2 using li  and co  capabilities.   In  this
         case the reported size reflects the size at the  first call and
         is not updated after a user-initiated resize of the terminal.

    WWiinnddoowwss  Getting  the   size  of  the   terminal  is  provided   for
         plwin.exe.   The  requested  value reflects  the current  size.
         For the multi-threaded  version the console that is  associated
         with the user_input stream is used.


44..3355 OOppeerraattiinngg SSyysstteemm IInntteerraaccttiioonn


sshheellll((_+_C_o_m_m_a_n_d_, _-_S_t_a_t_u_s))
    Execute  _C_o_m_m_a_n_d on the operating system.   _C_o_m_m_a_n_d is given to  the
    Bourne  shell (/bin/sh).  _S_t_a_t_u_s is unified with the exit  status of
    the command.

    On  _W_i_n_3_2  systems,  shell/[1,2]  executes  the  command  using  the
    CreateProcess()  API and  waits for the  command to  terminate.   If
    the  command  ends with  a &  sign,  the command  is  handed to  the
    WinExec()  API, which does not wait  for the new task to  terminate.
    See  also  win_exec/2  and  win_shell/2.     Please  note  that  the
    CreateProcess()  API does nnoott imply the Windows  command interpreter
    (command.exe  on  Windows  95/98  and  cmd.exe  on  Windows-NT)  and
    therefore  commands  built-in to  the command-interpreter  can  only
    be   activated  using  the  command  interpreter.      For  example:
    'command.exe /C copy file1.txt file2.txt'


sshheellll((_+_C_o_m_m_a_n_d))
    Equivalent to `shell(Command, 0)'.


sshheellll
    Start  an  interactive  Unix  shell.     Default  is  /bin/sh,   the
    environment  variable SHELL overrides this  default.  Not  available
    for Win32 platforms.


wwiinn__eexxeecc((_+_C_o_m_m_a_n_d_, _+_S_h_o_w))
    Win32  systems only.    Spawns a  Windows task  without waiting  for
    its  completion.  _S_h_o_w is  either iconic or normal and dictates  the
    initial  status of the window.   The iconic option is notably  handy
    to start (DDE) servers.


wwiinn__sshheellll((_+_O_p_e_r_a_t_i_o_n_, _+_F_i_l_e))
    Win32  systems only.    Opens the  document _F_i_l_e  using the  windows
    shell-rules  for doing  so.   _O_p_e_r_a_t_i_o_n  is  one of  open, print  or
    explore  or  another operation  registered with  the  shell for  the
    given document-type.   On modern systems it is also possible to pass
    a  URL as _F_i_l_e, opening  the URL in Windows  default browser.   This
    call interfaces to the Win32 API ShellExecute().


wwiinn__rreeggiissttrryy__ggeett__vvaalluuee((_+_K_e_y_, _+_N_a_m_e_, _-_V_a_l_u_e))
    Win32  systems  only.     Fetches the  value  of  a  Win32  registry
    key.     _K_e_y  is  an  atom formed  as  a  path-name  describing  the
    desired  registry key.   _N_a_m_e is the  desired attribute name of  the
    key.    _V_a_l_u_e  is  unified with  the value.    If  the value  is  of
    type  DWORD, the  value is returned  as an  integer.   If the  value
    is  a string  it is  returned as  a Prolog atom.    Other types  are
    currently  not supported.  The  default `root' is HKEY_CURRENT_USER.
    Other  roots  can  be  specified  explicitely as  HKEY_CLASSES_ROOT,
    HKEY_CURRENT_USER,  HKEY_LOCAL_MACHINE  or  HKEY_USERS.  The  example
    below fetches the  extension to use for Prolog files (see README.TXT
    on the Windows version):

    ?- win_registry_get_value('HKEY_LOCAL_MACHINE/Software/SWI/Prolog',
                              fileExtension,
                              Ext).

    Ext = pl


ggeetteennvv((_+_N_a_m_e_, _-_V_a_l_u_e))
    Get  environment variable.    Fails  silently if  the variable  does
    not  exist.     Please  note that  environment  variable  names  are
    case-sensitive on Unix systems and case-insensitive on Windows.


sseetteennvv((_+_N_a_m_e_, _+_V_a_l_u_e))
    Set  environment variable.   _N_a_m_e and  _V_a_l_u_e should be  instantiated
    to  atoms or  integers.   The  environment variable  will be  passed
    to  shell/[0-2] and  can be  requested using  getenv/2.   They  also
    influence expand_file_name/2.


uunnsseetteennvv((_+_N_a_m_e))
    Remove environment variable from the environment.


uunniixx((_+_C_o_m_m_a_n_d))
    This  predicate comes  from  the Quintus  compatibility library  and
    provides  a partial implementation thereof.   It provides access  to
    some operating system  features and unlike the name suggests, is not
    operating system specific.  Defined _C_o_m_m_a_n_d's are below.

    ssyysstteemm((_+_C_o_m_m_a_n_d))
         Equivalent to calling shell/1.  Use for compatibility only.

    sshheellll((_+_C_o_m_m_a_n_d))
         Equivalent to calling shell/1.  Use for compatibility only.

    sshheellll
         Equivalent to calling shell/0.  Use for compatibility only.

    ccdd
         Equivalent to calling working_directory/2 to the expansion (see
         expand_file_name/2) of ~.  For compatibility only.

    ccdd((_+_D_i_r_e_c_t_o_r_y))
         Equivalent   to  calling   working_directory/2.       Use   for
         compatibility only.

    aarrggvv((_-_A_r_g_v))
         Unify _A_r_g_v with the  list of commandline arguments provides  to
         this Prolog run.  Please note that  Prolog system-arguments and
         application arguments are separated  by --.  Integer  arguments
         are  passed as  Prolog  integers,  float arguments  and  Prolog
         floating  point  numbers and  all  other  arguments  as  Prolog
         atoms.  New applications should use the prolog-flag argv.   See
         also prolog prolog-flag argv.

         A  stand-alone program  could  use  the following  skeleton  to
         handle command-line arguments.  See also section 2.10.2.4.

         main :-
                 unix(argv(Argv)),
                 append(_PrologArgs, [--|AppArgs], Argv), !,
                 main(AppArgs).


44..3355..11 DDeeaalliinngg wwiitthh ttiimmee aanndd ddaattee

There is  no standard for time-representation  in the Prolog  community.
SWI-Prolog  represents it  as  a floating-point  number using  the  same
basic representation  as the POSIX standard,  seconds elapsed since  the
January  1970,  0 hours.    This  format  is  also used  for  predicates
accessing time-information from files (see time_file/2).


ggeett__ttiimmee((_-_T_i_m_e))
    Return  the number of  seconds that elapsed  since the epoch of  the
    POSIX,  tim representation:   January  1970,  0 hours.    _T_i_m_e is  a
    floating point number.  The granularity is system dependent.


ccoonnvveerrtt__ttiimmee((_+_T_i_m_e_, _-_Y_e_a_r_, _-_M_o_n_t_h_, _-_D_a_y_, _-_H_o_u_r_, _-_M_i_n_u_t_e_, _-_S_e_c_o_n_d_, _-_M_i_l_l_i_S_e_c_o_n_d_s))

    Convert   a  time  stamp,   provided  by   get_time/1,   time_file/2,
    etc.   _Y_e_a_r is  unified with the year,  _M_o_n_t_h with the month  number
    (January  is 1), _D_a_y  with the day of  the month (starting with  1),
    _H_o_u_r  with  the hour  of the  day (0--23),  _M_i_n_u_t_e  with the  minute
    (0--59).   _S_e_c_o_n_d with the  second (0--59) and _M_i_l_l_i_S_e_c_o_n_d with  the
    milliseconds  (0--999).  Note that the latter might not  be accurate
    or  might always be 0, depending  on the timing capabilities of  the
    system.  See also convert_time/2.


ccoonnvveerrtt__ttiimmee((_+_T_i_m_e_, _-_S_t_r_i_n_g))
    Convert  a time-stamp as  obtained though get_time/1 into a  textual
    representation  using the C-library function ctime().  The  value is
    returned  as a  SWI-Prolog string object  (see section  4.23).   See
    also convert_time/8.


44..3355..22 CCoonnttrroolllliinngg tthhee PLWIN.EXE ccoonnssoollee wwiinnddooww

The Windows executable  PLWIN.EXE console has a number of  predicates to
control the  appearance of  the console.    Being totally  non-portable,
we do  not advice using  it for your  own application,  but use XPCE  or
another  portable GUI  platform instead.    We give  the predicates  for
reference here.


wwiinnddooww__ttiittllee((_-_O_l_d_, _+_N_e_w))
    Unify  _O_l_d with the  title displayed in  the console and change  the
    title to _N_e_w.


wwiinn__wwiinnddooww__ppooss((_+_L_i_s_t_O_f_O_p_t_i_o_n_s))
    Interface  to the  MS-Windows  SetWindowPos() function,  controlling
    size,  position and stacking order of the window.   _L_i_s_t_O_f_O_p_t_i_o_n_s is
    a list that may hold any number of the terms below.

    ssiizzee((_W_, _H))
         Change the  size of  the window.    _W  and _H  are expressed  in
         character-units.

    ppoossiittiioonn((_X_, _Y))
         Change the  top-left corner  of  the window.    The values  are
         expressed in pixel units.

    zzoorrddeerr((_Z_O_r_d_e_r))
         Change the  location  in the  window stacking  order.    Values
         are bottom, top,  topmost and notopmost.   _T_o_p_m_o_s_t windows  are
         displayed above all other windows.

    sshhooww((_B_o_o_l))
         If true, show the window, if false hide the window.

    aaccttiivvaattee
         If present, activate the window.


wwiinn__hhaass__mmeennuu
    Suceeds if win_insert_menu/2 and win_insert_menu_item/4are present.


wwiinn__iinnsseerrtt__mmeennuu((_+_L_a_b_e_l_, _+_B_e_f_o_r_e))
    Insert  a new entry  (pulldown) in the  menu.   If the menu  already
    contains  this entry,  nothing  is done.    The _L_a_b_e_l  is the  label
    and  using the  Windows conventions,  a  letter prefixed  with &  is
    underlined  and defines the associated  accelerator key.  _B_e_f_o_r_e  is
    the label before which this one  must be inserted.  Using - adds the
    new  entry at the end (right).   For example, the call below  adds a
    Application entry just before the Help menu.

    win_insert_menu('&Application', '&Help')


wwiinn__iinnsseerrtt__mmeennuu__iitteemm((_+_P_u_l_l_d_o_w_n_, _+_L_a_b_e_l_, _+_B_e_f_o_r_e_, _:_G_o_a_l))
    Add  an  item  to  the  named  _P_u_l_l_d_o_w_n menu.     _L_a_b_e_l  and  _B_e_f_o_r_e
    are  handled  as in  win_insert_menu/2,  but the  label -  inserts  a
    _s_e_p_a_r_a_t_o_r.  _G_o_a_l is called if the user selects the item.


44..3366 FFiillee SSyysstteemm IInntteerraaccttiioonn


aacccceessss__ffiillee((_+_F_i_l_e_, _+_M_o_d_e))
    Succeeds  if _F_i_l_e exists and can be accessed by this  prolog process
    under  mode _M_o_d_e.   _M_o_d_e is  one of the  atoms read, write,  append,
    exist,  none or execute.  _F_i_l_e may also be the name  of a directory.
    Fails  silently otherwise.   access_file(File, none)simply  succeeds
    without testing anything.

    If  `Mode' is write or append,  this predicate also succeeds if  the
    file  does not exist and the user has write-access to  the directory
    of the specified location.


eexxiissttss__ffiillee((_+_F_i_l_e))
    Succeeds  when _F_i_l_e exists  and is a  regular file.   This does  not
    imply the user has read and/or write permission for the file.


ffiillee__ddiirreeccttoorryy__nnaammee((_+_F_i_l_e_, _-_D_i_r_e_c_t_o_r_y))
    Extracts  the  directory-part  of  _F_i_l_e.    The  returned  _D_i_r_e_c_t_o_r_y
    name  does  not end  in  /.   There  are  two special  cases.    The
    directory-name of /  is / itself and the directory-name if _F_i_l_e does
    not contain any / characters is ..


ffiillee__bbaassee__nnaammee((_+_F_i_l_e_, _-_B_a_s_e_N_a_m_e))
    Extracts the filename part  from a path specification.  If _F_i_l_e does
    not contain any directory separators, _F_i_l_e is returned.


ssaammee__ffiillee((_+_F_i_l_e_1_, _+_F_i_l_e_2))
    Succeeds  if both filenames refer to  the same physical file.   That
    is,  if _F_i_l_e_1  and _F_i_l_e_2  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).


eexxiissttss__ddiirreeccttoorryy((_+_D_i_r_e_c_t_o_r_y))
    Succeeds  if _D_i_r_e_c_t_o_r_y exists  and is  a directory.   This does  not
    imply  the user  has read, search  and or  write permission for  the
    directory.


ddeelleettee__ffiillee((_+_F_i_l_e))
    Remove _F_i_l_e from the file system.


rreennaammee__ffiillee((_+_F_i_l_e_1_, _+_F_i_l_e_2))
    Rename  _F_i_l_e_1 into _F_i_l_e_2.   Currently  files cannot be moved  across
    devices.


ssiizzee__ffiillee((_+_F_i_l_e_, _-_S_i_z_e))
    Unify _S_i_z_e with the size of _F_i_l_e in characters.


ttiimmee__ffiillee((_+_F_i_l_e_, _-_T_i_m_e))
    Unify  the last  modification time of  _F_i_l_e with  _T_i_m_e.   _T_i_m_e is  a
    floating  point number expressing the  seconds elapsed since Jan  1,
    1970.  See also convert_time/[2,8] and get_time/1.


aabbssoolluuttee__ffiillee__nnaammee((_+_F_i_l_e_, _-_A_b_s_o_l_u_t_e))
    Expand  a local file-name into an absolute path.  The  absolute path
    is  canonised:  references to . and .. are deleted.   This predicate
    ensures  that expanding  a file-name  it returns  the same  absolute
    path  regardless of  how the  file is  addressed.   SWI-Prolog  uses
    absolute  file names  to register  source files  independent of  the
    current  working directory.    See also  absolute_file_name/3.    See
    also absolute_file_name/3 and expand_file_name/2.


aabbssoolluuttee__ffiillee__nnaammee((_+_S_p_e_c_, _+_O_p_t_i_o_n_s_, _-_A_b_s_o_l_u_t_e))
    Converts  the  given  file  specification  into  an  absolute  path.
    _O_p_t_i_o_n is a list of options to guide the conversion:

    eexxtteennssiioonnss((_L_i_s_t_O_f_E_x_t_e_n_s_i_o_n_s))
         List of  file-extensions to  try.   Default is  ''.   For  each
         extension,  absolute_file_name/3 will first  add the  extension
         and then verify  the conditions imposed  by the other  options.
         If the  condition  fails, the  next extension  of  the list  is
         tried.   Extensions  may be specified  both as  ..ext or  plain
         ext.

    rreellaattiivvee__ttoo((_+_F_i_l_e_O_r_D_i_r))
         Resolve  the   path  relative   to  the   given  directory   or
         directory  the  holding   the  given  file.      Without   this
         option, paths  are resolved relative  to the working  directory
         (see   working_directory/2)   or,   if   _S_p_e_c  is   atomic   and
         absolute_file_name/[2,3] is executed  in a  directive, it  uses
         the current source-file as reference.

    aacccceessss((_M_o_d_e))
         Imposes the condition  access_file(_F_i_l_e, _M_o_d_e).   _M_o_d_e is on  of
         read, write, append, exist or none.  See also access_file/2.

    ffiillee__ttyyppee((_T_y_p_e))
         Defines  extensions.    Current  mapping:   txt  implies  [''],
         prolog  implies ['.pl', ''],  executable  implies  ['.so', ''],
         qlf implies  ['.qlf', '']  and  directory implies  [''].    The
         file-type source is  an alias for  prolog for compatibility  to
         SICStus Prolog.  See also prolog_file_type/2.

    ffiillee__eerrrroorrss((_f_a_i_l_/_e_r_r_o_r))
         If error (default), throw and  existence_error exception  if the
         file cannot be found.  If fail, stay silent.

    ssoolluuttiioonnss((_f_i_r_s_t_/_a_l_l))
         If  first (default),  the  predicates leaves  no  choice-point.
         Otherwise a  choice-point  will be  left and  backtracking  may
         yield more solutions.

    eexxppaanndd((_t_r_u_e_/_f_a_l_s_e))
         If  true  (default   is  false)  and   _S_p_e_c  is  atomic,   call
         expand_file_name/2  followed  by   member/2   on  _S_p_e_c   before
         proceeding.  This is a SWI-Prolog extension.

    The  prolog-flag  verbose_file_search  can be  set  to true  to  help
    debugging Prolog's search for files.

    Compatibility  considerations  to common  argument-order in  ISO  as
    well  as SICStus absolute_file_name/3forced us to  be flexible here.
    If  the last argument is a list  and the 2nd not, the  arguments are
    swapped,  making the call absolute_file_name(_+_S_p_e_c_,  _-_P_a_t_h_, _+_O_p_t_i_o_n_s)
    valid as well.


iiss__aabbssoolluuttee__ffiillee__nnaammee((_+_F_i_l_e))
    True  if _F_i_l_e specifies  and absolute path-name.   On Unix  systems,
    this   implies  the  path  starts  with  a  `/'.      For  Microsoft
    based   systems  this  implies  the   path  starts  with  <_l_e_t_t_e_r>:.
    This   predicate   is  intended   to  provide   platform-independent
    checking  for  absolute paths.    See also  absolute_file_name/2 and
    prolog_to_os_filename/2.


ffiillee__nnaammee__eexxtteennssiioonn((_?_B_a_s_e_, _?_E_x_t_e_n_s_i_o_n_, _?_N_a_m_e))
    This  predicate is used to add, remove or test  filename extensions.
    The  main reason  for  its introduction  is to  deal with  different
    filename  properties  in a  portable manner.    If  the file  system
    is   case-insensitive,  testing  for  an  extension  will   be  done
    case-insensitive too.   _E_x_t_e_n_s_i_o_n may be specified with or without a
    leading  dot (.).  If an _E_x_t_e_n_s_i_o_n is generated, it will  not have a
    leading dot.


eexxppaanndd__ffiillee__nnaammee((_+_W_i_l_d_C_a_r_d_, _-_L_i_s_t))
    Unify  _L_i_s_t with  a  sorted list  of files  or directories  matching
    _W_i_l_d_C_a_r_d.   The  normal Unix wildcard  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.

    If  the pattern  does contains  wildcard  characters, only  existing
    files  and directories are returned.  Expanding a  `pattern' without
    wildcard  characters returns the argument, regardless on  whether or
    not it exists.

    Before  expanding wildchards, the construct $var is expanded  to the
    value  of the  environment  variable _v_a_r  and a  possible leading  ~
    character is expanded to the user's home directory..


pprroolloogg__ttoo__ooss__ffiilleennaammee((_?_P_r_o_l_o_g_P_a_t_h_, _?_O_s_P_a_t_h))
    Converts  between the internal  Prolog pathname conventions and  the
    operating-system  pathname conventions.    The internal  conventions
    are  Unix and this predicates is  equivalent to =/2 (unify) on  Unix
    systems.   On  DOS systems it  will change the  directory-separator,
    limit  the filename length map dots,  except for the last one,  onto
    underscores.


rreeaadd__lliinnkk((_+_F_i_l_e_, _-_L_i_n_k_, _-_T_a_r_g_e_t))
    If _F_i_l_e points to  a symbolic link, unify _L_i_n_k with the value of the
    link and _T_a_r_g_e_t to  the file the link is pointing to.  _T_a_r_g_e_t points
    to  a file, directory or non-existing entry in the file  system, but
    never  to a link.   Fails if _F_i_l_e  is not a link.   Fails always  on
    systems that do not support symbolic links.


ttmmpp__ffiillee((_+_B_a_s_e_, _-_T_m_p_N_a_m_e))
    Create  a name for a temporary file.  _B_a_s_e is an  identifier for the
    category  of file.  The _T_m_p_N_a_m_e is guaranteed to be unique.   If the
    system  halts, it  will automatically  remove all created  temporary
    files.


mmaakkee__ddiirreeccttoorryy((_+_D_i_r_e_c_t_o_r_y))
    Create  a  new directory  (folder) on  the filesystem.    Raises  an
    exception  on failure.   On Unix systems,  the directory is  created
    with default permissions (defined by the process _u_m_a_s_k setting).


ddeelleettee__ddiirreeccttoorryy((_+_D_i_r_e_c_t_o_r_y))
    Delete directory (folder)  from the filesystem.  Raises an exception
    on failure.   Please note that in general it will not be possible to
    delete a non-empty directory.


wwoorrkkiinngg__ddiirreeccttoorryy((_-_O_l_d_, _+_N_e_w))
    Unify  _O_l_d with an  absolute path to  the current working  directory
    and   change  working   directory  to   _N_e_w.      Use  the   pattern
    working_directory(_C_W_D_, _C_W_D) to get the current directory.   See also
    absolute_file_name/2 and chdir/1.


cchhddiirr((_+_P_a_t_h))
    Compatibility predicate.  New code should use working_directory/2.


44..3377 UUsseerr TToopplleevveell MMaanniippuullaattiioonn


bbrreeaakk
    Recursively  start a new  Prolog top level.   This Prolog top  level
    has its 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-file character  (control-D). If  the
    -t toplevel  command  line  option is  given  this goal  is  started
    instead of entering the default interactive top level (prolog/0).


aabboorrtt
    Abort  the Prolog  execution  and restart  the top  level.   If  the
    -t toplevel  command  line options  is given  this  goal is  started
    instead of entering the default interactive top level.

    There  are two  implementations of abort/0.    The default one  uses
    the  exception  mechanism  (see  throw/1),  throwing  the  exception
    $aborted.   The other one uses the C-construct longjmp()  to discard
    the  entire environment  and rebuild a  new one.   Using  exceptions
    allows  for  proper recovery  of predicates  exploiting  exceptions.
    Rebuilding  the  environment  is  safer if  the  Prolog  stacks  are
    corrupt.    Therefore the  system will use  the rebuild-strategy  if
    the  abort was generated  by an internal  consistency check and  the
    exception  mechanism otherwise.   Prolog  can be  forced to use  the
    rebuild-strategy  setting  the prolog  flag  abort_with_exception  to
    false.


hhaalltt
    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.  Hooks may be registered both  in Prolog
    and  in foreign code.  Prolog hooks  are registered using at_halt/1.
    halt/0 is equivalent to halt(0).


hhaalltt((_+_S_t_a_t_u_s))
    Terminate  Prolog  execution  with  given  status.    Status  is  an
    integer.  See also halt/0.


pprroolloogg
    This  goal starts the  default interactive top  level.  Queries  are
    read  from the stream user_input.   See also the history prolog_flag
    (current_prolog_flag/2).    The  prolog/0  predicate  is  terminated
    (succeeds)  by typing  the  end-of-file character  (On most  systems
    control-D).

The following  two hooks allow  for expanding  queries and handling  the
result  of a  query.   These  hooks are  used by  the toplevel  variable
expansion mechanism described in section 2.8.


eexxppaanndd__qquueerryy((_+_Q_u_e_r_y_, _-_E_x_p_a_n_d_e_d_, _+_B_i_n_d_i_n_g_s_, _-_E_x_p_a_n_d_e_d_B_i_n_d_i_n_g_s))
    Hook  in module  user, normally  not defined.    _Q_u_e_r_y and  _B_i_n_d_i_n_g_s
    represents  the  query read  from  the user  and  the names  of  the
    free  variables as obtained  using read_term/3.   If this  predicate
    succeeds, it should  bind _E_x_p_a_n_d_e_d and _E_x_p_a_n_d_e_d_B_i_n_d_i_n_g_s to the query
    and  bindings to be  executed by  the toplevel.   This predicate  is
    used  by  the toplevel  (prolog/0).   See  also expand_answer/2  and
    term_expansion/2.


eexxppaanndd__aannsswweerr((_+_B_i_n_d_i_n_g_s_, _-_E_x_p_a_n_d_e_d_B_i_n_d_i_n_g_s))
    Hook  in module user,  normally not defined.   Expand the result  of
    a  successfully executed  toplevel  query.   _B_i_n_d_i_n_g_s  is the  query
    <_N_a_m_e>= <_V_a_l_u_e>binding list  from the query.  _E_x_p_a_n_d_e_d_B_i_n_d_i_n_g_s must
    be unified with the bindings the toplevel should print.


44..3388 CCrreeaattiinngg aa PPrroottooccooll ooff tthhee UUsseerr IInntteerraaccttiioonn

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.


pprroottooccooll((_+_F_i_l_e))
    Start  protocolling on file  _F_i_l_e.  If  there is already a  protocol
    file open then close it first.  If _F_i_l_e exists it is truncated.


pprroottooccoollaa((_+_F_i_l_e))
    Equivalent  to protocol/1,  but  does not  truncate the  _F_i_l_e if  it
    exists.


nnoopprroottooccooll
    Stop  making a protocol of the user interaction.  Pending  output is
    flushed on the file.


pprroottooccoolllliinngg((_-_F_i_l_e))
    Succeeds  if a protocol was  started with protocol/1 or  protocola/1
    and unifies _F_i_l_e with the current protocol output file.


44..3399 DDeebbuuggggiinngg aanndd TTrraacciinngg PPrrooggrraammss

This section is a  reference to the debugger interaction predicates.   A
more use-oriented overview of the debugger is in section 2.9.

If you have  installed XPCE, you can  use the graphical frontend of  the
tracer.  This frontend is installed using the predicate guitracer/0.


ttrraaccee
    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'.


ttrraacciinngg
    Succeeds  when  the tracer  is  currently switched  on.    tracing/0
    itself can not be seen in the tracer.


nnoottrraaccee
    Stop the tracer.  notrace/0 itself cannot be seen in the tracer.


gguuiittrraacceerr
    Installs  hooks  (see prolog_trace_interception/4) into  the  system
    that  redirects  tracing information  to  a GUI  frontend  providing
    structured  access to variable-bindings,  graphical overview of  the
    stack and highlighting of relevant source-code.


nnoogguuiittrraacceerr
    Reverts back to the textual tracer.


ttrraaccee((_+_P_r_e_d))
    Equivalent to trace(Pred, +all).


ttrraaccee((_+_P_r_e_d_, _+_P_o_r_t_s))
    Put  a  trace-point  on  all  predicates  satisfying  the  predicate
    specification  _P_r_e_d.   _P_o_r_t_s  is a  list of  portnames (call,  redo,
    exit,  fail).   The atom all refers  to all ports.   If the port  is
    preceded  by a - sign the trace-point  is cleared for the port.   If
    it is preceded by a + the trace-point is set.

    The  predicate trace/2  activates debug  mode (see debug/0).    Each
    time  a port (of the 4-port model) is passed that has  a trace-point
    set  the goal is printed as  with trace/0.  Unlike trace/0  however,
    the  execution is continued without asking for  further information.
    Examples:

        ?- trace(hello).         Trace all  ports of hello  with any
                                 arity in any module.
        ?- trace(foo/2, +fail).  Trace  failures  of  foo/2  in  any
                                 module.
        ?- trace(bar/1, -all).   Stop tracing bar/1.

    The predicate debugging/0 shows all currently defined trace-points.


nnoottrraaccee((_+_G_o_a_l))
    Call  _G_o_a_l,  but  suspend  the  debugger while  _G_o_a_l  is  executing.
    The  current  implementation cuts  the  choicepoints of  _G_o_a_l  after
    successful completion.   See once/1.  Later implementations may have
    the same semantics as call/1.


ddeebbuugg
    Start  debugger.     In  debug  mode,   Prolog  stops  at  spy-  and
    trace-points,  disables tail-recursion  optimisation and  aggressive
    destruction   of   choice-points  to   make  debugging   information
    accessible.  Implemented by the Prolog flag debug.


nnooddeebbuugg
    Stop  debugger.  Implementated by the  prolog flag debug.   See also
    debug/0.


ddeebbuuggggiinngg
    Print  debug status and  spy points on current  output stream.   See
    also the prolog flag debug.


ssppyy((_+_P_r_e_d))
    Put   a  spy   point  on  all   predicates  meeting  the   predicate
    specification _P_r_e_d.  See section 4.4.


nnoossppyy((_+_P_r_e_d))
    Remove   spy  point  from  all  predicates  meeting   the  predicate
    specification _P_r_e_d.


nnoossppyyaallll
    Remove all spy points from the entire program.


lleeaasshh((_?_P_o_r_t_s))
    Set/query leashing (ports  which allow for user interaction).  _P_o_r_t_s
    is  one of _+_N_a_m_e, _-_N_a_m_e,  _?_N_a_m_e or a list  of these.  _+_N_a_m_e  enables
    leashing  on that  port,  _-_N_a_m_e disables  it and  _?_N_a_m_e 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, full  refers to all ports  except for the unify  port
    (default).  half refers to the call, redo and fail port.


vviissiibbllee((_+_P_o_r_t_s))
    Set the ports shown  by the debugger.  See leash/1 for a description
    of the port specification.  Default is full.


uunnkknnoowwnn((_-_O_l_d_, _+_N_e_w))
    Edinburgh-prolog  compatibility predicate,  interfacing  to the  ISO
    prolog  flag unknown.   Values are  trace (meaning error) and  fail.
    If  the unknown flag is set to warning, unknown/2 reports  the value
    as trace.


ssttyyllee__cchheecckk((_+_S_p_e_c))
    Set  style checking options.   _S_p_e_c  is either  +<_o_p_t_i_o_n>, -<_o_p_t_i_o_n>,
    ?<_o_p_t_i_o_n>  or a  list  of such  options.    +<_o_p_t_i_o_n> sets  a  style
    checking option,  -<_o_p_t_i_o_n>clears it and ?<_o_p_t_i_o_n> succeeds or fails
    according to the  current setting.  consult/1 and derivatives 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_______________________________||singletonon|  ||

    |                         read_clause/1 (used by  consult/1)  warns |               ||
    |                         on variables  only  appearing once  in  a |               ||
    |                         term  (clause)  which  have  a  name  not |               ||

    ||atom          |  on    |starting with an underscore.              ||              ||

    |               |        |read/1 and  derivatives 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   |Backward    compatibility.            See |
    |               |        |the       prolog-flag       double_quotes |
    |_______________|________|(current_prolog_flag/2).__________________|


44..4400 OObbttaaiinniinngg RRuunnttiimmee SSttaattiissttiiccss


ssttaattiissttiiccss((_+_K_e_y_, _-_V_a_l_u_e))
    Unify system statistics  determined by _K_e_y with _V_a_l_u_e.  The possible
    keys  are given  in  the table  4.2.   The  last part  of the  table
    contains  keys  for compatibility  to other  Prolog  implementations
    (Quintus)  for improved  portability.   Note that  the ISO  standard
    does not define methods to collect system statistics.
_________________________________________________________________________
| agc                    |Number of atom garbage-collections performed   |
| agc_gained             N|umber of atoms removed                        |
| agc_time               T|ime spent in atom garbage-collections         |
| 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.                |
| heap                   |Estimated  total   size   of  the   heap   (see|
|                        |section 2.16.1.1)                              |
| heapused               |Bytes heap in use by Prolog.                   |
| heaplimit              |Maximum   size   of   the   heap    (see   sec-|
|                        |tion 2.16.1.1)                                 |

| 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.            |
| codes                  |Total amount of byte codes in all clauses.     |
| threads                |MT-version:  number of active threads          |
| threads_created        M|T-version:  number of created threads         |
| thread_cputime         M|T-version:  seconds CPU time used  by finished|
|                        t|hreads.   Supported on  Windows-NT and  later,|
|                        L|inux and  possibly  a few  more.    Verify  it|

|________________________g|ives_plausible_results_before_using.__________|
|___________________________Compatibility_keys___________________________ |
| runtime                |[   CPU   time,   CPU   time   since   last   ]|
|                        |(milliseconds)                                 |
| system_time            [|System CPU  time, System CPU time since  last |
|                        ]|(milliseconds)                                |
| real_time              [|Wall  time, Wall time  since last ]  (seconds |

|                        s|ince 1970)                                    |
| memory                 |[  Total unshared  data,  free memory  ]  (Uses|
|                        |getrusage() if available, otherwise  incomplete|
|                        |own statistics.                                |
| stacks                 |[ global use, local use ]                      |
| program                |[ heap, 0 ]                                    |
| global_stack           [|global use, global free ]                     |
| local_stack            [|local use, local free ]                       |

| trail                  |[ trail use, 0 ]                               |
| garbage_collection     [|number of GC, bytes gained, time spent ]      |
| stack_shifts           [|global  shifts,  local shifts,  time spent  ] |
|                        (|fails if no shifter in this version)          |
| atoms                  |[ number, memory use, 0 ]                      |
| atom_garbage_collection[|number of AGC, bytes gained, time spent ]     |
|_core___________________|Same_as_memory_________________________________|

                   Table 4.2:  Keys for statistics/2


ssttaattiissttiiccss
    Display a table of system statistics on the current output stream.


ttiimmee((_+_G_o_a_l))
    Execute  _G_o_a_l just  like once/1  (i.e., leaving  no choice  points),
    but  print used time, number  of logical inferences and the  average
    number  of  _l_i_p_s  (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.


44..4411 EExxeeccuuttiioonn pprrooffiilliinngg

This section  describes the  hierarchical execution profiler  introduced
in  SWI-Prolog 5.1.10.    This profiler  is based  on  ideas from  gprof
described  in  [??].     The  profiler  consists  of   two  parts:    the
information-gathering  is built  into  the kernel,  and  a  presentation
component which is  defined in the statistics  library.  The latter  can
be hooked, which  is used by the XPCE module  swi/pce_profile  to provide
an interactive graphical representation of results.


44..4411..11 PPrrooffiilliinngg pprreeddiiccaatteess

Currently, the interface is  kept compatible with the old profiler.   As
experience grows, it is  likely that the old interface is  replaced with
one that  better reflects the  new capabilities.   Feel free to  examine
the internal interfaces and report useful application thereof.


pprrooffiillee((_:_G_o_a_l))
    Execute  _G_o_a_l just like time/1, collecting profiling  statistics and
    call  show_profile(_p_l_a_i_n_, _2_5).   With  XPCE installed  this opens  a
    graphical interface to the collected profiling data.


pprrooffiillee((_:_G_o_a_l_, _+_S_t_y_l_e_, _+_N_u_m_b_e_r))
    Execute  _G_o_a_l just like  time/1.   Collect profiling statistics  and
    show  the top _N_u_m_b_e_r  procedures on the  current output stream  (see
    show_profile/1) using _S_t_y_l_e.   The results are kept in  the database
    until  reset_profiler/0or  profile/3 is called and can  be displayed
    again  with show_profile/1.  The  profile/1 predicate is a  backward
    compatibility interface to  profile/1.  The other predicates in this
    section are low-level predicates for special cases.


sshhooww__pprrooffiillee((_+_S_t_y_l_e_, _+_N_u_m_b_e_r))
    Show  the collected  results  of the  profiler.   It  shows the  top
    _N_u_m_b_e_r predicates according  the percentage cpu-time used.  If _S_t_y_l_e
    is  plain the time spent in the predicates itself is displayed.   If
    _S_t_y_l_e  is cumulative  the time  spent in its  siblings (callees)  is
    added to the predicate.

    This  predicate first calls prolog:show_profile_hook/2.  If XPCE  is
    loaded  this hook is used to  activate a GUI interface to  visialise
    the profile results.


sshhooww__pprrooffiillee((_+_N_u_m_b_e_r))
    Compatibility.  Same as show_profile(_p_l_a_i_n_, _N_u_m_b_e_r).


pprrooffiilleerr((_-_O_l_d_, _+_N_e_w))
    Query  or  change the  status of  the profiler.    The  status is  a
    boolean  (true or  false)  stating whether  or not  the profiler  is
    collecting  data.   It can  be used to  enable or disable  profiling
    certain parts of the program.


rreesseett__pprrooffiilleerr
    Switches the profiler to false and clears all collected statistics.


nnoopprrooffiillee((_+_N_a_m_e_/_+_A_r_i_t_y_, _._._.))
    Declares  the predicate _N_a_m_e/_A_r_i_t_y to be invisible to  the profiler.
    The  time  spend in  the  named predicate  is  added to  the  caller
    and  the  callees are  linked  directly  to the  caller.    This  is
    particulary  useful  for  simple  meta-predicates  such  as  call/1,
    ignore/1, catch/3, etc.


44..4411..22 VViissuuaalliizziinngg pprrooffiilliinngg ddaattaa

Browsing the annotated  call-tree as described in section 4.41.3  itself
is  not very  attractive.    Therefore,  the  results are  combined  per
predicate,  collecting  all _c_a_l_l_e_r_s  and  and  _c_a_l_l_e_e_s as  well  as  the
propagation  of time  and activations  in both  directions.   Figure  ????
illustrates  this.     The  central  yellowish  line  is  the  `current'
predicate with  counts for time  spent in  the predicate (`Self'),  time
spent in  its children  (`Siblings'), activations through  the call  and
redo ports.   Above  that are the _c_a_l_l_e_r_s.   Here,  the two time  fields
indicate  how much  time is  spent serving  each of  the callers.    The
columns sum to the time in the yellowish  line.  The caller <_r_e_c_u_r_s_i_v_e>
are  the number  of recursive  calls.   Below  the  yellowish lines  are
the callees, with  the time spent in  the callee itself for serving  the
current  predicate and  the time  spent  in the  callees of  the  callee
('Siblings'), so  the whole time-block adds  up to the `Siblings'  field
of the current predicate.   The `Access' fields show how many  times the
current predicate accesses each of the callees.

The predicates have a  menu that allows changing the view of  the detail
window to the given  caller or callee, showing the documentation  (if it
is a built-in) and/or jumping to the source.

The  statistics  shown  in  the  report-field  of  figure  ????  show  the
following information:

  o _s_a_m_p_l_e_s
    Number  of  times  the call-tree  was  sampled for  collecting  time
    statistics.   On  most hardware the  resolution of SIGPROF is  1/100
    second.    This number must  be sufficiently  large to get  reliable
    timing  figures.   The  Time menu  allows viewing  time as  samples,
    relative time or absolute time.

  o _s_e_c
    Total user CPU time with the profiler active.

  o _p_r_e_d_i_c_a_t_e_s
    Total  count of predicates that have  been called at least one  time
    during the profile.

  o _n_o_d_e_s
    Number of nodes in the call-tree.

  o _d_i_s_t_o_r_t_i_o_n
    How  much  of  the  time  is  spend  building  the  call-tree  as  a
    percentage  of the total execution time.   Timing samples while  the
    profiler is building the call-tree are not added to the call-tree.


44..4411..33 IInnffoorrmmaattiioonn ggaatthheerriinngg

While  the program  executes under  the profiler,  the  system builds  a
_d_y_n_a_m_i_c call-tree.    It does this  using three  hooks from the  kernel:
one that starts  a new goal (_p_r_o_f_C_a_l_l),  one the tells the system  which
goal  is  resumed after  an  _e_x_i_t  (_p_r_o_f_E_x_i_t)  and one  that  tells  the
system which  goal is  resumed after  a _f_a_i_l  (i.e. which  goal is  used
to _r_e_t_r_y  (_p_r_o_f_R_e_d_o)).   The  profCall() function finds  or creates  the
subnode for  the argument predicate below  the current node,  increments
the call-count of this  link and returns the sub-node which  is recorded
in the Prolog  stack-frame.  Choice-points  are marked with the  current
profiling  node.   profExit()  and profRedo()  pass  the profiling  node
where execution resumes.

Just using the above  algorithm would create a much too big tree  due to
recursion.  For this reason the system performs  detection of recursion.
In the  simplest case,  recursive procedures  increment the  `recursive'
count on  the current  node.   Mutual  recursion however  is not  easily
detected.   For example,  call/1 can call a  predicate that uses  call/1
itself.   This  can be  viewed as a  recursive invocation,  but this  is
generally not  desirable.   Recursion is currently  assumed if the  same
predicate _w_i_t_h _t_h_e _s_a_m_e _p_a_r_e_n_t appears higher in the  call-graph.  Early
experience with a some arbirary non-trivial programs are promising.

The last part of  the profiler collects statistics on the  CPU-time used
in  each node.    On  systems  providing  setitimer() with  SIGPROF,  it
`ticks' the  current node of  the call-tree each  time the timer  fires.
On Windows a MM-timer  in a seperate thread checks 100 times  per second
how much  time is  spent in  the profiled thread  and adds  this to  the
current node.  See section 4.41.3.1 for details.


44..4411..33..11 PPrrooffiilliinngg iinn tthhee WWiinnddoowwss IImmpplleemmeennttaattiioonn

Profiling in the Windows  version is similar but, especially  on Windows
95/98/ME one should  be aware of the  implementation.  Windows does  not
provide timers  that fire asynchronously,  frequent and proportional  to
the CPU  time used  by the process.    Windows does provide  multi-media
timers that  can run  at high  frequency.   Such timers  however run  in
a seperate  thread of  execution and  they are fired  on the  wall-clock
rather than  the amount of CPU  time used.   The profiler installs  such
a timer running, for  saving CPU time, rather inaccurately at  about 100
Hz.  Each time it is fired, it determines the  millisecons CPU time used
by Prolog since the last time it was fired.   If this value is non-zero,
active predicates are incremented with this value.

On  Windows 95/98/ME  (DOS-based Windows),  there is  no possibility  to
get the  CPU-time used  by a  thread or process.    TThheerreeffoorree,, oonn  tthheessee
ssyysstteemmss pprrooffiilliinngg  rreessuullttss ddooeess  nnoott ccoouunntt CCPPUU--ttiimmee,,  bbuutt eellaappsseedd  ttiimmee..
For sensible results  on these systems, ensure  the system has no  other
active tasks and  be aware that I/O  operations include the time  Prolog
is blocked waiting for data.


44..4422 MMeemmoorryy MMaannaaggeemmeenntt

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.


ggaarrbbaaggee__ccoolllleecctt
    Invoke  the global-  and trail  stack garbage collector.    Normally
    the  garbage   collector  is  invoked  automatically  if  necessary.
    Explicit  invocation  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.


ggaarrbbaaggee__ccoolllleecctt__aattoommss
    Reclaim  unused  atoms.     Normally  invoked  after  agc_margin  (a
    prolog  flag) atoms have been  created.  On multi-threaded  versions
    the   actual  collection  is  delayed  until  there  there   are  no
    threads  performing  normal  garbage  collection.     In  this  case
    garbage_collect_atoms/0  returns immediately.    Note  this  implies
    there  is no guarantee  it will _e_v_e_r happen  as there may always  be
    threads performing garbage collection.


lliimmiitt__ssttaacckk((_+_K_e_y_, _+_K_b_y_t_e_s))
    Limit one of the  stack areas to the specified value.  _K_e_y is one of
    local,  global or 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 unlimited the limit is set to
    its  maximum.   The maximum and initial  limit is determined by  the
    command line options -L, -G and -T.


ttrriimm__ssttaacckkss
    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, potentially large, amounts of
    stack space.  Such a loop should be written as follows:

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

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

ssttaacckk__ppaarraammeetteerr((_+_S_t_a_c_k_, _+_K_e_y_, _-_O_l_d_, _+_N_e_w))
    Query/set  a parameter  for the  runtime stacks.   _S_t_a_c_k  is one  of
    local,  global, trail or  argument.   The table below describes  the
    _K_e_y/_V_a_l_u_e pairs.  Old is first unified with the current value.

        ____________________________________________________________
        | limit    |Maximum size of the stack in bytes               |
        |_min_free_|Minimum_free_space_at_entry_of_foreign_predicate_|

    This predicate is  currently only available on versions that use the
    stack-shifter  to enlarge the runtime  stacks when necessary.   It's
    definition is subject to change.


44..4433 WWiinnddoowwss DDDDEE iinntteerrffaaccee

The  predicates in  this  section  deal with  MS-Windows  `Dynamic  Data
Exchange'  or DDE  protocol.    A Windows  DDE  conversation is  a  form
of interprocess  communication based  on sending reserved  window-events
between the communicating processes.

See also section 7.4 for loading Windows DLL's into SWI-Prolog.


44..4433..11 DDDDEE cclliieenntt iinntteerrffaaccee

The DDE client interface  allows Prolog to talk to DDE  server programs.
We  will demonstrate  the use  of the  DDE interface  using the  Windows
PROGMAN (Program Manager) application:

1 ?- open_dde_conversation(progman, progman, C).

C = 0
2 ?- dde_request(0, groups, X)

--> Unifies X with description of groups

3 ?- dde_execute(0, '[CreateGroup("DDE Demo")]').

Yes

4 ?- close_dde_conversation(0).

Yes

For  details   on  interacting  with   progman,   use  the  SDK   online
manual  section on  the  Shell  DDE interface.     See also  the  Prolog
library(progman),  which  may be  used  to  write simple  Windows  setup
scripts in Prolog.


ooppeenn__ddddee__ccoonnvveerrssaattiioonn((_+_S_e_r_v_i_c_e_, _+_T_o_p_i_c_, _-_H_a_n_d_l_e))
    Open a conversation  with a server supporting the given service name
    and  topic (atoms).    If successful,  _H_a_n_d_l_e  may be  used to  send
    transactions  to the server.    If no willing  server is found  this
    predicate fails silently.


cclloossee__ddddee__ccoonnvveerrssaattiioonn((_+_H_a_n_d_l_e))
    Close  the  conversation   associated  with  _H_a_n_d_l_e.     All  opened
    conversations  should  be  closed  when they're  no  longer  needed,
    although  the system  will  close any  that remain  open on  process
    termination.


ddddee__rreeqquueesstt((_+_H_a_n_d_l_e_, _+_I_t_e_m_, _-_V_a_l_u_e))
    Request  a value from the server.   _I_t_e_m is an atom  that identifies
    the  requested  data,  and  _V_a_l_u_e will  be  a string  (CF_TEXT  data
    in  DDE  parlance)  representing  that  data,   if  the  request  is
    successful.    If unsuccessful, _V_a_l_u_e  will be  unified with a  term
    of  form error(<_R_e_a_s_o_n>),  identifying the problem.   This call  uses
    SWI-Prolog  string objects  to return  the value  rather then  atoms
    to  reduce the  load on  the atom-space.    See section  4.23 for  a
    discussion on this data type.


ddddee__eexxeeccuuttee((_+_H_a_n_d_l_e_, _+_C_o_m_m_a_n_d))
    Request  the  DDE   server  to  execute  the  given  command-string.
    Succeeds  if the  command  could be  executed and  fails with  error
    message otherwise.


ddddee__ppookkee((_+_H_a_n_d_l_e_, _+_I_t_e_m_, _+_C_o_m_m_a_n_d))
    Issue  a POKE command to the server on the specified _I_t_e_m.   Command
    is passed as data of type CF_TEXT.


44..4433..22 DDDDEE sseerrvveerr mmooddee

The (autoload)  library(dde) defines  primitives to  realise simple  DDE
server applications in  SWI-Prolog.  These  features are provided as  of
version 2.0.6 and should be regarded prototypes.  The  C-part of the DDE
server can  handle some  more primitives,  so if you  need features  not
provided by this interface, please study library(dde).


ddddee__rreeggiisstteerr__sseerrvviiccee((_+_T_e_m_p_l_a_t_e_, _+_G_o_a_l))
    Register  a server  to handle  DDE request or  DDE execute  requests
    from  other applications.  To register a service for a  DDE request,
    _T_e_m_p_l_a_t_e is of the form:

         +Service(+Topic, +Item, +Value)

    _S_e_r_v_i_c_e  is the name  of the DDE  service provided (like progman  in
    the  client example  above).   _T_o_p_i_c is either  an atom,  indicating
    _G_o_a_l  only handles requests  on this topic  or a variable that  also
    appears  in _G_o_a_l.  _I_t_e_m and _V_a_l_u_e are variables that also  appear in
    _G_o_a_l.  _I_t_e_m represents the request data as a Prolog atom.

    The   example  below  registers   the  Prolog  current_prolog_flag/2
    predicate  to be accessible  from other applications.   The  request
    may  be  given  from  the  same  Prolog  as  well  as  from  another
    application.

    ?- dde_register_service(prolog(current_prolog_flag, F, V),
                            current_prolog_flag(F, V)).

    ?- open_dde_conversation(prolog, current_prolog_flag, Handle),
       dde_request(Handle, home, Home),
       close_dde_conversation(Handle).

    Home = '/usr/local/lib/pl-2.0.6/'

    Handling  DDE execute requests  is very similar.   In this case  the
    template is of the form:

         +Service(+Topic, +Item)

    Passing  a _V_a_l_u_e argument is  not needed as execute requests  either
    succeed  or fail.  If _G_o_a_l  fails, a `not processed' is  passed back
    to the caller of the DDE request.


ddddee__uunnrreeggiisstteerr__sseerrvviiccee((_+_S_e_r_v_i_c_e))
    Stop  responding  to  _S_e_r_v_i_c_e.     If  Prolog  is  halted,  it  will
    automatically call this on all open services.


ddddee__ccuurrrreenntt__sseerrvviiccee((_-_S_e_r_v_i_c_e_, _-_T_o_p_i_c))
    Find currently registered services and the topics served on them.


ddddee__ccuurrrreenntt__ccoonnnneeccttiioonn((_-_S_e_r_v_i_c_e_, _-_T_o_p_i_c))
    Find currently open conversations.


44..4444 MMiisscceellllaanneeoouuss


ddwwiimm__mmaattcchh((_+_A_t_o_m_1_, _+_A_t_o_m_2))
    Succeeds  if _A_t_o_m_1 matches _A_t_o_m_2  in `Do What I  Mean' sense.   Both
    _A_t_o_m_1  and _A_t_o_m_2  may also be  integers or  floats.   The two  atoms
    match if:

      o  They are identical

      o  They differ by one character (spy  spu)

      o  One character is inserted/deleted (debug  deug)

      o  Two characters are transposed (trace  tarce)

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

      o  Two   adjacent  sub   words  are   transposed   (existsFile
         fileExists)


ddwwiimm__mmaattcchh((_+_A_t_o_m_1_, _+_A_t_o_m_2_, _-_D_i_f_f_e_r_e_n_c_e))
    Equivalent  to  dwim_match/2,  but unifies  _D_i_f_f_e_r_e_n_c_e  with an  atom
    identifying the the  difference between _A_t_o_m_1 and _A_t_o_m_2.  The return
    values  are (in the same  order as above):   equal, mismatched_char,
    inserted_char, transposed_char, separated and transposed_word.


wwiillddccaarrdd__mmaattcchh((_+_P_a_t_t_e_r_n_, _+_S_t_r_i_n_g))
    Succeeds  if _S_t_r_i_n_g matches the  wildcard pattern _P_a_t_t_e_r_n.   _P_a_t_t_e_r_n
    is very similar 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 between the brackets.
            <_c_h_a_r_1>-<_c_h_a_r_2>indicates a range.
     {...}  Matches any of the patterns of the comma separated list between the braces.

    Example:

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

    Yes


ggeennssyymm((_+_B_a_s_e_, _-_U_n_i_q_u_e))
    Generate  a unique  atom from base  _B_a_s_e and  unify it with  _U_n_i_q_u_e.
    _B_a_s_e  should be an  atom.  The  first call will  return <_b_a_s_e>1,  the
    next  <_b_a_s_e>2, etc.   Note that this is  no warrant that the atom  is
    unique in the system.


sslleeeepp((_+_T_i_m_e))
    Suspend  execution _T_i_m_e seconds.   _T_i_m_e  is either a floating  point
    number  or an  integer.   Granularity is  dependent on the  system's
    timer  granularity.   A  negative time  causes the  timer to  return
    immediately.   On  most non-realtime operating  systems we can  only
    ensure execution is suspended for aatt lleeaasstt _T_i_m_e seconds.

    On  Unix systems the  sleep/1 predicate is  realised ---in order  of
    preference---  by nanosleep(),  usleep(),  select() if  the time  is
    below 1 minute or sleep().  On Windows systems Sleep() is used.


CChhaapptteerr 55..  UUSSIINNGG MMOODDUULLEESS


55..11 WWhhyy UUssiinngg MMoodduulleess??

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 intended  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 _p_u_b_l_i_c  _p_r_e_d_i_c_a_t_e_s 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.


55..22 NNaammee--bbaasseedd vveerrssuuss PPrreeddiiccaattee--bbaasseedd MMoodduulleess

Two approaches to  realize a module system  are commonly used in  Prolog
and other  languages.  The  first one is  the _n_a_m_e _b_a_s_e_d 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
_p_u_b_l_i_c.   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) :-
        atom_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 aallll 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 public  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.


55..33 DDeeffiinniinngg aa MMoodduullee

Modules normally are  created by loading a _m_o_d_u_l_e  _f_i_l_e.  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).


55..44 IImmppoorrttiinngg PPrreeddiiccaatteess iinnttoo aa MMoodduullee

As  explained  before,  in  the  predicate  based  approach  adapted  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 _i_m_p_o_r_t_i_n_g them from another module.

Two mechanisms for  importing predicates explicitly 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.


uussee__mmoodduullee((_+_F_i_l_e))
    Load  the  file(s) specified  with _F_i_l_e  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.


uussee__mmoodduullee((_+_F_i_l_e_, _+_I_m_p_o_r_t_L_i_s_t))
    Load  the file  specified  with _F_i_l_e  (only one  file is  accepted).
    _F_i_l_e  should be a module file.   _I_m_p_o_r_t_L_i_s_t 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.


iimmppoorrtt((_+_H_e_a_d))
    Import predicate _H_e_a_d  into the current context module.  _H_e_a_d should
    specify the  source module using the <_m_o_d_u_l_e>:<_t_e_r_m>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  inconvenient  to  have to  import  each  predicate
referred to by  the module, including the  system predicates.  For  this
reason each  module is  assigned a _d_e_f_a_u_l_t  _m_o_d_u_l_e.   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
one of  the module's _i_m_p_o_r_t  _m_o_d_u_l_e_s.  On  success, normal execution  is
resumed.


55..44..11 RReesseerrvveedd MMoodduulleess

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
import 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  import from  the module  user.    This implies  they
can use all  predicates imported into user without explicitly  importing
them.


55..55 UUssiinngg tthhee MMoodduullee SSyysstteemm

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  explicitly.   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 passing predicates.


55..55..11 OObbjjeecctt OOrriieenntteedd PPrrooggrraammmmiinngg

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 5.6.2 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  <_M_o_d_u_l_e>:<_G_o_a_l> explicitly  calls _G_o_a_l  in module  _M_o_d_u_l_e.
It is discussed in more detail in section 5.6.


55..66 MMeettaa--PPrreeddiiccaatteess iinn MMoodduulleess

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  choosing  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 explicitly.  For  this reason,
the notion _c_o_n_t_e_x_t _m_o_d_u_l_e has been introduced.


55..66..11 DDeeffiinniittiioonn aanndd CCoonntteexxtt MMoodduullee

Each  predicate  of  the program  is  assigned  a  module,  called  it's
_d_e_f_i_n_i_t_i_o_n _m_o_d_u_l_e.   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 _c_o_n_t_e_x_t _m_o_d_u_l_e 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 _m_o_d_u_l_e___t_r_a_n_s_p_a_r_e_n_t
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 successfully be applied to all succes-
sive pairs
%       of elements of List1 and List2.

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

55..66..22 OOvveerrrruulliinngg MMoodduullee BBoouunnddaarriieess

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  explicitly 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 _d_y_n_a_m_i_c _m_o_d_u_l_e_s (see section 5.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 `<_M_o_d_u_l_e>:<_T_e_r_m>'.  If  so,
the predicate is  searched for in _M_o_d_u_l_e  instead of the goal's  context
module.   The :  operator may be  nested, in  which case the  inner-most
module is used.

The special  calling construct  <_M_o_d_u_l_e>:<_G_o_a_l>pretends  _G_o_a_l is  called
from _M_o_d_u_l_e 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


55..77 DDyynnaammiicc MMoodduulleess

So  far,   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_a:consistent),
   world_a:unknown(_, fail).

These  calls  create  a  module  called  `world_a'  and  make  the  call
`world_a: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_b:export(solve(_,_)).          % exports solve/2 from world_b
?- world_c:import(world_b:solve(_,_)).  % and import it to world_c


55..88 MMoodduullee HHaannddlliinngg PPrreeddiiccaatteess

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

::-- mmoodduullee((_+_M_o_d_u_l_e_, _+_P_u_b_l_i_c_L_i_s_t))
    This directive can only  be used as the first term of a source file.
    It  declares  the file  to be  a _m_o_d_u_l_e  _f_i_l_e,  defining _M_o_d_u_l_e  and
    exporting  the predicates of  _P_u_b_l_i_c_L_i_s_t.   _P_u_b_l_i_c_L_i_s_t is a list  of
    name/arity pairs.


mmoodduullee__ttrraannssppaarreenntt _+_P_r_e_d_s
    _P_r_e_d_s   is  a  comma  separated  list  of  name/arity   pairs  (like
    dynamic/1).     Each goal  associated  with a  transparent  declared
    predicate will inherit the _c_o_n_t_e_x_t _m_o_d_u_l_e from its parent goal.


mmeettaa__pprreeddiiccaattee _+_H_e_a_d_s
    This  predicate  is  defined  in  quintus  and  provides  a  partial
    emulation of the Quintus predicate.  See section 5.9.1 for details.


ccuurrrreenntt__mmoodduullee((_-_M_o_d_u_l_e))
    Generates all currently known modules.


ccuurrrreenntt__mmoodduullee((_?_M_o_d_u_l_e_, _?_F_i_l_e))
    Is  true if _F_i_l_e is the file from which _M_o_d_u_l_e was loaded.   _F_i_l_e is
    the internal canonical filename.  See also source_file/[1,2].


ccoonntteexxtt__mmoodduullee((_-_M_o_d_u_l_e))
    Unify   _M_o_d_u_l_e  with  the  context  module  of  the   current  goal.
    context_module/1 itself is transparent.


eexxppoorrtt((_+_H_e_a_d))
    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.


eexxppoorrtt__lliisstt((_+_M_o_d_u_l_e_, _?_E_x_p_o_r_t_s))
    Unifies  _E_x_p_o_r_t_s with a list of terms.   Each term has the  name and
    arity  of a public predicate of _M_o_d_u_l_e.   The order of the  terms in
    _E_x_p_o_r_t_s is not defined.  See also predicate_property/2.


iimmppoorrtt__mmoodduullee((_+_M_o_d_u_l_e_, _-_I_m_p_o_r_t))
    True  if _I_m_p_o_r_t  is defined as  an import  module for _M_o_d_u_l_e.    All
    normal  modules only import  from user,  which imports from  system.
    The predicates  add_import_module/3and delete_import_module/2 can be
    used to manipulate the import list.


aadddd__iimmppoorrtt__mmoodduullee((_+_M_o_d_u_l_e_, _+_I_m_p_o_r_t_, _+_S_t_a_r_t_O_r_E_n_d))
    If  _I_m_p_o_r_t is not  already an  import module for  _M_o_d_u_l_e, add it  to
    this  list at the start  or end depending on  _S_t_a_r_t_O_r_E_n_d.  See  also
    import_module/2 and delete_import_module/2.


ddeelleettee__iimmppoorrtt__mmoodduullee((_+_M_o_d_u_l_e_, _+_I_m_p_o_r_t))
    Delete  _I_m_p_o_r_t from the  list of import modules  for _M_o_d_u_l_e.   Fails
    silently if _I_m_p_o_r_t is not in the list.


ddeeffaauulltt__mmoodduullee((_+_M_o_d_u_l_e_, _-_D_e_f_a_u_l_t))
    Succesively unifies _D_e_f_a_u_l_t  with the module names from which a call
    in  _M_o_d_u_l_e attempts to  use the  definition.   For the module  user,
    this  will generate user  and system.   For  any other module,  this
    will generate the module itself, followed by user and system.

    Backward compatibility.  New code should use import_module/2.


mmoodduullee((_+_M_o_d_u_l_e))
    The  call module(Module) may be  used to switch the default  working
    module  for the interactive  toplevel (see prolog/0).   This may  be
    used  to when  debugging  a module.    The example  below lists  the
    clauses of file_of_label/2 in the module tex.

    1 ?- module(tex).

    Yes
    tex: 2 ?- listing(file_of_label/2).
    ...


55..99 CCoommppaattiibbiilliittyy ooff tthhee MMoodduullee SSyysstteemm

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

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

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

  o 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:

  o Changing   a  meta_predicate   declaration  implies  all   predicates
    ccaalllliinngg  the predicate need to be reloaded.  This can  cause serious
    consistency problems.

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

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

  o 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  5.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 5.1:  findall/3 using modules


55..99..11 EEmmuullaattiinngg meta_predicate/1

The Quintus  meta_predicate/1 directive can  in many  cases be  replaced
by  the   transparent  declaration.      Below  is  the  definition   of
meta_predicate/1 as available from quintus.

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

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

CChhaapptteerr 66..  MMUULLTTII--TTHHRREEAADDEEDD AAPPPPLLIICCAATTIIOONNSS

SWI-Prolog multithreading is  based on standard C-language  multithread-
ing support.   It  is not like _P_a_r_L_o_g  or other paralel  implementations
of the Prolog language.   Prolog threads have their own stacks  and only
share the  Prolog _h_e_a_p:   predicates,  records, flags  and other  global
non-backtrackable data.  SWI-Prolog thread support is  designed with the
following goals in mind.

  o _M_u_l_t_i_-_t_h_r_e_a_d_e_d _s_e_r_v_e_r _a_p_p_l_i_c_a_t_i_o_n_s
    Todays   computing  services  often   focus  on  (internet)   server
    applications.   Such applications often have need  for communication
    between  services  and/or  fast  non-blocking  service  to  multiple
    concurrent  clients.   The shared  heap provides fast  communication
    and thread creation is relatively cheap.

  o _I_n_t_e_r_a_c_t_i_v_e _a_p_p_l_i_c_a_t_i_o_n_s
    Interactive   applications   often   need   to   perform   extensive
    computation.   If  such computations are  executed in a new  thread,
    the  main thread  can process events  and allow  the user to  cancel
    the  ongoing computation.    User interfaces can  also use  multiple
    threads,  each thread dealing  with input from  a distinct group  of
    windows.  See also section 6.7.

  o _N_a_t_u_r_a_l _i_n_t_e_g_r_a_t_i_o_n _w_i_t_h _f_o_r_e_i_g_n _c_o_d_e
    Each Prolog thread  runs in a native thread of the operating system,
    automatically  making them cooperate with _M_T_-_s_a_f_e foreign-code.   In
    addition,  any foreign thread can  create its own Prolog engine  for
    dealing with calling Prolog from C-code.

SWI-Prolog multi-threading  is based  on the POSIX  thread standard  [??]
used on most popular systems except for MS-Windows.   On Windows it uses
the  pthread-win32 emulation  of POSIX  threads mixed  with the  Windows
native API for smoother and faster operation.


66..11 CCrreeaattiinngg aanndd ddeessttrrooyyiinngg PPrroolloogg tthhrreeaaddss


tthhrreeaadd__ccrreeaattee((_:_G_o_a_l_, _-_I_d_, _+_O_p_t_i_o_n_s))
    Create  a new Prolog thread  (and underlying C-thread) and start  it
    by  executing  _G_o_a_l.   If  the thread  is created  succesfully,  the
    thread-identifier  of the created thread is unified to _I_d.   _O_p_t_i_o_n_s
    is a list of options.  Currently defined options are:

    llooccaall((_K_-_B_y_t_e_s))
         Set the  limit to  which  the local  stack of  this thread  may
         grow.   If omited,  the limit  of the  calling thread is  used.
         See also the -L commandline option.

    gglloobbaall((_K_-_B_y_t_e_s))
         Set the  limit to  which the global  stack of  this thread  may
         grow.   If omited,  the limit  of the  calling thread is  used.
         See also the -G commandline option.

    ttrraaiill((_K_-_B_y_t_e_s))
         Set the  limit to  which  the trail  stack of  this thread  may
         grow.   If omited,  the limit  of the  calling thread is  used.
         See also the -T commandline option.

    aarrgguummeenntt((_K_-_B_y_t_e_s))
         Set the limit  to which the argument  stack of this thread  may
         grow.   If omited,  the limit  of the  calling thread is  used.
         See also the -A commandline option.

    ssttaacckk((_K_-_B_y_t_e_s))
         Set  the  limit  to which  the  system  stack  of  this  thread
         may  grow.    The  default,  mimimum  and  maximum  values  are
         system-dependant.

    aalliiaass((_A_l_i_a_s_N_a_m_e))
         Associate an `alias-name' with  the thread.  This named  may be
         used to refer to the thread and remains valid  until the thread
         is joined (see thread_join/2).

    ddeettaacchheedd((_B_o_o_l))
         If  false  (default),  the  thread  can  be  waited  for  using
         thread_join/2.   thread_join/2 must  be called  on this  thread
         to  reclaim  the  all  resources  associated  to   the  thread.
         If  true, the  system  will  reclaim all  associated  resources
         automatically after  the thread  finishes.    Please note  that
         thread identifiers are freed for reuse after  a detached thread
         finishes  or a  normal  thread  has  been joined.     See  also
         thread_join/2 and thread_detach/1.

    The _G_o_a_l argument is  _c_o_p_i_e_d to the new Prolog engine.  This implies
    further  instantiation of this term  in either thread does not  have
    consequences  for the  other thread:   Prolog threads  do not  share
    data from their stacks.


tthhrreeaadd__sseellff((_-_I_d))
    Get  the Prolog thread  identifier of  the running thread.   If  the
    thread has an alias, the alias-name is returned.


tthhrreeaadd__jjooiinn((_+_I_d_, _-_S_t_a_t_u_s))
    Wait  for the termination of thread with  given _I_d.  Then  unify the
    result-status  of  the thread  with _S_t_a_t_u_s.    After this  call,  _I_d
    becomes  invalid and  all resources associated  with the thread  are
    reclaimed.    Note that  threads with  the attribute  detached(_t_r_u_e)
    cannot be joined.  See also current_thread/2.

    A thread  that has been completed without thread_join/2 being called
    on  it is partly reclaimed:  the Prolog stacks are released  and the
    C-thread  is destroyed.    A small  data-structure representing  the
    exit-status of  the thread is retained until thread_join/2 is called
    on the thread.  Defined values for _S_t_a_t_u_s are:

    ttrruuee
         The goal has been proven successfully.

    ffaallssee
         The goal has failed.

    eexxcceeppttiioonn((_T_e_r_m))
         The thread is terminated on an  exception.  See print_message/2
         to turn system exceptions into readable messages.

    eexxiitteedd((_T_e_r_m))
         The thread  is terminated on  thread_exit/1 using the  argument
         _T_e_r_m.


tthhrreeaadd__ddeettaacchh((_+_I_d))
    Switch  thread  into detached-state  (see detached(_B_o_o_l)  option  at
    thread_create/3)  at  runtime.     _I_d  is   the  identifier  of  the
    thread  placed  in detached  state.    This  may  be the  result  of
    PL_thread_self/1.

    One   of  the  possible  applications  is  to   simplify  debugging.
    Threads  that  are  created as  _d_e_t_a_c_h_e_d  leave  no traces  if  they
    crash.   For not-detached threads the status can be  inspected using
    current_thread/2.    Threads nobody is  waiting for  may be  created
    normally  and detach themselves  just before completion.   This  way
    they  leave no  traces  on normal  completion and  their reason  for
    failure can be inspected.


tthhrreeaadd__eexxiitt((_+_T_e_r_m))
    Terminates   the  thread   immediately,   leaving  exited(_T_e_r_m)   as
    result-state  for thread_join/2.   If the  thread has the  attribute
    detached(_t_r_u_e)  it  terminates,   but  its  exit  status  cannot  be
    retrieved  using thread_join/2 making the value of _T_e_r_m  irrelevant.
    The Prolog stacks and C-thread are reclaimed.


tthhrreeaadd__aatt__eexxiitt((_:_G_o_a_l))
    Run  _G_o_a_l  just before  releasing the  thread resources.    This  is
    to  be  compared to  at_halt/1, but  only  for the  current  thread.
    These  hooks are ran regardless of  why the execution of the  thread
    has  been  completed.    As these  hooks  are run,  the  return-code
    is  already available through  current_thread/2 using the result  of
    thread_self/1 as thread-identifier.


tthhrreeaadd__sseettccoonnccuurrrreennccyy((_-_O_l_d_, _+_N_e_w))
    Determine  the concurrency of the  process, which is defined as  the
    maximum  number  of  concurrently active  threads.    `Active'  here
    means  they are  using CPU time.    This option is  provided if  the
    thread-implementation  provides  pthread_setconcurrency().    Solaris
    is  a  typical example  of  this  family.    On other  systems  this
    predicate unifies _O_l_d to 0 (zero) and succeeds silently.


66..22 MMoonniittoorriinngg tthhrreeaaddss

Normal multi-threaded applications should not need  these the predicates
from  this section  because  almost any  usage  of these  predicates  is
unsafe.     For  example checking  the  existence  of  a  thread  before
signalling it  is of  no use  as it may  vanish between  the two  calls.
Catching exceptions  using catch/3  is the  only safe way  to deal  with
thread-existence errors.

These predicates are provided  for diagnosis and monitoring tasks.   See
also section 6.5, describing more high-level primitives.


ccuurrrreenntt__tthhrreeaadd((_?_I_d_, _?_S_t_a_t_u_s))
    Enumerates  identifiers and status  of all currently known  threads.
    Calling  current_thread/2 does not influence any  thread.  See  also
    thread_join/2.   For threads that  have an alias-name, this name  is
    returned  in _I_d instead of the numerical thread identifier.   _S_t_a_t_u_s
    is one of:

    rruunnnniinngg
         The  thread is  running.    This is  the  initial status  of  a
         thread.   Please note  that threads  waiting for something  are
         considered running too.

    ffaallssee
         The _G_o_a_l of the thread has been completed and failed.

    ttrruuee
         The _G_o_a_l of the thread has been completed and succeeded.

    eexxiitteedd((_T_e_r_m))
         The _G_o_a_l of the thread has  been terminated using thread_exit/1
         with _T_e_r_m  as argument.   If the  underlying native thread  has
         exited (using pthread_exit()) _T_e_r_m is unbound.

    eexxcceeppttiioonn((_T_e_r_m))
         The _G_o_a_l of the  thread has been terminated due to  an uncaught
         exception (see throw/1 and catch/3).


tthhrreeaadd__ssttaattiissttiiccss((_+_I_d_, _+_K_e_y_, _-_V_a_l_u_e))
    Obtains  statistical information on  thread _I_d as statistics/2  does
    in  single-threaded applications.    This call returns  all keys  of
    statistics/2, although  only information statistics about the stacks
    and CPU time yield different values for each thread.


mmuutteexx__ssttaattiissttiiccss
    Print  usage statistics on  internal mutexes and mutexes  associated
    with  dynamic predicates.  For  each mutex two numbers are  printed:
    the  number  of times  the  mutex was  acquired  and the  number  of
    _c_o_l_l_i_s_i_o_n_s:   the number  times the calling  thread has to wait  for
    the  mutex.   The collistion-count  is not  available on Windows  as
    this  would break portability  to Windows-95/98/ME or  significantly
    harm  performance.   Generally collision count  is close to zero  on
    single-CPU hardware.


66..33 TThhrreeaadd ccoommmmuunniiccaattiioonn


66..33..11 MMeessssaaggee qquueeuueess

Prolog  threads can  exchange data  using dynamic  predicates,  database
records,  and other globally  shared data.   These  provide no  suitable
means to wait for data or a condition as they can  only be checked in an
expensive polling loop.   _M_e_s_s_a_g_e _q_u_e_u_e_s provide a means for  threads to
wait for data or conditions without using the CPU.

Each thread  has a message-queue  attached to it  that is identified  by
the thread.  Additional queues are created using message_queue_create/2.


tthhrreeaadd__sseenndd__mmeessssaaggee((_+_Q_u_e_u_e_O_r_T_h_r_e_a_d_I_d_, _+_T_e_r_m))
    Place  _T_e_r_m in  the given queue  or default  queue of the  indicated
    thread  (which  can  even  be  the  message  queue  of  itself  (see
    thread_self/1).    Any  term  can  be  placed in  a  message  queue,
    but  note  that the  term  is copied  to  the receiving  thread  and
    variable-bindings are thus lost.  This call returns immediately.

    If  more than one thread is waiting for messages on the  given queue
    and  at least one of these is waiting with a  partially instantiated
    _T_e_r_m,  the waiting threads are _a_l_l sent a wakeup signal,  starting a
    rush  for the available messages in  the queue.  This behaviour  can
    seriously  harm performance  with many threads  waiting on the  same
    queue  as all-but-the-winner  perform a useless  scan of the  queue.
    If  there is  only one waiting  thread or  all waiting threads  wait
    with  an unbound variable an  arbitrary thread is restarted to  scan
    the queue.


tthhrreeaadd__ggeett__mmeessssaaggee((_?_T_e_r_m))
    Examines the thread  message-queue and if necessary blocks execution
    until  a term that unifies  to _T_e_r_m arrives in  the queue.  After  a
    term  from the queue has been  unified unified to _T_e_r_m, the  term is
    deleted from the queue and this predicate returns.

    Please  note that not-unifying messages remain in the queue.   After
    the  following has been  executed, thread 1  has the term b(_g_n_u)  in
    its queue and continues execution using _A is gnat.

       <thread 1>
       thread_get_message(a(A)),

       <thread 2>
       thread_send_message(b(gnu)),
       thread_send_message(a(gnat)),

    See also thread_peek_message/1.


tthhrreeaadd__ppeeeekk__mmeessssaaggee((_?_T_e_r_m))
    Examines  the thread  message-queue  and compares  the queued  terms
    with   _T_e_r_m  until  one  unifies  or  the  end  of  the   queue  has
    been  reached.    In  the first  case  the call  succeeds  (possibly
    instantiating  _T_e_r_m.   If no term from  the queue unifies this  call
    fails.


mmeessssaaggee__qquueeuuee__ccrreeaattee((_?_Q_u_e_u_e))
    If  _Q_u_e_u_e is an atom, create a  named queue.  To avoid  ambiguity of
    thread_send_message/2, the name  of a queue may  not be in use as  a
    thread-name.  If  _Q_u_e_u_e is unbound an anonymous queue is created and
    _Q_u_e_u_e is unified to its identifier.


mmeessssaaggee__qquueeuuee__ddeessttrrooyy((_+_Q_u_e_u_e))
    Destroy  a message queue created with message_queue_create/1.   It is
    _n_o_t allows to destroy  the queue of a thread.  Neither is it allowed
    to  destroy a queue other threads are waiting for or,  for anynymous
    message queues, may try to wait for later.


tthhrreeaadd__ggeett__mmeessssaaggee((_+_Q_u_e_u_e_, _?_T_e_r_m))
    As  thread_get_message/1, operating on a given queue.   It is allowed
    (but not advised) to get messages from the queue of other threads.


tthhrreeaadd__ggeett__mmeessssaaggee((_+_Q_u_e_u_e_, _?_T_e_r_m))
    As  thread_get_message/1, operating on a given queue.   It is allowed
    to  peek into another thread's message queue, an operation  that can
    be  used to check whether a  thread has swallowed a message sent  to
    it.

Explicit  message queues  are  designed with  the _w_o_r_k_e_r_-_p_o_o_l  model  in
mind,  where  multiple  threads wait  on  a  single queue  and  pick  up
the first  goal to  execute.   Below  is a  simple implementation  where
the workers  execute arbitrary  Prolog goals.   Note  that this  example
provides no means to tell when all work is done.   This must be realised
using additional synchronisation.

%       create_workers(+Id, +N)
%
%       Create a pool with given Id and number of workers.

create_workers(Id, N) :-
        message_queue_create(Id),
        forall(between(1, N, _),
               thread_create(do_work(Id), _, [])).

do_work(Id) :-
        repeat,
          thread_get_message(Id, Goal),
          (   catch(Goal, E, print_message(error, E))
          ->  true
          ;   print_message(error, goal_failed(Goal, worker(Id)))
          ),
        fail.

%       work(+Id, +Goal)
%
%       Post work to be done by the pool

work(Id, Goal) :-
        thread_send_message(Id, Goal).


66..33..22 SSiiggnnaalllliinngg tthhrreeaaddss

These  predicates provide  a mechanism  to make  another thread  execute
some  goal as  an  _i_n_t_e_r_r_u_p_t.    Signalling  threads  is safe  as  these
interrupts  are only  checked at  safe points  in  the virtual  machine.
Nevertheless,  signalling  in  multi-threaded   environments  should  be
handled  with  care as  the  receiving  thread  may hold  a  _m_u_t_e_x  (see
with_mutex).   Signalling  probably only makes  sense to start  debugging
threads and to  cancel no-longer-needed threads with throw/1,  where the
receiving thread  should be designed carefully  do handle exceptions  at
any point.


tthhrreeaadd__ssiiggnnaall((_+_T_h_r_e_a_d_I_d_, _:_G_o_a_l))
    Make thread _T_h_r_e_a_d_I_d execute  _G_o_a_l at the first opportunity.  In the
    current  implementation, this implies at the first pass  through the
    _C_a_l_l_-_p_o_r_t.   The  predicate thread_signal/2 itself places _G_o_a_l  into
    the signalled-thread's signal queue and returns immediately.

    Signals  (interrupts)  do  not  cooperate well  with  the  world  of
    multi-threading,  mainly  because the  status of  mutexes cannot  be
    guaranteed  easily.   At the call-port,  the Prolog virtual  machine
    holds no locks and therefore the asynchronous execution is safe.

    _G_o_a_l  can be any  valid Prolog goal,  including throw/1 to make  the
    receiving thread generate  an exception and trace/0 to start tracing
    the receiving thread.

    In  the Windows version,  the receiving thread immediately  executes
    the  signal  if  it  reaches  a  Windows  GetMessage()  call,  which
    generally happens of the thread is waiting for (user-)input.


66..33..33 TThhrreeaaddss aanndd ddyynnaammiicc pprreeddiiccaatteess

Besides  queues (section  6.3.1)  threads can  share and  exchange  data
using dynamic  predicates.  The  multi-threaded version knows about  two
types of dynamic predicates.   By default, a predicate  declared _d_y_n_a_m_i_c
(see dynamic/1)  is shared  by all  threads.   Each  thread may  assert,
retract and  run the dynamic predicate.   Synchronisation inside  Prolog
guarantees  the consistency  of the  predicate.    Updates are  _l_o_g_i_c_a_l:
visible  clauses  are  not affected  by  assert/retract  after  a  query
started on  the predicate.   In  many cases  primitive from section  6.4
should be  used to ensure  application invariants  on the predicate  are
maintained.

Besides shared predicates,  dynamic predicates can be declared  with the
thread_local/1 directive.   Such predicates share their attributes,  but
the clause-list is different in each thread.


tthhrreeaadd__llooccaall _+_F_u_n_c_t_o_r_/_+_A_r_i_t_y_, _._._.
    This  directive is  related to the  dynamic/1 directive.   It  tells
    the  system  that  the predicate  may  be modified  using  assert/1,
    retract/1,  etc. during  execution of  the program.   Unlike  normal
    shared dynamic data  however each thread has its own clause-list for
    the  predicate.   As  a thread starts,  this clause  list is  empty.
    If  there  are still  clauses  as the  thread terminates  these  are
    automatically  reclaimed by the system  (see also volatile/1).   The
    thread_local property implies the properties dynamic and volatile.

    Thread-local   dynamic  predicates  are  intended  for   maintaining
    thread-specific state or intermediate results of a computation.

    It  is not recommended to  put clauses for a thread-local  predicate
    into  a file as in the example  below as the clause is  only visible
    from  the thread  that loaded the  source-file.   All other  threads
    start with an empty clause-list.

    :- thread_local
            foo/1.

    foo(gnat).

    DDIISSCCLLAAIIMMEERR  Whether or  not this  declaration is  apropriate in  the
    sense  of the proper mechanism to  reach the goal is still  debated.
    If  you have strong feeling in favour or against, please  share them
    in the SWI-Prolog mailing list.


66..44 TThhrreeaadd ssyynncchhrroonniissaattiioonn

All  internal Prolog  operations  are thread-safe.    This  implies  two
Prolog  threads  can  operate on  the  same  dynamic  predicate  without
corrupting the consistency  of the predicate.   This section deals  with
user-level  _m_u_t_e_x_e_s (called  _m_o_n_i_t_o_r_s  in  ADA or  _c_r_i_t_i_c_a_l_-_s_e_c_t_i_o_n_s  by
Microsoft).   A  mutex is a  MMUUTTual EEXXclusive device,  which implies  at
most one thread can _h_o_l_d a mutex.

Mutexes are  used to  realise related  updates to  the Prolog  database.
With `related', we refer to the situation where  a `transaction' implies
two  or more  changes to  the Prolog  database.   For  example, we  have
a  predicate address/2,  representing the  address of  a  person and  we
want  to change  the address  by retracting  the old  and asserting  the
new address.    Between these  two operations the  database is  invalid:
this person  has either no  address or two  addresses, depending on  the
assert/retract order.

Here is how to realise a correct update:

:- initialization
        mutex_create(addressbook).

change_address(Id, Address) :-
        mutex_lock(addressbook),
        retractall(address(Id, _)),
        asserta(address(Id, Address)),
        mutex_unlock(addressbook).


mmuutteexx__ccrreeaattee((_?_M_u_t_e_x_I_d))
    Create  a mutex.  if _M_u_t_e_x_I_d  is an atom, a _n_a_m_e_d mutex  is created.
    If  it is  a variable,  an  anonymous mutex  reference is  returned.
    There is no limit to the number of mutexes that can be created.


mmuutteexx__ddeessttrrooyy((_+_M_u_t_e_x_I_d))
    Destroy  a mutex.    After this  call, _M_u_t_e_x_I_d  becomes invalid  and
    further references yield an existence_error exception.


wwiitthh__mmuutteexx((_+_M_u_t_e_x_I_d_, _:_G_o_a_l))
    Execute  _G_o_a_l while holding _M_u_t_e_x_I_d.  If _G_o_a_l  leaves choicepointes,
    these  are  destroyed  (as  in  once/1).    The  mutex  is  unlocked
    regardless  of whether _G_o_a_l succeeds, fails or raises  an exception.
    An  exception thrown by _G_o_a_l is  re-thrown after the mutex has  been
    successfully unlocked.  See also mutex_create/2 and call_cleanup/3.

    Although  described in  the thread-section,  this predicate is  also
    available  in the single-threaded  version, where it behaves  simply
    as once/1.


mmuutteexx__lloocckk((_+_M_u_t_e_x_I_d))
    Lock  the mutex.   Prolog mutexes are  _r_e_c_u_r_s_i_v_e mutexes:  they  can
    be  locked multiple times by the same thread.  Only  after unlocking
    it  as many times as it  is locked, the mutex becomes  available for
    locking  by other threads.   If another thread has locked the  mutex
    the calling thread is suspended until to mutex is unlocked.

    If  _M_u_t_e_x_I_d is  an atom,  and there  is no current  mutex with  that
    name,  the  mutex  is  created automatically  using  mutex_create/1.
    This implies named mutexes need not be declared explicitly.

    Please  note that  locking and  unlocking mutexes  should be  paired
    carefully.    Especially make  sure to  unlock mutexes  even if  the
    protected  code  fails or  raises an  exception.    For most  common
    cases  use  with_mutex/2,  wich  provides a  safer way  for  handling
    prolog-level  mutexes.  The predicate  call_cleanup/[2-3]is  another
    way  to  guarantee  that  the  mutex  is  unlocked  while  retaining
    non-determinism.


mmuutteexx__ttrryylloocckk((_+_M_u_t_e_x_I_d))
    As  mutex_lock/1,  but if the mutex  is held by another thread,  this
    predicates fails immediately.


mmuutteexx__uunnlloocckk((_+_M_u_t_e_x_I_d))
    Unlock  the mutex.  This can only be called if the mutex  is held by
    the  calling thread.   If this is  not the case,  a permission_error
    exception is raised.


mmuutteexx__uunnlloocckk__aallll
    Unlock  all  mutexes held  by the  current  thread.   This  call  is
    especially  useful  to handle  thread-termination using  abort/0  or
    exceptions.  See also thread_signal/2.


ccuurrrreenntt__mmuutteexx((_?_M_u_t_e_x_I_d_, _?_T_h_r_e_a_d_I_d_, _?_C_o_u_n_t))
    Enumerates  all existing  mutexes.   If the  mutex is  held by  some
    thread,  _T_h_r_e_a_d_I_d  is  unified with  the  identifier of  te  holding
    thread and _C_o_u_n_t with  the recursive count of the mutex.  Otherwise,
    _T_h_r_e_a_d_I_d is [] and _C_o_u_n_t is 0.


66..55 TThhrreeaadd--ssuuppppoorrtt lliibbrraarryy((tthhrreeaadduuttiill))

This library  defines a  couple of useful  predicates for  demonstrating
and debugging  multi-threaded applications.   This library is  certainly
not complete.


tthhrreeaaddss
    Lists  all  current threads  and their  status.   In  addition,  all
    `zombie'  threads  (finished  threads that  are  not  detached,  nor
    waited for) are joined to reclaim their resources.


iinntteerraaccttoorr
    Create  a  new console  and  run the  Prolog  toplevel in  this  new
    console.   See also attach_console/0.  In the Windows version  a new
    interactor can also be created from the Run/New thread menu.


aattttaacchh__ccoonnssoollee
    If  the  current thread  has no  console  attached yet,  attach  one
    and  redirect the  user streams (input,  output, and  error) to  the
    new  console  window.   On  Unix  systems the  console is  an  xterm
    application.    On  Windows systems  this requires  the GUI  version
    plwin.exe rather than the console based plcon.exe.

    This  predicate has  a couple  of useful applications.    One is  to
    separate (debugging) I/O  of different threads.  Another is to start
    debugging  a thread that  is running in the  background.  If  thread
    10  is running,  the following  sequence starts the  tracer on  this
    thread:

    ?- thread_signal(10, (attach_console, trace)).


66..66 MMuullttii--tthhrreeaaddeedd mmiixxeedd CC aanndd PPrroolloogg aapppplliiccaattiioonnss

All foreign-code  linked to  the multi-threading  version of  SWI-Prolog
should  be   thread-safe  (_r_e_e_n_t_r_a_n_t)   or  guarded   in  Prolog   using
with_mutex/2 from  simultaneous  access  from multiple  Prolog  threads.
If  you want  to write  mixed multi-threaded  C  and Prolog  application
you  should  first  familiarise  yourself  with  writing  multi-threaded
applications in C (C++).

If you are  using SWI-Prolog as an  embedded engine in a  multi-threaded
application you  can access the Prolog  engine from multiple threads  by
creating an _e_n_g_i_n_e in  each thread from which you call Prolog.   Without
creating an engine, a thread can only use functions that  do _n_o_t use the
term_t type (for example PL_new_atom()).

The system  supports two models.   Section  6.6.1 describes the  orginal
one-to-one mapping.   In this schema  a native thread attaches a  Prolog
thread if  it needs  to call Prolog  and detaches is  when finished,  as
opposed to the  model from section 6.6.2  where threads temporary use  a
Prolog engine.

PPlleeaassee nnoottee  tthhaatt tthhee  iinntteerrffaaccee bbeellooww  wwiillll oonnllyy wwoorrkk  iiff tthhrreeaaddiinngg  iinn
yyoouurr aapppplliiccaattiioonn iiss bbaasseedd oonn tthhee ssaammee tthhrreeaadd--lliibbrraarryy aass  uusseedd ttoo ccoommppiillee
SSWWII--PPrroolloogg..


66..66..11 AA PPrroolloogg tthhrreeaadd ffoorr eeaacchh nnaattiivvee tthhrreeaadd ((oonnee--ttoo--oonnee))

In  the  one-to-one  model,   the  thread  that  called  PL_initialise()
has  a   Prolog  engine  attached.      If   another  C-thread  in   the
system  wishes to  call Prolog  it  must first  attach an  engine  using
PL_thread_attach_engine() and call  PL_thread_destroy_engine()after  all
Prolog  work is  finished.    This  model  is especially  suitable  with
long  running threads  that  need  to do  Prolog  work  regulary.    See
section 6.6.2 for the alternative many-to-many model.


int PPLL__tthhrreeaadd__sseellff()
    Returns  the integer Prolog  identifier of the  engine or -1 if  the
    calling  thread  has  no Prolog  engine.    This  function  is  also
    provided  in the  single-threaded version  of  SWI-Prolog, where  it
    returns -2.


int PPLL__tthhrreeaadd__aattttaacchh__eennggiinnee(_c_o_n_s_t _P_L___t_h_r_e_a_d___a_t_t_r___t _*_a_t_t_r)
    Creates  a new Prolog engine in the calling thread.  If  the calling
    thread  already has an engine the  reference count of the engine  is
    incremented.  The  _a_t_t_r argument can be NULL to create a thread with
    default  attributes.  Otherwise it is a pointer to a  structure with
    the  definition below.   For any field  with value `0', the  default
    is  used.    The cancel  field may  be filled  with a  pointer to  a
    function  that is  called when  PL_cleanup() terminates the  running
    Prolog  engines.  If this  function is not present or returns  FALSE
    pthread_cancel() is used.

    typedef struct
    { unsigned long     local_size;    /* Stack sizes (K-bytes) */
      unsigned long     global_size;
      unsigned long     trail_size;
      unsigned long     argument_size;
      char *            alias;         /* alias name */
      int              (*cancel)(int thread);
    } PL_thread_attr_t;

    The  structure may be  destroyed after PL_thread_attach_engine() has
    returned.    On success  it returns  the Prolog  identifier for  the
    thread  (as returned by PL_thread_self()).   If an error occurs,  -1
    is  returned.  If this  Prolog is not compiled for  multi-threading,
    -2 is returned.


int PPLL__tthhrreeaadd__ddeessttrrooyy__eennggiinnee()
    Destroy  the  Prolog engine  in  the calling  thread.    Only  takes
    effect  if  PL_thread_destroy_engine() is called  as many  times  as
    PL_thread_attach_engine() in this thread.   Returns TRUE on  success
    and  FALSE if the calling thread  has no engine or this Prolog  does
    not support threads.

    Please  note  that  construction  and  destruction  of  engines  are
    relatively  expensive  operations.     Only  destroy  an  engine  if
    performance is not critical and memory is a critical resource.


int PPLL__tthhrreeaadd__aatt__eexxiitt(_v_o_i_d _(_*_f_u_n_c_t_i_o_n_)_(_v_o_i_d _*_)_, _v_o_i_d _*_c_l_o_s_u_r_e_, _i_n_t _g_l_o_b_a_l)

    Register   a  handle  to   be  called  as   the  Prolog  engine   is
    destroyed.   The handler function is called with one void * argument
    holding  _c_l_o_s_u_r_e.  If _g_l_o_b_a_l  is TRUE, the handler is installed  _f_o_r
    _a_l_l  _t_h_r_e_a_d_s.   Globally installed handlers  are executed after  the
    thread-local  handlers.  If the  handler is installed local for  the
    current thread only (_g_l_o_b_a_l  == FALSE) it is stored in the same FIFO
    queue as used by thread_at_exit/1.


66..66..22 PPoooolliinngg PPrroolloogg eennggiinneess ((mmaannyy--ttoo--mmaannyy))

In this model Prolog engines live as entities that  are independent from
threads.  If a  thread needs to call Prolog it takes one of  the engines
from the pool and returns the engine when done.   This model is suitable
in the following identified cases:

  o _C_o_m_p_a_t_i_b_i_l_i_t_y _w_i_t_h _t_h_e _s_i_n_g_l_e_-_t_h_r_e_a_d_e_d _v_e_r_s_i_o_n
    In  the  single-threaded  version,  foreign threads  must  serialise
    access  the the one  and only  thread engine.   Functions from  this
    section allow sharing one engine among multiple threads.

  o _M_a_n_y _n_a_t_i_v_e _t_h_r_e_a_d_s _w_i_t_h _i_n_f_r_e_q_u_e_n_t _P_r_o_l_o_g _w_o_r_k
    Prolog  threads are expensive in terms of memory and time  to create
    and  destroy them.  Systems that use a large number of  threads that
    only  infrequently need  to call  Prolog are better  take an  engine
    from a pool and return it there.

  o _P_r_o_l_o_g _s_t_a_t_u_s _m_u_s_t _b_e _h_a_n_d_e_d _t_o _a_n_o_t_h_e_r _t_h_r_e_a_d
    This  situation has  been identified  by Uwe Lesta  when creating  a
    .NET  interface for SWI-Prolog.   .NET  distributes work for  active
    internet  connection over a  pool of  threads.   If a Prolog  engine
    contains  state for a connection, it must be possible to  detach the
    engine  from a thread  and re-attach it  to another thread  handling
    the same connection.


PL_engine_t PPLL__ccrreeaattee__eennggiinnee(_P_L___t_h_r_e_a_d___a_t_t_r___t _*_a_t_t_r_i_b_u_t_e_s)
    Create  a  new   Prolog  engine.     _a_t_t_r_i_b_u_t_e_s  is  described  with
    PL_thread_attach_engine().   Any  thread can  make  this call  after
    PL_initialise()  returned  success.    The  returned engine  is  not
    attached  to any thread and lives  until PL_destroy_engine()is  used
    on the returned handle.

    In  the  single-threaded  version  this call  always  returns  NULL,
    indicating failure.


int PPLL__ddeessttrrooyy__eennggiinnee(_P_L___e_n_g_i_n_e___t _e)
    Destroy  the given engine.  Destroying an engine is only  allowed if
    the engine is not  attached to any thread or attached to the calling
    thread.    On success  this function  returns TRUE,  on failure  the
    return value is FALSE.


int PPLL__sseett__eennggiinnee(_P_L___e_n_g_i_n_e___t _e_n_g_i_n_e_, _P_L___e_n_g_i_n_e___t _*_o_l_d)
    Make  the calling thread ready  to use _e_n_g_i_n_e.   If _o_l_d is  non-NULL
    the  current engine  associated with  the calling  thread is  stored
    at  the  given  location.     If  _e_n_g_i_n_e equals  PL_ENGINE_MAIN  the
    initial  engine is attached  to the  calling thread.   If _e_n_g_i_n_e  is
    PL_ENGINE_CURRENT the  engine is  not  changed.   This  can be  used
    to  query the current  engine.   This call  returns PL_ENGINE_SET  if
    the  engine was switched successfully,  PL_ENGINE_INVAL if _e_n_g_i_n_e  is
    not  a  valid engine  handle and  PL_ENGINE_INUSE  if  the engine  is
    currently in use by another thread.

    Engines  can be changed  at any time.   For  example, it is  allowed
    to  select an engine to initiate a  Prolog goal, detach it and  at a
    later  moment execute the  goal from another  thread.  Note  however
    that  the term_t, qid_t and fid_t types are interpreted relative  to
    the  engine for which they are created.  Behaviour when  passing one
    of these types from one engine to another is undefined.

    In  the single-threaded  version this call  only succeeds if  _e_n_g_i_n_e
    refers to the main engine.


66..66..22..11 EEnnggiinneess iinn ssiinnggllee--tthhrreeaaddeedd SSWWII--PPrroolloogg

In  theory it  is possible  to  port the  API of  section  6.6.2 to  the
single-threaded  version of  SWI-Prolog.    This  allows  C-programs  to
control multiple  Prolog engines concurrently.   This  has not yet  been
realised.


66..77 MMuullttiitthhrreeaaddiinngg aanndd tthhee XXPPCCEE ggrraapphhiiccss ssyysstteemm

GUI applications  written in  XPCE can benefit  from the  multi-threaded
version of  XPCE/SWI-Prolog if  they need to  do expensive  computations
that block to UI in the single-threaded version.

Due  to  various  technical  problems  on  both   Windows  and  Unix/X11
threading is  best exploited by handing  long computations to their  own
thread.

The XPCE message  passing system is guarded  with a single _m_u_t_e_x,  which
synchronises both  access from  Prolog and activation  through the  GUI.
In  MS-Windows, GUI  events are  processed by  the  thread that  created
the window  in which the  event occurred, whereas  in Unix/X11 they  are
processed by the thread that dispatches messages.

Some tentative work is underway to improve the  integration between XPCE
and multi-threaded SWI-Prolog.


ppccee__ddiissppaattcchh((_+_O_p_t_i_o_n_s))
    Create   a  Prolog   thread  with  the   alias-name  pce  for   XPCE
    event-handling.  In  the X11 version this call creates a thread that
    executes  the X11  event-dispatch loop.   In  MS-Windows it  creates
    a  thread that  executes a windows  event-dispatch loop.   The  XPCE
    event-handling  thread has  the alias  pce.   _O_p_t_i_o_n_s specifies  the
    thread-attributes as thread_create/3.


ppccee__ccaallll((_:_G_o_a_l))
    Post  _G_o_a_l to  the pce  thread,  executing it  synchronous with  the
    thread's  event-loop.  The pce_call/1 predicate returns  immediately
    without waiting.  Note that _G_o_a_l is _c_o_p_i_e_d to the pce thread.

For          further           information          about           XPCE
in         threaded         applications,           please         visit
http://gollem.swi.psy.uva.nl/twiki/pl/bin/view/Development/MultiThreadsXPCE


66..88 TThhrreeaaddeedd PPrroolloogg::  SSttaattuuss aanndd ppllaannss

With  SWI-Prolog 5.1.0  Prolog  threads  have become  portable  and  the
performance  gap  between  the single  and  multi-threaded  version  has
become  acceptable.   Most  of the  basic machinery  and  API have  been
tested on some large  applications and appear to be stable.   Especially
as we do not anticipate problems as long as  multi-threading is not used
or threads do  not interact much we believe  it is time to move  towards
making the multi-threaded version the default distribution.


CChhaapptteerr 77..  FFOORREEIIGGNN LLAANNGGUUAAGGEE IINNTTEERRFFAACCEE

SWI-Prolog      offers      a     powerful      interface      to      C
[Kernighan & Ritchie, 1978].     The  main  design   objectives  of  the
foreign language interface  are flexibility and performance.   A foreign
predicate  is a  C-function that  has the  same number  of arguments  as
the predicate  represented.   C-functions  are provided  to analyse  the
passed terms,  convert them to basic C-types  as well as to  instantiate
arguments using unification.   Non-deterministic foreign predicates  are
supported,  providing the  foreign  function with  a handle  to  control
backtracking.

C can  call Prolog  predicates, providing  both an  query interface  and
an interface  to extract  multiple solutions  from an  non-deterministic
Prolog predicate.   There is no limit  to the nesting of Prolog  calling
C, calling Prolog,  etc.  It is also  possible to write the `main'  in C
and use Prolog as an embedded logical engine.


77..11 OOvveerrvviieeww ooff tthhee IInntteerrffaaccee

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.    The
installation process installs this file in the directory  include in the
SWI-Prolog home  directory (?- current_prolog_flag(home, Home).).   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:

  o Analysing Prolog terms

  o Constructing new terms

  o Unifying terms

  o Returning control information to Prolog

  o Registering foreign predicates with Prolog

  o Calling Prolog from C

  o Recorded database interactions

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

77..22 LLiinnkkiinngg FFoorreeiiggnn MMoodduulleess

Foreign modules  may be  linked to  Prolog in two  ways.   Using  _s_t_a_t_i_c
_l_i_n_k_i_n_g, the extensions,  a (short) file defining main()  which attaches
the extensions calls  Prolog and the SWI-Prolog kernel distributed  as a
C-library are linked together  to form a new executable.   Using _d_y_n_a_m_i_c
_l_i_n_k_i_n_g,  the extensions are  linked to  a shared library  (.so file  on
most  Unix systems)  or  dynamic-link library  (.DLL file  on  Microsoft
platforms) and loaded into the the running Prolog process..


77..22..11 WWhhaatt lliinnkkiinngg iiss pprroovviiddeedd??

The _s_t_a_t_i_c  _l_i_n_k_i_n_g schema can  be used on  all versions of  SWI-Prolog.
Whether or  not dynamic  linking is  supported can be  deduced from  the
prolog-flag  open_shared_object  (see current_prolog_flag/2).    If  this
prolog-flag yields true, open_shared_object/2 and related predicates are
defined.  See  section 7.4 for a suitable high-level interface  to these
predicates.


77..22..22 WWhhaatt kkiinndd ooff llooaaddiinngg sshhoouulldd II bbee uussiinngg??

All  described  approaches  have  their  advantages  and  disadvantages.
Static linking  is portable and allows  for debugging on all  platforms.
It is relatively  cumbersome and the libraries  you need to pass to  the
linker may vary from  system to system, though the utility  program plld
described in section 7.7 often hides these problems from the user.

Loading  shared objects  (DLL  files on  Windows) provides  sharing  and
protection  and is  generally the  best choice.    If  a saved-state  is
created using qsave_program/[1,2], an initialization/1 directive  may be
used to load the appropriate library at startup.

Note  that  the  definition of  the  foreign  predicates  is  the  same,
regardless of the linking type used.


77..33 DDyynnaammiicc LLiinnkkiinngg ooff sshhaarreedd lliibbrraarriieess

The interface  defined in this  section allows the  user to load  shared
libraries  (.so files  on most  Unix systems,  .dll  files on  Windows).
This  interface is  portable to  Windows  as well  as to  Unix  machines
providing  dlopen(2)  (Solaris,  Linux,  FreeBSD, Irix  and  many  more)
or  shl_open(2) (HP/UX).  It  is  advised to  use  the  predicates  from
section 7.4 in your application.


ooppeenn__sshhaarreedd__oobbjjeecctt((_+_F_i_l_e_, _-_H_a_n_d_l_e))
    _F_i_l_e  is the name of a  .so file (see your C programmers  documenta-
    tion  on how to create  a .so file).   This file is attached to  the
    current  process and _H_a_n_d_l_e is unified  with a handle to the  shared
    object.    Equivalent to open_shared_object(File, [global], Handle).
    See also load_foreign_library/[1,2].

    On  errors, an  exception shared_object(_A_c_t_i_o_n_, _M_e_s_s_a_g_e) is  raised.
    _M_e_s_s_a_g_e is the return value from dlerror().


ooppeenn__sshhaarreedd__oobbjjeecctt((_+_F_i_l_e_, _+_O_p_t_i_o_n_s_, _-_H_a_n_d_l_e))
    As  open_shared_object/2, but  allows  for  additional flags  to  be
    passed.   _O_p_t_i_o_n_s is a list of  atoms.  now implies the  symbols are
    resolved  immediately rather  than lazy (default).   global  implies
    symbols of the  loaded object are visible while loading other shared
    objects (by default they  are local).  Note that these flags may not
    be  supported by your operating system.  Check the  documentation of
    dlopen() or equivalent  on your operating system.  Unsupported flags
    are silently ignored.


cclloossee__sshhaarreedd__oobbjjeecctt((_+_H_a_n_d_l_e))
    Detach the shared object identified by _H_a_n_d_l_e.


ccaallll__sshhaarreedd__oobbjjeecctt__ffuunnccttiioonn((_+_H_a_n_d_l_e_, _+_F_u_n_c_t_i_o_n))
    Call the named function  in the loaded shared library.  The function
    is  called  without  arguments  and  the  return-value  is  ignored.
    Normally  this function installs  foreign language predicates  using
    calls to PL_register_foreign().


77..44 UUssiinngg tthhee lliibbrraarryy sshhlliibb ffoorr .DLL aanndd .so ffiilleess

This  section discusses  the  functionality  of the  (autoload)  library
shlib.pl, providing an interface to shared libraries.   This library can
only be used if the prolog-flag open_shared_object is enabled.


llooaadd__ffoorreeiiggnn__lliibbrraarryy((_+_L_i_b_, _+_E_n_t_r_y))
    Search  for the  given foreign library  and link  it to the  current
    SWI-Prolog  instance.  The library may be specified with  or without
    the  extension.    First,  absolute_file_name/3 is  used  to  locate
    the  file.    If  this succeeds,  the  full path  is passed  to  the
    low-level  function  to open  the library.    Otherwise,  the  plain
    library  name  is passed,  exploiting  the operating-system  defined
    search  mechanism for  the shared  library.   The file_search_path/2
    alias  mechanism  defines the  alias foreign,  which  refers to  the
    directories <_p_l_h_o_m_e>/lib/<_a_r_c_h>and <_p_l_h_o_m_e>/lib, in this order.

    If  the library  can be loaded,  the function  called _E_n_t_r_y will  be
    called  without arguments.    The return  value of  the function  is
    ignored.

    The  _E_n_t_r_y  function  will  normally  call PL_register_foreign()  to
    declare functions in the library as foreign predicates.


llooaadd__ffoorreeiiggnn__lliibbrraarryy((_+_L_i_b))
    Equivalent  to load_foreign_library/2.   For  the entry-point,  this
    function  first identifies the `base-name' of the library,  which is
    defined  to be the file-name with path nor extension.  It  will then
    try  the  entry-point install-<_b_a_s_e>.    On  failure it  will try  to
    function install().  Otherwise no install function will be called.


uunnllooaadd__ffoorreeiiggnn__lliibbrraarryy((_+_L_i_b))
    If  the foreign  library defines  the function  uninstall_<_b_a_s_e>() or
    uninstall(),  this  function will  be called  without arguments  and
    its  return value is  ignored.   Next, abolish/2  is used to  remove
    all  known foreign predicates defined in  the library.  Finally  the
    library itself is detached from the process.


ccuurrrreenntt__ffoorreeiiggnn__lliibbrraarryy((_-_L_i_b_, _-_P_r_e_d_i_c_a_t_e_s))
    Query  the currently loaded foreign libraries and  their predicates.
    _P_r_e_d_i_c_a_t_e_s  is  a  list  with  elements  of  the  form  _M_o_d_u_l_e_:_H_e_a_d,
    indicating  the predicates installed with PL_register_foreign() when
    the entry-point of the library was called.

Figure  7.1 connects  a Windows  message-box using  a foreign  function.
This example was tested using Windows NT and Microsoft Visual C++ 2.0.

#include <windows.h>
#include <SWI-Prolog.h>

static foreign_t
pl_say_hello(term_t to)
{ char *a;

  if ( PL_get_atom_chars(to, &a) )
  { MessageBox(NULL, a, "DLL test", MB_OK|MB_TASKMODAL);

    PL_succeed;
  }

  PL_fail;
}

install_t
install()
{ PL_register_foreign("say_hello", 1, pl_say_hello, 0);
}

            Figure 7.1:  MessageBox() example in Windows NT


77..44..11 SSttaattiicc LLiinnkkiinngg

Below  is an  outline of  the files  structure  required for  statically
linking  SWI-Prolog  with  foreign extensions.     \ldots/pl  refers  to
the  SWI-Prolog  home  directory (see  current_prolog_flag/2).    <_a_r_c_h>
refers  to  the  architecture identifier  that  may  be  obtained  using
current_prolog_flag/2.

     .../pl/runtime/<_a_r_c_h>/libpl.a   SWI-Library
     \ldots/pl/include/SWI-Prolog.h  Include file
     \ldots/pl/include/SWI-Stream.h  Stream I/O include file
     \ldots/pl/include/SWI-Exports   Export declarations (AIX only)
     \ldots/pl/include/stub.c        Extension stub

The  definition   of  the  foreign  predicates   is  the  same  as   for
dynamic  linking.   Unlike  with dynamic  linking however,  there is  no
initialisation  function.   Instead,  the file  \ldots/pl/include/stub.c
may  be copied  to  your project  and  modified  to define  the  foreign
extensions.   Below is  stub.c, modified to  link the lowercase  example
described later in this chapter:

#include <stdio.h>
#include <SWI-Prolog.h>

extern foreign_t pl_lowercase(term, term);

PL_extension predicates[] =
{
/*{ "name",      arity,  function,      PL_FA_<flags> },*/

  { "lowercase", 2       pl_lowercase,  0 },
  { NULL,        0,      NULL,          0 }     /* terminating line */
};

int
main(int argc, char **argv)
{ PL_register_extensions(predicates);

  if ( !PL_initialise(argc, argv) )
    PL_halt(1);

  PL_install_readline();                /* delete if not required */

  PL_halt(PL_toplevel() ? 0 : 1);
}

Now,  a  new  executable may  be  created  by compiling  this  file  and
linking  it to  libpl.a from  the runtime  directory  and the  libraries
required  by both  the  extensions and  the  SWI-Prolog  kernel.    This
may  be  done  by   hand,  or  using  the  plld  utility   described  in
secrefplld.   If  the linking is  preformed `by  hand', the  commandline
option -dump-runtime-variables (see  section 2.4) can be used to  obtain
the  required paths,  libraries  and linking  options  to link  the  new
executable.


77..55 IInntteerrffaaccee DDaattaa ttyyppeess


77..55..11 TTyyppee term_t::  aa rreeffeerreennccee ttoo aa PPrroolloogg tteerrmm

The principal  data-type is term_t.   Type term_t is what Quintus  calls
QP_term_ref.   This name indicates  better what the type represents:   it
is a _h_a_n_d_l_e for a  term rather than the term itself.  Terms can  only be
represented and manipulated  using this type, as  this is the only  safe
way to  ensure the  Prolog kernel is  aware of  all terms referenced  by
foreign code  and thus allows the  kernel to perform  garbage-collection
and/or stack-shifts while foreign  code is active, for example  during a
callback from C.

A term  reference is  a C unsigned  long, representing  the offset of  a
variable on the Prolog environment-stack.  A foreign  function is passed
term references for the predicate-arguments, one for each  argument.  If
references for intermediate  results are needed, such references  may be
created using PL_new_term_ref() or PL_new_term_refs().   These references
normally live till the foreign function returns control  back to Prolog.
Their scope can  be explicitly limited using PL_open_foreign_frame() and
PL_close_foreign_frame()/PL_discard_foreign_frame().

A term_t  always refers to a valid Prolog term (variable,  atom, integer,
float  or compound  term).    A  term  lives either  until  backtracking
takes  us back  to a  point before  the term  was created,  the  garbage
collector  has collected  the  term or  the  term  was created  after  a
PL_open_foreign_frame()and PL_discard_foreign_frame()has been called.

The  foreign-interface functions  can either  _r_e_a_d,  _u_n_i_f_y or  _w_r_i_t_e  to
term-references.   In the  this document we  use the following  notation
for arguments of type term_t:

     term_t +t  Accessed   in  read-mode.       The   `+'
                indicates the argument is `input'.
     term_t -t  Accessed in write-mode.
     term_t ?t  Accessed in unify-mode.

Term references are obtained in any of the following ways.

  o _P_a_s_s_e_d _a_s _a_r_g_u_m_e_n_t
    The  C-functions implementing  foreign predicates  are passed  their
    arguments  as term-references.    These  references may  be read  or
    unified.  Writing to these variables causes undefined behaviour.

  o _C_r_e_a_t_e_d _b_y PL_new_term_ref()
    A  term  created  by  PL_new_term_ref() is normally  used  to  build
    temporary  terms or be  written by one  of the interface  functions.
    For  example, PL_get_arg() writes a  reference to the  term-argument
    in its last argument.

  o _C_r_e_a_t_e_d _b_y PL_new_term_refs(_i_n_t _n)
    This   function  returns  a   set  of  term   refs  with  the   same
    characteristics as PL_new_term_ref().  See PL_open_query().

  o _C_r_e_a_t_e_d _b_y PL_copy_term_ref(_t_e_r_m___t _t)
    Creates a new term-reference  to the same term as the argument.  The
    term may be written to.  See figure 7.3.

Term-references  can safely  be  copied  to other  C-variables  of  type
term_t, but all copies will always refer to the same term.


term_t PPLL__nneeww__tteerrmm__rreeff()
    Return  a fresh reference  to a  term.   The reference is  allocated
    on  the _l_o_c_a_l  stack.   Allocating  a term-reference  may trigger  a
    stack-shift  on machines  that cannot  use sparse-memory  management
    for allocation the  Prolog stacks.  The returned reference describes
    a variable.


term_t PPLL__nneeww__tteerrmm__rreeffss(_i_n_t _n)
    Return  _n  new  term  references.     The  first  term-reference  is
    returned.   The others are _t +1, _t +2, etc.   There are two reasons
    for  using this function.   PL_open_query()expects the  arguments as
    a  set of  consecutive term references  and _v_e_r_y time-critical  code
    requiring a number of term-references can be written as:

    pl_mypredicate(term_t a0, term_t a1)
    { term_t t0 = PL_new_term_refs(2);
      term_t t1 = t0+1;

      ...
    }


term_t PPLL__ccooppyy__tteerrmm__rreeff(_t_e_r_m___t _f_r_o_m)
    Create a new term  reference and make it point initially to the same
    term  as _f_r_o_m.  This function  is commonly used to copy  a predicate
    argument to a term reference that may be written.


void PPLL__rreesseett__tteerrmm__rreeffss(_t_e_r_m___t _a_f_t_e_r)
    Destroy  all term  references that  have been  created after  _a_f_t_e_r,
    including  _a_f_t_e_r itself.    Any  reference to  the invalidated  term
    references after this call results in undefined behaviour.

    Note  that  returning  from  the  foreign  context  to  Prolog  will
    reclaim  all references  used in  the foreign  context.   This  call
    is  only necessary  if  references are  created inside  a loop  that
    never  exits  back to  Prolog.    See  also  PL_open_foreign_frame(),
    PL_close_foreign_frame() and PL_discard_foreign_frame().


77..55..11..11 IInntteerraaccttiioonn wwiitthh tthhee ggaarrbbaaggee ccoolllleeccttoorr aanndd ssttaacckk--sshhiifftteerr

Prolog implements two  mechanisms for avoiding stack overflow:   garbage
collection and stack expansion.   On machines that allow for  it, Prolog
will use virtual  memory management to detect stack overflow  and expand
the  runtime stacks.    On  other machines  Prolog will  reallocate  the
stacks and update all pointers to them.  To do so,  Prolog needs to know
which data is  referenced by C-code.  As  all Prolog data known by  C is
referenced through term references (term_t), Prolog has  all information
necessary to perform  its memory management without special  precautions
from the C-programmer.


77..55..22 OOtthheerr ffoorreeiiggnn iinntteerrffaaccee ttyyppeess

aattoomm__tt An atom in Prologs  internal representation.  Atoms  are pointers
    to  an  opaque structure.    They are  a  unique representation  for
    represented  text, which  implies that  atom A  represents the same
    text as atom B  if-and-only-if A and B are the same pointer.

    Atoms  are  the  central  representation for  textual  constants  in
    Prolog  The  transformation  of C  a  character  string to  an  atom
    implies  a hash-table lookup.  If the same atom is needed  often, it
    is  advised to  store its reference  in a  global variable to  avoid
    repeated lookup.

ffuunnccttoorr__tt A  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.

pprreeddiiccaattee__tt Handle  to a  Prolog  predicate.    Predicate  handles  live
    forever (although they can loose their definition).

qqiidd__tt Query         Identifier.                          Used         by
    PL_open_query()/PL_next_solution()/PL_close_query() to  handle  back-
    tracking from C.

ffiidd__tt Frame         Identifier.                          Used         by
    PL_open_foreign_frame()/PL_close_foreign_frame().

mmoodduullee__tt A module is  a unique handle to a  Prolog module.  Modules  are
    used only to call predicates in a specific module.

ffoorreeiiggnn__tt Return type for a C-function implementing a Prolog predicate.

ccoonnttrrooll__tt Passed  as additional  argument to  non-deterministic  foreign
    functions.  See PL_retry*() and PL_foreign_context*().

iinnssttaallll__tt Type for the install() and uninstall() functions  of shared or
    dynamic link libraries.  See secrefshlib.


77..66 TThhee FFoorreeiiggnn IInncclluuddee FFiillee


77..66..11 AArrgguummeenntt PPaassssiinngg aanndd CCoonnttrrooll

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;:::; <_a_r_i_t_y>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:


_(_r_e_t_u_r_n_) _f_o_r_e_i_g_n___t PPLL__ssuucccceeeedd(())
    Succeed deterministically.  PL_succeed is defined as return TRUE.


_(_r_e_t_u_r_n_) _f_o_r_e_i_g_n___t PPLL__ffaaiill(())
    Fail  and  start  Prolog  backtracking.     PL_fail  is  defined  as
    return FALSE.


77..66..11..11 NNoonn--ddeetteerrmmiinniissttiicc FFoorreeiiggnn PPrreeddiiccaatteess

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:

  o _I_n_i_t_i_a_l _c_a_l_l _(PL_FIRST_CALL_)
    Prolog  has just created a frame  for the foreign function and  asks
    it to produce the first answer.

  o _R_e_d_o _c_a_l_l _(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.

  o _T_e_r_m_i_n_a_t_e _c_a_l_l _(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  control_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*()
macros  and  extract  the handle  from  the  extra  argument  using  the
PL_foreign_context*() macro.


_(_r_e_t_u_r_n_) _f_o_r_e_i_g_n___t PPLL__rreettrryy((_l_o_n_g))
    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() returns the  handle passed  via
    PL_retry().   This handle  is a 30 bits  signed value (two bits  are
    used  for status indication).  Defined  as return _PL_retry(_n).   See
    also PL_succeed().


_(_r_e_t_u_r_n_) _f_o_r_e_i_g_n___t PPLL__rreettrryy__aaddddrreessss((_v_o_i_d _*))
    As  PL_retry(),  but ensures  an address as  returned by malloc()  is
    correctly  recovered  by PL_foreign_context_address().    Defined  as
    return  _PL_retry_address(_n).  See also PL_succeed().


_i_n_t PPLL__ffoorreeiiggnn__ccoonnttrrooll((_c_o_n_t_r_o_l___t))
    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.


_l_o_n_g PPLL__ffoorreeiiggnn__ccoonntteexxtt((_c_o_n_t_r_o_l___t))
    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).


_v_o_i_d _* PPLL__ffoorreeiiggnn__ccoonntteexxtt__aaddddrreessss((_c_o_n_t_r_o_l___t))
    Extracts an address as passed in by PL_retry_address().

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

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

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

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

  switch( PL_foreign_control(handle) )
  { case PL_FIRST_CALL:
        ctxt = malloc(sizeof(struct context));
        ...
        PL_retry_address(ctxt);
    case PL_REDO:

        ctxt = PL_foreign_context_address(handle);
        ...
        PL_retry_address(ctxt);
    case PL_CUTTED:
        ctxt = PL_foreign_context_address(handle);
        ...
        free(ctxt);
        PL_succeed;

  }
}

     Figure 7.2:  Skeleton for non-deterministic foreign functions


77..66..22 AAttoommss aanndd ffuunnccttoorrss

The  following  functions  provide for  communication  using  atoms  and
functors.


atom_t PPLL__nneeww__aattoomm(_c_o_n_s_t _c_h_a_r _*)
    Return an atom handle  for the given C-string.  This function always
    succeeds.    The returned handle  is valid  as long as  the atom  is
    referenced (see section 7.6.2.1).


const char* PPLL__aattoomm__cchhaarrss(_a_t_o_m___t _a_t_o_m)
    Return  a C-string for the text represented by the given atom.   The
    returned  text will not be changed by Prolog.  It is  not allowed to
    modify  the contents, not even `temporary' as the string  may reside
    in  read-only memory.   The returned  string becomes invalid if  the
    atom is garbage-collected  (see section 7.6.2.1).  Foreign functions
    that  require the text from an atom passed in  a term_t  normally use
    PL_get_atom_chars() or PL_get_atom_nchars().


functor_t PPLL__nneeww__ffuunnccttoorr(_a_t_o_m___t _n_a_m_e_, _i_n_t _a_r_i_t_y)
    Returns  a _f_u_n_c_t_o_r  _i_d_e_n_t_i_f_i_e_r, a  handle for  the name/arity  pair.
    The returned handle is valid for the entire Prolog session.


atom_t PPLL__ffuunnccttoorr__nnaammee(_f_u_n_c_t_o_r___t _f)
    Return an atom representing the name of the given functor.


int PPLL__ffuunnccttoorr__aarriittyy(_f_u_n_c_t_o_r___t _f)
    Return the arity of the given functor.


77..66..22..11 AAttoommss aanndd aattoomm--ggaarrbbaaggee ccoolllleeccttiioonn

With  the introduction  of  atom-garbage  collection in  version  3.3.0,
atoms  no  longer  live  as  long  as  the  process.    Instead,   their
lifetime is  guaranteed only as  long as  they are referenced.   In  the
single-threaded version,  atom garbage collections  are only invoked  at
the  _c_a_l_l_-_p_o_r_t.   In  the multi-threaded  version (see  section 6,  they
appear asynchronously, except for the invoking thread.

For dealing with  atom garbage collection, two additional  functions are
provided:


void PPLL__rreeggiisstteerr__aattoomm(_a_t_o_m___t _a_t_o_m)
    Increment  the reference count  of the  atom by one.   PL_new_atom()
    performs  this automatically,  returning  an atom  with a  reference
    count of at least one.


void PPLL__uunnrreeggiisstteerr__aattoomm(_a_t_o_m___t _a_t_o_m)
    Decrement  the reference count of the atom.  If  the reference-count
    drops below zero, an assertion error is raised.

Please note that the  following two calls are different with  respect to
atom garbage collection:

PL_unify_atom_chars(t, "text");
PL_unify_atom(t, PL_new_atom("text"));

The  latter increments  the  reference count  of  the atom  text,  which
effectively ensures the atom will never be collected.   It is advised to
use the *_chars() or *_nchars() functions whenever applicable.


77..66..33 AAnnaallyyssiinngg TTeerrmmss vviiaa tthhee FFoorreeiiggnn IInntteerrffaaccee

Each argument  of a foreign function  (except for the control  argument)
is of type term_t, an opaque  handle to a Prolog term.  Three  groups of
functions are  available for  the analysis  of terms.    The first  just
validates the type,  like the Prolog  predicates var/1, atom/1, etc  and
are  called PL_is_*().    The second  group  attempts to  translate  the
argument into a C primitive type.   These predicates take a term_t and a
pointer to the appropriate C-type and return TRUE or  FALSE depending on
successful or unsuccessful translation.   If the translation fails,  the
pointed-to data is never modified.


77..66..33..11 TTeessttiinngg tthhee ttyyppee ooff aa tteerrmm


int PPLL__tteerrmm__ttyyppee(_t_e_r_m___t)
    Obtain  the type  of a  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.   Note that the extraction  functions
    PL_ge_t*() also validate  the type and  thus the two sections  below
    are equivalent.

            if ( PL_is_atom(t) )
            { char *s;

              PL_get_atom_chars(t, &s);
              ...;
            }

    or

            char *s;
            if ( PL_get_atom_chars(t, &s) )
            { ...;
            }

    ___________________________________________________________________
    | 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_./2._______________________|

The functions PL_is_<_t_y_p_e> are an alternative to PL_term_type().  The test
PL_is_variable(_t_e_r_m) is equivalent to  PL_term_type(_t_e_r_m)== PL_VARIABLE,
but  the first  is considerably  faster.   On  the other  hand, using  a
switch over  PL_term_type() is faster  and more readable  then using  an
if-then-else using  the functions  below.   All  these functions  return
either TRUE or FALSE.


int PPLL__iiss__vvaarriiaabbllee(_t_e_r_m___t)
    Returns non-zero if _t_e_r_m is a variable.


int PPLL__iiss__aattoomm(_t_e_r_m___t)
    Returns non-zero if _t_e_r_m is an atom.


int PPLL__iiss__ssttrriinngg(_t_e_r_m___t)
    Returns non-zero if _t_e_r_m is a string.


int PPLL__iiss__iinntteeggeerr(_t_e_r_m___t)
    Returns non-zero if _t_e_r_m is an integer.


int PPLL__iiss__ffllooaatt(_t_e_r_m___t)
    Returns non-zero if _t_e_r_m is a float.


int PPLL__iiss__ccoommppoouunndd(_t_e_r_m___t)
    Returns non-zero if _t_e_r_m is a compound term.


int PPLL__iiss__ffuunnccttoorr(_t_e_r_m___t_, _f_u_n_c_t_o_r___t)
    Returns  non-zero if _t_e_r_m  is compound and  its functor is  _f_u_n_c_t_o_r.
    This  test is  equivalent to  PL_get_functor(),  followed by  testing
    the functor, but easier to write and faster.


int PPLL__iiss__lliisstt(_t_e_r_m___t)
    Returns non-zero if _t_e_r_m  is a compound term with functor ./2 or the
    atom [].


int PPLL__iiss__aattoommiicc(_t_e_r_m___t)
    Returns non-zero if _t_e_r_m is atomic (not variable or compound).


int PPLL__iiss__nnuummbbeerr(_t_e_r_m___t)
    Returns non-zero if _t_e_r_m is an integer or float.


77..66..33..22 RReeaaddiinngg ddaattaa ffrroomm aa tteerrmm

The functions PL_get_*() read information from  a Prolog term.  Most  of
them take two arguments.  The first is the input  term and the second is
a pointer to the output value or a term-reference.


int PPLL__ggeett__aattoomm(_t_e_r_m___t _+_t_, _a_t_o_m___t _*_a)
    If _t is an atom,  store the unique atom identifier over _a.  See also
    PL_atom_chars() and PL_new_atom().   If there is  no need to  access
    the data (characters)  of an atom, it is advised to manipulate atoms
    using  their handle.  As the  atom is referenced by _t, it  will live
    at  least as long as _t does.   If longer live-time is required,  the
    atom should be locked using PL_register_atom().


int PPLL__ggeett__aattoomm__cchhaarrss(_t_e_r_m___t _+_t_, _c_h_a_r _*_*_s)
    If  _t is an atom, store a  pointer to a 0-terminated C-string  in _s.
    It is explicitly  nnoott allowed to modify the contents of this string.
    Some  built-in  atoms may  have the  string  allocated in  read-only
    memory, so `temporary manipulation' can cause an error.


int PPLL__ggeett__ssttrriinngg__cchhaarrss(_t_e_r_m___t _+_t_, _c_h_a_r _*_*_s_, _i_n_t _*_l_e_n)
    If  _t  is  a  string  object,  store a  pointer  to  a  0-terminated
    C-string  in _s  and the  length of  the string in  _l_e_n.   Note  that
    this pointer  is invalidated by backtracking, garbage-collection and
    stack-shifts,  so generally the only save operations are to  pass it
    immediately to a C-function that doesn't involve Prolog.


int PPLL__ggeett__cchhaarrss(_t_e_r_m___t _+_t_, _c_h_a_r _*_*_s_, _u_n_s_i_g_n_e_d _f_l_a_g_s)
    Convert  the argument term _t to  a 0-terminated C-string.  _f_l_a_g_s  is
    a  bitwise disjunction  from two  groups of  constants.   The  first
    specifies  which term-types should converted and the second  how the
    argument  is stored.  Below  is a specification of these  constants.
    BUF_RING implies, if  the data is not static (as from an  atom), the
    data  is copied to the next buffer from a ring of 16 buffers.   This
    is  a convenient way  of converting multiple  arguments passed to  a
    foreign  predicate to C-strings.    If BUF_MALLOC  is used, the  data
    must be freed using PL_free() when not needed any longer.
    ___________________________________________________________________
    | CVT_ATOM               |Convert if term is an atom               |
    | CVT_STRING             |Convert if term is a string              |
    | CVT_LIST               |Convert  if term  is a  list of  integers|
    |                        |between 1 and 255                        |

    | CVT_INTEGER            |Convert if term is an integer (using %d) |
    | CVT_FLOAT              |Convert if term is a float (using %f)    |
    | CVT_NUMBER             |Convert if term is a integer or float    |
    | CVT_ATOMIC             |Convert if term is atomic                |
    | CVT_VARIABLE           |Convert variable to print-name           |
    | CVT_WRITE              |Convert any  term that  is not  converted|
    |                        |by any of the  other flags using write/1.|
    |                        |If  no  BUF_*  is  provided,  BUF_RING  is|

    |                        |implied.                                 |
    | CVT_ALL                |Convert  if term  is  any  of the  above,|
    |________________________|except_for_CVT_VARIABLE_and_CVT_WRITE____|
    | BUF_DISCARDABLE        |Data must copied immediately             |
    | BUF_RING               |Data is stored in a ring of buffers      |
    | BUF_MALLOC             |Data is  copied to a new  buffer returned|
    |                        |by PL_malloc(3).   When no  longer needed|

    |________________________|the_user_must_call_PL_free()_on_the_data.|_


int PPLL__ggeett__lliisstt__cchhaarrss(_+_t_e_r_m___t _l_, _c_h_a_r _*_*_s_, _u_n_s_i_g_n_e_d _f_l_a_g_s)
    Same  as PL_get_chars(_l_, _s_, _C_V_T___L_I_S_T___f_l_a_g_s), provided _f_l_a_g_s  contains
    no of the CVT_* flags.


int PPLL__ggeett__iinntteeggeerr(_+_t_e_r_m___t _t_, _i_n_t _*_i)
    If  _t is  a Prolog  integer, assign  its value over  _i.   On  32-bit
    machines,  this is the  same as PL_get_long(), but avoids a  warning
    from the compiler.  See also PL_get_long().


int PPLL__ggeett__lloonngg(_t_e_r_m___t _+_t_, _l_o_n_g _*_i)
    If  _t is  a Prolog  integer, assign  its value over  _i.   Note  that
    Prolog integers have limited  value-range.  If _t is a floating point
    number that can  be represented as a long, this function succeeds as
    well.


int PPLL__ggeett__bbooooll(_t_e_r_m___t _+_t_, _i_n_t _*_v_a_l)
    If _t has the value  true or false, set _v_a_l to the C constant TRUE or
    FALSE and return success.  otherwise return failure.


int PPLL__ggeett__ppooiinntteerr(_t_e_r_m___t _+_t_, _v_o_i_d _*_*_p_t_r)
    In   the  current  system,   pointers  are  represented  by   Prolog
    integers,   but  need  some  manipulation  to  make  sure   they  do
    not  get  truncated   due  to  the  limited  Prolog  integer  range.
    PL_put_pointer()/PL_get_pointer() guarantees pointers  in the  range
    of malloc() are handled without truncating.


int PPLL__ggeett__ffllooaatt(_t_e_r_m___t _+_t_, _d_o_u_b_l_e _*_f)
    If _t is a float or integer, its value is assigned over _f.


int PPLL__ggeett__ffuunnccttoorr(_t_e_r_m___t _+_t_, _f_u_n_c_t_o_r___t _*_f)
    If  _t  is  compound  or  an  atom,   the  Prolog  representation  of
    the   name-arity  pair  will  be  assigned   over  _f.     See   also
    PL_get_name_arity() and PL_is_functor().


int PPLL__ggeett__nnaammee__aarriittyy(_t_e_r_m___t _+_t_, _a_t_o_m___t _*_n_a_m_e_, _i_n_t _*_a_r_i_t_y)
    If  _t is  compound or  an atom,  the functor-name  will be  assigned
    over  _n_a_m_e and the arity over _a_r_i_t_y.   See also PL_get_functor() and
    PL_is_functor().


int PPLL__ggeett__mmoodduullee(_t_e_r_m___t _+_t_, _m_o_d_u_l_e___t _*_m_o_d_u_l_e)
    If _t is an  atom, the system will lookup or create the corresponding
    module and assign an opaque pointer to it over _m_o_d_u_l_e,.


int PPLL__ggeett__aarrgg(_i_n_t _i_n_d_e_x_, _t_e_r_m___t _+_t_, _t_e_r_m___t _-_a)
    If  _t is  compound and  index is  between 1  and arity  (including),
    assign _a with a term-reference to the argument.


int _PPLL__ggeett__aarrgg(_i_n_t _i_n_d_e_x_, _t_e_r_m___t _+_t_, _t_e_r_m___t _-_a)
    Same  as PL_get_arg(),  but no checking  is performed, nor whether  _t
    is actually a term, nor whether _i_n_d_e_x is a valid argument-index.


77..66..33..33 EExxcchhaannggiinngg tteexxtt uussiinngg lleennggtthh aanndd ssttrriinngg

All  internal text-representation  of  SWI-Prolog is  represented  using
char * plus length and  allow for _0_-_b_y_t_e_s in them.  The  foreign library
supports this by implementing  a *_nchars() function for  each applicable
*_chars()  function.   Below we briefly present  the signatures of  these
functions.  For full documentation consult the *_chars() function.


int PPLL__ggeett__aattoomm__nncchhaarrss(_t_e_r_m___t _t_, _u_n_s_i_g_n_e_d _i_n_t _*_l_e_n_, _c_h_a_r _*_*_s)
    See PL_get_atom_chars().


int PPLL__ggeett__lliisstt__nncchhaarrss(_t_e_r_m___t _t_, _u_n_s_i_g_n_e_d _i_n_t _*_l_e_n_, _c_h_a_r _*_*_s)
    See PL_get_list_chars().


int PPLL__ggeett__nncchhaarrss(_t_e_r_m___t _t_, _u_n_s_i_g_n_e_d _i_n_t _*_l_e_n_, _c_h_a_r _*_*_s_, _u_n_s_i_g_n_e_d _i_n_t _f_l_a_g_s)

    See PL_get_chars().


int PPLL__ppuutt__aattoomm__nncchhaarrss(_t_e_r_m___t _t_, _u_n_s_i_g_n_e_d _i_n_t _l_e_n_, _c_o_n_s_t _c_h_a_r _*_s)
    See PL_put_atom_chars().


int PPLL__ppuutt__ssttrriinngg__nncchhaarrss(_t_e_r_m___t _t_, _u_n_s_i_g_n_e_d _i_n_t _l_e_n_, _c_o_n_s_t _c_h_a_r _*_s)
    See PL_put_string_chars().


int PPLL__ppuutt__lliisstt__nnccooddeess(_t_e_r_m___t _t_, _u_n_s_i_g_n_e_d _i_n_t _l_e_n_, _c_o_n_s_t _c_h_a_r _*_s)
    See PL_put_list_codes().


int PPLL__ppuutt__lliisstt__nncchhaarrss(_t_e_r_m___t _t_, _u_n_s_i_g_n_e_d _i_n_t _l_e_n_, _c_o_n_s_t _c_h_a_r _*_s)
    See PL_put_list_chars().


int PPLL__uunniiffyy__aattoomm__nncchhaarrss(_t_e_r_m___t _t_, _u_n_s_i_g_n_e_d _i_n_t _l_e_n_, _c_o_n_s_t _c_h_a_r _*_s)
    See PL_unify_atom_chars().


int PPLL__uunniiffyy__ssttrriinngg__nncchhaarrss(_t_e_r_m___t _t_, _u_n_s_i_g_n_e_d _i_n_t _l_e_n_, _c_o_n_s_t _c_h_a_r _*_s)
    See PL_unify_string_chars().


int PPLL__uunniiffyy__lliisstt__nnccooddeess(_t_e_r_m___t _t_, _u_n_s_i_g_n_e_d _i_n_t _l_e_n_, _c_o_n_s_t _c_h_a_r _*_s)
    See PL_unify_codes().


int PPLL__uunniiffyy__lliisstt__nncchhaarrss(_t_e_r_m___t _t_, _u_n_s_i_g_n_e_d _i_n_t _l_e_n_, _c_o_n_s_t _c_h_a_r _*_s)
    See PL_unify_list_chars().

In  addition, the  following functions  are available  for creating  and
inspecting atoms:


atom_t PPLL__nneeww__aattoomm__nncchhaarrss(_u_n_s_i_g_n_e_d _i_n_t _l_e_n_, _c_o_n_s_t _c_h_a_r _*_s)
    Create a new atom as PL_new_atom(), but from length and characters.


const char * PPLL__aattoomm__nncchhaarrss(_a_t_o_m___t _a_, _u_n_s_i_g_n_e_d _i_n_t _*_l_e_n)
    Extract text and length of an atom.


77..66..33..44 RReeaaddiinngg aa lliisstt

The functions from this section are intended to read  a Prolog list from
C. Suppose we expect a list of atoms, the following  code will print the
atoms, each on a line:

foreign_t
pl_write_atoms(term_t l)
{ term_t head = PL_new_term_ref();      /* variable for the elements */
  term_t list = PL_copy_term_ref(l);    /* copy as we need to write */

  while( PL_get_list(list, head, list) )
  { char *s;

    if ( PL_get_atom_chars(head, &s) )
      Sprintf("%s\n", s);
    else
      PL_fail;
  }

  return PL_get_nil(list);              /* test end for [] */
}


int PPLL__ggeett__lliisstt(_t_e_r_m___t _+_l_, _t_e_r_m___t _-_h_, _t_e_r_m___t _-_t)
    If  _l is a list and not [] assign a term-reference to the  head to _h
    and to the tail to _t.


int PPLL__ggeett__hheeaadd(_t_e_r_m___t _+_l_, _t_e_r_m___t _-_h)
    If _l is a list and not [] assign a term-reference to the head to _h.


int PPLL__ggeett__ttaaiill(_t_e_r_m___t _+_l_, _t_e_r_m___t _-_t)
    If _l is a list and not [] assign a term-reference to the tail to _t.


int PPLL__ggeett__nniill(_t_e_r_m___t _+_l)
    Succeeds if  represents the atom [].


77..66..33..55 AAnn eexxaammppllee::  ddeeffiinniinngg write/1 iinn CC

Figure  7.3 shows  a  simplified  definition of  write/1  to  illustrate
the described  functions.   This simplified version  does not deal  with
operators.    It is  called  display/1, because  it mimics  closely  the
behaviour of this Edinburgh predicate.
foreign_t
pl_display(term_t t)

{ functor_t functor;
  int arity, len, n;
  char *s;

  switch( PL_term_type(t) )
  { case PL_VARIABLE:
    case PL_ATOM:

    case PL_INTEGER:
    case PL_FLOAT:
      PL_get_chars(t, &s, CVT_ALL);
      Sprintf("%s", s);
      break;
    case PL_STRING:
      PL_get_string_chars(t, &s, &len);
      Sprintf("\"%s\"", s);

      break;
    case PL_TERM:
    { term_t a = PL_new_term_ref();

      PL_get_name_arity(t, &name, &arity);
      Sprintf("%s(", PL_atom_chars(name));
      for(n=1; n<=arity; n++)

      { PL_get_arg(n, t, a);
        if ( n > 1 )
          Sprintf(", ");
        pl_display(a);
      }
      Sprintf(")");
      break;
    default:

      PL_fail;                          /* should not happen */
  }

  PL_succeed;
}

             Figure 7.3:  A Foreign definition of display/1


77..66..44 CCoonnssttrruuccttiinngg TTeerrmmss

Terms  can  be  constructed  using  functions from  the  PL_put_*()  and
PL_cons_*()  families.    This  approach  builds the  term  `inside-out',
starting  at  the  leaves  and  subsequently  creating  compound  terms.
Alternatively,   terms  may  be  created   `top-down',  first   creating
a  compound  holding  only  variables  and   subsequently  unifying  the
arguments.   This section  discusses functions  for the first  approach.
This approach  is generally  used for  creating arguments  for PL_call()
and PL_open_query.


void PPLL__ppuutt__vvaarriiaabbllee(_t_e_r_m___t _-_t)
    Put  a fresh variable in  the term.   The new variable lives on  the
    global  stack.   Note that the initial  variable lives on the  local
    stack  and is  lost after  a write to  the term-references.    After
    using this function, the variable will continue to live.


void PPLL__ppuutt__aattoomm(_t_e_r_m___t _-_t_, _a_t_o_m___t _a)
    Put  an  atom  in the  term  reference from  a  handle.    See  also
    PL_new_atom() and PL_atom_chars().


void PPLL__ppuutt__aattoomm__cchhaarrss(_t_e_r_m___t _-_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s)
    Put an atom  in the term-reference constructed from the 0-terminated
    string.  The  string itself will never be references by Prolog after
    this function.


void PPLL__ppuutt__ssttrriinngg__cchhaarrss(_t_e_r_m___t _-_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s)
    Put  a zero-terminated string in the term-reference.  The  data will
    be copied.  See also PL_put_string_nchars().


void PPLL__ppuutt__ssttrriinngg__nncchhaarrss(_t_e_r_m___t _-_t_, _u_n_s_i_g_n_e_d _i_n_t _l_e_n_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s)

    Put  a string,  represented by  a length/start pointer  pair in  the
    term-reference.   The data will be copied.  This interface  can deal
    with 0-bytes in the string.  See also section 7.6.17.


void PPLL__ppuutt__lliisstt__cchhaarrss(_t_e_r_m___t _-_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s)
    Put a list of ASCII values in the term-reference.


void PPLL__ppuutt__iinntteeggeerr(_t_e_r_m___t _-_t_, _l_o_n_g _i)
    Put a Prolog integer in the term reference.


void PPLL__ppuutt__ppooiinntteerr(_t_e_r_m___t _-_t_, _v_o_i_d _*_p_t_r)
    Put a Prolog integer  in the term-reference.  Provided ptr is in the
    `malloc()-area', PL_get_pointer() will get the pointer back.


void PPLL__ppuutt__ffllooaatt(_t_e_r_m___t _-_t_, _d_o_u_b_l_e _f)
    Put a floating-point value in the term-reference.


void PPLL__ppuutt__ffuunnccttoorr(_t_e_r_m___t _-_t_, _f_u_n_c_t_o_r___t _f_u_n_c_t_o_r)
    Create  a new compound  term from _f_u_n_c_t_o_r and  bind _t to this  term.
    All arguments of the  term will be variables.  To create a term with
    instantiated  arguments, either instantiate the arguments  using the
    PL_unify_*() functions or use PL_cons_functor().


void PPLL__ppuutt__lliisstt(_t_e_r_m___t _-_l)
    Same as PL_put_functor(_l_, _P_L___n_e_w___f_u_n_c_t_o_r_(_P_L___n_e_w___a_t_o_m_(_"_._"), 2)).


void PPLL__ppuutt__nniill(_t_e_r_m___t _-_l)
    Same as PL_put_atom_chars(_"_[_]_").


void PPLL__ppuutt__tteerrmm(_t_e_r_m___t _-_t_1_, _t_e_r_m___t _+_t_2)
    Make _t_1 point to the same term as _t_2.


void PPLL__ccoonnss__ffuunnccttoorr(_t_e_r_m___t _-_h_, _f_u_n_c_t_o_r___t _f_, _._._.)
    Create  a term,  whose arguments are  filled from variable  argument
    list  holding the same number of term_t objects as the arity  of the
    functor.  To create the term animal(gnu, 50), use:

    { term_t a1 = PL_new_term_ref();
      term_t a2 = PL_new_term_ref();
      term_t t  = PL_new_term_ref();
      functor_t animal2;

      /* animal2 is a constant that may be bound to a global
         variable and re-used
      */
      animal2 = PL_new_functor(PL_new_atom("animal"), 2);

      PL_put_atom_chars(a1, "gnu");
      PL_put_integer(a2, 50);
      PL_cons_functor(t, animal2, a1, a2);
    }

    After  this sequence, the term-references _a_1 and _a_2 may be  used for
    other purposes.


void PPLL__ccoonnss__ffuunnccttoorr__vv(_t_e_r_m___t _-_h_, _f_u_n_c_t_o_r___t _f_, _t_e_r_m___t _a_0)
    Creates  a compound term like PL_cons_functor(), but _a_0 is  an array
    of  term references as  returned by PL_new_term_refs().   The  length
    of  this array should match the number of arguments required  by the
    functor.


void PPLL__ccoonnss__lliisstt(_t_e_r_m___t _-_l_, _t_e_r_m___t _+_h_, _t_e_r_m___t _+_t)
    Create  a list (cons-) cell in _l from  the head and tail.   The code
    below  creates a list of  atoms from a char **.   The list is  built
    tail-to-head.   The  PL_unify_*()  functions can be  used to build  a
    list head-to-tail.

    void
    put_list(term_t l, int n, char **words)
    { term_t a = PL_new_term_ref();

      PL_put_nil(l);
      while( --n >= 0 )
      { PL_put_atom_chars(a, words[n]);
        PL_cons_list(l, a, l);
      }
    }

    Note  that _l can  be redefined  within a PL_cons_list call as  shown
    here because operationally  its old value is consumed before its new
    value is set.


77..66..55 UUnniiffyyiinngg ddaattaa

The  functions  of  this  sections  _u_n_i_f_y  terms  with  other  terms  or
translated C-data structures.   Except for PL_unify(), the functions  of
this section  are specific  to SWI-Prolog.   They  have been  introduced
to make translation  of old code easier,  but also because they  provide
for a faster mechanism  for returning data to Prolog that  requires less
term-references.  Consider the case where we want  a foreign function to
return the  host name of the  machine Prolog is running  on.  Using  the
PL_get_*() and PL_put_*() functions, the code becomes:

foreign_t
pl_hostname(term_t name)
{ char buf[100];

  if ( gethostname(buf, sizeof(buf)) )
  { term_t tmp = PL_new_term_ref();

    PL_put_atom_chars(tmp, buf);
    return PL_unify(name, tmp);
  }

  PL_fail;
}

Using PL_unify_atom_chars(), this becomes:

foreign_t
pl_hostname(term_t name)
{ char buf[100];

  if ( gethostname(buf, sizeof(buf)) )
    return PL_unify_atom_chars(name, buf);

  PL_fail;
}


int PPLL__uunniiffyy(_t_e_r_m___t _?_t_1_, _t_e_r_m___t _?_t_2)
    Unify two Prolog terms and return non-zero on success.


int PPLL__uunniiffyy__aattoomm(_t_e_r_m___t _?_t_, _a_t_o_m___t _a)
    Unify _t with the atom _a and return non-zero on success.


int PPLL__uunniiffyy__aattoomm__cchhaarrss(_t_e_r_m___t _?_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s)
    Unify  _t with  an atom  created from  _c_h_a_r_s and  return non-zero  on
    success.


int PPLL__uunniiffyy__lliisstt__cchhaarrss(_t_e_r_m___t _?_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s)
    Unify _t with a list of ASCII characters constructed from _c_h_a_r_s.


void PPLL__uunniiffyy__ssttrriinngg__cchhaarrss(_t_e_r_m___t _?_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s)
    Unify  _t  with  a  Prolog  string  object  created  from  the  zero-
    terminated  string  _c_h_a_r_s.   The  data will  be copied.    See  also
    PL_unify_string_nchars().


void PPLL__uunniiffyy__ssttrriinngg__nncchhaarrss(_t_e_r_m___t _?_t_, _u_n_s_i_g_n_e_d _i_n_t _l_e_n_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s)

    Unify   _t   with   a  Prolog   string   object  created   from   the
    string  created from the _l_e_n/_c_h_a_r_s pair.   The data will be  copied.
    This  interface can  deal  with 0-bytes  in the  string.   See  also
    section 7.6.17.


int PPLL__uunniiffyy__iinntteeggeerr(_t_e_r_m___t _?_t_, _l_o_n_g _n)
    Unify _t with a Prolog integer from _n.


int PPLL__uunniiffyy__ffllooaatt(_t_e_r_m___t _?_t_, _d_o_u_b_l_e _f)
    Unify _t with a Prolog float from _f.


int PPLL__uunniiffyy__ppooiinntteerr(_t_e_r_m___t _?_t_, _v_o_i_d _*_p_t_r)
    Unify  _t with a  Prolog integer  describing the pointer.   See  also
    PL_put_pointer() and PL_get_pointer().


int PPLL__uunniiffyy__ffuunnccttoorr(_t_e_r_m___t _?_t_, _f_u_n_c_t_o_r___t _f)
    If  _t is a compound term with  the given functor, just succeed.   If
    it  is unbound,  create a term  and bind the  variable, else  fails.
    Not  that this function  does not create a  term if the argument  is
    already instantiated.


int PPLL__uunniiffyy__lliisstt(_t_e_r_m___t _?_l_, _t_e_r_m___t _-_h_, _t_e_r_m___t _-_t)
    Unify  _l with a list-cell (./2).   If successful, write  a reference
    to  the head of  the list to _h  and a reference  to the tail of  the
    list  in _t.   This  reference may  be used for  subsequent calls  to
    this  function.   Suppose we  want to  return a list  of atoms  from
    a  char **.   We could  use the example  described by PL_put_list(),
    followed by  a call to PL_unify(), or we can use  the code below.  If
    the  predicate argument is unbound,  the difference is minimal  (the
    code  based on PL_put_list() is probably slightly  faster).  If  the
    argument  is bound, the code below may fail before reaching  the end
    of  the word-list, but even  if the unification succeeds, this  code
    avoids a duplicate (garbage) list and a deep unification.

    foreign_t
    pl_get_environ(term_t env)
    { term_t l = PL_copy_term_ref(env);
      term_t a = PL_new_term_ref();
      extern char **environ;
      char **e;

      for(e = environ; *e; e++)
      { if ( !PL_unify_list(l, a, l) ||
             !PL_unify_atom_chars(a, *e) )
          PL_fail;
      }

      return PL_unify_nil(l);
    }


int PPLL__uunniiffyy__nniill(_t_e_r_m___t _?_l)
    Unify _l with the atom [].


int PPLL__uunniiffyy__aarrgg(_i_n_t _i_n_d_e_x_, _t_e_r_m___t _?_t_, _t_e_r_m___t _?_a)
    Unifies the _i_n_d_e_x_-_t_h argument (1-based) of _t with _a.


int PPLL__uunniiffyy__tteerrmm(_t_e_r_m___t _?_t_, _._._.)
    Unify  _t with a (normally) compound  term.  The remaining  arguments
    is  a  sequence  of a  type  identifier,  followed by  the  required
    arguments.      This  predicate  is  an  extension  to  the  Quintus
    and  SICStus foreign  interface  from which  the SWI-Prolog  foreign
    interface  has been  derived, but has  proved to  be a powerful  and
    comfortable  way to create compound terms from C. Due to  the vararg
    packing/unpacking and  the required type-switching this interface is
    slightly  slower than using the primitives.   Please note that  some
    bad  C-compilers have fairly low  limits on the number of  arguments
    that may be passed to a function.

    Special  attention is required when  passing numbers.  C  `promotes'
    any  integral  smaller than  int  to  int.    I.e. the  types  char,
    short  and  int  are all  passed  as int.    In  addition,  on  most
    32-bit  platforms int and  long are the same.   Upto version  4.0.5,
    only  PL_INTEGER  could be specified which  was taken from the  stack
    as  long.   Such  code fails when  passing small  integral types  on
    machines  where int  is smaller than  long.   It is  advised to  use
    PL_SHORT, PL_INT or  PL_LONG  as appropriate.   Similar, C  compilers
    promote  float to  double and  therefore PL_FLOAT and  PL_DOUBLE  are
    synonyms.

    The type identifiers are:

    PL_VARIABLE nnoonnee
         No op.  Used in arguments of PL_FUNCTOR.

    PL_BOOL iinntt
         Unify the argument with true or false.

    PL_ATOM aattoomm__tt
         Unify the argument with an atom, as in PL_unify_atom().

    PL_CHARS ccoonnsstt cchhaarr **
         Unify the  argument with  an atom created  from a  0-terminated
         string.

    PL_NCHARS uunnssiiggnneedd iinntt,, ccoonnsstt cchhaarr **
         Unify the argument with  an atom created from the  given number
         of  characters  starting  at the  given  address.     See  also
         PL_unify_atom_nchars();

    PL_SHORT sshhoorrtt
         Unify the argument  with an integer,  as in PL_unify_integer().
         As short is promoted to int, PL_SHORT is a synonym for PL_INT.

    PL_INT iinntt
         Unify the argument with an integer, as in PL_unify_integer().

    PL_LONG lloonngg
         Unify the argument with an integer, as in PL_unify_integer().

    PL_INTEGER lloonngg
         Unify the argument with an integer, as in PL_unify_integer().

    PL_DOUBLE ddoouubbllee
         Unify  the  argument  with a  float,  as  in  PL_unify_float().
         Note  that,  as the  argument  is  passed using  the  C  vararg
         conventions, a float must be casted to a double explicitly.

    PL_FLOAT ddoouubbllee
         Unify the argument with a float, as in PL_unify_float().

    PL_POINTER vvooiidd **
         Unify the argument with a pointer, as in PL_unify_pointer().

    PL_STRING ccoonnsstt cchhaarr **
         Unify   the   argument   with   a   string   object,    as   in
         PL_unify_string_chars().

    PL_TERM tteerrmm__tt
         Unify  a  subterm.    Note  this  may the  return  value  of  a
         PL_new_term_ref()call to get access to a variable.

    PL_CHARS ccoonnsstt cchhaarr **
         Unify the argument  with an atom,  constructed from the C  char
         *, as in PL_unify_atom_chars().

    PL_FUNCTOR ffuunnccttoorr__tt,, ......
         Unify the argument  with a compound  term.  This  specification
         should be  followed by  exactly as many  specifications as  the
         number of arguments of the compound term.

    PL_FUNCTOR_CHARS ccoonnsstt cchhaarr **nnaammee,, iinntt aarriittyy,, ......
         Create a functor from the given name and arity  and then behave
         as PL_FUNCTOR.

    PL_LIST iinntt lleennggtthh,, ......
         Create  a  list  of  the  indicated  length.     The  following
         arguments contain the elements of the list.

    For  example, to  unify an argument  with the term  language(dutch),
    the following skeleton may be used:

    static functor_t FUNCTOR_language1;

    static void
    init_constants()
    { FUNCTOR_language1 = PL_new_functor(PL_new_atom("language"), 1);
    }

    foreign_t
    pl_get_lang(term_t r)
    { return PL_unify_term(r,
                           PL_FUNCTOR, FUNCTOR_language1,
                               PL_CHARS, "dutch");
    }

    install_t
    install()
    { PL_register_foreign("get_lang", 1, pl_get_lang, 0);
      init_constants();
    }


int PPLL__cchhaarrss__ttoo__tteerrmm(_c_o_n_s_t _c_h_a_r _*_c_h_a_r_s_, _t_e_r_m___t _-_t)
    Parse  the string _c_h_a_r_s  and put the  resulting Prolog term into  _t.
    _c_h_a_r_s  may or may not  be closed using  a Prolog full-stop (i.e.,  a
    dot  followed by  a blank).   Returns  FALSE if a  syntax error  was
    encountered  and TRUE after successful  completion.  In addition  to
    returning  FALSE, the exception-term  is returned in  _t on a  syntax
    error.  See also term_to_atom/2.

    The following example build a goal-term from a string and calls it.

    int
    call_chars(const char *goal)
    { fid_t fid = PL_open_foreign_frame();
      term_t g = PL_new_term_ref();
      BOOL rval;

      if ( PL_string_to_term(goal, g) )
        rval = PL_call(goal, NULL);
      else
        rval = FALSE;

      PL_discard_foreign_frame(fid);
      return rval;
    }

      ...
      call_chars("consult(load)");
      ...


char * PPLL__qquuoottee(_i_n_t _c_h_r_, _c_o_n_s_t _c_h_a_r _*_s_t_r_i_n_g)
    Return a quoted version of  _s_t_r_i_n_g.  If _c_h_r is '\'', the result is a
    quoted  atom.  If _c_h_r  is '"', the result is  a string.  The  result
    string  is stored in the same ring of buffers as described  with the
    BUF_RING argument of PL_get_chars();

    In  the  current implementation,  the string  is  surrounded by  _c_h_r
    and  any  occurence  of   _c_h_r  is  doubled.     In  the  future  the
    behaviour  will depend  on the  character_escape prolog-flag.    See
    current_prolog_flag/2.


77..66..66 CCaalllliinngg PPrroolloogg ffrroomm CC

The  Prolog engine  can  be called  from  C.  There are  two  interfaces
for  this.    For the  first,  a  term is  created  that could  be  used
as an  argument to  call/1 and next  PL_call() is used  to call  Prolog.
This  system is  simple, but  does not  allow to  inspect the  different
answers  to a  non-deterministic  goal and  is  relatively slow  as  the
runtime  system needs  to  find the  predicate.    The  other  interface
is  based on  PL_open_query(),  PL_next_solution() and  PL_cut_query() or
PL_close_query().     This mechanism  is  more powerful,  but  also  more
complicated to use.


77..66..66..11 PPrreeddiiccaattee rreeffeerreenncceess

This  section  discusses   the  functions  used  to  communicate   about
predicates.   Though a Prolog predicate  may defined or not,  redefined,
etc., a Prolog predicate has a handle that is  not destroyed, nor moved.
This handle is known by the type predicate_t.


predicate_t PPLL__pprreedd(_f_u_n_c_t_o_r___t _f_, _m_o_d_u_l_e___t _m)
    Return  a handle to a predicate for the specified name/arity  in the
    given module.   This function always succeeds, creating a handle for
    an undefined predicate if no handle was available.


predicate_t PPLL__pprreeddiiccaattee(_c_o_n_s_t _c_h_a_r _*_n_a_m_e_, _i_n_t _a_r_i_t_y_, _c_o_n_s_t _c_h_a_r_* _m_o_d_u_l_e)

    Same   a  PL_pred(),   but   provides  a   more  convenient   inter-
    face to the C-programmer.


void PPLL__pprreeddiiccaattee__iinnffoo(_p_r_e_d_i_c_a_t_e___t _p_, _a_t_o_m___t _*_n_, _i_n_t _*_a_, _m_o_d_u_l_e___t _*_m)
    Return  information on the  predicate _p.   The  name is stored  over
    _n,  the  arity  over _a,  while  _m  receives the  definition  module.
    Note  that  the  latter need  not  be  the same  as  specified  with
    PL_predicate().    If the  predicate was  imported  into the  module
    given to  PL_predicate(), this function will  return the module where
    the predicate was defined.


77..66..66..22 IInniittiiaattiinngg aa qquueerryy ffrroomm CC

This  section discusses  the  functions  for creating  and  manipulating
queries from C. Note that a foreign context can have  at most one active
query.    This  implies it  is allowed  to  make strictly  nested  calls
between  C and  Prolog (Prolog  calls C,  calls Prolog,  calls C,  etc.,
but it  is nnoott  allowed to  open multiple queries  and start  generating
solutions for  each of them by  calling PL_next_solution().   Be sure  to
call PL_cut_query() or PL_close_query() on any  query you opened  before
opening the next or returning control back to Prolog.


qid_t PPLL__ooppeenn__qquueerryy(_m_o_d_u_l_e___t _c_t_x_, _i_n_t _f_l_a_g_s_, _p_r_e_d_i_c_a_t_e___t _p_, _t_e_r_m___t _+_t_0)

    Opens  a query  and returns  an identifier for  it.   This  function
    always  succeeds,  regardless whether  the predicate  is defined  or
    not.    _c_t_x is  the _c_o_n_t_e_x_t  _m_o_d_u_l_e of  the goal.    When NULL,  the
    context  module of  the calling  context will  be used,  or user  if
    there  is no calling  context (as may  happen in embedded  systems).
    Note  that the  context module  only matters  for _m_o_d_u_l_e___t_r_a_n_s_p_a_r_e_n_t
    predicates.   See context_module/1 and module_transparent/1.   The _p
    argument  specifies the  predicate, and  should be the  result of  a
    call  to PL_pred() or PL_predicate().   Note that  it is allowed  to
    store  this handle as global data  and reuse it for future  queries.
    The  term-reference _t_0 is the  first of a vector of  term-references
    as returned by PL_new_term_refs(_n).

    The  _f_l_a_g_s  arguments provides  some additional  options  concerning
    debugging  and  exception handling.    It  is a  bitwise or  of  the
    following values:

    PL_Q_NORMAL
         Normal operation.    The  debugger inherits  its settings  from
         the environment.   If an exception  occurs that is not  handled
         in Prolog, a  message is printed and  the tracer is started  to
         debug the error.

    PL_Q_NODEBUG
         Switch off the debugger while executing the goal.   This option
         is used by many  calls to hook-predicates to avoid  tracing the
         hooks.   An example is  print/1 calling portray/1 from  foreign
         code.

    PL_Q_CATCH_EXCEPTION
         If an  exception is  raised while  executing the  goal, do  not
         report it, but make it available for PL_exception().

    PL_Q_PASS_EXCEPTION
         As PL_Q_CATCH_EXCEPTION,  but do  not invalidate the  exception-
         term  while   calling  PL_close_query().      This  option   is
         experimental.

    The  example below opens a query to the predicate is_a/2  to find the
    ancestor of for some name.

    char *
    ancestor(const char *me)
    { term_t a0 = PL_new_term_refs(2);
      static predicate_t p;

      if ( !p )
        p = PL_predicate("is_a", 2, "database");

      PL_put_atom_chars(a0, me);
      PL_open_query(NULL, PL_Q_NORMAL, p, a0);
      ...
    }


int PPLL__nneexxtt__ssoolluuttiioonn(_q_i_d___t _q_i_d)
    Generate the first (next)  solution for the given query.  The return
    value  is TRUE if  a solution  was found, or  FALSE to indicate  the
    query  could not be proven.  This function may be  called repeatedly
    until it fails to generate all solutions to the query.


void PPLL__ccuutt__qquueerryy(_q_i_d)
    Discards  the query, but does not delete any of the data  created by
    the  query.   It just  invalidate _q_i_d,  allowing for a  new call  to
    PL_open_query() in this context.


void PPLL__cclloossee__qquueerryy(_q_i_d)
    As  PL_cut_query(), but  all data and  bindings created by the  query
    are destroyed.


int PPLL__ccaallll__pprreeddiiccaattee(_m_o_d_u_l_e___t _m_, _i_n_t _f_l_a_g_s_, _p_r_e_d_i_c_a_t_e___t _p_r_e_d_, _t_e_r_m___t _+_t_0)

    Shorthand  for  PL_open_query(),  PL_next_solution(),  PL_cut_query(),
    generating  a single solution.   The arguments  are the same as  for
    PL_open_query(), the return value is the same as PL_next_solution().


int PPLL__ccaallll(_t_e_r_m___t_, _m_o_d_u_l_e___t)
    Call term just like  the Prolog predicate once/1.  _T_e_r_m is called in
    the  specified module, or in the context  module if module_t  = NULL.
    Returns  TRUE if  the call succeeds,  FALSE otherwise.   Figure  7.4
    shows an example to  obtain the number of defined atoms.  All checks
    are omitted to improve readability.


77..66..77 DDiissccaarrddiinngg DDaattaa

The Prolog  data created and  term-references needed  to setup the  call
and/or analyse  the result can  in most cases  be discarded right  after
the  call.   PL_close_query() allows  for  destructing the  data,  while
leaving the  term-references.   The calls below may  be used to  destroy
term-references and data.  See figure 7.4 for an example.


fid_t PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee()
    Created  a foreign  frame,  holding a  mark that  allows the  system
    to  undo  bindings and  destroy data  created after  it  as well  as
    providing  the  environment  for  creating term-references.     This
    function   is  called  by  the  kernel  before  calling   a  foreign
    predicate.


void PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(_f_i_d___t _i_d)
    Discard  all term-references  created  after the  frame was  opened.
    All  other Prolog data is retained.  This function is called  by the
    kernel whenever a foreign function returns control back to Prolog.


void PPLL__ddiissccaarrdd__ffoorreeiiggnn__ffrraammee(_f_i_d___t _i_d)
    Same  as PL_close_foreign_frame(),  but also  undo all bindings  made
    since the open and destroy all Prolog data.


void PPLL__rreewwiinndd__ffoorreeiiggnn__ffrraammee(_f_i_d___t _i_d)
    Undo all bindings  and discard all term-references created since the
    frame was created, but  does not pop the frame.  I.e. the same frame
    can  be rewinded multiple  times, and must  eventually be closed  or
    discarded.

It is obligatory to call either of the two  closing functions to discard
a foreign frame.  Foreign frames may be nested.

int
count_atoms()
{ fid_t fid = PL_open_foreign_frame();
  term_t goal  = PL_new_term_ref();
  term_t a1    = PL_new_term_ref();
  term_t a2    = PL_new_term_ref();
  functor_t s2 = PL_new_functor(PL_new_atom("statistics"), 2);

  int atoms;

  PL_put_atom_chars(a1, "atoms");
  PL_cons_functor(goal, s2, a1, a2);
  PL_call(goal, NULL);         /* call it in current module */

  PL_get_integer(a2, &atoms);
  PL_discard_foreign_frame(fid);

  return atoms;
}

                      Figure 7.4:  Calling Prolog


77..66..88 FFoorreeiiggnn CCooddee aanndd MMoodduulleess

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

module_t PPLL__ccoonntteexxtt()
    Return the module  identifier of the context module of the currently
    active foreign predicate.


int PPLL__ssttrriipp__mmoodduullee(_t_e_r_m___t _+_r_a_w_, _m_o_d_u_l_e___t _*_m_, _t_e_r_m___t _-_p_l_a_i_n)
    Utility  function.  If  _r_a_w is a  term, possibly holding the  module
    construct  <_m_o_d_u_l_e>:<_r_e_s_t>this function will make _p_l_a_i_n a  reference
    to  <_r_e_s_t>  and fill  _m_o_d_u_l_e _*  with <_m_o_d_u_l_e>.    For further  nested
    module  constructs  the inner  most module  is  returned via  _m_o_d_u_l_e
    _*.   If  _r_a_w is  not a module  construct _a_r_g will  simply be put  in
    _p_l_a_i_n.   If _m_o_d_u_l_e _* 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"));
      term_t plain = PL_new_term_ref();

      PL_strip_module(term, &m, plain);
      ...


atom_t PPLL__mmoodduullee__nnaammee(_m_o_d_u_l_e___t)
    Return the name of _m_o_d_u_l_e as an atom.


module_t PPLL__nneeww__mmoodduullee(_a_t_o_m___t _n_a_m_e)
    Find  an existing or create a new module with name specified  by the
    atom _n_a_m_e.


77..66..99 PPrroolloogg eexxcceeppttiioonnss iinn ffoorreeiiggnn ccooddee

This     section    discusses     PL_exception(),     PL_throw()     and
PL_raise_exception(),  the  interface functions  to  detect and  generate
Prolog  exceptions from  C-code.    PL_throw()  and PL_raise_exception()
from  the  C-interface   to  raise  an  exception  from  foreign   code.
PL_throw() exploits the  C-function longjmp()  to return immediately  to
the  innermost PL_next_solution().   PL_raise_exception() registers  the
exception term and returns FALSE. If a foreign  predicate returns FALSE,
while  and exception-term  is  registered  a Prolog  exception  will  be
raised by the virtual machine.

Calling these functions  outside the context of a function  implementing
a foreign predicate results in undefined behaviour.

PL_exception() may  be used  after a  call to  PL_next_solution() fails,
and returns a  term reference to an  exception term if an exception  was
raised, and 0 otherwise.

If  a C-function,  implementing  a predicate  calls Prolog  and  detects
an  exception using  PL_exception(),  it can  handle  this exception,  or
return  with the  exception.    Some caution  is required  though.    It
is  nnoott allowed  to call  PL_close_query() or  PL_discard_foreign_frame()
afterwards,  as  this  will  invalidate  the  exception  term.     Below
is  the  code that  calls  a  Prolog defined  arithmetic  function  (see
arithmethic_function/1).

If PL_next_solution() succeeds,  the result  is analysed and  translated
to  a number,  after  which the  query  is closed  and all  Prolog  data
created  after  PL_open_foreign_frame() is  destroyed.    On  the  other
hand,  if  PL_next_solution() fails  and  if an  exception  was  raised,
just  pass it.     Otherwise generate  an  exception  (PL_error() is  an
internal  call  for  building  the  standard  error  terms  and  calling
PL_raise_exception()).    After this,  the Prolog  environment should  be
discarded  using  PL_cut_query() and  PL_close_foreign_frame() to  avoid
invalidating the exception term.

static int
prologFunction(ArithFunction f, term_t av, Number r)
{ int arity = f->proc->definition->functor->arity;
  fid_t fid = PL_open_foreign_frame();
  qid_t qid;
  int rval;

  qid = PL_open_query(NULL, PL_Q_NORMAL, f->proc, av);

  if ( PL_next_solution(qid) )
  { rval = valueExpression(av+arity-1, r);
    PL_close_query(qid);
    PL_discard_foreign_frame(fid);
  } else
  { term_t except;

    if ( (except = PL_exception(qid)) )
    { rval = PL_throw(except);          /* pass exception */
    } else
    { char *name = stringAtom(f->proc->definition->functor->name);

                                        /* generate exception */
      rval = PL_error(name, arity-1, NULL, ERR_FAILED, f->proc);
    }

    PL_cut_query(qid);                  /* donot destroy data */
    PL_close_foreign_frame(fid);        /* same */
  }

  return rval;
}


int PPLL__rraaiissee__eexxcceeppttiioonn(_t_e_r_m___t _e_x_c_e_p_t_i_o_n)
    Generate  an exception (as  throw/1) and return  FALSE. Below is  an
    example returning an exception from foreign predicate:

    foreign_t
    pl_hello(term_t to)
    { char *s;

      if ( PL_get_atom_chars(to, &s) )
      { Sprintf("Hello \"%s\"\n", s);

        PL_succeed;
      } else
      { term_t except = PL_new_term_ref();

        PL_unify_term(except,
                      PL_FUNCTOR_CHARS, "type_error", 2,
                        PL_CHARS, "atom",
                        PL_TERM, to);

        return PL_raise_exception(except);
      }
    }


int PPLL__tthhrrooww(_t_e_r_m___t _e_x_c_e_p_t_i_o_n)
    Similar  to PL_raise_exception(),  but returns using the C  longjmp()
    function to the innermost PL_next_solution().


term_t PPLL__eexxcceeppttiioonn(_q_i_d___t _q_i_d)
    If  PL_next_solution() fails,  this  can be  due to  normal  failure
    of  the  Prolog  call, or  because  an  exception was  raised  using
    throw/1.   This function returns  a handle to the exception term  if
    an exception was raised, or 0 if the Prolog goal simply failed..


77..66..1100 CCaattcchhiinngg SSiiggnnaallss ((SSooffttwwaarree IInntteerrrruuppttss))

SWI-Prolog offers both  a C and Prolog  interface to deal with  software
interrupts (signals).   The Prolog mapping  is defined in section  4.10.
This subsection deals with handling signals from C.

If a signal is not  used by Prolog and the handler does not  call Prolog
in any way, the native signal interface routines may be used.

Some versions of SWI-Prolog, notably running on  popular Unix platforms,
handle SIG_SEGV  for guarding  the Prolog stacks.    If the  application
whishes to handle this signal too,  it should use PL_signal() to install
its handler after initialisating Prolog.   SWI-Prolog will pass SIG_SEGV
to the user  code if it detected the  signal is not related to a  Prolog
stack overflow.

Any handler that  wishes to call one  of the Prolog interface  functions
should call PL_signal() for its installation.


void (*)() PPLL__ssiiggnnaall(_s_i_g_, _f_u_n_c)
    This  function  is equivalent  to  the BSD-Unix  signal()  function,
    regardless  of the  platform used.   The  signal handler is  blocked
    while  the signal routine  is active, and automatically  reactivated
    after the handler returns.

    After  a  signal handler  is  registered using  this  function,  the
    native  signal interface  redirects the signal  to a generic  signal
    handler  inside  SWI-Prolog.   This  generic  handler validates  the
    environment,   creates  a  suitable  environment  for   calling  the
    interface functions described  in this chapter and finally calls the
    registered user-handler.

    By  default, signals  are handled asynchronously  (i.e. at the  time
    they  arrive).   It is  inheritly dangerous  to call extensive  code
    fragments,  and especially exception related code  from asynchronous
    handlers.     The  interface  allows  for  _s_y_n_c_h_r_o_n_o_u_s  handling  of
    signals.   In  this case  the native OS  handler just schedules  the
    signal  using PL_raise(),  which is checked by PL_handle_signals() at
    the  call- and redo-port.  This behaviour is realised by  or-ing _s_i_g
    with the constant PL_SIGSYNC.

    Signal    handling    routines    may   raise    exceptions    using
    PL_raise_exception().      The  use  of  PL_throw()  is  not   safe.
    If  a  synchronous handler  raises an  exception,  the exception  is
    delayed to the next call to PL_handle_signals();


int PPLL__hhaannddllee__ssiiggnnaallss(_v_o_i_d)
    Handle  any signals pending from PL_raise().  PL_handle_signals() is
    called  at  each pass  through the  call- and  redo-port  at a  safe
    point.   Exceptions raised by the handler using PL_raise_exception()
    are properly passed to the environment.

    The  user  may   call  this  function  inside  long-running  foreign
    functions to handle  scheduled interrupts.  This routine returns the
    number  of signals handled.   If a handler raises an exception,  the
    return value is  -1 and the calling routine should return with FALSE
    as soon as possible.


77..66..1111 MMiisscceellllaanneeoouuss


77..66..1111..11 TTeerrmm CCoommppaarriissoonn


int PPLL__ccoommppaarree(_t_e_r_m___t _t_1_, _t_e_r_m___t _t_2)
    Compares  two terms using  the standard order  of terms and  returns
    -1, 0 or 1.  See also compare/3.


int PPLL__ssaammee__ccoommppoouunndd(_t_e_r_m___t _t_1_, _t_e_r_m___t _t_2)
    Yields TRUE if _t_1  and _t_2 refer to physically the same compound term
    and FALSE otherwise.


77..66..1111..22 RReeccoorrddeedd ddaattaabbaassee

In some  applications it is  useful to store  and retreive Prolog  terms
from C-code.  For example, the XPCE graphical  environment does this for
storing arbitrary Prolog data as slot-data of XPCE objects.

Please note  that the  returned handles  have no meaning  at the  Prolog
level  and  the recorded  terms  are  not  visible from  Prolog.     The
functions PL_recorded() and PL_erase() are  the only functions that  can
operate on the stored term.

Two groups  of functions are  provided.The first group  (PL_record() and
friends) store Prolog terms on the Prolog heap for  retrieval during the
same session.   These functions are also used by recorda/3  and friends.
The recorded  database may be used  to communicate Prolog terms  between
threads.


record_t PPLL__rreeccoorrdd(_t_e_r_m___t _+_t)
    Record  the term _t into the Prolog database as recorda/3  and return
    an  opaque handle to  the term.   The returned handle remains  valid
    until  PL_erase() is called on  it.   PL_recorded() is used to  copy
    recorded terms back to the Prolog stack.


void PPLL__rreeccoorrddeedd(_r_e_c_o_r_d___t _r_e_c_o_r_d_, _t_e_r_m___t _-_t)
    Copy a recorded term  back to the Prolog stack.  The same record may
    be used to copy  multiple instances at any time to the Prolog stack.
    See also PL_record() and PL_erase().


void PPLL__eerraassee(_r_e_c_o_r_d___t _r_e_c_o_r_d)
    Remove  the recorded term from  the Prolog database, reclaiming  all
    associated memory resources.

The  second group  (headed  by PL_record_external()) provides  the  same
functionality, but the returned data has properties  that enable storing
the  data on  an external  device.   It  has been  designed  to make  it
possible to store Prolog terms fast an compact in  an external database.
Here are the main features:

  o _I_n_d_e_p_e_n_d_e_n_t _o_f _s_e_s_s_i_o_n
    Records  can  be communicated  to another  Prolog  session and  made
    visible using PL_recorded_external().

  o _B_i_n_a_r_y
    The representation is  binary for maximum performance.  The returned
    data may contain 0-bytes.

  o _B_y_t_e_-_o_r_d_e_r _i_n_d_e_p_e_n_d_e_n_t
    The   representation  can  be  transferred  between   machines  with
    different byte-order.

  o _N_o _a_l_i_g_n_m_e_n_t _r_e_s_t_r_i_c_t_i_o_n_s
    There are no  memory alignment restrictions and copies of the record
    can  thus be  moved freely.    For example,  it is  possible to  use
    this  representation to exchange  terms using shared memory  between
    different Prolog processes.

  o _C_o_m_p_a_c_t
    It  is  assumed  that a  smaller  memory footprint  will  eventually
    outperform slightly faster representations.

  o _S_t_a_b_l_e
    The  format is  designed  for future  enhancements without  breaking
    compatibility with older records.


char * PPLL__rreeccoorrdd__eexxtteerrnnaall(_t_e_r_m___t _+_t_, _u_n_s_i_g_n_e_d _i_n_t _*_l_e_n)
    Record  the term _t into the Prolog database as recorda/3  and return
    an  opaque handle to  the term.   The returned handle remains  valid
    until PL_erase() is called on it.

    It  is allowed  to copy the  data and use  PL_recorded_external() on
    the  copy.   The user  is responsible for  the memory management  of
    the  copy.    After copying,  the original  may  be discarded  using
    PL_erase_external().

    PL_recorded_external() is used to  copy such recorded terms back  to
    the Prolog stack.


int PPLL__rreeccoorrddeedd__eexxtteerrnnaall(_c_o_n_s_t _c_h_a_r _*_r_e_c_o_r_d_, _t_e_r_m___t _-_t)
    Copy a recorded term  back to the Prolog stack.  The same record may
    be used to copy  multiple instances at any time to the Prolog stack.
    See also PL_record_external() and PL_erase_external().


int PPLL__eerraassee__eexxtteerrnnaall(_c_h_a_r _*_r_e_c_o_r_d)
    Remove  the recorded term from  the Prolog database, reclaiming  all
    associated memory resources.


77..66..1111..33 GGeettttiinngg ffiillee nnaammeess

The function PL_get_file_name() provides access to Prolog filenames  and
its  file-search mechanism  described  with absolute_file_name/3.    Its
existence  is motivated  to realise  a uniform  interface  to deal  with
file-properties, search, naming conventions etc. from foreign code.


int PPLL__ggeett__ffiillee__nnaammee(_t_e_r_m___t _s_p_e_c_, _c_h_a_r _*_*_n_a_m_e_, _i_n_t _f_l_a_g_s)
    Translate  a Prolog  term into  a file  name.   The  name is  stored
    in  the  static  buffer ring  described  with  PL_get_chars() option
    BUF_RING. _f_l_a_g_s  is a bit-mask  controlling the conversion  process.
    Options are:

    PL_FILE_ABSOLUTE
         Return an absolute path to the requested file.

    PL_FILE_OSPATH
         Return  a the  name  using the  hosting  OS  conventions.    On
         MS-Windows, \ is  used to seperate directories rather than  the
         canonical /.

    PL_FILE_SEARCH
         Invoke  absolute_file_name/3.      This   implies  rules   from
         file_search_path/2are used.

    PL_FILE_EXIST
         Demand the path to refer to an existing entity.

    PL_FILE_READ
         Demand read-access on the result.

    PL_FILE_WRITE
         Demand write-access on the result.

    PL_FILE_EXECUTE
         Demand execute-access on the result.

    PL_FILE_NOERRORS
         Do not raise any exceptions.


77..66..1122 EErrrroorrss aanndd wwaarrnniinnggss

PL_warning() prints a  standard Prolog warning  message to the  standard
error (user_error) stream.   Please note  that new code should  consider
using  PL_raise_exception() to  raise a  Prolog  exception.    See  also
section 4.9.


int PPLL__wwaarrnniinngg(_f_o_r_m_a_t_, _a_1_, _._._.)
    Print  an  error message  starting  with `[WARNING: ',  followed  by
    the  output from  _f_o_r_m_a_t, followed  by a `]'  and a newline.    Then
    start  the tracer.   _f_o_r_m_a_t and  the arguments are  the same as  for
    printf(2).  Always returns FALSE.


77..66..1133 EEnnvviirroonnmmeenntt CCoonnttrrooll ffrroomm FFoorreeiiggnn CCooddee


int PPLL__aaccttiioonn(_i_n_t_, _._._.)
    Perform  some  action on  the  Prolog system.    _i_n_t  describes  the
    action,  Remaining arguments depend  on the requested  action.   The
    actions are listed in table 7.1.
    ___________________________________________________________________
    | PL_ACTION_TRACE        |Start Prolog tracer (trace/0).   Requires|
    |                        |no arguments.                            |
    | PL_ACTION_DEBUG        |Switch  on Prolog  debug mode  (debug/0).|
    |                        |Requires no arguments.                   |
    | PL_ACTION_BACKTRACE    |Print   backtrace   on   current   output|
    |                        |stream.   The  argument (an  int) is  the|
    |                        |number of frames printed.                |

    | 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.    The|
    |                        |argument (an int) is the  exit code.  See|
    |                        |halt/1.                                  |
    | PL_ACTION_ABORT        |Generate a Prolog abort  (abort/0).  This|

    |                        |call  does  not  return.     Requires  no|
    |                        |arguments.                               |
    | PL_ACTION_BREAK        |Create  a  standard  Prolog  break  envi-|
    |                        |ronment  (break/0).    Returns after  the|
    |                        |user  types  the  end-of-file  character.|
    ||                       |Requires|no arguments.                   ||

    | PL_ACTION_GUIAPP       |Win32:  Used to  indicate the kernel that|
    |                        |the application  is a GUI  application if|
    |                        |the  argument  is  not 0  and  a  console|
    |                        |application if  the argument  is 0.    If|
    |                        |a  fatal error  occurs,  the system  uses|
    |                        |a windows  messagebox to  report this  on|
    |                        |a GUI  application and simply  prints the|
    |                        |error and exits otherwise.               |
    | PL_ACTION_WRITE        |Write  the  argument,  a  char *  to  the|

    |                        |current output stream.                   |
    | PL_ACTION_FLUSH        |Flush  the current  output stream.    Re-|
    |                        |quires no arguments.                     |
    | PL_ACTION_ATTACH_CONSOLE|Attach a console  to a thread if  it does|
    |________________________|not_have_one.__See_attach_console/0._____|

                    Table 7.1:  PL_action() options


77..66..1144 QQuueerryyiinngg PPrroolloogg


C_type PPLL__qquueerryy(_i_n_t)
    Obtain  status  information  on  the  Prolog system.     The  actual
    argument  type depends on the  information required.  _i_n_t  describes
    what information is wanted.  The options are given in table 7.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_MAX_INTEGER         |Return a  long, representing  the maximal|
    |                        |integer  value  represented by  a  Prolog|
    |                        |integer.                                 |
    | PL_MIN_INTEGER         |Return a  long, representing  the minimal|
    |                        |integer value.                           |
    | PL_QUERY_VERSION       |Return a  long, representing  the version|

    |                        |as 10; 000M* +100m* +p, where  M is  the |
    |                        |major,  m the  minor version  number and |
    |                        |p the  patch-level.   For  example, 20717|
    |________________________|means_2.7.17.____________________________|

                     Table 7.2:  PL_query() options


77..66..1155 RReeggiisstteerriinngg FFoorreeiiggnn PPrreeddiiccaatteess


int PPLL__rreeggiisstteerr__ffoorreeiiggnn(_c_o_n_s_t _c_h_a_r _*_n_a_m_e_, _i_n_t _a_r_i_t_y_, _f_o_r_e_i_g_n___t _(_*_f_u_n_c_t_i_o_n_)_(_)_, _i_n_t _f_l_a_g_s)

    Register   a   C-function   to   implement   a   Prolog   predicate.
    After  this call  returns successfully  a predicate  with name  _n_a_m_e
    (a  char *) and  arity _a_r_i_t_y  (a C int)  is created.   As a  special
    case,  _n_a_m_e may consist of a sequence of  alpha-numerical characters
    followed  by the colon (:).   In this case the name uptil  the colon
    is  taken to be the destination module and the rest of the  name the
    predicate name.

    When  called in  Prolog, Prolog  will call  _f_u_n_c_t_i_o_n.   _f_l_a_g_s  forms
    bitwise or'ed 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.     See|
    |                        |also PL_retry().                         |

    |_PL_FA_VARARGS__________|Use_alternative_calling_convention.______|


void PPLL__llooaadd__eexxtteennssiioonnss(_P_L___e_x_t_e_n_s_i_o_n _*_e)
    Register  foreign  predicates from  a  table of  structures.    This
    is  an alternative  to multiple  calls to  PL_register_foreign() and
    simplifies  code that wishes  to use  PL_register_extensions()as  an
    alternative.  The type PL_extension is defined as:

    typedef struct _PL_extension
    { char          *predicate_name; /* Name of the predicate */
      short         arity;           /* Arity of the predicate */
      pl_function_t function;        /* Implementing functions */
      short         flags;           /* Or of PL_FA_... */
    } PL_extension;


void PPLL__rreeggiisstteerr__eexxtteennssiioonnss(_P_L___e_x_t_e_n_s_i_o_n _*_e)
    The      function      PL_register_extensions()      behaves      as
    PL_load_extensions(),  but  is  the  only  PL_*  function  that  may
    be  called bbeeffoorree  PL_initialise().    The predicates are  registered
    iinnttoo  tthhee mmoodduullee user after  registration of the SWI-Prolog  builtin
    foreign  predicates  and before  loading  the initial  saved  state.
    This implies that initialization/1 directives can refer to them.

    Here is an example of its usage:

    static PL_extension predicates[] = {
    { "foo",        1,      pl_foo, 0 },
    { "bar",        2,      pl_bar, PL_FA_NONDETERMINISTIC },
    { NULL,         0,      NULL,   0 }
    };

    main(int argc, char **argv)
    { PL_register_extensions(predicates);

      if ( !PL_initialise(argc, argv) )
        PL_halt(1);

      ...
    }


77..66..1166 FFoorreeiiggnn CCooddee HHooookkss

For various specific applications some hooks re provided.


PL_dispatch_hook_t PPLL__ddiissppaattcchh__hhooookk(_P_L___d_i_s_p_a_t_c_h___h_o_o_k___t)
    If  this hook  is not  NULL, this  function is  called when  reading
    from  the  terminal.     It is  supposed  to  dispatch  events  when
    SWI-Prolog  is connected  to a window  environment.   It can  return
    two  values:  PL_DISPATCH_INPUT indicates Prolog input is  available
    on  file descriptor 0 or PL_DISPATCH_TIMEOUT to indicate a  timeout.
    The  old hook is  returned.  The  type PL_dispatch_hook_t is  defined
    as:

    typedef int  (*PL_dispatch_hook_t)(void);


void PPLL__aabboorrtt__hhooookk(_P_L___a_b_o_r_t___h_o_o_k___t)
    Install  a hook  when abort/0 is  executed.   SWI-Prolog abort/0  is
    implemented  using C  setjmp()/longjmp() construct.   The hooks  are
    executed  in  the  reverse order  of  their registration  after  the
    longjmp()  took place and before  the Prolog toplevel is  reinvoked.
    The type PL_abort_hook_t is defined as:

    typedef void (*PL_abort_hook_t)(void);


int PPLL__aabboorrtt__uunnhhooookk(_P_L___a_b_o_r_t___h_o_o_k___t)
    Remove  a hook installed with PL_abort_hook().  Returns FALSE  if no
    such hook is found, TRUE otherwise.


void PPLL__oonn__hhaalltt(_v_o_i_d _(_*_f_)_(_i_n_t_, _v_o_i_d _*_)_, _v_o_i_d _*_c_l_o_s_u_r_e)
    Register  the function _f to be called if SWI-Prolog is halted.   The
    function  is  called with  two  arguments:   the  exit code  of  the
    process  (0 if this cannot  be determined on your operating  system)
    and  the _c_l_o_s_u_r_e argument passed to the PL_on_halt()call.   See also
    at_halt/1.


PL_agc_hook_t PPLL__aaggcc__hhooookk(_P_L___a_g_c___h_o_o_k___t _n_e_w)
    Register    a   hook   with   the   atom-garbage    collector   (see
    garbage_collect_atoms/0  that  is   called  on  any  atom  that   is
    reclaimed.    The old hook  is returned.   If  no hook is  currently
    defined,  NULL is returned.  The argument of the called hook  is the
    atom  that is to be garbage collected.  The return value  is an int.
    If  the return value is zero, the  atom is nnoott reclaimed.   The hook
    may invoke any Prolog predicate.

    The  example  below  defines  a foreign  library  for  printing  the
    garbage collected atoms for debugging purposes.

    #include <SWI-Stream.h>
    #include <SWI-Prolog.h>

    static int
    atom_hook(atom_t a)
    { Sdprintf("AGC: deleting %s\n", PL_atom_chars(a));

      return TRUE;
    }

    static PL_agc_hook_t old;

    install_t
    install()
    { old = PL_agc_hook(atom_hook);
    }

    install_t
    uninstall()
    { PL_agc_hook(old);
    }


77..66..1177 SSttoorriinngg ffoorreeiiggnn ddaattaa

This section  provides some hints for  handling foreign data in  Prolog.
With foreign  data, we refer  to data that is  used by foreign  language
predicates  and  needs  to  be passed  around  in  Prolog.     Excluding
combinations, there are three principal options for storing such data

  o _N_a_t_u_r_a_l _P_r_o_l_o_g _d_a_t_a
    E.i.  using the  representation  one would  choose if  there was  no
    foreign interface required.

  o _O_p_a_q_u_e _p_a_c_k_e_d _P_r_o_l_o_g _d_a_t_a
    Data can also  be represetented in a foreign structure and stored on
    the  Prolog stacks using  PL_put_string_nchars()and retrieved  using
    PL_get_string_chars().   It is generally good  practice to wrap  the
    string  in a compound term with arity 1, so Prolog can  identify the
    type.    portray/1 rules  may be  used to  streamline printing  such
    terms during development.

  o _N_a_t_u_r_a_l _f_o_r_e_i_g_n _d_a_t_a_, _p_a_s_s_i_n_g _a _p_o_i_n_t_e_r
    An  alternative is to pass  a pointer to the  foreign data.   Again,
    this functor may be wrapped in a compound term.

The choice may be guided using the following distinctions

  o _I_s _t_h_e _d_a_t_a _o_p_a_q_u_e _t_o _P_r_o_l_o_g
    With  `opaque' data, we refer to data handled in  foreign functions,
    passed  around in  Prolog, but  of which Prolog  never examines  the
    contents  of the  data itself.   If  the data is  opaque to  Prolog,
    the  choosen representation  does not depend  on simple analysis  by
    Prolog,  and the selection  will be driven  solely by simplicity  of
    the interface and performance (both in time and space).

  o _H_o_w _b_i_g _i_s _t_h_e _d_a_t_a
    Is  effient encoding  required?   For  examine, a  boolean aray  may
    be  expressed as  a compound  term, holding integers  each of  which
    contains a number of bits, or as a list of true and false.

  o _W_h_a_t _i_s _t_h_e _n_a_t_u_r_e _o_f _t_h_e _d_a_t_a
    For  examples in C,  constants are often  expressed using `enum'  or
    #define'd  integer values.   If  prolog needs  to handle this  data,
    atoms  are a more logical  choice.  Whether  or not this mapping  is
    used  depends on  whether Prolog  needs to interpret  the data,  how
    important debugging is and how important performance is.

  o _W_h_a_t _i_s _t_h_e _l_i_f_e_t_i_m_e _o_f _t_h_e _d_a_t_a
    We can distinguish three cases.

     1.  The lifetime  is dictated by  the accesibility  of the data  on
         the Prolog stacks.   Their is no way by which the  foreign code
         when the  data becomes `garbage',  and the  data thus needs  to
         be represented  on the Prolog  stacks using Prolog  data-types.
         (2),

     2.  The  data lives  on  the  `heap' and  is  explicitly  allocated
         and deallocated.   In  this case,  representing the data  using
         native foreign representation and passing a pointer to  it is a
         sensible choice.

     3.  The data lives as  during the lifetime of a  foreign predicate.
         If the predicate is deterministic, foreign  automatic variables
         are suitable.  if the predicate is  non-deterministic, the data
         may be allocated  using malloc() and  a pointer may be  passed.
         See section 7.6.1.1.


77..66..1177..11 EExxaammpplleess ffoorr ssttoorriinngg ffoorreeiiggnn ddaattaa

In this section, we wull outline some examples,  covering typical cases.
In  the  first  example,  we will  deal  with  extending  Prolog's  data
representation with  integer-sets, represented as  bit-vectors.  In  the
second example, we  look at handling a  `netmask'.  Finally, we  discuss
the outline of the DDE interface.

IInntteeggeerr  sseettss with  not-to-far-apart  upper-  and  lower-bounds  can  be
represented using  bit-vectors.  Common  set operations, such as  union,
intersection,  etc.    are  reduced to  simple  and'ing and  or'ing  the
bitvectors.    This  can  be  done  in Prolog,  using  a  compound  term
holding  integer  arguments.    Especially  if  the  integers  are  kept
below  the maximum  tagged  integer  value (see  current_prolog_flag/2),
this representation  is fairly space-efficient (wasting  1 word for  the
functor and and  7 bits per integer for  the tags).  Arithmetic can  all
be performed in Prolog too.

For really demanding  applications, foreign representation will  perform
better,  especially  time-wise.    Bit-vectors are  natrually  expressed
using  string  objects.    If  the  string is  wrapped  in  bitvector/1,
lower-bound of the  vector is 0, and  the upperbound is not defined,  an
implementation for getting  and putting the setes  as well as the  union
predicate for it is below.

#include <SWI-Prolog.h>

#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))

static functor_t FUNCTOR_bitvector1;

static int
get_bitvector(term_t in, int *len, unsigned char **data)
{ if ( PL_is_functor(in, FUNCTOR_bitvector1) )
  { term_t a = PL_new_term_ref();

    PL_get_arg(1, in, a);
    return PL_get_string(a, (char **)data, len);
  }

  PL_fail;
}

static int
unify_bitvector(term_t out, int len, const unsigned char *data)
{ if ( PL_unify_functor(out, FUNCTOR_bitvector1) )
  { term_t a = PL_new_term_ref();

    PL_get_arg(1, out, a);

    return PL_unify_string_nchars(a, len, (const char *)data);
  }

  PL_fail;
}

static foreign_t
pl_bitvector_union(term_t t1, term_t t2, term_t u)
{ unsigned char *s1, *s2;
  int l1, l2;

  if ( get_bitvector(t1, &l1, &s1) &&
       get_bitvector(t2, &l2, &s2) )
  { int l = max(l1, l2);
    unsigned char *s3 = alloca(l);

    if ( s3 )
    { int n;
      int ml = min(l1, l2);

      for(n=0; n<ml; n++)
        s3[n] = s1[n] | s2[n];
      for( ; n < l1; n++)
        s3[n] = s1[n];
      for( ; n < l2; n++)
        s3[n] = s2[n];

      return unify_bitvector(u, l, s3);
    }

    return PL_warning("Not enough memory");
  }

  PL_fail;
}

install_t
install()
{ PL_register_foreign("bitvector_union", 3, pl_bitvector_union, 0);

  FUNCTOR_bitvector1 = PL_new_functor(PL_new_atom("bitvector"), 1);
}

NNeettmmaasskk''ss are  used with  TCP/IP  configuration.    Suppose we  have  an
application dealing with reasoning about a network configuration.   Such
an  application  requires  communicating  netmask  structures  from  the
operating system,  reasoning about  them and  possibly communicate  them
to the  user.   A  netmask consists  of 4  bitmasks between  0 and  255.
C-application  normally see  them as  an 4-byte  wide unsigned  integer.
SWI-Prolog cannot do that, as integers are always signed.

We could use the string approach outlined above, but  this makes it hard
to handle  these terms in Prolog.   A better  choice is a compound  term
netmask/4, holding the 4 submasks as integer arguments.

As the implementation is trivial, we will omit this here.

TThhee DDDDEE  iinntteerrffaaccee (see section  4.43) represents  another common  usage
of  the foreign  interface:   providing communication  to new  operating
system features.  The DDE interface requires knowledge  about active DDE
server and  client channels.   These  channels contains various  foreign
data-types.  Such an interface is normally achieved  using an open/close
protocol that creates and destroys a _h_a_n_d_l_e.  The  handle is a reference
to a foreign data-structure containing the relevant information.

There are a  couple of possibilities for  representing the handle.   The
choice  depends on  responsibilities  and  debugging facilities.     The
simplest  aproach is  to using  PL_unify_pointer() and PL_get_pointer().
This  approach is  fast and  easy, but  has the  drawbacks of  (untyped)
pointers:   there  is no  reliable way  to detect  the  validity of  the
pointer, not  to verify  it is pointing  to a  structure of the  desired
type.   The pointer  may be wrapped  into a compound  term with arity  1
(i.e., dde_channel(<_P_o_i_n_t_e_r>)), making the type-problem less serious.

Alternatively  (used in  the  DDE  interface),  the interface  code  can
maintain a  (preferably variable  length) array of  pointers and  return
the index in this  array.  This provides better protection.   Especially
for debugging  purposes, wrapping  the handle  in a compound  is a  good
suggestion.


77..66..1188 EEmmbbeeddddiinngg SSWWII--PPrroolloogg iinn ootthheerr aapppplliiccaattiioonnss

With embedded Prolog we refer to the situation where  the `main' program
is not the Prolog application.  Prolog is sometimes  embedded in C, C++,
Java or  other languages  to provide  logic based services  in a  larger
application.   Embedding  loads the Prolog  engine as  a library to  the
external language.   Prolog  itself only provides  for embedding in  the
C-language (compatible  to C++).   Embedding in  Java is achieved  using
JPL using a C-glue between the Java and Prolog C-interfaces.

The  most   simple  embedded   program  is   below.      The   interface
function  PL_initialise()  mmuusstt  be  called  before  any  of  the  other
SWI-Prolog  foreign  language  functions  described  in   this  chapter,
except for PL_initialise_hook(), PL_new_atom()and PL_register_foreign().
PL_initialise() interprets  all the command-line  arguments, except  for
the -t toplevel flag that is interpreted by PL_toplevel().

int
main(int argc, char **argv)
{
#ifdef READLINE /* Remove if you don't want readline */
  PL_initialise_hook(install_readline);
#endif

  if ( !PL_initialise(argc, argv) )
    PL_halt(1);

  PL_halt(PL_toplevel() ? 0 : 1);
}


int PPLL__iinniittiiaalliissee(_i_n_t _a_r_g_c_, _c_h_a_r _*_*_a_r_g_v)
    Initialises  the SWI-Prolog  heap and  stacks,  restores the  Prolog
    state, loads the  system and personal initialisation files, runs the
    at_initialization/1 hooks and finally runs the -g goal hook.

    Special  consideration  is required  for argv[0].    On  UUnniixx,  this
    argument  passes the part of the commandline that is used  to locate
    the  executable.   Prolog  uses this to  find the  file holding  the
    running executable.   The WWiinnddoowwss version uses this to find a _m_o_d_u_l_e
    of  the  running executable.    If the  specified  module cannot  be
    found, it tries  the module libpl.dll, containing the Prolog runtime
    kernel.   In  all these cases,  the resulting file  is used for  two
    purposes

      o  See whether a Prolog saved-state  is appended to the file.   If
         this is  the case,  this state  will be loaded  instead of  the
         default boot.prc file from the SWI-Prolog home directory.   See
         also qsave_program/[1,2] and section 7.7.

      o  Find the Prolog home  directory.  This process is  described in
         detail in section 7.8.

    PL_initialise()  returns 1  if all  initialisation  succeeded and  0
    otherwise.

    In  most cases, _a_r_g_c and _a_r_g_v will be passed from the  main program.
    It  is allowed to create your own argument vector,  provided argv[0]
    is constructed according to the rules above.  For example:

    int
    main(int argc, char **argv)
    { char *av[10];
      int ac = 0;

      av[ac++] = argv[0];
      av[ac++] = "-x";
      av[ac++] = "mystate";
      av[ac]   = NULL;

      if ( !PL_initialise(ac, av) )
        PL_halt(1);
      ...
    }

    Please  note that the  passed argument vector  may be referred  from
    Prolog  at any time  and should  therefore be valid  as long as  the
    Prolog engine is used.

    A  good setup  in Windows is  to add  SWI-Prolog's bin directory  to
    your  PATH  and  either pass  a  module holding  a  saved-state,  or
    "libpl.dll"  as argv[0].  If the  Prolog state is attached to  a DLL
    (see the -dll option of plld, pass the name of this DLL.


int PPLL__iiss__iinniittiiaalliisseedd(_i_n_t _*_a_r_g_c_, _c_h_a_r _*_*_*_a_r_g_v)
    Test  whether the  Prolog engine  is already initialised.    Returns
    FALSE  if Prolog  is not  initialised and TRUE  otherwise.   If  the
    engine is initialised  and _a_r_g_c is not NULL, the argument count used
    with  PL_initialise() is  stored in  _a_r_g_c.   Same  for the  argument
    vector _a_r_g_v.


void PPLL__iinnssttaallll__rreeaaddlliinnee()
    Installs  the GNU-readline line-editor.  Embedded  applications that
    do  not use the  Prolog toplevel should  normally delete this  line,
    shrinking  the Prolog kernel significantly.   Note that the  Windows
    version does not use GNU readline.


int PPLL__ttoopplleevveell()
    Runs  the  goal of  the -t toplevel  switch  (default prolog/0)  and
    returns 1 if successful, 0 otherwise.


void PPLL__cclleeaannuupp(_i_n_t _s_t_a_t_u_s)
    This  function performs  the reverse  of PL_initialise().   It  runs
    the  PL_on_halt()and at_halt/1 handlers, closes all  streams (except
    for the `standard  I/O' streams which are flushed only), deallocates
    all  memory and restores all signal  handlers.  The _s_t_a_t_u_s  argument
    is  passed  to  the  various termination  hooks  and  indicates  the
    _e_x_i_t_-_s_t_a_t_u_s.

    This  function allows deleting and  restarting the Prolog system  in
    the same  process.  Use it with care, as PL_initialise() is a costly
    function.   Unix  users should consider  using exec() (available  as
    part of the clib package,).


int PPLL__hhaalltt(_i_n_t _s_t_a_t_u_s)
    Cleanup  the Prolog environment using PL_cleanup() and calls  exit()
    with  the  status argument.    As  PL_cleanup() can only  be  called
    from  the main thread, this function returns FALSE when  called from
    another thread as the main one.


77..66..1188..11 TThhrreeaaddiinngg,, SSiiggnnaallss aanndd eemmbbeeddddeedd PPrroolloogg

This section  applies to  Unix-based environments that  have signals  or
multi-threading.   The Windows version  is compiled for  multi-threading
and Windows lacks proper signals.

We  can distinguish  two classes  of embedded  executables.   There  are
small C/C++-programs  that act  as an interfacing  layer around  Prolog.
Most  of  these  programs  can  be  replaced  using  the  normal  Prolog
executable extended with  a dynamically loaded foreign extension and  in
most cases  this is  the preferred  route.   In other  cases, Prolog  is
embedded in a complex application that---like  Prolog---wants to control
the process  environment.   A good  example is Java.   Embedding  Prolog
is generally  the only  way to  get these environments  together in  one
process image.   Java applications however are by  nature multi-threaded
and appear to do signal-handling (software interrupts).

To  make  Prolog  operate smoothly  in  such  environments  it  must  be
told not  to alter  the process  environment.   This is  partly done  at
build-time and  partly execution time.   At  build-time we must  specify
the  use of  software stack-overflow  rather then  the default  hardware
checks.  This is done using

sh configure --disable-segv-handling

The resulting  Prolog executable  is about  10% slower  than the  normal
executable,  but  behaves much  more  reliable in  complicated  embedded
situations.  In addition, as the process  no longer handles segmentation
violations, debugging foreign code linked to it is much easier.

At runtime,  it is adviced to pass  the flag -nosignals, which  inhibits
all default signal handling.  This has a few consequences though:

  o It  is  no  longer  possible  to break  into  the  tracer  using  an
    interrupt signal (Control-C).

  o SIGPIPE is normally set  to be ignored.  Prolog uses return-codes to
    diagnose  broken pipes.  Depending on the situation one  should take
    appropriate action if Prolog streams are connected to pipes.

  o Fatal errors  normally cause Prolog to call PL_cleanup() and exit().
    It is  adviced to call PL_cleanup()as part  of the exit-procedure of
    your application.


77..77 LLiinnkkiinngg eemmbbeeddddeedd aapppplliiccaattiioonnss uussiinngg pplllldd

The  utility program  plld (Win32:   plld.exe)  may be  used  to link  a
combination of C-files  and Prolog files into a stand-alone  executable.
plld automates most of what is described in the previous sections.

In the normal  usage, a copy is  made of the default embedding  template
\ldots/pl/include/stub.c.    The  main()  routine is  modified  to  suit
your  application.    PL_initialise() mmuusstt  be passed  the  program-name
(_a_r_g_v_[_0_])  (Win32:    the  executing  program  can   be  obtained  using
GetModuleFileName()).   The other  elements of  the command-line may  be
modified.  Next, plld is typically invoked as:

plld -o output stubfile.c [other-c-or-o-files] [plfiles]

plld  will first  split the  options into  various groups  for both  the
C-compiler and the Prolog  compiler.  Next, it will add  various default
options to the  C-compiler and call it  to create an executable  holding
the  user's C-code  and the  Prolog kernel.    Then,  it  will call  the
SWI-Prolog compiler  to create a  saved state  from the provided  Prolog
files  and finally,  it  will attach  this saved  state to  the  created
emulator to create the requested executable.

Below, it  is described how the options  are split and which  additional
options are passed.

--hheellpp
    Print brief synopsis.

--ppll _p_r_o_l_o_g
    Select  the prolog to use.   This prolog  is used for two  purposes:
    get  the home-directory as well  as the compiler/linker options  and
    create a saved state of the Prolog code.

--lldd _l_i_n_k_e_r
    Linker  used to  link the raw  executable.   Default is  to use  the
    C-compiler (Win32:  link.exe).

--cccc _C_-_c_o_m_p_i_l_e_r
    Compiler  for  .c  files found  on  the  commandline.    Default  is
    the  compiler used  to build SWI-Prolog  (see current_prolog_flag/2)
    (Win32:  cl.exe).

--cc++++ _C_+_+_-_c_o_m_p_i_l_e_r
    Compiler  for C++ sources (extensions  .cpp, .cxx, .cc or .C)  files
    found  on the commandline.  Default is c++ or g++ if  the C-compiler
    is gcc) (Win32:  cl.exe).

--nnoossttaattee
    Just  relink  the  kernel,  do  not  add  any  Prolog  code  to  the
    new  kernel.     This  is  used  to  create  a  new  kernel  holding
    additional  foreign predicates on machines  that do not support  the
    shared-library  (DLL) interface, or if building the state  cannot be
    handled  by the default procedure used by plld.  In the  latter case
    the  state is created  seperately and appended  to the kernel  using
    cat <_k_e_r_n_e_l> <_s_t_a_t_e> > <_o_u_t>(Win32:  copy /b <_k_e_r_n_e_l>+<_s_t_a_t_e> <_o_u_t>)

--sshhaarreedd
    Link  C, C++ or object files into a shared object (DLL) that  can be
    loaded  by the  load_foreign_library/1predicate.    If used with  -c
    it  sets the proper  options to compile  a C or  C++ file ready  for
    linking into a shared object

--ddllll
    _W_i_n_d_o_w_s  _o_n_l_y.     Embed  SWI-Prolog  into  a  DLL  rather  than  an
    executable.

--cc
    Compile  C  or C++  source-files  into object  files.    This  turns
    plld  into a  replacement for  the C  or C++  compiler where  proper
    options  such as the  location of the  include directory are  passed
    automatically to the compiler.

--EE
    Invoke the C preprocessor.   Used to make plld a replacement for the
    C or C++ compiler.

--ppll--ooppttiioonnss _,_._._.
    Additional  options passed to Prolog when creating the  saved state.
    The  first character  immediately  following pl-options  is used  as
    separator  and  translated to  spaces when  the  argument is  built.
    Example:  -pl-options,-F,xpce  passed -F xpce as additional flags to
    Prolog.

--lldd--ooppttiioonnss _,_._._.
    Passes options to the linker, similar to -pl-options.

--cccc--ooppttiioonnss _,_._._.
    Passes options to the C/C++ compiler, similar to -pl-options.

--vv
    Select  verbose operation,  showing the  various programs and  their
    options.

--oo _o_u_t_f_i_l_e
    Reserved to specify the final output file.

--ll_l_i_b_r_a_r_y
    Specifies  a library for the C-compiler.   By default, -lpl  (Win32:
    libpl.lib) and the libraries needed by the Prolog kernel are given.

--LL_l_i_b_r_a_r_y_-_d_i_r_e_c_t_o_r_y
    Specifies  a  library directory  for  the C-compiler.    By  default
    the  directory  containing  the  Prolog C-library  for  the  current
    architecture is passed.

-g | -Iinclude-directory | -Ddefinition
    These  options  are passed  to  the C-compiler.    By  default,  the
    include directory containing SWI-Prolog.h  is passed.  plld adds two
    additional * -Ddef flags:

    --DD____SWI_PROLOG__
         Indicates the code is to be connected to SWI-Prolog.

    --DD____SWI_EMBEDDED__
         Indicates the creation of an embedded program.

 _*_._o | _*_._c | _*_._C | _*_._c_x_x | _*_._c_p_p
    Passed as input files to the C-compiler

 _*_._p_l |_*_._q_l_f
    Passed  as  input  files  to  the  Prolog  compiler  to  create  the
    saved-state.

 *
    I.e.  all other options.  These are passed as linker options  to the
    C-compiler.


77..77..11 AA ssiimmppllee eexxaammppllee

The  following is  a very  simple example  going through  all the  steps
outlined above.   It  provides an arithmetic expression  evaluator.   We
will call  the application calc  and define it in  the files calc.c  and
calc.pl.  The Prolog file is simple:

calc(Atom) :-
        term_to_atom(Expr, Atom),
        A is Expr,
        write(A),
        nl.

The  C-part  of   the  application  parses  the  command-line   options,
initialises the  Prolog engine, locates  the calc/1 predicate and  calls
it.  The coder is in figure 7.5.

#include <stdio.h>
#include <SWI-Prolog.h>

#define MAXLINE 1024

int
main(int argc, char **argv)
{ char expression[MAXLINE];
  char *e = expression;
  char *program = argv[0];
  char *plav[2];
  int n;

  /* combine all the arguments in a single string */

  for(n=1; n<argc; n++)
  { if ( n != 1 )
      *e++ = ' ';
    strcpy(e, argv[n]);
    e += strlen(e);

  }

  /* make the argument vector for Prolog */

  plav[0] = program;
  plav[1] = NULL;

  /* initialise Prolog */

  if ( !PL_initialise(1, plav) )
    PL_halt(1);

  /* Lookup calc/1 and make the arguments and call */

  { predicate_t pred = PL_predicate("calc", 1, "user");

    term_t h0 = PL_new_term_refs(1);
    int rval;

    PL_put_atom_chars(h0, expression);
    rval = PL_call_predicate(NULL, PL_Q_NORMAL, pred, h0);

    PL_halt(rval ? 0 : 1);
  }

  return 0;
}

             Figure 7.5:  C-source for the calc application

The application is now created using the following command-line:

% plld -o calc calc.c calc.pl

The following indicates the usage of the application:

% calc pi/2
1.5708


77..88 TThhee PPrroolloogg ``hhoommee'' ddiirreeccttoorryy

Executables  embedding SWI-Prolog  should  be able  to find  the  `home'
directory  of  the  development  environment  unless   a  self-contained
saved-state has  been added to  the executable  (see qsave_program/[1,2]
and section 7.7).

If Prolog starts up, it will try to  locate the development environment.
To do so, it will try the following steps until one succeeds.

 1. If  the environment variable  SWI_HOME_DIRis  defined and points  to
    an existing directory, use this.

 2. If  the  environment variable  SWIPL  is defined  and points  to  an
    existing directory, use this.

 3. Locate  the  primary   executable  or  (Windows  only)  a  component
    (_m_o_d_u_l_e)  thereof  and check  whether the  parent  directory of  the
    directory  holding this file contains the  file swipl.  If so,  this
    file  contains the (relative) path to  the home directory.  If  this
    directory  exists, use this.   This is the normal mechanism  used by
    the binary distribution.

 4. If  the precompiled path exists, use it.  This is only  useful for a
    source installation.

If  all fails  and  there is  no state  attached  to the  executable  or
provided Windows module (see PL_initialise()), SWI-Prolog gives up.   If
a state is attached, the current working directory is used.

The file_search_path/2 alias swi is set  to point to the home  directory
located.


77..99 EExxaammppllee ooff UUssiinngg tthhee FFoorreeiiggnn IInntteerrffaaccee

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  7.6 shows the C-source
file, figure 7.7 illustrates compiling and loading of foreign code.
/*  Include file depends on local installation */

#include <SWI-Prolog.h>
#include <stdlib.h>
#include <ctype.h>

foreign_t
pl_lowercase(term_t u, term_t l)
{ char *copy;
  char *s, *q;

  int rval;

  if ( !PL_get_atom_chars(u, &s) )
    return PL_warning("lowercase/2: instantiation fault");
  copy = malloc(strlen(s)+1);

  for( q=copy; *s; q++, s++)

    *q = (isupper(*s) ? tolower(*s) : *s);
  *q = '\0';

  rval = PL_unify_atom_chars(l, copy);
  free(copy);

  return rval;
}

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

                   Figure 7.6:  Lowercase source file

% gcc -I/usr/local/lib/pl-\plversion/include -fpic -c lowercase.c
% gcc -shared -o lowercase.so lowercase.o

% pl
Welcome to SWI-Prolog (Version \plversion)
Copyright (c) 1993-1996 University of Amsterdam.  All rights reserved.

For help, use ?- help(Topic). or ?- apropos(Word).

1 ?- load_foreign_library(lowercase).

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

L = 'hello world!'

Yes

    Figure 7.7:  Compiling the C-source and loading the object file


77..1100 NNootteess oonn UUssiinngg FFoorreeiiggnn CCooddee


77..1100..11 MMeemmoorryy AAllllooccaattiioonn

SWI-Prolog's heap  memory allocation is based  on the malloc(3)  library
routines.     The  stacks  are  allocated  using  mmap()  on  most  Unix
machines and using  VirtualAlloc() on windows.  SWI-Prolog  provides the
functions below  as a  wrapper around  malloc().   Allocation errors  in
these functions  trap SWI-Prolog's  fatal-error handler,  in which  case
PL_malloc() or PL_realloc()do not return.

Portable applications must use PL_free() to release strings  returned by
PL_get_chars()using  the BUF_MALLOC argument.   Portable applications may
use both PL_malloc() and friends or malloc() and friends  but should not
mix these two sets of functions on the same memory.


void * PPLL__mmaalllloocc(_s_i_z_e___t _b_y_t_e_s)
    Allocate  _b_y_t_e_s of  memory.    On failure  SWI-Prolog's fatal  error
    handler  is  called  and  PL_malloc()  does  not  return.     Memory
    allocated  using these functions must use PL_realloc() and PL_free()
    rather than realloc() and free().


void * PPLL__rreeaalllloocc(_v_o_i_d _*_m_e_m_, _s_i_z_e___t _s_i_z_e)
    Change  the size of the  allocated chunk, possibly  moving it.   The
    _m_e_m  argument  must  be  obtained  from a  previous  PL_malloc()  or
    PL_realloc() call.


void PPLL__ffrreeee(_v_o_i_d _*_m_e_m)
    Release  memory.  The _m_e_m argument must be obtained from  a previous
    PL_malloc() or PL_realloc() call.


77..1100..22 CCoommppaattiibbiilliittyy bbeettwweeeenn PPrroolloogg vveerrssiioonnss

Great  care  is   taken  to  ensure  binary  compatibility  of   foreign
extensions  between  different   Prolog  versions.     Only  much   less
frequently  used  stream  interface  has  been  responsible  for  binary
incompatibilities.

Source-code that  relies on new  features of  the foreign interface  can
use  the  macro  PLVERSION to  find  the  version  of  SWI-Prolog.h  and
PL_query() using  the  option PL_QUERY_VERSION to  find the  version  of
the  attached Prolog  system.   Both  follow the  same numbering  schema
explained with PL_query().


77..1100..33 DDeebbuuggggiinngg FFoorreeiiggnn CCooddee

Statically  linked foreign  code  or embedded  systems can  be  debugged
normally.     Most  modern  environments  provide  debugging  tools  for
dynamically  loaded shared  objects  or dynamic  load  libraries.    The
following example traces  the code of lowercase  using gdb(1) in a  Unix
environment.

% gcc -I/usr/local/lib/pl-2.2.0/include -fpic -c -g lowercase.c
% gcc -shared -o lowercase.so lowercase.o
% gdb pl
(gdb) r
Welcome to SWI-Prolog (Version \plversion)
Copyright (c) 1993-1996 University of Amsterdam.  All rights reserved.

For help, use ?- help(Topic). or ?- apropos(Word).

?- load_foreign_library(lowercase).
<type Control-C>
(gdb) shared                    % loads symbols for shared objects
(gdb) break pl_lowercase
(gdb) continue
?- lowercase('HELLO', X).


77..1100..44 NNaammee CCoonnfflliiccttss iinn CC mmoodduulleess

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_

Note  that shared  libraries do  not  have this  problem as  the  shared
library loader  will only look  for symbols in  the main executable  for
symbols that are not defined in the library itself.


77..1100..55 CCoommppaattiibbiilliittyy ooff tthhee FFoorreeiiggnn IInntteerrffaaccee

The term-reference  mechanism was first used  by Quintus Prolog  version
3.     SICStus  Prolog version  3  is  strongly  based  on  the  Quintus
interface.  The  described SWI-Prolog interface is similar to  using the
Quintus or SICStus interfaces, defining all  foreign-predicate arguments
of  type  +term.    SWI-Prolog  explicitly uses  type  functor_t,  while
Quintus  and SICStus  uses <_n_a_m_e>  and  <_a_r_i_t_y>.   As  the  names of  the
functions differ  from Prolog to  Prolog, a  simple macro layer  dealing
with the names can also deal with this detail.  For example:

#define QP_put_functor(t, n, a) PL_put_functor(t, PL_new_functor(n, a))

The  PL_unify_*()  functions are  lacking from  the  Quintus and  SICStus
interface.    They can  easily  be emulated  or the  put/unify  approach
should be used to write compatible code.

The PL_open_foreign_frame()/PL_close_foreign_frame() combination is lack-
ing from both other  Prologs.  SICStus has PL_new_term_refs(_0),  followed
by PL_reset_term_refs()that allows for discarding term references.

The  Prolog interface  for  the graphical  user interface  package  XPCE
shares about  90% of the code  using a simple  macro layer to deal  with
different naming and calling conventions of the interfaces.


CChhaapptteerr 88..  GGEENNEERRAATTIINNGG RRUUNNTTIIMMEE AAPPPPLLIICCAATTIIOONNSS

This  chapter  describes  the  features  of  SWI-Prolog  for  delivering
applications that can run without the development version  of the system
installed.

A SWI-Prolog runtime executable is a file consisting of two  parts.  The
first part  is the  _e_m_u_l_a_t_o_r, which is  machine dependent.   The  second
part is the _r_e_s_o_u_r_c_e  _a_r_c_h_i_v_e, which contains the compiled program  in a
machine-independent format,  startup options  and possibly  user-defined
_r_e_s_o_u_r_c_e_s, see resource/3 and open_resource/3.

These two parts  can be connected in various  different ways.  The  most
common way  for distributed runtime applications  is to _c_o_n_c_a_t_e_n_a_t_e  the
two parts.   This can be achieved  using external commands (Unix:   cat,
Windows:   copy), or  using the  stand_alone option  to qsave_program/2.
The  second option  is  to  attach a  startup  script  in front  of  the
resource that  starts the  emulator with the  proper options.   This  is
the default  under Unix.   Finally,  an emulator  can be told  to use  a
specified resource file using the -x commandline switch.


qqssaavvee__pprrooggrraamm((_+_F_i_l_e_, _+_L_i_s_t_O_f_O_p_t_i_o_n_s))
    Saves   the  current  state  of  the  program  to  the   file  _F_i_l_e.
    The  result  is a  resource archive  containing  a saved-state  that
    expresses  all  Prolog   data  from  the  running  program  and  all
    user-defined  resources.   Depending on the stand_alone option,  the
    resource is headed by the emulator, a Unix shell-script or nothing.

    _L_i_s_t_O_f_O_p_t_i_o_n_s  is a  list of  <_K_e_y>=<_V_a_l_u_e> or  <_K_e_y>(<_V_a_l_u_e>)  pairs.
    The available keys are described in table 8.1.
_________________________________________________________________________
|__KKeeyy________________||OOppttiioonn__||________TTyyppee____________||DDeessccrriippttiioonn__________________________________________________||
|| local      | --LL   ||    K-bytes    |Size (Limit) of local stack         |
| global     | --GG   ||    K-bytes    |Size (Limit) of global stack        |
| trail      | --TT   ||    K-bytes    |Size (Limit) of trail stack         |

| argument   | --AA   ||    K-bytes    |Size (Limit) of argument stack      |
| goal       | --gg   ||     atom      |Initialisation goal                 |
| toplevel   | --tt   ||     atom      |Prolog toplevel goal                |
|_init_file___|--ff___||_____atom______|Personal_initialisation_file________||||||
| class      |      |     atom      |If  runtime,  only  read  resources |
|            |      |               |from  the  state  (default).     If |

|            |      |               |kernel,  lock  all   predicates  as |
|            |      |               |system predicates  If  development, |
|            |      |               |save  the   predicates   in   their |
|            |      |               |current  state  and  keep   reading |
|            |      |               |resources  from  their  source  (if |
|            |      |               |present).  See also resource/3.     |
| autoload   |      |     bool      |If true, run autoload/0 first       |
| map        |      |     file      |File to write info on dump          |
| op         |      | save/standard |Save operator declarations?         |

| stand_alone |     |     bool      |Include the emulator in the state   |
| emulator   |      |     file      |Emulator attached  to  the  (stand- |
|            |      |               |alone) executable.  Default  is the |
|____________|______|_______________|running_emulator.___________________|

          Table 8.1:  <_K_e_y> = <_V_a_l_u_e> pairs for qsave_program/2

    Before   writing  the  data   to  file,  qsave_program/2  will   run
    autoload/0  to all  required  autoloading the  system can  discover.
    See autoload/0.

    Provided  the  application  does  not  require  any  of  the  Prolog
    libraries  to  be  loaded  at  runtime,   the  only  file  from  the
    SWI-Prolog development  environment required is the emulator itself.
    The  emulator may  be built in  two flavours.   The  default is  the
    _d_e_v_e_l_o_p_m_e_n_t  _e_m_u_l_a_t_o_r.  The  _r_u_n_t_i_m_e _e_m_u_l_a_t_o_r is similar, but  lacks
    the tracer.

    If the  option stand_alone(on)is present, the  emulator is the first
    part of the state.   If the emulator is started it will test whether
    a  boot-file (state)  is attached  to the emulator  itself and  load
    this  state.   Provided  the application has  all libraries  loaded,
    the  resulting executable is  completely independent of the  runtime
    environment or location where it was build.

    See also section 2.10.2.4.


qqssaavvee__pprrooggrraamm((_+_F_i_l_e))
    Equivalent to qsave_program(File, []).


aauuttoollooaadd
    Check  the current Prolog program  for predicates that are  referred
    to,  are  undefined and  have a  definition in  the Prolog  library.
    Load the appropriate libraries.

    This  predicate is used  by qsave_program/[1,2] to ensure the  saved
    state  will not  depend  on one  of the  libraries.   The  predicate
    autoload/0  will find all ddiirreecctt references to predicates.   It does
    not  find predicates referenced via meta-predicates.   The predicate
    log/2  is  defined  in the  library(quintus)  to provide  a  quintus
    compatible means to compute  the natural logarithm of a number.  The
    following program will  behave correctly if its state is executed in
    an environment where the library(quintus) is not available:

    logtable(From, To) :-
            From > To, !.
    logtable(From, To) :-
            log(From, Value),
            format('~d~t~8|~2f~n', [From, Value]),
            F is From + 1,
            logtable(F, To).

    However,  the following implementation  refers to log/2 through  the
    meta-predicate  maplist/3.   Autoload will not  be able to find  the
    reference.   This problem may be fixed either by loading  the module
    libtary(quintus)  explicitly or  use  require/1 to  tell the  system
    that the predicate log/2 is required by this module.

    logtable(From, To) :-
            findall(X, between(From, To, X), Xlist),
            maplist(log, Xlist, SineList),
            write_table(Xlist, SineList).

    write_table([], []).
    write_table([I|IT], [V|VT]) :-
            format('~d~t~8|~2f~n', [I, V]),
            write_table(IT, VT).


vvoollaattiillee _+_N_a_m_e_/_A_r_i_t_y_, _._._.
    Declare  that  the clauses  of specified  predicates  should nnoott  be
    saved  to the program.   The  volatile declaration is normally  used
    to avoid that  the clauses of dynamic predicates that represent data
    for the current session is saved in the state file.


88..11 LLiimmiittaattiioonnss ooff qqssaavvee__pprrooggrraamm

There  are  three  areas  that  require  special  attention  when  using
qsave_program/[1,2].

  o If  the  program  is an  embedded  Prolog  application or  uses  the
    foreign  language interface,  care has  to be taken  to restore  the
    appropriate foreign context.  See section 8.2 for details.

  o If  the program uses directives (:- goal. lines) that  perform other
    actions then  setting predicate attributes (dynamic, volatile, etc.)
    or  loading files  (consult,  etc.), the  directive may  need to  be
    prefixed with initialization/1.

  o Database  references as returned by clause/3, recorded/3, etc.   are
    not preserved and may thus not be part of the database when saved.


88..22 RRuunnttiimmeess aanndd FFoorreeiiggnn CCooddee

Some  applications may  need  to  use the  foreign  language  interface.
Object code is  by definition machine-dependent and thus cannot  be part
of the saved program file.

To complicate the matter even further there are various  ways of loading
foreign code:

  o _U_s_i_n_g _t_h_e _l_i_b_r_a_r_y_(_s_h_l_i_b_) _p_r_e_d_i_c_a_t_e_s
    This  is the preferred way of dealing  with foreign code.   It loads
    quickly and ensures  an acceptable level of independence between the
    versions  of the emulator and the foreign code loaded.  It  works on
    Unix  machines supporting shared libraries and library  functions to
    load  them.  Most  modern Unixes, as  well as Win32 (Windows  95/NT)
    satisfy this constraint.

  o _S_t_a_t_i_c _l_i_n_k_i_n_g
    This  mechanism works on  all machines,  but generally requires  the
    same  C-compiler and linker to be  used for the external code as  is
    used to build SWI-Prolog itself.

To make  a runtime  executable that  can run on  multiple platforms  one
must make runtime  checks to find the correct  way of linking.   Suppose
we have  a source-file  myextension defining  the installation  function
install().

If this file  is compiled into a  shared library, load_foreign_library/1
will load this library and call the installation  function to initialise
the  foreign code.    If it  is  loaded as  a static  extension,  define
install() as the predicate install/0:

static foreign_t
pl_install()
{ install();

  PL_succeed;
}

PL_extension PL_extensions [] =
{
/*{ "name",     arity,  function,       PL_FA_<flags> },*/

  { "install",  0,      pl_install,     0 },
  { NULL,       0,      NULL,           0 }     /* terminating line */
};

Now, use the following Prolog code to load the foreign library:

load_foreign_extensions :-
        current_predicate(install, install), !, % static loaded
        install.
load_foreign_extensions :-                      % shared library
        load_foreign_library(foreign(myextension)).

:- initialization load_foreign_extensions.

The path  alias foreign  is defined by  file_search_path/2.   By  default
it  searches  the  directories <_h_o_m_e>/lib/<_a_r_c_h> and  <_h_o_m_e>/lib.     The
application can specify additional rules for file_search_path/2.


88..33 UUssiinngg pprrooggrraamm rreessoouurrcceess

A  _r_e_s_o_u_r_c_e is  very  similar to  a  file.    Resources however  can  be
represented in two different formats:  on files, as well  as part of the
resource _a_r_c_h_i_v_e of a saved-state (see qsave_program/2).

A resource has a _n_a_m_e  and a _c_l_a_s_s.  The _s_o_u_r_c_e data of the  resource is
a file.   Resources are declared by declaring the  predicate resource/3.
They are accessed using the predicate open_resource/3.

Before  going into  details,  let  us start  with  an  example.    Short
texts  can easily  be expressed  in Prolog  sourcecode,  but long  texts
are cumbersome.   Assume our application  defines a command `help'  that
prints a  helptext to the screen.   We put  the content of the  helptext
into a  file called help.txt.   The following  code implements our  help
command such that help.txt is incorperated into the runtime executable.

resource(help, text, 'help.txt').

help :-
        open_resource(help, text, In),
        copy_stream(In, user_output),
        close(In).

copy_stream(In, Out) :-
        get0(In, C),
        copy_stream(C, In, Out).

copy_stream(-1, _, _) :- !.
copy_stream(C, In, Out) :-
        put(Out, C),
        get0(In, C2),
        copy_stream(C2, In, Out).

The predicate  help/0 opens  the resource  as a Prolog  stream.   If  we
are executing this from the development environment,  this will actually
return  a stream  to  the  gelp.txt itself.     When executed  from  the
saved-state, the stream will actually be a stream  opened on the program
resource file, taking care of the offset and length of the resource.


88..33..11 PPrreeddiiccaatteess DDeeffiinniittiioonnss


rreessoouurrccee((_+_N_a_m_e_, _+_C_l_a_s_s_, _+_F_i_l_e_S_p_e_c))
    This  predicate is  defined  as a  dynamic predicate  in the  module
    user.    Clauses for  it may  be  defined in  any module,  including
    the  user module.    _N_a_m_e is  the name  of the  resource (an  atom).
    A  resource name  may contain  any character,  except for  $ and  :,
    which  are  reserved for  internal usage  by  the resource  library.
    _C_l_a_s_s  describes the what kind of object is stored in  the resource.
    In  the  current implementation,  it  is just  an  atom.    _F_i_l_e_S_p_e_c
    is  a file  specification that  may exploit  file_search_path/2 (see
    absolute_file_name/2).

    Normally,  resources are  defined as unit  clauses (facts), but  the
    definition  of this  predicate also allows  for rules.   For  proper
    generation  of the  saved state,  it must be  possible to  enumerate
    the  available  resources by  calling this  predicate  with all  its
    arguments unbound.

    Dynamic  rules are useful to turn  all files in a certain  directory
    into  resources, without specifying a resources for each file.   For
    example,  assume the file_search_path/2icons refers to  the resource
    directory  containing icon-files.   The  following definition  makes
    all these images available as resources:

    resource(Name, image, icons(XpmName)) :-
            atom(Name), !,
            file_name_extension(Name, xpm, XpmName).
    resource(Name, image, XpmFile) :-
            var(Name),
            absolute_file_name(icons(.), [type(directory)], Dir)
            concat(Dir, '/*.xpm', Pattern),
            expand_file_name(Pattern, XpmFiles),
            member(XpmFile, XpmFiles).


ooppeenn__rreessoouurrccee((_+_N_a_m_e_, _?_C_l_a_s_s_, _-_S_t_r_e_a_m))
    Opens  the resource specified by _N_a_m_e and  _C_l_a_s_s.  If the  latter is
    a  variable, it will be unified  to the class of the  first resource
    found that has the  specified _N_a_m_e.  If successful, _S_t_r_e_a_m becomes a
    handle to a  binary input stream, providing access to the content of
    the resource.

    The  predicate  open_resource/3  first  checks  resource/3.     When
    succesful   it  will   open  the   returned  resource   source-file.
    Otherwise  it will  look in the  programs resource  database.   When
    creating  a  saved-state,  the system  normally saves  the  resource
    contents  into the resource archive, but does not save  the resource
    clauses.

    This   way,  the  development   environment  uses  the  files   (and
    modifications   to   the   resource/3  declarations   and/or   files
    containing  resource   info  thus  immediately  affect  the  running
    environment,  while the runtime  system quickly accesses the  system
    resources.


88..33..22 TThhee plrc pprrooggrraamm

The  utility program  plrc can  be used  to examine  and manipulate  the
contents of  a SWI-Prolog resource  file.  The  options are inspired  by
the Unix ar program.  The basic command is:

% plrc option resource-file member ...

The options are described below.

ll
    List contents of the archive.

xx
    Extract  named (or  all)  members of  the archive  into the  current
    directory.

aa
    Add  files  to the  archive.    If the  archive already  contains  a
    member  with the  same name,  the contents  is replaced.    Anywhere
    in   the  sequence  of  members,   the  options  --class=_c_l_a_s_s   and
    --encoding=_e_n_c_o_d_i_n_g may appear.   They affect the class and encoding
    of subsequent files.  The initial class is data and encoding none.

dd
    Delete named members from the archive.

This command is also described in the pl(1) Unix manual page.


88..44 FFiinnddiinngg AApppplliiccaattiioonn ffiilleess

If your application  uses files that are  not part of the saved  program
such as database  files, configuration files, etc., the  runtime version
has to be able to  locate these files.  The file_search_path/2 mechanism
in combination with  the -palias command-line argument is the  preferred
way to  locate runtime  files.   The first  step is to  define an  alias
for the  toplevel directory  of your  application.   We  will call  this
directory gnatdir in our examples.

A  good  place  for storing  data  associated  with  SWI-Prolog  runtime
systems is  below the emulator's  home-directory.   swi is a  predefined
alias for this directory.  The following is  a useful default definition
for the search path.

user:file_search_path(gnatdir, swi(gnat)).

The  application  should  locate   all  files  using  absolute_file_name.
Suppose   gnatdir   contains   a  file   config.pl   to   define   local
configuration.  Then use the code below to load this file:

configure_gnat :-
        (   absolute_file_name(gnatdir('config.pl'), ConfigFile)
            ->  consult(ConfigFile)
            ;   format(user_error, 'gnat: Cannot locate config.pl~n'),
            halt(1)
            ).


88..44..11 PPaassssiinngg aa ppaatthh ttoo tthhee aapppplliiccaattiioonn

Suppose   the  system   administrator  has   installed  the   SWI-Prolog
runtime  environment  in  /usr/local/lib/rt-pl-3.2.0.     A  user  wants
to  install  gnat,   but  gnat  will  look  for  its   configuration  in
/usr/local/lib/rt-pl-3.2.0/gnat where the user cannot write.

The user  decides to install the  gnat runtime files in  /users/bob/lib/
gnat.  For one-time  usage, the user may decide to start gnat  using the
command:

% gnat -p gnatdir=/users/bob/lib/gnat


88..55 TThhee RRuunnttiimmee EEnnvviirroonnmmeenntt


88..55..11 TThhee RRuunnttiimmee EEmmuullaattoorr

The sources  may be  used to built  two versions  of the emulator.    By
default,  the _d_e_v_e_l_o_p_m_e_n_t _e_m_u_l_a_t_o_r  is built.    This emulator  contains
all features  for interactive development  of Prolog  applications.   If
the system is  configured using --enable-runtime, make(1) will  create a
_r_u_n_t_i_m_e _v_e_r_s_i_o_n  of the emulator.   This emulator  is equivalent to  the
development version, except for the following features:

  o _N_o _i_n_p_u_t _e_d_i_t_i_n_g
    The  GNU library -lreadline  that provides EMACS compatible  editing
    of input lines will not be linked to the system.

  o _N_o _t_r_a_c_e_r
    The  tracer and  all its options  are removed,  making the system  a
    little faster too.

  o _N_o _p_r_o_f_i_l_e_r
    profile/3 and friends are  not supported.  This saves some space and
    provides better performance.

  o _N_o _i_n_t_e_r_r_u_p_t
    Keyboard  interrupt (Control-C  normally)  is not  rebound and  will
    normally terminate the application.

  o _c_u_r_r_e_n_t___p_r_o_l_o_g___f_l_a_g_(_r_u_n_t_i_m_e_, _t_r_u_e_) _s_u_c_c_e_e_d_s
    This  may  be used  to verify  your application  is  running in  the
    runtime environment rather than the development environment.

  o clause/[2,3] _d_o _n_o_t _w_o_r_k _o_n _s_t_a_t_i_c _p_r_e_d_i_c_a_t_e_s
    This  prolog-flag inhibits listing your program.  It is only  a very
    limited protection however.

The  following  fragment   is  an  example  for  building  the   runtime
environment in  \env{HOME}/lib/rt-pl-3.2.0.   If  possible, the  shared-
library interface should  be configured to ensure  it can serve a  large
number of applications.

% cd pl-3.2.0
% mkdir runtime
% cd runtime
% ../src/configure --enable-runtime --prefix=$HOME
% make
% make rt-install

The  runtime directory  contains  the components  listed  below.    This
directory may be tar'ed and shipped with your application.

           __________________________________________________
           |_README.RT____|Info_on_the_runtime_environment___|
           |_bin/<_a_r_c_h>/pl|The_emulator_itself_______________|

           |_man/pl.1_____|Manual_page_for_pl________________|
           |_swipl________|pointer_to_the_home_directory_(.)_|
           | lib/         |directory for shared libraries    |
           |_lib/<_a_r_c_h>/__|machine-specific_shared_libraries_|


CChhaapptteerr 99..  TTHHEE SSWWII--PPRROOLLOOGG LLIIBBRRAARRYY

This chapter documents  the SWI-Prolog library.  As  SWI-Prolog provides
auto-loading,  there is  little  difference between  library  predicates
and built-in predicates.   Part of  the library is therefore  documented
in the  rest of  the manual.   Library  predicates differ from  built-in
predicates in the following ways.

  o User-definition  of a  built-in leads to  a permission-error,  while
    using the name of a library predicate is allowed.

  o If  autoloading is disabled explicitely or because  trapping unknown
    predicates  is disabled  (see unknown/2  and current_prolog_flag/2),
    library predicates must be loaded explicitely.

  o Using  libraries reduce  the  footprint of  applications that  don't
    need them.

    _T_h_e  _d_o_c_u_m_e_n_t_a_t_i_o_n _o_f  _t_h_e _l_i_b_r_a_r_y _i_s  _j_u_s_t _s_t_a_r_t_e_d_.   _M_a_t_e_r_i_a_l
    _f_r_o_m  _t_h_e _s_t_a_n_d_a_r_d _p_a_c_k_a_g_e_s _s_h_o_u_l_d _b_e _m_o_v_e_d _h_e_r_e_, _s_o_m_e _m_a_t_e_r_i_a_l
    _f_r_o_m  _o_t_h_e_r _p_a_r_t_s _o_f _t_h_e _m_a_n_u_a_l _s_h_o_u_l_d _b_e _m_o_v_e_d _t_o_o _a_n_d _v_a_r_i_o_u_s
    _l_i_b_r_a_r_i_e_s _a_r_e _n_o_t _d_o_c_u_m_e_n_t_e_d _a_t _a_l_l_.


99..11 lists::  LLiisstt MMaanniippuullaattiioonn

This  library  provides  commonly accepted  basic  predicates  for  list
manipulation  in   the  Prolog   community.      Some  additional   list
manipulations are built-in.  Their description is in section 4.29.


aappppeenndd((_?_L_i_s_t_1_, _?_L_i_s_t_2_, _?_L_i_s_t_3))
    Succeeds  when _L_i_s_t_3  unifies with  the concatenation  of _L_i_s_t_1  and
    _L_i_s_t_2.   The  predicate can be  used with any instantiation  pattern
    (even three variables).


mmeemmbbeerr((_?_E_l_e_m_, _?_L_i_s_t))
    Succeeds  when _E_l_e_m can be unified with one of the members  of _L_i_s_t.
    The predicate can be used with any instantiation pattern.


nneexxttttoo((_?_X_, _?_Y_, _?_L_i_s_t))
    Succeeds when _Y follows _X in _L_i_s_t.


ddeelleettee((_+_L_i_s_t_1_, _?_E_l_e_m_, _?_L_i_s_t_2))
    Delete all members  of _L_i_s_t_1 that simultaneously unify with _E_l_e_m and
    unify the result with _L_i_s_t_2.


sseelleecctt((_?_E_l_e_m_, _?_L_i_s_t_, _?_R_e_s_t))
    Select  _E_l_e_m  from _L_i_s_t  leaving  _R_e_s_t.    It behaves  as  member/2,
    returning  the  remaining  elements in  _R_e_s_t.    Note  that  besides
    selecting  elements  from a  list, it  can also  be  used to  insert
    elements.


nntthh00((_?_I_n_d_e_x_, _?_L_i_s_t_, _?_E_l_e_m))
    Succeeds  when  the  _I_n_d_e_x-th element  of  _L_i_s_t unifies  with  _E_l_e_m.
    Counting starts at 0.


nntthh11((_?_I_n_d_e_x_, _?_L_i_s_t_, _?_E_l_e_m))
    Succeeds  when  the  _I_n_d_e_x-th element  of  _L_i_s_t unifies  with  _E_l_e_m.
    Counting starts at 1.


llaasstt((_?_L_i_s_t_, _?_E_l_e_m))
    Succeeds  if _E_l_e_m unifies with  the last element of  _L_i_s_t.  If  _L_i_s_t
    is  a proper list last/2 is deterministic.   If _L_i_s_t has  an unbound
    tail, backtracking will cause _L_i_s_t to grow.


rreevveerrssee((_+_L_i_s_t_1_, _-_L_i_s_t_2))
    Reverse  the order  of the elements  in _L_i_s_t_1  and unify the  result
    with the elements of _L_i_s_t_2.


ppeerrmmuuttaattiioonn((_?_L_i_s_t_1_, _?_L_i_s_t_2))
    Permuation  is true  when  _L_i_s_t_1 is  a permutation  of _L_i_s_t_2.    The
    implementation  can  solve  for _L_i_s_t_2  given  _L_i_s_t_1 or  _L_i_s_t_1  given
    _L_i_s_t_2, or even enumerate _L_i_s_t_1 and _L_i_s_t_2 together.


ffllaatttteenn((_+_L_i_s_t_1_, _-_L_i_s_t_2))
    Transform  _L_i_s_t_1, possibly holding lists  as elements into a  `flat'
    list by replacing  each list with its elements (recursively).  Unify
    the resulting flat list with _L_i_s_t_2.  Example:

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

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

ssuummlliisstt((_+_L_i_s_t_, _-_S_u_m))
    Unify  _S_u_m to the result of adding all elements in _L_i_s_t.   _L_i_s_t must
    be  a proper  list holding numbers.   See  number/1 and  is/2.   for
    details on arithmetic.


nnuummlliisstt((_+_L_o_w_, _+_H_i_g_h_, _-_L_i_s_t))
    If  _L_o_w and _H_i_g_h are integers with Low=< High, unify _L_i_s_t to a list
    [Low, Low +1, ...High].  See also between/3.


99..11..11 SSeett MMaanniippuullaattiioonn


iiss__sseett((_+_S_e_t))
    Succeeds if _S_e_t is a list (see is_list/1) without duplicates.


lliisstt__ttoo__sseett((_+_L_i_s_t_, _-_S_e_t))
    Unifies  _S_e_t  with a  list  holding the  same  elements as  _L_i_s_t  in
    the  same order.   If  _l_i_s_t contains duplicates,  only the first  is
    retained.  See also sort/2.  Example:

    ?- list_to_set([a,b,a], X)

    X = [a,b]


iinntteerrsseeccttiioonn((_+_S_e_t_1_, _+_S_e_t_2_, _-_S_e_t_3))
    Succeeds  if _S_e_t_3 unifies  with the intersection  of _S_e_t_1 and  _S_e_t_2.
    _S_e_t_1  and _S_e_t_2  are  lists without  duplicates.   They  need not  be
    ordered.


ssuubbttrraacctt((_+_S_e_t_, _+_D_e_l_e_t_e_, _-_R_e_s_u_l_t))
    Delete  all  elements  of set  `Delete'  from  `Set' and  unify  the
    resulting set with `Result'.


uunniioonn((_+_S_e_t_1_, _+_S_e_t_2_, _-_S_e_t_3))
    Succeeds if _S_e_t_3 unifies  with the union of _S_e_t_1 and _S_e_t_2.  _S_e_t_1 and
    _S_e_t_2 are lists without duplicates.  They need not be ordered.


ssuubbsseett((_+_S_u_b_s_e_t_, _+_S_e_t))
    Succeeds if all elements of _S_u_b_s_e_t are elements of _S_e_t as well.


99..22 check::  EElleemmeennttaarryy ccoommpplleetteenneessss cchheecckkss

This library defines the predicate check/0 and a few  friends that allow
for a quick-and-dirty cross-referencing.


cchheecckk
    Performs  the three checking passes implemented by list_undefined/0,
    list_autoload/0 and  list_redefined/0.   Please check the  definition
    of these predicates for details.

    The  typical usage  of this  predicate is right  after loading  your
    program  to get a  quick overview on  the completeness and  possible
    conflicts in your program.


lliisstt__uunnddeeffiinneedd
    Scans  the  database for  predicates that  have no  definition.    A
    predicate  is  considered defined  if it  has clauses,  is  declared
    using  dynamic/1 or  multifile/1.   As a  program is compiled  calls
    are  translated to predicates.   If the called predicate is not  yet
    defined  it  is created  as a  predicate without  definition.    The
    same  happens with runtime  generated calls.   This predicate  lists
    all  such undefined predicates that  are referenced and not  defined
    in  the library.   See  also list_autoload/0.   Below is an  example
    from a real  program and an illustration how to edit the referencing
    predicate using edit/1.

    ?- list_undefined.
    Warning: The predicates below are not defined. If these are defined
    Warning: at runtime using assert/1, use :- dynamic Name/Arity.
    Warning:
    Warning: rdf_edit:rdfe_retract/4, which is referenced by
    Warning:         1-st clause of rdf_edit:undo/4
    Warning: rdf_edit:rdfe_retract/3, which is referenced by
    Warning:         1-st clause of rdf_edit:delete_object/1
    Warning:         1-st clause of rdf_edit:delete_subject/1
    Warning:         1-st clause of rdf_edit:delete_predicate/1

    ?- edit(rdf_edit:undo/4).


lliisstt__aauuttoollooaadd
    Lists  all undefined (see  list_undefined/0)  predicates that have  a
    definition  in the library along with the file from which  they will
    be autoloaded when accessed.  See also autoload/0.


lliisstt__rreeddeeffiinneedd
    Lists  predicates that  are  defined in  the global  module user  as
    well  as in a normal  module.  I.e.  predicates for which the  local
    definition overrules the global default definition.


99..33 debug::  SSoommee rreeuussaabbllee ccooddee ttoo hheellpp ddeebbuuggggiinngg aapppplliiccaattiioonnss

This  library provides  an  structured  alternative for  putting  print-
statements into  your source-code  to trace  what is  going on.    Debug
messages are organised in _t_o_p_i_c_s that can be  activated and de-activated
without  changing  the  source.     In  addition,   if  the  application
is  compiled  with  the -O  flag  these  predicates  are  removed  using
goal_expansion/2.

Although  this library  can be  used through  the normal  demand-loading
mechanism it is adviced  to load it explicitely before code using  it to
profit from goal-expansion,  which removes these calls if  compiled with
optimisation on and records the topics from debug/3  and debugging/1 for
list_debug_topics/0.


ddeebbuugg((_+_T_o_p_i_c_, _+_F_o_r_m_a_t_, _+_A_r_g_s))
    If  _T_o_p_i_c is a selected debugging  topic (see debug/1) a message  is
    printed using  print_message/2with level informational.   _F_o_r_m_a_t and
    _A_r_g_s are interpreted by format/2.  Here is a typical example:

            ...,
            debug(init, 'Initialised ~w', [Module]),
            ...,

    _T_o_p_i_c  can be any Prolog term.   Compound terms can be used  to make
    categories of topics that can be activated using debug/1.


ddeebbuuggggiinngg((_+_T_o_p_i_c))
    Succeeds  if _T_o_p_i_c is  a selected debugging topic.   It is  intended
    to  execute  arbitrary  code  depending on  the  users  debug  topic
    selection.     The  construct  (debugging(Topic) -> Code ; true)  is
    removed if the code is compiled in optimise mode.


ddeebbuugg((_+_T_o_p_i_c))
    Select  all registered topics that  unify with _T_o_p_i_c for  debugging.
    This  call is normally  used from the  toplevel to activate a  topic
    for debugging.  Topics are de-activated using nodebug/1.


nnooddeebbuugg((_+_T_o_p_i_c))
    Deactivates topics for debugging.  See debug/1 for the arguments.


lliisstt__ddeebbuugg__ttooppiiccss
    List   the  current  status  of   registered  topics.     See   also
    debugging/0.


aassssuummee((_:_G_o_a_l))
    This  predicate  is   to  be  compared  to  the  C-library  assert()
    function.   By inserting this goal you explicitely state  you expect
    _G_o_a_l  to succeed  at  this place.    As assume/1  calls are  removed
    when compiling in  optimized mode _G_o_a_l should not have side-effects.
    Typical  examples are type-tests  and validating invariants  defined
    by your application.

    If _G_o_a_l fails the system prints a message and starts the debugger.


99..44 readutil::  RReeaaddiinngg lliinneess,, ssttrreeaammss aanndd ffiilleess

This library contains  primitives to read lines, files,  multiple terms,
etc.


rreeaadd__lliinnee__ttoo__ccooddeess((_+_S_t_r_e_a_m_, _-_C_o_d_e_s))
    Read  the  next line  of  input from  _S_t_r_e_a_m  and unify  the  result
    with  _C_o_d_e_s _a_f_t_e_r the  line has  been read.   A line  is ended by  a
    newline character or end-of-file.  Unlike  read_line_to_codes/3, this
    predicate removes trailing newline character.

    On  end-of-file  the  atom  end_of_file  is  returned.     See  also
    at_end_of_stream/[0,1].


rreeaadd__lliinnee__ttoo__ccooddeess((_+_S_t_r_e_a_m_, _-_C_o_d_e_s_, _?_T_a_i_l))
    Diference-list version to  read an input line to a list of character
    codes.   Reading stops at the newline or end-of-file  character, but
    unlike  read_line_to_codes/2, the newline is retained in  the output.
    This  predicate is especially  useful for readine  a block of  lines
    upto  some delimiter.   The following  example reads an HTTP  header
    ended by a blank line:

    read_header_data(Stream, Header) :-
            read_line_to_codes(Stream, Header, Tail),
            read_header_data(Header, Stream, Tail).

    read_header_data("\r\n", _, _) :- !.
    read_header_data("\n", _, _) :- !.
    read_header_data("", _, _) :- !.
    read_header_data(_, Stream, Tail) :-
            read_line_to_codes(Stream, Tail, NewTail),
            read_header_data(Tail, Stream, NewTail).


rreeaadd__ssttrreeaamm__ttoo__ccooddeess((_+_S_t_r_e_a_m_, _-_C_o_d_e_s))
    Read all input until end-of-file and unify the result to _C_o_d_e_s.


rreeaadd__ssttrreeaamm__ttoo__ccooddeess((_+_S_t_r_e_a_m_, _-_C_o_d_e_s_, _?_T_a_i_l))
    Difference-list version of read_stream_to_codes/2.


rreeaadd__ffiillee__ttoo__ccooddeess((_+_S_p_e_c_, _-_C_o_d_e_s_, _+_O_p_t_i_o_n_s))
    Read  a  file to  a  list of  character  codes.    _S_p_e_c is  a  file-
    specification  for  absolute_file_name/3.    _C_o_d_e_s is  the  resulting
    code-list.   _O_p_t_i_o_n_s  is a list of  options for absolute_file_name/3
    and open/4.   In addition, the option tail(_T_a_i_l) is defined, forming
    a difference-list.


rreeaadd__ffiillee__ttoo__tteerrmmss((_+_S_p_e_c_, _-_T_e_r_m_s_, _+_O_p_t_i_o_n_s))
    Read  a  file  to  a list  of  prolog  terms  (see read/1).     _S_p_e_c
    is  a  file-specification for  absolute_file_name/3.    _T_e_r_m_s is  the
    resulting  list of  Prolog  terms.   _O_p_t_i_o_n_s  is a  list of  options
    for  absolute_file_name/3 and  open/4.    In  addition,  the  option
    tail(_T_a_i_l) is defined, forming a difference-list.


99..55 netscape::  AAccttiivvaattiinngg yyoouurr WWeebb--bbrroowwsseerr

This library deals with the very system dependent task  of opening a web
page in a browser.  See also url and the HTTP package.


wwwwww__ooppeenn__uurrll((_+_U_R_L))
    Open  _U_R_L in  an external  web-browser.   The reason  to place  this
    in  the library  is  to centralise  the maintenance  on this  highly
    platform  and browser specific task.   It distinguishes between  the
    following cases:

      o  _M_S_-_W_i_n_d_o_w_s
         If it detects MS-Windows  it uses win_shell/2 to open the  _U_R_L.
         The behaviour  and browser  started depends on  the Window  and
         Windows-shell configuration,  but in general  it should be  the
         behaviour expected by the user.

      o  _O_t_h_e_r _p_l_a_t_f_o_r_m_s
         On  other platforms  it  tests  the environment  variable  (see
         getenv/1) named BROWSER  or uses netscape  if this variable  is
         not  set.    If the  browser  is  either mozilla  or  netscape,
         www_open_url/1 first tries to  open a new  window on a  running
         using the  -remote option of netscape.   If  this fails or  the
         browser is  not mozilla  or netscape the  system simply  passes
         the URL as first argument to the program.


99..66 registry::  MMaanniippuullaattiinngg tthhee WWiinnddoowwss rreeggiissttrryy

The registry is only available on the MS-Windows  version of SWI-Prolog.
It loads  the foreign extension  plregtry.dll, providing the  predicates
described below.   This  library only makes  the most common  operations
on the registry available  through the Prolog user.  The  underlying DLL
provides a  more complete coverage of  the Windows registry API.  Please
consult  the  sources  in  pl/src/win32/foreign/plregtry.c  for  further
details.

In  all these  predicates,  _P_a_t_h refers  to a  `/' separated  path  into
the registry.   This  is _n_o_t an atom  containing `/'-characters as  used
for  filenames, but  a term  using the  functor  //2.   Windows  defines
the  following  roots for  the  registry:   classes_root,  current_user,
local_machine and users


rreeggiissttrryy__ggeett__kkeeyy((_+_P_a_t_h_, _-_V_a_l_u_e))
    Get  the principal (default)  value associated to  this key.   Fails
    silently of the key does not exist.


rreeggiissttrryy__ggeett__kkeeyy((_+_P_a_t_h_, _+_N_a_m_e_, _-_V_a_l_u_e))
    Get a named value associated to this key.


rreeggiissttrryy__sseett__kkeeyy((_+_P_a_t_h_, _+_V_a_l_u_e))
    Set the principal (default)  value of this key.  Creates (a path to)
    the key if this does not already exist.


rreeggiissttrryy__sseett__kkeeyy((_+_P_a_t_h_, _+_N_a_m_e_, _+_V_a_l_u_e))
    Associated  a named value to this key.  Creates (a path  to) the key
    if this does not already exist.


rreeggiissttrryy__ddeelleettee__kkeeyy((_+_P_a_t_h))
    Delete the indicated key.


sshheellll__rreeggiisstteerr__ffiillee__ttyyppee((_+_E_x_t_, _+_T_y_p_e_, _+_N_a_m_e_, _+_O_p_e_n_A_c_t_i_o_n))
    Register  a file-type.   _E_x_t is  the extension to  associate.   _T_y_p_e
    is  the type name,  often something link prolog.type.   _N_a_m_e is  the
    name visible in  the Windows file-type browser.  Finally, _O_p_e_n_A_c_t_i_o_n
    defines  the action to  execute when a  file with this extension  is
    opened in the Windows explorer.


sshheellll__rreeggiisstteerr__ddddee((_+_T_y_p_e_, _+_A_c_t_i_o_n_, _+_S_e_r_v_i_c_e_, _+_T_o_p_i_c_, _+_C_o_m_m_a_n_d_, _+_I_f_N_o_t_R_u_n_n_i_n_g))

    Associate   DDE   actions  to   a  type.       _T_y_p_e   is  the   same
    type  as used  for the  2nd  argument of  shell_register_file_type/4,
    _A_c_t_i_o_n  is the a  action to perform,  _S_e_r_v_i_c_e and _T_o_p_i_c specify  the
    DDE  topic to address and _C_o_m_m_a_n_d is the command to execute  on this
    topic.   Finally, _I_f_N_o_t_R_u_n_n_i_n_g defines the command to execute if the
    required DDE server is not present.


sshheellll__rreeggiisstteerr__pprroolloogg((_+_E_x_t))
    Default  registration of  SWI-Prolog, which  is invoked  as part  of
    the  initialisation process on Windows systems.  As the  source also
    explains the above predicates, it is given as an example:

    shell_register_prolog(Ext) :-
            current_prolog_flag(argv, [Me|_]),
            concat_atom(['"', Me, '" "%1"'], OpenCommand),
            shell_register_file_type(Ext, 'prolog.type', 'Pro-
    log Source',
                                     OpenCommand),
            shell_register_dde('prolog.type', consult,
                               prolog, control, 'consult(''%1'')', Me),
            shell_register_dde('prolog.type', edit,
                               prolog, control, 'edit(''%1'')', Me).


99..77 url::  AAnnaallyyssiinngg aanndd ccoonnssttrruuccttiinngg UURRLL

This  library  deals  with the  analysis  and  construction  of  a  URL,
UUniversal  RResource  LLocator.    URL  is  the  basis  for  communicating
locations of resources (data) on the web.  A URL  consists of a protocol
identifier  (e.g. HTTP,  FTP), and  a  protocol-specific syntax  further
defining the location.  URLs are standardized in RFC-1738.

The implementation in  this library covers only  a small portion of  the
defined protocols.  Though the initial  implementation followed RFC-1738
strictly, the current  is more relaxed to deal with  frequent violations
of the standard encountered in practical use.

This  library contains  code by  Jan Wielemaker  who  wrote the  initial
version and Lukas Faulstich who added various extensions.


ppaarrssee__uurrll((_?_U_R_L_, _?_P_a_r_t_s))
    Construct  or analyse  a _U_R_L.  _U_R_L is  an atom  holding a  URL or  a
    variable.  _P_a_r_t_s  is a list of components.  Each component is of the
    format Name(_V_a_l_u_e).  Defined components are:

    pprroottooccooll((_P_r_o_t_o_c_o_l))
         The used  protocol.    This is,  after  the optional  url:,  an
         identifier  separated  from the  remainder  of  the  URL  using
         :.   parse_url/2 assumes the  http protocol  if no protocol  is
         specified and  the  URL can  be  parsed as  a valid  HTTP  url.
         In addition  to  the RFC-1738  specified protocols,  the  file:
         protocol is supported as well.

    hhoosstt((_H_o_s_t))
         Host-name  or IP-address  on  which  the resource  is  located.
         Supported by all network-based protocols.

    ppoorrtt((_P_o_r_t))
         Integer port-number to access  on the _H_o_s_t.  This  only appears
         if  the port  is  explicitly  specified in  the  URL.  Implicit
         default  ports  (e.g.  80  for  HTTP)  do  _n_o_t  appear  in  the
         part-list.

    ppaatthh((_P_a_t_h))
         (File-) path addressed  by the URL.  This is supported for  the
         ftp, http and file protocols.  If no path  appears, the library
         generates the path /.

    sseeaarrcchh((_L_i_s_t_O_f_N_a_m_e_V_a_l_u_e))
         Search-specification of HTTP  URL. This is  the part after  the
         ?, normally used to transfer data from HTML forms  that use the
         `GET' protocol.   In the URL it consists of  a www-form-encoded
         list of _N_a_m_e=_V_a_l_u_e pairs.   This is mapped to a list  of Prolog
         _N_a_m_e=_V_a_l_u_e terms with decoded names and values.

    ffrraaggmmeenntt((_F_r_a_g_m_e_n_t))
         Fragment specification of HTTP URL. This is the  part after the
         # character.

    The example below illustrates the all this for an HTTP UTL.

    ?- parse_url('http://swi.psy.uva.nl/message.cgi?msg=Hello+World%21#x',
                 P).
    P = [ protocol(http),
          host('swi.psy.uva.nl'),
          fragment(x),
          search([ msg = 'Hello World!'
                 ]),
          path('/message.cgi')
        ].

    By  instantiating  the  parts-list this  predicate  can be  used  to
    create a URL.


ppaarrssee__uurrll((_?_U_R_L_, _+_B_a_s_e_U_R_L_, _?_P_a_r_t_s))
    Same  as parse_url/2,  but dealing  a url  that is  relative to  the
    given  _B_a_s_e_U_R_L. This is used to analyse or construct a URI  found in
    the document behind _B_a_s_e_U_R_L.


gglloobbaall__uurrll((_+_U_R_L_, _+_B_a_s_e_U_R_L_, _-_A_b_s_o_l_u_t_e_U_r_l))
    Transform a (possibly) relative URL into a global one.


hhttttpp__llooccaattiioonn((_?_P_a_r_t_s_, _?_L_o_c_a_t_i_o_n))
    Similar to  parse_url/2, but only deals with the  location part of an
    HTTP  URL. That is,  the path, search and  fragment specifiers.   In
    the HTTP protocol, the first line of a message is

         _A_c_t_i_o_n _L_o_c_a_t_i_o_n [HTTP/_H_t_t_p_V_e_r_s_i_o_n]

    _L_o_c_a_t_i_o_n is either an atom or a code-list.


wwwwww__ffoorrmm__eennccooddee((_?_V_a_l_u_e_, _?_W_w_w_F_o_r_m_E_n_c_o_d_e_d))
    Translate  between   a  string-literal  and  the  x-www-form-encoded
    representation  used in path and  search specifications of the  HTTP
    protocol.

    Encoding  implies  mapping space  to +,  preserving  alpha-numercial
    characters,  map newlines to %0D%0A  and anything else to %XX.  When
    decoding, newlines appear as a single newline (10) character.


CChhaapptteerr 1100..  HHAACCKKEERRSS CCOORRNNEERR

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.


1100..11 EExxaammiinniinngg tthhee EEnnvviirroonnmmeenntt SSttaacckk


pprroolloogg__ccuurrrreenntt__ffrraammee((_-_F_r_a_m_e))
    Unify   _F_r_a_m_e  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.


pprroolloogg__ffrraammee__aattttrriibbuuttee((_+_F_r_a_m_e_, _+_K_e_y_, _-_V_a_l_u_e))
    Obtain  information  about  the local  stack  frame  _F_r_a_m_e.    _F_r_a_m_e
    is  a  frame reference  as obtained  through prolog_current_frame/1,
    prolog_trace_interception/4 or this predicate.   The key values  are
    described below.

    aalltteerrnnaattiivvee
         _V_a_l_u_e is unified with  an integer reference to the  local stack
         frame in  which execution  is  resumed if  the goal  associated
         with _F_r_a_m_e  fails.    Fails  if the  frame has  no  alternative
         frame.

    hhaass__aalltteerrnnaattiivveess
         _V_a_l_u_e is unified  with true if _F_r_a_m_e  still is a candidate  for
         backtracking.  false otherwise.

    ggooaall
         _V_a_l_u_e is unified with the  goal associated with _F_r_a_m_e.   If the
         definition module of the active predicate is not  user the goal
         is represented as <_m_o_d_u_l_e>:<_g_o_a_l>.  Do not instantiate variables
         in this goal  unless you kknnooww  what you are  doing!  Note  that
         the  returned term  may contain  references  to the  frame  and
         should be discarded before the frame terminates.

    ppaarreenntt__ggooaall
         If _V_a_l_u_e  is  instantiated to  a callable  term,  find a  frame
         executing  the  predicate described  by  _V_a_l_u_e  and  unify  the
         arguments of _V_a_l_u_e  to the goal  arguments associated with  the
         frame.    This  is  intended  to check  the  current  execution
         context.  The user  must ensure the checked parent goal  is not
         removed from  the stack  due to last-call  optimisation and  be
         aware of the slow operation on deeply nested calls.

    ccllaauussee
         _V_a_l_u_e is  unified with  a  reference to  the currently  running
         clause.    Fails  if the  current  goal  is associated  with  a
         foreign  (C) defined  predicate.    See  also nth_clause/3  and
         clause_property/2.

    lleevveell
         _V_a_l_u_e is unified  with the recursion level  of _F_r_a_m_e.  The  top
         level frame is at level `0'.

    ppaarreenntt
         _V_a_l_u_e is unified with an integer reference to  the parent local
         stack frame of _F_r_a_m_e.  Fails if _F_r_a_m_e is the top frame.

    ccoonntteexxtt__mmoodduullee
         _V_a_l_u_e is  unified with the  name of the  context module of  the
         environment.

    ttoopp
         _V_a_l_u_e is  unified with  true if _F_r_a_m_e  is the  top Prolog  goal
         from a recursive  call back from the  foreign language.   false
         otherwise.

    hhiiddddeenn
         _V_a_l_u_e is  unified with  true if the  frame is  hidden from  the
         user, either  because a  parent has  the hide-childs  attribute
         (all  system  predicates),  or  the  system   has  no  trace-me
         attribute.

    ppcc
         _V_a_l_u_e is unified with  the program-pointer saved on behalve  of
         the parent-goal if  the parent-goal is  not owned by a  foreign
         predicate.

    aarrgguummeenntt((_N))
         _V_a_l_u_e is  unified with the _N-th  slot of the  frame.   Argument
         1 is  the first  argument of  the goal.    Arguments above  the
         arity refer to local variables.  Fails silently if _N  is out of
         range.


pprroolloogg__cchhooiiccee__aattttrriibbuuttee((_+_C_h_o_i_c_e_P_o_i_n_t_, _+_K_e_y_, _-_V_a_l_u_e))
    Extract  attributes of a choice-point.   _C_h_o_i_c_e_P_o_i_n_t is a  reference
    to  a choice-point as  passed to  prolog_trace_interception/4on  the
    3-th argument.  _K_e_y specifies the requested information:

    ppaarreenntt
         Requests a reference to the first older choice-point.

    ffrraammee
         Requests a  reference to  the frame to  which the  choice-point
         refers.

    ttyyppee
         Requests  the type.     Defined  values are  clause  (the  goal
         has alternative  clauses),  foreign (non-deterministic  foreign
         predicate),  jump  (clause internal  choicepoint),  top  (first
         dummy choice-point), catch  (catch/3 to allow for undo),  debug
         (help the debugger), or none (has been deleted).

    This  predicate  is used  for  the graphical  debugger to  show  the
    choicepoint stack.


ddeetteerrmmiinniissttiicc((_-_B_o_o_l_e_a_n))
    Unifies  its argument with  true if the  clause in which is  appears
    has  not created any choicepoints since  it was started.  There  are
    few  realistic situations for using this  predicate.  It is used  by
    the  prolog/0 toplevel  to check  whether Prolog  should prompt  the
    user for alternatives.


1100..22 IInntteerrcceeppttiinngg tthhee TTrraacceerr


pprroolloogg__ttrraaccee__iinntteerrcceeppttiioonn((_+_P_o_r_t_, _+_F_r_a_m_e_, _+_C_h_o_i_c_e_, _-_A_c_t_i_o_n))
    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 _A_c_t_i_o_n.
    Otherwise the normal Prolog debugger actions are performed.

    _P_o_r_t  denotes  the reason  to  activate the  tracer (`port'  in  the
    4/5-port, but with some additions:

    ccaallll
         Normal extry through the call-port of the 4-port debugger.

    rreeddoo
         Normal extry  through  the call-port  of the  4-port  debugger.
         The  redo  port  signals  resuming  a  predicate   to  generate
         alternative solutions.

    uunniiffyy
         The unify-port represents the _n_e_c_k instruction,  signalling the
         end  of the  head-matching  process.    This port  is  normally
         unvisible.  See leash/1 and visible/1.

    eexxiitt
         The exit-port signals the goal  is proved.  It is  possible for
         the goal to have alternative.   See prolog_frame_attribute/3 to
         examine the goal-stack.

    ffaaiill
         The fail-port signals final failure of the goal.

    eexxcceeppttiioonn((_E_x_c_e_p_t))
         An  exception is  raised  and still  pending.    This  port  is
         activated on  each parent  frame  of the  frame generating  the
         exception until the  exception is caught  or the user  restarts
         normal  computation  using  retry.     _E_x_c_e_p_t  is  the  pending
         exception-term.

    bbrreeaakk((_P_C))
         A break instruction is executed.  _P_C is program counter.   This
         port is used by the graphical debugger.

    ccuutt__ccaallll((_P_C))
         A cut is encountered at _P_C. This port is used  by the graphical
         debugger.  to visualise the effect of the cut.

    ccuutt__eexxiitt((_P_C))
         A  cut  has  been   executed.     See   cut_call(_P_C)  for   more
         information.

    _F_r_a_m_e  is  a  reference to  the  current local  stack  frame,  which
    can  be  examined  using  prolog_frame_attribute/4.     _C_h_o_i_c_e  is  a
    reference  to  the  last  choice-point and  can  be  examined  using
    prolog_choice_attribute/3.   _A_c_t_i_o_n  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  4.39 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 below records  all goals trapped  by the tracer in  the
    database.

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

    To  trace the execution of `go' this way the following  query should
    be given:

    ?- trace, go, notrace.


pprroolloogg__sskkiipp__lleevveell((_-_O_l_d_, _+_N_e_w))
    Unify  _O_l_d with  the old  value of `skip  level' and  than set  this
    level  according to _N_e_w.   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).


1100..33 HHooookkss uussiinngg tthhee exception/3 pprreeddiiccaattee

This section describes  the predicate exception/3, which may  be defined
by the  user in the module  user as a multifile  predicate.  Unlike  the
name  suggests, this  is  actually a  _h_o_o_k predicate.    Exceptions  are
handled by  the ISO  predicates catch/3 and  throw/1.   They all  frames
created after the matching catch/3 to be discarded immediately.

The  predicate exception/3  is  called by  the  kernel  on a  couple  of
events,  allowing the user  to alter  the behaviour  on some  predefined
events.


eexxcceeppttiioonn((_+_E_x_c_e_p_t_i_o_n_, _+_C_o_n_t_e_x_t_, _-_A_c_t_i_o_n))
    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 _E_x_c_e_p_t_i_o_n are described below.

    uunnddeeffiinneedd__pprreeddiiccaattee
         If _E_x_c_e_p_t_i_o_n is undefined_predicate _C_o_n_t_e_x_t is  instantiated to
         a term  _N_a_m_e/_A_r_i_t_y.    _N_a_m_e refers  to the  name  and _A_r_i_t_y  to
         the  arity of  the  undefined predicate.    If  the  definition
         module of  the predicate is  not _u_s_e_r, _C_o_n_t_e_x_t  will be of  the
         form <_M_o_d_u_l_e>:<_N_a_m_e>/<_A_r_i_t_y>.   If  the  predicate fails  Prolog
         will generate an  esistence_error exception.  If the  predicate
         succeeds it should instantiate the last argument  either to the
         atom fail to tell Prolog to fail the predicate,  the atom retry
         to tell  Prolog to  retry the predicate  or error  to make  the
         system generate  an exception.    The action  retry only  makes
         sense if the exception handler has defined the predicate.


1100..44 HHooookkss ffoorr iinntteeggrraattiinngg lliibbrraarriieess

Some libraries  realise an entirely new  programming paradigm on top  of
Prolog.   An example is  XPCE which adds  an object-system to Prolog  as
well as an extensive  set of graphical primitives.   SWI-Prolog provides
several hooks to  improve the integration of  such libraries.  See  also
section 4.4  for editing hooks  and section 4.9.3  for hooking into  the
message system.


pprroolloogg__lliisstt__ggooaall((_:_G_o_a_l))
    Hook, normally not defined.   This hook is called by the 'L' command
    of  the  tracer in  the module  user to  list  the currently  called
    predicate.   This hook may be defined to list only  relevant clauses
    of  the indicated  _G_o_a_l  and/or show  the actual  source-code in  an
    editor.  See also portray/1 and multifile/1.


pprroolloogg::ddeebbuugg__ccoonnttrrooll__hhooookk((_:_A_c_t_i_o_n))
    Hook for the  debugger-control predicates that allows the creator of
    more  high-level programming languages  to use the common  front-end
    predicates  to control de  debugger.  For  example, XPCE uses  these
    hooks  to allow for spying methods  rather then predicates.   _A_c_t_i_o_n
    is one of:

    ssppyy((_S_p_e_c))
         Hook in  spy/1.  If  the hook succeeds  spy/1 takes no  further
         action.

    nnoossppyy((_S_p_e_c))
         Hook in nospy/1.   If the hook succeeds spy/1 takes  no further
         action.    If  spy/1  is  hooked,  it is  advised  to  place  a
         complementary hook for nospy/1.

    nnoossppyyaallll
         Hook in nospyall/0.   Should remove all spy-points.   This hook
         is called in a failure-driven loop.

    ddeebbuuggggiinngg
         Hook in  debugging/0.   It can  be used in  two ways.   It  can
         report the status of the additional debug-points  controlled by
         the above hooks  and fail to let  the system report the  others
         or it succeed, overruling the entire behaviour of debugging/0.


pprroolloogg::hheellpp__hhooookk((_+_A_c_t_i_o_n))
    Hook  into help/0 and help/1.   If  the hook succeeds, the  built-in
    actions are not  executed.  For example, ?- help(picture). is caught
    by  the XPCE help-hook to give help  on the class _p_i_c_t_u_r_e.   Defined
    actions are:

    hheellpp
         User entered plain  help/0 to give default  help.  The  default
         performs help(help/1), giving help on help.

    hheellpp((_W_h_a_t))
         Hook in help/1 on the topic _W_h_a_t.

    aapprrooppooss((_W_h_a_t))
         Hook in apropos/1 on the topic _W_h_a_t.


1100..55 HHooookkss ffoorr llooaaddiinngg ffiilleess

All  loading of  source-files is  achieved by  load_files/2.   The  hook
prolog_load_file/2 can be  used to  load Prolog code  from non-files  or
even load entirely different information, such as foreign files.


uusseerr::pprroolloogg__llooaadd__ffiillee((_+_S_p_e_c_, _+_O_p_t_i_o_n_s))
    Load  a single object.  If this  call succeeds, load_files/2 assumes
    the  action has been  taken care of.   This hook  is only called  if
    _O_p_t_i_o_n_s does not contain the stream(_I_n_p_u_t) option.

    The  http_load  provides an example, loading Prolog sources  directly
    from an HTTP server.


1100..66 RReeaaddlliinnee IInntteerraaccttiioonn

The       following       predicates       are        available       if
current_prolog_flag(readline, true) succeeds.      They  allow  for  di-
rect  interaction   with  the   GNU  readline   library.      See   also
readline(3)


rrll__rreeaadd__iinniitt__ffiillee((_+_F_i_l_e))
    Read  a readline  initialisation file.   Readline  by default  reads
    ~/.inputrc.     This  predicate  may be  used  to  read  alternative
    readline initialisation files.


rrll__aadddd__hhiissttoorryy((_+_L_i_n_e))
    Add  a  line  to  the  Control-P/Control-N  history  system  of  the
    readline library.


CChhaapptteerr 1111..  GGLLOOSSSSAARRYY OOFF TTEERRMMSS

aannoonnyymmoouuss [[vvaarriiaabbllee]]
    The  variable  _  is  called  the  _a_n_o_n_y_m_o_u_s  variable.     Multiple
    occurrences of _ in a single _t_e_r_m are not _s_h_a_r_e_d.

aarrgguummeennttss
    Arguments  are _t_e_r_m_s that appear in a _c_o_m_p_o_u_n_d _t_e_r_m.  _A_1  and _a_2 are
    the first and second argument of the term myterm(_A_1_, _a_2).

aarriittyy
    Argument count (is number of arguments) of a _c_o_m_p_o_u_n_d _t_e_r_m.

aasssseerrtt
    Add a _c_l_a_u_s_e to  a _p_r_e_d_i_c_a_t_e.  Clauses can be added at either end of
    the clause-list of a _p_r_e_d_i_c_a_t_e.  See assert/1 and assertz/1.

aattoomm
    Textual  constant.   Used as name for  _c_o_m_p_o_u_n_d terms, to  represent
    constants or text.

bbaacckkttrraacckkiinngg
    Searching  process used by Prolog.   If a predicate offers  multiple
    _c_l_a_u_s_e_s  to  solve  a _g_o_a_l,  they  are  tried one-by-one  until  one
    _s_u_c_c_e_e_d_s.    If  a subsequent  part of  the prove  is not  satisfied
    with  the resulting _v_a_r_i_a_b_l_e _b_i_n_d_i_n_g, it may ask for  an alternative
    _s_o_l_u_t_i_o_n (= _b_i_n_d_i_n_g  of the _v_a_r_i_a_b_l_e_s), causing Prolog to reject the
    previously chosen _c_l_a_u_s_e and try the next one.

bbiinnddiinngg [[ooff aa vvaarriiaabbllee]]
    Current value of the _v_a_r_i_a_b_l_e.  See also _b_a_c_k_t_r_a_c_k_i_n_g and _q_u_e_r_y.

bbuuiilltt--iinn [[pprreeddiiccaattee]]
    Predicate  that is part of the  Prolog system.  Built in  predicates
    cannot  be redefined  by the  user, unless this  is overruled  using
    redefine_system_predicate/1.

bbooddyy
    Part of a _c_l_a_u_s_e behind the _n_e_c_k operator (:-).

ccllaauussee
    `Sentence'  of a Prolog program.   A _c_l_a_u_s_e  consists of a _h_e_a_d  and
    _b_o_d_y  separated by  the _n_e_c_k operator  (:-) or it  is a _f_a_c_t.    For
    example:

    parent(X) :-
            father(X, _).

    Expressed  ``X is a parent if X is a father of someone''.   See also
    _v_a_r_i_a_b_l_e and _p_r_e_d_i_c_a_t_e.

ccoommppiillee
    Process  where  a Prolog  _p_r_o_g_r_a_m  is translated  to a  sequence  of
    instructions.   See  also _i_n_t_e_r_p_r_e_t_e_d.   SWI-Prolog always  compiles
    your program before executing it.

ccoommppoouunndd [[tteerrmm]]
    Also  called  _s_t_r_u_c_t_u_r_e.    It  consists of  a  name followed  by  _N
    _a_r_g_u_m_e_n_t_s,  each of which are _t_e_r_m_s.   _N is called the _a_r_i_t_y  of the
    term.

ccoonntteexxtt mmoodduullee
    If  a _t_e_r_m  is referring  to a _p_r_e_d_i_c_a_t_e  in a  _m_o_d_u_l_e, the  _c_o_n_t_e_x_t
    _m_o_d_u_l_e  is used to find the target module.  The context  module of a
    _g_o_a_l  is the module in which  the _p_r_e_d_i_c_a_t_e is defined, unless  this
    _p_r_e_d_i_c_a_t_e  is _m_o_d_u_l_e _t_r_a_n_s_p_a_r_e_n_t, in  which case the _c_o_n_t_e_x_t  _m_o_d_u_l_e
    is inherited from the parent _g_o_a_l.  See also module_transparent/1.

ddyynnaammiicc [[pprreeddiiccaattee]]
    A _d_y_n_a_m_i_c predicate  is a predicate to which _c_l_a_u_s_e_s may be _a_s_s_e_r_ted
    and  from  which  _c_l_a_u_s_e_s may  be  _r_e_t_r_a_c_ted  while the  program  is
    running.  See also _u_p_d_a_t_e _v_i_e_w.

eexxppoorrtteedd [[pprreeddiiccaattee]]
    A  _p_r_e_d_i_c_a_t_e is  said to  be _e_x_p_o_r_t_e_d from  a _m_o_d_u_l_e  if it  appears
    in  the  _p_u_b_l_i_c _l_i_s_t.     This implies  that  the predicate  can  be
    _i_m_p_o_r_t_e_d  into another module  to make it visible  there.  See  also
    use_module/[1,2].

ffaacctt
    _C_l_a_u_s_e  without a _b_o_d_y.   This is called a fact because  interpreted
    as logic, there is  no condition to be satisfied.  The example below
    states john is a person.

    person(john).

ffaaiill
    A _g_o_a_l is said to haved failed if it could not be _p_r_o_v_e_n.

ffllooaatt
    Computers  cripled representation of a real number.   Represented as
    `IEEE double'.

ffoorreeiiggnn
    Computer code expressed  in other languages than Prolog.  SWI-Prolog
    can only cooperate directly with the C and C++ computer languages.

ffuunnccttoorr
    Combination  of name and _a_r_i_t_y of a _c_o_m_p_o_u_n_d term.  The  term foo(_a_,
    _b_,  _c) is said to be a  term belonging to the functor foo/3.   foo/0
    is used to refer to the _a_t_o_m foo.

ggooaall
    Question  stated to the Prolog engine.  A _g_o_a_l is either  an _a_t_o_m or
    a  _c_o_m_p_o_u_n_d term.  A _g_o_a_l  succeeds, in which case the  _v_a_r_i_a_b_l_e_s in
    the _c_o_m_p_o_u_n_d terms have  a _b_i_n_d_i_n_g or _f_a_i_l_s if Prolog fails to prove
    the _g_o_a_l.

hhaasshhiinngg
    _I_n_d_e_x_i_n_g technique used for quick lookup.

hheeaadd
    Part  of a _c_l_a_u_s_e before the _n_e_c_k  instruction.  This is an  atom or
    _c_o_m_p_o_u_n_d term.

iimmppoorrtteedd [[pprreeddiiccaattee]]
    A  _p_r_e_d_i_c_a_t_e is said to be _i_m_p_o_r_t_e_d  into a _m_o_d_u_l_e if it  is defined
    in  another _m_o_d_u_l_e  and made  available in this  _m_o_d_u_l_e.   See  also
    chapter 5.

iinnddeexxiinngg
    Indexing  is a  technique used to  quickly select candidate  _c_l_a_u_s_e_s
    of  a  _p_r_e_d_i_c_a_t_e for  a specific  _g_o_a_l.    In most  Prolog  systems,
    including  SWI-Prolog, indexing  is done  on the  first _a_r_g_u_m_e_n_t  of
    the  _h_e_a_d.  If  this argument is  instantiated to an _a_t_o_m,  _i_n_t_e_g_e_r,
    _f_l_o_a_t or _c_o_m_p_o_u_n_d  term with _f_u_n_c_t_o_r, _h_a_s_h_i_n_g is used quickly select
    all  _c_l_a_u_s_e_s of which  the first argument  may _u_n_i_f_y with the  first
    argument of the _g_o_a_l.

iinntteeggeerr
    Whole  number.   On most current  machines, SWI-Prolog integers  are
    represented  as `32-bit signed values', ranging from  -2147483648 to
    2147483647.  See also current_prolog_flag/2.

iinntteerrpprreetteedd
    As  opposed  to  _c_o_m_p_i_l_e_d,   interpreted  means  the  Prolog  system
    attempts  to prove  a _g_o_a_l  by directly reading  the _c_l_a_u_s_e_s  rather
    than executing instructions  from an (abstract) instruction set that
    is not or only indirectly related to Prolog.

mmeettaa pprreeddiiccaattee
    A  _p_r_e_d_i_c_a_t_e that reasons about other _p_r_e_d_i_c_a_t_e_s, either  by calling
    them, (re)defining them or querying _p_r_o_p_e_r_t_i_e_s.

mmoodduullee
    Collection  of predicates.    Each module defines  a name-space  for
    predicates.   _b_u_i_l_t_-_i_n predicates  are accessible from all  modules.
    Predicates  can be published (_e_x_p_o_r_t_e_d)  and _i_m_p_o_r_t_e_d to make  their
    definition available to other modules.

mmoodduullee ttrraannssppaarreenntt [[pprreeddiiccaattee]]
    A  _p_r_e_d_i_c_a_t_e that  does not change  the _c_o_n_t_e_x_t  _m_o_d_u_l_e.   Sometimes
    also called a _m_e_t_a _p_r_e_d_i_c_a_t_e.

mmuullttiiffiillee [[pprreeddiiccaattee]]
    Predicate  for which  the  definition is  distributed over  multiple
    source-files.  See multi_file/1.

nneecckk
    Operator (:-) separating _h_e_a_d from _b_o_d_y in a _c_l_a_u_s_e.

ooppeerraattoorr
    Symbol (_a_t_o_m) that  may be placed before its _o_p_e_r_a_n_t (prefix), after
    its _o_p_e_r_a_n_t (postfix) or between its two _o_p_e_r_a_n_t_s (infix).

    In  Prolog, the expression a+b is exactly the same as  the canonical
    term +(a,b).

ooppeerraanntt
    _A_r_g_u_m_e_n_t of an _o_p_e_r_a_t_o_r.

pprreecceeddeennccee
    The  _p_r_i_o_r_i_t_y  of an  _o_p_e_r_a_t_o_r.    Operator  precedence is  used  to
    interpret a+b*c as +(a, *(b,c)).

pprreeddiiccaattee
    Collection  of _c_l_a_u_s_e_s  with the same  _f_u_n_c_t_o_r (name/_a_r_i_t_y).   If  a
    _g_o_a_l  is proved,  the system  looks for  a _p_r_e_d_i_c_a_t_e  with the  same
    functor,  then used  _i_n_d_e_x_i_n_g to select  candidate _c_l_a_u_s_e_s and  then
    tries these _c_l_a_u_s_e_s one-by-one.  See also _b_a_c_k_t_r_a_c_k_i_n_g.

pprriioorriittyy
    In the context of _o_p_e_r_a_t_o_r_s a synonym for _p_r_e_c_e_d_e_n_c_e.

pprrooggrraamm
    Collection of _p_r_e_d_i_c_a_t_e_s.

pprrooppeerrttyy
    Attribute  of  an object.    SWI-Prolog  defines  various _*___p_r_o_p_e_r_t_y
    predicates to query the status of predicates, clauses.  etc.

pprroovvee
    Process  where Prolog attempts to prove a _q_u_e_r_y using  the available
    _p_r_e_d_i_c_a_t_e_s.

ppuubblliicc lliisstt
    List of _p_r_e_d_i_c_a_t_e_s exported from a _m_o_d_u_l_e.

qquueerryy
    See _g_o_a_l.

rreettrraacctt
    Remove  a _c_l_a_u_s_e from a  _p_r_e_d_i_c_a_t_e.   See also _d_y_n_a_m_i_c, _u_p_d_a_t_e  _v_i_e_w
    and _a_s_s_e_r_t.

sshhaarreedd
    Two  _v_a_r_i_a_b_l_e_s  are called  _s_h_a_r_e_d after  they are  _u_n_i_f_i_e_d.    This
    implies  if either of them is _b_o_u_n_d, the other is bound to  the same
    value:

    ?- A = B, A = a.

    A = a,
    B = a

ssiinngglleettoonn [[vvaarriiaabbllee]]
    _V_a_r_i_a_b_l_e  appearing only one time in a _c_l_a_u_s_e.   SWI-Prolog normally
    warns  for  this to  avoid  you  making spelling  mistakes.    If  a
    variable  appears on purpose only  once in a  clause, write it as  _
    (see  _a_n_o_n_y_m_o_u_s) or make sure the first character is a _.   See also
    the style_check/1 option singletons.

ssoolluuttiioonn
    _B_i_n_d_i_n_g_s resulting from a successfully _p_r_o_v_en _g_o_a_l.

ssttrruuccttuurree
    Synonym for _c_o_m_p_o_u_n_d term.

ssttrriinngg
    Used  for the  following representations  of text:   a packed  array
    (see  section 4.23, SWI-Prolog specific), a list of  character codes
    or a list of one-character _a_t_o_m_s.

ssuucccceeeedd
    A _g_o_a_l is said to have _s_u_c_c_e_e_d_e_d if it has been _p_r_o_v_e_n.

tteerrmm
    Value in Prolog.   A _t_e_r_m is either a _v_a_r_i_a_b_l_e, _a_t_o_m, integer, float
    or  _c_o_m_p_o_u_n_d term.   In addition,  SWI-Prolog also defines the  type
    _s_t_r_i_n_g

ttrraannssppaarreenntt
    See _m_o_d_u_l_e _t_r_a_n_s_p_a_r_e_n_t.

uunniiffyy
    Prolog  process to make  two terms equal  by assigning variables  in
    one term to  values at the corresponding location of the other term.
    For example:

    ?- foo(a, B) = foo(A, b).

    A = a,
    B = b

    Unlike  assignment (which does not exist in Prolog),  unification is
    not directed.

uuppddaattee vviieeww
    How  Prolog behaves when a _d_y_n_a_m_i_c _p_r_e_d_i_c_a_t_e is changed while  it is
    running.   There are two models.   In most older Prolog  systems the
    change  becomes immediately visible to  the _g_o_a_l, in modern  systems
    including  SWI-Prolog, the running _g_o_a_l is  not affected.  Only  new
    _g_o_a_l_s `see' the new definition.

vvaarriiaabbllee
    A  Prolog  variable is  a value  that `is  not yet  bound'.    After
    _b_i_n_d_i_n_g a variable, it  cannot be modified.  _B_a_c_k_t_r_a_c_k_i_n_g to a point
    in  the execution before  the variable was  bound will turn it  back
    into a variable:

    ?- A = b, A = c.
    No
    ?- (A = b; true; A = c).
    A = b ;
    A = _G283 ;
    A = c ;
    No

    See also _u_n_i_f_y.


CChhaapptteerr 1122..  SSWWII--PPRROOLLOOGG LLIICCEENNSSEE CCOONNDDIITTIIOONNSS AANNDD TTOOOOLLSS

SWI-Prolog licensing aims at a large audience, combining  ideas from the
Free Software Foundation and the less principal  Open Source Initiative.
The license aims at:

  o Make SWI-Prolog itself and its libraries are `As free as possible'.

  o Allow for easy integration of contributions.  See section 12.2.

  o Free software can build on SWI-Prolog without limitations.

  o Non-free  (open  or  proprietary)  software can  be  produced  using
    SWI-Prolog,  although contributed pure  GPL-ed components cannot  be
    used.

To achieve this, different parts of the system  have different licenses.
SWI-Prolog  programs consists  of  a mixture  of `native'  code  (source
compiled to  machine instructions)  and `virtual  machine' code  (Prolog
source  compiled to  SWI-Prolog virtual  machine instructions,  covering
both compiled SWI-Prolog libraries and your compiled application).

For  maximal coherence  between free  licenses, we  start  with the  two
prime  licenses from  the  Free  Software Foundation,  the  GNU  General
Public License (GPL)  and the Lesser GNU General Public  License (LGPL),
after which we add a proven (used by the  GNU-C compiler runtime library
as  well as  the  GNU _C_l_a_s_s_P_a_t_h  project)  exception  to deal  with  the
specific nature of compiled virtual machine code in a saved state.


1122..11 TThhee SSWWII--PPrroolloogg kkeerrnneell aanndd ffoorreeiiggnn lliibbrraarriieess

The SWI-Prolog  kernel and our foreign  libraries are distributed  under
the  LLGGPPLL. A  Prolog executable  consists of  the  combination of  these
`native'  code  components  and  Prolog  virtual  machine  code.     The
SWI-Prolog  plrc  utility allows  for  disassembling  and  re-assembling
these parts, a process satisfying article 66bb of the LGPL.

Under  the LGPL  SWI-Prolog  can be  linked  to code  distributed  under
arbitrary licenses,  provided a number  of requirements are  fullfilled.
The most  important requirement is  that, if  an application replies  on
a _m_o_d_i_f_i_e_d  version of  SWI-Prolog, the  modified sources  must be  made
available.


1122..11..11 TThhee SSWWII--PPrroolloogg PPrroolloogg lliibbrraarriieess

Lacking a  satisfactory technical solution  to handle  article 66 of  the
LGPL, this  license cannot be  used for the Prolog  source code that  is
part of the  SWI-Prolog system (both libraries  and kernel code).   This
situation is  comparable to libgcc,  the runtime  library used with  the
GNU C-compiler.    Therefore, we use  the same  proven license terms  as
this library.    The libgcc  license is  the with  a special  exception.
Below we rephrased this exception adjusted to our needs:

    _A_s  _a _s_p_e_c_i_a_l  _e_x_c_e_p_t_i_o_n_, _i_f _y_o_u  _l_i_n_k _t_h_i_s  _l_i_b_r_a_r_y _w_i_t_h _o_t_h_e_r
    _f_i_l_e_s_,  _c_o_m_p_i_l_e_d  _w_i_t_h  _a _F_r_e_e  _S_o_f_t_w_a_r_e  _c_o_m_p_i_l_e_r_,  _t_o _p_r_o_d_u_c_e
    _a_n  _e_x_e_c_u_t_a_b_l_e_,  _t_h_i_s  _l_i_b_r_a_r_y  _d_o_e_s _n_o_t  _b_y  _i_t_s_e_l_f  _c_a_u_s_e _t_h_e
    _r_e_s_u_l_t_i_n_g  _e_x_e_c_u_t_a_b_l_e _t_o _b_e  _c_o_v_e_r_e_d _b_y _t_h_e  _G_N_U _G_e_n_e_r_a_l _P_u_b_l_i_c
    _L_i_c_e_n_s_e_.   _T_h_i_s _e_x_c_e_p_t_i_o_n _d_o_e_s _n_o_t _h_o_w_e_v_e_r _i_n_v_a_l_i_d_a_t_e _a_n_y _o_t_h_e_r
    _r_e_a_s_o_n_s  _w_h_y _t_h_e  _e_x_e_c_u_t_a_b_l_e _f_i_l_e _m_i_g_h_t  _b_e _c_o_v_e_r_e_d _b_y  _t_h_e _G_N_U
    _G_e_n_e_r_a_l _P_u_b_l_i_c _L_i_c_e_n_s_e_.


1122..22 CCoonnttrriibbuuttiinngg ttoo tthhee SSWWII--PPrroolloogg pprroojjeecctt

To  achieve maximal  coherence using  SWI-Prolog for  Free and  Non-Free
software we  advice the  use of  the LGPL for  contributed foreign  code
and the  use of the  GPL with SWI-Prolog exception  for Prolog code  for
contributed modules.

As a  rule of thumb  it is  advised to use  the above licenses  whenever
possible and only use a strict GPL compliant license  only if the module
contains other code under strict GPL compliant licenses.


1122..33 SSooffttwwaarree ssuuppppoorrtt ttoo kkeeeepp ttrraacckk ooff lliicceennssee ccoonnddiittiioonnss

Given the above, it is possible that SWI-Prolog  packages and extensions
will  rely  on the  GPL.  The  predicates below  allow  for  registering
license  requirements  for  Prolog files  and  foreign  modules.     The
predicate  eval_license/0 reports  which  components from  the  currenly
configured  system  are  distributed under  copy-left  and  open  source
enforcing  licenses (the  GPL)  and therefore  must be  replaced  before
distributing linked applications under non-free license conditions.


eevvaall__lliicceennssee
    Evaluate  the license conditions of all  loaded components.  If  the
    system  contains  one or  more components  that  are licenced  under
    GPL-like  restrictions the  system indicates this  program may  only
    be  distributed under the  GPL license as  well as which  components
    prohibit the use of other license conditions.


lliicceennssee((_+_L_i_c_e_n_s_e_I_d_, _+_C_o_m_p_o_n_e_n_t))
    Register  the fact  that _C_o_m_p_o_n_e_n_t  is distributed  under a  license
    identified by _L_i_c_e_n_s_e_I_d.  The most important _L_i_c_e_n_s_e_I_d's are:

    sswwiippll
         Indicates this  module  is distributed  under the  GNU  General
         Public License (GPL) with the SWI-Prolog exception:

             _A_s _a  _s_p_e_c_i_a_l _e_x_c_e_p_t_i_o_n_, _i_f _y_o_u _l_i_n_k _t_h_i_s _l_i_b_r_a_r_y _w_i_t_h
             _o_t_h_e_r  _f_i_l_e_s_, _c_o_m_p_i_l_e_d _w_i_t_h _S_W_I_-_P_r_o_l_o_g_,  _t_o _p_r_o_d_u_c_e _a_n
             _e_x_e_c_u_t_a_b_l_e_, _t_h_i_s  _l_i_b_r_a_r_y _d_o_e_s _n_o_t _b_y _i_t_s_e_l_f _c_a_u_s_e _t_h_e
             _r_e_s_u_l_t_i_n_g _e_x_e_c_u_t_a_b_l_e  _t_o _b_e _c_o_v_e_r_e_d _b_y _t_h_e _G_N_U _G_e_n_e_r_a_l
             _P_u_b_l_i_c  _L_i_c_e_n_s_e_.    _T_h_i_s  _e_x_c_e_p_t_i_o_n  _d_o_e_s  _n_o_t _h_o_w_e_v_e_r
             _i_n_v_a_l_i_d_a_t_e  _a_n_y _o_t_h_e_r _r_e_a_s_o_n_s _w_h_y  _t_h_e _e_x_e_c_u_t_a_b_l_e _f_i_l_e
             _m_i_g_h_t _b_e _c_o_v_e_r_e_d _b_y _t_h_e _G_N_U _G_e_n_e_r_a_l _P_u_b_l_i_c _L_i_c_e_n_s_e_.

         This should  be the  default  for software  contributed to  the
         SWI-Prolog  project  as it  allows  the  community  to  prosper
         both in  the free  and non-free  world.    Still, people  using
         SWI-Prolog  to create  non-free  applications  must  contribute
         sources to improvements they make to the community.

    llggppll
         This is the  default license for foreign-libraries linked  with
         SWI-Prolog.   Use PL_license() to  register the condition  from
         foreign code.

    ggppll
         Indicates  this  module   is  strictly  Free  Software,   which
         implies it  cannot be  used together  with any  module that  is
         incompatible to the GPL. Please only use  these conditions when
         forced by other code used in the component.


lliicceennssee((_+_L_i_c_e_n_s_e_I_d))
    Intented  as a  directive  in Prolog  source files.    It takes  the
    current filename and calls license/2.


void PPLL__lliicceennssee(_c_o_n_s_t _c_h_a_r _*_L_i_c_e_n_s_e_I_d_, _c_o_n_s_t _c_h_a_r _*_C_o_m_p_o_n_e_n_t)
    Intended  for the install()  procedure of foreign  libraries.   This
    call can be made _b_e_f_o_r_e PL_initialise().


CChhaapptteerr 1133..  SSUUMMMMAARRYY


1133..11 PPrreeddiiccaatteess

The  predicate summary  is used  by the  Prolog  predicate apropos/1  to
suggest predicates from a keyword.

 !/0                           Cut (discard choicepoints)
 !/1                           Cut block.  See block/3
 ,/2                           Conjunction of goals
 ->/2                          If-then-else
 *->/2                         Soft-cut
 ./2                           Consult.  Also list constructor
 ;/2                           Disjunction of goals.  Same as |/2
 </2                           Arithmetic smaller

 =/2                           Unification
 =../2                         ``Univ.''  Term to list conversion
 =:=/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                          Standard order smaller
 @=</2                         Standard order smaller or equal
 @>/2                          Standard order larger
 @>=/2                         Standard order larger or equal
 \+/1                          Negation by failure.  Same as not/1
 \=/2                          Not unifyable

 \==/2                         Not identical
 \=@=/2                        Not structural identical
 ^/2                           Existential quantification (bagof/3, setof/3)
 |/2                           Disjunction of goals.  Same as ;/2
 abolish/1                     Remove predicate definition from the database
 abolish/2                     Remove predicate definition from the database
 abort/0                       Abort execution, return to top level

 absolute_file_name/2          Get absolute path name
 absolute_file_name/3          Get absolute path name with options
 access_file/2                 Check access permissions of a file
 add_import_module/3           Add module to the auto-import list
 append/1                      Append to a file
 apply/2                       Call goal with additional arguments
 apropos/1                     online_help Search manual
 arg/3                         Access argument of a term

 arithmetic_function/1         Register an evaluable function
 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)

 assume/1                      Make assertions about your program
 attach_console/0              Attach I/O console to thread
 at_end_of_stream/0            Test for end of file on input
 at_end_of_stream/1            Test for end of file on stream
 at_halt/1                     Register goal to run at halt/1
 at_initialization/1           Register goal to run at start-up
 atom/1                        Type check for an atom
 atom_chars/2                  Convert between atom and list of characters

 atom_codes/2                  Convert between atom and list of characters codes
 atom_length/2                 Determine length of an atom
 atom_prefix/2                 Test for start of atom
 atom_number/2                 Convert between atom and number
 atom_to_term/3                Convert between atom and term
 atomic/1                      Type check for primitive
 autoload/0                    Autoload all predicates now

 bagof/3                       Find all solutions to a goal
 between/3                     Integer range checking/generating
 block/3                       Start a block (`catch'/`throw')
 break/0                       Start interactive toplevel
 call/1                        Call a goal
 call/[2..]                    Call with additional arguments
 call_cleanup/3                Guard a goal with a cleaup-handler
 call_cleanup/2                Guard a goal with a cleaup-handler

 call_shared_object_function/2 UNIX: Call C-function in shared (.so) file
 call_with_depth_limit/3       Prove goal with bounded depth
 callable/1                    Test for atom or compound term
 catch/3                       Call goal, watching for exceptions
 char_code/2                   Convert between character and character code
 char_conversion/2             Provide mapping of input characters
 char_type/2                   Classify characters

 character_count/2             Get character index on a stream
 chdir/1                       Compatibility:  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
 clause_property/2             Get properties of a clause
 close/1                       Close stream
 close/2                       Close stream (forced)

 close_dde_conversation/1      Win32:  Close DDE channel
 close_shared_object/1         UNIX: Close shared library (.so file)
 compare/3                     Compare, using a predicate to determine the order
 compile_predicates/1          Compile dynamoc code to static
 compiling/0                   Is this a compilation run?
 compound/1                    Test for compound term
 atom_concat/3                 Append two atoms

 code_type/2                   Classify a character-code
 concat_atom/2                 Append a list of atoms
 concat_atom/3                 Append a list of atoms with separator
 consult/1                     Read (compile) a Prolog source file
 context_module/1              Get context module of current goal
 convert_time/8                Break time stamp into fields
 convert_time/2                Convert time stamp to string
 copy_stream_data/2            Copy all data from stream to stream

 copy_stream_data/3            Copy n bytes from stream to stream
 copy_term/2                   Make a copy of a term
 current_arithmetic_function/1 Examine evaluable functions
 current_atom/1                Examine existing atoms
 current_char_conversion/2     Query input character mapping
 current_flag/1                Examine existing flags
 current_foreign_library/2     shlib Examine loaded shared libraries (.so files)

 current_format_predicate/2    Enumerate user-defined format codes
 current_functor/2             Examine existing name/arity pairs
 current_input/1               Get current input stream
 current_key/1                 Examine existing database keys
 current_module/1              Examine existing modules
 current_module/2              Examine existing modules
 current_mutex/3               Examine existing mutexes
 current_op/3                  Examine current operator declarations

 current_output/1              Get the current output stream
 current_predicate/1           Examine existing predicates (ISO)
 current_predicate/2           Examine existing predicates
 current_signal/3              Current software signal mapping
 current_stream/3              Examine open streams
 current_thread/2              Examine Prolog threads
 dde_current_connection/2      Win32:  Examine open DDE connections

 dde_current_service/2         Win32:  Examine DDE services provided
 dde_execute/2                 Win32:  Execute command on DDE server
 dde_register_service/2        Win32:  Become a DDE server
 dde_request/3                 Win32:  Make a DDE request
 dde_poke/3                    Win32:  POKE operation on DDE server
 dde_unregister_service/1      Win32:  Terminate a DDE service
 debug/0                       Test for debugging mode
 debug/1                       Select topic for debugging

 debug/3                       Print debugging message on topic
 debug_control_hook/1          (hook) Extend spy/1, etc.
 debugging/0                   Show debugger status
 debugging/1                   Test where we are debugging topic
 default_module/2              Get the default modules of a module
 delete_directory/1            Remove a folder from the file system
 delete_file/1                 Remove a file from the file system

 delete_import_module/2        Remove module from import list
 deterministic/1               Test deterministicy of current clause
 discontiguous/1               Indicate distributed definition of a predicate
 downcase_atom/2               Convert atom to lower-case
 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

 edit/0                        Edit current script- or associated file
 edit/1                        Edit a file, predicate, module (extensible)
 ensure_loaded/1               Consult a file if that has not yet been done
 erase/1                       Erase a database record or clause
 eval_license/0                Evaluate licenses of loaded modules
 exception/3                   (hook) Handle runtime exceptions
 exists_directory/1            Check existence of directory

 exists_file/1                 Check existence of file
 exit/2                        Exit from named block.  See block/3
 expand_answer/2               Expand answer of query
 expand_file_name/2            Wildcard expansion of file names
 expand_file_search_path/2     Wildcard expansion of file paths
 expand_goal/2                 Compiler:  expand goal in clause-body
 expand_query/4                Expanded entered query
 expand_term/2                 Compiler:  expand read term into clause(s)

 explain/1                     explain Explain argument
 explain/2                     explain 2nd argument is explanation of first
 export/1                      Export a predicate from a module
 export_list/2                 List of public predicates of a module
 fail/0                        Always false
 fail/1                        Immediately fail named block.  See block/3
 current_prolog_flag/2         Get system configuration parameters

 file_base_name/2              Get file part of path
 file_directory_name/2         Get directory part of path
 file_name_extension/3         Add, remove or test file extensions
 file_search_path/2            Define path-aliases for locating files
 fileerrors/2                  Do/Don't warn on file errors
 findall/3                     Find all solutions to a goal
 flag/3                        Simple global variable system
 float/1                       Type check for a floating point number

 flush_output/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
 format/1                      Formatted output
 format/2                      Formatted output with arguments
 format/3                      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
 garbage_collect_atoms/0       Invoke the atom 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_byte/1                    Read next byte (ISO)
 get_byte/2                    Read next byte from a stream (ISO)
 get_char/1                    Read next character as an atom (ISO)
 get_char/2                    Read next character from a stream (ISO)
 get_code/1                    Read next character (ISO)
 get_code/2                    Read next character from a stream (ISO)

 get_single_char/1             Read next character from the terminal
 get_time/1                    Get current time
 getenv/2                      Get shell environment variable
 goal_expansion/2              Hook for macro-expanding goals
 ground/1                      Verify term holds no unbound variables
 guitracer/0                   Install hooks for the graphical debugger
 halt/0                        Exit from Prolog
 halt/1                        Exit from Prolog with status

 hash_term/2                   Hash-value of ground term
 help/0                        Give help on help
 help/1                        Give help on predicates and show parts of manual
 help_hook/1                   (hook) User-hook in the help-system
 ignore/1                      Call the argument, but always succeed
 import/1                      Import a predicate from a module
 import_module/2               Query import modules

 include/1                     Include a file with declarations
 index/1                       Change clause indexing
 initialization/1              Initialization directive
 int_to_atom/2                 Convert from integer to atom
 int_to_atom/3                 Convert from integer to atom (non-decimal)
 integer/1                     Type check for integer
 interactor/0                  Start new thread with console and toplevel
 is/2                          Evaluate arithmetic expression

 is_absolute_file_name/1       True if arg defines an absolute path
 is_list/1                     Type check for a list
 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           (hook) Directories holding Prolog libraries

 license/1                     Define license for current file
 license/2                     Define license for named module
 limit_stack/2                 Limit stack expansion
 line_count/2                  Line number on stream
 line_position/2               Character position in line on stream
 list_debug_topics/0           List registered topics for debugging
 listing/0                     List program in current module
 listing/1                     List predicate

 load_files/2                  Load source files with options
 load_foreign_library/1        shlib Load shared library (.so file)
 load_foreign_library/2        shlib Load shared library (.so file)
 make/0                        Reconsult all changed source files
 make_directory/1              Create a folder on the file system
 make_fat_filemap/1            Win32:  Create file containing non-FAT filenames
 make_library_index/1          Create autoload file INDEX.pl

 make_library_index/2          Create selective autoload file INDEX.pl
 maplist/3                     Transform all elements of a list
 memberchk/2                   Deterministic member/2
 merge/3                       Merge two sorted lists
 merge_set/3                   Merge two sorted sets
 message_hook/3                Intercept print_message/2
 message_queue_create/1        Create queue for thread communication
 message_queue_destroy/1       Destroy queue for thread communication

 message_to_string/2           Translate message-term to string
 meta_predicate/1              Quintus compatibility
 module/1                      Query/set current type-in module
 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

 mutex_create/1                Create a thread-synchronisation device
 mutex_destroy/1               Destroy a mutex
 mutex_lock/1                  Become owner of a mutex
 mutex_statistics/0            Print statistics on mutex usage
 mutex_trylock/1               Become owner of a mutex (non-blocking)
 mutex_unlock/1                Release ownership of mutex
 mutex_unlock_all/0            Release ownership of all mutexes
 name/2                        Convert between atom and list of character codes

 nl/0                          Generate a newline
 nl/1                          Generate a newline on a stream
 nodebug/0                     Disable debugging
 nodebug/1                     Disable debug-topic
 noguitracer/0                 Disable the graphical debugger
 nonvar/1                      Type check for bound term
 noprofile/1                   Hide (meta) predicate for the profiler

 noprotocol/0                  Disable logging of user interaction
 nospy/1                       Remove spy point
 nospyall/0                    Remove all spy points
 not/1                         Negation by failure (argument not provable).  Same as \+/1
 notrace/0                     Stop tracing
 notrace/1                     Do not debug argument goal
 nth_clause/3                  N-th clause of a predicate
 number/1                      Type check for integer or float

 number_chars/2                Convert between number and one-char atoms
 number_codes/2                Convert between number and character codes
 numbervars/3                  Number unbound variables of a term
 numbervars/4                  Number unbound variables of a term
 on_signal/3                   Handle a software signal
 once/1                        Call a goal deterministically
 op/3                          Declare an operator

 open/3                        Open a file (creating a stream)
 open/4                        Open a file (creating a stream)
 open_dde_conversation/3       Win32:  Open DDE channel
 open_null_stream/1            Open a stream to discard output
 open_resource/3               Open a program resource as a stream
 open_shared_object/2          UNIX: Open shared library (.so file)
 open_shared_object/3          UNIX: Open shared library (.so file)
 pce_dispatch/1                Run XPCE GUI in seperate thread

 pce_call/1                    Run goal in XPCE GUI thread
 peek_byte/1                   Read byte without removing
 peek_byte/2                   Read byte without removing
 peek_char/1                   Read character without removing
 peek_char/2                   Read character without removing
 peek_code/1                   Read character-code without removing
 peek_code/2                   Read character-code without removing

 phrase/2                      Activate grammar-rule set
 phrase/3                      Activate grammar-rule set (returning rest)
 please/3                      Query/change environment parameters
 plus/3                        Logical integer addition
 portray/1                     (hook) Modify behaviour of print/1
 portray_clause/1              Pretty print a clause
 portray_clause/2              Pretty print a clause to a stream
 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
 print_message/2               Print message from (exception) term
 print_message_lines/3         Print message to stream
 profile/1                     Obtain execution statistics

 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_choice_attribute/3     Examine the choice-point stack
 prolog_current_frame/1        Reference to goal's environment stack
 prolog_edit:locate/2          Locate targets for edit/1
 prolog_edit:locate/3          Locate targets for edit/1

 prolog_edit:edit_source/1     Call editor for edit/1
 prolog_edit:edit_command/2    Specify editor activation
 prolog_edit:load/0            Load edit/1 extensions
 prolog_file_type/2            Define meaning of file extension
 prolog_frame_attribute/3      Obtain information on a goal environment
 prolog_ide/1                  Program access to the development enviroment
 prolog_list_goal/1            (hook) Intercept tracer 'L' command

 prolog_load_context/2         Context information for directives
 prolog_load_file/2            (hook) Program load_files/2
 prolog_skip_level/2           Indicate deepest recursion to trace
 prolog_to_os_filename/2       Convert between Prolog and OS filenames
 prolog_trace_interception/4   user Intercept the Prolog tracer
 prompt1/1                     Change prompt for 1 line
 prompt/2                      Change the prompt used by read/1
 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
 put_byte/1                    Write a byte
 put_byte/2                    Write a byte on a stream
 put_char/1                    Write a character

 put_char/2                    Write a character on a stream
 put_code/1                    Write a character-code
 put_code/2                    Write a character-code on a stream
 qcompile/1                    Compile source to Quick Load File
 qsave_program/1               Create runtime application
 qsave_program/2               Create runtime application
 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_history/6                Read using history substitution
 read_link/3                   Read a symbolic link
 read_term/2                   Read term with options
 read_term/3                   Read term with options 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)
 redefine_system_predicate/1   Abolish system definition
 reload_library_index/0        Force reloading the autoload index
 rename_file/2                 Change name of file

 repeat/0                      Succeed, leaving infinite backtrack points
 require/1                     This file requires these predicates
 reset_profiler/0              Clear statistics obtained by the profiler
 resource/3                    Declare a program resource
 retract/1                     Remove clause from the database
 retractall/1                  Remove unifying clauses from the database
 same_file/2                   Succeeds if arguments refer to same file

 see/1                         Change the current input stream
 seeing/1                      Query the current input stream
 seek/4                        Modify the current position in a stream
 seen/0                        Close the current input stream
 set_input/1                   Set current input stream from a stream
 set_output/1                  Set current output stream from a stream
 set_prolog_flag/2             Define a system feature
 set_stream/2                  Set stream attribute

 set_stream_position/2         Seek stream to position
 set_tty/2                     Set `tty' stream
 setarg/3                      Destructive assignment on term
 setenv/2                      Set shell 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 subshell
 shell/1                       Execute OS command
 shell/2                       Execute OS command
 show_profile/1                Show results of the profiler
 show_profile/2                Show results of the profiler
 size_file/2                   Get size of a file in characters
 skip/1                        Skip to character in current input
 skip/2                        Skip to character on stream

 rl_add_history/1              Add line to readline(3) history
 rl_read_init_file/1           Read readline(3) init file
 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
 source_location/2             Location of last read term

 spy/1                         Force tracer on specified predicate
 stack_parameter/4             Some systems:  Query/Set runtime stack parameter
 statistics/0                  Show execution statistics
 statistics/2                  Obtain collected statistics
 stream_property/2             Get stream properties
 string/1                      Type check for string
 string_concat/3               atom_concat/3for strings
 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 character codes
 style_check/1                 Change level of warnings
 sub_atom/5                    Take a substring from an atom
 sublist/3                     Determine elements that meet condition
 sub_string/5                  Take a substring from a string
 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
 tell/1                        Change current output stream
 telling/1                     Query current output stream
 term_expansion/2              (hook) Convert term before compilation
 term_to_atom/2                Convert between term and atom

 thread_at_exit/1              Register goal to be called at exit
 thread_create/3               Create a new Prolog task
 thread_detach/1               Make thread cleanup after completion
 thread_exit/1                 Terminate Prolog task with value
 thread_get_message/1          Wait for message
 thread_get_message/2          Wait for message in a queue
 thread_join/2                 Wait for Prolog task-completion

 thread_local/1                Declare thread-specific clauses for a predicate
 thread_peek_message/1         Test for message
 thread_peek_message/2         Test for message in a queue
 thread_self/1                 Get identifier of current thread
 thread_send_message/2         Send message to another thread
 thread_setconcurrency/2       Number of active threads
 thread_signal/2               Execute goal in another thread
 thread_statistics/3           Get statistics of another thread

 threads/0                     List running threads
 throw/1                       Raise an exception (see catch/3)
 time/1                        Determine time needed to execute goal
 time_file/2                   Get last modification time of file
 tmp_file/2                    Create a temporary filename
 told/0                        Close current output
 trace/0                       Start the tracer

 trace/1                       Set trace-point on predicate
 trace/2                       Set/Clear trace-point on ports
 tracing/0                     Query status of the tracer
 trim_stacks/0                 Release unused memory resources
 true/0                        Succeed
 tty_get_capability/3          Get terminal parameter
 tty_goto/2                    Goto position on screen
 tty_put/2                     Write control string to terminal

 tty_size/2                    Get row/column size of the terminal
 ttyflush/0                    Flush output on terminal
 unify_with_occurs_check/2     Logically sound unification
 unix/1                        OS interaction
 unknown/2                     Trap undefined predicates
 unload_foreign_library/1      shlib Detach shared library (.so file)
 unsetenv/1                    Delete shell environment variable

 upcase_atom/2                 Convert atom to upper-case
 use_module/1                  Import a module
 use_module/2                  Import predicates from a module
 var/1                         Type check for unbound variable
 visible/1                     Ports that are visible in the tracer
 volatile/1                    Predicates that are not saved
 wait_for_input/3              Wait for input with optional timeout
 wildcard_match/2              Csh(1) style wildcard match

 win_exec/2                    Win32:  spawn Windows task
 win_has_menu/0                Win32:  true if console menu is available
 win_insert_menu/2             plwin.exe:  add menu
 win_insert_menu_item/4        plwin.exe:  add item to menu
 win_shell/2                   Win32:  open document through Shell
 win_registry_get_value/3      Win32:  get registry value
 win_window_pos/1              Win32:  change size and position of window

 window_title/2                Win32:  change title of window
 with_mutex/2                  Run goal while holding mutex
 working_directory/2           Query/change CWD
 write/1                       Write term
 write/2                       Write term to stream
 writeln/1                     Write term, followed by a newline
 write_canonical/1             Write a term with quotes, ignore operators
 write_canonical/2             Write a term with quotes, ignore operators on a stream

 write_term/2                  Write term with options
 write_term/3                  Write term with options to stream
 writef/1                      Formatted write
 writef/2                      Formatted write on stream
 writeq/1                      Write term, insert quotes
 writeq/2                      Write term, insert quotes on stream


1133..22 LLiibbrraarryy pprreeddiiccaatteess


1133..22..11 lists

 append/3        Concatenate lists
 delete/3        Delete all matching members from a list

 flatten/2       Transform nested list into flat list
 intersection/3  Set intersection
 is_set/1        Type check for a set
 list_to_set/2   Remove duplicates
 member/2        Element is member of a list
 nextto/3        Y follows X in List
 nth0/3          N-th element of a list (0-based)
 nth1/3          N-th element of a list (1-based)

 numlist/3       Create list of integers in interval
 permutation/2   Test/generate permutations of a list
 reverse/2       Inverse the order of the elements in a list
 select/3        Select element of a list
 subset/2        Check subset relation for unordered sets
 subtract/3      Delete elements that do not satisfy condition
 sumlist/2       Add all numbers in a list

 union/3         Union of two sets


1133..22..22 check

 check/0          Program completeness and consistency
 list_undefined/0 List undefined predicates

 list_autoload/0  List predicates that require autoload
 list_redefined/0 List locally redefined predicates


1133..22..33 readutil

 read_line_to_codes/2  Read line from a stream
 read_line_to_codes/3  Read line from a stream

 read_stream_to_codes/2Read contents of stream
 read_stream_to_codes/3Read contents of stream
 read_file_to_codes/3  Read contents of file
 read_file_to_terms/3  Read contents of file to Prolog terms


1133..22..44 netscape

 www_open_url/1 Open a web-page in a browser


1133..22..55 registry

 registry_get_key/2        Get principal value of key
 registry_get_key/3        Get associated value of key
 registry_set_key/2        Set principal value of key
 registry_set_key/3        Set associated value of key
 registry_delete_key/1     Remove a key
 shell_register_file_type/4Register a file-type
 shell_register_dde/6      Register DDE action
 shell_register_prolog/1   Register Prolog


1133..22..66 url

 parse_url/2       Analyse or construct a URL
 parse_url/3       Analyse or construct a relative URL

 global_url/3      Make relative URL global
 http_location/2   Analyse or construct location
 www_form_encode/2 Encode or decode form-data


1133..33 AArriitthhmmeettiicc FFuunnccttiioonnss

 */2                     Multiplication
 **/2                    Power function

 +/2                     Addition
 -/1                     Unary minus
 -/2                     Subtraction
 //2                     Division
 ///2                    Integer division
 /\/2                    Bitwise and
 <</2                    Bitwise left shift
 >>/2                    Bitwise right shift

 ./2                     List of one character:  character code
 \/1                     Bitwise negation
 \//2                    Bitwise or
 ^/2                     Power function
 abs/1                   Absolute value
 acos/1                  Inverse (arc) cosine
 asin/1                  Inverse (arc) sine

 atan/1                  Inverse (arc) tangent
 atan/2                  Rectangular to polar conversion
 ceil/1                  Smallest integer larger than arg
 ceiling/1               Smallest integer larger than arg
 cos/1                   Cosine
 cputime/0               Get CPU time
 e/0                     Mathematical constant
 exp/1                   Exponent (base e)

 float/1                 Explicitly convert to float
 float_fractional_part/1 Fractional part of a float
 float_integer_part/1    Integer part of a float
 floor/1                 Largest integer below argument
 integer/1               Round to nearest integer
 log/1                   Natural logarithm
 log10/1                 10 base logarithm

 max/2                   Maximum of two numbers
 min/2                   Minimum of two numbers
 mod/2                   Remainder of division
 random/1                Generate random number
 rem/2                   Remainder of division
 round/1                 Round to nearest integer
 truncate/1              Truncate float to integer
 pi/0                    Mathematical constant

 sign/1                  Extract sign of value
 sin/1                   Sine
 sqrt/1                  Square root
 tan/1                   Tangent
 xor/2                   Bitwise exclusive or


1133..44 OOppeerraattoorrss

 $                     1    fx   Bind toplevel variable
 ^                   200   xfy   Predicate
 ^                   200   xfy   Arithmetic function
 mod                 300   xfx   Arithmetic function
 *                   400   yfx   Arithmetic function
 /                   400   yfx   Arithmetic function
 //                  400   yfx   Arithmetic function
 <<                  400   yfx   Arithmetic function

 >>                  400   yfx   Arithmetic function
 xor                 400   yfx   Arithmetic function
 +                   500    fx   Arithmetic function
 -                   500    fx   Arithmetic function
 ?                   500    fx   XPCE: obtainer
 \                   500    fx   Arithmetic function
 +                   500   yfx   Arithmetic function

 -                   500   yfx   Arithmetic function
 /\                  500   yfx   Arithmetic function
 \/                  500   yfx   Arithmetic function
 :                   600   xfy   module:term separator
 <                   700   xfx   Predicate
 =                   700   xfx   Predicate
 =..                 700   xfx   Predicate
 =:=                 700   xfx   Predicate

 <                   700   xfx   Predicate
 ==                  700   xfx   Predicate
 =@=                 700   xfx   Predicate
 =\=                 700   xfx   Predicate
 >                   700   xfx   Predicate
 >=                  700   xfx   Predicate
 @<                  700   xfx   Predicate

 @=<                 700   xfx   Predicate
 @>                  700   xfx   Predicate
 @>=                 700   xfx   Predicate
 is                  700   xfx   Predicate
 \=                  700   xfx   Predicate
 \==                 700   xfx   Predicate
 =@=                 700   xfx   Predicate
 not                 900    fy   Predicate

 \+                  900    fy   Predicate
 ,                  1000   xfy   Predicate
 ->                 1050   xfy   Predicate
 *->                1050   xfy   Predicate
 ;                  1100   xfy   Predicate
 |                  1100   xfy   Predicate
 discontiguous      1150    fx   Predicate

 dynamic            1150    fx   Predicate
 module_transparent 1150    fx   Predicate
 meta_predicate     1150    fx   Head
 multifile          1150    fx   Predicate
 thread_local       1150    fx   Predicate
 volatile           1150    fx   Predicate
 initialization     1150    fx   Predicate
 :-                 1200    fx   Introduces a directive

 ?-                 1200    fx   Introduces a directive
 -->                1200   xfx   DCGrammar:  rewrite
 :-                 1200   xfx   head :- body.  separator


Bibliography

[Anjewierden & Wielemaker, 1989]  A.  Anjewierden  and  J.   Wielemaker.
                                  Extensible  objects.  ESPRIT   Project
                                  1098 Technical Report  UvA-C1-TR-006a,
                                  University of Amsterdam, March 1989.

[BIM, 1989]                       _B_I_M  _P_r_o_l_o_g  _r_e_l_e_a_s_e  _2_._4.   Everberg,
                                  Belgium, 1989.

[Bowen & Byrd, 1983]              D. L. Bowen and L. M. Byrd. A portable
                                  Prolog compiler.  In  L.  M.  Pereira,
                                  editor,  _P_r_o_c_e_e_d_i_n_g_s   _o_f  _t_h_e   _L_o_g_i_n
                                  _P_r_o_g_r_a_m_m_i_n_g  _W_o_r_k_s_h_o_p  _1_9_8_3,  Lisabon,
                                  Portugal, 1983.  Universidade nova  de
                                  Lisboa.

[Bratko, 1986]                    I. Bratko. _P_r_o_l_o_g _P_r_o_g_r_a_m_m_i_n_g _f_o_r  _A_r_-
                                  _t_i_f_i_c_i_a_l _I_n_t_e_l_l_i_g_e_n_c_e. Addison-Wesley,
                                  Reading, Massachusetts, 1986.

[Clocksin & Melish, 1987]         W.  F.  Clocksin  and  C.  S.  Melish.
                                  _P_r_o_g_r_a_m_m_i_n_g   _i_n  _P_r_o_l_o_g.    Springer-
                                  Verlag, New York,  Third, Revised  and
                                  Extended edition, 1987.

[Deransart _e_t _a_l_., 1996]          P.  Deransart,    A.  Ed-Dbali,    and
                                  L. Cervoni.  _P_r_o_l_o_g_:    _T_h_e  _S_t_a_n_d_a_r_d.
                                  Springer-Verlag, New York, 1996.

[Kernighan & Ritchie, 1978]       B. W. Kernighan and D. M. Ritchie. _T_h_e
                                  _C _P_r_o_g_r_a_m_m_i_n_g _L_a_n_g_u_a_g_e. Prentice-Hall,
                                  Englewood Cliffs, New Jersey, 1978.

[OKeefe, 1990]                    R. A.  OKeefe.  _T_h_e _C_r_a_f_t  _o_f  _P_r_o_l_o_g.
                                  MIT Press, Massachussetts, 1990.

[Pereira, 1986]                   F. Pereira.  _C_-_P_r_o_l_o_g  _U_s_e_r_'_s  _M_a_n_u_a_l,
                                  1986.

[Qui, 1997]                       _Q_u_i_n_t_u_s   _P_r_o_l_o_g_,   _U_s_e_r   _G_u_i_d_e   _a_n_d
                                  _R_e_f_e_r_e_n_c_e  _M_a_n_u_a_l.  Berkhamsted,   UK,
                                  1997.

[Sterling & Shapiro, 1986]        L.  Sterling  and   E.  Shapiro.   _T_h_e
                                  _A_r_t _o_f _P_r_o_l_o_g.  MIT Press,  Cambridge,
                                  Massachusetts, 1986.

[Warren, 1983]                    D.   H.  D.   Warren.    The   runtime
                                  environment  for  a  prolog   compiler
                                  using  a  copy  algorithm.   Technical
                                  Report 83/052,  SUNY and Stone  Brook,
                                  New York, 1983.  Major revision  March
                                  1984.

                                  1014


Index

'MANUAL' _l_i_b_r_a_r_y, 39                   open_shared_object/3, 699
--disable-segv-handling, 885           open_resource/3,  18,  899,   906,
-lpl _l_i_b_r_a_r_y, 886                            909
-lreadline _l_i_b_r_a_r_y, 914                open_shared_object/2, 57, 695, 699
.pl, 77                                operator
.pro, 77                                  and modules, 383
=:=/2, 398
/\/2, 427                              package
=\=/2, 397                                clib, 883
|/2, 174                               parse_url/2, 968
,/2, 172                               parse_url/3, 969
!/0, 171                               parse_url/2, 968, 969, 971
!/1, 206                               pce_call/1, 690
/, 78                                  pce_dispatch/1, 689
//2, 405                               pce_call/1, 690
./2, 413                               peek_byte/1, 310
=/2, 157                               peek_byte/2, 311
==/2, 155                              peek_char/1, 314
>=/2, 396                              peek_char/2, 315
>/2, 393                               peek_code/1, 312
^/2, 442                               peek_code/2, 313
///2, 408                              peek_byte/[1
->/2, 175                                 2], 102
=</2, 395                              peek_char/[1
<</2, 425                                 2], 102
</2, 394                               peek_code/[1
-/1, 401                                  2], 102
-/2, 403                               permutation/2, 926
\=/2, 159                              phrase/2, 207, 208
\/1, 429                               phrase/3, 207, 209
\==/2, 156                             pi/0, 443
\+/1, 177                              PL_abort_hook(), 872
\//2, 426                              PL_abort_unhook(), 873
+/2, 402                               PL_action(), 863
**/2, 441                              PL_agc_hook(), 875
>>/2, 424                              PL_atom_chars(), 728
;/2, 173                               PL_atom_nchars(), 777
*->/2, 176                             PL_call(), 829
=@=/2, 160                             PL_call_predicate(), 828
\=@=/2, 161                            PL_chars_to_term(), 816
@>=/2, 165                             PL_cleanup(), 883
@>/2, 164                              PL_close_foreign_frame(), 832
*/2, 404                               PL_close_query(), 827
@=</2, 163                             PL_compare(), 849
@</2, 162                              PL_cons_functor(), 798
=../2, 348                             PL_cons_functor_v(), 799
_PL_get_arg(), 763                     PL_cons_list(), 800
\, 78                                  PL_context(),P836L_copy_term_ref(), 712

abolish/1, 17, 211, 212                PL_create_engine(), 684
abolish/2, 212, 705                    PL_cut_query(), 826
abolish/[1                             PL_destroy_engine(), 685
   2], 57                              PL_discard_foreign_frame(), 833
abort/0,  37, 48,  57, 254,  263,      PL_dispatch_hook(), 871
      537, 671, 863, 872               PL_erase(), 854
abs/1, 409                             PL_erase_external(), 857
absolute_file_name/2, 523              PL_exception(), 843
absolute_file_name/3, 524              PL_fail(), 719
absolute_file_name/2,   28,   104,     PL_foreign_context(), 724
      115, 525, 533, 908               PL_foreign_context_address(), 725
absolute_file_name/3, 57, 59, 103,     PL_foreign_control(), 723
      112,  523,  524, 703,  858,      PL_free(), 894
      859, 954, 955                    PL_functor_arity(), 731
absolute_file_name/[2                  PL_functor_name(), 730
   3], 57, 111, 524                    PL_get_arg(), 762
access_file/2, 513                     PL_get_atom(), 749
access_file/2, 57, 524                 PL_get_atom_chars(), 750
acos/1, 435                            PL_get_atom_nchars(), 765
add_import_module/3, 632               PL_get_bool(), 756
add_import_module/3, 631               PL_get_chars(), 752
address/2, 664                         PL_get_file_name(), 859
Alpha                                  PL_get_float(), 758
   DEC, 16                             PL_get_functor(), 759
append/1, 264, 268                     PL_get_head(), 780
append/3, 365, 917                     PL_get_integer(), 754
apply/2, 181                           PL_get_list(), 779
apropos/1, 41, 42, 59, 987, 1004       PL_get_list_chars(), 753
arg/3, 346                             PL_get_list_nchars(), 766
arithmethic_function/1, 840            PL_get_long(), 755
arithmetic_function/1, 447             PL_get_module(), 761
arithmetic_function/1, 446             PL_get_name_arity(), 760
asin/1, 434                            PL_get_nchars(), 767
assert/1,  103,  110, 210,  216--      PL_get_nil(), 782
      219,  230,  234, 235,  246,      PL_get_pointer(), 757
      618, 636, 663, 993               PL_get_string_chars(), 751
assert/2, 219--221, 228, 249           PL_get_tail(), 781
asserta/1, 37, 110, 217                PL_halt(), 884
asserta/2, 220, 228                    PL_handle_signals(), 846
assertions, 948                        PL_initialise(), 879
assertz/1, 218, 993                    PL_install_readline(), 881
assertz/2, 221, 228                    PL_is_atom(), 739
assume/1, 948                          PL_is_atomic(), 746
at_end_of_stream/0, 319                PL_is_compound(), 743
at_end_of_stream/1, 320                PL_is_float(), 742
at_halt/1, 123                         PL_is_functor(), 744
at_initialization/1, 122               PL_is_initialised(), 880
at_end_of_stream/[0                    PL_is_integer(), 741
   1], 259, 950                        PL_is_list(), 745
at_halt/1,  122,  538,  645,  874,     PL_is_number(), 747
      883                              PL_is_string(), 740
at_initialization/1, 124, 879          PL_is_variable(), 738
atan/1, 436                            PL_license(), 1002
atan/2, 437                            PL_load_extensions(), 868
atom/1, 147, 735                       PL_malloc(), 892
atom_chars/2, 21, 355                  PL_module_name(), 838
atom_codes/2, 354                      PL_new_atom(), 727
atom_concat/3, 365, 1004               PL_new_atom_nchars(), 776
atom_length/2, 368                     PL_new_functor(), 729
atom_number/2, 359                     PL_new_module(), 839
atom_prefix/2, 369                     PL_new_term_ref(), 710
atom_to_term/3, 364                    PL_new_term_refs(), 711
atom_chars/2,  57, 102,  304, 353,     PL_next_solution(), 825
      357, 373                         PL_on_halt(), 874
atom_codes/2,  21,  57, 102,  353,     PL_open_foreign_frame(), 831
      355, 359, 373                    PL_open_query(), 824
atom_concat/3, 366, 381                PL_pred(), 820
atom_length/2, 57, 380                 PL_predicate(), 821
atom_to_term/3, 323                    PL_predicate_info(), 822
atomic/1, 149                          PL_put_atom(), 786
attach_console/0, 676                  PL_put_atom_chars(), 787
attach_console/0, 675, 863             PL_put_atom_nchars(), 768
autoload/0, 108, 900, 902, 940         PL_put_float(), 793

backcomp _l_i_b_r_a_r_y, 17, 21               PL_put_functor(),P794L_put_integer(), 791
bagof/3, 120, 460--462, 1004           PL_put_list(), 795
between/3, 390, 929                    PL_put_list_chars(), 790
block/3, 202, 203, 1004                PL_put_list_nchars(), 771
break/0, 37, 48, 536, 863              PL_put_list_ncodes(), 770

call/1, 21,  120, 151,  179, 181,      PL_put_nil(),P796L_put_pointer(), 792
      189, 556, 579, 581, 818          PL_put_string_chars(), 788
call/2, 180                            PL_put_string_nchars(), 769, 789
call/[2-6], 180                        PL_put_term(), 797
call_cleanup/2, 187                    PL_put_variable(), 785
call_cleanup/3, 186                    PL_query(), 865
call_shared_object_function/2, 701     PL_quote(), 817
call_with_depth_limit/3, 185           PL_raise_exception(), 841
call_cleanup/2, 186                    PL_realloc(), 893
call_cleanup/3, 186, 667               PL_record(), 852
call_cleanup/[2-3], 668                PL_record_external(), 855
call_with_depth_limit/3, 185           PL_recorded(), 853
callable/1, 151                        PL_recorded_external(), 856
catch/3,  17, 19,  188--191, 202,      PL_register_atom(), 733
      283,  339,  579, 647,  648,      PL_register_extensions(), 869
      977, 982, 1004                   PL_register_foreign(), 867
ceil/1, 423                            PL_reset_term_refs(), 713
ceiling/1, 422, 423                    PL_retry(), 721
char_code/2, 356                       PL_retry_address(), 722
char_conversion/2, 387                 PL_rewind_foreign_frame(), 834
char_type/2, 372                       PL_same_compound(), 850
char_code/2, 102                       PL_set_engine(), 686
char_conversion/2, 57, 388             PL_signal(), 845
char_type/2, 373--375                  PL_strip_module(), 837
character_count/2, 280                 PL_succeed(), 718
chdir/1, 533, 534                      PL_term_type(), 737
check  _l_i_b_r_a_r_y,  109,  246,  937,      PL_thread_at_exit(), 682
      1007                             PL_thread_attach_engine(), 680
check/0, 108, 937, 938                 PL_thread_destroy_engine(), 681
check_old_select/0, 22                 PL_thread_self(), 679
checklist/2, 464                       PL_throw(), 842
checkselect _l_i_b_r_a_r_y, 22                PL_toplevel(), 882
clause/2, 248, 249                     PL_unify(), 802
clause/3, 219, 228, 249, 251, 904      PL_unify_arg(), 814
clause/[2                              PL_unify_atom(), 803
   3], 57, 914                         PL_unify_atom_chars(), 804
clause_property/2, 251                 PL_unify_atom_nchars(), 772
clause_property/2, 115, 976            PL_unify_float(), 809
clib                                   PL_unify_functor(), 811
   package, 883                        PL_unify_integer(), 808
close/1, 252, 257                      PL_unify_list(), 812
close/2, 258                           PL_unify_list_chars(), 805
close_dde_conversation/1, 592          PL_unify_list_nchars(), 775
close_shared_object/1, 700             PL_unify_list_ncodes(), 774
code_type/2, 373                       PL_unify_nil(), 813
code_type/2, 371, 374                  PL_unify_pointer(), 810
commandline                            PL_unify_string_chars(), 806
   arguments, 37                       PL_unify_string_nchars(), 773, 807
compare/3, 166, 456, 849               PL_unify_term(), 815
compile_predicates/1, 235              PL_unregister_atom(), 734
compile_predicates/1, 234              PL_warning(), 861
compiling/0, 125, 128                  plus/3, 180, 392
completion                             PLVERSION, 895
   TAB, 83                             portray/1, 48, 59, 80, 323,  324,
compound/1, 150                              332, 334, 824, 876, 985
concat_atom/2, 366                     portray_clause/1, 139
concat_atom/3, 367                     portray_clause/2, 140
concat_atom/2, 367                     portray_clause/1, 137, 140
consult/1,  32, 35,  50, 59,  91,      portray_clause/2, 139
      103--106,  127,  128,  236,      predicate_property/2, 246
      337, 566                         predicate_property/2, 630
context_module/1, 628                  predsort/3, 456
context_module/1, 628, 824             preprocessor/2, 126
convert_time/2, 505                    print/1, 324, 332, 334, 473, 478,
convert_time/8, 504                          824, 1004
convert_time/2, 504                    print/2, 333
convert_time/8, 505                    print/[1
convert_time/[2                           2], 323
   8], 522                             print_message/2, 194, 1004
copy_stream_data/2, 322                print_message_lines/3, 195
copy_stream_data/3, 321                print_message/2, 20, 57,  59, 104,
copy_term/2, 352                             123,  193--196,  339,  642,
copy_term/2, 352                             943
cos/1, 432                             print_message_lines/3,   20,   194,
cputime/0, 445                               196
ctype _l_i_b_r_a_r_y, 371                     profile file, 35
current_arithmetic_function/1, 448     profile/1, 573, 574
current_atom/1, 240                    profile/3, 574, 914
current_char_conversion/2, 388         profiler/2, 577
current_flag/1, 242                    prolog/0, 37, 57, 536, 540,  541,
current_foreign_library/2, 706               635, 882, 978
current_format_predicate/2, 484        prolog:debug_control_hook/1,    59,
current_functor/2, 241                       986
current_input/1, 276                   prolog:help_hook/1, 59, 987
current_key/1, 243                     prolog:show_profile_hook/2, 575
current_module/1, 626                  prolog_choice_attribute/3, 977
current_module/2, 627                  prolog_current_frame/1, 975
current_mutex/3, 672                   prolog_edit:edit_command/2,     59,
current_op/3, 385                            135
current_output/1, 277                  prolog_edit:edit_source/1, 59, 134
current_predicate/1, 245               prolog_edit:load/0, 136
current_predicate/2, 244               prolog_edit:locate/2, 133
current_prolog_flag/2, 57              prolog_edit:locate/3, 59, 132
current_signal/3, 200                  prolog_file_type/2, 113
current_stream/3, 21, 260              prolog_frame_attribute/3, 976
current_thread/2, 648                  prolog_ide _c_l_a_s_s, 98
current_atom/1, 240                    prolog_ide/1, 98
current_char_conversion/2, 387         prolog_list_goal/1, 59, 985
current_input/1, 116, 269              prolog_load_context/2, 116
current_output/1, 270                  prolog_load_file/2, 59
current_predicate/1, 245               prolog_skip_level/2, 981
current_predicate/2, 245               prolog_to_os_filename/2, 528
current_prolog_flag/2, 21, 37, 56,     prolog_trace_interception/4,    59,
      57,  60, 64, 67,  102, 104,            980
      154,  191,  194, 323,  328,      prolog_choice_attribute/3, 980
      339,  540,  566, 597,  695,      prolog_current_frame/1, 976
      707,  817,  877, 886,  915,      prolog_edit:edit_source/1,  82, 99,
      993                                    130
current_signal/3, 199                  prolog_edit:locate/3,  129,   130,
current_stream/3, 260                        133, 134
current_thread/2,  642, 643,  645,     prolog_file_type/2, 103, 113, 524
      648                              prolog_frame_attribute/3, 251, 980
DCG, 103, 207                          prolog_frame_attribute/4,p980rolog_ide/1, 97
dde_current_connection/2, 600          prolog_load_context/2, 117
dde_current_service/2, 599             prolog_load_file/2, 104, 988
dde_execute/2, 594                     prolog_to_os_filename/2, 78, 525
dde_poke/4, 595                        prolog_trace_interception/4,    92,
dde_register_service/2, 597                  552, 976, 977
dde_request/3, 593                     prompt/2, 341--343
dde_unregister_service/1, 598          prompt1/1, 343
debug _l_i_b_r_a_r_y, 942                     protocol/1, 544, 545, 547
debug/0, 48, 191,  555, 557, 558,      protocola/1, 545, 547
      863                              protocolling/1, 547
debug/1, 943, 945, 946                 prove/3, 84
debug/3, 942, 943                      put/1, 287, 289, 291, 293
debugging                              put/2, 288, 290, 292, 294
   exceptions, 191                     put_byte/1, 289
debugging/0,  59, 555,  559, 947,      put_byte/2, 290
      986                              put_char/1, 291
debugging/1, 942, 944                  put_char/2, 292
DEC                                    put_code/1, 293
   Alpha, 16                           put_code/2, 294
default_module/2, 634                  put_byte/[1
delete/3, 920                             2], 102
delete_directory/1, 532                put_char/[1
delete_file/1, 519                        2], 102
delete_import_module/2, 633            put_code/[1
delete_import_module/2, 631, 632          2], 102
deterministic/1, 978
Development environment, 74            qcompile/1, 104, 125, 127, 128
discontiguous/1, 233, 237              qsave_program/1, 901
display/1, 473, 783                    qsave_program/2, 900
display/[1                             qsave_program/2, 14,  55, 57,  80,
   2], 17                                    97, 899, 900, 906
displayq/1, 478                        qsave_program/[1
displayq/[1                               2], 13,  18, 37, 54, 57,  124,
   2], 17                                    246,  696, 879,  888,  902,
downcase_atom/2, 375                         904
downcase_atom/2, 372, 376              quiet, 37, 194
dup/2, 21                              quintus _l_i_b_r_a_r_y, 21, 625, 637
dup_stream/2, 21
dup_stream/2, 21                       random/1, 414
dwim_match/2, 602                      read/1, 57,  72, 254,  297,  330,
dwim_match/3, 603                            335,  337, 339,  342,  377,
dwim_predicate/2, 247                        566, 955, 1004
dwim_match/2, 247, 603                 read/2, 279, 336
dynamic/1,  57,   210,  233--235,      read_clause/1, 337
      246, 624, 662, 663, 939          read_clause/2, 338

e/0, 444                               read_file_to_codes/3,r954ead_file_to_terms/3, 955
edit/0, 131                            read_history/6, 341
edit/1, 23,  57, 59, 83,  86, 91,      read_line_to_codes/2, 950
      99,   109,  129--132,  134,      read_line_to_codes/3, 951
      939, 1004                        read_link/3, 529
edit_source/1, 135                     read_stream_to_codes/2, 952
editor _c_l_a_s_s, 82, 87                   read_stream_to_codes/3, 953
Emacs, 38                              read_term/2, 339
emacs/[0                               read_term/3, 340
   1], 86                              read_clause/1, 338, 566
emacs/prolog_colour _l_i_b_r_a_r_y, 90        read_history/6, 341
emacs/swi_prolog _l_i_b_r_a_r_y, 23           read_line_to_codes/2, 951
ensure_loaded/1, 106                   read_line_to_codes/3, 950
ensure_loaded/1,   50,  103,  106,     read_stream_to_codes/2, 953
      612                              read_term/2,  46,  57,  337,  340,
erase/1, 219, 222, 228, 249                  341, 364
eval_license/0, 999                    read_term/3, 339, 387, 541
eval_license/0, 998                    read_term/[2
exception/3, 59, 982, 983                 3], 339
exceptions                             readutil _l_i_b_r_a_r_y, 81, 949, 1008
   debugging, 191                      reconsult/1, 103
exists_directory/1, 518                recorda/2, 223
exists_file/1, 514                     recorda/3, 222,  224,  228,  243,
exists_file/1, 57                            851, 852, 855
exit/2, 203, 204                       recorded/2, 227
exp/1, 400, 440                        recorded/3, 226, 228, 904
expand_answer/2, 542                   recordz/2, 225
expand_file_name/2, 527                recordz/3, 224
expand_file_search_path/2, 112         redefine_system_predicate/1, 213
expand_goal/2, 121                     redefine_system_predicate/1,    11,
expand_query/4, 541                          993
expand_term/2, 119                     registry, 70
expand_answer/2, 541                   registry _l_i_b_r_a_r_y, 958, 1010
expand_file_name/2, 57,  499, 501,     registry_delete_key/1, 963
      523, 524                         registry_get_key/2, 959
expand_goal/2, 57, 118, 120            registry_get_key/3, 960
expand_term/2, 118, 120, 207           registry_set_key/2, 961
explain _l_i_b_r_a_r_y, 1004                  registry_set_key/3, 962
explain/1, 43                          reload_library_index/0, 63
explain/2, 44                          reload_library_index/0, 63
export/1, 621, 629                     rem/2, 407
export_list/2, 630                     rename_file/2, 520

fail/0, 168                            repeat/0,r170,e185quire/1, 108, 902
fail/1, 205                            reset_profiler/0, 578
feature/2, 21                          reset_profiler/0, 574
file_base_name/2, 516                  resource/3, 18, 57, 59, 899, 900,
file_directory_name/2, 515                   906, 908, 909
file_name_extension/3, 526             retract/1, 103,  110,  210,  211,
file_search_path/2, 59, 111                  214,  230, 234,  235,  246,
file_search_path/2,  35,  37,  57,           636, 663
      60,  63, 79, 105, 111, 113,      retractall/1, 210, 211, 215
      703,  859,  888, 905,  908,      reverse/2, 610, 925
      911                              RFC-1738, 967
fileerrors/2, 57, 283                  rl_add_history/1, 992
findall/3, 120, 460, 636               rl_read_init_file/1, 991
flag/3, 57, 229, 242                   rlimit _l_i_b_r_a_r_y, 25
flatten/2, 927                         round/1, 415, 416
float/1, 145, 399, 417
float_fractional_part/1, 418           same_file/2, 517
float_integer_part/1, 419              see/1, 20, 252, 254, 264--266
float_integer_part/1, 420              seeing/1, 264, 265, 269
floor/1, 421                           seek/4, 259, 261, 262
flush_output/0, 297                    seen/0, 271
flush_output/1, 298                    select/3, 22, 921
flush_output/0, 297                    set_feature/2, 21
flush_output/1, 195                    set_input/1, 274
flush_output/[0                        set_output/1, 275
   1], 254, 299                        set_prolog_flag/2, 58
foo/0, 993                             set_stream/2, 263
foo/3, 993                             set_stream_position/2, 261
forall/2, 120, 468                     set_tty/2, 489
format/1, 195, 477                     set_feature/2, 21
format/2, 478--480, 943                set_input/1, 263, 266
format/3, 195, 479                     set_output/1, 267
format/[1                              set_prolog_flag/2, 21, 45, 56, 389
   2], 57, 323, 469, 1004              set_stream/2, 254, 279
format/[2                              set_stream_position/2, 259, 262
   3], 67                              setarg/3, 347, 352
format_predicate/2, 483                setenv/2, 499
free_variables/2, 351                  setof/3, 120, 462, 1004
free_variables/2, 339                  sformat/2, 481
FTP, 967                               sformat/3, 323, 480
functor/3, 6, 150, 151, 345            shell/0, 494, 501

garbage_collect/0, 584                 shell/1,s78,h135,e493,l501l/2, 492
garbage_collect_atoms/0, 585           shell/[0-2], 499
garbage_collect_atoms/0, 585, 875      shell/[1
gensym/2, 605                             2], 492
get/1, 308                             shell_register_dde/6, 965
get/2, 309                             shell_register_file_type/4, 964
get0/1, 254, 306, 316, 318             shell_register_prolog/1, 966
get0/2, 307                            shell_register_file_type/4, 965
get_byte/1, 300                        shlib _l_i_b_r_a_r_y, 1004
get_byte/2, 301                        show_profile/1, 576
get_char/1, 304                        show_profile/2, 575
get_char/2, 305                        show_profile/1, 574
get_code/1, 302                        sign/1, 410
get_code/2, 303                        silent, 194
get_single_char/1, 318                 sin/1, 400, 431
get_time/1, 503                        size_file/2, 521
get_byte/1, 306, 310                   skip/1, 316, 317
get_byte/2, 305, 307, 311              skip/2, 317
get_byte/[1                            sleep/1, 606
   2], 102                             socket _l_i_b_r_a_r_y, 279
get_char/1, 302, 314                   Solaris, 646
get_char/2, 305, 315                   sort/2, 453, 454, 456, 462, 932
get_char/[1                            source_file/1, 114
   2], 102                             source_file/2, 115
get_code/1, 312                        source_location/2, 117
get_code/2, 305, 313                   source_file/2, 128, 246
get_code/[1                            source_file/[1
   2], 102                                2], 627
get_single_char/1, 37, 57              source_location/2, 116
get_time/1, 504, 505, 522              spy/1, 48,  57, 59,  93, 94,  99,
getenv/1, 957                                560, 986, 1004
getenv/2, 498, 499                     sqrt/1, 430
global_url/3, 970                      stack
GNU-Emacs, 38                             memory management, 71
go/0, 36                               stack_parameter/4, 588
goal_expansion/2, 59, 120              startup file, 35
goal_expansion/2,  103, 118,  120,     statistics _l_i_b_r_a_r_y, 571
      121, 942                         statistics/0, 569
Graphics, 8                            statistics/2, 445, 568, 649
ground/1, 152, 232                     stream_property/2, 259
GUI, 8                                 stream_property/2, 261--263, 339
guitracer/0, 23, 93--95, 99, 548,      string/1, 148, 478
      552                              string_concat/3, 381

halt/0, 48, 538, 539                   string_length/2, 380
halt/1, 539, 863, 1004                 string_to_atom/2, 378
halt/[0                                string_to_list/2, 379
   1], 123                             string_concat/3, 365
hash_term/2, 232                       style_check/1, 566
hash_term/2, 231                       style_check/1, 72, 73, 237, 993
help/0, 40, 59, 906, 987               sub_atom/5, 370
help/1, 39--41, 57, 59, 987            sub_string/5, 382
helpidx _l_i_b_r_a_r_y, 39                    sub_atom/5, 382
hooks, 59                              sublist/3, 466
HTTP, 967                              subset/2, 936
http_load _l_i_b_r_a_r_y, 104, 989            subtract/3, 934
http_location/2, 971                   succ/2,s391umlist/2, 928

IDE, 74                                swi/pce_profile _l_i_b_r_a_r_y, 571
ignore/1, 120, 184, 579                swi_edit _l_i_b_r_a_r_y, 136
immediate                              swi_help _l_i_b_r_a_r_y, 39
   update view, 230                    swritef/2, 475
import/1, 611, 614, 621                swritef/3, 474
import_module/2, 631
import_module/2, 632, 634              TAB
include/1, 103, 107                       completion, 83
include/2, 104                         tab/1, 295
index/1, 231, 238, 246                 tab/2, 296
initialization/1, 124,  696, 869,      tan/1, 433
      904                              tell/1, 20, 252,  254, 264,  265,
install/0, 905                               267, 268
int_to_atom/2, 362                     telling/1, 264, 265, 270
int_to_atom/3, 361                     term_expansion/2, 59, 118
integer/1, 144, 416                    term_to_atom/2, 363
interactor/0, 263, 675                 term_expansion/2,  59, 103,  118--
intersection/3, 933                          120, 125, 128, 541
is/2, 57, 399, 417, 447, 928           term_to_atom/2, 323, 816
is_absolute_file_name/1, 525           thread_at_exit/1, 645
is_list/1, 450                         thread_create/3, 640
is_set/1, 931                          thread_detach/1, 643
is_list/1, 931                         thread_exit/1,t644hread_get_message/1, 654
keysort/2, 455, 456                    thread_get_message/2,t658,h659read_join/2, 642

last/2, 924                            thread_local/1, 663
leash/1, 48, 563, 564, 980             thread_peek_message/1, 655
length/2, 452                          thread_self/1, 641
library_directory/1, 59, 110           thread_send_message/2, 653
library_directory/1, 60, 105           thread_setconcurrency/2, 646
library_directory/2, 63                thread_signal/2, 661
license/1, 1001                        thread_statistics/3, 649
license/2, 1000, 1001                  thread_at_exit/1, 682
likes/2, 32                            thread_create/3, 643, 689
limit_stack/2, 586                     thread_detach/1, 640
limit_stack/2, 583                     thread_exit/1, 642, 648
line_count/2, 281                      thread_get_message/1, 658, 659
line_position/2, 282                   thread_join/2, 640, 642, 644, 648
line_count/2, 263, 487                 thread_local/1, 234, 246, 662
line_position/2, 263, 487              thread_peek_message/1, 654
list_autoload/0, 940                   thread_self/1, 57, 643, 645, 653
list_debug_topics/0, 947               thread_send_message/2, 656
list_redefined/0, 941                  thread_signal/2, 661, 671
list_to_set/2, 932                     threads/0, 674
list_undefined/0, 939                  throw/1, 17,  48, 188--190,  202,
list_autoload/0, 938, 939                    537,  648, 660,  661,  841,
list_debug_topics/0, 942                     843, 982
list_redefined/0, 938                  time/1, 445, 570, 573, 574
list_undefined/0, 109, 938, 940        time_file/2, 522
listing/0, 138                         time_file/2, 502, 504
listing/1, 48, 137, 138                tmp_file/2, 530
lists _l_i_b_r_a_r_y, 449, 916, 1006          told/0, 272
load_files/2, 104, 1004                trace/0, 48,  93,  94,  99,  549,
load_foreign_library/1, 704                  555, 661, 863
load_foreign_library/2, 703            trace/1, 57, 554
load_files/1, 59                       trace/2, 555
load_files/2,  59, 104,  105, 988,     tracing/0, 550
      989                              trim_stacks/0, 587
load_foreign_library/1, 886, 905       trim_stacks/0, 57, 583, 584
load_foreign_library/2, 704            true/0, 57, 169, 185
load_foreign_library/[1                truncate/1, 420
   2], 111, 698                        tty_get_capability/3, 486
log/1, 438                             tty_goto/2, 487
log10/1, 439                           tty_put/2, 488
logical                                tty_size/2, 490
   update view, 230                    tty_get_capability/2,t490ty_get_capability/3, 488

MacOS X, 7                             tty_goto/2, 489
main/0, 55                             tty_put/2, 489
make/0,  7, 60,  63, 84,  91, 99,      tty_size/2, 490
      109                              ttyflush/0, 299, 473
make_directory/1, 531
make_library_index/1, 61               unify_with_occurs_check/2, 158
make_library_index/2, 62               union/3, 935
make_library_index/1, 60               Unix, 7
make_library_index/2, 60               unix, 57
make_library_index/[1                  unix/1, 21, 501
   2], 63                              unknown/2, 60, 565, 621, 915
manpce/0, 70                           unload_foreign_library/1, 705
maplist/3, 465, 619, 902               unsetenv/1, 500
max/2, 411                             upcase_atom/2, 376
member/2, 48, 186, 250, 451, 524,      upcase_atom/2, 372
      918, 921, 1004                   update view, 230
memberchk/2, 451                       URL, 496
memory                                 url _l_i_b_r_a_r_y, 956, 967, 1011
   layout, 71                          use_module/1, 612
merge/3, 457                           use_module/2, 613
merge_set/3, 458                       use_module/1, 59, 79
message_hook/3, 59, 196                use_module/2, 60
message_queue_create/1, 656            use_module/[1
message_queue_destroy/1, 657              2],  50, 91,  103,  104,  106,
message_to_string/2, 197                     611, 614, 616, 629, 993
message_hook/3, 20, 193--195           user _l_i_b_r_a_r_y, 1004
message_queue_create/1, 657            user profile file, 35
message_queue_create/2, 652            user:prolog_load_file/2, 989
message_to_string/2, 194, 196          utf-8, 102
meta_predicate/1, 625, 637
meta_predicate/1, 636, 637             var/1, 12, 142, 735
min/2, 412                             verbose, 37
mod/2, 406                             visible/1, 564, 980
module/1, 635                          volatile/1, 246, 663, 903
module/2, 118, 610, 623, 629
module_transparent/1, 624              wait_for_input/3, 279
module_transparent/1,   246,  636,     wait_for_input/3, 263, 279
      824, 993                         wildcard_match/2, 604
msort/2, 454, 455                      win_exec/2, 495
multi_file/1, 993                      win_has_menu/0, 509
multifile/1, 129,  233, 236, 246,      win_insert_menu/2, 510
      939, 985                         win_insert_menu_item/4, 511
mutex_create/1, 665                    win_registry_get_value/3, 497
mutex_destroy/1, 666                   win_shell/2, 496
mutex_lock/1, 668                      win_window_pos/1, 508
mutex_statistics/0, 650                win_exec/2, 492
mutex_trylock/1, 669                   win_insert_menu/2, 509, 511
mutex_unlock/1, 670                    win_insert_menu_item/4, 509
mutex_unlock_all/0, 671                win_shell/2, 492, 957
mutex_create/1, 668                    Window interface, 8
mutex_create/2, 667                    window_title/2, 507
mutex_lock/1, 669                      Windows,w7indows, 57

name/2, 353, 360                       with_mutex/2, 667
netmask/4, 877                         with_mutex/2, 668, 677
netscape _l_i_b_r_a_r_y, 956, 1009            working_directory/2, 533
nextto/3, 919                          working_directory/2,   501,   524,
nl/0, 285                                    534
nl/1, 286                              write/1, 57, 328, 332, 363,  368,
nl/[0                                        473, 478, 752, 783
   1], 473                             write/2, 329
nodebug/0, 558                         write_canonical/1, 326
nodebug/1, 945, 946                    write_canonical/2, 327
noguitracer/0, 93, 95, 99, 553         write_term/2, 324
nonvar/1, 143                          write_term/3, 325
noprofile/1, 579                       write_canonical/[1
noprotocol/0, 546                         2], 17
nospy/1, 48, 59, 561, 986              write_term/2, 48,  57, 158,  324--
nospyall/0, 59, 562, 986                     326, 377, 473, 478
not/1, 120, 182, 1004                  write_term/3, 59, 349
notrace/0, 551                         write_term/[2
notrace/1, 556                            3], 17, 57
nth0/3, 922                            writef/1, 472
nth1/3, 923                            writef/2, 28, 67, 323, 473, 474
nth_clause/3, 250                      writef/[1
nth_clause/3, 251, 976                    2], 469
number/1, 146, 928                     writeln/1, 471
number_chars/2, 21, 357                writeq/1, 330, 473, 478
number_codes/2, 358                    writeq/2, 331
number_chars/2, 21, 102, 358           www_form_encode/2, 972
number_codes/2, 21, 102, 353, 359      www_open_url/1, 957
numbervars/3, 349, 350                 www_open_url/1, 957
numbervars/4, 349, 350                 X-Windows, 7
numlist/3, 929                         X11, 8

on_signal/3, 199                       xor/2, 428
on_signal/3, 19, 199, 200              XPCE, 8
once/1, 120, 183,  184, 186, 199,
      556, 570, 667, 829
online_help _l_i_b_r_a_r_y, 1004
onsult/1, 105
op/3, 21, 101, 233, 324, 384, 385
open/3, 57, 252, 253, 255
open/4, 13,  102, 254,  255, 259,
      263, 320, 954, 955
open_dde_conversation/3, 591
open_null_stream/1, 256
open_resource/3, 909
open_shared_object/2, 698

                                  1015
