University of Amsterdam Dept. of Social Science Informatics (SWI) Herengracht 196, 1016 BS Amsterdam The Netherlands Tel. (+31) 20 5252073 SWI-Prolog 1.6 Reference Manual Jan Wielemaker jan@swi.psy.uva.nl SWI-Prolog is a WAM (Warren Abstract Machine, ) based implementation of Prolog. SWI-Prolog has been designed and implemented such that it can easily be modified for experiments with logic programming and the relation between logic programming and other programming paradigms (such as the object oriented PCE environment, ). SWI-Prolog has a rich set of built-in predicates and reasonable performance, which makes it possible to develop substantial applications in it. The current version offers a module system, garbage collection and an interface to the C language. This document gives an overview of the features, system limits and built-in predicates. Copyright (C) 1990 Jan Wielemaker Chapter 1 Introduction SWI-Prolog has been designed and implemented to get a Prolog implementation which can be used for experiments with logic programming and the relation to other programming paradigms. The intention was to build a Prolog environment which offers enough power and flexibility to write substantial applications, but is straightforward enough to be modified for experiments with debugging, optimisation or the introduction of non-standard data types. Performance optimisation is limited due to the main objectives: portability (SWI-Prolog is entirely written in C and Prolog) and modifiability. SWI-Prolog is based on a very restricted form of the WAM (Warren Abstract Machine) described in which defines only 7 instructions. Prolog can easily be compiled into this language and the abstract machine code is easily decompiled back into Prolog. As it is also possible to wire a standard 4-port debugger in the WAM interpreter there is no need for a distinction between compiled and interpreted code. Besides simplifying the design of the Prolog system itself this approach has advantages for program development: the compiler is simple and fast, the user does not have to decide in advance whether debugging is required and the system only runs slightly slower when in debug mode. The price we have to pay is some performance degradation (taking out the debugger from the WAM interpreter improves performance by about 20%) and somewhat additional memory usage to help the decompiler and debugger. SWI-Prolog extends the minimal set of instructions described in to improve performance. While extending this set care has been taken to maintain the advantages of decompilation and tracing of compiled code. The extensions include specialised instructions for unification, predicate invocation, some frequently used built-in predicates, arithmetic, and control (;/2, |/2), if-then (->/2) and not (\+/1). This manual does not describe the full syntax and semantics of SWI-Prolog, nor how one should write a program in Prolog. These subjects have been described extensively in the literature. See , and . For more advanced Prolog material see . Syntax and standard operator declarations confirm to the `Edinburgh standard'. Most built in predicates are compatible with those described in . SWI-Prolog also offers a number of primitive predicates compatible with Quintus Prolog, and BIM_Prolog . 1 1.1 Status This manual describes version 2.0.6 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 unfrequently used builtin predicates. Some bugs are known to the author. They are described as footnotes in this manual. 1.2 Should you be Using SWI-Prolog? There are a number of reasons why you better choose a commercial Prolog system, or another academic product: SWI-Prolog is not supported Although I usually fix bugs shortly after a bug report arrives, I cannot promise anything. Now that the sources are provided, you can always dig into them yourself. Memory requirements and performance are your first concerns A number of commercial compilers are more keen on memory and performance than SWI-Prolog. I do not wish to offer some of the nice features of the system, nor its portability to compete on raw performance. You need features not offered by SWI-Prolog In this case you may wish to give me suggestions for extensions. If you have great plans, please contact me (you might have to implement them yourself however). On the other hand, SWI-Prolog offers some nice facilities: Nice environment This includes `Do What I Mean', automatic completion of atom names, history mechanism and a tracer that operates on single key-strokes. Interfaces to standard Unix editors are provided, as well as a facility to maintain programs (see make/0). Very fast compiler The compiler handles about 100K bytes per second on a SPARC-II processor. Transparent compiled code 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. Profiling SWI-Prolog offers tools for performance analysis, which can be very useful to optimise programs. Unless you are very familiar with Prolog and Prolog performance considerations this might be more helpful than a better compiler without these facilities. Flexibility SWI-Prolog allows for easy and flexible integration with C, both Prolog calling C functions as C calling Prolog predicates. SWI-Prolog is provided in source form, which implies SWI-Prolog can be linked in with another package. Command line options and predicates to obtain information from the system and feedback into the system are provided. Integration with PCE SWI-Prolog offers a tight integration to the Object Oriented Package for User Interface Development, called PCE (). PCE is now also available for X-windows. 1.3 Graphics SWI-Prolog has no provisions for graphical applications itself. The standard graphical environment to be used with SWI-Prolog is XPCE. XPCE/SWI-Prolog provides an interactive graphical develpment platform that is portable over many Unix/X11 implementations as well as MS-Windows (3.1) and Windows-NT (3.5). XPCE is a licenced product. A fully functional free demo version for PC/Linux is available from ftp://swi.psy.uva.nl/pub/xpce/linux For more information, see URL http://swi.psy.uva.nl/projects/xpceor contact xpce-request@swi.psy.uva.nl. 1.4 Version 1.5 Release Notes There are not many changes between version 1.4 and 1.5. The C-sources have been cleaned and comments have been updated. The stack memory management based on using the MMU has been changed to run on a number of system-V Unix systems offering shared memory. Handling dates has been changed. All functions handling dates now return a floating point number, expressing the time in seconds since january 1, 1970. A predicate convert_time/8 is available to get the year, month, etc. The predicate time/6 has been deleted. get_time/1 and convert_time/8 together do the same. From version 1.5, the system is distributed in source form, rather than in object form as used with previous releases. This allows users to port SWI-Prolog to new machines, extend and improve the system. If you want your changes to be incorporated in the next release, please indicate all changes using a C-preprocessor flag and send complete source files back to me. Difference listings are of no use, as I generally won't have exactly the same version around. 1.5 Version 1.6 Release Notes Version 1.6 is completely compatible with version 1.5. Some new features have been added, the system has been ported to various new platforms and there is a provisional interface to GNU-Emacs. This interface will be improved and documented later. The WAM virtual-machine interpreter has been modified to use GCC-2's support for threated code. From version 1.6, the sources are now versioned using the CVS version control system. 1.6 Version 1.7 Release Notes Version 1.7 intergrates the GNU-readline library, offering powerful history and command-line editing both using EMACS and vi key-bindings. 1.7 Version 1.8 Release Notes Version 1.8 offers a stack-shifter to provide dynamically expanding stacks on machines that donot offer operating-system support for implementing dynamic stacks. 1.8 Version 1.9 Release Notes Version 1.9 offers better portability including an MS-Windows 3.1 version. Changes to the Prolog system include: Redefinition of system predicates Redefinition of system predicates was allowed silently in older versions. Version 1.9 only allows it if the new definition is headed by a :- redefine_system_predicate/1 directive. `Answer' reuse 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. Better sourcecode administration Allows for proper updating of multifile predicates and finding the sources of individual clauses. 1.9 Version 2.0 Release Notes 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: 32-bit Virtual Machine Removes various limits and improves performance. Inline foreign functions `Simple' foreign predicates no longer build a Prolog stack-frame, but are directly called from the VM. Notably provides a speedup for the test predicates such as var/1, etc. Various compatibility improvements Stream based I/O library All SWI-Prolog's I/O is now handled by the stream-package defined in the foreign include file . Physical I/O of Prolog streams may be redefined through the foreign language interface, facilating much simpler integration in window environments. Version 2.0.6 offers a few incompatibilities: retractall/1 In previous releases, the definition of retractall/1 was: retractall(Term) :- retract(Term), fail. retractall(_). As from version 2.0.6, retractall/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. Foreign interface types All foreign interface types now have names ending in _t to lessen the chance for conflicts. term, atomic, functorand modulehave #define's for backward compatibility. PL_register_foreign() 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 (99will generate a compiler warning, but work properly otherwise. Predicates with more than one attributes must be changed. PL_dispatch_events This pointer is replaced by PL_dispatch_hook(). A function was necessary for the Windows-NT .DLL interface. 1.10 Acknowledgements Some small parts of the Prolog code of SWI-Prolog are modified versions of the corresponding Edinburgh C-Prolog code: grammar rule compilation and writef/2. Also some of the C-code originates from C-Prolog: finding the path of the currently running executable and the code underlying absolute_file_name/2. Ideas on programming style and techniques originate from C-Prolog and Richard O'Keefe's thief editor. An important source of inspiration are the programming techniques introduced by Anjo Anjewierden in PCE version 1 and 2. I also would like to thank those who had the fade of using the early versions of this system, suggested extensions or reported bugs. Among them are Anjo Anjewierden, Huub Knops, Bob Wielinga, Wouter Jansweijer, Luc Peerdeman, Eric Nombden, Frank van Harmelen, Bert Rengel. Chapter 2 Overview 12 2.1 Starting SWI-Prolog from the Unix Shell It is advised to install SWI-Prolog as `pl' in the local binary directory. SWI-Prolog can then be started from the Unix shell by typing `pl'. The system will boot from the system's default boot file, perform the necessary initialisations and then enter the interactive top level. After the necessary system initialisation the system consults (see consult/1) the user's initialisation file. This initialisation file should be named `verb:plrc' and reside either in the current directory or in the user's home directory. If both exist the initialisation file from the current directory is loaded. The name of the initialisation file can be changed with the `-f file' option. After loading the initialisation file SWI-Prolog executes a user initialisation goal. The default goal is a system predicate that prints the banner message. The default can be modified with the `-g goal' option. Next the toplevel goal is started. Default is the interactive Prolog loop (see prolog/0). The user can overwrite this default with the `-t toplevel' option. 2.1.1 Command Line Options The full set of command line options is given below: -Lsize Give local stack size in K bytes (200 K default). Note that there is no space between the size option and its argument. For machines with dynamic stack allocation this flag sets the maximum value to which the stack is allowed to grow (2 Mbytes default). A maximum is useful to stop buggy programs from claiming all memory resources. -L0 sets the limit to the highest possible value. -Gsize Give global stack size in K bytes (100 K default). For machines with dynamic stack allocation the default is 4 Mbytes. See -L for more details. -Tsize Give trail stack size in K bytes (50 K default). For machines with dynamic stack allocation the default is 4 Mbytes. See -L for more details. -Asize Give argument stack size in K bytes (5 K default). For machines with dynamic stack allocation the default is 1 Mbytes. See -L for more details. -c file ... Compile files into an `intermediate code file'. See section 2.7. -o output Used in combination with -c or -b to determine output file for compilation. -O Optimised compilation. See please/3. -f file Use file as initialisation file instead of `.plrc'. `-f none' stops SWI-Prolog from searching for an initialisation file. -g goal Goal is executed just before entering the top level. Default is a predicate which prints the welcome message. The welcome message can thus be suppressed by giving -g true. goal can be a complex term. In this case quotes are normally needed to protect it from being expanded by the Unix shell. -t goal Use goal as interactive toplevel instead of the default goal prolog/0. goal can be a complex term. If the toplevel goal succeeds SWI-Prolog exits with status 0. If it fails the exit status is 1. This flag also determines the goal started by break/0 and abort/0. If you want to stop the user from entering interactive mode start the application with `-g goal' and give `halt' as toplevel. +/-tty Switches tty control (using ioctl(2)) on (+tty) or off (-tty). Normally tty control is switched on. This default depends on the installation. You may wish to switch tty control off if Prolog is used from an editor such as GNU EMACS. If switched off get_single_char/1 and the tracer will wait for a return. -x bootfile Boot from bootfile instead of the system's default boot file. A bootfile is a file resulting from a Prolog compilation using the -b or -c option. -r restorefile Restore a state created by save_program/[1,2] or save/[1,2] using the new-style saved-states. Equivalent to restore(restorefile) from Prolog. -- 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 initfile ... -c file ... Boot compilation. initfile ...are compiled by the C-written bootstrap compiler, file ...by the normal Prolog compiler. System maintenance only. -d level Set debug level to level. System maintenance only. 2.2 GNU Emacs Interface A provisional interface to GNU-Emacs is delivered with version 1.6 of SWI-Prolog. The interface is based on the freely distributed interface delivered with Quintus Prolog. When running Prolog as an inferior process under GNU-Emacs, there is support for finding predicate definitions, completing atoms, finding the locations of compilation-warnings and many more. For details, see the files pl/lisp/README and pl/lisp/swi-prolog.el. 2.3 Online Help Online help provides a fast lookup and browsing facility to this manual. The online manual can show predicate definitions as well as entire sections of the manual. help Equivalent to help(help/1). help(+What) Show specified part of the manual. What is one of: Name/Arity give help on specified predicate Name give help on named predicate with any arity or C interface function with that name Section display specified section. section numbers are dash-separated numbers: 2-3 refers to section 2.3 of the manual. Section numbers are obtained using apropos/1. Examples ?- help(assert). give help on predicate assert ?- help(3-4). display section 3.4 of the manual ?- help('PL_retry'). give help on interface function PL_retry() apropos(+Pattern) Display all predicates, functions and sections that have Pattern in their name or summary description. Lowercase letters in Pattern also match a corresponding uppercase letter. Example: ?- apropos(file). Display predicates, functions and sections that have `file' (or `File', etc.) in their summary description. explain(+ToExplain) 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 Name/Arity or a term of the form Module:Name/Arity, explain will try to explain the predicate as well as possible references to it. explain(+ToExplain, -Explanation) Unify Explanation with an explanation for ToExplain. Backtracing yields further explanations. 2.4 Query Substitutions SWI-Prolog offers a query substitution mechanism similar to that of Unix csh (csh(1)), called `history'. It allows the user to compose new queries from those typed before and remembered by the system. It also allows to correct queries and syntax errors. SWI-Prolog does not offer the Unix csh capabilities to include arguments. This is omitted as it is unclear how the first, second, etc. argument should be defined. The available history commands are shown in table 2.1. Figure 2.1 gives some examples. !!. Repeat last query !nr. Repeat query numbered !str. Repeat last query starting with !?str. Repeat last query holding ^old^new. Substitute into of last query !nr^old^new. Substitute in query numbered !str^old^new. Substitute in query starting with !?str^old^new. Substitute in query holding h. Show history list !h. Show this list Table 2.1: History commands /u4/staff/jan/.plrc consulted, 0.066667 seconds, 591 bytes Welcome to SWI-Prolog (version 1.5.0, August 1990) Copyright (c) 1990, University of Amsterdam. All rights reserved. 1 ?- append("Hello ", "World", L). L = [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100] Yes 2 ?- !!, writef('L = %s\n', [L]). append("Hello ", "World", L), writef('L = %s\n', [L]). L = Hello World L = [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100] Yes 3 ?- sublist(integer, [3, f, 3.4], L). L = [3] Yes 4 ?- ^integer^number. sublist(number, [3, f, 3.4], L). L = [3, 3.400000] Yes 5 ?- h. 1 append("Hello ", "World", L). 2 append("Hello ", "World", L), writef('L = %s\n', [L]). 3 sublist(integer, [3, f, 3.4], L). 4 sublist(number, [3, f, 3.4], L). 5 ?- !2^World^Universe. append("Hello ", "Universe", L), writef('L = %s\n', [L]). L = Hello Universe L = [72, 101, 108, 108, 111, 32, 85, 110, 105, 118, 101, 114, 115, 101] Yes 6 ?- halt. Figure 2.1: Some examples of the history facility 2.4.1 Limitations of the History System When in top level SWI-Prolog reads the user's queries using history_read/6 rather than read/1. This predicate first reads the current input stream up to a full stop. While doing so it maps all contiguous blank space onto a single space and deletes /* ... */ and % ... comments. Parts between double quotes (") or single quotes (') are left unaltered. Note that a Prolog full stop consists of a `non-symbol' character, followed by a period (.), followed by a blank character. `Symbol' characters are: #$&*+-./:<=>?@^`~. A single quote immediately preceded by a digit (0-9) considered part of the '... (e.g. 2'101; binary number 101) sequence. After this initial parsing the result is first checked for the special ^old^new. construction. If this fails the string is checked for all occurrences of the !, followed by a !, ?, a digit, a letter or an underscore. These special sequences are analysed and the appropriate substitution from the history list is made. From the above it follows that it is hard or impossible to correct quotation with single or double quotes, comment delimiters and spacing. 2.5 Reuse of toplevel bindings Bindings resulting from the successfull 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: 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.6 Overview of the Debugger SWI-Prolog has a standard 4-port tracer with an optional fifth port. This fifth port, called unify allows the user to inspect the result after unification of the head. The ports are called call, exit, redo, fail and unify. The tracer is started by the trace/0 command, when a spy point is reached and the system is in debugging mode (see spy/1 and debug/1) or when an error is detected at run time. Note that in the interactive toplevel goal trace/0 means ``trace the next query''. The tracer shows the port, displaying the port name, the current depth of the recursion and the goal. The goal is printed using the Prolog predicate print/1 (default), write/1 or display/1. An example using all five ports is shown in figure 2.3. 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 leashed ports (set with the predicate leash/1, default are call, exit, redo and fail) the user is prompted for an action. All actions are single character commands which are executed without waiting for a return (Unix `cbreak' mode), unless the command line option -tty is active. Tracer options: + Spy all Set a spy point (see spy/1) on the current predicate. No spy all Remove the spy point (see nospy/1) from the current predicate. / Find all Search for a port. After the `/', the user can enter a line to specify the port to search for. This line consists of a set of letters indicating the port type, followed by an optional term, that should unify with the goal run by the port. If no term is specified it is taken as a variable, searching for any port of the specified type. If an atom is given, any goal whose functor has a name equal to that atom matches. Examples: /f Search for any fail port /fe solve Search for a fail or exit port of any goal with name solve /c solve(a, _) Search for a call to solve/2 whose first argument is a variable or the atom a /a member(_, _) Search for any port on member/2. This is equivalent to setting a spy point on member/2. . Repeat find all Repeat the last find command (see `/') A Alternatives all Show all goals that have alternatives. C Context all Toggle `Show Context'. If on the context module of the goal is displayed between square brackets (see section 4). Default is off. L Listing all List the current predicate with listing/1. a Abort all Abort Prolog execution (see abort/0). b Break all Enter a Prolog break environment (see break/0). c Creep all Continue execution, stop at next port. (Also return, space). d Display all Write goals using the Prolog predicate display/1. e Exit all Terminate Prolog (see halt/0). f Fail call, redo, exit Force failure of the current goal g Goals all Show the list of parent goals (the execution stack). Note that due to tail recursion optimization a number of parent goals might not exist any more. h Help all Show available options (also `?'). i Ignore call, redo, fail Ignore the current goal, pretending it succeeded. l Leap all Continue execution, stop at next spy point. n No debug all Continue execution in `no debug' mode. p Print all Write goals using the Prolog predicate print/1 (default). r Retry redo, exit, fail Undo all actions (except for database and i/o actions) back to the call port of the current goal and resume execution at the call port. s Skip call, redo Continue execution, stop at the next port of this goal (thus skipping all calls to children of this goal). u Up all Continue execution, stop at the next port of the parent goal (thus skipping this goal and all calls to children of this goal). This option is useful to stop tracing a failure driven loop. w Write all Write goals using the Prolog predicate write/1. The ideal 4 port model as described in many Prolog books is not visible in many Prolog implementations because code optimisation removes part of the choice- and exit points. Backtrack points are not shown if either the goal succeeded deterministically or its alternatives were removed using the cut. When running in debug mode (debug/0) choice points are only destroyed when removed by the cut. In debug mode tail recursion optimisation is switched off. 2.7 Compilation Collections of SWI-Prolog source files can be compiled into an intermediate code file. An intermediate code file is a data file from which SWI-Prolog can be started. The command to compile a bundle of source files is: pl [options] [-o output] -c file ... The individual source files may include other files using the standard list notation, consult/1, ensure_loaded/1 and use_module/[1,2]. When the -o fileoption is omitted a file named a.out is created that holds the intermediate code file. Intermediate code files start with the BSD Unix magic code #! and are executable. This implies they can be started as a command: sun% pl -o my_program -c ... ... sun% my_program [options] Alternatively, my_program can be started with sun% pl -x my_program [options] The following restrictions apply to source files that are to be compiled with `-c': term_expansion/2 should not use assert/1 and or retract/1 other than for local computational purposes. Files can only be included by the standard include directives: [...], consult/1, ensure_loaded/1 and use_module/[1,2]. User defined loading predicate invocations will not be compiled. Directives are executed both when compiling the program and when loading the intermediate code file. 2.8 Environment Control please(+Key, -Old, +New) The predicate please/3 is a solution to avoid large numbers of environment control predicates. Later versions will support other environment control as now provided via the predicates style_check/2, leash/1, unknown/2, the tracer predicates, etc. These predicates are then moved into a library for backwards compatibility. The currently available options are: optimise on/off (default: off) Switch optimise mode for the compiler on or off (see also the command line option -O). Currently optimised compilation only implies compilation of arithmetic, making it fast, but invisible to the tracer. Later versions might imply various other optimisations such as incorporating a number of basic predicates in the virtual machine (var/1, fail/0, =/2, etc.) to gain speed at the cost of crippling the debugger. Also source level optimisations such as integrating small predicates into their callers, eliminating constant expressions and other predictable constructs. Source code optimisation is never applied to predicates that are declared dynamic (see dynamic/1). autoload on/off (default: on) If on autoloading of library functions is enabled. If off autoloading is disabled. See section 2.10. verbose_autoload on/off (default: off) If on the normal consult message will be printed if a library is autoloaded. By default this message is suppressed. Intended to be used for debugging purposes (e.g. where does this predicate come from?). feature(?Key, -Value) The predicate feature/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 and the Value is the atom true. Currently defined keys: arch (atom) 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 load_foreign/5. version (atom) The version identifier is an atom consisting of 3 numeric values separated by dots (e.g. 1.9.2). home (atom) SWI-Prolog's notion of the home-directory. SWI-Prolog uses it's home directory to find its startup file as /startup/startup. and to find its library as /library. pipe (bool) If true, tell(pipe(command)), etc. are supported. load_foreign (bool) If true, load_foreign/[2,5] are implemented. open_shared_object (bool) If true, open_shared_object/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. dynamic_stacks (bool) If true, the system provides virtual memory based stack expansion. This makes stack-expansion safe when called from C and while running C-defined functions without these functions taking any precautions. Pure Prolog programs are not affected by this feature as the system will use stack-shifting to expand the stacks at runtime. c_libs (atom) 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. c_staticlibs (atom) On some machines, the SWI-Prolog executable is dynamically linked, but requires some libraries to be statically linked. c_cc (atom) Name of the C-compiler used to compile SWI-Prolog. Normally either gcc or cc. c_ldflags (atom) Special linker flags passed to link SWI-Prolog. save (bool) If true, save/[1,2] is implemented. save_program (bool) If true, save_program/[1,2] is implemented. readline (bool) If true, SWI-Prolog is linked with the readline library. This is done by default if you have this library installed on your system. runtime (bool) If true, SWI-Prolog is compiled with -DO_RUNTIME, disabling various useful development features (currently the tracer and profiler). max_integer (integer) Maximum integer value. Most arithmetic operations will automatically convert to floats if integer values above this are returned. min_integer (integer) Minimum integer value. set_feature(+Key, +Value) Define a new feature or change its value. Both arguments must be atoms. 2.9 Saved States 2.9.1 Types of Saved States and Portability On some architectures, SWI-Prolog allows for the creation of saved states. Currently, the C-sources define two alternative implementations for them. The old implementation creates an entirely self-contained executable. It supports only the save_program/[1,2] predicates. The new implementation creates a file that is read by the `base' program. This file contains the data-area of the SWI-Prolog process and optionally the Prolog- and C stacks. This implementation supports save_program/[1,2], save/[1,2] and restore/1. The state-file depends entirely on exactly the Unix program-file used to create it. 2.9.2 Save Predicates save_program(+NewProgram, +ListOfOptions) Create a new executable wich will be named NewProgram. ListOfOptions is a list of Key = Valuepairs that specify the default command line options that will be saved into the new program. If a default is not specified the default compiled into the currently running Prolog executable is used. The available keys are given in table 2.2 Key Option Type Description local -L K-bytes Size (Limit) of local stack global -G K-bytes Size (Limit) of global stack trail -T K-bytes Size (Limit) of trail stack argument -A K-bytes Size (Limit) of argument stack goal -g atom Initialisation goal toplevel -t atom Prolog toplevel goal init_file -f atom Personal initialisation file tty +/--tty on/off Use ioctl(2) calls Table 2.2: Key = Value pairs for save_program/2 As the entire data image of the current process will be saved on the new executable it is desirable to keep this small. Notably the Prolog machine stacks should be kept small. The best way to do this is first to compile the program using the -c option. If this is not possible try to find the smallest possible stack sizes to compile the program. On machines with dynamic stack allocation the stacks are not written to file and so their size does not matter. Figure 2.4 shows a possible session. Note the use of `initialise', which is supposed to be a predicate of the application doing time consuming initialisation. sun% pl -c load foreign file dbase loaded 0.066667 seconds, 1578 bytes. setup consulted, 0.500000 seconds, 5091 bytes. main consulted, 0.333333 seconds, 3352 bytes. load consulted, 1.000000 seconds, 9867 bytes. sun% a.out -f none -L10 -G10 -T5 foreign file dbase loaded 0.066667 seconds, 1578 bytes. Welcome to SWI-Prolog (version 1.5.0, August 1990) Copyright (c) 1990, University of Amsterdam. All rights reserved. 1 ?- initialise. Yes 2 ?- save_program(my_program, [ local = 500 , goal = go , init_file = none ]). Running executable: /usr/local/bin/pl Saving to my_program; text: 204800 ... data: 357000 ... symbols ... done. Yes 2 ?- halt. sun% Figure 2.4: Create a stand-alone executable The resulting program can be used for incremental compilation using -c or another save_program/2. save_program(+NewProgram) Equivalent to `save_program(NewProgram, [])'. save(+State) Writes the current status on the program, Prolog- and C-stacks to the file State. When this file is restored, save/1 succeeds in the restored state and execution continues as illustrated by the following example: 1 ?- save(state), format('Hello World~n'). Hello World Yes 2 ?- halt. machine% ./state Hello World Yes 2 ?- h. 1 save(state), format('Hello World~n'). 2 ?- The save/1 predicate is normally used for debugging purposes. save_program/[1,2] is the preferred way to create a new program. save(+State, -Rval) Like save/1, but unifies Rval with 0 when save/2 returns from a real save and with 1 when save/2 returns from a restore. restore(+State) Equivalent to restarting State. 2.10 Automatic loading of libraries If ---at runtime--- an undefined predicate is trapped the system will first try to import the predicate from the module's default module. If this fails the auto loader is activated. On first activation an index to all library files in all library directories is loaded in core (see library_directory/1). If the undefined predicate can be located in the one of the libraries that library file is automatically loaded and the call to the (previously undefined) predicate is resumed. By default this mechanism loads the file silently. The please/3 option verbose_autoload is provided to get verbose loading. The please option autoloadcan be used to enable/disable the entire auto load system. Autoloading only handles (library) source files that use the module mechanism described in chapter 4. The files are loaded with use_module/2 and only the trapped undefined predicate will be imported to the module where the undefined predicate was called. Each library directory must hold a file INDEX.plthat contains an index to all library files in the directory. This file consists of lines of the following format: index(Name, Arity, Module, File). The predicate make/0 scans the autoload libraries and updates the index if it exists, is writable and out-of-date. It is adviced to create an empty file called INDEX.plin a library directory meant for auto loading before doing anything else. This index file can then be updated by running the prolog make_library_index/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 library_directory/1 predicate and within the directory alphabetically. make_library_index(+Directory) 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.10.1 Notes on Automatic Loading The autoloader is a new feature to SWI-Prolog. Its aim is to simplify program development and program management. Common lisp has a similar feature, but here the user has to specify which library is to be loaded if a specific function is called which is not defined. The advantage of the SWI-Prolog schema is that the user does not have to specify this. The disadvantage however is that the user might be wondering ``where the hell this predicate comes from''. Only experience can learn whether the functionality of the autoloader is appropriate. Comments are welcome. The autoloader only works if the unknown flag (see unknown/2) is set to trace(default). A more appropriate interaction with this flag will be considered. 2.11 Garbage Collection SWI-Prolog version 1.4 was the first release to support garbage collection. Together with tail-recursion optimisation this guaranties forward chaining programs do not waste indefinite amounts of memory. Previous releases of this manual stressed on using failure-driven loops in those cases that no information needed to be passed to the next iteration via arguments. This to avoid large amounts of garbage. This is no longer stricktly necessary, but it should be noticed that garbage collection is a time consuming activity. Failure driven loops tend to be faster for this reason. BUG: The garbage collector is deactivated when Prolog is called back from a foreign language predicate. This implies there is no garbage collection within a break environment. More seriously, there is no garbage collection when handling call-backs from ---for example--- the XPCE package. 2.12 Syntax Notes SWI-Prolog uses standard `Edinburgh' syntax. A description of this syntax can be found in the Prolog books referenced in the introduction. Below are some non-standard or non-common constructs that are accepted by SWI-Prolog: 0' This construct is not accepted by all Prolog systems that claim to have Edinburgh compatible syntax. It describes the ASCII value of . To test whether C is a lower case character one can use `between(0'a, 0'z, C)'. /* ... /* .... */ ... */ The /* ... */ comment statement can be nested. This is useful if some code with /* ... */ comment statements in it should be commented out. 2.13 System Limits 2.13.1 Limits on Memory Areas SWI-Prolog has a number of memory areas which are not enlarged at run time, unless you have a version with dynamic stack allocation. The default sizes for these areas should suffice for small applications, but most serious application require larger ones. They all can be modified by command line options. The table below shows these areas. The first column gives the option name to modify the size of the area. This option character should be followed immediately by a number and expresses the number of kilo bytes to use for the area. There are no other limits than the available memory of the machine to the sizes of the areas. The areas are described in table 2.3. The heap is a memory area to store atoms, clauses, records, flags, etc. This area is dynamically enlarged at runtime on all versions of SWI-Prolog. Option Default Area name Description -L 200K (2M) local stack The local stack is used to store the execution environments of procedure invocations. The space for an environment is reclaimed when it fails, exits without leaving choice points, the alternatives are cut of with the ! predicate or no choice points have been created since the invocation and the last subclause is started (tail recursion optimisation). -G 100K (4M) global stack The global stack is used to store terms created during Prolog's execution. Terms on this stack will be reclaimed by backtracking to a point before the term was created or by garbage collection (provided the term is no longer referenced). -T 50K (4M) trail stack The trail stack is used to store assignments during execution. Entries on this stack remain alive until backtracking before the point of creation or the garbage collector determines they are nor needed any longer. -A 5K (1M) argument stack The argument stack is used to store one of the intermediate code interpreter's registers. The amount of space needed on this stack is determined entirely by the depth in which terms are nested in the clauses that constitute the program. Overflow is most likely when using long strings in a clause. Table 2.3: Memory areas 2.13.2 Other Limits ClausesCurrently the following limitations apply to clauses. The arity may not be more than 128, the number of links to the `outside world' (predicates, atoms, (large) integers, etc) may not exceed 512 and the number of variables should be less than 256. Atoms and StringsSWI-Prolog has no limits on the sizes of atoms and strings. read/1 and its derivates however normally limit the number of newlines in an atom or string to 5 to improve error detection and recovery. This can be switched off with style_check/1. Address spaceSWI-Prolog uses tagged pointers internally. This limits the number of available bits for addressing memory to 29 (512 Mb). IntegersIntegers are tagged values. Their value is limited between 226 and 226 1. FloatsFloating point numbers are C-doubles with a 12 bit reduction of the mantisse. For machines using IEEE floating point format, this implies the range is about 10308and the accurracy about 10 digits. 2.13.3 Reserved Names The boot compiler (see -b option) does not support the module system (yet). As large parts of the system are written in Prolog itself we need some way to avoid name clashes with the user's predicates, database keys, etc. Like Edinburgh C-Prolog all predicates, database keys, etc. that should be hidden from the user start with a dollar ($) sign (see style_check/2). The compiler uses the special functor $VAR$/1 while analysing the clause to compile. Using this functor in a program causes unpredictable behaviour of the compiler and resulting program. Chapter 3 Built-In Predicates 48 3.1 Notation of Predicate Descriptions We have tried to keep the predicate descriptions clear and concise. First the predicate name is printed in bold face, followed by the arguments in italics. Arguments are preceded by a `+', `--' or `?' sign. `+' indicates the argument is input to the predicate, `--' denotes output and `?' denotes `either input or output'. Constructs like `op/3' refer to the predicate `op' with arity `3'. 3.2 Consulting Prolog Source files SWI-Prolog source files normally have a suffix `.pl'. Specifying the suffix is optional. All predicates that handle source files first check whether a file with suffix `.pl' exists. If not the plain file name is checked for existence. Library files are specified by embedding the file name using the functor library/1. Thus `foo' refers to `foo.pl' or `foo' in the current directory, `library(foo)' refers to `foo.pl' or `foo' in one of the library directories specified by the dynamic predicate library_directory/1. SWI-Prolog recognises grammar rules as defined in . The user may define additional compilation of the source file by defining the dynamic predicate term_expansion/2. Transformations by this predicate overrule the systems grammar rule transformations. It is not allowed to use assert/1, retract/1 or any other database predicate in term_expansion/2 other than for local computational purposes. Directives may be placed anywhere in a source file, invoking any predicate. They are executed when encountered. If the directive fails, a warning is printed. Directives are specified by :-/1 or ?-/1. There is no difference between the two. SWI-Prolog does not have a separate reconsult/1 predicate. Reconsulting is implied automatically by the fact that a file is consulted which is already loaded. consult(+File) Read File as a Prolog source file. File may be a list of files, in which case all members are consulted in turn. File may start with the csh(1) special sequences ~, ~ and $. File may also be library(Name), in which case the libraries are searched for a file with the specified name. See also library_directory/1. consult/1 may be abbreviated by just typing a number of file names in a list. Examples: ?- consult(load). % consult `load' or `load.pl' ?- [library(quintus)]. % load Quintus compatibility library ensure_loaded(+File) Equivalent to consult/1, but the file is consulted only if this was not done before. This is the recommended way to load files from other files. make Consult all source files that have been changed since they were consulted. It checks all loaded source files: files loaded into a compiled state using pl -c ... and files loaded using consult or one of its derivates. make/0 is normally invoked by the edit/[0,1] and ed/[0,1] predicates. make/0 can be combined with the compiler to speed up the development of large packages. In this case compile the package using sun% pl -g make -o my_program -c file ... If `my_program' is started it will first reconsult all source files that have changed since the compilation. library_directory(-Atom) Dynamic predicate used to specify library directories. Default ., ./lib, ~/lib/prolog and the system's library (in this order) are defined. The user may add library directories using assert/1, asserta/1 or remove system defaults using retract/1. file_search_path(+Alias, -Path) 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 file_search_path/2 may be another alias. Currently the only predefined alias is file_search_path(library, X) :- library_directory(X). Used by all loading predicates as well as by absolute_file_name/2. source_file(-File) Succeeds if File was loaded using consult/1 or ensure_loaded/1. File refers to the full path name of the file (see expand_file_name/2). Source_file/1 backtracks over all loaded source files. source_file(?Pred, ?File) Is true if the predicate specified by Pred was loaded from file File, where File is an absolute path name (see expand_file_name/2). Can be used with any instantiation pattern, but the database only maintains the source file for each predicate. Predicates declared multifile (see multifile/1) cannot be found this way. prolog_load_context(?Key, ?Value) Determine loading context. The following keys are defined: Key Description module Module into which file is loaded file File loaded stream Stream identifier (see current_stream/1) directory Directory in which File lives. term_position Postion of last term read. Term of the form '$stream_position'(0,Line,0,0,0) Quintus compatibility predicate. See also source_location/2. term_expansion(+Term1, -Term2) Dynamic predicate, normally not defined. When defined by the user all terms read during consulting that are given to this predicate. If the predicate succeeds Prolog will assert Term2 in the database rather then the read term (Term1). Term2 may be a term of a the form `?- Goal' or `:- Goal'. Goal is then treated as a directive. Term2 may also be a list, in which case all terms of the list are stored in the database or called (for directives). See also expand_term/2. expand_term(+Term1, -Term2) This predicate is normally called by the compiler to perform preprocessing. First it calls term_expansion/2. If this predicate fails it performs a grammar-rule translation. If this fails it returns the first argument. at_initialisation(+Goal) Register Goal 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 ran in the order they were registered. A warning message is issued if Goal fails, but execution continues. See also at_halt/1 at_halt(+Goal) Register Goal to be ran when the system halts. The hooks are ran in the order they were registered. Success or failure executing a hook is ignored. These hooks may not call halt/[0,1]. compiling Succeeds if the system is compiling source files with the -c option into an intermediate code file. Can be used to perform code optimisations in expand_term/2 under this condition. preprocessor(-Old, +New) Read the input file via a Unix process that acts as preprocessor. A preprocessor is specified as an atom. The first occurrence of the string `%f' is replaced by the name of the file to be loaded. The resulting atom is called as a Unix command and the standard output of this command is loaded. To use the Unix C preprocessor one should define: ?- preprocessor(Old, '/lib/cpp -C -P %f'), consult(...). Old = none 3.2.1 Quick Load Files The features described in this section should be regarded alpha. 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 qcompile/1. They may be loaded explicitely using qload/1 or implicitely using consult/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 qload/1 to load the file. When no extension is specified, it will load the .qlf file when present and the .pl file otherwise. qcompile(+File) Takes a single file specification like consult/1 (i.e. accepts constructs like library(LibFile) and creates a Quick Load File from File. 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 term_expansion/2, the same rules as described in section 2.7 apply. Source references (source_file/2) in the Quick Load File refer to the Prolog source file from which the compiled code originates. qload(+File) Loads the `Quick Load File'. It has the same semantics as consult/1 for a normal sourcefile. Equivalent to consult(File) iff File refers to a `Quick Load File'. 3.3 Listing Predicates and Editor Interface SWI-Prolog offers an interface to the Unix vi editor (vi(1)), Richard O'Keefe's top editor and the GNU-EMACS invocations emacs and emacsclient. Which editor is used is determined by the Unix environment variable EDITOR, which should hold the full pathname of the editor. If this variable is not defined, vi(1) is used. After the user quits the editor make/0 is invoked to reload all modified source files using consult/1. If the editor can be quit such that an exit status non-equal to 0 is returned make/0 will not be invoked. top can do this by typing control-C, vi cannot do this. A predicate specification is either a term with the same functor and arity as the predicate wanted, a term of the form Functor/Arityor a single atom. In the latter case the database is searched for a predicate of this name and arbitrary arity (see current_predicate/2). When more than one such predicate exists the system will prompt for confirmation on each of the matched predicates. Predicates specifications are given to the `Do What I Mean' system (see dwim_predicate/2) if the requested predicate does not exist. ed(+Pred) Invoke the user's preferred editor on the source file of Pred, providing a search specification which searches for the predicate at the start of a line. ed Invoke ed/1 on the predicate last edited using ed/1. Asks the user to confirm before starting the editor. edit(+File) Invoke the user's preferred editor on File. File is a file specification as for consult/1 (but not a list). Note that the file should exist. edit Invoke edit/1 on the file last edited using edit/1. Asks the user to confirm before starting the editor. listing(+Pred) List specified predicates (when an atom is given all predicates with this name will be listed). The listing is produced on the basis of the internal representation, thus loosing user's layout and variable name information. See also portray_clause/1. listing List all predicates of the database using listing/1. portray_clause(+Clause) Pretty print a clause as good as we can. A clause should be specified as a term `Head :- Body' (put brackets around it to avoid operator precedence problems). Facts are represented as `Head :- true'. 3.4 Verify Type of a Term var(+Term) Succeeds if Term currently is a free variable. nonvar(+Term) Succeeds if Term currently is not a free variable. integer(+Term) Succeeds if Term is bound to an integer. float(+Term) Succeeds if Term is bound to a floating point number. number(+Term) Succeeds if Term is bound to an integer or a floating point number. atom(+Term) Succeeds if Term is bound to an atom. string(+Term) Succeeds if Term is bound to a string. atomic(+Term) Succeeds if Term is bound to an atom, string, integer or floating point number. ground(+Term) Succeeds if Term holds no free variables. 3.5 Comparison and Unification or Terms 3.5.1 Standard Order of Terms Comparison and unification of arbitrary terms. Terms are ordered in the so called ``standard order''. This order is defined as follows: 1. Variables< Atoms< Strings< Numbers< Terms 2. Old Variable < New Variable 3. Atoms are compared alphabetically. 4. Strings are compared alphabetically. 5. Numbers are compared by value. Integers and floats are treated identically. 6. Terms are first checked on their functor (alphabetically), then on their arity and finally recursively on their arguments, left most argument first. +Term1 == +Term2 Succeeds if Term1 is equivalent to Term2. A variable is only identical to a sharing variable. +Term1 \== +Term2 Equivalent to `\+ Term1 == Term2'. +Term1 = +Term2 Unify Term1 with Term2. Succeeds if the unification succeeds. +Term1 \= +Term2 Equivalent to `\+ Term1 = Term2'. +Term1 =@= +Term2 Succeeds if Term1 is `structurally equal' to Term2. Structural equivalence is weaker than equivalence (==/2), but stronger than unification (=/2). Two terms are structurally equal if their tree representation is identical and they have the same `pattern' of variables. Examples: a =@=A false A =@=B true x(A,A) =@=x(B,C) false x(A,A) =@=x(B,B) true x(A,B) =@=x(C,D) true +Term1 \=@= +Term2 Equivalent to `\+ Term1 =@= Term2'. +Term1 @< +Term2 Succeeds if Term1 is before Term2 in the standard order of terms. +Term1 @=< +Term2 Succeeds if both terms are equal (==) or Term1 is before Term2 in the standard order of terms. +Term1 @> +Term2 Succeeds if Term1 is after Term2 in the standard order of terms. +Term1 @>= +Term2 Succeeds if both terms are equal (==) or Term1 is after Term2 in the standard order of terms. 3.6 Control Predicates The predicates of this section implement control structures. Normally these constructs are translated into virtual machine instructions by the compiler. It is still necessary to implement these constructs as true predicates to support meta-calls, as demonstrated in the example below. The predicate finds all currently defined atoms of 1 character long. Note that the cut has no effect when called via one of these predicates (see !/0). one_character_atoms(As) :- findall(A, (current_atom(A), atom_length(A, 1)), As). fail Always fail. true Always succeed. repeat Always succeed, provide an infinite number of choice points. ! Cut. Discard choice points of parent frame and frames created after the parent frame. Note that the control structures ;/2, |/2 ->/2 and \+/1 are normally handled by the compiler and do not create a frame, which implies the cut operates through these predicates. Some examples are given below. Note the difference between t3/1 and t4/1. Also note the effect of call/1 in t5/0. As the argument of call/1 is evaluated by predicates rather than the compiler the cut has no effect. t1 :- (a, !, fail ; b). % cuts a/0 and t1/0 t2 :- (a -> b, ! ; c). % cuts b/0 and t2/0 t3(G) :- a, G, fail. % if `G = !' cuts a/0 and t1/1 t4(G) :- a, call(G), fail. % if `G = !' cut has no effect t5 :- call((a, !, fail ; b)).% Cut has no effect t6 :- \+ (a, !, fail ; b). % cuts a/0 and t6/0 +Goal1 , +Goal2 Conjunction. Succeeds if both `Goal1' and `Goal2' can be proved. It is defined as (this definition does not lead to a loop as the second comma is handled by the compiler): Goal1, Goal2 :- Goal1, Goal2. +Goal1 ; +Goal2 The `or' predicate is defined as: Goal1 ; _Goal2 :- Goal1. _Goal1 ; Goal2 :- Goal2. +Goal1 | +Goal2 Equivalent to ;/2. Retained for compatibility only. New code should use ;/2. +Condition -> +Action If-then and If-Then-Else. Implemented as: If -> Then; _Else :- If, !, Then. If -> _Then; Else :- !, Else. If -> Then :- If, !, Then. \+ +Goal Succeeds if `Goal' cannot be proven (mnemnonic: + refers to provable and the backslash is normally used to indicate negation). 3.7 Meta-Call Predicates Meta call predicates are used to call terms constructed at run time. The basic meta-call mechanism offered by SWI-Prolog is to use variables as a subclause (which should of course be bound to a valid goal at runtime). A meta-call is slower than a normal call as it involves actually searching the database at runtime for the predicate, while for normal calls this search is done at compile time. call(+Goal) Invoke Goal as a goal. Note that clauses may have variables as subclauses, which is identical to call/1, except when the argument is bound to the cut. See !/0. apply(+Term, +List) Append the members of List to the arguments of Term and call the resulting term. For example: `apply(plus(1), [2, X])' will call `plus(1, 2, X)'. Apply/2 is incorporated in the virtual machine of SWI-Prolog. This implies that the overhead can be compared to the overhead of call/1. not +Goal Succeeds when Goal cannot be proven. Retained for compatibility only. New code should use \+/1. once(+Goal) Defined as: once(Goal) :- Goal, !. Once/1 can in many cases be replaced with ->/2. The only difference is how the cut behaves (see !/0). The following two clauses are identical: 1) a :- once((b, c)), d. 2) a :- b, c -> d. ignore(+Goal) Calls Goal as once/1, but succeeds, regardless of whether Goal succeeded or not. Defined as: ignore(Goal) :- Goal, !. ignore(_). 3.8 Advanced control-structures: blocks The predicates of this section form a tightly related set for realising premature successfull or failing exits from a block. These predicates are first of all useful for error-recovery. They were primarily implemented for compatibily reasons. block(+Label, +Goal, -ExitValue) Execute Goal in a block. Label is the name of the block. Label is normally an atom, but the system imposes no type constraints and may even be a variable. ExitValue is normally unified to the second argument of an exit/2 call invoked by Goal. exit(+Label, +Value) Calling exit/2 makes the innermost block which' Label unifies exit. The block's ExitValue is unified with Value. If this unification fails the block fails. fail(+Label) Calling fail/1 makes the innermost block which' Label unifies fail immediately. Implemented as fail(Label) :- !(Label), fail. !(+Label) Cut all choice-points created since the entry of the innermost block which' Label 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.9 Grammar rule interface (phrase) The predicates below may be called to activate a grammar-rule set: phrase(+RuleSet, +InputList) Equivalent to phrase(RuleSet, InputList, []). phrase(+RuleSet, +InputList, -Rest) 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.10 Database SWI-Prolog offers three different database mechanisms. The first one is the common assert/retract mechanism for manipulating the clause database. As facts and clauses asserted using assert/1 or one of it's derivates become part of the program these predicates compile the term given to them. Retract/1 and retractall/1 have to unify a term and therefore have to decompile the program. For these reasons the assert/retract mechanism is expensive. On the other hand, once compiled, queries to the database are faster than querying the recorded database discussed below. See also dynamic/1. The second way of storing arbitrary terms in the database is using the ``recorded database''. In this database terms are associated with a key. A key can be an atom, integer or term. In the last case only the functor and arity determine the key. Each key has a chain of terms associated with it. New terms can be added either at the head or at the tail of this chain. This mechanism is considerably faster than the assert/retract mechanism as terms are not compiled, but just copied into the heap. The third mechanism is a special purpose one. It associates an integer or atom with a key, which is an atom, integer or term. Each key can only have one atom or integer associated with it. It again is considerably faster than the mechanisms described above, but can only be used to store simple status information like counters, etc. abolish(+Functor, +Arity) Removes all clauses of a predicate with functor Functor and arity Arity from the database. Unlike version 1.2, all predicate attributes (dynamic, multifile, index, etc.) are reset to their defaults. Abolishing an imported predicate only removes the import link; the predicate will keep its old definition in its definition module. For `cleanup' of the dynamic database, one should use retractall/1 rather than abolish/2. redefine_system_predicate(+Head) 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 facilates the definition of compatibility packages. Use in other context is discouraged. retract(+Term When Term is an atom or a term it is) unified with the first unifying fact or clause in the database. The fact or clause is removed from the database. retractall(+Head) Allfacts or clauses in the database for which the head unifies with Head are removed. assert(+Term) Assert a fact or clause in the database. Term is asserted as the last fact or clause of the corresponding predicate. asserta(+Term) Equivalent to assert/1, but Term is asserted as first clause or fact of the predicate. assertz(+Term) Equivalent to assert/1. assert(+Term, -Reference) Equivalent to assert/1, but Reference is unified with a unique reference to the asserted clause. This key can later be used with clause/3 or erase/1. asserta(+Term, -Reference) Equivalent to assert/2, but Term is asserted as first clause or fact of the predicate. assertz(+Term, -Reference) Equivalent to assert/2. recorda(+Key, +Term, -Reference) Assert Term in the recorded database under key Key. Key is an integer, atom or term. Reference is unified with a unique reference to the record (see erase/1). recorda(+Key, +Term) Equivalent to recorda(Key, Value, _). recordz(+Key, +Term, -Reference) Equivalent to recorda/3, but puts the Term at the tail of the terms recorded under Key. recordz(+Key, +Term) Equivalent to recordz(Key, Value, _). recorded(+Key, -Value, -Reference) Unify Value with the first term recorded under Key which does unify. Reference is unified with the memory location of the record. recorded(+Key, -Value) Equivalent to recorded(Key, Value, _). erase(+Reference) Erase a record or clause from the database. Reference is an integer returned by recorda/3 or recorded/3, clause/3, assert/2, asserta/2 or assertz/2. Other integers might conflict with the internal consistency of the system. Erase can only be called once on a record or clause. A second call also might conflict with the internal consistency of the system. BUG: The system should have a special type for pointers, thus avoiding the Prolog user having to worry about consistency matters. Currently some simple heuristics are used to determine whether a reference is valid. flag(+Key, -Old, +New) Key is an atom, integer or term. Unify Old with the old value associated with Key. If the key is used for the first time Old is unified with the integer 0. Then store the value of New, which should be an integer, atom or arithmetic integer expression, under Key. flag/3 is a very fast mechanism for storing simple facts in the database. Example: :- module_transparent succeeds_n_times/2. succeeds_n_times(Goal, Times) :- flag(succeeds_n_times, _, 0), Goal, flag(succeeds_n_times, N, N+1), fail ; flag(succeeds_n_times, Times, Times). 3.11 Declaring Properties of Predicates This section describes directives which manipulate attributes of predicate definitions. The functors dynamic/1, multifile/1 and discontiguous/1 are operators of priority 1150 (see op/3), which implies the list of predicates they involve can just be a comma separated list: :- dynamic foo/0, baz/2. On SWI-Prolog all these directives are just predicates. This implies they can also be called by a program. Do not rely on this feature if you want to maintain portability to other Prolog implementations. dynamic +Functor/+Arity, ... Informs the interpreter that the definition of the predicate(s) may change during execution (using assert/1 and/or retract/1). Currently dynamic/1 only stops the interpreter from complaining about undefined predicates (see unknown/2). Future releases might prohibit assert/1 and retract/1 for not-dynamic declared procedures. multifile +Functor/+Arity, ... Informs the system that the specified predicate(s) may be defined over more than one file. This stops consult/1 from redefining a predicate when a new definition is found. discontiguous +Functor/+Arity, ... Informs the system that the clauses of the specified predicate(s) might not be together in the source file. See also style_check/1. index(+Head) Index the clauses of the predicate with the same name and arity as Head on the specified arguments. Head is a term of which all arguments are either `1' (denoting `index this argument') or `0' (denoting `do not index this argument'). Indexing has no implications for the semantics of a predicate, only on its performance. If indexing is enabled on a predicate a special purpose algorithm is used to select candidate clauses based on the actual arguments of the goal. This algorithm checks whether indexed arguments might unify in the clause head. Only atoms, integers and functors (e.g. name and arity of a term) are considered. Indexing is very useful for predicates with many clauses representing facts. Due to the representation technique used at most 4 arguments can be indexed. All indexed arguments should be in the first 32 arguments of the predicate. If more than 4 arguments are specified for indexing only the first 4 will be accepted. Arguments above 32 are ignored for indexing. By default all predicates with arity 1 are indexed on their first argument. It is possible to redefine indexing on predicates that already have clauses attached to them. This will initiate a scan through the predicate's clause list to update the index summary information stored with each clause. If --for example-- one wants to represents sub-types using a fact list `sub_type(Sub, Super)'that should be used both to determine sub- and super types one should declare sub_type/2 as follows: :- index(sub_type(1, 1)). sub_type(horse, animal). ... ... 3.12 Examining the Program current_atom(-Atom) Successively unifies Atom with all atoms known to the system. Note that current_atom/1 always succeeds if Atom is intantiated to an atom. current_functor(?Name, ?Arity) Successively unifies Name with the name and Arity with the arity of functors known to the system. current_flag(-FlagKey) Successively unifies FlagKey with all keys used for flags (see flag/3). current_key(-Key) Successively unifies Key with all keys used for records (see recorda/3, etc.). current_predicate(?Name, ?Head) Successively unifies Name with the name of predicates currently defined and Head with the most general term built from Name and the arity of the predicate. This predicate succeeds for all predicates defined in the specified module, imported to it, or in one of the modules from which the predicate will be imported if it is called. predicate_property(?Head, ?Property) Succeeds if Head refers to a predicate that has property Property. Can be used to test whether a predicate has a certain property, obtain all properties known for Head, find all predicates having property or even obtaining all information available about the current program. Property is one of: interpreted Is true if the predicate is defined in Prolog. We return true on this because, although the code is actually compiled, it is completely transparent, just like interpreted code. built_in Is true if the predicate is locked as a built-in predicate. This implies it cannot be redefined in it's definition module and it can normally not be seen in the tracer. foreign Is true if the predicate is defined in the C language. dynamic Is true if the predicate is declared dynamic using the dynamic/1 declaration. multifile Is true if the predicate is declared multifile using the multifile/1 declaration. undefined Is true if a procedure definition block for the predicate exists, but there are no clauses in it and it is not declared dynamic. This is true if the predicate occurs in the body of a loaded predicate, an attempt to call it has been made via one of the meta-call predicates or the predicate had a definition in the past. See the library package check for example usage. transparent Is true if the predicate is declared transparent using the module_transparent/1 declaration. exported Is true if the predicate is in the public list of the context module. imported_from(Module) Is true if the predicate is imported into the context module from module Module. indexed(Head) Predicate is indexed (see index/1) according to Head. Head is a term whose name and arity are identical to the predicate. The arguments are unified with `1' for indexed arguments, `0' otherwise. file(FileName) Unify FileName with the name of the sourcefile in which the predicate is defined. See also source_file/2. line_count(LineNumber) Unify LineNumber with the line number of the first clause of the predicate. Fails if the predicate is not associated with a file. See also source_file/2. dwim_predicate(+Term, -Dwim) `Do What I Mean' (`dwim') support predicate. Term is a term, which name and arity are used as a predicate specification. Dwim is instantiated with the most general term built from Name and the arity of a defined predicate that matches the predicate specified by Term in the `Do What I Mean' sence. See dwim_match/2 for `Do What I Mean' string matching. Internal system predicates are not generated, unless style_check(+dollar)is active. Backtracking provides all alternative matches. clause(?Head, ?Body) Succeeds when Head can be unified with a clause head and Body with the corresponding clause body. Gives alternative clauses on backtracking. For facts Body is unified with the atom true. Normally clause/2 is used to find clause definitions for a predicate, but it can also be used to find clause heads for some body template. clause(?Head, ?Body, ?Reference) Equivalent to clause/2, but unifies Reference with a unique reference to the clause (see also assert/2, erase/1). If Reference is instantiated to a reference the clause's head and body will be unified with Head and Body. nth_clause(?Pred, ?Index, ?Reference) Provides access to the clauses of a predicate using their index number. Counting starts at 1. If Reference is specified it unifies Pred with the most general term with the same name/arity as the predicate and Index with the index-number of the clause. Otherwise the name and arity of Pred are used to determine the predicate. If Index is provided Reference will be unified with the clause reference. If Index is unbound, backtracking will yield both the indices and the references of all clauses of the predicate. The following example finds the 2nd clause of member/2: ?- nth_clause(member(_,_), 2, Ref), clause(Head, Body, Ref). Ref = 160088 Head = system : member(G575, [G578|G579]) Body = member(G575, G579) clause_property(+ClauseRef, -Property) Queries properties of a clause. ClauseRef is a reference to a clause as produced by clause/3, nth_clause/3 or prolog_frame_attribute/3. Property is one of the following: file(FileName) Unify FileName with the name of the sourcefile in which the clause is defined. Fails if the clause is not associated to a file. line_count(LineNumber) Unify LineNumber with the line number of the clause. Fails if the clause is not associated to a file. 3.13 Input and Output SWI-Prolog provides two different packages for input and output. One confirms to the Edinburgh standard. This package has a notion of `current-input' and `current-output'. The reading and writing predicates implicitely refer to these streams. In the second package, streams are opened explicitely and the resulting handle is used as an argument to the reading and writing predicate to specify the source or destination. Both packages are fully integrated; the user may switch freely between them. 3.13.1 Input and Output Using Implicit Source and Destination The package for implicit input and output destination is upwards compatible to DEC-10 and C-Prolog. The reading and writing predicates refer to resp. the current input- and output stream. Initially these streams are connected to the terminal. The current output stream is changed using tell/1 or append/1. The current input stream is changed using see/1. The stream's current value can be obtained using telling/1 for output- and seeing/1 for input streams. The table below shows the valid stream specifications. The reserved names user_input, user_output and user_errorare for neat integration with the explicit streams. user This reserved name refers to the terminal user_input Input from the terminal user_output Output to the terminal stderr or user_error Unix error stream (output only) Atom Name of a Unix file pipe(Atom) Name of a Unix command Source and destination are either a file, one of the reserved words above, or a term `pipe(Command)'. In the predicate descriptions below we will call the source/destination argument `SrcDest'. Below are some examples of source/destination specifications. ?- see(data). % Start reading from file `data'. ?- tell(stderr). % Start writing on the error stream. ?- tell(pipe(lpr)). % Start writing to the printer. Another example of using the pipe/1 construct is shown on in figure 3.1. Note that the pipe/1 construct is not part of Prolog's standard I/O reportoire. getwd(Wd) :- seeing(Old), see(pipe(pwd)), collect_wd(String), seen, see(Old), name(Wd, String). collect_wd([C|R]) :- get0(C), C \== -1, !, collect_wd(R). collect_wd([]). Figure 3.1: Get the working directory see(+SrcDest) Make SrcDest the current input stream. If SrcDest was already opened for reading with see/1 and has not been closed since, reading will be resumed. Otherwise SrcDest will be opened and the file pointer is positioned at the start of the file. tell(+SrcDest) Make SrcDest the current output stream. If SrcDest was already opened for writing with tell/1 or append/1 and has not been closed since, writing will be resumed. Otherwise the file is created or --when existing-- truncated. See also append/1. append(+File) Similar to tell/1, but positions the file pointer at the end of File rather than truncating an existing file. The pipe construct is not accepted by this predicate. seeing(-SrcDest) Unify the name of the current input stream with SrcDest. telling(-SrcDest) Unify the name of the current output stream with SrcDest. seen Close the current input stream. The new input stream becomes user. told Close the current output stream. The new output stream becomes user. 3.13.2 Explicit Input and Output Streams The predicates below are part of the Quintus compatible stream-based I/O package. In this package streams are explicitely created using the predicate open/3. The resulting stream identifier is then passed as a parameter to the reading and writing predicates to specify the source or destination of the data. open(+SrcDest, +Mode, ?Stream) SrcDest is either an atom, specifying a Unix file, or a term `pipe(Command)', just like see/1 and tell/1. Mode is one of read, writeor append. Stream is either a variable, in which case it is bound to a small integer identifying the stream, or an atom, in which case this atom will be the stream indentifier. In the latter case the atom cannot be an already existing stream identifier. Examples: ?- open(data, read, Stream). % Open `data' for reading. ?- open(pipe(lpr), write, printer).% `printer' is a stream to `lpr'. open_null_stream(?Stream) On Unix systems, this is equivalent to open('/dev/null', write, Stream). Characters written to this stream are lost, but the stream information (see character_count/2, etc.) is maintained. close(+Stream) Close the specified stream. If Stream is not open an error message is displayed. If the closed stream is the current input or output stream the terminal is made the current input or output. current_stream(?File, ?Mode, ?Stream) Is true if a stream with file specification File, mode Mode and stream identifier Stream is open. The reserved streams user and user_error are not generated by this predicate. If a stream has been opened with mode appendthis predicate will generate mode write. stream_position(+Stream, -Old, +New) Unify the position parameters of Stream with Old and set them to New. A position is represented by the following term: '$stream_position'(CharNo, LineNo, LinePos). It is only possible to change the position parameters if the stream is connected to a disk file. If the position is changed, the CharNo field determines the new position in the file. The LineNo and LinePos are copied in the stream administration. 3.13.3 Switching Between Implicit and Explicit I/O The predicates below can be used for switching between the implicit- and the explicit stream based I/O predicates. set_input(+Stream) Set the current input stream to become Stream. Thus, open(file, read, Stream), set_input(Stream) is equivalent to see(file). set_output(+Stream) Set the current output stream to become Stream. current_input(-Stream) Get the current input stream. Useful to get access to the status predicates associated with streams. current_output(-Stream) Get the current output stream. 3.14 Status of Input and Output Streams wait_for_input(+ListOfStreams, -ReadyList, +TimeOut) Wait for input on one of the streams in ListOfStreams and return a list of streams on which input is available in ReadyList. wait_for_input/3 waits for at most TimeOut seconds. Timeout may be specified as a floating point number to specify fractions of a second. If Timeout equals 0, wait_for_input/3 waits indefinetely. This predicate can be used to implement timeout while reading and to handle input from multiple sources. The following example will wait for input from the user and an explicitely opened second terminal. On return, Inputs may hold user or P4 or both. ?- open('/dev/ttyp4', read, P4), wait_for_input([user, P4], Inputs, 0). character_count(+Stream, -Count) Unify Count with the current character index. For input streams this is the number of characters read since the open, for output streams this is the number of characters written. Counting starts at 0. line_count(+Stream, -Count) Unify Count with the number of lines read or written. Counting starts at 1. line_position(+Stream, -Count) Unify Count with the position on the current line. Note that this assumes the position is 0 after the open. Tabs are assumed to be defined on each 8-th character and backspaces are assumed to reduce the count by one, provided it is positive. fileerrors(-Old, +New) Define error behaviour on errors when opening a file for reading or writing. Valid values are the atoms on (default) and off. First Old is unified with the current value. Then the new value is set to New. tty_fold(-OldColumn, +NewColumn) Fold Prolog output to stream user on column NewColumn. If Column is 0 or less no folding is performed (default). OldColumn is first unified with the current folding column. To be used on terminals that do not support line folding. 3.15 Primitive Character Input and Output nl Write a newline character to the current output stream. On Unix systems nl/0 is equivalent to put(10). nl(+Stream) Write a newline to Stream. put(+Char) Write Char to the current output stream, Char is either an integer-expression evaluating to an ASCII value (0 Char 255) or an atom of one character. put(+Stream, +Char) Write Char to Stream. tab(+Amount) Writes Amount spaces on the current output stream. Amount should be an expression that evaluates to a positive integer (see section 3.21). tab(+Stream, +Amount) Writes Amount spaces to Stream. flush Flush pending output on current output stream. flush/0 is automatically generated by read/1 and derivates if the current input stream is user and the cursor is not at the left margin. flush_output(+Stream) Flush output on the specified stream. The stream must be open for writing. ttyflush Flush pending output on stream user. See also flush/0. get0(-Char) Read the current input stream and unify the next character with Char. Char is unified with -1 on end of file. get0(+Stream, -Char) Read the next character from Stream. get(-Char) Read the current input stream and unify the next non-blank character with Char. Char is unified with -1 on end of file. get(+Stream, -Char) Read the next non-blank character from Stream. skip(+Char) Read the input until Char or the end of the file is encountered. A subsequent call to get0/1 will read the first character after Char. skip(+Stream, +Char) Skip input (as skip/1) on Stream. get_single_char(-Char) Get a single character from input stream `user' (regardless of the current input stream). Unlike get0/1 this predicate does not wait for a return. The character is not echoed to the user's terminal. This predicate is meant for keyboard menu selection etc.. If SWI-Prolog was started with the -tty flag this predicate reads an entire line of input and returns the first non-blank character on this line, or the ASCII code of the newline (10) if the entire line consisted of blank characters. 3.16 Term Reading and Writing display(+Term) Write Term on the current output stream using standard parenthesised prefix notation (i.e. ignoring operator declarations). Display is normally used to examine the internal representation for terms holding operators. display(+Stream, +Term) Display Term on Stream. displayq(+Term) Write Term on the current output stream using standard parenthesised prefix notation (i.e. ignoring operator declarations). Atoms that need quotes are quoted. Terms written with this predicate can always be read back, regardless of current operator declarations. displayq(+Stream, +Term) Display Term on Stream. Equivalent to Quintus write_canonical/2. write(+Term) Write Term to the current output, using brackets and operators where appropriate. write(+Stream, +Term) Write Term to Stream. writeq(+Term) Write Term to the current output, using brackets and operators where appropriate. Atoms that need quotes are quoted. Terms written with this predicate can be read back with read/1 provided the currently active operator declarations are identical. writeq(+Stream, +Term) Write Term to Stream, inserting quotes. print(+Term) Prints Term on the current output stream similar to write/1, but for each (sub)term of Term first the dynamic predicate portray/1 is called. If this predicate succeeds print assumes the (sub)term has been written. This allows for user defined term writing. print(+Stream, +Term) Print Term to Stream. portray(+Term) A dynamic predicate, which can be defined by the user to change the behaviour of print/1 on (sub)terms. For each subterm encountered that is not a variable print/1 first calls portray/1 using the term as argument. For lists only the list as a whole is given to portray/1. If portray succeeds print/1 assumes the term has been written. read(-Term) Read the next Prolog term from the current input stream and unify it with Term. On a syntax error read/1 displays an error message, attempts to skip the erroneous term and fails. On reaching end-of-file Term is unified with the atom end_of_file. read(+Stream, -Term) Read Term from Stream. read_clause(-Term) Equivalent to read/1, but warns the user for variables only occurring once in a term (singleton variables) which do not start with an underscore if style_check(singleton)is active (default). Used to read Prolog source files (see consult/1). read_clause(+Stream, -Term) Read a clause from Stream. read_variables(-Term, -Bindings) Similar to read/1, but Bindings is unified with a list of `Name= Var' tuples, thus providing access to the actual variable names. read_variables(+Stream, -Term, -Bindings) Read, returning term and bindings from Stream. read_history(+Show, +Help, +Special, +Prompt, -Term, -Bindings) Similar to read_variables/2, but allows for history substitutions. history_read/6 is used by the top level to read the user's actions. Show is the command the user should type to show the saved events. Help is the command to get an overview of the capabilities. Special is a list of commands that are not saved in the history. Prompt is the first prompt given. Continuation prompts for more lines are determined by prompt/2. A %w in the prompt is substituted by the event number. See section 2.4 for available substitutions. SWI-Prolog calls history_read/6 as follows: read_history(h, '!h', [trace], '%w ?- ', Goal, Bindings) history_depth(-Int) Dynamic predicate, normally not defined. The user can define this predicate to set the history depth. It should unify the argument with a positive integer. When not defined 15 is used as the default. prompt(-Old, +New) Set prompt associated with read/1 and its derivates. Old is first unified with the current prompt. On success the prompt will be set to New if this is an atom. Otherwise an error message is displayed. A prompt is printed if one of the read predicates is called and the cursor is at the left margin. It is also printed whenever a newline is given and the term has not been terminated. Prompts are only printed when the current input stream is user. 3.17 Analysing and Constructing Terms functor(?Term, ?Functor, ?Arity) Succeeds if Term is a term with functor Functor and arity Arity. If Term is a variable it is unified with a new term holding only variables. functor/3 silently fails on instantiation faults If Term is an atom or number, Functor will be unified with Term and arity will be unified with the integer 0 (zero). arg(?Arg, ?Term, ?Value) Term should be instantiated to a term, Arg to an integer between 1 and the arity of Term. Value is unified with the Arg-th argument of Term. Arg may also be unbound. In this Value will be unified with the successive arguments of the term. On successfull unification, Arg is unified with the argument number. Backtracking yields alternative solutions. ?Term =.. ?List List is a list which head is the functor of Term and the remaining arguments are the arguments of the term. Each of the arguments may be a variable, but not both. This predicate is called `Univ'. Examples: ?- foo(hello, X) =.. List. List = [foo, hello, X] ?- Term =.. [baz, foo(1)] Term = baz(foo(1)) numbervars(+Term, +Functor, +Start, -End) Unify the free variables of Term with a term constructed from the atom Functor with one argument. The argument is the number of the variable. Counting starts at Start. End is unified with the number that should be given to the next variable. Example: ?- numbervars(foo(A, B, A), this_is_a_variable, 0, End). A = this_is_a_variable(0) B = this_is_a_variable(1) End = 2 In Edinburgh Prolog the second argument is missing. It is fixed to be '$VAR'. free_variables(+Term, -List) Unify List with a list of variables, each sharing with a unique variable of Term. For example: ?- free_variables(a(X, b(Y, X), Z), L). L = [G367, G366, G371] X = G367 Y = G366 Z = G371 copy_term(+In, -Out) Make a copy of term In and unify the result with Out. Ground parts of In are shared by Out. Provided In and Out have no sharing variables before this call they will have no sharing variables afterwards. copy_term/2 is semantically equivalent to: copy_term(In, Out) :- recorda(copy_key, In, Ref), recorded(copy_key, Out, Ref), erase(Ref). 3.18 Analysing and Constructing Atoms These predicates convert between Prolog constants and lists of ASCII values. The predicates atom_chars/2, number_chars/2 and number/2 behave the same when converting from a constant to a list of ASCII values. When converting the other way around, atom_chars/2 will generate an atom, number_chars will generate a number or fail and name/2 will return a number if possible and an atom otherwise. atom_chars(?Atom, ?String) Convert between an atom and a list of ASCII values. If Atom is instantiated, if will be translated into a list of ASCII values and the result is unified with String. If Atom is unbound and String is a list of ASCII values, it will Atom will be unified with an atom constructed from this list. atom_char(?Atom, ?ASCII) Convert between character and ASCII value for a single character. number_chars(?Number, ?String) Similar to atom_chars/2, but converts between a number and its representation as a list of ASCII values. Fails silently if Atom is unbound and String does not describe a number. name(?AtomOrInt, ?String) String is a list of ASCII values describing Atom. Each of the arguments may be a variable, but not both. When String is bound to an ASCII value list describing an integer and Atom is a variable Atom will be unified with the integer value described by String (e.g. `name(N, "300"), 400 is N + 100' succeeds). int_to_atom(+Int, +Base, -Atom) Convert Int to an ascii representation using base Base and unify the result with Atom. If Base6= 10 the base will be prepended to Atom. Base= 0 will try to interpret Int as an ASCII value and return 0'c. Otherwise 2 Base 36. Some examples are given below. int_to_atom(45, 2, A) ! A = 20101101 int_to_atom(97, 0, A) ! A = 00a int_to_atom(56, 10, A) ! A = 56 int_to_atom(+Int, -Atom) Equivalent to int_to_atom(Int, 10, Atom). term_to_atom(?Term, ?Atom) Succeeds if Atom describes a term that unifies with Term. When Atom is instantiated Atom is converted and then unified with Term. Otherwise Term is ``written'' on Atom using write/1. atom_to_term(+Atom, -Term, -Bindings) Use Atom as input to read_variables/2 and return the read term in Term and the variable bindings in Bindings. Bindings is a list of Name= Varcouples, thus providing access to the actual variable names. See also read_variables/2. concat(?Atom1, ?Atom2, ?Atom3) Atom3 forms the concatenation of Atom1 and Atom2. At least two of the arguments must be instantiated to atoms, intergers or floating point numbers. concat_atom(+List, -Atom) List is a list of atoms, integers or floating point numbers. Succeeds if Atom can be unified with the concatenated elements of List. If List has exactly 2 elements it is equivalent to concat/3, allowing for variables in the list. atom_length(+Atom, -Length) Succeeds if Atom is an atom of Length characters long. This predicate also works for integers and floats, expressing the number of characters output when given to write/1. 3.19 Representing Text in Strings SWI-Prolog supports the data type string. Strings are a time and space efficient mechanism to handle text in Prolog. Atoms are under some circumstances not suitable because garbage collection on them is next to impossible (Although it is possible: BIM_prolog does it). Representing text as a list of ASCII values is, from the logical point of view, the cleanest solution. It however has two drawbacks: 1) they cannot be distinguished from a list of (small) integers; and 2) they consume (in SWI-Prolog) 12 bytes for each character stored. Within strings each character only requires 1 byte storage. Strings live on the global stack and their storage is thus reclaimed on backtracking. Garbage collection can easily deal with strings. The ISO standard proposes "..." is transformed into a string object by read/1 and derivates. This poses problems as in the old convention "..." is transformed into a list of ascii characters. For this reason the style check option `string' is available (see style_check/2). The set of predicates associated with strings is incomplete and tentative. Names and definitions might change in the future to confirm to the emerging standard. string_to_atom(?String, ?Atom) Logical conversion between a string and an atom. At least one of the two arguments must be instantiated. Atom can also be an integer or floating point number. string_to_list(?String, ?List) Logical conversion between a string and a list of ASCII characters. At least one of the two arguments must be instantiated. string_length(+String, -Length) Unify Length with the number of characters in String. This predicate is functonally equivalent to atom_length/2 and also accepts atoms, integers and floats as its first argument. substring(+String, +Start, +Length, -Sub) Create a substring of String that starts at character Start (1 base) and has Length characters. Unify this substring with Sub. 3.20 Operators op(+Precedence, +Type, +Name) Declare Name to be an operator of type Type with precedence Precedence. Name can also be a list of names, in which case all elements of the list are declared to be identical operators. Precedence is an integer between 0 and 1200. Precedence 0 removes the declaration. Type is one of: xf, yf, xfx, xfy, yfx, yfy, fy or fx. The `f' indicates the position of the functor, while x and y indicate the position of the arguments. `y' should be interpreted as ``on this position a term with precedence lower or equal to the precedence of the functor should occur''. For `x' the precedence of the argument must be strictly lower. The precedence of a term is 0, unless its principal functor is an operator, in which case the precedence is the precedence of this operator. A term enclosed in brackets ((...)) has precedence 0. The predefined operators are shown in table 3.1. Note that all operators can be redefined by the user. 1200 xfx -->, :- 1200 fx :-, ?- 1150 fx dynamic, multifile, module_transparent, discontiguous 1100 xfy ;, | 1050 xfy -> 1000 xfy , 954 xfy \\ 900 fy \+, not 900 fx ~ 700 xfx <, =, =.., =@=, =:=, =<, ==, =\=, >, >=, @<, @=<, @>, @>=, \=, \==, is 600 xfy : 500 yfx +, -, /\, \/, xor 500 fx +, -, ?, \ 400 yfx *, /, //, <<, >> 300 xfx mod 200 xfy ^ Table 3.1: System operators current_op(?Precedence, ?Type, ?Name) Succeeds when Name is currently defined as an operator of type Type with precedence Precedence. See also op/3. 3.21 Arithmetic Arithmetic can be divided into some special purpose integer predicates and a series of general predicates for floating point and integer arithmetic as appropriate. The integer predicates are as ``logical'' as possible. Their usage is recommended whenever applicable, resulting in faster and more ``logical'' programs. The general arithmic predicates are optionaly compiled now (see please/3 and the -O command line option). Compiled arithmetic reduces global stack requirements and improves performance. Unfortunately compiled arithmetic cannot be traced, which is why it is optional. The general arithmetic predicates all handle expressions. An expression is either a simple number or a function. The arguments of a function are expressions. The functions are described in section 3.22. between(+Low, +High, ?Value) Low and High are integers, High Low. If Value is an integer, Low Value High. When Value is a variable it is successively bound to all integers between Low and High. succ(?Int1, ?Int2) Succeeds if Int2= Int1+ 1. At least one of the arguments must be instantiated to an integer. plus(?Int1, ?Int2, ?Int3) Succeeds if Int3= Int1+ Int2. At least two of the three arguments must be instantiated to integers. +Expr1 > +Expr2 Succeeds when expression Expr1 evaluates to a larger number than Expr2. +Expr1 < +Expr2 Succeeds when expression Expr1 evaluates to a smaller number than Expr2. +Expr1 =< +Expr2 Succeeds when expression Expr1 evaluates to a smaller or equal number to Expr2. +Expr1 >= +Expr2 Succeeds when expression Expr1 evaluates to a larger or equal number to Expr2. +Expr1 =\= +Expr2 Succeeds when expression Expr1 evaluates to a number non-equal to Expr2. +Expr1 =:= +Expr2 Succeeds when expression Expr1 evaluates to a number equal to Expr2. -Number is +Expr Succeeds when Number has successfully been unified with the number Expr evaluates to. 3.22 Arithmetic Functions Arithmetic functions are terms which are evaluated by the arithmetic predicates described above. SWI-Prolog tries to hide the difference between integer arithmetic and floating point arithmetic from the Prolog user. Arithmetic is done as integer arithmetic as long as possible and converted to floating point arithmetic whenever one of the arguments or the combination of them requires it. If a function returns a floating point value which is whole it is automatically transformed into an integer. There are three types of arguments to functions: Expr Arbitrary expression, returning either a floating point value or an integer. IntExpr Arbitrary expression that should evaluate into an integer. Int An integer. In case integer addition, subtraction and multiplication would lead to an integer overflow the operands are automatically converted to floating point numbers. The floating point functions (sin/1, exp/1, etc.) form a direct interface to the corresponding C library functions used to compile SWI-Prolog. Please refer to the C library documentation for details on percision, error handling, etc. - +Expr Result= Expr +Expr1 + +Expr2 Result= Expr1+ Expr2 +Expr1 - +Expr2 Result= Expr1 Expr2 +Expr1 * +Expr2 Result= Expr1Expr2times +Expr1 / +Expr2 Result= Expr1=Expr2 +IntExpr1 mod +IntExpr2 Result= Expr1mod Expr2 (remainder of division). +IntExpr1 // +IntExpr2 Result= Expr1div Expr2 (integer division). abs(+Expr) Evaluate Expr and return the absolute value of it. max(+Expr1, +Expr2) Evaluates to the largest of both Expr1 and Expr2. min(+Expr1, +Expr2) Evaluates to the smallest of both Expr1 and Expr2. .(+Int, []) A list of one element evaluates to the element. This implies "a" evaluates to the ASCII value of the letter a (97). This option is available for compatibility only. It will not work if `style_check(+string)' is active as "a" will then be tranformed into a string object. The recommended way to specify the ASCII value of the letter `a' is 0'a. random(+Int) Evaluates to a random integer i for which 0 i < Int. The seed of this random generator is determined by the system clock when SWI-Prolog was started. integer(+Expr) Evaluates Expr and rounds the result to the nearest integer. floor(+Expr) Evaluates Expr and returns the largest integer smaller or equal to the result of the evaluation. ceil(+Expr) Evaluates Expr and returns the smallest integer larger or equal to the result of the evaluation. +IntExpr >> +IntExpr Bitwise shift IntExpr1 by IntExpr2 bits to the right. Note that integers are only 27 bits. +IntExpr << +IntExpr Bitwise shift IntExpr1 by IntExpr2 bits to the left. +IntExpr \/ +IntExpr Bitwise `or' IntExpr1 and IntExpr2. +IntExpr /\ +IntExpr Bitwise `and' IntExpr1 and IntExpr2. +IntExpr xor +IntExpr Bitwise `exclusive or' IntExpr1 and IntExpr2. \ +IntExpr Bitwise negation. sqrt(+Expr) Result= square root of Expr sin(+Expr) Result= sine of Expr. Expr is the angle in radials. cos(+Expr) Result= cosine of Expr. Expr is the angle in radials. tan(+Expr) Result= tangus of Expr. Expr is the angle in radials. asin(+Expr) Result= inverse sine of Expr. Result is the angle in radials. acos(+Expr) Result= inverse cosine of Expr. Result is the angle in radials. atan(+Expr) Result= inverse tangus of Expr. Result is the angle in radials. atan(+YExpr, +XExpr) Result= inverse tangus of YExpr / XExpr. Result is the angle in radials. The return value is in the range pi:::pi. Used to convert between rectangular and polar coordinate system. log(+Expr) Result= natural logarithm of Expr log10(+Expr) Result= 10 base logarithm of Expr exp(+Expr) Result= e to the power Expr +Expr1 ^ +Expr2 Result= Expr1 to the power Expr2 pi Evaluates to the mathematical constant pi (3.141593...). e Evaluates to the mathematical constant e (2.718282...). cputime Evaluates to a floating point number expressing the cpu time (in seconds) used by Prolog up till now. See also statistics/2 and time/1. 3.23 Adding Arithmetic Functions Prolog predicates can be given the role of arithmetic function. The last argument is used to return the result, the arguments before the last are the inputs. Arithmetic functions are added using the predicate arithmetic_function/1, which takes the head as its argument. Arithmetic functions are module sensitive, that is they are only visible from the module in which the function is defined and delared. Global arithmetic functions should be defined and registered from module user. Global definitions can be overruled locally in modules. The builtin functions described above can be redefined as well. arithmetic_function(+Head) Register a Prolog predicate as an arithmetic function (see is/2, >/2, etc.). The Prolog predicate should have one more argument than specified by Head, which it either a term Name/Arity, an atom or a complex term. This last argument is an unbound variable at call time and should be instantiated to an integer or floating point number. The other arguments are the parameters. This predicate is module sensitive and will declare the arithmetic function only for the context module, unless declared from module user. Example: 1 ?- [user]. :- arithmetic_function(mean/2). mean(A, B, C) :- C is (A+B)/2. user compiled, 0.07 sec, 440 bytes. Yes 2 ?- A is mean(4, 5). A = 4.500000 current_arithmetic_function(?Head) Succesively unifies all arithmetic functions that are visible from the context module with Head. 3.24 List Manipulation is_list(+Term) Succeeds if Term is bound to the empty list ([]) or a term with functor `.' and arity 2. proper_list(+Term) Equivalent to is_list/1, but also requires the tail of the list to be a list (recursively). Examples: is_list([x|A]) % true proper_list([x|A]) % false append(?List1, ?List2, ?List3) Succeeds when List3 unifies with the concatenation of List1 and List2. The predicate can be used with any instantiation pattern (even three variables). member(?Elem, ?List) Succeeds when Elem can be unified with one of the members of List. The predicate can be used with any instantiation pattern. memberchk(?Elem, +List) Equivalent to member/2, but leaves no choice point. delete(+List1, ?Elem, ?List2) Delete all members of List1 that simultaneously unify with Elem and unify the result with List2. select(?List1, ?Elem, ?List2) Select an element of List1 that unifies with Elem. List2 is unified with the list remaining from List1 after deleting the selected element. Normally used with the instantiation pattern +List1, -Elem, -List2, but can also be used to insert an element in a list using -List1, +Elem, +List2. nth0(?Index, ?List, ?Elem) Succeeds when the Index-th element of List unifies with Elem. Counting starts at 0. nth1(?Index, ?List, ?Elem) Succeeds when the Index-th element of List unifies with Elem. Counting starts at 1. last(?Elem, ?List) Succeeds if Elem unifies with the last element of List. reverse(+List1, -List2) Reverse the order of the elements in List1 and unify the result with the elements of List2. flatten(+List1, -List2) Transform List1, possibly holding lists as elements into a `flat' list by replacing each list with its elements (recursively). Unify the resulting flat list with List2. Example: ?- flatten([a, [b, [c, d], e]], X). X = [a, b, c, d, e] length(?List, ?Int) Succeeds if Int represents the number of elements of list List. Can be used to create a list holding only variables. merge(+List1, +List2, -List3) List1 and List2 are lists, sorted to the standard order of terms (see section 3.5). List3 will be unified with an ordered list holding the both the elements of List1 and List2. Duplicates are not removed. 3.25 Set Manipulation is_set(+Set) Succeeds if set is a proper list (see proper_list/1) without duplicates. list_to_set(+List, -Set) Succeeds if Set holds the same elements as List in the same order, but has no duplicates. See also sort/1. intersection(+Set1, +Set2, -Set3) Succeeds if Set3 unifies with the intersection of Set1 and Set2. Set1 and Set2 are lists without duplicates. They need not be ordered. subtract(+Set, +Delete, -Result) Delete all elements of set `Delete' from `Set' and unify the resulting set with `Result'. union(+Set1, +Set2, -Set3) Succeeds if Set3 unifies with the union of Set1 and Set2. Set1 and Set2 are lists without duplicates. They need not be ordered. subset(+Subset, +Set) Succeeds if all elements of Subset are elements of Set as well. merge_set(+Set1, +Set2, -Set3) Set1 and Set2 are lists without duplicates, sorted to the standard order of terms. Set3 is unified with an ordered list without duplicates holding the union of the elements of Set1 and Set2. 3.26 Sorting Lists sort(+List, -Sorted) Succeeds if Sorted can be unified with a list holding the elements of List, sorted to the standard order of terms (see section 3.5). Duplicates are removed. msort(+List, -Sorted) Equivalent to sort/2, but does not remove duplicates. keysort(+List, -Sorted) List is a list of Key-Valuepairs (e.g. terms of the functor `-' with arity 2). keysort/2 sorts List like msort/2, but only compares the keys. Can be used to sort terms not on standard order, but on any criterion that can be expressed on a multi-dimensional scale. Sorting on more than one criterion can be done using terms as keys, putting the first criterion as argument 1, the second as argument 2, etc. predsort(+Pred, +List, -Sorted) Sorts similar to msort/2, but determines the order of two terms by applying Pred to pairs of elements from List (see apply/2). The predicate should succeed if the first element should be before the second. 3.27 Finding all Solutions to a Goal findall(+Var, +Goal, -Bag) Creates a list of the instantiations Var gets successively on backtracking over Goal and unifies the result with Bag. Succeeds with an empty list if Goal has no solutions. findall/3 is equivalent to bagof/3 with all free variables bound with the existence operator (^), except that bagof/3 fails when goal has no solutions. bagof(+Var, +Goal, -Bag) Unify Bag with the alternatives of Var, if Goal has free variables besides the one sharing with Var bagof will backtrack over the alternatives of these free variables, unifying Bag with the corresponding alternatives of Var. The construct Var^Goal tells bagof not to bind Var in Goal. Bagof/3 fails if Goal has no solutions. The example below illustrates bagof/3 and the ^ operator. The variable bindings are printed together on one line to save paper. 2 ?- listing(foo). foo(a, b, c). foo(a, b, d). foo(b, c, e). foo(b, c, f). foo(c, c, g). Yes 3 ?- bagof(C, foo(A, B, C), Cs). A = a, B = b, C = G308, Cs = [c, d] ; A = b, B = c, C = G308, Cs = [e, f] ; A = c, B = c, C = G308, Cs = [g] ; No 4 ?- bagof(C, A^foo(A, B, C), Cs). A = G324, B = b, C = G326, Cs = [c, d] ; A = G324, B = c, C = G326, Cs = [e, f, g] ; No 5 ?- setof(+Var, +Goal, -Set) Equivalent to bagof/3, but sorts the result using sort/2 to get a sorted list of alternatives without duplicates. 3.28 Invoking Predicates on all Members of a List All the predicates in this section call a predicate on all members of a list or until the predicate called fails. The predicate is called via apply/2, which implies common arguments can be put in front of the arguments obtained from the list(s). For example: ?- maplist(plus(1), [0, 1, 2], X). X = [1, 2, 3] we will phrase this as ``Predicate is applied on ...'' checklist(+Pred, +List) Pred is applied successively on each element of List until the end of the list or Pred fails. In the latter case the checklist/2 fails. maplist(+Pred, ?List1, ?List2) Apply Pred on all successive pairs of elements from List1 and List2. Fails if Pred can not be applied to a pair. See the example above. sublist(+Pred, +List1, ?List2) Unify List2 with a list of all elements of List1 to which Pred applies. 3.29 Forall forall(+Cond, +Action) For all alternative bindings of Cond Action can be proven. The example verifies that all arithmic statements in the list L are correct. It does not say which is wrong if one proves wrong. ?- forall(member(Result = Formula, [2 = 1 + 1, 4 = 2 * 2]), Result =:= Formula). 3.30 Formatted Write The current version of SWI-Prolog provides two formatted write predicates. The first is writef/[1,2], which is compatible with Edinburgh C-Prolog. The second is format/[1,2], which is compatible with Quintus Prolog. We hope the Prolog community will once define a standard formatted write predicate. If you want performance use format/[1,2] as this predicate is defined in C. Otherwise compatibility reasons might tell you which predicate to use. 3.30.1 Writef write_ln(+Term) Equivalent to write(Term), nl. writef(+Atom) Equivalent to writef(Atom, []). writef(+Format, +Arguments) Formatted write. Format is an atom whose characters will be printed. Format may contain certain special character sequences which specify certain formatting and substitution actions. Arguments then provides all the terms required to be output. Escape sequences to generate a single special character: \n is output \l is output \r is output \t is output \\ The character `\' is output \% The character `%' is output \nnn where nnn is an integer (1-3 digits) the character with ASCII code nnn is output (NB : nnn is read as DECIMAL) Escape sequences to include arguments from Arguments. Each time a % escape sequence is found in Format the next argument from Arguments is formatted according to the specification. %t print/1 the next item (mnemonic: term) %w write/1 the next item %q writeq/1 the next item %d display/1 the next item %p print/1 the next item (identical to %t) %n put the next item as a character (i.e. it is an ASCII value) %r write the next item N times where N is the second item (an integer) %s write the next item as a String (so it must be a list of characters) %f perform a ttyflush/0 (no items used) %Nc write the next item Centered in N columns. %Nl write the next item Left justified in N columns. %Nr write the next item Right justified in N columns. N is a decimal number with at least one digit. The item must be an atom, integer, float or string. swritef(-String, +Format, +Arguments) Equivalent to writef/3, but ``writes'' the result on String instead of the current output stream. Example: ?- swritef(S, '%15L%w', ['Hello', 'World']). S = "Hello World" swritef(-String, +Format) Equivalent to swritef(String, Format, []). 3.30.2 Format format(+Format) Defined as `format(Format) :- format(Format, []).' format(+Format, +Arguments) Format is an atom, list of ASCII values, or a Prolog string. Arguments provides the arguments required by the format specification. If only one argument is required and this is not a list of ASCII values the argument need not be put in a list. Otherwise the arguments are put in a list. Special sequences start with the tilde (~), followed by an optional numeric argument, followed by a character describing the action to be undertaken. A numeric argument is either a sequence of digits, representing a positive decimal number, a sequence `, representing the ASCII value of the character (only useful for ~t) or a asterisk (*), in when the numeric argument is taken from the next argument of the argument list, which should be a positive integer. Actions are: ~ Output the tilde itself. a Output the next argument, which should be an atom. This option is equivalent to w. Compatibility reasons only. c Output the next argument as an ASCII value. This argument should be an integer in the range [0, ..., 255] (including 0 and 255). d Output next argument as a decimal number. It should be an integer. If a numeric argument is specified a dot is inserted argument positions from the right (useful for doing fixed point arithmetic with integers, such as handling amounts of money). D Same as d, but makes large values easier to read by inserting a comma every three digits left to the dot or right. e Output next argument as a floating point number in exponentional notation. The numeric argument specifies the precission. Default is 6 digits. Exact representation depends on the C library function printf(). This function is invoked with the format %.e. E Equivalent to e, but outputs a capital E to indicate the exponent. f Floating point in non-exponentional notation. See C library function printf(). g Floating point in e or f notation, whichever is shorter. G Floating point in E or f notation, whichever is shorter. i Ignore next argument of the argument list. Produces no output. k Give the next argument to displayq/1 (canonical write). n Output a newline character. N Only output a newline if the last character output on this stream was not a newline. Not properly implemented yet. p Give the next argument to print/1. q Give the next argument to writeq/1. r Print integer in radix the numeric argument notation. Thus ~16r prints its argument hexadecimal. The argument should be in the range [2, ... 36]. Lower case letters are used for digits above 9. R Same as r, but uses upper case letters for digits above 9. s Output a string of ASCII characters from the next argument. t All remaining space between 2 tabstops is distributed equaly over ~t statements between the tabstops. This space is padded with spaces by default. If an argument is supplied this is taken to be the ASCII value of the character used for padding. This can be used to do left or right alignment, centering, distributing, etc. See also ~| and ~+ to set tab stops. A tabstop is assumed at the start of each line. __Set a tabstop on the current position. If an argument is supplied set a tabstop on the position of that argument. This will cause all ~t's to be distributed between the previous and this tabstop. + Set a tabstop relative to the current position. Further the same as ~|. w Give the next argument to write/1. Example: simple_statistics :- % left to the user format('~tStatistics~t~72|~n~n'), format('Runtime: ~`.t ~2f~34| Inferences: ~`.t ~D~72|~n', [RunT, Inf]), .... Will output Statistics Runtime: .................. 3.45 Inferences: .......... 60,345 sformat(-String, +Format, +Arguments) Equivalent to format/3, but ``writes'' the result on String instead of the current output stream. Example: ?- sformat(S, '~w~t~15|~w', ['Hello', 'World']). S = "Hello World" sformat(-String, +Format) Equivalent to `sformat(String, Format, []).' 3.30.3 Programming Format format_predicate(+Char, +Head) If a sequence ~c (tilde, followed by some character) is found, the format derivates will first check whether the user has defined a predicate to handle the format. If not, the built in formatting rules described above are used. Char is either an ascii value, or a one character atom, specifying the letter to be (re)defined. Head is a term, whose name and arity are used to determine the predicate to call for the redefined formatting character. The first argument to the predicate is the numeric argument of the format command, or the atom defaultif no argument is specified. The remaining arguments are filled from the argument list. The example below redefines ~n to produce Arg times return followed by linefeed (so a (Grr.) DOS machine is happy with the output). :- format_predicate(n, dos_newline(_Arg)). dos_newline(Arg) :- between(1, Ar, _), put(13), put(10), fail ; true. 3.31 Terminal Control The following predicates form a simple access mechanism to the Unix termcap library to provide terminal independant I/O for screen terminals. The library package tty builds on top of these predicates. tty_get_capability(+Name, +Type, -Result) Get the capability named Name from the termcap library. See termcap(5) for the capability names. Type specifies the type of the expected result, and is one of string, numberor bool. String results are returned as an atom, number result as an integer and bool results as the atom on or off. If an option cannot be found this predicate fails silently. The results are only computed once. Succesive queries on the same capability are fast. tty_goto(+X, +Y) Goto position (X, Y) on the screen. Note that the predicates line_count/2 and line_position/2 will not have a well defined behaviour while using this predicate. tty_put(+Atom, +Lines) Put an atom via the termcap library function tputs(). This function decodes padding information in the strings returned by tty_get_capability/3 and should be used to output these strings. Lines is the number of lines affected by the operation, or 1 if not applicable (as in almost all cases). set_tty(-OldStream, +NewStream) Set the output stream, used by tty_put/2 and tty_goto/2 to a specific stream. Default is user_output. 3.32 Unix Interaction shell(+Command, -Status) Execute Command on the operating system. Command is given to the bourne shell (/bin/sh). Status is unified with the exit status of the command. shell(+Command) Equivalent to `shell(Command, 0)'. shell Start an interactive Unix shell. Default is /bin/sh, the environment variable SHELL overrides this default. getenv(+Name, -Value) Get Unix environment variable (see csh(1) and sh(1)). Fails if the variable does not exist. setenv(+Name, +Value) Set Unix environment variable. Name and Value should be instantiated to atoms or integers. The environment variable will be passed to shell/[0-2] and can be requested using getenv/2. unsetenv(+Name) Remove Unix environment variable from the environment. get_time(-Time) Return the number of seconds that elapsed since the epoch of Unix, 1 January 1970, 0 hours. Time is a floating point number. Its granularity is system dependant. On SUN, this is 1/60 of a second. convert_time(+Time, -Year, -Month, -Day, -Hour, -Minute, -Second, -MilliSeconds) Convert a time stamp, provided by get_time/1, file_time/2, etc. Year is unified with the year, Month with the month number (January is 1), Day with the day of the month (starting with 1), Hour with the hour of the day (0--23), Minute with the minute (0--59). Second with the second (0--59) and MilliSecond with the milli seconds (0--999). Note that the latter might not be acurate or might always be 0, depending on the timing capabilities of the system. 3.33 Unix File System Interaction access_file(+File, +Mode) Succeeds when File exists and can be accessed by this prolog process under mode Mode. Mode is one of the atoms read, write, append, exist, none or execute. File may also be the name of a directory. Fails silently otherwise. access_file(File, none)simply succeeds without testing anything. exists_file(+File) Succeeds when File exists. This does not imply the user has read and/or write permission for the file. same_file(+File1, +File2) Succeeds if both filenames refer to the same physical file. That is, if File1 and File2 are the same string or both names exist and point to the same file (due to hard or symbolic links and/or relative vs. absolute paths). exists_directory(+Directory) Succeeds if Directory exists. This does not imply the user has read, search and or write permission for the directory. delete_file(+File) Unlink File from the Unix file system. rename_file(+File1, +File2) Rename File1 into File2. Currently files cannot be moved across devices. size_file(+File, -Size) Unify Size with the size of File in characters. time_file(+File, -Time) Unify the last modification time of File with Time. Time is a floating point number expressing the seconds elapsed since Jan 1, 1970. absolute_file_name(+File, -Absolute) Expand Unix file specification into an absolute path. User home directory expansion (~ and ~user) and variable expansion is done. The absolute path is canonised: references to `.' and `..' are deleted. SWI-Prolog uses absolute file names to register source files independant of the current working directory. is_absolute_file_name(+File) True if File 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 :. This predicate is intended to provide platform-independent checking for absolute paths. See also absolute_file_name/2 and prolog_to_os_filename/2. expand_file_name(+WildChart, -List) Unify List with a sorted list of files or directories matching WildChart. The normal Unix wildchart constructs `?', `*', `[...]' and `{...}' are recognised. The interpretation of `{...}' is interpreted slightly different from the C shell (csh(1)). The comma separated argument can be arbitrary patterns, including `{...}' patterns. The empty pattern is legal as well: `{.pl,}' matches either `.pl' or the empty string. prolog_to_os_filename(?PrologPath, ?OsPath) 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. chdir(+Path) Change working directory to Path. 3.34 User Toplevel Manipulation break Recursively start a new Prolog top level. This Prolog top level has it's own stacks, but shares the heap with all break environments and the top level. Debugging is switched off on entering a break and restored on leaving one. The break environment is terminated by typing the system's end-of-filecharacter (control-D). If the -t toplevelcommand line option is given this goal is started instead of entering the default interactive top level (prolog/0). abort Abort the Prolog execution and start a new top level. If the -t toplevelcommand line options is given this goal is started instead of entering the default interactive top level. Break environments are aborted as well. All open files except for the terminal related files are closed. The input- and output stream again refers to user. BUG: Erased clauses which could not actually be removed from the database, because they are active in the interpreter, will never be garbage collected after an abort. halt Terminate Prolog execution. Open files are closed and if the command line option -tty is not active the terminal status (see Unix stty(1)) is restored. Hooks may be registered both in Prolog and in foreign code. Prolog hooks are registered using at_halt/1. halt/0 is equivalent to halt(0). halt(+Status) Terminate Prolog execution with given status. Status is an integer. See also halt/0. prolog This goal starts the default interactive top level. prolog/0 is terminated (succeeds) by typing control-D. 3.35 Creating a Protocol of the User Interaction SWI-Prolog offers the possibility to log the interaction with the user on a file. All Prolog interaction, including warnings and tracer output, are written on the protocol file. protocol(+File) Start protocolling on file File. If there is already a protocol file open then close it first. If File exists it is truncated. protocola(+File) Equivalent to protocol/1, but does not truncate the File if it exists. noprotocol Stop making a protocol of the user interaction. Pending output is flushed on the file. protocolling(-File) Succeeds if a protocol was started with protocol/1 or protocola/1 and unifies File with the current protocol output file. 3.36 Debugging and Tracing Programs trace Start the tracer. trace/0 itself cannot be seen in the tracer. Note that the Prolog toplevel treats trace/0 special; it means `trace the next goal'. tracing Succeeds when the tracer is currently switched on. tracing/0 itself can not be seen in the tracer. notrace Stop the tracer. notrace/0 itself cannot be seen in the tracer. trace(+Pred) Equivalent to trace(Pred, +all). trace(+Pred, +Ports) Put a trace-point on all predicates meeting the predicate specification Pred. Ports is a list of portnames (call, redo, exit, fail). The atom all refers to all ports. If the port is predeced by a `-' sign the trace-point is cleared for the port. If it is predeced by a `+' the trace-point is set. The predicate trace/2 activates debug mode (see debug/0). Each time a port (of the 4-port model) is passed that has a trace-point set the goal is printed as with trace/0. Unlike trace/0 however, the execution is continued without asking for further information. Examples: ?- trace(hello). Trace all ports of hello with any arity in any module. ?- trace(foo/2, +fail) Trace failures of foo/2 in any module. ?- trace(bar/1, -all) Stop tracing bar/1. The predicate debugging/0 shows all currently defined trace-points. debug Start debugger (stop at spy points). nodebug Stop debugger (do not trace, nor stop at spy points). debugging Print debug status and spy points on current output stream. spy(+Pred) Put a spy point on all predicates meeting the predicate specification Pred. See section 3.3. nospy(+Pred) Remove spy point from all predicates meeting the predicate specification Pred. nospyall Remove all spy points from the entire program. leash(?Ports) Set/query leashing (ports which allow for user interaction). Ports is one of +Name, -Name, ?Name or a list of these. +Nameenables leashing on that port, -Name disables it and ?Name succeeds or fails according to the current setting. Recognised ports are: call, redo, exit, fail and unify. The special shorthand all refers to all ports, fullrefers to all ports except for the unify port (default). half refers to the call, redo and fail port. visible(+Ports) Set the ports shown by the debugger. See leash/1 for a description of the port specification. Default is full. unknown(-Old, +New) Unify Old with the current value of the unknown system flag. On success New will be used to specify the new value. New should be instantiated to either fail or trace and determines the interpreter's action when an undefined predicate which is not declared dynamic is encountered (see dynamic/1). fail implies the predicate just fails silently. traceimplies the tracer is started. Default is trace. The unknown flag is local to each module and unknown/2 is module transparent. Using it as a directive in a module file will only change the unknown flag for that module. Using the :/2 construct the behaviour on trapping an undefined predicate can be changed for any module. Note that if the unknown flag for a module equals fail the system will not call exception/3 and will not try to resolve the predicate via the dynamic library system. The system will still try to import the predicate from the public module. style_check(+Spec) Set style checking options. Spec is either +