
                    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 33..11

                        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 _3_._1_._0_, _J_u_l_y _1_9_9_8

                         _J_a_n _W_i_e_l_e_m_a_k_e_r

                       jan@swi.psy.uva.nl

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

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

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

SWI-Prolog  is based  on  a very  restricted  form  of the  WAM  (Warren
Abstract Machine) described  in [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, |//22),  if-then
(->//22) and not (\+//11).

This manual  does not  describe the  full syntax and  semantics of  SWI-
Prolog, nor how  one should write a program  in Prolog.  These  subjects
have been described extensively in the literature.   See [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].


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

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

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

11..33 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 standard  Unix editors  are  provided, as  well as  a
    facility to maintain programs (see mmaakkee//00).

  o _V_e_r_y _f_a_s_t _c_o_m_p_i_l_e_r
    The  compiler handles  about  100K bytes  per second  on a  SPARC-II
    processor.

  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,  assert to  or retract  from 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  allows  for   easy  and  flexible  integration  with  C,
    both  Prolog calling  C functions  as C  calling Prolog  predicates.
    SWI-Prolog  is provided  in source  form,  which implies  SWI-Prolog
    can  be linked in  with another package.   Command line options  and
    predicates  to obtain information from the system and  feedback into
    the system are provided.

  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 and Win32 (Windows 95 and NT).


11..44 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(Self, send_super, 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"::
        (   term_to_atom(Term, From)
        ->  get(Self, member, view, V),
            pce_open(V, write, Fd),
            set_output(Fd),
            listing(Term),
            close(Fd)
        ;   send(Self, report, error, 'Syntax error')
        ).

:- pce_end_class.

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

The  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  and
Windows NT. It has been connected to SWI-Prolog, SICStustm and Quintustm
Prolog as well  as some Lisp dialects and  C++.  The Quintus version  is
commercially distributed and supported as ProWindows-3tm.

IInnffoo.. further        information        is         available        from
http://www.swi.psy.uva.nl/projects/xpce/home.html   or  by   E-mail   to
xpce-request@swi.psy.uva.nl.   There is  a demo  version for Windows  95
and  NT  in  ftp://swi.psy.uva.nl/pub/xpce/Windows/bin/,   and  one  for
the  i386/Linux  system in  ftp://swi.psy.uva.nl/pub/xpce/linux.     For
information  on  ProWindows-3,  please  see  http://www.aiil.co.uk,   or
contact sales@aiil.co.uk.


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

There are not many  changes between version 1.4 and 1.5.   The C-sources
have been  cleaned and  comments have been  updated.   The stack  memory
management based on  using the MMU has been  changed to run on a  number
of System-V  Unix systems offering  shared memory.   Handling dates  has
been  changed.   All  functions  handling dates  now return  a  floating
point number,  expressing the  time in  seconds since  January 1,  1970.
A predicate  ccoonnvveerrtt__ttiimmee//88 is available to  get the  year, month,  etc.
The predicate  ttiimmee//66 has  been deleted.   ggeett__ttiimmee//11 and ccoonnvveerrtt__ttiimmee//88
together do the same.

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

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

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

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

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

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

Version  1.7  integrates the  GNU-readline  library,  offering  powerful
history and command-line editing both using Emacs and vi key-bindings.


11..88 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..99 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 :- 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//11directive.

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

  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..1100 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

Version 2.0 is  first of all a freeze  of all the features added to  the
various 1.9.x releases.  Version 2.0.6 for PC has  moved from the WATCOM
C  32-bit windows  extender to  Windows NT  and runs  under Windows  3.1
using the Win32s NT emulator.

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 vvaarr//1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.

Version 2.0.6 offers a few incompatibilities:

  o rreettrraaccttaallll//11
    In previous releases, the definition of rreettrraaccttaallll//11 was:

    retractall(Term) :-
            retract(Term),
            fail.
    retractall(_).

    As   from  version   2.0.6,   rreettrraaccttaallll//11  is   implemented  as   a
    deterministic foreign predicate  compatible with Quintus Prolog.  It
    behaves as:

    retractall(Head) :-
            retract(Head),
            fail.
    retractall(Head) :-
            retract((Head :- _)),
            fail.
    retractall(_).

    I.e.  the  definition  behaves  the same  when  handling  predicates
    consisting  of  facts.     Clauses with  a  non-true  body  will  be
    retracted if their head matches.

  o _F_o_r_e_i_g_n _i_n_t_e_r_f_a_c_e _t_y_p_e_s
    All  foreign interface types now  have names ending in  _t to  lessen
    the  chance for conflicts.   term, atomic,  functor and module  have
    #define's for backward compatibility.

  o PPLL__rreeggiisstteerr__ffoorreeiiggnn(())
    The  attributes is now  a bitwise or  of the attribute flags  rather
    than  a 0 terminated list.  This has no consequences  for predicates
    that  have no attributes (99%  of them), while predicates with  just
    one  attribute will generate a  compiler warning, but work  properly
    otherwise.     Predicates with  more  than  one attributes  must  be
    changed.

  o PL_dispatch_events
    This  pointer  is replaced  by PPLL__ddiissppaattcchh__hhooookk(()).    A function  was
    necessary for the Win32 .DLL interface.


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

In addition  to several  bug fixes,  the 2.1 versions  provide some  new
features:

  o sseettaarrgg//33
    A new  predicate sseettaarrgg//33 for extra-logical (destructive) assignment
    to arguments of terms is provided.

  o _M_o_d_i_f_i_e_d kkeeyyssoorrtt//22
    kkeeyyssoorrtt//22  is now stable with regard to multiple values on  the same
    key.  Makes this predicate compatible with SICStus and Quintus.

  o _M_o_d_i_f_i_e_d _g_r_a_m_m_a_r _r_u_l_e _e_x_p_a_n_s_i_o_n
    DCG  translation of  free variables  now calls  pphhrraassee//33, which  has
    been  changed slightly to deal  with `un-parsing'.  Modification  is
    probably  not complete,  but it fixes  some problems encountered  by
    Michael B"ohlen.

  o _E_x_c_e_p_t_i_o_n _h_a_n_d_l_i_n_g
    The  top of the runtime  stack are automatically dumped on  floating
    point exceptions.

  o _F_o_r_e_i_g_n _i_n_t_e_r_f_a_c_e
    Added   facilities  to   allow   for  embedding   SWI-Prolog  in   C
    applications.


11..1122 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.

According  to the  current plan,  ISO compliant  exception handling  and
hooks for source-code debugging will be added before the  system will be
called 3.0.

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:     ooppeenn//4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  qqssaavvee__pprrooggrraamm//[[11,,22]] allows  for  the   creating  of
    machine independent saved-states that load very quickly.


11..1133 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 qqssaavvee__pprrooggrraamm//22.


11..1144 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 should  be
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..1155 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

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

11..1166 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 ccaattcchh//33, tthhrrooww//11,  aabboolliisshh//11, wwrriittee__tteerrmm//[[22,,33]], wwrriittee__ccaannoonniiccaall//[[11,,22]]
and  the  C-functions PPLL__eexxcceeppttiioonn(()) and  PPLL__tthhrrooww(()).    The  predicates
ddiissppllaayy//[[11,,22]] and ddiissppllaayyqq//[[11,,22]]  have been moved to  library(backcomp),
so old code referring to them will autoload them.

The interface  to PPLL__ooppeenn__qquueerryy(()) 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..1177 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  rreessoouurrccee//33, ooppeenn__rreessoouurrccee//33,
and qqssaavvee__pprrooggrraamm//[[11,,22]].


11..1188 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 oonn__ssiiggnnaall//33 and  PPLL__ssiiggnnaall(())).    Prolog stack  overflows now  raise
the resource_error  exception and thus  can be handled  in Prolog  using
ccaattcchh//33.


11..1199 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 wwrriitteeff//22.    Also some  of the  C-code originates  from
C-Prolog:  finding the path of the currently running  executable and the
code underlying  aabbssoolluuttee__ffiillee__nnaammee//2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 SSttaarrttiinngg SSWWII--PPrroolloogg ffrroomm tthhee UUnniixx SShheellll

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

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

22..11..11 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 feature(arch, Arch)) and exits.

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

--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
    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.    The  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.

--HH_s_i_z_e_[_k_m_]
    Give  mmaalllloocc(()) heap limit.   The  default is to  raise the limit  as
    high  as possible.  This  option only applies to machines using  the
    mmmmaapp(())  function for allocating the Prolog stacks.  See -L  for more
    details.

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

--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 pplleeaassee//33.

--ff _f_i_l_e
    Use  _f_i_l_e as  initialisation  file instead  of `.plrc'.    `-f none'
    stops SWI-Prolog from searching for an initialisation file.

--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
    pprroolloogg//0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
    bbrreeaakk//00  and aabboorrtt//0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
    Switches  tty  control (using  ioctl(2)) on  (+tty)  or off  (-tty).
    Normally  tty  control is  switched on.    This  default depends  on
    the  installation.    You may  wish  to switch  tty control  off  if
    Prolog  is used  from an  editor such  as Emacs.    If switched  off
    ggeett__ssiinnggllee__cchhaarr//11and the tracer will wait for a return.

--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 qqssaavvee__pprrooggrraamm//[[11,,22]].

--rr _r_e_s_t_o_r_e_f_i_l_e
    Restore  a state  created by ssaavvee__pprrooggrraamm//[[11,,22]] or ssaavvee//[[11,,22]]  using
    the  new-style  saved-states.   Equivalent  to  restore(restorefile)
    from Prolog.

--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 : separated  list of  values for  the
    alias.    A  value is  either a  term of  the  form alias(value)  or
    pathname.    The  computed  aliases are  added to  ffiillee__sseeaarrcchh__ppaatthh//22
    using  aasssseerrttaa//11, so they precede  predefined values for the  alias.
    See  ffiillee__sseeaarrcchh__ppaatthh//2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.

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..22 GGNNUU EEmmaaccss IInntteerrffaaccee

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

22..33 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 library('MANUAL').  The file
library(helpidx) provides  an index into this  file.   library('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 library(swi_help), presenting  the
information from  the online help  in a hypertext window.   The  feature
write_help_with_overstrike  controls whether  or  not hheellpp//11  writes  its
output using  overstrike to realise bold  and underlined output or  not.
If this  feature 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 ~/.plrc.

:- set_feature(write_help_with_overstrike, true).


hheellpp
    Equivalent to help(hheellpp//1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
                         aapprrooppooss//1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
                            PPLL__rreettrryy(())


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..44 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 sseett__ffeeaattuurree//22, using the history feature.   By default,
history is available if  the feature readline is false.  To  enable this
feature, remembering the  last 50 commands, put the following  into your
~/.plrc file:

:- set_feature(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.   Figure  2.1
gives some examples.
       __________________________________________________________
       | !!.            |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> of 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

/staff/jan/.plrc consulted, 0.066667 seconds, 591 bytes
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 ?- append("Hello ", "World", L).

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

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

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

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

L = [3]

Yes
4 ?- ^integer^number.

sublist(number, [3, f, 3.4], L).

L = [3, 3.400000]

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

    3   sublist(integer, [3, f, 3.4], L).
    4   sublist(number, [3, f, 3.4], L).

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

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

Yes
6 ?- halt.

           Figure 2.1:  Some examples of the history facility


22..44..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

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

After this initial parsing  the result is first checked for  the special
^<_o_l_d>^<_n_e_w>.construction.  If this fails the string is  checked for all
occurrences of  the !,  followed by  a !,  ?, a  digit, a  letter or  an
underscore.   These special sequences  are analysed and the  appropriate
substitution from the history list is made.

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

22..55 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]

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

                 Figure 2.2:  Reusing toplevel bindings

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

6 ?- X = statistics.

X = statistics

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


22..66 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 tthhrrooww//11 or one
of the built-in predicates.  See section 3.8.

The standard  ports are called call,  exit, redo, fail  and unify.   The
tracer is started  by the ttrraaccee//00 command,  when a spy point is  reached
and the system is  in debugging mode (see ssppyy//11 and ddeebbuugg//00) or  when an
exception is raised.

The interactive  toplevel goal ttrraaccee//0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  wwrriittee__tteerrmm//22.    The  style can  be  modified to  include  the
ignore_ops and/or portray options using the w, p or d command.
Yes
2 ?- visible(+all), leash(-exit).

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

  Exit:  ( 4) min([2], 2)
  Call:  ( 4) min(3, 2, G235) ? creep
  Unify: ( 4) min(3, 2, G235)
  Call:  ( 5) 3 < 2 ? creep
  Fail:  ( 5) 3 < 2 ? creep
  Redo:  ( 4) min(3, 2, G235) ? creep
  Exit:  ( 4) min(3, 2, 2)
  Exit:  ( 3) min([3, 2], 2)

                       Figure 2.3:  Example trace

On _l_e_a_s_h_e_d  _p_o_r_t_s (set  with the  predicate lleeaasshh//1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 ssppyy//11) on the current predicate.

- ((NNoo ssppyy))
    Remove the spy point (see nnoossppyy//1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  mmeemmbbeerr//22.
                             This is equivalent to setting a spy
                             point on mmeemmbbeerr//2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 4).  Default is off.

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

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

b ((BBrreeaakk))
    Enter a Prolog break environment (see bbrreeaakk//0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))
    Write goals using ignore_ops option.

e ((EExxiitt))
    Terminate Prolog (see hhaalltt//0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))
    Write goals using the portray option (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))
    Write goals without using the portray option.

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 (ddeebbuugg//00) choice  points are only destroyed  when
removed by  the cut.    In debug  mode, tail  recursion optimisation  is
switched off.


22..77 CCoommppiillaattiioonn


22..77..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
ccoonnssuulltt//11, or the list  abreviation.  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 uussee__mmoodduullee//[[11,,22]]  or eennssuurree__llooaaddeedd//1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..77..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..77..22..11 CCrreeaattiinngg aa sshheellll--ssccrriipptt

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 :-
        unix(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..77..22..22 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 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 qqssaavvee__pprrooggrraamm//[[11,,2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,
exectable.  This process is descriped in chapter 6.


22..77..22..33 CCoommppiilli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 is mostly  for backward compatibility.  It  creates files
in the  same format  as saved-states created  using qqssaavvee__pprrooggrraamm//[[11,,22]],
but  the resulting  file  is a  translation  of the  source-files  read,
rather than  a translation of the  state of the  machine.  Unlike  saved
states, programs  created using -c file do  not include the Prolog  part
of the development  system.  The result  is very dependent on the  local
SWI-Prolog installation.

The command below is used to compile one or more source-files.

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

The individual source  files may include other files using  the standard
list notation,  ccoonnssuulltt//11,  eennssuurree__llooaaddeedd//11and  uussee__mmoodduullee//[[11,,22]].    When
the -o file option is  omitted a file named a.out is created  that holds
the intermediate code file.

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

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

Alternatively, my_program can be started with

% pl -x my_program [options]

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

  o tteerrmm__eexxppaannssiioonn//22 should  not  use aasssseerrtt//11  and or  rreettrraacctt//11  other
    than for local computational purposes.

  o Files  can  only be  included by  the  standard include  directives:
    [...],   ccoonnssuulltt//11,  eennssuurree__llooaaddeedd//11 and  uussee__mmoodduullee//[[11,,22]].     User
    defined loading predicate invocations will not be compiled.

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

22..88 EEnnvviirroonnmmeenntt CCoonnttrrooll

The current  system defines 3 different  mechanisms to query and/or  set
properties  of the  environment:    pplleeaassee//33,  ffllaagg//33 and  ffeeaattuurree//22  as
well  as a  number of  special purpose  predicates  of which  uunnkknnoowwnn//22,
ffiilleeeerrrroorrss//22 are examples.  The ISO standard defines prolog_flag.  It is
likely that all  these global features will  be merged into a single  in
the future.


pplleeaassee((_+_K_e_y_, _-_O_l_d_, _+_N_e_w))
    The  predicate pplleeaassee//33  is  a solution  to avoid  large numbers  of
    environment  control  predicates.     Later  versions  will  support
    other  environment  control  as  now  provided  via  the  predicates
    ssttyyllee__cchheecckk//11,  lleeaasshh//11,  uunnkknnoowwnn//22,  the  tracer  predicates,  etc.
    These  predicates  are  then  moved into  a  library  for  backwards
    compatibility.  The currently available options are:

    ooppttiimmiissee _o_n_/_o_f_f (default:  _o_f_f_)
         Switch optimise  mode  for the  compiler on  or  off (see  also
         the command line  option -O).   Currently optimise  compilation
         only  implies  compilation  of  arithmetic,   making  it  fast,
         but  invisible to  the  tracer.    Later versions  might  imply
         various  other optimisations  such  as incorporating  a  number
         of basic  predicates  in the  virtual machine  (vvaarr//11,  ffaaiill//00,
         =/2,  etc.)    to  gain speed  at  the  cost of  crippling  the
         debugger.  Also source level optimisations  such as integrating
         small  predicates  into  their  callers,  eliminating  constant
         expressions and  other  predictable constructs.    Source  code
         optimisation is never  applied to predicates that are  declared
         dynamic (see ddyynnaammiicc//11).

    aauuttoollooaadd _o_n_/_o_f_f (default:  _o_n_)
         If on  autoloading of  library functions is  enabled.   If  off
         autoloading is disabled.  See section 2.9.

    vveerrbboossee__aauuttoollooaadd _o_n_/_o_f_f (default:  _o_f_f_)
         If on the normal  consult message will be printed if  a library
         is  autoloaded.     By  default  this  message  is  suppressed.
         Intended to  be used  for debugging purposes  (e.g. where  does
         this predicate come from?).


ffeeaattuurree((_?_K_e_y_, _-_V_a_l_u_e))
    The  predicate   ffeeaattuurree//22  defines  an  interface  to  installation
    features:   options  compiled in,  version, home,  etc.   With  both
    arguments unbound, it  will generate all defined features.  With the
    `Key'  instantiated it  unify the value  of the  feature.   Features
    come in three  types:  boolean features, features with an atom value
    and  features with an integer value.  A boolean feature is  true iff
    the  feature is present aanndd the _V_a_l_u_e  is the atom true.   Currently
    defined keys:

    aarrcchh ((_a_t_o_m))
         Identifier for the hardware and operating system  SWI-Prolog is
         running on.  Used  to determine the startup file as well  as to
         select foreign  files for  the right  architecture.   See  also
         llooaadd__ffoorreeiiggnn//55.

    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  upto  2.7.10  this   feature  yielded
         an  atom   holding  the  three   numbers  separated  by   dots.
         The  current representation  is  much easier  for  implementing
         version-conditional statements.

    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>/startup/startup.<_a_r_c_h> and  to   find  its  library   as
         <_h_o_m_e>/library.

    ppiippee ((_b_o_o_l))
         If true, tell(pipe(command)), etc. are supported.

    llooaadd__ffoorreeiiggnn ((_b_o_o_l))
         If true, llooaadd__ffoorreeiiggnn//[[22,,55]]are implemented.

    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,  ooppeenn__sshhaarreedd__oobbjjeecctt//22 and  friends  are  implemented,
         providing  access  to shared  libraries  (.so  files).     This
         requires the C-library  functions dlopen() and friends as  well
         as the configuration option --with-dlopen.

    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 ttrriimm__ssttaacckkss//00 (called by pprroolloogg//00  after
         finishing a user-query).

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

    cc__ssttaattiicclliibbss ((_a_t_o_m))
         On  some machines,  the  SWI-Prolog executable  is  dynamically
         linked, but  requires some libraries  to be statically  linked.
         Obsolete.

    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 5.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 5.7.

    ssaavvee ((_b_o_o_l))
         If true,  ssaavvee//[[11,,22]] is implemented.    Saving using ssaavvee//00  is
         obsolete.  See qqssaavvee__pprrooggrraamm//[[11,,22]].

    ssaavvee__pprrooggrraamm ((_b_o_o_l))
         If  true,  ssaavvee__pprrooggrraamm//[[11,,22]] is  implemented.    Saving  using
         ssaavvee__pprrooggrraamm//00is obsolete.  See qqssaavvee__pprrooggrraamm//[[11,,22]].

    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.

    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
         qqssaavvee__pprrooggrraamm//[[11,,22]].

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

    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miinn__iinntteeggeerr ((_i_n_t_e_g_e_r))
         Minimum integer value.

    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__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.

    ffllooaatt__ffoorrmmaatt ((_a_t_o_m))
         C printf()  format specification  used by  wwrriittee//11 and  friends
         to determine  how  floating point  numbers are  printed.    The
         default is %g.  May be changed.  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.   See also  ffoorrmmaatt//[[11,,22]],
         wwrriittee//11, pprriinntt//11 and ppoorrttrraayy//11.

    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chhaarraacctteerr__eessccaappeess ((_b_o_o_l))
         If true  (default),  rreeaadd//11 interprets  \  escape sequences  in
         quoted atoms and strings.  May be changed.

    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))
         If true  (default  is false),  Functor(arg) is  read  as if  it
         was written 'Functor'(arg).   Some applications use the  Prolog
         rreeaadd//11  predicate for  reading  an application  defined  script
         language.   In these  cases, it is  often difficult to  explain
         none-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 rreeaadd__tteerrmm//22using  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.

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

    ggcc ((_b_o_o_l))
         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.

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

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

    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  feature  describing rounding  by  //  and  rem  arithmetic
         functions.  Value depends on the C-compiler used.

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

    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
         ggeett__ssiinnggllee__cchhaarr//11, which  also reads  the  user-actions for  the
         trace.  May be set.  See also the +/-tty command-line option.

    ddeebbuugg__oonn__eerrrroorr ((_b_o_o_l))
         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 ffiilleeeerrrroorrss//22  and  the
         feature report_error.  May be changed.  Default is true, except
         for the runtime version.

    rreeppoorrtt__eerrrroorr ((_b_o_o_l))
         If true, print  error messages, otherwise  suppress them.   May
         be changed.   See also the debug_on_error feature.  Default  is
         true, except for the runtime version.

    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.

    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, NT, etc.).


sseett__ffeeaattuurree((_+_K_e_y_, _+_V_a_l_u_e))
    Define a new feature or  change its value.  _K_e_y is an atom, _V_a_l_u_e is
    an atom or number.


22..99 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 lliibbrraarryy__ddiirreeccttoorryy//11).   If the undefined  predicate can be  located
in the one  of the libraries that  library file is automatically  loaded
and the  call to the  (previously undefined) predicate is  resumed.   By
default this  mechanism loads the  file silently.   The pplleeaassee//33  option
verbose_autoload is provided to get verbose loading.   The please option
autoload can be used to enable/disable the entire auto load system.

Autoloading  only handles  (library) source  files that  use the  module
mechanism  described  in  chapter  4.     The  files   are  loaded  with
uussee__mmoodduullee//2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 mmaakkee//00  scans  the  autoload libraries  and  updates  the
index if  it exists,  is writable  and out-of-date.   It  is advised  to
create an empty  file called INDEX.pl in  a library directory meant  for
auto loading  before doing  anything else.    This index  file can  then
be updated  by running the prolog  mmaakkee__lliibbrraarryy__iinnddeexx//11(`%' is the  Unix
prompt):

% 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  a there is a library file  that defines the module in  which the
    undefined predicate is trapped, this file is used.

 2. Otherwise  library files  are considered  in the  order they  appear
    in  the  lliibbrraarryy__ddiirreeccttoorryy//1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.


22..99..11 NNootteess oonn AAuuttoommaattiicc LLooaaddiinngg

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

The autoloader only works if the unknown flag (see  uunnkknnoowwnn//22) is set to
trace (default).  A more appropriate interaction with  this flag will be
considered.


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

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

22..1111 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 ASCII  value 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111..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111..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  upto 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.  Nor 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  \ 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
feature(character_escapes, true) is  active (default).   See  ffeeaattuurree//22.
Character  escapes  conflict  with  wwrriitteeff//22  in  two  ways:     \40  is
interpreted as  decimal 40 by wwrriitteeff//22,  but character escapes  handling
by  read has  already  interpreted  as 32  (40  octal).    Also,  \l  is
translated to  a single  `l'.   Double  the \  (e.g. \\,  use the  above
escape sequences or use ffoorrmmaatt//22.


22..1111..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122 SSyysstteemm LLiimmiittss


22..1122..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 64  Mbytes on  32
bit processors,  or more in general to  2 to the power bits-per-long - 6
bytes.
       ___________________________________________________________
       |_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122..11..11 TThhee hheeaapp

With  the heap,  we  refer  to the  memory  area  used by  mmaalllloocc(())  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  mmaalllloocc(()) and
friends.

On  some machines,  the  runtime stacks  described above  are  allocated
using `sparse allocation'.   Virtual space upto the limit is  claimed at
startup and  committed and released  while the  area grows and  shrinks.
On Win32  platform this  is realised using  VViirrttuuaallAAlllloocc(()) and  friends.
On Unix systems this is realised using mmmmaapp(()),  either mapping /dev/zero
or a temporary file created in /tmp.

As Unix  provides no  way to  reserve part  of the  address space,  this
process may  lead to  conflicts.   By default,  SWI-Prolog computes  the
required virtual address  space for the runtime  stacks.  If  available,
it uses ggeettrrlliimmiitt(()) to  determine the top of the virtual  space reserved
for mmaalllloocc(()) usage and locates  the stacks in the top of this area.   It
assumes no  other mmmmaapp(()) activity  such as  mapping shared libraries  or
mmmmaapp(()) by foreign  modules will use the  area reserved for the heap  and
mmaalllloocc(()), mmaalllloocc(())  will grow the  heap from low  to high addresses  and
will notice the existence of the Prolog stacks.

These  assumptions appear  to  hold.    The user  may  using the  -H  to
specify the  maximum heap-size.   In this case,  the Prolog stacks  will
be allocated  at the indicated  size from the current  top of the  heap.
On  these system,  ssttaattiissttiiccss//[[00,,22]] reports  heaplimit and  heap.    The
heaplimit value is the  distance between the _b_r_e_a_k and the  first Prolog
stack.   The heap value is the  distance between what Prolog assumes  to
be the base of the heap and the current location of the break.


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

CCllaauusseess  Currently the  following limitations  apply to  clauses.    The
    arity  may not be more than 1024 and the number of  variables should
    be less than 65536.

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.   rreeaadd//1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
    ssttyyllee__cchheecckk//1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.  With some
    redesign,  the program area could be split into data that  should be
    within  this range and  the rest of  the data, virtually  unlimiting
    the program size.

IInntteeggeerrss  Integers are 32-bit to the  user, but integers upto the  value
    of the max_tagged_integer feature are represented more efficiently.

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

22..1122..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
(yet).    As large  parts of  the system  are written  in Prolog  itself
we  need some  way to  avoid name  clashes with  the user's  predicates,
database  keys,  etc.    Like  Edinburgh  C-Prolog  [Pereira, 1986]  all
predicates,  database keys,  etc. that should  be hidden  from the  user
start with a dollar ($) sign (see ssttyyllee__cchheecckk//11).

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

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

33..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 `oopp//33' refer to the predicate `op' with arity `3'.


33..22 CCoonnssuullttiinngg PPrroolloogg SSoouurrccee ffiilleess

SWI-Prolog source files  normally have a suffix  `.pl'.  Specifying  the
suffix  is optional.    All predicates  that handle  source files  first
check  whether a  file with  suffix  `.pl' exists.    If  not the  plain
file name  is checked  for existence.   Library  files are specified  by
embedding the file name using the functor lliibbrraarryy//11.   Thus `foo' refers
to `foo.pl'  or `foo'  in the current  directory, `library(foo)'  refers
to `foo.pl'  or `foo'  in one  of the library  directories specified  by
the dynamic predicate  lliibbrraarryy__ddiirreeccttoorryy//11.   The user may specify  other
`aliases'  than library  using the  predicate ffiillee__sseeaarrcchh__ppaatthh//22.    This
is strongly  encouraged for  managing complex  applications.   See  also
aabbssoolluuttee__ffiillee__nnaammee//[[22,,33]].

SWI-Prolog     recognises     grammar    rules     as     defined     in
[Clocksin & Melish, 1987].     The  user  may   define  additional  com-
pilation  of  the   source  file  by  defining  the  dynamic   predicate
tteerrmm__eexxppaannssiioonn//22.     Transformations  by  this  predicate  overrule  the
systems  grammar  rule transformations.     It  is not  allowed  to  use
aasssseerrtt//11, rreettrraacctt//11 or  any other database predicate in tteerrmm__eexxppaannssiioonn//2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   rreeccoonnssuulltt//1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 llooaadd__ffiilleess//22 is the parent  of all the other  loading
    predicates.    It  currently supports  a subset  of  the options  of
    Quintus  llooaadd__ffiilleess//2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  aabbssoolluuttee__ffiillee__nnaammee//2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 uussee__mmoodduullee//[[11,,2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.


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 csh(1) 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 lliibbrraarryy__ddiirreeccttoorryy//11 and
    ffiillee__sseeaarrcchh__ppaatthh//22.   ccoonnssuulltt//1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

    Equivalent to load_files(Files, []).


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 ccoonnssuulltt//1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,
    eennssuurree__llooaaddeedd//11 will call ccoonnssuulltt//1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 uussee__mmoodduullee//[[11,,22]].

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

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 this does  not
    exist.    This will flag  the predicate  as `undefined'.   See  also
    cchheecckk//00 and aauuttoollooaadd//0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.   mmaakkee//00  is normally  invoked by  the
    eeddiitt//[[00,,11]]  and eedd//[[00,,11]] predicates.   mmaakkee//00  can be combined  with
    the  compiler to speed  up the  development of large  packages.   In
    this case compile the package using

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

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

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  aasssseerrtt//11,
    aasssseerrttaa//11 or remove system defaults using rreettrraacctt//1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, '~/demo').

    the   file   specification   demo(myfile)  will   be   expanded   to
    ~/demo/myfile.    The second  argument of  ffiillee__sseeaarrcchh__ppaatthh//22may  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
    llooaadd__ffoorreeiiggnn__lliibbrraarryy//[[11,,22]].

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

    The  ffiillee__sseeaarrcchh__ppaatthh//22expansion is used  by all loading  predicates
    as well as by aabbssoolluuttee__ffiillee__nnaammee//22.


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  will   all  possible  expansions  of  the  file  name
    specification _S_p_e_c.  See also aabbssoolluuttee__ffiillee__nnaammee//33.


ssoouurrccee__ffiillee((_?_F_i_l_e))
    Succeeds  if  _F_i_l_e was  loaded using  ccoonnssuulltt//11  or eennssuurree__llooaaddeedd//11.
    _F_i_l_e   refers   to   the  full   path   name   of  the   file   (see
    eexxppaanndd__ffiillee__nnaammee//22).  The predicate ssoouurrccee__ffiillee//11 backtracks over all
    loaded source files.


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 eexxppaanndd__ffiillee__nnaammee//22).
    Can  be used with any  instantiation pattern, but the database  only
    maintains  the source file for each predicate.   Predicates declared
    multifile (see mmuullttiiffiillee//11) cannot be found this way.


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 ccuurrrreenntt__iinnppuutt//1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 ssoouurrccee__llooccaattiioonn//2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 pprroolloogg__llooaadd__ccoonntteexxtt//2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 4 and the directive mmoodduullee//22),
    eexxppaanndd__tteerrmm//22 will  first try  tteerrmm__eexxppaannssiioonn//22in  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,  eexxppaanndd__tteerrmm//22 will  try
    user:tteerrmm__eexxppaannssiioonn//22.   For compatibility with SICStus and  Quintus
    Prolog, this feature should not be used.  See also eexxppaanndd__tteerrmm//2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 tteerrmm__eexxppaannssiioonn//22.   If this predicate
    fails  it performs  a grammar-rule translation.    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   ran   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 aatt__hhaalltt//11


aatt__hhaalltt((_+_G_o_a_l))
    Register  _G_o_a_l to be ran when the  system halts.  The hooks  are run
    in  the order they were registered.  Success or failure  executing a
    hook is ignored.  These hooks may not call hhaalltt//[[00,,11]].


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 aatt__iinniittiiaalliizzaattiioonn//11.    Directives
    that  do  other things  that  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 qqssaavvee__pprrooggrraamm//[[11,,22]].


ccoommppiilliinngg
    Succeeds if the  system is compiling source files with the -c option
    into  an  intermediate code  file.    Can be  used to  perform  code
    optimisations in eexxppaanndd__tteerrmm//22 under this condition.


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


33..22..11 QQuuiicckk LLooaadd FFiilleess

The features described in this section should be regarded aallpphhaa.

As of  version 2.0.0, SWI-Prolog  supports compilation of individual  or
multiple Prolog  sourcefiles into  `Quick Load  Files'.   A `Quick  Load
Files' (.qlf  file) stores  the contents  of the file  in a  precompiled
format very similar to compiled files created using the  -b and -c flags
(see section 2.7).

These files load  considerably faster than sourcefiles 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  qqccoommppiillee//11.   They  may be  loaded
explicitly using  qqllooaadd//11 or implicitly  using ccoonnssuulltt//11  or one of  the
other file-loading predicates described  in section 3.2.  If  consult is
given the  explicit .pl  file, it  will load  the Prolog source.    When
given the .qlf  file, it will  call qqllooaadd//11 to load the  file.  When  no
extension is specified, it will load the .qlf file  when present and the
fileextpl file otherwise.


qqccoommppiillee((_+_F_i_l_e))
    Takes  a  single file  specification  like ccoonnssuulltt//1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)'   or   `:- [+File]'
    statements,  the  referred 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  tteerrmm__eexxppaannssiioonn//22,  the same  rules as described  in section  2.7
    apply.

    Source  references (ssoouurrccee__ffiillee//22)  in the Quick  Load File refer  to
    the Prolog source file from which the compiled code originates.


qqllooaadd((_+_F_i_l_e))
    Loads  the  `Quick  Load  File'.    It  has the  same  semantics  as
    ccoonnssuulltt//11 for a  normal sourcefile.  Equivalent to consult(File) iff
    _F_i_l_e refers to a `Quick Load File'.


33..33 LLiissttiinngg PPrreeddiiccaatteess 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 interface  to the Unix vi editor and the  GNU Emacs
invocations emacs and emacsclient.   Which editor is used  is determined
by the  Unix environment  variable EDITOR,  which should  hold the  full
pathname of the editor.  If this variable is not defined, vi is used.

After  the user  quits  the editor,  mmaakkee//00  is  invoked to  reload  all
modified source files using  ccoonnssuulltt//11.  If the editor can be  quit such
that  an exit  status non-equal  to 0  is returned  mmaakkee//00  will not  be
invoked.  _t_o_p can do this by typing control-C, _v_i cannot do this.

A predicate  specification is either  a term with  the same functor  and
arity  as the  predicate wanted,  a term  of the  form _F_u_n_c_t_o_r/_A_r_i_t_y  or
a single  atom.   In  the latter  case the  database is  searched for  a
predicate of  this name  and arbitrary arity  (see ccuurrrreenntt__pprreeddiiccaattee//22).
When  more  than  one such  predicate  exists  the  system  will  prompt
for  confirmation  on  each of  the  matched  predicates.     Predicates
specifications  are  given   to  the  `Do  What  I  Mean'   system  (see
ddwwiimm__pprreeddiiccaattee//22) if the requested predicate does not exist.


eedd((_+_P_r_e_d))
    Invoke  the user's  preferred  editor on  the source  file of  _P_r_e_d,
    providing  a search specification  which searches for the  predicate
    at the start of a line.


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

eeddiitt((_+_F_i_l_e))
    Invoke  the  user's preferred  editor  on  _F_i_l_e.    _F_i_l_e is  a  file
    specification  as for ccoonnssuulltt//11  (but not  a list).   Note that  the
    file should exist.


eeddiitt
    Invoke  eeddiitt//11 on the file last edited using eeddiitt//11.  Asks  the user
    to confirm before starting the editor.


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 loosing user's  layout
    and variable name information.  See also ppoorrttrraayy__ccllaauussee//11.


lliissttiinngg
    List all predicates of the database using lliissttiinngg//1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  as good  as we  can.   A  clause should  be
    specified  as a  term `<_H_e_a_d> :- <_B_o_d_y>' (put  brackets around it  to
    avoid  operator  precedence problems).    Facts  are represented  as
    `<_H_e_a_d> :- true'.


eeddiitt__ssoouurrccee((_+_S_p_e_c))
    A  hook that may be  defined in the module  user to specify how  the
    predicates  eedd//11 and eeddiitt//11  call the editor.   If eedd//11 is  invoking
    this hook, _S_p_e_c is a term of the format

         File:LineNo:Name/Arity

    Where  _F_i_l_e  and _L_i_n_e_N_o  represents the  location  of the  predicate
    remembered by Prolog, and  _N_a_m_e and _A_r_i_t_y specify the predicate.  If
    invoked by eeddiitt//11, _S_p_e_c  is an atom denoting the name of the file to
    be edited.   This hook is defined by the library library(swi_prolog)
    distributed  with the  XPCE package  for using XPCE  to edit  Prolog
    files.


33..44 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 ffuunnccttoorr//33
    and =../2.


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

33..55 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


33..55..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. _T_e_r_m_s  are first checked on their functor (alphabetically),  then on
    their  arity and  finally recursively on  their arguments,  leftmost
    argument first.


_+_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.


_+_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2),  but stronger  than
    unification  (=//2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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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.


33..66 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 ffaaiill//00  is translated  into a  single
    virtual machine instruction.


ttrruuee
    Always  succeed.  The predicate  ttrruuee//0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.   Note  that the  control structures  ;//22,
    |//22,  ->//22  and \+//11  are normally handled  by the  compiler and  do
    not  create a frame,  which implies the  cut operates through  these
    predicates.   Some  examples are given below.   Note the  difference
    between t3/1 and t4/1.   Also note the effect of ccaallll//11 in t5/0.  As
    the  argument of ccaallll//11 is  evaluated by predicates rather than  the
    compiler the cut has no effect.

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

       t6 :- \+(a, !, fail ; b).      % cuts a/0 and t6/0


_+_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2.    Retained for compatibility  only.   New  code
    should use ;//22.  Still nice though for grammar rules.


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

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

    Note   that  the   operator  precedence  relation   between  ;   and
    ->   ensure  If -> Then ; Else  is  actually  a  term  of  the  form
    ;(->(If, Then), Else).     The  first  two  clauses  belong  to  the
    definition of ;//22), while only the last defines ->//22 .


_+_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.


\+ _+_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).


33..77 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 ccaallll//11, except when  the argument
    is bound to the cut.  See !//00.


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
    pplluuss//3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
    ccaallll//[[22--6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).   aappppllyy//22 is  incorporated in the virtual machine  of
    SWI-Prolog.   This implies that the overhead can be compared  to the
    overhead  of ccaallll//1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1.


oonnccee((_+_G_o_a_l))
    Defined as:

    once(Goal) :-
            Goal, !.

    oonnccee//11  can  in  many  cases  be replaced  with  ->//2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 oonnccee//1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,
    ccaallll__wwiitthh__ddeepptthh__lliimmiitt//3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 differ
    from  the  depth  computed  based  on a  theoretical  model.     For
    example,  ttrruuee//00  is  translated  into an  inlined  virtual  machine
    instruction.   Also, rreeppeeaatt//00 is not implemented as below, but  as a
    non-deterministic foreign predicate.

    repeat.
    repeat :-
            repeat.

    As  a  result,  ccaallll__wwiitthh__ddeepptthh__lliimmiitt//33may 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.


33..88 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 ccaattcchh//33 and tthhrrooww//11  for ISO compliant
raising  and catching  of exceptions.    In  the current  implementation
(2.9.0), only part of  the built-in predicates generate exceptions.   In
general, exceptions are implemented for I/O and arithmetic.


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 ccaallll//11 if  no exception is  raised when executing  _G_o_a_l.
    If  a exception  is raised  using tthhrrooww//1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 tthhrrooww//11,  all choicepoints generated  by _G_o_a_l are  cut,
    and _R_e_c_o_v_e_r is called as in ccaallll//11.

    The  overhead of calling a  goal through ccaattcchh//33 is very  comparable
    to ccaallll//11.  Recovery from an exception has a similar overhead.


tthhrrooww((_+_E_x_c_e_p_t_i_o_n))
    Raise an exception.   The system will look for the innermost ccaattcchh//3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 ccaattcchh//33 call.  See ccaattcchh//33 for details.

    If  there is no  ccaattcchh//33 willing to catch  the error in the  current
    Prolog  context,  the  toplevel  (pprroolloogg//00) catches  the  error  and
    prints  a  warning  message.    If  an  exception was  raised  in  a
    callback  from C  (see chapter 5),  PPLL__nneexxtt__ssoolluuttiioonn(())will fail  and
    the exception context can be retrieved using PPLL__eexxcceeppttiioonn(()).


33..88..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 feature  (see ffeeaattuurree//2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 ccaattcchh//3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
ccaattcchh//3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 ccaattcchh//3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  feature
debug_on_error:

  o _f_e_a_t_u_r_e_(_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
    PPLL__eexxcceeppttiioonn(()).  This is the default.

  o _f_e_a_t_u_r_e_(_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
adviced to switch on debug mode using the predicate ddeebbuugg//00.


33..88..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.


33..88..33 PPrriinnttiinngg aa mmeessssaaggee ffrroomm aann eexxcceeppttiioonn

The predicate pprriinntt__mmeessssaaggee//22 may be used to print an exception  term in
a human readable format:


pprriinntt__mmeessssaaggee((_+_K_i_n_d_, _+_T_e_r_m))
    This  predicate is  modelled after  the Quintus  predicate with  the
    same  name, though  its current  implementation is incomplete.    It
    is  used only  for printing messages  from exceptions from  built-in
    predicates.    _K_i_n_d is  one of  informational, warning,  consterror,
    help  or silent.    Currently only  error is defined.    _T_e_r_m is  an
    eerrrroorr((_2)) term described  in section 3.8.2.  A human-readable message
    is printed to the stream user_error.

    This  predicate first  obtains the `human  translation' of _T_e_r_m  and
    then  calls mmeessssaaggee__hhooookk//33.  If this fails the message  is printed to
    the stream user_error.

    The  pprriinntt__mmeessssaaggee//2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.


mmeessssaaggee__hhooookk((_+_T_e_r_m_, _+_K_i_n_d_, _+_M_e_s_s_a_g_e))
    Hook  predicate that may be define  in the module user to  intercept
    messages  from  pprriinntt__mmeessssaaggee//22.    _T_e_r_m  and _K_i_n_d  are the  same  as
    passed  to  pprriinntt__mmeessssaaggee//22.    _M_e_s_s_a_g_e is  a  string containing  the
    human  readable  translation of  the  message.   If  this  predicate
    succeeds, pprriinntt__mmeessssaaggee//22 considers the message printed.

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

33..99 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 5.6.11).

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.    oonn__ssiiggnnaall//3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  3.8.   default resets  the handler  to the settings  active
    before SWI-Prolog manipulated the handler.

    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 5):

    #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 following Prolog code:

    :- load_foreign_library(alarm).

    :- on_signal(alrm, throw).

    :- module_transparent
            call_with_time_limit/2.

    call_with_time_limit(Goal, MaxTime) :-
            alarm(MaxTime),
            catch(Goal, signal(alrm, _), fail), !,
            alarm(0).
    call_with_time_limit(_, _) :-
            alarm(0),
            fail.

    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 ccuurrrreenntt__ssiiggnnaall//33may
    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 oonn__ssiiggnnaall//33).


33..99..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  PPLL__nneexxtt__ssoolluuttiioonn(()),
    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.

  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  with the garbage collector  is
    active,  and internally delayed  if they occur  will in a  `critical
    section'.  The critical sections are generally very short.


33..1100 AAddvvaanncceedd ccoonnttrrooll--ssttrruuccttuurreess::  bblloocckkss

The predicates of this section form a tightly related  set for realising
premature successful or  failing exits from a  _b_l_o_c_k.  These  predicates
are  first of  all  useful for  error-recovery.    They  were  primarily
implemented for compatibility reasons.


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 eexxiitt//22 call invoked by _G_o_a_l.


eexxiitt((_+_L_a_b_e_l_, _+_V_a_l_u_e))
    Calling  eexxiitt//2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  ffaaiill//1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.

The example  below illustrate these constructs  to immediately report  a
syntax-error from a  `deep-down' procedure to the outside world  without
passing it as an argument `all-over-the-place'.

parse(RuleSet, InputList, Rest) :-
        block(syntaxerror, phrase(RuleSet, InputList, Rest), Error),
        (   var(Error)
        ->  true
        ;   format('Syntax-error: ~w~n', Error),
            fail
        ).

integer(N) -->
        digit(D1), !, digits(Ds),
        { name(N, [D1|Ds]) }.

digits([D|R]) --> digit(D), digits(R).
digits(_) --> letter(_), !, { exit(syntaxerror, 'Illegal number') }.
digits([]) --> [].

digit(D, [D|R], R)  :- between(0'0, 0'9, D).
letter(D, [D|R], R) :- between(0'a, 0'z, D).


33..1111 GGrraammmmaarr rruullee iinntteerrffaaccee ((pphhrraassee))

The predicates below may be called to activate a grammar-rule set:


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.


33..1122 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  aasssseerrtt//11  or one  of
its  derivatives become  part of  the program  these predicates  compile
the term  given to them.    rreettrraacctt//11 and rreettrraaccttaallll//1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 ddyynnaammiicc//1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 again  is
considerably 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.    Unlike  version  1.2,  all  predicate
    attributes  (dynamic, multifile, index,  etc.)   are reset to  their
    defaults.   Abolishing an imported predicate only removes the import
    link;  the predicate will keep its old definition in  its definition
    module.    For `cleanup'  of the  dynamic database,  one should  use
    rreettrraaccttaallll//11 rather than aabboolliisshh//22.


aabboolliisshh((_+_N_a_m_e_, _+_A_r_i_t_y))
    Same  as abolish(Name/Arity).   The predicate aabboolliisshh//22 conforms  to
    the Edinburgh standard, while aabboolliisshh//1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 aasssseerrtt//1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 aasssseerrtt//11.


aasssseerrtt((_+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e))
    Equivalent  to  aasssseerrtt//1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
    ccllaauussee//33 or eerraassee//11.


aasssseerrttaa((_+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e))
    Equivalent  to aasssseerrtt//2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 aasssseerrtt//2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 eerraassee//1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 rreeccoorrddaa//3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  rreeccoorrddaa//33 or  rreeccoorrddeedd//33, ccllaauussee//33,  aasssseerrtt//22,
    aasssseerrttaa//22  or aasssseerrttzz//2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.   ffllaagg//3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).


33..1122..11 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 iinnddeexx//11.

For advanced database indexing, it defines hhaasshh__tteerrmm//2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 ggrroouunndd//1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.


33..1133 DDeeccllaarriinngg PPrrooppeerrttiieess ooff PPrreeddiiccaatteess

This  section  describes  directives  which  manipulate   attributes  of
predicate  definitions.     The  functors  ddyynnaammiicc//11,   mmuullttiiffiillee//11  and
ddiissccoonnttiigguuoouuss//11  are  operators  of  priority  1150  (see  oopp//3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 _+_F_u_n_c_t_o_r_/_+_A_r_i_t_y_, _._._.
    Informs  the interpreter  that  the definition  of the  predicate(s)
    may  change  during  execution (using  aasssseerrtt//11  and/or  rreettrraacctt//11).
    Currently  ddyynnaammiicc//11  only stops  the interpreter  from  complaining
    about  undefined  predicates  (see  uunnkknnoowwnn//22).     Future  releases
    might  prohibit  aasssseerrtt//11  and rreettrraacctt//11  for  not-dynamic  declared
    procedures.


mmuullttiiffiillee _+_F_u_n_c_t_o_r_/_+_A_r_i_t_y_, _._._.
    Informs  the system that the  specified predicate(s) may be  defined
    over  more than one  file.  This  stops ccoonnssuulltt//1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 _+_F_u_n_c_t_o_r_/_+_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 ssttyyllee__cchheecckk//1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  functors   (e.g.  name  and  arity  of  a  term)  are
    considered.    Indexing  is  very useful  for predicates  with  many
    clauses representing facts.

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

    By  default  all predicates  with <_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).
    ...
    ...


33..1144 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  ccuurrrreenntt__aattoomm//11always  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
    ffllaagg//3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
    rreeccoorrddaa//3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.


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  the  predicate  is  declared  dynamic  using  the
         ddyynnaammiicc//11 declaration.

    mmuullttiiffiillee
         Is  true if  the  predicate  is declared  multifile  using  the
         mmuullttiiffiillee//11 declaration.

    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 in it and it is  not declared
         dynamic.   This is  true if  the predicate occurs  in the  body
         of a  loaded predicate,  an attempt  to call it  has been  made
         via one  of the  meta-call predicates  or the  predicate had  a
         definition in  the past.   See  the library  package _c_h_e_c_k  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
         mmoodduullee__ttrraannssppaarreenntt//11declaration.

    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 iinnddeexx//1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  sourcefile in which  the
         predicate is defined.  See also ssoouurrccee__ffiillee//2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 ssoouurrccee__ffiillee//2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  ddwwiimm__mmaattcchh//22for  `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 ccllaauussee//2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  ccllaauussee//22,   but  unifies  _R_e_f_e_r_e_n_c_e  with  a  unique
    reference to the  clause (see also aasssseerrtt//22, eerraassee//1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 mmeemmbbeerr//2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   ccllaauussee//33,   nntthh__ccllaauussee//33   or
    pprroolloogg__ffrraammee__aattttrriibbuuttee//3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  sourcefile 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.


33..1155 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.   One
confirms  to  the  Edinburgh  standard.    This  package  has  a  notion
of  `current-input' and  `current-output'.    The  reading  and  writing
predicates implicitly refer  to these streams.   In the second  package,
streams are  opened explicitly and  the resulting handle  is used as  an
argument to the reading  and writing predicate to specify the  source or
destination.   Both packages are fully  integrated; the user may  switch
freely between them.


33..1155..11 IInnppuutt aanndd OOuuttppuutt UUssiinngg IImmpplliicciitt SSoouurrccee aanndd DDeessttiinnaattiioonn

The  package  for  implicit input  and  output  destination  is  upwards
compatible to DEC-10 and  C-Prolog.  The reading and  writing predicates
refer to resp.   the current input- and output stream.   Initially these
streams are  connected to the  terminal.  The  current output stream  is
changed using tteellll//11 or  aappppeenndd//11.  The current input stream  is changed
using sseeee//11.  The streams current value can  be obtained using tteelllliinngg//11
for output- and sseeeeiinngg//11  for input streams.  The table below  shows the
valid stream specifications.  The reserved names user_input, user_output
and user_error are for neat integration with the explicit streams.

           ___________________________________________________
           | user        |This  reserved name  refers to  the|
           |             |terminal                           |
           | user_input  I|nput from the terminal            |

           | user_output O|utput to the terminal             |
           | user_error  U|nix error stream (output only)    |
           | <_A_t_o_m>      N|ame of a Unix file                |
           |_pipe(<_A_t_o_m>)N|ame_of_a_Unix_command_____________|_

Source and  destination are  either a file,  one of  the reserved  words
above, or a term  `pipe(_C_o_m_m_a_n_d)'.  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(stderr).     % Start writing on the error stream.

       ?- tell(pipe(lpr)).  % Start writing to the printer.

Another example  of using  the ppiippee//11 construct  is shown  below.   Note
that  the  ppiippee//1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_chars(Wd, String).

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

sseeee((_+_S_r_c_D_e_s_t))
    Make  _S_r_c_D_e_s_t the  current input  stream.   If  _S_r_c_D_e_s_t was  already
    opened  for  reading  with sseeee//11  and  has  not been  closed  since,
    reading  will be resumed.  Otherwise _S_r_c_D_e_s_t will be opened  and the
    file pointer is positioned at the start of the file.


tteellll((_+_S_r_c_D_e_s_t))
    Make  _S_r_c_D_e_s_t the  current output stream.    If _S_r_c_D_e_s_t was  already
    opened  for writing with tteellll//11 or aappppeenndd//11 and has not  been closed
    since,  writing will  be resumed.    Otherwise the  file is  created
    or---when existing---truncated.  See also aappppeenndd//11.


aappppeenndd((_+_F_i_l_e))
    Similar  to tteellll//1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))
    Unify the name of the current input stream with _S_r_c_D_e_s_t.


tteelllliinngg((_?_S_r_c_D_e_s_t))
    Unify the name of the current output stream with _S_r_c_D_e_s_t.


sseeeenn
    Close the current input stream.  The new input stream becomes _u_s_e_r.


ttoolldd
    Close  the current  output stream.   The  new output stream  becomes
    _u_s_e_r.


33..1155..22 EExxpplliicciitt 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  below are  part of the  Quintus compatible  stream-based
I/O package.   In this package streams are explicitly created  using the
predicate ooppeenn//3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.


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)',  just
    like  sseeee//11 and  tteellll//1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.  See also ssttrreeaamm__ppoossiittiioonn//33.   _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.     The  following  two  calls  are
         identical, but only the latter is allowed in ISO Prolog.

         ?- open(foo, read, in, []).
         ?- open(foo, read, S, [alias(in)]).

    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 ggeett00//11  and friends return  -1
         and rreeaadd//1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  fullf (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 fflluusshh//00  and fflluusshh__oouuttppuutt//1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
         aabboorrtt//0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 ppiippee//11 construct).

    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 ooppeenn//4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cuurrrreenntt__ssttrreeaamm((_?_F_i_l_e_, _?_M_o_d_e_, _?_S_t_r_e_a_m))
    Is  true if  a stream with  file specification _F_i_l_e,  mode _M_o_d_e  and
    stream  identifier _S_t_r_e_a_m is  open.   The reserved streams user  and
    user_error are  not generated by  this predicate.   If a stream  has
    been  opened  with mode  append this  predicate  will generate  mode
    write.


ssttrreeaamm__ppoossiittiioonn((_+_S_t_r_e_a_m_, _-_O_l_d_, _+_N_e_w))
    Unify  the position parameters  of _S_t_r_e_a_m with  _O_l_d and set them  to
    _N_e_w.  A position is represented by the following term:

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

    It is only  possible to change the position parameters if the stream
    is  connected to  a disk  file.   If  the position  is changed,  the
    _C_h_a_r_N_o  field determines the new position  in the file.  The  _L_i_n_e_N_o
    and  _L_i_n_e_P_o_s are  copied in  the stream  administration.   See  also
    sseeeekk//4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 sseeeekk//44 is  compatible to  Quintus Prolog, though  the
    error  conditions  and  signalling  is  ISO compliant.     See  also
    ssttrreeaamm__ppoossiittiioonn//33.


33..1155..33 SSwwiittcchhiinngg BBeettwweeeenn IImmpplliicciitt aanndd EExxpplliicciitt 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.


dduupp__ssttrreeaamm((_+_F_r_o_m_, _+_T_o))
    Duplicate  the  underlying data  from stream  _F_r_o_m to  streamTo,  so
    actions  performed  on either  stream have  the same  effect.    The
    primary  goal  of this  predicate is  to  facilitate redirection  of
    the  user  interaction  to allow  for  `interactor'  windows.    For
    example,  the following code will redirect output to user_output and
    user_error to an XPCE text window:

            ...,
            pce_open(Window, append, Fd),
            dup_stream(user_output, Fd),
            dup_stream(user_error, Fd),
            ...

    The  old  status of  a stream  can  be stored  by duplicating  to  a
    null-stream as obtained using ooppeenn__nnuullll__ssttrreeaamm//11.

    This predicate is SWI-Prolog specific.


33..1166 SSttaattuuss ooff 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


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.
    wwaaiitt__ffoorr__iinnppuutt//3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 0, wwaaiitt__ffoorr__iinnppuutt//33waits  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).


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.


33..1177 PPrriimmiittiivvee CChhaarraacctteerr IInnppuutt aanndd OOuuttppuutt


nnll
    Write  a newline character  to the current output  stream.  On  Unix
    systems nnll//0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 an ASCII  value (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.


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

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
    Flush  pending  output  on  current  output  stream.     fflluusshh//00  is
    automatically  generated by  rreeaadd//1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 fflluusshh//00.


ggeett00((_-_C_h_a_r))
    Read  the current  input stream  and unify the  next character  with
    _C_h_a_r.  _C_h_a_r is unified with -1 on end of file.


ggeett00((_+_S_t_r_e_a_m_, _-_C_h_a_r))
    Read the next character from _S_t_r_e_a_m.


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((_-_C_h_a_r))
    Reads  the next input character like ggeett00//11, but does not  remove it
    from the input stream.  This predicate is ISO compliant.


ppeeeekk__bbyyttee((_+_S_t_r_e_a_m_, _-_C_h_a_r))
    Reads  the next input character like ggeett00//22, but does not  remove it
    from the stream.  This predicate is ISO compliant.


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 ggeett00//1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 sskkiipp//1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 ggeett00//1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  ASCII 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.


33..1188 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  tteerrmm__ttoo__aattoomm//22 and  aattoomm__ttoo__tteerrmm//33 provide   means  for
translating atoms  and strings to  terms.   The predicates  ffoorrmmaatt//[[11,,22]]
and wwrriitteeff//22 provide formatted output.

There are  two ways  to manipulate  the output  format.   The  predicate
pprriinntt//[[11,,22]] may be programmed  using ppoorrttrraayy//11.  The format  of floating
point  numbers may  be  manipulated using  the feature  (see  ffeeaattuurree//22)
float_format.

Reading is  sensitive to the  feature 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  wwrriittee__tteerrmm//22 is  the  generic  form  of  all  Prolog
    term-write predicates.  Valid options are:

    qquuootteedd((true _o_r false))
         If true, atoms and  functors that needs quotes will  be quoted.
         The default is false.

    iiggnnoorree__ooppss((true _o_r false))
         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.

    nnuummbbeerrvvaarrss((true _o_r false))
         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((true _o_r false))
         If true, the  hook ppoorrttrraayy//11 is  called before printing a  term
         that is not  a variable.   If ppoorrttrraayy//11  succeeds, the term  is
         considered printed.  See  also pprriinntt//11.  The default  is false.
         This option is an extension to the ISO write_term 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  wwrriittee__tteerrmm//2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  parenthe-
    sised 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 wwrriittee__tteerrmm//2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 ffeeaattuurree//2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 rreeaadd//1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 wwrriittee//11,  but
    for each (sub)term  of _T_e_r_m first the dynamic predicate ppoorrttrraayy//1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 pprriinntt//11 on (sub)terms.   For each subterm  encountered
    that is not  a variable pprriinntt//11 first calls ppoorrttrraayy//11 using the term
    as  argument.    For lists  only the  list as  a whole  is given  to
    ppoorrttrraayy//11.   If portray succeeds  pprriinntt//1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 rreeaadd//1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  rreeaadd//1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 ccoonnssuulltt//11).  New  code should
    use rreeaadd__tteerrmm//2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 rreeaadd__ccllaauussee//11.


rreeaadd__vvaarriiaabblleess((_-_T_e_r_m_, _-_B_i_n_d_i_n_g_s))
    Similar  to  rreeaadd//11,   but  _B_i_n_d_i_n_g_s  is  unified  with  a  list  of
    `_N_a_m_e = _V_a_r' tuples, thus  providing access to  the actual variable
    names.      New  code  should   use  rreeaadd__tteerrmm//22 using  the   option
    variables(X).


rreeaadd__vvaarriiaabblleess((_+_S_t_r_e_a_m_, _-_T_e_r_m_, _-_B_i_n_d_i_n_g_s))
    Read,    returning  term   and   bindings   from  _S_t_r_e_a_m.        See
    rreeaadd__vvaarriiaabblleess//22.


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
    rreeaadd//11.   The options are upward compatible to Quintus Prolog.   The
    argument order is according to the ISO standard.  Options:

    ssyynnttaaxx__eerrrroorrss((_a_t_o_m _o_r _v_a_r_i_a_b_l_e))
         Define the  behaviour for  when  a syntax  error occurs.    The
         possible values are:

         ffaaiill
             Default behaviour.  The error  is reported as a warning and
             the predicate fails.

         qquuiieett
             Quietly fails if a syntax error has occurred.

         VVaarriiaabbllee
             If  no error  occurs, the  variable is  unified with  none,
             otherwise _V_a_r_i_a_b_l_e is unified with a term of the form

             '$stream_position'(CharNo, LineNo, LinePos):Message

             This behaviour is a SWI-Prolog extension.

    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.

    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.

    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 ssttrreeaamm__ppoossiittiioonn//33.

    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 rreeaadd__tteerrmm//2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 rreeaadd__vvaarriiaabblleess//22,  but allows for history  substitutions.
    rreeaadd__hhiissttoorryy//66 is 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  pprroommpptt//22.   A  %w in  the prompt  is
    substituted  by the  event number.   See  section 2.4 for  available
    substitutions.

    SWI-Prolog calls rreeaadd__hhiissttoorryy//6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 rreeaadd//1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 pprroommpptt//22.


33..1199 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.    ffuunnccttoorr//3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  aarrgg//3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
    sseettaarrgg//33 call.

    This  predicate may  be used  for destructive  assignment to  terms,
    using them as and extra-logical storage bin.


_?_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_, _+_F_u_n_c_t_o_r_, _+_S_t_a_r_t_, _-_E_n_d))
    Unify  the free variables of _T_e_r_m  with a term constructed from  the
    atom  _F_u_n_c_t_o_r with one argument.  The argument 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), this_is_a_variable, 0, End).

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

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

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.  ccooppyy__tteerrmm//22 is semantically equivalent to:

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

33..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 AAttoommss

These predicates  convert between  Prolog constants and  lists of  ASCII
values.   The predicates  aattoomm__cchhaarrss//22, nnuummbbeerr__cchhaarrss//22 and nnaammee//22  behave
the same  when converting  from a constant  to a  list of ASCII  values.
When  converting the  other way  around,  aattoomm__cchhaarrss//22 will generate  an
atom, number_chars will generate a  number or fail and nnaammee//22 will return
a number if possible and an atom otherwise.


aattoomm__cchhaarrss((_?_A_t_o_m_, _?_S_t_r_i_n_g))
    Convert  between an atom  and a list  of ASCII values.   If _A_t_o_m  is
    instantiated, if will  be translated into a list of ASCII values 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  ASCII values, 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r((_?_A_t_o_m_, _?_A_S_C_I_I))
    Convert between character and ASCII value for a single character.


nnuummbbeerr__cchhaarrss((_?_N_u_m_b_e_r_, _?_S_t_r_i_n_g))
    Similar  to  aattoomm__cchhaarrss//22,  but  converts between  a number  and  its
    representation as a list  of ASCII values.  Fails silently if _N_u_m_b_e_r
    is unbound and _S_t_r_i_n_g does not describe a number.


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 ASCII  values describing  _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  ASCII value 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  ascii 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  ASCII value 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.
    Otherwise _T_e_r_m is ``written'' on _A_t_o_m using wwrriittee//1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  rreeaadd__vvaarriiaabblleess//22and  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 rreeaadd__vvaarriiaabblleess//22.


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.


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 ccoonnccaatt//3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  ccoonnccaatt__aattoomm//2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'


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 integers and floats, expressing the number
    of characters output when given to wwrriittee//11.


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

33..2211 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.   Atoms are  under
some circumstances  not suitable because garbage  collection on them  is
next  to impossible  (Although  it is  possible:   BIM_prolog  does  it).
Representing text as a  list of ASCII values is, from the  logical point
of view, the cleanest solution.  It however has two  drawbacks:  1) they
cannot be  distinguished from a  list of (small)  integers; and 2)  they
consume (in SWI-Prolog) 12 bytes for each character stored.

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

The ISO standard proposes " ..." is transformed into a  string object by
rreeaadd//11 and derivatives.   This poses  problems as in the old  convention
" ..." is transformed into a list of ascii characters.   For this reason
the style check option `string' is available (see ssttyyllee__cchheecckk//11).

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

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 ASCII 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  aattoomm__lleennggtthh//2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 ccoonnccaatt//3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bssttrriinngg((_+_S_t_r_i_n_g_, _+_S_t_a_r_t_, _+_L_e_n_g_t_h_, _-_S_u_b))
    Create  a substring  of  _S_t_r_i_n_g that  starts at  character _S_t_a_r_t  (1
    base) and has _L_e_n_g_t_h characters.  Unify this substring with _S_u_b.


33..2222 OOppeerraattoorrss


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 3.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  |\+, not                                        |
     |  900 | fx  |~                                              |
     |  700 |xfx  |<, =, =.., =@=,  =:=, =<, ==, =\=,  >, >=, @<, |
     |      |     |@=<, @>, @>=, \=, \==, is                      |
     |  600 |xfy  |:                                              |

     |  500 | yfx |+, -, /\, \/, xor                              |
     |  500 | fx  |+, -, ?, \                                     |
     |  400 | yfx |*, /, //, <<, >>, mod, rem                     |
     |  200 |xfx  |**                                             |
     |__200_|xfy__|^______________________________________________|_

                      Table 3.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 oopp//33.


33..2233 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
pplleeaassee//33 and the -O  command line option).  Compiled  arithmetic reduces
global  stack requirements  and  improves  performance.    Unfortunately
compiled arithmetic cannot be traced, which is why it is optional.

The  general  arithmetic   predicates  all  handle  _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 3.24.


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.  At least one of  the arguments must be
    instantiated to an integer.


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, iiss//2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   iiss//22   will
                                      represent this as the integer
                                      1,  after  which  unify  will
                                      fail.

         ?- 1.0 is float(sin(pi/2)).  Succeeds,   as   the  ffllooaatt//11
                                      function forces the result to
                                      be float.
         ?- 1.0 =:= sin(pi/2).        Succeeds as expected.


33..2244 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 (ssiinn//11,  eexxpp//1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
    _R_e_s_u_l_t =_E_x_p_r_1mod_E_x_p_r_2 (remainder of division).


_+_I_n_t_E_x_p_r_1 rreemm _+_I_n_t_E_x_p_r_2
    _R_e_s_u_l_t =_E_x_p_r_1rem_E_x_p_r_2 (remainder of division).


_+_I_n_t_E_x_p_r_1 // _+_I_n_t_E_x_p_r_2
    _R_e_s_u_l_t =_E_x_p_r_1 _E_x_p_r_2 (integer division).


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 ASCII value  of the  letter `a' (97).    This
    option  is available for  compatibility only.   It will not work  if
    `style_check(+string)'  is active as  "a" will  then be  transformed
    into  a string object.    The recommended way  to specify the  ASCII
    value 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 rroouunndd//1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 iiss//2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 ffllooaatt__iinntteeggeerr__ppaarrtt//1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 cceeiilliinngg//1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 ssttaattiissttiiccss//22  and
    ttiimmee//11.


33..2255 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 aarriitthhmmeettiicc__ffuunnccttiioonn//1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  iiss//22,
    >//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.


33..2266 LLiisstt MMaanniippuullaattiioonn


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.


pprrooppeerr__lliisstt((_+_T_e_r_m))
    Equivalent  to iiss__lliisstt//11, but  also requires the tail of the  list to
    be a list (recursively).  Examples:

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

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.


mmeemmbbeerrcchhkk((_?_E_l_e_m_, _+_L_i_s_t))
    Equivalent to mmeemmbbeerr//22, but leaves no choice point.


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((_?_L_i_s_t_1_, _?_E_l_e_m_, _?_L_i_s_t_2))
    Select  an  element of  _L_i_s_t_1 that  unifies  with _E_l_e_m.    _L_i_s_t_2  is
    unified  with  the  list remaining  from  _L_i_s_t_1 after  deleting  the
    selected  element.   Normally  used with  the instantiation  pattern
    _+_L_i_s_t_1_, _-_E_l_e_m_, _-_L_i_s_t_2,  but can also be used to insert an element in
    a list using _-_L_i_s_t_1_, _+_E_l_e_m_, _+_L_i_s_t_2.


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((_?_E_l_e_m_, _?_L_i_s_t))
    Succeeds if _E_l_e_m unifies with the last element of _L_i_s_t.


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.


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]


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.


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 3.5).    _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.


33..2277 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  proper  list  (see pprrooppeerr__lliisstt//1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 ssoorrtt//2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.


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.


33..2288 SSoorrttiinngg LLiissttss


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  3.5).
    Duplicates  are removed.  Implemented by translating the  input list
    into  a temporary  array,  calling the  C-library function  qqssoorrtt((3))
    using  PPLL__ccoommppaarree(()) for  comparing  the elements,  after  which  the
    result is translated into the result list.


mmssoorrtt((_+_L_i_s_t_, _-_S_o_r_t_e_d))
    Equivalent to ssoorrtt//22, but does not remove duplicates.


kkeeyyssoorrtt((_+_L_i_s_t_, _-_S_o_r_t_e_d))
    _L_i_s_t  is  a list  of  Key-Value pairs  (e.g.  terms of  the  functor
    `-'  with  arity  2).    kkeeyyssoorrtt//22  sorts  _L_i_s_t  like  mmssoorrtt//22,  but
    only  compares  the  keys.    Can  be  used  to sort  terms  not  on
    standard  order, but  on any criterion  that can  be expressed on  a
    multi-dimensional scale.   Sorting on more than one criterion can be
    done  using terms as keys,  putting the first criterion as  argument
    1,  the second as argument 2,  etc.  The order of  multiple elements
    that have the same _K_e_y is not changed.


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 mmssoorrtt//22, but determines the order of two  terms by
    applying  _P_r_e_d to pairs  of elements from _L_i_s_t  (see aappppllyy//22).   The
    predicate  should succeed if the first element should be  before the
    second.


33..2299 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((_+_V_a_r_, _+_G_o_a_l_, _-_B_a_g))
    Creates  a  list  of the  instantiations  _V_a_r 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.    ffiinnddaallll//33  is
    equivalent  to  bbaaggooff//33  with  all free  variables  bound  with  the
    existence  operator (^), except that bbaaggooff//33 fails when goal  has no
    solutions.


bbaaggooff((_+_V_a_r_, _+_G_o_a_l_, _-_B_a_g))
    Unify  _B_a_g with the alternatives of _V_a_r, if _G_o_a_l has  free variables
    besides  the one  sharing  with _V_a_r  bagof will  backtrack over  the
    alternatives  of  these  free  variables,   unifying  _B_a_g  with  the
    corresponding  alternatives of _V_a_r.   The construct +Var^Goal  tells
    bagof  not to  bind  _V_a_r in  _G_o_a_l.   bbaaggooff//33  fails if  _G_o_a_l has  no
    solutions.

    The  example below  illustrates bbaaggooff//3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((_+_V_a_r_, _+_G_o_a_l_, _-_S_e_t))
    Equivalent  to bbaaggooff//33, but sorts the  result using ssoorrtt//22 to get  a
    sorted list of alternatives without duplicates.


33..3300 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 aappppllyy//2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  cchheecckklliisstt//2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.


33..3311 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).


33..3322 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 wwrriitteeff//[[11,,22]],  which  is  compatible  with
Edinburgh C-Prolog.   The  second is  ffoorrmmaatt//[[11,,2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
ffoorrmmaatt//[[11,,22]] as this predicate is defined in  C. Otherwise compatibility
reasons might tell you which predicate to use.


33..3322..11 WWrriitteeff


wwrriittee__l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 |
             |      |nnll//[[00,,1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 ASCII  code  <_n_n_n> is |

             |______|output_(NB_:_<_n_n_n>_is_read_as_ddeecciimmaall)____|

    Note  that \l,  \\bnfmeta{nnn}  and \\  are interpreted  differently
    when character-escapes are in effect.  See section 2.11.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  pprriinntt//11 the next item (mnemonic:  term)   |    |

              | %q  |wwrriittee//11the next item                     |

              |     |wwrriitteeqq//11the next item                    |
              | %d  |Write the term,  ignoring operators.  See|
              |     |also  wwrriittee__tteerrmm//22.      Mnemonic:    old|
              | %p  |Edinburgh ddiissppllaayy//11.                     |

              |     |pprriinntt//11the next item (identical to %t)   |
              | %n  |Put  the next item  as a  character (i.e.|

              |     |it is an ASCII value)                    |
              | %r  |Write the  next item  N times where  N is|
              |     |the second item (an integer)             |
              | %s  |Write the  next item  as a String  (so it|
              |     |must be a list of characters)            |
              | %f  |Perform a ttttyyfflluusshh//0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 wwrriitteeff//2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, []).


33..3322..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   ASCII  values,   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  ASCII values the  argument need  not be put  in a  list.
    Otherwise the arguments are put in a list.

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

      ~  Output the tilde itself.

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

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

      d  Output  next argument  as  a decimal  number.    It  should  be
         an integer.    If  a numeric  argument is  specified  a dot  is
         inserted _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 ddiissppllaayyqq//1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 pprriinntt//11.

      q  Give the next argument to wwrriitteeqq//1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 a string of  ASCII characters or a string  (see ssttrriinngg//11
         and section 3.21) 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 ASCII value of the character  used for
         padding.   This  can be  used to  do left  or right  alignment,
         centering, distributing, etc.   See also  ~| and ~+ to set  tab
         stops.  A 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 wwrriittee//11.

    Example:

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

    Will output

                                 Statistics

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

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 ffoorrmmaatt//2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 ffoorrmmaatt//2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, []).'


33..3322..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.


33..3333 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.   The  library package  library(tty) builds on  top of  these
predicates.


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
    lliinnee__ccoouunntt//22  and  lliinnee__ppoossiittiioonn//2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
    ttttyy__ggeett__ccaappaabbiilliittyy//3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  ttttyy__ppuutt//22 and  ttttyy__ggoottoo//22 to  a
    specific stream.  Default is user_output.


33..3344 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,  sshheellll//[[11,,2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
    wwiinn__eexxeecc//22.


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.


ggeetteennvv((_+_N_a_m_e_, _-_V_a_l_u_e))
    Get Unix environment variable  (see csh(1) and sh(1)).  Fails if the
    variable does not exist.


sseetteennvv((_+_N_a_m_e_, _+_V_a_l_u_e))
    Set   Unix  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 sshheellll//[[00--22]] and can be requested using ggeetteennvv//22.


uunnsseetteennvv((_+_N_a_m_e))
    Remove Unix environment variable from the environment.


ggeett__ttiimmee((_-_T_i_m_e))
    Return  the number of seconds that elapsed since the epoch  of Unix,
    1  January 1970, 0  hours.  _T_i_m_e  is a floating  point number.   Its
    granularity is system dependent.  On sun, this is 1/60 of a second.


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  ggeett__ttiimmee//11,  ttiimmee__ffiillee//2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.


33..3355 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.  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 resulting  _D_i_r_e_c_t_o_r_y name
    ends  with the directory separator character /.  If _F_i_l_e is  an atom
    that does not  contain any directory separator characters, the empty
    atom '' is returned.  See also ffiillee__bbaassee__nnaammee//22.


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.    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))
    Unlink _F_i_l_e from the Unix 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.


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  Unix file specification  into an absolute  path.  User  home
    directory  expansion (~ and ~<_u_s_e_r>) and variable expansion  is done.
    The  absolute  path  is canonised:    references  to .  and  ..  are
    deleted.   SWI-Prolog  uses absolute file  names to register  source
    files  independent  of the  current  working directory.    See  also
    aabbssoolluuttee__ffiillee__nnaammee//33.


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 conformation process:

    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, aabbssoolluuttee__ffiillee__nnaammee//33will 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.

    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 aacccceessss__ffiillee//2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 [''].

    ffiillee__eerrrroorrss((_f_a_i_l_/_t_r_u_e))
         Report if  the  path cannot  be resolved  or be  silent.    The
         default is to 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.


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 aabbssoolluuttee__ffiillee__nnaammee//22 and
    pprroolloogg__ttoo__ooss__ffiilleennaammee//2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.


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.


cchhddiirr((_+_P_a_t_h))
    Change working directory to _P_a_t_h.


33..3366 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 (pprroolloogg//00).


aabboorrtt
    Abort  the Prolog  execution and  start a  new top  level.   If  the
    -t toplevel  command  line options  is given  this  goal is  started
    instead  of  entering the  default  interactive top  level.    Break
    environments  are aborted as  well.  All  open files except for  the
    terminal  related files are  closed.   The input- and output  stream
    again refers to _u_s_e_r.


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 aatt__hhaalltt//11.
    hhaalltt//0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 hhaalltt//0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  feature
    (ffeeaattuurree//22).    The pprroolloogg//00 predicate  is terminated (succeeds)  by
    typing the end-of-file character (Unix:  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.5.


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 rreeaadd__tteerrmm//3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  (pprroolloogg//00).   See also eexxppaanndd__aannsswweerr//22 and
    tteerrmm__eexxppaannssiioonn//2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.


33..3377 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 pprroottooccooll//1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 pprroottooccooll//11 or  pprroottooccoollaa//11
    and unifies _F_i_l_e with the current protocol output file.


33..3388 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


ttrraaccee
    Start  the tracer.   ttrraaccee//00  itself cannot be  seen in the  tracer.
    Note  that  the Prolog  toplevel treats  ttrraaccee//00 special;  it  means
    `trace the next goal'.


ttrraacciinngg
    Succeeds  when  the tracer  is  currently switched  on.    ttrraacciinngg//00
    itself can not be seen in the tracer.


nnoottrraaccee
    Stop the tracer.  nnoottrraaccee//00 itself cannot be seen in the 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 ttrraaccee//22  activates debug  mode (see ddeebbuugg//00).    Each
    time  a port (of the 4-port model) is passed that has  a trace-point
    set  the goal is printed as  with ttrraaccee//00.  Unlike ttrraaccee//0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 ddeebbuuggggiinngg//0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 oonnccee//11.  Later implementations may have
    the same semantics as ccaallll//11.


ddeebbuugg
    Start debugger (stop at spy points).


nnooddeebbuugg
    Stop debugger (do not trace, nor stop at spy points).


ddeebbuuggggiinngg
    Print debug status and spy points on current output stream.


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

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 lleeaasshh//1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))
    Unify  _O_l_d  with  the current  value  of  the unknown  system  flag.
    On  success  _N_e_w  will be  used  to specify  the  new  value.    _N_e_w
    should  be  instantiated  to either  fail  or trace  and  determines
    the  interpreters action  when an undefined  predicate which is  not
    declared  dynamic  is encountered  (see ddyynnaammiicc//11).    fail  implies
    the  predicate  just  fails silently.     trace implies  the  tracer
    is  started.    Default is  trace.   The  unknown flag  is local  to
    each  module and uunnkknnoowwnn//22  is module  transparent.   Using it as  a
    directive  in a module  file will only  change the unknown flag  for
    that  module.   Using the  :/2 construct  the behaviour on  trapping
    an  undefined predicate can  be changed for any  module.  Note  that
    if  the unknown flag  for a module equals  fail the system will  not
    call  eexxcceeppttiioonn//33 and will nnoott try to resolve the predicate  via the
    dynamic  library system.   The system will  still try to import  the
    predicate from the public module.


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.  ccoonnssuulltt//1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|  ||

    |                         rreeaadd__ccllaauussee//11 (used by  ccoonnssuulltt//11)  warns |               ||
    |                         on variables  only  appearing once  in  a |               ||
    |                         term  (clause)  which  have  a  name  not |               ||

    ||atom          |  on    |starting with an underscore.              ||              ||

    |               |        |rreeaadd//1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   |Read  and  derivatives  transform   "..." |
    |               |        |into a prolog  string instead  of a  list |
    |_______________|________|of_ASCII_characters.______________________|


33..3399 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 3.2.
     _______________________________________________________________
     | cputime     |(User)  cpu time  since Prolog  was started  in|
     |             |seconds                                        |
     | inferences  |Total number  of passes via  the call and  redo|
     |             |ports since Prolog was started.                |
     | heap        |Estimated   total  size   of   the  heap   (see|

     |             |section 2.12.1.1)                              |
     | heapused    |Bytes heap in use by Prolog.                   |
     | heaplimit   |Maximum   size   of   the    heap   (see   sec-|
     |             |tion 2.12.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._____|_

                   Table 3.2:  Keys for ssttaattiissttiiccss//2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  oonnccee//1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.


33..4400 FFiinnddiinngg PPeerrffoorrmmaannccee BBoottttlleenneecckkss

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

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

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  ttiimmee//11.    Collect  profiling  statistics
    according  to  style  (see  pprrooffiilleerr//22)  and  show  the  top  _N_u_m_b_e_r
    procedures  on  the  current  output  stream  (see  sshhooww__pprrooffiillee//11).
    The  results  are kept  in  the database  until  rreesseett__pprrooffiilleerr//00 or
    pprrooffiillee//33  is called and can be displayed again with sshhooww__pprrooffiillee//11.
    pprrooffiillee//33 is the normal  way to invoke the profiler.  The predicates
    below are low-level predicates that can be used for special cases.


sshhooww__pprrooffiillee((_+_N_u_m_b_e_r))
    Show  the collected  results of the  profiler.   Stops the  profiler
    first  to avoid interference from sshhooww__pprrooffiillee//11.  It shows  the top
    _N_u_m_b_e_r predicates according the percentage cpu-time used.


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  one
    of  off,  plain or  cumulative.    plain implies  the  time used  by
    children  of a predicate is not added to the time of  the predicate.
    For  status cumulative  the time  of children is  added (except  for
    recursive  calls).     Cumulative profiling  implies  the  stack  is
    scanned  up  to the  top  on  each time  slice  to find  all  active
    predicates.    This implies the  overhead grows  with the number  of
    active  frames on the stack.  Cumulative profiling  starts debugging
    mode  to disable tail recursion optimisation, which  would otherwise
    remove  the necessary  parent environments.   Switching status  from
    plain  to cumulative  resets the profiler.    Switching to and  from
    status  off does not reset  the collected statistics, thus  allowing
    to suspend profiling for certain parts of the program.


rreesseett__pprrooffiilleerr
    Switches the profiler to off and clears all collected statistics.


pprrooffiillee__ccoouunntt((_+_H_e_a_d_, _-_C_a_l_l_s_, _-_P_r_o_m_i_l_a_g_e))
    Obtain profile statistics  of the predicate specified by _H_e_a_d.  _H_e_a_d
    is  an atom  for predicates with  arity 0  or a term  with the  same
    name  and arity as the predicate required (see ccuurrrreenntt__pprreeddiiccaattee//22).
    _C_a_l_l_s  is unified with the number  of `calls' and `redos' while  the
    profiler was active.   _P_r_o_m_i_l_a_g_e is unified with the relative number
    of  counts the predicate  was active (cumulative)  or on top of  the
    stack (plain).  _P_r_o_m_i_l_a_g_e is an integer between 0 and 1000.


33..4411 MMeemmoorryy MMaannaaggeemmeenntt

Note:   lliimmiitt__ssttaacckk//22and  ttrriimm__ssttaacckkss//00have 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  ttrriimm__ssttaacckkss//00 is invoked  to  release  the
    collected memory resources.


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.


33..4422 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 5.4 for loading Windows DLL's into SWI-Prolog.


33..4422..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  3.21 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.


33..4422..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.

    The  example below  registers the Prolog  ffeeaattuurree//2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(feature, F, V),
                            feature(F, V)).

    ?- open_dde_conversation(prolog, feature, 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.


33..4433 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  ddwwiimm__mmaattcchh//2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.


CChhaapptteerr 44..  UUSSIINNGG MMOODDUULLEESS


44..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.


44..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) :-
        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.


44..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 mmoodduullee//22 directive as its first term.   The mmoodduullee//2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 rreevveerrssee//22.

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

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

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

44..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 uussee__mmoodduullee//[[11,,22]] predicates load a  module file and  import
(part of  the) public predicates  of the file.   The iimmppoorrtt//1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 eennssuurree__llooaaddeedd//1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  eennssuurree__llooaaddeedd//11 becomes
    apparent  if the file  is already  loaded into another  module.   In
    this  case eennssuurree__llooaaddeedd//1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
    uussee__mmoodduullee//[[11,,22]].    iimmppoorrtt//1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
the module's default module.  On success, normal execution is resumed.


44..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
default module of module  user is system, making all  built-in predicate
definitions available  as defaults.    Built-in predicates  thus can  be
overruled by defining them in module user before they are used.

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

44..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
uussee__mmoodduullee//[[11,,2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.


44..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 4.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 3.7.


44..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 aasssseerrtt//1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.


44..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
mmaapplliisstt//33  is declared  module_transparent.    This  implies the  context
module remains extend, the  context module of add_extension/3.   This way
mmaapplliisstt//3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).


44..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 4.7).

For  this purpose,  the reserved  term ://2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


44..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 uunnkknnoowwnn//22).

Import and  export from dynamically  created world  is arranged via  the
predicates iimmppoorrtt//11 and eexxppoorrtt//11:

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

44..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
    ddyynnaammiicc//1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  library(quintus)  and  provides  a
    partial  emulation of the Quintus predicate.  See section  4.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 ssoouurrccee__ffiillee//[[11,,2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.
    ccoonntteexxtt__mmoodduullee//1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 uussee__mmoodduullee//[[11,,22]].  Note  that predicates are
    normally  exported using the directive mmoodduullee//22.  eexxppoorrtt//1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 pprreeddiiccaattee__pprrooppeerrttyy//22.


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.


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 pprroolloogg//0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).
    ...


44..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 `mmeettaa__pprreeddiiccaattee//11' declaration were SWI-Prolog  has
    the mmoodduullee__ttrraannssppaarreenntt//11 declaration.

The mmeettaa__pprreeddiiccaattee//11 declaration  causes the compiler  to tag  arguments
that pass  module sensitive information  with the  module using the  ://2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  mmeettaa__pprreeddiiccaattee//1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 ffiinnddaallll//33
using aasssseerrtt//11  and rreettrraacctt//11.    The example  in figure  4.1 gives  the
solution.
:- module(findall, [findall/3]).

:- dynamic

        solution/1.

:- module_transparent
        findall/3,
        store/2.

findall(Var, Goal, Bag) :-

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

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

        fail.
store(_, _).

collect(Bag) :-
        ...,

                  Figure 4.1:  ffiinnddaallll//33 using modules


44..99..11 EEmmuullaattiinngg mmeettaa__pprreeddiiccaattee//11

The Quintus  mmeettaa__pprreeddiiccaattee//11 directive can  in many  cases be  replaced
by  the   transparent  declaration.      Below  is  the  definition   of
mmeettaa__pprreeddiiccaattee//11as available from library(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 55..  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.


55..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 (?- feature(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 Global actions on Prolog (halt, break, abort, etc.)


55..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 three  ways.  Using  _s_t_a_t_i_c
_l_i_n_k_i_n_g,  the  extensions,  a  small  description  file  and  the  basic
SWI-Prolog object  file 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..


55..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.
The  ffeeaattuurree//22 predicate  may be  used to  find out  what other  linking
methods are provided for this version.

  o _f_e_a_t_u_r_e_(_o_p_e_n___s_h_a_r_e_d___o_b_j_e_c_t_, _t_r_u_e_)
    If  this succeeds  the system  provides the  ooppeenn__sshhaarreedd__oobbjjeecctt//22and
    related predicates that  allow for handling Unix shared object files
    based  on the  Unix library functions  ddllooppeenn((2)) and  friends.   See
    section 5.4.

  o _f_e_a_t_u_r_e_(_d_l_l_, _t_r_u_e_)
    If  this succeeds the system provides an interface for  loading .DLL
    files by means of ooppeenn__ddllll//22 and friends.  See section 5.4.

If either  the feature  open_shared_object  or dll is  true, the  library
library(shlib) provides  a common  interface for  loading foreign  files
from Prolog.


55..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.

Loading  shared objects  or DLL  files provides  sharing and  protection
and is  generally the best choice.   If  a saved-state is created  using
qqssaavvee__pprrooggrraamm//[[11,,22]],  an iinniittiiaalliizzaattiioonn//1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.


55..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).   This interface is portable
to  all machines  providing  the function  ddllooppeenn((2)) or  an  equivalent,
normally  from the  library -ldl.    These functions  provide the  basic
interface layer.   It is advised to use the predicates from  section 5.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 llooaadd__ffoorreeiiggnn__lliibbrraarryy//[[11,,22]].


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  ooppeenn__sshhaarreedd__oobbjjeecctt//2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.


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 PPLL__rreeggiisstteerr__ffoorreeiiggnn(()).


55..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.   Currently  it
supports MS-Windows  DLL (.DLL) libraries and  Unix .so (shared  object)
files.


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(Lib, install).


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,  aabbssoolluuttee__ffiillee__nnaammee//33is  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  ffiillee__sseeaarrcchh__ppaatthh//2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  PPLL__rreeggiisstteerr__ffoorreeiiggnn(()) to
    declare functions in the library as foreign predicates.


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(),  this
    function  will be called without  arguments and its return value  is
    ignored.    Next,  aabboolliisshh//2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  PPLL__rreeggiisstteerr__ffoorreeiiggnn(())when
    the entry-point of the library was called.

Figure  5.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 5.1:  MessageBox() example in Windows NT


55..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.    .../pl refers  to  the
SWI-Prolog  home  directory (see  ffeeaattuurree//22).     <_a_r_c_h> refers  to  the
architecture identifier that may be obtained using ffeeaattuurree//22.

      .../pl/runtime/<_a_r_c_h>/libpl.a SWI-Library
      .../pl/include/SWI-Prolog.h   Include file
      .../pl/include/SWI-Stream.h   Stream I/O include file
      .../pl/include/SWI-Exports    Export declarations (AIX only)
      .../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  .../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:

/*  Copyright (c) 1991 Jan Wielemaker. All rights reserved.
    jan@swi.psy.uva.nl

    Purpose: Skeleton for extensions
*/

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

55..44..22 DDyynnaammiicc LLiinnkkiinngg bbaasseedd oonn llooaadd__ffoorreeiiggnn//[[22,,55]]

The  predicates  below  are considered  obsolete.     They  are  briefly
described here  for compatibility  purposes.   New code  should use  the
predicates from the library(shlib).


llooaadd__ffoorreeiiggnn((_+_F_i_l_e_, _+_E_n_t_r_y))
    Load  a  foreign file  or list  of files  specified by  _F_i_l_e.    The
    files  are searched for similar to ccoonnssuulltt//11.  Except that  the `.o'
    extension is used rather than `.pl'.

    _E_n_t_r_y  defines the  entry point of  the resulting  executable.   The
    entry  point  will  be  called  by Prolog  to  install  the  foreign
    predicates.


llooaadd__ffoorreeiiggnn((_+_F_i_l_e_, _+_E_n_t_r_y_, _+_O_p_t_i_o_n_s_, _+_L_i_b_r_a_r_i_e_s_, _+_S_i_z_e))
    The  first two arguments  are identical to  those of llooaadd__ffoorreeiiggnn//22.
    _O_p_t_i_o_n_s is (a list  of) additional option to be given to the loader.
    The  options are inserted  just before the files.   _L_i_b_r_a_r_i_e_s is  (a
    list  of) libraries to be passed to  the loader.  They  are inserted
    just  after the files.   If _S_i_z_e  is specified Prolog first  assumes
    that  the resulting  executable will fit  in _S_i_z_e  bytes and do  the
    loading in one pass.


ffoorreeiiggnn__ffiillee((_?_F_i_l_e))
    Is  true if  _F_i_l_e is  the absolute  path name  of a  file loaded  as
    foreign file.


55..55 IInntteerrffaaccee DDaattaa ttyyppeess


55..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  PPLL__nneeww__tteerrmm__rreeff(())or  PPLL__nneeww__tteerrmm__rreeffss(()).   These  references
normally live till the foreign function returns control  back to Prolog.
Their scope  can be explicitly  limited using PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())and
PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(())/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(()).

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
PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())and 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(())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 PPLL__nneeww__tteerrmm__rreeff(())
    A  term  created  by  PPLL__nneeww__tteerrmm__rreeff(())is  normally  used  to  build
    temporary  terms or be  written by one  of the interface  functions.
    For example,  PPLL__ggeett__aarrgg(())writes a reference  to the term-argument in
    its last argument.

  o _C_r_e_a_t_e_d _b_y PPLL__nneeww__tteerrmm__rreeffss((_i_n_t _n))
    This   function  returns  a   set  of  term   refs  with  the   same
    characteristics as PPLL__nneeww__tteerrmm__rreeff(()).  See PPLL__ooppeenn__qquueerryy(()).

  o _C_r_e_a_t_e_d _b_y PPLL__ccooppyy__tteerrmm__rreeff((_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 5.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.


_t_e_r_m___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.


_t_e_r_m___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.   PPLL__ooppeenn__qquueerryy(())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;

      ...
    }


_t_e_r_m___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.


_v_o_i_d 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  PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(()),
    PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(())and 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(()).


55..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.


55..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
    PPLL__ooppeenn__qquueerryy(())/PPLL__nneexxtt__ssoolluuttiioonn(())/PPLL__cclloossee__qquueerryy(()) to  handle   back-
    tracking from C.

ffiidd__tt Frame         Identifier.                          Used         by
    PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())/PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(()).

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.


55..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


55..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:


_v_o_i_d PPLL__ssuucccceeeedd(())
    Succeed deterministically.  PL_succeed is defined as return TRUE.


_v_o_i_d PPLL__ffaaiill(())
    Fail  and  start  Prolog  backtracking.     PL_fail  is  defined  as
    return FALSE.


55..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   PPLL__rreeggiisstteerr__ffoorreeiiggnn(()))  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  PPLL__ffoorreeiiggnn__ccoonnttrrooll(())
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.


_v_o_i_d 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 PPLL__ffoorreeiiggnn__ccoonntteexxtt(())will return  the handle passed via
    PPLL__rreettrryy(()).   This handle is  a 30 bits signed  value (two bits  are
    used for status indication).


_v_o_i_d PPLL__rreettrryy__aaddddrreessss((_v_o_i_d _*))
    As  PPLL__rreettrryy(()),  but ensures an  address as  returned by malloc()  is
    correctly recovered by 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(()).


_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 PPLL__rreettrryy(()) 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 PPLL__rreettrryy__aaddddrreessss(()).

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 5.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, foreign_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:
        free(ctxt);
        PL_succeed;
  }
}

     Figure 5.2:  Skeleton for non-deterministic foreign functions


55..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.


_a_t_o_m___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 for the entire session.


_c_o_n_s_t _c_h_a_r _* 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.


_f_u_n_c_t_o_r___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.


_a_t_o_m___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.


_i_n_t 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.


55..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 vvaarr//11, aattoomm//1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.


55..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


_i_n_t 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2._______________________|

The functions PL_is_<_t_y_p_e> are an alternative to PPLL__tteerrmm__ttyyppee(()).  The test
PPLL__iiss__vvaarriiaabbllee((_t_e_r_m))is  equivalent  to PPLL__tteerrmm__ttyyppee((_t_e_r_m))== PL_VARIABLE,
but  the first  is considerably  faster.   On  the other  hand, using  a
switch over  PPLL__tteerrmm__ttyyppee(())is  faster and  more readable  then using  an
if-then-else using  the functions  below.   All  these functions  return
either TRUE or FALSE.


_i_n_t 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.


_i_n_t 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.


_i_n_t 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.


_i_n_t 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.


_i_n_t 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.


_i_n_t 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.


_i_n_t 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 PPLL__ggeett__ffuunnccttoorr(()),  followed by testing the
    functor, but easier to write and faster.


_i_n_t 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 [].


_i_n_t 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).


_i_n_t 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.


55..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.


_i_n_t 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
    PPLL__aattoomm__cchhaarrss(())and PPLL__nneeww__aattoomm(()).  If there is no need  to access the
    data  (characters) of  an atom,  it is advised  to manipulate  atoms
    using their handle.


_i_n_t 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.


_i_n_t PPLL__ggeett__ssttrriinngg((_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.


_i_n_t 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 four  (4) 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 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_ALL                |Convert  if term  is  any  of the  above,|
    |________________________|except_for_variables_____________________|
    | 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__mmaalllloocc((3))__________________________________________________________||


_i_n_t 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 PPLL__ggeett__cchhaarrss((_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.


_i_n_t 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  PPLL__ggeett__lloonngg(()),  but avoids a  warning
    from the compiler.  See also PPLL__ggeett__lloonngg(()).


_i_n_t 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.


_i_n_t 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.
    PPLL__ppuutt__ppooiinntteerr(())/PPLL__ggeett__ppooiinntteerr(())guarantees pointers in the  range of
    malloc() are handled without truncating.


_i_n_t 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.


_i_n_t 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
    PPLL__ggeett__nnaammee__aarriittyy(())and PPLL__iiss__ffuunnccttoorr(()).


_i_n_t 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 PPLL__ggeett__ffuunnccttoorr(())and
    PPLL__iiss__ffuunnccttoorr(()).


_i_n_t 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,.


_i_n_t 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.


55..66..33..33 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 [] */
}


_i_n_t 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.


_i_n_t 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.


_i_n_t 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.


_i_n_t PPLL__ggeett__nniill((_t_e_r_m___t _+_l))
    Succeeds if  represents the atom [].


55..66..33..44 AAnn eexxaammppllee::  ddeeffiinniinngg wwrriittee//11 iinn CC

Figure  5.3 shows  a  simplified  definition of  wwrriittee//11  to  illustrate
the described  functions.   This simplified version  does not deal  with
operators.    It is  called  ddiissppllaayy//1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 5.3:  A Foreign definition of ddiissppllaayy//11


55..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 PPLL__ccaallll(()) and
PL_open_query.


_v_o_i_d 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.


_v_o_i_d 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
    PPLL__nneeww__aattoomm(())and PPLL__aattoomm__cchhaarrss(()).


_v_o_i_d 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.


_v_o_i_d 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 PPLL__ppuutt__ssttrriinngg__nncchhaarrss(()).


_v_o_i_d 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 5.6.17.


_v_o_i_d 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.


_v_o_i_d 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.


_v_o_i_d 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', PPLL__ggeett__ppooiinntteerr(())will get the pointer back.


_v_o_i_d 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.


_v_o_i_d 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 PPLL__ccoonnss__ffuunnccttoorr(()).


_v_o_i_d PPLL__ppuutt__lliisstt((_t_e_r_m___t _-_l))
    Same as PPLL__ppuutt__ffuunnccttoorr((_l_, _P_L___n_e_w___f_u_n_c_t_o_r_(_P_L___n_e_w___a_t_o_m_(_"_._")), 2)).


_v_o_i_d PPLL__ppuutt__nniill((_t_e_r_m___t _-_l))
    Same as PPLL__ppuutt__aattoomm__cchhaarrss((_"_[_]_")).


_v_o_i_d 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.


_v_o_i_d 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();

            PL_put_atom_chars(a1, "gnu");
            PL_put_integer(a2, 50);
            PL_cons_functor(t, PL_new_functor(PL_new_atom("animal"), 2),
                            a1, a2);

    After  this sequence, the term-references _a_1 and _a_2 may be  used for
    other purposes.


_v_o_i_d 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  PPLL__ccoonnss__ffuunnccttoorr(()),  but _a_0 is an  array
    of  term references as returned by PPLL__nneeww__tteerrmm__rreeffss(()).  The  length of
    this  array should  match the  number of arguments  required by  the
    functor.


_v_o_i_d 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.


55..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  PPLL__uunniiffyy(()), 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, buf);
  }

  PL_fail;
}

Using PPLL__uunniiffyy__aattoomm__cchhaarrss(()), 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;
}


_i_n_t 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.


_i_n_t 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.


_i_n_t 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.


_i_n_t 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.


_v_o_i_d PPLL__uunniissy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
    PPLL__ppuutt__ssttrriinngg__nncchhaarrss(()).


_v_o_i_d 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))

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

_i_n_t 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.


_i_n_t 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.


_i_n_t 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
    PPLL__ppuutt__ppooiinntteerr(())and PPLL__ggeett__ppooiinntteerr(()).


_i_n_t 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.


_i_n_t 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 PPLL__ppuutt__lliisstt(()),
    followed by  a call to PPLL__uunniiffyy(()), or we can use the code  below.  If
    the  predicate argument is unbound,  the difference is minimal  (the
    code  based on PPLL__ppuutt__lliisstt(())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;

      while(*environ)
      { if ( !PL_unify_list(l, a, l) ||
             !PL_unify_atom_chars(a, *environ) )
          PL_fail;
      }

      return PL_unify_nil(l);
    }


_i_n_t PPLL__uunniiffyy__nniill((_t_e_r_m___t _?_l))
    Unify _l with the atom [].


_i_n_t 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.


_i_n_t 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.

    The type identifiers are:

    PL_VARIABLE nnoonnee
         No op.  Used in arguments of PL_FUNCTOR.

    PL_ATOM aattoomm__tt
         Unify the argument with an atom, as in PPLL__uunniiffyy__aattoomm(()).

    PL_INTEGER lloonngg
         Unify the argument with an integer, as in PPLL__uunniiffyy__iinntteeggeerr(()).

    PL_FLOAT ddoouubbllee
         Unify  the  argument  with  a  float,  as  in  PPLL__uunniiffyy__ffllooaatt(()).
         Note  that,  as the  argument  is  passed using  the  C  vararg
         conventions, a float must be casted to a double explicitly.

    PL_STRING ccoonnsstt cchhaarr **
         Unify   the   argument   with   a   string   object,    as   in
         PPLL__uunniiffyy__ssttrriinngg__cchhaarrss(()).

    PL_TERM tteerrmm__tt
         Unify  a  subterm.    Note  this  may the  return  value  of  a
         PPLL__nneeww__tteerrmm__rreeff(())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 PPLL__uunniiffyy__aattoomm__cchhaarrss(()).

    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_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();
    }


55..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 to interfaces  for
this.    For the  first, a  term is  created that  could be  used as  an
argument to  ccaallll//11 and  next PPLL__ccaallll(()) 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
PPLL__ooppeenn__qquueerryy(()), PPLL__nneexxtt__ssoolluuttiioonn(())and  PPLL__ccuutt__qquueerryy(())or PPLL__cclloossee__qquueerryy(()).
This mechanism is more powerful, but also more complicated to use.


55..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.


_p_r_e_d_i_c_a_t_e___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.


_p_r_e_d_i_c_a_t_e___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  PPLL__pprreedd(()),   but  provides  a  more  convenient   interface
    to the C-programmer.


_v_o_i_d 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
    PPLL__pprreeddiiccaattee(()).    If the  predicate was  imported  into the  module
    given  to PPLL__pprreeddiiccaattee(()), this function will return the  module where
    the predicate was defined.


55..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 PPLL__nneexxtt__ssoolluuttiioonn(()).   Be sure  to
call PPLL__ccuutt__qquueerryy(()) or PPLL__cclloossee__qquueerryy(())on  any query  you opened  before
opening the next or returning control back to Prolog.


_q_i_d___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 ccoonntteexxtt__mmoodduullee//11 and mmoodduullee__ttrraannssppaarreenntt//11.  The  _p
    argument  specifies the  predicate, and  should be the  result of  a
    call  to PPLL__pprreedd(()) or PPLL__pprreeddiiccaattee(()).   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 PPLL__nneeww__tteerrmm__rreeffss((_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  pprriinntt//11 calling ppoorrttrraayy//1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 PPLL__eexxcceeppttiioonn(()).

    PL_Q_PASS_EXCEPTION
         As PL_Q_CATCH_EXCEPTION,  but do  not invalidate the  exception-
         term  while   calling  PPLL__cclloossee__qquueerryy(()).       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);
      ...
    }


_i_n_t 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.


_v_o_i_d 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
    PPLL__ooppeenn__qquueerryy(())in this context.


_v_o_i_d PPLL__cclloossee__qquueerryy((_q_i_d))
    As  PPLL__ccuutt__qquueerryy(()),  but all  data and bindings  created by the  query
    are destroyed.


_i_n_t 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 _d_e_b_u_g_, _p_r_e_d_i_c_a_t_e___t _p_r_e_d_, _t_e_r_m___t _+_t_0))

    Shorthand   for  PPLL__ooppeenn__qquueerryy(()),   PPLL__nneexxtt__ssoolluuttiioonn(()),  PPLL__ccuutt__qquueerryy(()),
    generating  a single solution.   The arguments  are the same as  for
    PPLL__ooppeenn__qquueerryy(()), the return value is the same as PPLL__nneexxtt__ssoolluuttiioonn(()).


_i_n_t 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 oonnccee//1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  5.4
    shows an example to  obtain the number of defined atoms.  All checks
    are omitted to improve readability.


55..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.    PPLL__cclloossee__qquueerryy(())allows  for destructing  the  data,  while
leaving the  term-references.   The calls below may  be used to  destroy
term-references and data.  See figure 5.4 for an example.


_f_i_d___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.


_v_o_i_d 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.


_v_o_i_d 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 PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(()), but  also undo  all bindings  made
    since the open and destroy all Prolog data.

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 5.4:  Calling Prolog


55..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.


_m_o_d_u_l_e___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.


_i_n_t 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);
      ...


_a_t_o_m___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.


_m_o_d_u_l_e___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.


55..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    PPLL__eexxcceeppttiioonn(()),      PPLL__tthhrrooww(())    and
PPLL__rraaiissee__eexxcceeppttiioonn(()),  the   interface  functions  to  detect  and   gen-
erate Prolog exceptions from C-code.  PPLL__tthhrrooww(()) and PPLL__rraaiissee__eexxcceeppttiioonn(())
from  the  C-interface   to  raise  an  exception  from  foreign   code.
PPLL__tthhrrooww(()) exploits the  C-function longjmp() to  return immediately  to
the  innermost PPLL__nneexxtt__ssoolluuttiioonn(()).    PPLL__rraaiissee__eexxcceeppttiioonn(()) 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.

PPLL__eexxcceeppttiioonn(()) may be used after a call to  PPLL__nneexxtt__ssoolluuttiioonn(())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 PPLL__eexxcceeppttiioonn(()), it can handle this exception,  or return
with  the exception.    Some caution  is required  though.    It is  nnoott
allowed to call PPLL__cclloossee__qquueerryy(())or 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(())afterwards,
as this  will invalidate the  exception term.   Below  is the code  that
calls a Prolog defined arithmetic function (see aarriitthhmmeetthhiicc__ffuunnccttiioonn//11).

If PPLL__nneexxtt__ssoolluuttiioonn(()) succeeds, the  result is  analysed and  translated
to  a number,  after  which the  query  is closed  and all  Prolog  data
created  after  PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())is  destroyed.     On  the  other
hand,  if  PPLL__nneexxtt__ssoolluuttiioonn(()) fails and  if  an  exception  was  raised,
just  pass  it.    Otherwise  generate an  exception  (PPLL__eerrrroorr(()) is  an
internal  call  for  building  the  standard  error  terms  and  calling
PPLL__rraaiissee__eexxcceeppttiioonn(())).     After  this,  the  Prolog  environment  should
be  discarded using  PPLL__ccuutt__qquueerryy(())and PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(())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;
}


_i_n_t 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  tthhrrooww//1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, PL_new_functor(PL_new_atom("type_error"), 2),
                        PL_CHARS, "atom",
                        PL_TERM,  to);

        return PL_raise_exception(except);
      }
    }


_i_n_t 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 PPLL__rraaiissee__eexxcceeppttiioonn(()), but returns  using the C  longjmp()
    function to the innermost PPLL__nneexxtt__ssoolluuttiioonn(()).


_t_e_r_m___t PPLL__eexxcceeppttiioonn((_q_i_d___t _q_i_d))
    If  PPLL__nneexxtt__ssoolluuttiioonn(()) fails, this  can  be  due to  normal  failure
    of  the  Prolog  call, or  because  an  exception was  raised  using
    tthhrrooww//11.   This function returns  a handle to the exception term  if
    an exception was raised, or 0 if the Prolog goal simply failed..


55..66..1100 MMiisscceellllaanneeoouuss


_i_n_t 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 ccoommppaarree//33.


55..66..1111 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  ????.
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 PPLL__ssiiggnnaall(()) 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 PPLL__ssiiggnnaall(())for its installation.


_v_o_i_d _(_*_)_(_) 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.


55..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

PPLL__wwaarrnniinngg(()) prints a standard  Prolog warning  message to the  standard
error (user_error) stream.   Please note  that new code should  consider
using  PPLL__rraaiissee__eexxcceeppttiioonn(())to  raise  a  Prolog exception.     See  also
section 3.8.


_i_n_t 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
    pprriinnttff((2)).  Always returns FALSE.


55..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


_i_n_t PPLL__aaccttiioonn((_i_n_t_, _C___t_y_p_e))
    Perform  some  action on  the  Prolog system.    _i_n_t  describes  the
    action,  _C___t_y_p_e provides the argument if necessary.   The actions are
    listed in table 5.1.
    ___________________________________________________________________
    | PL_ACTION_TRACE        |Start Prolog tracer                      |
    | PL_ACTION_DEBUG        |Switch on Prolog debug mode              |
    | PL_ACTION_BACKTRACE    |Print   backtrace   on   current   output|
    |                        |stream.   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.          |
    | PL_ACTION_ABORT        |Generate a Prolog abort.   This call does|
    |                        |not return.                              |
    | PL_ACTION_BREAK        |Create a  standard Prolog  break environ-|
    |                        |ment.     Returns after  the  user  types|
    |                        |control-D.                               |

    | PL_ACTION_SYMBOLFILE   |The  argument (a  char  *) is  considered|
    |                        |to  be hold  the  symbolfile for  further|
    |                        |incremental   loading.        Should   be|
    |                        |called by user  applications that perform|
    |                        |incremental loading  as well and  want to|
    |________________________|inform_Prolog_of_the_new_symbol_table.___|

                     Table 5.1:  PPLL__aaccttiioonn(())options


55..66..1144 QQuueerryyiinngg PPrroolloogg


_C___t_y_p_e 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 5.2.
    ___________________________________________________________________
    | PL_QUERY_ARGC          |Return an  integer holding the  number of|
    |                        |arguments given to Prolog from Unix.     |
    | PL_QUERY_ARGV          |Return  a char  **  holding the  argument|
    |                        |vector given to Prolog from Unix.        |
    | PL_QUERY_SYMBOLFILE    |Return  a  char  *  holding  the  current|

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

    | PL_MAX_INTEGER         |Return a  long, representing  the maximal|
    |                        |integer  value  represented  by  Prolog's|
    |                        |tagged integers.                         |
    | PL_MIN_INTEGER         |Return  a long,  represented 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 5.2:  PPLL__qquueerryy(()) options


55..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


_i_n_t PPLL__rreeggiisstteerr__ffoorreeiiggnn((_n_a_m_e_, _a_r_i_t_y_, _f_u_n_c_t_i_o_n_, _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.   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_PPLL__rreettrryy(())._________________________|


_v_o_i_d 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))
    Register  foreign predicates from a table  of structures.  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;

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

      ...
    }

    The  function PPLL__rreeggiisstteerr__eexxtteennssiioonnss(())is the only PL_*  function that
    may  be called bbeeffoorree PPLL__iinniittiiaalliissee(()).  The  functions are registered
    after  registration  of the  SWI-Prolog builtin  foreign  predicates
    and  before loading  the initial  saved state.    This implies  that
    iinniittiiaalliizzaattiioonn//11 directives can refer to them.


55..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.


_P_L___d_i_s_p_a_t_c_h___h_o_o_k___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);


_v_o_i_d 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 aabboorrtt//00 is  executed.   SWI-Prolog aabboorrtt//0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);


_i_n_t 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  PPLL__aabboorrtt__hhooookk(()).   Returns FALSE if  no
    such hook is found, TRUE otherwise.


55..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 PPLL__ppuutt__ssttrriinngg__nncchhaarrss(())and retrieved using
    PPLL__ggeett__ssttrriinngg__cchhaarrss(()).   It is  generally good practice  to wrap  the
    string  in a compound term with arity 1, so Prolog can  identify the
    type.    ppoorrttrraayy//1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 5.6.1.1.


55..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 ffeeaattuurree//2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  bbiittvveeccttoorr//1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
nneettmmaasskk//4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  3.42) 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  PPLL__uunniiffyy__ppooiinntteerr(())and  PPLL__ggeett__ppooiinntteerr(()).
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.


55..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 aa CC--pprrooggrraamm

As  of  version  2.1.0,  SWI-Prolog may  be  embedded  in  a  C-program.
To  reach  at  a compiled  C-program  with  SWI-Prolog  as  an  embedded
application is very  similar to creating a statically linked  SWI-Prolog
executable as described in section 5.4.1.

The  file   .../pl/include/stub.c  defines   SWI-Prologs  default   main
program:

int
main(int argc, char **argv)
{ if ( !PL_initialise(argc, argv) )
    PL_halt(1);

  PL_install_readline();        /* delete if you don't want readline */

  PL_halt(PL_toplevel() ? 0 : 1);
}

This  may be  replaced with  your own  main C-program.    The  interface
function  PPLL__iinniittiiaalliissee(()) mmuusstt  be   called  before  any  of  the  other
SWI-Prolog  foreign  language  functions  described  in   this  chapter.
PPLL__iinniittiiaalliissee(()) interprets all  the command-line  arguments, except  for
the -t toplevel flag that is interpreted by PPLL__ttoopplleevveell(()).


_i_n_t 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_, _c_h_a_r _*_*_e_n_v_i_r_o_n))
    Initialises  the SWI-Prolog heap and  stacks, restores the boot  QLF
    file,  loads the system and personal initialisation files,  runs the
    aatt__iinniittiiaalliizzaattiioonn//11 hooks and finally runs the -g goal hook.

    PPLL__iinniittiiaalliissee(()) returns  1  if all  initialisation succeeded  and  0
    otherwise.    Various fatal errors  may cause  PL_initialise to  call
    PPLL__hhaalltt((_1)), preventing it from returning at all.


_v_o_i_d 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.


_i_n_t PPLL__ttoopplleevveell(())
    Runs  the  goal of  the -t toplevel  switch  (default pprroolloogg//00)  and
    returns 1 if successful, 0 otherwise.


_v_o_i_d PPLL__hhaalltt((_i_n_t _s_t_a_t_u_s))
    Cleanup  the Prolog  environment and  calls exit()  with the  status
    argument.


55..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  .../pl/include/stub.c.    The main()  routine is  modified  to
suit your application.   PPLL__iinniittiiaalliissee(())mmuusstt be passed  the program-name
(_a_r_g_v_[_0_])  (Win32:    the  executing  program  can   be  obtained  using
GGeettMMoodduulleeFFiilleeNNaammee(())).   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 ffeeaattuurree//2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>)

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

55..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 5.5.

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

PL_extension PL_extensions [] =
{

/*{ "name",     arity,  function,       PL_FA_<flags> },*/

  { NULL,       0,      NULL,           0 }     /* terminating line */
};

#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, FALSE, pred, h0);

    PL_halt(rval ? 0 : 1);

  }

  return 0;
}

             Figure 5.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


55..88 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  5.6 shows the C-source
file, figure 5.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 5.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 5.7:  Compiling the C-source and loading the object file


55..99 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


55..99..11 MMeemmoorryy AAllllooccaattiioonn

SWI-Prolog's  memory  allocation  is  based  on  the  mmaalllloocc((3))  library
routines.   Foreign  applications can safely  use mmaalllloocc((3)),  rreeaalllloocc((3))
and ffrreeee((3)).   Memory allocation using bbrrkk((2)) or ssbbrrkk((2)) is  not allowed
as these calls conflict with mmaalllloocc((3)).


55..99..22 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 ggddbb((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).


55..99..33 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.


55..99..44 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 PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())/PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(())combination  is lacking
from both  other Prologs.   SICStus has  PPLL__nneeww__tteerrmm__rreeffss((_0)), followed  by
PPLL__rreesseett__tteerrmm__rreeffss(())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 66..  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 rreessoouurrccee//33 and ooppeenn__rreessoouurrccee//3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 qqssaavvee__pprrooggrraamm//2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 6.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, |
|            |      |               |change  the  predicates  in   their |
|            |      |               |current  state  and  keep   reading |
|            |      |               |resources  from  their  source  (if |
|            |      |               |present).  See also rreessoouurrccee//33.     |
| autoload   |      |     bool      |If true, run aauuttoollooaadd//0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 6.1:  <_K_e_y> = <_V_a_l_u_e> pairs for qqssaavvee__pprrooggrraamm//22

    Before   writing  the  data   to  file,   qqssaavvee__pprrooggrraamm//22 will   run
    aauuttoollooaadd//00  to all  required  autoloading the  system can  discover.
    See aauuttoollooaadd//0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.


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 qqssaavvee__pprrooggrraamm//[[11,,22]] to ensure the  saved
    state  will not  depend  on one  of the  libraries.   The  predicate
    aauuttoollooaadd//0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  mmaapplliisstt//3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  rreeqquuiirree//1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.


66..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
qqssaavvee__pprrooggrraamm//[[11,,2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 6.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 iinniittiiaalliizzaattiioonn//11.

  o Database  references as returned by ccllaauussee//33, rreeccoorrddeedd//33, etc.   are
    not preserved and may thus not be part of the database when saved.


66..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
iinnssttaallll(()).

If this  file is compiled  into a shared  library, llooaadd__ffoorreeiiggnn__lliibbrraarryy//11
will load this library and call the installation  function to initialise
the  foreign code.    If it  is  loaded as  a static  extension,  define
iinnssttaallll(()) as the predicate iinnssttaallll//0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 ffiillee__sseeaarrcchh__ppaatthh//2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 ffiillee__sseeaarrcchh__ppaatthh//22.


66..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 qqssaavvee__pprrooggrraamm//2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 rreessoouurrccee//33.
They are accessed using the predicate ooppeenn__rreessoouurrccee//3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  hheellpp//0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.


66..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 all  characters, except  for $ and  :,
    which  are  reserved for  internal usage  by  the resource  library.
    _C_l_a_s_s  describes  the  what kind  of  object  we are  dealing  with.
    In  the  current implementation,  it  is just  an  atom.    _F_i_l_e_S_p_e_c
    is  a  file specification  that may  exploit ffiillee__sseeaarrcchh__ppaatthh//22 (see
    aabbssoolluuttee__ffiillee__nnaammee//22).

    Normally,  resources are  defined as unit  clauses (facts), but  the
    definition  of this  predicate can  also imply  rules.   For  proper
    generation  of the saved  state generation, it  must be possible  to
    enumerate  the available  resources by calling  this predicate  with
    all its arguments unbound.

    Dynamic  rules  can  be  useful  to turn  all  files  in  a  certain
    directory  into resources, without  specifying a resources for  each
    file.     For example,  assume  the  ffiillee__sseeaarrcchh__ppaatthh//22icons  refers
    to  the resource directory  containing (XPM) icons.   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 tehe 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  ooppeenn__rreessoouurrccee//33  first  checks  rreessoouurrccee//3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   rreessoouurrccee//33  declarations   and/or   files
    containing  resource   info  thus  immediately  affect  the  running
    environment,  while the runtime  system quickly accesses the  system
    resources.


66..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 ffiillee__sseeaarrcchh__ppaatthh//22mechanism
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)
            ).


66..55 UUssiinngg cchhppll ffoorr CCoonnffiigguurraattiioonn IInnffoorrmmaattiioonn


66..55..11 CChhaannggiinngg tthhee eemmuullaattoorr ooff aa rruunnttiimmee aapppplliiccaattiioonn

The program chpl, may  be used to manipulate the header of  a SWI-Prolog
bootfile or state created with qqssaavvee__pprrooggrraamm//[[11,,22]].

It will be used  most commonly by the installer of a  SWI-Prolog runtime
application  to specify  the path  to the  emulator.    If the  end-user
decided to install the SWI-Prolog runtime environment in

/usr/local/lib/rt-pl-2.1.4

the gnat application can be told to use this emulator using:

% /usr/local/lib/rtpl-2.1.4/bin/chpl -e /usr/local/lib/rt-pl-
2.1.4/bin/pl gnat

Now,  gnat may  be  installed in  any public  or private  directory  for
binaries.


66..55..22 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-2.1.4.     A  user  wants
to  install  gnat,   but  gnat  will  look  for  its   configuration  in
/usr/local/lib/rt-pl-2.1.4/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

For a more  widely used executable, this is  not very comfortable.   The
user may decide  to edit the shell-script part  of gnat.  Upto the  line
holding

# End Header

gnat is a  simple /bin/sh script.   After this line, the file is  binary
and may  contain long lines.   Most editors  are not capable of  editing
such files.   Instead of editing the file directly, the  program cchhppll((1))
may be used  to extract and replace the  header of gnat.  The  following
editing sequence  will work  with any  editor capable  of editing  ASCII
files.

% chpl -x gnat > gnat.hdr
% emacs gnat.hdr
% chpl -h gnat.hdr gnat

The header may be changed to the following to install gnat properly:

#!/bin/sh
# SWI-Prolog version: 2.1.4
# SWI-Prolog save-version: 25
exec ${SWIPL-/usr/local/lib/rt-pl-2.1.4/bin/pl} -x $0 \
-p gnatdir=/users/bob/lib/gnat "$@"


66..66 TThhee RRuunnttiimmee EEnnvviirroonnmmeenntt


66..66..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, mmaakkee((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
    pprrooffiillee//3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 _f_e_a_t_u_r_e_(_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 ccllaauussee//[[22,,3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  feature inhibits  listing your  program.   It is  only a  very
    limited protection however.

The  following  fragment   is  an  example  for  building  the   runtime
environment in  HOME/lib/rt-pl-2.1.4.   If possible, the  shared-library
interface should be configured to ensure it can serve  a large number of
applications.

% cd pl-2.1.4
% 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/pl     |The emulator itself               |

            |_bin/chpl___|The_utility_to_change_the_runtime_|
            | man/chpl.1 |Manual page for chpl              |
            |_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 77..  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.


77..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  pprroolloogg__ccuurrrreenntt__ffrraammee//11,
    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//44or  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!

    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  nntthh__ccllaauussee//33 and
         ccllaauussee__pprrooppeerrttyy//2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.


77..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_, _+_P_C_, _-_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  is one  of call,  redo,  exit, fail  or unify.    _F_r_a_m_e is  an
    integer  reference to  the current  local stack frame.    _P_C is  the
    current  value  of the  program-counter, relative  to  the start  of
    the  current clause,  or 0  if it  is invalid,  for example  because
    the  current frame runs a foreign  predicate, or no clause has  been
    selected  yet.    _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  3.38 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).


uusseerr::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 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
    ppoorrttrraayy//11 and mmuullttiiffiillee//11.


77..33 EExxcceeppttiioonn HHaannddlliinngg

A  start has  been made  to  make exception  handling available  to  the
Prolog user.   On exceptions a  dynamic and multifile defined  predicate
eexxcceeppttiioonn//33 is called.   If this user defined predicate  succeeds Prolog
assumes the  exception has  been taken care  of.   Otherwise the  system
default exception handler is called.


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 eexxcceeppttiioonn//3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
         print the  default error  warning  and start  the tracer.    If
         the predicate succeeds it should instantiate the  last argument
         either to the  atom fail to tell  Prolog to fail the  predicate
         or the atom retry to tell Prolog to retry the predicate.   This
         only  makes sense  if the  exception  handler has  defined  the
         predicate.  Otherwise it will lead to a loop.

    wwaarrnniinngg
         If prolog  wants to  give a warning  while reading  a file,  it
         will first raise the  exception _w_a_r_n_i_n_g.  The  context argument
         is  a  term  of  the  form  warning(<_P_a_t_h>, <_L_i_n_e_N_o>, <_M_e_s_s_a_g_e>),
         where _P_a_t_h  is  the absolute  filename of  the  file prolog  is
         reading; _L_i_n_e_N_o  is an  estimate of the  line number where  the
         error occurred and  _M_e_s_s_a_g_e is a  Prolog string indicating  the
         message.    The _A_c_t_i_o_n  argument  is ignored.    The  error  is
         supposed to be presented  to the user if the  exception handler
         succeeds.   Otherwise  the standard Prolog  warning message  is
         printed.

         This exception  is used  by the library(emacs_interface),  that
         integrates error handling with GNU Emacs.


77..44 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  feature(readline, true)
succeeds.    They allow  for direct  interaction with  the GNU  readline
library.  See also rreeaaddlliinnee((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 88..  SSUUMMMMAARRYY


88..11 PPrreeddiiccaatteess

The  predicate summary  is used  by the  Prolog  predicate aapprrooppooss//11  to
suggest predicates from a keyword.

 !/0                           Cut (discard choicepoints)
 !/1                           Cut block.  See bblloocckk//3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
 </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 nnoott//11
 \=/2                          Not unifyable

 \==/2                         Not identical
 \=@=/2                        Not structural identical
 ^/2                           Existential quantification (bbaaggooff//33, sseettooff//33)
 |/2                           Disjunction of goals.  Same as ;//2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
 append/1                      Append to a file
 append/3                      Concatenate lists
 apply/2                       Call goal with additional arguments
 apropos/1                     library(online_help) Show related predicates and manual sections
 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)

 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 hhaalltt//11
 at_initialization/1           Register goal to run at start-up
 atom/1                        Type check for an atom
 atom_char/2                   Convert between atom and ASCII value
 atom_chars/2                  Convert between atom and list of ASCII values
 atom_length/2                 Determine length of an atom

 atom_prefix/2                 Test for start of atom
 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_dll_function/2           Win32:  Call function in dynamic link library (.dll file)
 call_shared_object_function/2 UNIX: Call C-function in shared (.so) file
 call_with_depth_limit/3       Prove goal with bounded depth
 catch/3                       Call goal, watching for exceptions
 character_count/2             Get character index on a stream

 chdir/1                       Change working directory
 checklist/2                   Invoke goal on all members of a list
 clause/2                      Get clauses of a predicate
 clause/3                      Get clauses of a predicate
 clause_property/2             Get properties of a clause
 close/1                       Close stream
 close_dde_conversation/1      Win32:  Close DDE channel

 close_dll/1                   Win32:  Close dynamic link library (.dll file)
 close_shared_object/1         UNIX: Close shared library (.so file)
 compare/3                     Compare, using a predicate to determine the order
 compiling/0                   Is this a compilation run?
 compound/1                    Test for compound term
 concat/3                      Append two atoms
 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                Convert time stamp
 copy_term/2                   Make a copy of a term
 current_arithmetic_function/1 Examine evaluable functions
 current_atom/1                Examine existing atoms
 current_flag/1                Examine existing flags

 current_foreign_library/2     library(shlib) Examine loaded shared libraries (.so files)
 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_op/3                  Examine current operator declarations
 current_output/1              Get the current output stream

 current_predicate/2           Examine existing predicates
 current_signal/3              Current software signal mapping
 current_stream/3              Examine open streams
 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
 debugging/0                   Show debugger status
 default_module/2              Get the default modules of a module
 delete/3                      Delete all matching members from a list
 delete_file/1                 Remove a file from the file system

 discontiguous/1               Indicate distributed definition of a predicate
 dup_stream/2                  Duplicate I/O streams
 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
 ed/0                          Edit last edited predicate

 ed/1                          Edit a predicate
 edit/0                        Edit last edited file
 edit/1                        Edit a file
 edit_source/1                 (hook) Intercept editing
 ensure_loaded/1               Consult a file if that has not yet been done
 erase/1                       Erase a database record or clause
 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 bblloocckk//3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_query/4                Expanded entered query
 expand_term/2                 Compiler:  expand read term into clause(s)

 explain/1                     library(explain) Explain argument
 explain/2                     library(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 bblloocckk//33
 feature/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
 flatten/2                     Transform nested list into flat list

 float/1                       Type check for a floating point number
 flush/0                       Output pending characters on current stream
 flush_output/1                Output pending characters on specified stream
 forall/2                      Prove goal for all solutions of another goal
 foreign_file/1                Examine loaded foreign files
 format/1                      Formatted output
 format/2                      Formatted output with arguments
 format/3                      Formatted output on a stream

 format_predicate/2            Program ffoorrmmaatt//[[11,,22]]
 free_variables/2              Find unbound variables in a term
 functor/3                     Get name and arity of a term or construct a term
 garbage_collect/0             Invoke the garbage collector
 gensym/2                      Generate unique atoms from a base
 get/1                         Read first non-blank character
 get/2                         Read first non-blank character from a stream

 get0/1                        Read next character
 get0/2                        Read next character from a stream
 get_single_char/1             Read next character from the terminal
 get_time/1                    Get current time
 getenv/2                      Get shell environment variable
 ground/1                      Verify term holds no unbound variables
 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
 ignore/1                      Call the argument, but always succeed
 import/1                      Import a predicate from a module
 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
 intersection/3                Set intersection
 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
 is_set/1                      Type check for a set

 keysort/2                     Sort, using a key
 last/2                        Last element of a list
 leash/1                       Change ports visited by the tracer
 length/2                      Length of a list
 library_directory/1           (hook) Directories holding Prolog libraries
 limit_stack/2                 Limit stack expansion
 line_count/2                  Line number on stream

 line_position/2               Character position in line on stream
 list_to_set/2                 Remove duplicates
 listing/0                     List program in current module
 listing/1                     List predicate
 load_files/2                  Load source files with options
 load_foreign/2                Load foreign (C) module
 load_foreign/5                Load foreign (C) module
 load_foreign_library/1        library(shlib) Load shared library (.so file)

 load_foreign_library/2        library(shlib) Load shared library (.so file)
 make/0                        Reconsult all changed source files
 make_fat_filemap/1            Win32:  Create file containing non-FAT filenames
 make_library_index/1          Create autoload file INDEX.pl
 maplist/3                     Transform all elements of a list
 member/2                      Element is member of a list
 memberchk/2                   Deterministic mmeemmbbeerr//22

 merge/3                       Merge two sorted lists
 merge_set/3                   Merge two sorted sets
 message_hook/3                Intercept pprriinntt__mmeessssaaggee//22
 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
 name/2                        Convert between atom and list of ASCII characters
 nl/0                          Generate a newline
 nl/1                          Generate a newline on a stream
 nodebug/0                     Disable debugging
 nonvar/1                      Type check for bound term
 noprotocol/0                  Disable logging of user interaction

 nospy/1                       Remove spy point
 nospyall/0                    Remove all spy points
 not/1                         Negation by failure (argument not provable).  Same as \+//11
 notrace/0                     Stop tracing
 notrace/1                     Do not debug argument goal
 nth0/3                        N-th element of a list (0-based)
 nth1/3                        N-th element of a list (1-based)
 nth_clause/3                  N-th clause of a predicate

 number/1                      Type check for integer or float
 number_chars/2                Convert between number and atom
 numbervars/4                  Enumerate unbound variables of a term using a given base
 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)
 peek_byte/1                   Read character without removing
 peek_byte/2                   Read character 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 pprriinntt//11
 portray_clause/1              Pretty print a clause
 predicate_property/2          Query predicate attributes

 predsort/3                    Sort, using a predicate to determine the order
 preprocessor/2                Install a preprocessor before the compiler
 print/1                       Print a term
 print/2                       Print a term on a stream
 print_message/2               Print message from (exception) term
 profile/3                     Obtain execution statistics
 profile_count/3               Obtain profile results on a predicate
 profiler/2                    Obtain/change status of the profiler

 prolog/0                      Run interactive toplevel
 prolog_current_frame/1        Reference to goal's environment stack
 prolog_frame_attribute/3      Obtain information on a goal environment
 prolog_list_goal/1            Hook.  Intercept tracer 'L' command
 prolog_load_context/2         Context information for directives
 prolog_skip_level/2           Indicate deepest recursion to trace
 prolog_to_os_filename/2       Convert between Prolog and OS filenames

 prolog_trace_interception/4   library(user) Intercept the Prolog tracer
 prompt1/1                     Change prompt for 1 line
 prompt/2                      Change the prompt used by rreeaadd//11
 proper_list/1                 Type check for list
 protocol/1                    Make a log of the user interaction
 protocola/1                   Append log of the user interaction to file
 protocolling/1                On what file is user interaction logged
 put/1                         Write a character

 put/2                         Write a character on a stream
 qcompile/1                    Compile source to Quick Load File
 qload/1                       Load Quick Load File as ccoonnssuulltt//11
 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
 read_variables/2              Read clause including variable names
 read_variables/3              Read clause including variable names from stream

 recorda/2                     Record term in the database (first)
 recorda/3                     Record term in the database (first)
 recorded/2                    Obtain term from the database
 recorded/3                    Obtain term from the database
 recordz/2                     Record term in the database (last)
 recordz/3                     Record term in the database (last)
 redefine_system_predicate/1   Abolish system definition

 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
 restore/1                     Restore saved-state (ssaavvee//11, ssaavvee__pprrooggrraamm//11)
 retract/1                     Remove clause from the database
 retractall/1                  Remove unifying clauses from the database

 reverse/2                     Inverse the order of the elements in a list
 same_file/2                   Succeeds if arguments refer to same file
 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
 select/3                      Select element of a list

 set_feature/2                 Define a system feature
 set_input/1                   Set current input stream from a stream
 set_output/1                  Set current output stream from a stream
 set_tty/2                     Set `tty' stream
 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
 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_position/3             Get/seek to position in file
 string/1                      Type check for string
 string_concat/3               ccoonnccaatt//33 for strings (non-deterministic)

 string_length/2               Determine length of a string
 string_to_atom/2              Conversion between string and atom
 string_to_list/2              Conversion between string and list of ASCII
 style_check/1                 Change level of warnings
 sublist/3                     Determine elements that meet condition
 subset/2                      Generate/check subset relation
 substring/4                   Get part of a string
 subtract/3                    Delete elements that do not meet condition

 succ/2                        Logical integer successor relation
 swritef/2                     Formatted write on a string
 swritef/3                     Formatted write on a string
 tab/1                         Output number of spaces
 tab/2                         Output number of spaces on a stream
 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
 throw/1                       Raise an exception (see ccaattcchh//3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
 ttyflush/0                    Flush output on terminal
 union/3                       Union of two sets
 unknown/2                     Trap undefined predicates
 unload_foreign_library/1      library(shlib) Detach shared library (.so file)
 unsetenv/1                    Delete shell environment variable
 use_module/1                  Import a module
 use_module/2                  Import predicates from a module

 var/1                         Type check for unbound variable
 visible/1                     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
 write/1                       Write term

 write/2                       Write term to stream
 write_ln/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


88..22 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


88..33 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
 multifile          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.

                                  738
