University of Amsterdam Dept. of Social Science Informatics (SWI) Roeterstraat 15, 1018 WB Amsterdam The Netherlands Tel. (+31) 20 5256121 SSWWII--PPrroolloogg 22..99 RReeffeerreennccee MMaannuuaall _U_p_d_a_t_e_d _f_o_r _v_e_r_s_i_o_n _2_._9_._9_, _M_a_r_c_h _1_9_9_8 _J_a_n _W_i_e_l_e_m_a_k_e_r jan@swi.psy.uva.nl SWI-Prolog is a Prolog implementation based on a subset of the WAM (Warren Abstract Machine [Warren, 1983]). SWI-Prolog has been designed and implemented such that it can easily be modified for experiments with logic programming and the relation between logic programming and other programming paradigms (such as the object oriented XPCE environment [Anjewierden & Wielemaker, 1989]). SWI-Prolog has a rich set of built-in predicates and reasonable performance, which makes it possible to develop substantial applications in it. The current version offers a module system, garbage collection and an interface to the C language. This document gives an overview of the features, system limits and built-in predicates. Copyright Oc 1990--1998, University of Amsterdam CChhaapptteerr 11.. IINNTTRROODDUUCCTTIIOONN 11..11 SSWWII--PPrroolloogg SWI-Prolog has been designed and implemented to get a Prolog implementation which can be used for experiments with logic programming and the relation to other programming paradigms. The intention was to build a Prolog environment which offers enough power and flexibility to write substantial applications, but is straightforward enough to be modified for experiments with debugging, optimisation or the introduction of non-standard data types. Performance optimisation is limited due to the main objectives: portability (SWI-Prolog is entirely written in C and Prolog) and modifiability. SWI-Prolog is based on a very restricted form of the WAM (Warren Abstract Machine) described in [Bowen & Byrd, 1983] which defines only 7 instructions. Prolog can easily be compiled into this language and the abstract machine code is easily decompiled back into Prolog. As it is also possible to wire a standard 4-port debugger in the WAM interpreter there is no need for a distinction between compiled and interpreted code. Besides simplifying the design of the Prolog system itself this approach has advantages for program development: the compiler is simple and fast, the user does not have to decide in advance whether debugging is required and the system only runs slightly slower when in debug mode. The price we have to pay is some performance degradation (taking out the debugger from the WAM interpreter improves performance by about 20%) and somewhat additional memory usage to help the decompiler and debugger. SWI-Prolog extends the minimal set of instructions described in [Bowen & Byrd, 1983] to improve performance. While extending this set care has been taken to maintain the advantages of decompilation and tracing of compiled code. The extensions include specialised instructions for unification, predicate invocation, some frequently used built-in predicates, arithmetic, and control (;//22, |//22), if-then (->//22) and not (\+//11). This manual does not describe the full syntax and semantics of SWI- Prolog, nor how one should write a program in Prolog. These subjects have been described extensively in the literature. See [Bratko, 1986], [Sterling & Shapiro, 1986], and [Clocksin & Melish, 1987]. For more advanced Prolog material see [OKeefe, 1990]. Syntax and standard operator declarations confirm to the `Edinburgh standard'. Most built in predicates are compatible with those described in [Clocksin & Melish, 1987]. SWI-Prolog also offers a number of primitive predicates compatible with Quintus Prolog [Qui, 1997] and BIM_Prolog [BIM, 1989]. ISO compliant predicates are based on ``Prolog: The Standard'', [Deransart _e_t _a_l_., 1996]. 11..22 SSttaattuuss This manual describes version 2.9 of SWI-Prolog. SWI-Prolog has been used now for several years. The application range includes Prolog course material, meta-interpreters, simulation of parallel Prolog, learning systems, natural language processing and two large workbenches for knowledge engineering. Although we experienced rather obvious and critical bugs can remain unnoticed for a remarkable long period, we can assume the basic Prolog system is fairly stable. Bugs can be expected in infrequently used builtin predicates. Some bugs are known to the author. They are described as footnotes in this manual. 11..33 SShhoouulldd yyoouu bbee UUssiinngg SSWWII--PPrroolloogg?? There are a number of reasons why you better choose a commercial Prolog system, or another academic product: o _S_W_I_-_P_r_o_l_o_g _i_s _n_o_t _s_u_p_p_o_r_t_e_d Although I usually fix bugs shortly after a bug report arrives, I cannot promise anything. Now that the sources are provided, you can always dig into them yourself. o _M_e_m_o_r_y _r_e_q_u_i_r_e_m_e_n_t_s _a_n_d _p_e_r_f_o_r_m_a_n_c_e _a_r_e _y_o_u_r _f_i_r_s_t _c_o_n_c_e_r_n_s A number of commercial compilers are more keen on memory and performance than SWI-Prolog. I do not wish to sacrifice some of the nice features of the system, nor its portability to compete on raw performance. o _Y_o_u _n_e_e_d _f_e_a_t_u_r_e_s _n_o_t _o_f_f_e_r_e_d _b_y _S_W_I_-_P_r_o_l_o_g In this case you may wish to give me suggestions for extensions. If you have great plans, please contact me (you might have to implement them yourself however). On the other hand, SWI-Prolog offers some nice facilities: o _N_i_c_e _e_n_v_i_r_o_n_m_e_n_t This includes `Do What I Mean', automatic completion of atom names, history mechanism and a tracer that operates on single key-strokes. Interfaces to standard Unix editors are provided, as well as a facility to maintain programs (see mmaakkee//00). o _V_e_r_y _f_a_s_t _c_o_m_p_i_l_e_r The compiler handles about 100K bytes per second on a SPARC-II processor. o _T_r_a_n_s_p_a_r_e_n_t _c_o_m_p_i_l_e_d _c_o_d_e SWI-Prolog compiled code can be treated just as interpreted code: you can list it, trace it, assert to or retract from it, etc. This implies you do not have to decide beforehand whether a module should be loaded for debugging or not. Also, performance is much better than the performance of most interpreters. o _P_r_o_f_i_l_i_n_g SWI-Prolog offers tools for performance analysis, which can be very useful to optimise programs. Unless you are very familiar with Prolog and Prolog performance considerations this might be more helpful than a better compiler without these facilities. o _F_l_e_x_i_b_i_l_i_t_y SWI-Prolog allows for easy and flexible integration with C, both Prolog calling C functions as C calling Prolog predicates. SWI-Prolog is provided in source form, which implies SWI-Prolog can be linked in with another package. Command line options and predicates to obtain information from the system and feedback into the system are provided. o _I_n_t_e_g_r_a_t_i_o_n _w_i_t_h _X_P_C_E SWI-Prolog offers a tight integration to the Object Ori- ented Package for User Interface Development, called XPCE [Anjewierden & Wielemaker, 1989]. XPCE allows you to implement graphical user interfaces that are source-code compatible over Unix/X11 and Win32 (Windows 95 and NT). 11..44 TThhee XXPPCCEE GGUUII ssyysstteemm ffoorr PPrroolloogg The XPCE GUI system for dynamically typed languages has been with SWI-Prolog for a long time. It is developed by Anjo Anjewierden and Jan Wielemaker from the department of SWI, University of Amsterdam. It aims at a high-productive development environment for graphical applications based on Prolog. Object oriented technology has proven to be a suitable model for implementing GUIs, which typically deal with things Prolog is not very good at: event-driven control and global state. With XPCE, we designed a system that has similar characteristics that make Prolog such a powerful tool: dynamic typing, meta-programming and dynamic modification of the running system. XPCE is an object-system written in the C-language. It provides for the implementation of methods in multiple languages. New XPCE classes may be defined from Prolog using a simple, natural syntax. The body of the method is executed by Prolog itself, providing a natural interface between the two systems. Below is a very simple class definition. :- pce_begin_class(prolog_lister, frame, "List Prolog predicates"). initialise(Self) :-> "As the C++ constructor":: send(Self, send_super, initialise, 'Prolog Lister'), send(Self, append, new(D, dialog)), send(D, append, text_item(predicate, message(Self, list, @arg1))), send(new(view), below, D). list(Self, From:name) :-> "List predicates from specification":: ( term_to_atom(Term, From) -> get(Self, member, view, V), pce_open(V, write, Fd), set_output(Fd), listing(Term), close(Fd) ; send(Self, report, error, 'Syntax error') ). :- pce_end_class. test :- send(new(prolog_lister), open). The 165 built-in classes deal with the meta-environment, data- representation and---of course---graphics. The graphics classes concentrate on direct-manipulation of diagrammatic representations. AAvvaaiillaabbiilliittyy.. XPCE runs on most Unixtm platforms, Windows 95 and Windows NT. It has been connected to SWI-Prolog, SICStustm and Quintustm Prolog as well as some Lisp dialects and C++. The Quintus version is commercially distributed and supported as ProWindows-3tm. IInnffoo.. further information is available from http://www.swi.psy.uva.nl/projects/xpce/home.html or by E-mail to xpce-request@swi.psy.uva.nl. There is a demo version for Windows 95 and NT in ftp://swi.psy.uva.nl/pub/xpce/Windows/bin/, and one for the i386/Linux system in ftp://swi.psy.uva.nl/pub/xpce/linux. For information on ProWindows-3, please see http://www.aiil.co.uk, or contact sales@aiil.co.uk. 11..55 VVeerrssiioonn 11..55 RReelleeaassee NNootteess 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 ccoonnvveerrtt__ttiimmee//88 is available to get the year, month, etc. The predicate ttiimmee//66 has been deleted. ggeett__ttiimmee//11 and ccoonnvveerrtt__ttiimmee//88 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. 11..66 VVeerrssiioonn 11..66 RReelleeaassee NNootteess Version 1.6 is completely compatible with version 1.5. Some new features have been added, the system has been ported to various new platforms and there is a provisional interface to GNU Emacs. This interface will be improved and documented later. The WAM virtual-machine interpreter has been modified to use GCC-2's support for threaded code. From version 1.6, the sources are now versioned using the CVS version control system. 11..77 VVeerrssiioonn 11..77 RReelleeaassee NNootteess Version 1.7 integrates the GNU-readline library, offering powerful history and command-line editing both using Emacs and vi key-bindings. 11..88 VVeerrssiioonn 11..88 RReelleeaassee NNootteess Version 1.8 offers a stack-shifter to provide dynamically expanding stacks on machines that do not offer operating-system support for implementing dynamic stacks. 11..99 VVeerrssiioonn 11..99 RReelleeaassee NNootteess Version 1.9 offers better portability including an MS-Windows 3.1 version. Changes to the Prolog system include: o _R_e_d_e_f_i_n_i_t_i_o_n _o_f _s_y_s_t_e_m _p_r_e_d_i_c_a_t_e_s Redefinition of system predicates was allowed silently in older versions. Version 1.9 only allows it if the new definition is headed by a :- rreeddeeffiinnee__ssyysstteemm__pprreeddiiccaattee//11directive. o _`_A_n_s_w_e_r_' _r_e_u_s_e The toplevel maintains a table of bindings returned by toplevel goals and allows for reuse of these bindings by prefixing the variables with the $ sign. See section 2.5. o _B_e_t_t_e_r _s_o_u_r_c_e _c_o_d_e _a_d_m_i_n_i_s_t_r_a_t_i_o_n Allows for proper updating of multifile predicates and finding the sources of individual clauses. 11..1100 VVeerrssiioonn 22..00 RReelleeaassee NNootteess Version 2.0 is first of all a freeze of all the features added to the various 1.9.x releases. Version 2.0.6 for PC has moved from the WATCOM C 32-bit windows extender to Windows NT and runs under Windows 3.1 using the Win32s NT emulator. New features offered: o _3_2_-_b_i_t _V_i_r_t_u_a_l _M_a_c_h_i_n_e Removes various limits and improves performance. o _I_n_l_i_n_e _f_o_r_e_i_g_n _f_u_n_c_t_i_o_n_s `Simple' foreign predicates no longer build a Prolog stack-frame, but are directly called from the VM. Notably provides a speedup for the test predicates such as vvaarr//11, etc. o _V_a_r_i_o_u_s _c_o_m_p_a_t_i_b_i_l_i_t_y _i_m_p_r_o_v_e_m_e_n_t_s o _S_t_r_e_a_m _b_a_s_e_d _I_/_O _l_i_b_r_a_r_y All SWI-Prolog's I/O is now handled by the stream-package defined in the foreign include file SWI-Stream.h. Physical I/O of Prolog streams may be redefined through the foreign language interface, facilitating much simpler integration in window environments. Version 2.0.6 offers a few incompatibilities: o rreettrraaccttaallll//11 In previous releases, the definition of rreettrraaccttaallll//11 was: retractall(Term) :- retract(Term), fail. retractall(_). As from version 2.0.6, rreettrraaccttaallll//11 is implemented as a deterministic foreign predicate compatible with Quintus Prolog. It behaves as: retractall(Head) :- retract(Head), fail. retractall(Head) :- retract((Head :- _)), fail. retractall(_). I.e. the definition behaves the same when handling predicates consisting of facts. Clauses with a non-true body will be retracted if their head matches. o _F_o_r_e_i_g_n _i_n_t_e_r_f_a_c_e _t_y_p_e_s All foreign interface types now have names ending in _t to lessen the chance for conflicts. term, atomic, functor and module have #define's for backward compatibility. o PPLL__rreeggiisstteerr__ffoorreeiiggnn(()) The attributes is now a bitwise or of the attribute flags rather than a 0 terminated list. This has no consequences for predicates that have no attributes (99% of them), while predicates with just one attribute will generate a compiler warning, but work properly otherwise. Predicates with more than one attributes must be changed. o PL_dispatch_events This pointer is replaced by PPLL__ddiissppaattcchh__hhooookk(()). A function was necessary for the Win32 .DLL interface. 11..1111 VVeerrssiioonn 22..11 RReelleeaassee NNootteess In addition to several bug fixes, the 2.1 versions provide some new features: o sseettaarrgg//33 A new predicate sseettaarrgg//33 for extra-logical (destructive) assignment to arguments of terms is provided. o _M_o_d_i_f_i_e_d kkeeyyssoorrtt//22 kkeeyyssoorrtt//22 is now stable with regard to multiple values on the same key. Makes this predicate compatible with SICStus and Quintus. o _M_o_d_i_f_i_e_d _g_r_a_m_m_a_r _r_u_l_e _e_x_p_a_n_s_i_o_n DCG translation of free variables now calls pphhrraassee//33, which has been changed slightly to deal with `un-parsing'. Modification is probably not complete, but it fixes some problems encountered by Michael B"ohlen. o _E_x_c_e_p_t_i_o_n _h_a_n_d_l_i_n_g The top of the runtime stack are automatically dumped on floating point exceptions. o _F_o_r_e_i_g_n _i_n_t_e_r_f_a_c_e Added facilities to allow for embedding SWI-Prolog in C applications. 11..1122 VVeerrssiioonn 22..55 RReelleeaassee NNootteess Version 2.5 is an intermediate release on the path from 2.1 to 3.0. All changes are to the foreign-language interface, both to user- and system predicates implemented in the C-language. The aim is twofold. First of all to make garbage-collection and stack-expansion (stack-shifts) possible while foreign code is active without the C-programmer having to worry about locking and unlocking C-variables pointing to Prolog terms. The new approach is closely compatible to the Quintus and SICStus Prolog foreign interface using the +term argument specification (see their respective manuals). This allows for writing foreign interfaces that are easily portable over these three Prolog platforms. According to the current plan, ISO compliant exception handling and hooks for source-code debugging will be added before the system will be called 3.0. Apart from various bug fixes listed in the Changelog file, these are the main changes since 2.1.0: o _I_S_O _c_o_m_p_a_t_i_b_i_l_i_t_y Many ISO compatibility features have been added: ooppeenn//44, arithmetic functions, syntax, etc. o _W_I_N_3_2 Many fixes for the Win32 (NT, '95 and win32s) platforms. Notably many problems related to pathnames and a problem in the garbage collector. o _P_e_r_f_o_r_m_a_n_c_e Many changes to the clause indexing system: added hash-tables, lazy computation of the index information, etc. o _P_o_r_t_a_b_l_e _s_a_v_e_d_-_s_t_a_t_e_s The predicate qqssaavvee__pprrooggrraamm//[[11,,22]] allows for the creating of machine independent saved-states that load very quickly. 11..1133 VVeerrssiioonn 22..66 RReelleeaassee NNootteess Version 2.6 provides a stable implementation of the features added in the 2.5.x releases, but at the same time implements a number of new features that may have impact on the system stability. o _3_2_-_b_i_t _i_n_t_e_g_e_r _a_n_d _d_o_u_b_l_e _f_l_o_a_t _a_r_i_t_h_m_e_t_i_c The biggest change is the support for full 32-bit signed integers and raw machine-format double precision floats. The internal data representation as well as the arithmetic instruction set and interface to the arithmetic functions has been changed for this. o _E_m_b_e_d_d_i_n_g _f_o_r _W_i_n_3_2 _a_p_p_l_i_c_a_t_i_o_n_s The Win32 version has been reorganised. The Prolog kernel is now implemented as Win32 DLL that may be embedded in C-applications. Two front ends are provided, one for window-based operation and one to run as a Win32 console application. o _C_r_e_a_t_i_n_g _s_t_a_n_d_-_a_l_o_n_e _e_x_e_c_u_t_a_b_l_e_s Version 2.6.0 can create stand-alone executables by attaching the saved-state to the emulator. See qqssaavvee__pprrooggrraamm//22. 11..1144 VVeerrssiioonn 22..77 RReelleeaassee NNootteess Version 2.7 reorganises the entire data-representation of the Prolog data itself. The aim is to remove most of the assumption on the machine's memory layout to improve portability in general and enable embedding on systems where the memory layout may depend on invocation or on how the executable is linked. The latter is notably a problem on the Win32 platforms. Porting to 64-bit architectures should be feasible now. Furthermore, 2.7 lifts the limits on arity of predicates and number of variables in a clause considerably and allow for further expansion at minimal cost. 11..1155 VVeerrssiioonn 22..88 RReelleeaassee NNootteess data-representation changes of 2.7.x stable. Version 2.8 exploits the changes of of 2.7 to support 64-bit processors like the DEC Alpha. As of version 2.8.5, the representation of recorded the terms has changed, and terms on the heap are now represented in a compiled format. SWI-Prolog no longer limits the use of mmaalllloocc(()) or uses assumptions on the addresses returned by this function. 11..1166 VVeerrssiioonn 22..99 RReelleeaassee NNootteess Version 2.9 is the next step towards version 3.0, improving ISO compliance and introducing ISO compliant exception handling. New are ccaattcchh//33, tthhrrooww//11, aabboolliisshh//11, wwrriittee__tteerrmm//[[22,,33]], wwrriittee__ccaannoonniiccaall//[[11,,22]] and the C-functions PPLL__eexxcceeppttiioonn(()) and PPLL__tthhrrooww(()). The predicates ddiissppllaayy//[[11,,22]] and ddiissppllaayyqq//[[11,,22]] have been moved to library(backcomp), so old code referring to them will autoload them. The interface to PPLL__ooppeenn__qquueerryy(()) has changed. The _d_e_b_u_g argument is replaced by a bitwise or'ed _f_l_a_g_s argument. The values FALSE and TRUE have their familiar meaning, making old code using these constants compatible. Non-zero values other than TRUE (1) will be interpreted different. 11..1177 AAcckknnoowwlleeddggeemmeennttss Some small parts of the Prolog code of SWI-Prolog are modified versions of the corresponding Edinburgh C-Prolog code: grammar rule compilation and wwrriitteeff//22. Also some of the C-code originates from C-Prolog: finding the path of the currently running executable and the code underlying aabbssoolluuttee__ffiillee__nnaammee//22. Ideas on programming style and techniques originate from C-Prolog and Richard O'Keefe's _t_h_i_e_f editor. An important source of inspiration are the programming techniques introduced by Anjo Anjewierden in PCE version 1 and 2. I also would like to thank those who had the fade of using the early versions of this system, suggested extensions or reported bugs. Among them are Anjo Anjewierden, Huub Knops, Bob Wielinga, Wouter Jansweijer, Luc Peerdeman, Eric Nombden, Frank van Harmelen, Bert Rengel. Martin Jansche (jansche@novell1.gs.uni-heidelberg.de) has been so kind to reorganise the sources for version 2.1.3 of this manual. Horst von Brand has been so kind to fix many typos in the 2.7.14 manual. Thanks! CChhaapptteerr 22.. OOVVEERRVVIIEEWW 22..11 SSttaarrttiinngg SSWWII--PPrroolloogg ffrroomm tthhee UUnniixx SShheellll 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 ccoonnssuulltt//11) the user's initialisation file. This initialisation file should be named `.plrc' and reside either in the current directory or in the user's home directory. If both exist the initialisation file from the current directory is loaded. The name of the initialisation file can be changed with the `-f file' option. After loading the initialisation file SWI-Prolog executes a user initialisation goal. The default goal is a system predicate that prints the banner message. The default can be modified with the `-g goal' option. Next the toplevel goal is started. Default is the interactive Prolog loop (see pprroolloogg//00). The user can overwrite this default with the `-t toplevel' option. 22..11..11 CCoommmmaanndd LLiinnee OOppttiioonnss The full set of command line options is given below: --hheellpp When given as the only option, it summarises the most important options. --vv When given as the only option, it summarises the version and the architecture identifier. --aarrcchh When given as the only option, it prints the architecture identifier (see feature(arch, Arch)) and exits. --LL_s_i_z_e_[_k_m_] Give local stack limit (2 Mbytes default). Note that there is no space between the size option and its argument. By default, the argument is interpreted in Kbytes. Postfixing the argument with m causes the argument to be interpreted in Mbytes. The following example specifies 32 Mbytes local stack. % pl -L32m A maximum is useful to stop buggy programs from claiming all memory resources. -L0 sets the limit to the highest possible value. --GG_s_i_z_e_[_k_m_] Give global stack limit (4 Mbytes default). See -L for more details. --TT_s_i_z_e_[_k_m_] Give trail stack limit (4 Mbytes default). This limit is relatively high because trail-stack overflows are not often caused program bugs. See -L for more details. --AA_s_i_z_e_[_k_m_] Give argument stack limit (1 Mbytes default). The argument stack limits the maximum nesting of terms that can be compiled and executed. The SWI-Prolog does `last-argument optimisation' to avoid many deeply nested structure using this stack. Enlarging this limit is only necessary in extreme cases. See -L for more details. --HH_s_i_z_e_[_k_m_] Give mmaalllloocc(()) heap limit. The default is to raise the limit as high as possible. This option only applies to machines using the mmmmaapp(()) function for allocating the Prolog stacks. See -L for more details. --cc _f_i_l_e _._._. Compile files into an `intermediate code file'. See section 2.7. --oo _o_u_t_p_u_t Used in combination with -c or -b to determine output file for compilation. --OO Optimised compilation. See pplleeaassee//33. --ff _f_i_l_e Use _f_i_l_e as initialisation file instead of `.plrc'. `-f none' stops SWI-Prolog from searching for an initialisation file. --FF _s_c_r_i_p_t Selects a startup-script from the SWI-Prolog home directory. The script-file is named <_s_c_r_i_p_t>.rc. The default _s_c_r_i_p_t name is deduced from the executable, taking the leading alphanumerical characters (letters, digits and underscore) from the program-name. -F none stops looking for a script. Intended for simple management of slightly different versions. One could for example write a script iso.rc and then select ISO compatibility mode using pl -F iso or make a link from iso-pl to pl. --gg _g_o_a_l _G_o_a_l is executed just before entering the top level. Default is a predicate which prints the welcome message. The welcome message can thus be suppressed by giving -g true. _g_o_a_l can be a complex term. In this case quotes are normally needed to protect it from being expanded by the Unix shell. --tt _g_o_a_l Use _g_o_a_l as interactive toplevel instead of the default goal pprroolloogg//00. _g_o_a_l can be a complex term. If the toplevel goal succeeds SWI-Prolog exits with status 0. If it fails the exit status is 1. This flag also determines the goal started by bbrreeaakk//00 and aabboorrtt//00. If you want to stop the user from entering interactive mode start the application with `-g goal' and give `halt' as toplevel. --ttttyy Switches tty control (using ioctl(2)) on (+tty) or off (-tty). Normally tty control is switched on. This default depends on the installation. You may wish to switch tty control off if Prolog is used from an editor such as Emacs. If switched off ggeett__ssiinnggllee__cchhaarr//11and the tracer will wait for a return. --xx _b_o_o_t_f_i_l_e Boot from _b_o_o_t_f_i_l_e instead of the system's default boot file. A bootfile is a file resulting from a Prolog compilation using the -b or -c option or a program saved using qqssaavvee__pprrooggrraamm//[[11,,22]]. --rr _r_e_s_t_o_r_e_f_i_l_e Restore a state created by ssaavvee__pprrooggrraamm//[[11,,22]] or ssaavvee//[[11,,22]] using the new-style saved-states. Equivalent to restore(restorefile) from Prolog. --pp _a_l_i_a_s_=_p_a_t_h_1_[_:_p_a_t_h_2 _._._._] Define a path alias for file_search_path. _a_l_i_a_s is the name of the alias, _p_a_t_h_1 _._._. is a : separated list of values for the alias. A value is either a term of the form alias(value) or pathname. The computed aliases are added to ffiillee__sseeaarrcchh__ppaatthh//22 using aasssseerrttaa//11, so they precede predefined values for the alias. See ffiillee__sseeaarrcchh__ppaatthh//22 for details on using this file-location mechanism. -- Stops scanning for more arguments, so you can pass arguments for your application after this one. The following options are for system maintenance. They are given for reference only. --bb _i_n_i_t_f_i_l_e _._._.-c _f_i_l_e _._._. Boot compilation. _i_n_i_t_f_i_l_e _._._. are compiled by the C-written bootstrap compiler, _f_i_l_e _._._. by the normal Prolog compiler. System maintenance only. --dd _l_e_v_e_l Set debug level to _l_e_v_e_l. Only has effect if the system is compiled with the -DO_DEBUG flag. System maintenance only. 22..22 GGNNUU EEmmaaccss IInntteerrffaaccee A provisional interface to emacs has been included since version 1.6 of SWI-Prolog. The interface is based on the freely distributed interface delivered with Quintus Prolog. When running Prolog as an inferior process under GNU-Emacs, there is support for finding predicate definitions, completing atoms, finding the locations of compilation-warnings and many more. For details, see the files pl/lisp/README and pl/lisp/swi-prolog.el. 22..33 OOnnlliinnee HHeellpp Online help provides a fast lookup and browsing facility to this manual. The online manual can show predicate definitions as well as entire sections of the manual. The online help is displayed from the file library('MANUAL'). The file library(helpidx) provides an index into this file. library('MANUAL') is created from the LaTeX sources with a modified version of dvitty, using overstrike for printing bold text and underlining for rendering italic text. XPCE is shipped with library(swi_help), presenting the information from the online help in a hypertext window. The feature write_help_with_overstrike controls whether or not hheellpp//11 writes its output using overstrike to realise bold and underlined output or not. If this feature is not set it is initialised by the help library to true if the TERM variable equals xterm and false otherwise. If this default does not satisfy you, add the following line to ~/.plrc. :- set_feature(write_help_with_overstrike, true). hheellpp Equivalent to help(hheellpp//11). hheellpp((_+_W_h_a_t)) Show specified part of the manual. _W_h_a_t is one of: <_N_a_m_e>/<_A_r_i_t_y> give help on specified predicate <_N_a_m_e> give help on named predicate with any arity or C interface function with that name <_S_e_c_t_i_o_n> display specified section. section numbers are dash-separated numbers: 2-3 refers to section 2.3 of the manual. Section numbers are obtained using aapprrooppooss//11. 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 PPLL__rreettrryy(()) aapprrooppooss((_+_P_a_t_t_e_r_n)) Display all predicates, functions and sections that have _P_a_t_t_e_r_n in their name or summary description. Lowercase letters in _P_a_t_t_e_r_n also match a corresponding uppercase letter. Example: ?- apropos(file). Display predicates, functions and sec- tions that have `file' (or `File', etc.) in their summary description. eexxppllaaiinn((_+_T_o_E_x_p_l_a_i_n)) Give an explanation on the given `object'. The argument may be any Prolog data object. If the argument is an atom, a term of the form _N_a_m_e_/_A_r_i_t_y or a term of the form _M_o_d_u_l_e_:_N_a_m_e_/_A_r_i_t_y, explain will try to explain the predicate as well as possible references to it. eexxppllaaiinn((_+_T_o_E_x_p_l_a_i_n_, _-_E_x_p_l_a_n_a_t_i_o_n)) Unify _E_x_p_l_a_n_a_t_i_o_n with an explanation for _T_o_E_x_p_l_a_i_n. Backtracking yields further explanations. 22..44 QQuueerryy SSuubbssttiittuuttiioonnss SWI-Prolog offers a query substitution mechanism similar to that of Unix csh (csh(1)), called `history'. The availability of this feature is controlled by sseett__ffeeaattuurree//22, using the history feature. By default, history is available if the feature readline is false. To enable this feature, remembering the last 50 commands, put the following into your ~/.plrc file: :- set_feature(history, 50). The history system allows the user to compose new queries from those typed before and remembered by the system. It also allows to correct queries and syntax errors. SWI-Prolog does not offer the Unix csh capabilities to include arguments. This is omitted as it is unclear how the first, second, etc. argument should be defined. The available history commands are shown in table 2.1. Figure 2.1 gives some examples. __________________________________________________________ | !!. |Repeat last query | | !nr. |Repeat query numbered <_n_r> | | !str. |Repeat last query starting with <_s_t_r> | | !?str. |Repeat last query holding <_s_t_r> | | ^old^new. |Substitute <_o_l_d> into <_n_e_w> of last query | | !nr^old^new. |Substitute in query numbered <_n_r> | | !str^old^new. |Substitute in query starting with <_s_t_r> | | !?str^old^new. |Substitute in query holding <_s_t_r> | | h. |Show history list | |_!h.____________|Show_this_list__________________________ | Table 2.1: History commands /staff/jan/.plrc consulted, 0.066667 seconds, 591 bytes Welcome to SWI-Prolog (Version \plversion) Copyright (c) 1993-1996 University of Amsterdam. All rights reserved. For help, use ?- help(Topic). or ?- apropos(Word). 1 ?- append("Hello ", "World", L). L = [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100] Yes 2 ?- !!, writef('L = %s\n', [L]). append("Hello ", "World", L), writef('L = %s\n', [L]). L = Hello World L = [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100] Yes 3 ?- sublist(integer, [3, f, 3.4], L). L = [3] Yes 4 ?- ^integer^number. sublist(number, [3, f, 3.4], L). L = [3, 3.400000] Yes 5 ?- h. 1 append("Hello ", "World", L). 2 append("Hello ", "World", L), writef('L = %s\n', [L]). 3 sublist(integer, [3, f, 3.4], L). 4 sublist(number, [3, f, 3.4], L). 5 ?- !2^World^Universe. append("Hello ", "Universe", L), writef('L = %s\n', [L]). L = Hello Universe L = [72, 101, 108, 108, 111, 32, 85, 110, 105, 118, 101, 114, 115, 101] Yes 6 ?- halt. Figure 2.1: Some examples of the history facility 22..44..11 LLiimmiittaattiioonnss ooff tthhee HHiissttoorryy SSyysstteemm When in top level SWI-Prolog reads the user's queries using rreeaadd__hhiissttoorryy//66 rather than rreeaadd//11. This predicate first reads the current input stream up to a full stop. While doing so it maps all contiguous blank space onto a single space and deletes /* ...*/ and % ...<_c_r> comments. Parts between double quotes (") or single quotes (') are left unaltered. Note that a Prolog full stop consists of a `non-symbol' character, followed by a period (.), followed by a blank character. `Symbol' characters are: #$&*+-./:<=>?@^`~. A single quote immediately preceded by a digit (0-9) is considered part of the <_d_i_g_i_t>'<_d_i_g_i_t>...(e.g. 2'101; binary number 101) sequence. After this initial parsing the result is first checked for the special ^<_o_l_d>^<_n_e_w>.construction. If this fails the string is checked for all occurrences of the !, followed by a !, ?, a digit, a letter or an underscore. These special sequences are analysed and the appropriate substitution from the history list is made. From the above it follows that it is hard or impossible to correct quotation with single or double quotes, comment delimiters and spacing. 22..55 RReeuussee ooff ttoopplleevveell bbiinnddiinnggss Bindings resulting from the successful execution of a toplevel goal are asserted in a database. These values may be reused in further toplevel queries as $Var. Only the latest binding is available. Example: 1 ?- maplist(plus(1), "hello", X). X = [105,102,109,109,112] 2 ?- format('~s~n', [$X]). ifmmp Figure 2.2: Reusing toplevel bindings Note that variables may be set by executing =//22: 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 22..66 OOvveerrvviieeww ooff tthhee DDeebbuuggggeerr SWI-Prolog has a 6-port tracer, extending the standard 4-port tracer [Clocksin & Melish, 1987] with two additional ports. The optional _u_n_i_f_y port allows the user to inspect the result after unification of the head. The _e_x_c_e_p_t_i_o_n port shows exceptions raised by tthhrrooww//11 or one of the built-in predicates. See section 3.8. The standard ports are called call, exit, redo, fail and unify. The tracer is started by the ttrraaccee//00 command, when a spy point is reached and the system is in debugging mode (see ssppyy//11 and ddeebbuugg//00) or when an exception is raised. The interactive toplevel goal ttrraaccee//00 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 pprriinntt//11 (default), wwrriittee//11 or ddiissppllaayy//11. An example using all 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 _l_e_a_s_h_e_d _p_o_r_t_s (set with the predicate lleeaasshh//11, default are call, exit, redo and fail) the user is prompted for an action. All actions are single character commands which are executed wwiitthhoouutt waiting for a return, unless the command line option -tty is active. Tracer options: + ((SSppyy)) Set a spy point (see ssppyy//11) on the current predicate. - ((NNoo ssppyy)) Remove the spy point (see nnoossppyy//11) from the current predicate. / ((FFiinndd)) 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 mmeemmbbeerr//22. This is equivalent to setting a spy point on mmeemmbbeerr//22. . ((RReeppeeaatt ffiinndd)) Repeat the last find command (see `/') A ((AAlltteerrnnaattiivveess)) Show all goals that have alternatives. C ((CCoonntteexxtt)) Toggle `Show Context'. If on the context module of the goal is displayed between square brackets (see section 4). Default is off. L ((LLiissttiinngg)) List the current predicate with lliissttiinngg//11. a ((AAbboorrtt)) Abort Prolog execution (see aabboorrtt//00). b ((BBrreeaakk)) Enter a Prolog break environment (see bbrreeaakk//00). c ((CCrreeeepp)) Continue execution, stop at next port. (Also return, space). d ((DDiissppllaayy)) Write goals using the Prolog predicate ddiissppllaayy//11. e ((EExxiitt)) Terminate Prolog (see hhaalltt//00). f ((FFaaiill)) Force failure of the current goal g ((GGooaallss)) 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 ((HHeellpp)) Show available options (also `?'). i ((IIggnnoorree)) Ignore the current goal, pretending it succeeded. l ((LLeeaapp)) Continue execution, stop at next spy point. n ((NNoo ddeebbuugg)) Continue execution in `no debug' mode. p ((PPrriinntt)) Write goals using the Prolog predicate pprriinntt//11 (default). r ((RReettrryy)) 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 ((SSkkiipp)) Continue execution, stop at the next port of tthhiiss goal (thus skipping all calls to children of this goal). u ((UUpp)) Continue execution, stop at the next port of tthhee ppaarreenntt 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 ((WWrriittee)) Write goals using the Prolog predicate wwrriittee//11. The ideal 4 port model as described in many Prolog books [Clocksin & Melish, 1987] is not visible in many Prolog implementations because code optimisation removes part of the choice- and exit points. Backtrack points are not shown if either the goal succeeded deterministically or its alternatives were removed using the cut. When running in debug mode (ddeebbuugg//00) choice points are only destroyed when removed by the cut. In debug mode, tail recursion optimisation is switched off. 22..77 CCoommppiillaattiioonn 22..77..11 DDuurriinngg pprrooggrraamm ddeevveellooppmmeenntt During program development, programs are normally loaded using ccoonnssuulltt//11, or the list abreviation. It is common practice to organise a project as a collection of source-files and a _l_o_a_d_-_f_i_l_e, a Prolog file containing only uussee__mmoodduullee//[[11,,22]] or eennssuurree__llooaaddeedd//11 directives, possibly with a definition of the _e_n_t_r_y_-_p_o_i_n_t of the program, the predicate that is normally used to start the program. This file is often called load.pl. If the entry-point is called _g_o, a typical session starts as: % pl 1 ?- [load]. Yes 2 ?- go. When using Windows, the user may open load.pl from the Windows explorer, which will cause plwin.exe to be started in the directory holding load.pl. Prolog loads load.pl before entering the toplevel. 22..77..22 FFoorr rruunnnniinngg tthhee rreessuulltt There are various options if you want to make your program ready for real usage. The best choice depends on whether the program is to be used only on machines holding the SWI-Prolog development system, the size of the program and the operating system (Unix vs. Windows). 22..77..22..11 CCrreeaattiinngg aa sshheellll--ssccrriipptt Especially on Unix systems and not-too-large applications, writing a shell-script that simply loads your application and calls the entry-point is often a good choice. A skeleton for the script is given below, followed by the Prolog code to obtain the program arguments. #!/bin/sh base= PL=pl exec $PL -f none -g "load_files(['$base/load'],[silent(true)])" -t go - - $* go :- unix(argv(Arguments)), append(_SytemArgs, [--|Args], Arguments), !, go(Args). go(Args) :- ... On Windows systems, similar behaviour can be achieved by creating a shortcut to Prolog, passing the proper options or writing a .bat file. 22..77..22..22 CCrreeaattiinngg aa ssaavveedd--ssttaattee For larger programs, as well as for programs that are required run on systems that do not have the SWI-Prolog development system installed, creating a saved state is the best solution. A saved state is created using qqssaavvee__pprrooggrraamm//[[11,,22]] or using the linker plld(1). A saved state is a file containing machine-independent intermediate code in a format dedicated for fast loading. Optionally, the emulator may be integrated in the saved state, creating a single-file, but machine-dependent, exectable. This process is descriped in chapter 6. 22..77..22..33 CCoommppiilliillaattiioonn uussiinngg tthhee --cc ccoommmmaannddlliinnee ooppttiioonn This mechanism is mostly for backward compatibility. It creates files in the same format as saved-states created using qqssaavvee__pprrooggrraamm//[[11,,22]], but the resulting file is a translation of the source-files read, rather than a translation of the state of the machine. Unlike saved states, programs created using -c file do not include the Prolog part of the development system. The result is very dependent on the local SWI-Prolog installation. The command below is used to compile one or more source-files. pl [options] [-o output] -c file ... The individual source files may include other files using the standard list notation, ccoonnssuulltt//11, eennssuurree__llooaaddeedd//11and uussee__mmoodduullee//[[11,,22]]. When the -o file option is omitted a file named a.out is created that holds the intermediate code file. Intermediate code files start with the Unix magic code #! and are executable. This implies they can be started as a command: % pl -o my_program -c ... ... % my_program [options] Alternatively, my_program can be started with % pl -x my_program [options] The following restrictions apply to source files that are to be compiled with `-c': o tteerrmm__eexxppaannssiioonn//22 should not use aasssseerrtt//11 and or rreettrraacctt//11 other than for local computational purposes. o Files can only be included by the standard include directives: [...], ccoonnssuulltt//11, eennssuurree__llooaaddeedd//11 and uussee__mmoodduullee//[[11,,22]]. User defined loading predicate invocations will not be compiled. Directives are executed both when compiling the program and when loading the intermediate code file. 22..88 EEnnvviirroonnmmeenntt CCoonnttrrooll The current system defines 3 different mechanisms to query and/or set properties of the environment: pplleeaassee//33, ffllaagg//33 and ffeeaattuurree//22 as well as a number of special purpose predicates of which uunnkknnoowwnn//22, ffiilleeeerrrroorrss//22 are examples. The ISO standard defines prolog_flag. It is likely that all these global features will be merged into a single in the future. pplleeaassee((_+_K_e_y_, _-_O_l_d_, _+_N_e_w)) The predicate pplleeaassee//33 is a solution to avoid large numbers of environment control predicates. Later versions will support other environment control as now provided via the predicates ssttyyllee__cchheecckk//11, lleeaasshh//11, uunnkknnoowwnn//22, the tracer predicates, etc. These predicates are then moved into a library for backwards compatibility. The currently available options are: ooppttiimmiissee _o_n_/_o_f_f (default: _o_f_f_) Switch optimise mode for the compiler on or off (see also the command line option -O). Currently optimise compilation only implies compilation of arithmetic, making it fast, but invisible to the tracer. Later versions might imply various other optimisations such as incorporating a number of basic predicates in the virtual machine (vvaarr//11, ffaaiill//00, =/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 ddyynnaammiicc//11). aauuttoollooaadd _o_n_/_o_f_f (default: _o_n_) If on autoloading of library functions is enabled. If off autoloading is disabled. See section 2.9. vveerrbboossee__aauuttoollooaadd _o_n_/_o_f_f (default: _o_f_f_) If on the normal consult message will be printed if a library is autoloaded. By default this message is suppressed. Intended to be used for debugging purposes (e.g. where does this predicate come from?). ffeeaattuurree((_?_K_e_y_, _-_V_a_l_u_e)) The predicate ffeeaattuurree//22 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 aanndd the _V_a_l_u_e is the atom true. Currently defined keys: aarrcchh ((_a_t_o_m)) Identifier for the hardware and operating system SWI-Prolog is running on. Used to determine the startup file as well as to select foreign files for the right architecture. See also llooaadd__ffoorreeiiggnn//55. vveerrssiioonn ((_i_n_t_e_g_e_r)) The version identifier is an integer with value: 10000_*Major+ 100_*Minor+_P_a_t_c_h Note that in releases upto 2.7.10 this feature yielded an atom holding the three numbers separated by dots. The current representation is much easier for implementing version-conditional statements. hhoommee ((_a_t_o_m)) SWI-Prolog's notion of the home-directory. SWI-Prolog uses it's home directory to find its startup file as <_h_o_m_e>/startup/startup.<_a_r_c_h> and to find its library as <_h_o_m_e>/library. ppiippee ((_b_o_o_l)) If true, tell(pipe(command)), etc. are supported. llooaadd__ffoorreeiiggnn ((_b_o_o_l)) If true, llooaadd__ffoorreeiiggnn//[[22,,55]]are implemented. ooppeenn__sshhaarreedd__oobbjjeecctt ((_b_o_o_l)) If true, ooppeenn__sshhaarreedd__oobbjjeecctt//22 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. ddyynnaammiicc__ssttaacckkss ((_b_o_o_l)) If true, the system uses some form of `sparse-memory manage- ment' to realise the stacks. If false, malloc()/realloc() are used for the stacks. In earlier days this had consequenses for foreign code. As of version 2.5, this is no longer the case. Systems using `sparse-memory management' are a bit faster as there is no stack-shifter, and checking the stack-boundary is often realised by the hardware using a `guard-page'. Also, memory is actually returned to the system after a garbage collection or call to ttrriimm__ssttaacckkss//00 (called by pprroolloogg//00 after finishing a user-query). cc__lliibbss ((_a_t_o_m)) Libraries passed to the C-linker when SWI-Prolog was linked. May be used to determine the libraries needed to create statically linked extensions for SWI-Prolog. See section 5.7. cc__ssttaattiicclliibbss ((_a_t_o_m)) On some machines, the SWI-Prolog executable is dynamically linked, but requires some libraries to be statically linked. Obsolete. cc__cccc ((_a_t_o_m)) Name of the C-compiler used to compile SWI-Prolog. Normally either gcc or cc. See section 5.7. cc__llddffllaaggss ((_a_t_o_m)) Special linker flags passed to link SWI-Prolog. See section 5.7. ssaavvee ((_b_o_o_l)) If true, ssaavvee//[[11,,22]] is implemented. Saving using ssaavvee//00 is obsolete. See qqssaavvee__pprrooggrraamm//[[11,,22]]. ssaavvee__pprrooggrraamm ((_b_o_o_l)) If true, ssaavvee__pprrooggrraamm//[[11,,22]] is implemented. Saving using ssaavvee__pprrooggrraamm//00is obsolete. See qqssaavvee__pprrooggrraamm//[[11,,22]]. rreeaaddlliinnee ((_b_o_o_l)) If true, SWI-Prolog is linked with the readline library. This is done by default if you have this library installed on your system. It is also true for the Win32 plwin.exe version of SWI-Prolog, which realises a subset of the readline functionality. ssaavveedd__pprrooggrraamm ((_b_o_o_l)) If true, Prolog is started from a state saved with qqssaavvee__pprrooggrraamm//[[11,,22]]. rruunnttiimmee ((_b_o_o_l)) If true, SWI-Prolog is compiled with -DO_RUNTIME, disabling various useful development features (currently the tracer and profiler). mmaaxx__iinntteeggeerr ((_i_n_t_e_g_e_r)) Maximum integer value. Most arithmetic operations will automatically convert to floats if integer values above this are returned. mmiinn__iinntteeggeerr ((_i_n_t_e_g_e_r)) Minimum integer value. mmaaxx__ttaaggggeedd__iinntteeggeerr ((_i_n_t_e_g_e_r)) Maximum integer value represented as a `tagged' value. Tagged integers require 4-bytes storage and are used for indexing. Larger integers are represented as `indirect data' and require 16-bytes on the stacks (though a copy requires only 4 additional bytes). mmiinn__ttaaggggeedd__iinntteeggeerr ((_i_n_t_e_g_e_r)) Start of the tagged-integer value range. ffllooaatt__ffoorrmmaatt ((_a_t_o_m)) C printf() format specification used by wwrriittee//11 and friends to determine how floating point numbers are printed. The default is %g. May be changed. The specified value is passed to printf() without further checking. For example, if you want more digits printed, %.12g will print all floats using 12 digits instead of the default 6. See also ffoorrmmaatt//[[11,,22]], wwrriittee//11, pprriinntt//11 and ppoorrttrraayy//11. ccoommppiilleedd__aatt ((_a_t_o_m)) Describes when the system has been compiled. Only available if the C-compiler used to compile SWI-Prolog provides the __DATE__and __TIME__macros. cchhaarraacctteerr__eessccaappeess ((_b_o_o_l)) If true (default), rreeaadd//11 interprets \ escape sequences in quoted atoms and strings. May be changed. aallllooww__vvaarriiaabbllee__nnaammee__aass__ffuunnccttoorr ((_b_o_o_l)) If true (default is false), Functor(arg) is read as if it was written 'Functor'(arg). Some applications use the Prolog rreeaadd//11 predicate for reading an application defined script language. In these cases, it is often difficult to explain none-Prolog users of the application that constants and functions can only start with a lowercase letter. Variables can be turned into atoms starting with an uppercase atom by calling rreeaadd__tteerrmm//22using the option variable_names and binding the variables to their name. Using this feature, F(x) can be turned into valid syntax for such script languages. Suggested by Robert van Engelen. SWI-Prolog specific. hhiissttoorryy ((_i_n_t_e_g_e_r)) If >0, support Unix csh(1) like history as described in section 2.4. Otherwise, only support reusing commands through the commandline editor. The default is to set this feature to 0 if a commandline editor is provided (see feature readline) and 15 otherwise. ggcc ((_b_o_o_l)) If true (default), the garbage collector is active. If false, neither garbage-collection, nor stack-shifts will take place, even not on explicit request. May be changed. ttrraaccee__ggcc ((_b_o_o_l)) If true (false is the default), garbage collections and stack-shifts will be reported on the terminal. May be changed. mmaaxx__aarriittyy ((_u_n_b_o_u_n_d_e_d)) ISO feature describing there is no maximum arity to compound terms. iinntteeggeerr__rroouunnddiinngg__ffuunnccttiioonn ((_d_o_w_n_,_t_o_w_a_r_d___z_e_r_o)) ISO feature describing rounding by // and rem arithmetic functions. Value depends on the C-compiler used. bboouunnddeedd ((_t_r_u_e)) ISO feature describing integer representation is bound by min_integer and min_integer. ttttyy__ccoonnttrrooll ((_b_o_o_l)) Determines whether the terminal is switched to raw mode for ggeett__ssiinnggllee__cchhaarr//11, which also reads the user-actions for the trace. May be set. See also the +/-tty command-line option. ddeebbuugg__oonn__eerrrroorr ((_b_o_o_l)) If true, start the tracer after an error is detected. Otherwise just continue execution. The goal that raised the error will normally fail. See also ffiilleeeerrrroorrss//22 and the feature report_error. May be changed. Default is true, except for the runtime version. rreeppoorrtt__eerrrroorr ((_b_o_o_l)) If true, print error messages, otherwise suppress them. May be changed. See also the debug_on_error feature. Default is true, except for the runtime version. uunniixx ((_b_o_o_l)) If true, the operating system is some version of Unix. Defined if the C-compiler used to compile this version of SWI-Prolog either defines __unix__ or unix. wwiinnddoowwss ((_b_o_o_l)) If true, the operating system is an implementation of Microsoft Windows (3.1, 95, NT, etc.). sseett__ffeeaattuurree((_+_K_e_y_, _+_V_a_l_u_e)) Define a new feature or change its value. _K_e_y is an atom, _V_a_l_u_e is an atom or number. 22..99 AAuuttoommaattiicc llooaaddiinngg ooff lliibbrraarriieess If ---at runtime--- an undefined predicate is trapped the system will first try to import the predicate from the module's default module. If this fails the _a_u_t_o _l_o_a_d_e_r is activated. On first activation an index to all library files in all library directories is loaded in core (see lliibbrraarryy__ddiirreeccttoorryy//11). 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 pplleeaassee//33 option verbose_autoload is provided to get verbose loading. The please option autoload can be used to enable/disable the entire auto load system. Autoloading only handles (library) source files that use the module mechanism described in chapter 4. The files are loaded with uussee__mmoodduullee//22 and only the trapped undefined predicate will be imported to the module where the undefined predicate was called. Each library directory must hold a file INDEX.pl that contains an index to all library files in the directory. This file consists of lines of the following format: index(Name, Arity, Module, File). The predicate mmaakkee//00 scans the autoload libraries and updates the index if it exists, is writable and out-of-date. It is advised to create an empty file called INDEX.pl in a library directory meant for auto loading before doing anything else. This index file can then be updated by running the prolog mmaakkee__lliibbrraarryy__iinnddeexx//11(`%' 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 lliibbrraarryy__ddiirreeccttoorryy//11 predicate and within the directory alphabetically. mmaakkee__lliibbrraarryy__iinnddeexx((_+_D_i_r_e_c_t_o_r_y)) Create an index for this directory. The index is written to the file 'INDEX.pl' in the specified directory. Fails with a warning if the directory does not exist or is write protected. 22..99..11 NNootteess oonn AAuuttoommaattiicc LLooaaddiinngg 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 uunnkknnoowwnn//22) is set to trace (default). A more appropriate interaction with this flag will be considered. 22..1100 GGaarrbbaaggee CCoolllleeccttiioonn SWI-Prolog version 1.4 was the first release to support garbage collection. Together with tail-recursion optimisation this guaranties forward chaining programs do not waste indefinite amounts of memory. Previous releases of this manual stressed on using failure-driven loops in those cases that no information needed to be passed to the next iteration via arguments. This to avoid large amounts of garbage. This is no longer strictly necessary, but it should be noticed that garbage collection is a time consuming activity. Failure driven loops tend to be faster for this reason. 22..1111 SSyynnttaaxx NNootteess SWI-Prolog uses standard `Edinburgh' syntax. A description of this syntax can be found in the Prolog books referenced in the introduction. Below are some non-standard or non-common constructs that are accepted by SWI-Prolog: o 0'<_c_h_a_r> This construct is not accepted by all Prolog systems that claim to have Edinburgh compatible syntax. It describes the ASCII value of <_c_h_a_r>. To test whether C is a lower case character one can use between(0'a, 0'z, C). o /* .../* ...*/ ...*/ The /* ...*/ comment statement can be nested. This is useful if some code with /* ...*/ comment statements in it should be commented out. 22..1111..11 IISSOO SSyynnttaaxx SSuuppppoorrtt SWI-Prolog offers ISO compatible extensions to the Edinburgh syntax. 22..1111..11..11 CChhaarraacctteerr EEssccaappee SSyynnttaaxx Within quoted atoms (using single quotes: '<_a_t_o_m>'special characters are represented using escape-sequences. An escape sequence is lead in by the backslash (\) character. The list of escape sequences is compatible with the ISO standard, but contains one extension and the interpretation of numerically specified characters is slightly more flexible to improve compatibility. \a Alert character. Normally the ASCII character 7 (beep). \b Backspace character. \c No output. All input characters upto but not including the first non-layout character are skipped. This allows for the specification of pretty-looking long lines. For compatibility with Quintus Prolog. Nor supported by ISO. Example: format('This is a long line that would look better if it was \c split across multiple physical lines in the input') \ No output. Skips input till the next non-layout character or to the end of the next line. Same intention as \c but ISO compatible. \f Form-feed character. \n Next-line character. \r Carriage-return only (i.e. go back to the start of the line). \t Horizontal tab-character. \v Vertical tab-character (ASCII 11). \x23 Hexadecimal specification of a character. 23 is just an example. The `x' may be followed by a maximum of 2 hexadecimal digits. The closing \ is optional. The code \xa\3 emits the character 10 (hexadecimal `a') followed by `3'. The code \x201 emits 32 (hexadecimal `20') followed by `1'. According to ISO, the closing \ is obligatory and the number of digits is unlimited. The SWI-Prolog definition allows for ISO compatible specification, but is compatible with other implementations. \40 Octal character specification. The rules and remarks for hexadecimal specifications apply to octal specifications too, but the maximum allowed number of octal digits is 3. \<_c_h_a_r_a_c_t_e_r> Any character immediately preceded by a \ is copied verbatim. Thus, '\\' is an atom consisting of a single \ and '\'' and '''' both describe the atom with a single '. Character escaping is only available if the feature(character_escapes, true) is active (default). See ffeeaattuurree//22. Character escapes conflict with wwrriitteeff//22 in two ways: \40 is interpreted as decimal 40 by wwrriitteeff//22, but character escapes handling by read has already interpreted as 32 (40 octal). Also, \l is translated to a single `l'. Double the \ (e.g. \\, use the above escape sequences or use ffoorrmmaatt//22. 22..1111..11..22 SSyynnttaaxx ffoorr NNoonn--DDeecciimmaall NNuummbbeerrss SWI-Prolog implements both Edinburgh and ISO representations for non-decimal numbers. According to Edinburgh syntax, such numbers are written as <_r_a_d_i_x>'<_n_u_m_b_e_r>, where <_r_a_d_i_x> is a number between 2 and 36. ISO defines binary, octal and hexadecimal numbers using 0[bxo]<_n_u_m_b_e_r>. For example: A is 0b100 \/ 0xf00 is a valid expression. Such numbers are always unsigned. 22..1122 SSyysstteemm LLiimmiittss 22..1122..11 LLiimmiittss oonn MMeemmoorryy AArreeaass SWI-Prolog has a number of memory areas which are only enlarged to a certain limit. The default sizes for these areas should suffice for most applications, but big applications may require larger ones. They are modified by command line options. The table below shows these areas. The first column gives the option name to modify the size of the area. The option character is immediately followed by a number and optionally by a k or m. With k or no unit indicator, the value is interpreted in Kbytes (1024 bytes), with m, the value is interpreted in Mbytes (10241* 024 bytes). The local-, global- and trail-stack are limited to 64 Mbytes on 32 bit processors, or more in general to 2 to the power bits-per-long - 6 bytes. ___________________________________________________________ |_Option_|Default_|Area_name______|Description____________|_||-L||2Mllooccaa||llTssttaacckkhe|l||||ocal|stack is used | | to store the execu- | | || | | tion environments of | | || | | procedure invocations. | | || | | The space for an en- | | || | | vironment is reclaimed | | || | | when it fails, exits | | || | | without leaving choice | | || | | points, the alterna- | | || | | tives are cut of with | | || | | | | || | | the !/0 predicate or | | || | | no choice points have | | || | | been created since the | | || | | invocation and the last | | || | | subclause is started | | || | | (tail recursion optimi- | | || || || | ||sation). || | || | -G | 4M |gglloobbaall ssttaacckk ||Theusglobaled stacktois store| terms | | | ||created during Prolog's | | | | ||execution. Terms on | | | | || | | | | ||this stack will be re- | | | | ||claimed by backtracking | | | | ||to a point before the | | | | ||term was created or | | | | ||by garbage collection | | | | ||(provided the term is | || || || ||no||longer referenced). || | -T | 4M |ttrraaiill ssttaacckk ||Theusetraild stackto isstore| as- | | | ||signments during execu- | | | | || | | | | ||tion. Entries on this | | | | ||stack remain alive un- | | | | ||til backtracking before | | | | ||the point of creation | | | | ||or the garbage collec- | | | | ||tor determines they are | || || || ||nor||needed any longer. || | -A | 1M |aarrgguummeenntt ssttaacckk ||Theusargumentestackd isto| store one | | | ||of the intermediate | | | | ||code interpreter's reg- | | | | ||isters. The amount | | | | ||of space needed on this | | | | ||stack is determined en- | | | | || | | | | ||tirely by the depth in | | | | ||which terms are nested | | | | ||in the clauses that | | | | ||constitute the program. | | | | ||Overflow is most likely | | | | ||when using long strings | |________|_______|_______________||in_a_clause.____________|_ Table 2.2: Memory areas 22..1122..11..11 TThhee hheeaapp With the heap, we refer to the memory area used by mmaalllloocc(()) and friends. SWI-Prolog uses the area to store atoms, functors, predicates and their clauses, records and other dynamic data. As of SWI-Prolog 2.8.5, no limits are imposed on the addresses returned by mmaalllloocc(()) and friends. On some machines, the runtime stacks described above are allocated using `sparse allocation'. Virtual space upto the limit is claimed at startup and committed and released while the area grows and shrinks. On Win32 platform this is realised using VViirrttuuaallAAlllloocc(()) and friends. On Unix systems this is realised using mmmmaapp(()), either mapping /dev/zero or a temporary file created in /tmp. As Unix provides no way to reserve part of the address space, this process may lead to conflicts. By default, SWI-Prolog computes the required virtual address space for the runtime stacks. If available, it uses ggeettrrlliimmiitt(()) to determine the top of the virtual space reserved for mmaalllloocc(()) usage and locates the stacks in the top of this area. It assumes no other mmmmaapp(()) activity such as mapping shared libraries or mmmmaapp(()) by foreign modules will use the area reserved for the heap and mmaalllloocc(()), mmaalllloocc(()) will grow the heap from low to high addresses and will notice the existence of the Prolog stacks. These assumptions appear to hold. The user may using the -H to specify the maximum heap-size. In this case, the Prolog stacks will be allocated at the indicated size from the current top of the heap. On these system, ssttaattiissttiiccss//[[00,,22]] reports heaplimit and heap. The heaplimit value is the distance between the _b_r_e_a_k and the first Prolog stack. The heap value is the distance between what Prolog assumes to be the base of the heap and the current location of the break. 22..1122..22 OOtthheerr LLiimmiittss CCllaauusseess Currently the following limitations apply to clauses. The arity may not be more than 1024 and the number of variables should be less than 65536. AAttoommss aanndd SSttrriinnggss SWI-Prolog has no limits on the sizes of atoms and strings. rreeaadd//11 and its derivatives however normally limit the number of newlines in an atom or string to 5 to improve error detection and recovery. This can be switched off with ssttyyllee__cchheecckk//11. AAddddrreessss ssppaaccee SWI-Prolog data is packed in a 32-bit word, which contains both type and value information. The size of the various memory areas is limited to 128 Mb for each of the areas. With some redesign, the program area could be split into data that should be within this range and the rest of the data, virtually unlimiting the program size. IInntteeggeerrss Integers are 32-bit to the user, but integers upto the value of the max_tagged_integer feature are represented more efficiently. FFllooaattss Floating point numbers are represented as native double precision floats, 64 bit IEEE on most machines. 22..1122..33 RReesseerrvveedd NNaammeess The boot compiler (see -b option) does not support the module system (yet). As large parts of the system are written in Prolog itself we need some way to avoid name clashes with the user's predicates, database keys, etc. Like Edinburgh C-Prolog [Pereira, 1986] all predicates, database keys, etc. that should be hidden from the user start with a dollar ($) sign (see ssttyyllee__cchheecckk//11). 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. CChhaapptteerr 33.. BBUUIILLTT--IINN PPRREEDDIICCAATTEESS 33..11 NNoottaattiioonn ooff PPrreeddiiccaattee DDeessccrriippttiioonnss 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 `oopp//33' refer to the predicate `op' with arity `3'. 33..22 CCoonnssuullttiinngg PPrroolloogg SSoouurrccee ffiilleess 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 lliibbrraarryy//11. 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 lliibbrraarryy__ddiirreeccttoorryy//11. The user may specify other `aliases' than library using the predicate ffiillee__sseeaarrcchh__ppaatthh//22. This is strongly encouraged for managing complex applications. See also aabbssoolluuttee__ffiillee__nnaammee//[[22,,33]]. SWI-Prolog recognises grammar rules as defined in [Clocksin & Melish, 1987]. The user may define additional com- pilation of the source file by defining the dynamic predicate tteerrmm__eexxppaannssiioonn//22. Transformations by this predicate overrule the systems grammar rule transformations. It is not allowed to use aasssseerrtt//11, rreettrraacctt//11 or any other database predicate in tteerrmm__eexxppaannssiioonn//22 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 rreeccoonnssuulltt//11 predicate. Reconsulting is implied automatically by the fact that a file is consulted which is already loaded. llooaadd__ffiilleess((_+_F_i_l_e_s_, _+_O_p_t_i_o_n_s)) The predicate llooaadd__ffiilleess//22 is the parent of all the other loading predicates. It currently supports a subset of the options of Quintus llooaadd__ffiilleess//22. _F_i_l_e_s is either specifies a single, or a list of source-files. The specification for a source-file is handled aabbssoolluuttee__ffiillee__nnaammee//22. See this predicate for the supported expansions. _O_p_t_i_o_n_s is a list of options using the format _O_p_t_i_o_n_N_a_m_e(_O_p_t_i_o_n_V_a_l_u_e) The following options are currently supported: iiff((_C_o_n_d_i_t_i_o_n)) Load the file only if the specified condition is satisfied. The value true loads the file unconditionally, changed loads the file if it was not loaded before, or has been modified since it was loaded the last time, not_loaded loads the file if it was not loaded before. mmuusstt__bbee__mmoodduullee((_B_o_o_l)) If true, raise an error if the file is not a module file. Used by uussee__mmoodduullee//[[11,,22]]. iimmppoorrttss((_L_i_s_t_O_r_A_l_l)) If all and the file is a module file, import all public predicates. Otherwise import only the named predicates. Each predicate is refered to as <_n_a_m_e>/<_a_r_i_t_y>. This option has no effect if the file is not a module file. ssiilleenntt((_B_o_o_l)) If true, load the file without printing a message. The specified value is the default for all files loaded as a result of loading the specified files. ccoonnssuulltt((_+_F_i_l_e)) Read _F_i_l_e as a Prolog source file. _F_i_l_e may be a list of files, in which case all members are consulted in turn. _F_i_l_e may start with the csh(1) special sequences ~, ~<_u_s_e_r>and $<_v_a_r>. _F_i_l_e may also be library(Name), in which case the libraries are searched for a file with the specified name. See also lliibbrraarryy__ddiirreeccttoorryy//11 and ffiillee__sseeaarrcchh__ppaatthh//22. ccoonnssuulltt//11 may be abbreviated by just typing a number of file names in a list. Examples: ?- consult(load). % consult load or load.pl ?- [library(quintus)]. % load Quintus compatibility library Equivalent to load_files(Files, []). eennssuurree__llooaaddeedd((_+_F_i_l_e)) If the file is not already loaded, this is equivalent to ccoonnssuulltt//11. Otherwise, if the file defines a module, import all public predicates. Finally, if the file is already loaded, is not a module file and the context module is not the global user module, eennssuurree__llooaaddeedd//11 will call ccoonnssuulltt//11. With the semantics, we hope to get as closely possible to the clear semantics without the presence of a module system. Applications using modules should consider using uussee__mmoodduullee//[[11,,22]]. Equivalent to load_files(Files, [if(changed)]). rreeqquuiirree((_+_L_i_s_t_O_f_N_a_m_e_A_n_d_A_r_i_t_y)) Declare that this file/module requires the specified predicates to be defined ``with their commonly accepted definition''. This predicate originates from the Prolog portability layer for XPCE. It is intended to provide a portable mechanism for specifying that this module requires the specified predicates. The implementation normally first verifies whether the predicate is already defined. If not, it will search the libraries and load the required library. SWI-Prolog, having autoloading, does nnoott load the library. Instead it creates a procedure header for the predicate if this does not exist. This will flag the predicate as `undefined'. See also cchheecckk//00 and aauuttoollooaadd//00. mmaakkee Consult all source files that have been changed since they were consulted. It checks _a_l_l loaded source files: files loaded into a compiled state using pl -c ... and files loaded using consult or one of its derivatives. mmaakkee//00 is normally invoked by the eeddiitt//[[00,,11]] and eedd//[[00,,11]] predicates. mmaakkee//00 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. lliibbrraarryy__ddiirreeccttoorryy((_?_A_t_o_m)) Dynamic predicate used to specify library directories. Default ./lib, ~/lib/prolog and the system's library (in this order) are defined. The user may add library directories using aasssseerrtt//11, aasssseerrttaa//11 or remove system defaults using rreettrraacctt//11. ffiillee__sseeaarrcchh__ppaatthh((_+_A_l_i_a_s_, _?_P_a_t_h)) Dynamic predicate used to specify `path-aliases'. This feature is best described using an example. Given the definition file_search_path(demo, '~/demo'). the file specification demo(myfile) will be expanded to ~/demo/myfile. The second argument of ffiillee__sseeaarrcchh__ppaatthh//22may be another alias. Below is the initial definition of the file search path. This path implies swi(<_P_a_t_h>) refers to a file in the SWI-Prolog home directory. The alias foreign(<_P_a_t_h>) is intended for storing shared libraries (.so or .DLL files). See also llooaadd__ffoorreeiiggnn__lliibbrraarryy//[[11,,22]]. user:file_search_path(library, X) :- library_directory(X). user:file_search_path(swi, Home) :- feature(home, Home). user:file_search_path(foreign, swi(ArchLib)) :- feature(arch, Arch), concat('lib/', Arch, ArchLib). user:file_search_path(foreign, swi(lib)). The ffiillee__sseeaarrcchh__ppaatthh//22expansion is used by all loading predicates as well as by aabbssoolluuttee__ffiillee__nnaammee//22. eexxppaanndd__ffiillee__sseeaarrcchh__ppaatthh((_+_S_p_e_c_, _-_P_a_t_h)) Unifies _P_a_t_h will all possible expansions of the file name specification _S_p_e_c. See also aabbssoolluuttee__ffiillee__nnaammee//33. ssoouurrccee__ffiillee((_?_F_i_l_e)) Succeeds if _F_i_l_e was loaded using ccoonnssuulltt//11 or eennssuurree__llooaaddeedd//11. _F_i_l_e refers to the full path name of the file (see eexxppaanndd__ffiillee__nnaammee//22). The predicate ssoouurrccee__ffiillee//11 backtracks over all loaded source files. ssoouurrccee__ffiillee((_?_P_r_e_d_, _?_F_i_l_e)) Is true if the predicate specified by _P_r_e_d was loaded from file _F_i_l_e, where _F_i_l_e is an absolute path name (see eexxppaanndd__ffiillee__nnaammee//22). Can be used with any instantiation pattern, but the database only maintains the source file for each predicate. Predicates declared multifile (see mmuullttiiffiillee//11) cannot be found this way. pprroolloogg__llooaadd__ccoonntteexxtt((_?_K_e_y_, _?_V_a_l_u_e)) Determine loading context. The following keys are defined: ________________________________________________________________ |__KKeeyy______________________||DDeessccrriippttiioonn________________________________________________________________________|| || module |Module into which file is loaded | | file |File loaded | | stream |Stream identifier (see ccuurrrreenntt__iinnppuutt//11) | | directory |Directory in which _F_i_l_e lives. | | term_position |Position of last term read. Term of the form| |_______________|'$stream_position'(0,<_L_i_n_e>,0,0,0)_____________| Quintus compatibility predicate. See also ssoouurrccee__llooccaattiioonn//22. ssoouurrccee__llooccaattiioonn((_-_F_i_l_e_, _-_L_i_n_e)) If the last term has been read from a physical file (i.e. not from the file user or a string), unify _F_i_l_e with an absolute path to the file and _L_i_n_e with the line-number in the file. New code should use pprroolloogg__llooaadd__ccoonntteexxtt//22. tteerrmm__eexxppaannssiioonn((_+_T_e_r_m_1_, _-_T_e_r_m_2)) Dynamic predicate, normally not defined. When defined by the user all terms read during consulting that are given to this predicate. If the predicate succeeds Prolog will assert _T_e_r_m_2 in the database rather then the read term (_T_e_r_m_1). _T_e_r_m_2 may be a term of a the form `?- _G_o_a_l' or `:- _G_o_a_l'. _G_o_a_l is then treated as a directive. If _T_e_r_m_2 is a list all terms of the list are stored in the database or called (for directives). If _T_e_r_m_2 is of the form below, the system will assert _C_l_a_u_s_e and record the indicated source-location with it. '$source_location'(<_F_i_l_e>, <_L_i_n_e>):<_C_l_a_u_s_e> When compiling a module (see chapter 4 and the directive mmoodduullee//22), eexxppaanndd__tteerrmm//22 will first try tteerrmm__eexxppaannssiioonn//22in the module being compiled to allow for term-expansion rules that are local to a module. If there is no local definition, or the local definition fails to translate the term, eexxppaanndd__tteerrmm//22 will try user:tteerrmm__eexxppaannssiioonn//22. For compatibility with SICStus and Quintus Prolog, this feature should not be used. See also eexxppaanndd__tteerrmm//22. eexxppaanndd__tteerrmm((_+_T_e_r_m_1_, _-_T_e_r_m_2)) This predicate is normally called by the compiler to perform preprocessing. First it calls tteerrmm__eexxppaannssiioonn//22. If this predicate fails it performs a grammar-rule translation. If this fails it returns the first argument. aatt__iinniittiiaalliizzaattiioonn((_+_G_o_a_l)) Register _G_o_a_l to be ran when the system initialises. Initialisation takes place after reloading a .qlf (formerly .wic) file as well as after reloading a saved-state. The hooks are run in the order they were registered. A warning message is issued if _G_o_a_l fails, but execution continues. See also aatt__hhaalltt//11 aatt__hhaalltt((_+_G_o_a_l)) Register _G_o_a_l to be ran when the system halts. The hooks are run in the order they were registered. Success or failure executing a hook is ignored. These hooks may not call hhaalltt//[[00,,11]]. iinniittiiaalliizzaattiioonn((_+_G_o_a_l)) Call _G_o_a_l and register it using aatt__iinniittiiaalliizzaattiioonn//11. Directives that do other things that creating clauses, records, flags or setting predicate attributes should normally be written using this tag to ensure the initialisation is executed when a saved system starts. See also qqssaavvee__pprrooggrraamm//[[11,,22]]. ccoommppiilliinngg 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 eexxppaanndd__tteerrmm//22 under this condition. pprreepprroocceessssoorr((_-_O_l_d_, _+_N_e_w)) Read the input file via a Unix process that acts as preprocessor. A preprocessor is specified as an atom. The first occurrence of the string `%f' is replaced by the name of the file to be loaded. The resulting atom is called as a Unix command and the standard output of this command is loaded. To use the Unix C preprocessor one should define: ?- preprocessor(Old, '/lib/cpp -C -P %f'), consult(...). Old = none 33..22..11 QQuuiicckk LLooaadd FFiilleess The features described in this section should be regarded aallpphhaa. 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 qqccoommppiillee//11. They may be loaded explicitly using qqllooaadd//11 or implicitly using ccoonnssuulltt//11 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 qqllooaadd//11 to load the file. When no extension is specified, it will load the .qlf file when present and the fileextpl file otherwise. qqccoommppiillee((_+_F_i_l_e)) Takes a single file specification like ccoonnssuulltt//11 (i.e. accepts constructs like library(LibFile) and creates a Quick Load File from _F_i_l_e. The file-extension of this file is .qlf. The base name of the Quick Load File is the same as the input file. If the file contains `:- consult(+File)' or `:- [+File]' statements, the referred files are compiled into the same .qlf file. Other directives will be stored in the .qlf file and executed in the same fashion as when loading the .pl file. For tteerrmm__eexxppaannssiioonn//22, the same rules as described in section 2.7 apply. Source references (ssoouurrccee__ffiillee//22) in the Quick Load File refer to the Prolog source file from which the compiled code originates. qqllooaadd((_+_F_i_l_e)) Loads the `Quick Load File'. It has the same semantics as ccoonnssuulltt//11 for a normal sourcefile. Equivalent to consult(File) iff _F_i_l_e refers to a `Quick Load File'. 33..33 LLiissttiinngg PPrreeddiiccaatteess aanndd EEddiittoorr IInntteerrffaaccee SWI-Prolog offers an interface to the Unix vi editor and the GNU Emacs invocations emacs and emacsclient. Which editor is used is determined by the Unix environment variable EDITOR, which should hold the full pathname of the editor. If this variable is not defined, vi is used. After the user quits the editor, mmaakkee//00 is invoked to reload all modified source files using ccoonnssuulltt//11. If the editor can be quit such that an exit status non-equal to 0 is returned mmaakkee//00 will not be invoked. _t_o_p can do this by typing control-C, _v_i cannot do this. A predicate specification is either a term with the same functor and arity as the predicate wanted, a term of the form _F_u_n_c_t_o_r/_A_r_i_t_y or a single atom. In the latter case the database is searched for a predicate of this name and arbitrary arity (see ccuurrrreenntt__pprreeddiiccaattee//22). 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 ddwwiimm__pprreeddiiccaattee//22) if the requested predicate does not exist. eedd((_+_P_r_e_d)) Invoke the user's preferred editor on the source file of _P_r_e_d, providing a search specification which searches for the predicate at the start of a line. eedd Invoke eedd//11 on the predicate last edited using eedd//11. Asks the user to confirm before starting the editor. eeddiitt((_+_F_i_l_e)) Invoke the user's preferred editor on _F_i_l_e. _F_i_l_e is a file specification as for ccoonnssuulltt//11 (but not a list). Note that the file should exist. eeddiitt Invoke eeddiitt//11 on the file last edited using eeddiitt//11. Asks the user to confirm before starting the editor. lliissttiinngg((_+_P_r_e_d)) List specified predicates (when an atom is given all predicates with this name will be listed). The listing is produced on the basis of the internal representation, thus loosing user's layout and variable name information. See also ppoorrttrraayy__ccllaauussee//11. lliissttiinngg List all predicates of the database using lliissttiinngg//11. ppoorrttrraayy__ccllaauussee((_+_C_l_a_u_s_e)) Pretty print a clause as good as we can. A clause should be specified as a term `<_H_e_a_d> :- <_B_o_d_y>' (put brackets around it to avoid operator precedence problems). Facts are represented as `<_H_e_a_d> :- true'. eeddiitt__ssoouurrccee((_+_S_p_e_c)) A hook that may be defined in the module user to specify how the predicates eedd//11 and eeddiitt//11 call the editor. If eedd//11 is invoking this hook, _S_p_e_c is a term of the format File:LineNo:Name/Arity Where _F_i_l_e and _L_i_n_e_N_o represents the location of the predicate remembered by Prolog, and _N_a_m_e and _A_r_i_t_y specify the predicate. If invoked by eeddiitt//11, _S_p_e_c is an atom denoting the name of the file to be edited. This hook is defined by the library library(swi_prolog) distributed with the XPCE package for using XPCE to edit Prolog files. 33..44 VVeerriiffyy TTyyppee ooff aa TTeerrmm vvaarr((_+_T_e_r_m)) Succeeds if _T_e_r_m currently is a free variable. nnoonnvvaarr((_+_T_e_r_m)) Succeeds if _T_e_r_m currently is not a free variable. iinntteeggeerr((_+_T_e_r_m)) Succeeds if _T_e_r_m is bound to an integer. ffllooaatt((_+_T_e_r_m)) Succeeds if _T_e_r_m is bound to a floating point number. nnuummbbeerr((_+_T_e_r_m)) Succeeds if _T_e_r_m is bound to an integer or a floating point number. aattoomm((_+_T_e_r_m)) Succeeds if _T_e_r_m is bound to an atom. ssttrriinngg((_+_T_e_r_m)) Succeeds if _T_e_r_m is bound to a string. aattoommiicc((_+_T_e_r_m)) Succeeds if _T_e_r_m is bound to an atom, string, integer or floating point number. ccoommppoouunndd((_+_T_e_r_m)) Succeeds if _T_e_r_m is bound to a compound term. See also ffuunnccttoorr//33 and =../2. ggrroouunndd((_+_T_e_r_m)) Succeeds if _T_e_r_m holds no free variables. 33..55 CCoommppaarriissoonn aanndd UUnniiffiiccaattiioonn oorr TTeerrmmss 33..55..11 SSttaannddaarrdd OOrrddeerr ooff TTeerrmmss Comparison and unification of arbitrary terms. Terms are ordered in the so called ``standard order''. This order is defined as follows: 1. _V_a_r_i_a_b_l_e_s <_A_t_o_m_s <_S_t_r_i_n_g_s <_N_u_m_b_e_r_s <_T_e_r_m_s 2. _O_l_d _V_a_r_i_a_b_l_e <_N_e_w _V_a_r_i_a_b_l_e 3. _A_t_o_m_s are compared alphabetically. 4. _S_t_r_i_n_g_s are compared alphabetically. 5. _N_u_m_b_e_r_s are compared by value. Integers and floats are treated identically. 6. _T_e_r_m_s are first checked on their functor (alphabetically), then on their arity and finally recursively on their arguments, leftmost argument first. _+_T_e_r_m_1 == _+_T_e_r_m_2 Succeeds if _T_e_r_m_1 is equivalent to _T_e_r_m_2. A variable is only identical to a sharing variable. _+_T_e_r_m_1 \== _+_T_e_r_m_2 Equivalent to \+Term1 == Term2. _+_T_e_r_m_1 = _+_T_e_r_m_2 Unify _T_e_r_m_1 with _T_e_r_m_2. Succeeds if the unification succeeds. _+_T_e_r_m_1 \= _+_T_e_r_m_2 Equivalent to \+Term1 = Term2. _+_T_e_r_m_1 =@= _+_T_e_r_m_2 Succeeds if _T_e_r_m_1 is `structurally equal' to _T_e_r_m_2. Structural equivalence is weaker than equivalence (==//22), but stronger than unification (=//22). Two terms are structurally equal if their tree representation is identical and they have the same `pattern' of variables. Examples: a =@= A false A =@= B true x(A,A) =@= x(B,C) false x(A,A) =@= x(B,B) true x(A,B) =@= x(C,D) true _+_T_e_r_m_1 \=@= _+_T_e_r_m_2 Equivalent to `\+Term1 =@= Term2'. _+_T_e_r_m_1 @< _+_T_e_r_m_2 Succeeds if _T_e_r_m_1 is before _T_e_r_m_2 in the standard order of terms. _+_T_e_r_m_1 @=< _+_T_e_r_m_2 Succeeds if both terms are equal (==//22) or _T_e_r_m_1 is before _T_e_r_m_2 in the standard order of terms. _+_T_e_r_m_1 @> _+_T_e_r_m_2 Succeeds if _T_e_r_m_1 is after _T_e_r_m_2 in the standard order of terms. _+_T_e_r_m_1 @>= _+_T_e_r_m_2 Succeeds if both terms are equal (==//22) or _T_e_r_m_1 is after _T_e_r_m_2 in the standard order of terms. ccoommppaarree((_?_O_r_d_e_r_, _+_T_e_r_m_1_, _+_T_e_r_m_2)) Determine or test the _O_r_d_e_r between two terms in the standard order of terms. _O_r_d_e_r is one of <, > or =, with the obvious meaning. 33..66 CCoonnttrrooll PPrreeddiiccaatteess 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). ffaaiill Always fail. The predicate ffaaiill//00 is translated into a single virtual machine instruction. ttrruuee Always succeed. The predicate ttrruuee//00 is translated into a single virtual machine instruction. rreeppeeaatt 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 ;//22, |//22, ->//22 and \+//11 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 ccaallll//11 in t5/0. As the argument of ccaallll//11 is evaluated by predicates rather than the compiler the cut has no effect. t1 :- (a, !, fail ; b). % cuts a/0 and t1/0 t2 :- (a -> b, ! ; c). % cuts b/0 and t2/0 t3(G) :- a, G, fail. % if `G = !' cuts a/0 and t1/1 t4(G) :- a, call(G), fail. % if `G = !' cut has no effect t5 :- call((a, !, fail ; b)). % Cut has no effect t6 :- \+(a, !, fail ; b). % cuts a/0 and t6/0 _+_G_o_a_l_1 , _+_G_o_a_l_2 Conjunction. Succeeds if both `Goal1' and `Goal2' can be proved. It is defined as (this definition does not lead to a loop as the second comma is handled by the compiler): Goal1, Goal2 :- Goal1, Goal2. _+_G_o_a_l_1 ; _+_G_o_a_l_2 The `or' predicate is defined as: Goal1 ; _Goal2 :- Goal1. _Goal1 ; Goal2 :- Goal2. _+_G_o_a_l_1 | _+_G_o_a_l_2 Equivalent to ;//22. Retained for compatibility only. New code should use ;//22. Still nice though for grammar rules. _+_C_o_n_d_i_t_i_o_n -> _+_A_c_t_i_o_n If-then and If-Then-Else. The ->//22 construct commits to the choices made at its left-hand side, destroying choice-points created inside the clause (by ;//22), or by goals called by this clause. Unlike !//00, the choicepoint of the predicate as a whole (due to multiple clauses) is nnoott destroyed. The combination ;//22 and ->//22 is defines as: If -> Then; _Else :- If, !, Then. If -> _Then; Else :- !, Else. If -> Then :- If, !, Then. Note that the operator precedence relation between ; and -> ensure If -> Then ; Else is actually a term of the form ;(->(If, Then), Else). The first two clauses belong to the definition of ;//22), while only the last defines ->//22 . _+_C_o_n_d_i_t_i_o_n *-> _+_A_c_t_i_o_n _; _+_E_l_s_e This construct implements the so-called `soft-cut'. The control is defined as follows: If _C_o_n_d_i_t_i_o_n succeeds at least once, the semantics is the same as (_C_o_n_d_i_t_i_o_n, _A_c_t_i_o_n). If _C_o_n_d_i_t_i_o_n does not succeed, the semantics is that of (_C_o_n_d_i_t_i_o_n, _E_l_s_e). In other words, If _C_o_n_d_i_t_i_o_n succeeds at least once, simply behave as the conjunction of _C_o_n_d_i_t_i_o_n and _A_c_t_i_o_n, otherwise execute _E_l_s_e. \+ _+_G_o_a_l Succeeds if `Goal' cannot be proven (mnemonic: + refers to _p_r_o_v_a_b_l_e and the backslash (\) is normally used to indicate negation). 33..77 MMeettaa--CCaallll PPrreeddiiccaatteess 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. ccaallll((_+_G_o_a_l)) Invoke _G_o_a_l as a goal. Note that clauses may have variables as subclauses, which is identical to ccaallll//11, except when the argument is bound to the cut. See !//00. ccaallll((_+_G_o_a_l_, _+_E_x_t_r_a_A_r_g_1_, _._._.)) Append _E_x_t_r_a_A_r_g_1_, _E_x_t_r_a_A_r_g_2_, _._._. to the argument list of _G_o_a_l and call the result. For example, call(plus(1), 2, X) will call pplluuss//33, binding _X to 3. The call/[2..] construct is handled by the compiler, which implies that redefinition as a predicate has no effect. The predicates ccaallll//[[22--66]] are defined as true predicates, so they can be handled by interpreted code. aappppllyy((_+_T_e_r_m_, _+_L_i_s_t)) Append the members of _L_i_s_t to the arguments of _T_e_r_m and call the resulting term. For example: apply(plus(1), [2, X]) will call plus(1, 2, X). aappppllyy//22 is incorporated in the virtual machine of SWI-Prolog. This implies that the overhead can be compared to the overhead of ccaallll//11. New code should use call/[2..] if the length of _L_i_s_t is fixed, which is more widely supported and faster because there is no need to build and examine the argument list. nnoott((_+_G_o_a_l)) Succeeds when _G_o_a_l cannot be proven. Retained for compatibility only. New code should use \+//11. oonnccee((_+_G_o_a_l)) Defined as: once(Goal) :- Goal, !. oonnccee//11 can in many cases be replaced with ->//22. 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. iiggnnoorree((_+_G_o_a_l)) Calls _G_o_a_l as oonnccee//11, but succeeds, regardless of whether _G_o_a_l succeeded or not. Defined as: ignore(Goal) :- Goal, !. ignore(_). ccaallll__wwiitthh__ddeepptthh__lliimmiitt((_+_G_o_a_l_, _+_L_i_m_i_t_, _-_R_e_s_u_l_t)) If _G_o_a_l can be proven without recursion deeper than _L_i_m_i_t levels, ccaallll__wwiitthh__ddeepptthh__lliimmiitt//33 succeeds, binding _R_e_s_u_l_t to the deepest recursion level used during the proof. Otherwise, _R_e_s_u_l_t is unified with depth_limit_exceeded if the limit was exceeded during the proof, or the entire predicate fails if _G_o_a_l fails without exceeding _L_i_m_i_t. The depth-limit is guarded by the internal machinery. This differ from the depth computed based on a theoretical model. For example, ttrruuee//00 is translated into an inlined virtual machine instruction. Also, rreeppeeaatt//00 is not implemented as below, but as a non-deterministic foreign predicate. repeat. repeat :- repeat. As a result, ccaallll__wwiitthh__ddeepptthh__lliimmiitt//33may still loop inifitly on programs that should theoretically finish in finite time. This problem can be cured by using Prolog equivalents to such built-in predicates. This predicate may be used for theorem-provers to realise techniques like _i_t_e_r_r_a_t_i_v_e _d_e_e_p_e_n_i_n_g. It was implemented after discussion with Steve Moyle smoyle@ermine.ox.ac.uk. 33..88 IISSOO ccoommpplliiaanntt EExxcceeppttiioonn hhaannddlliinngg SWI-Prolog defines the predicates ccaattcchh//33 and tthhrrooww//11 for ISO compliant raising and catching of exceptions. In the current implementation (2.9.0), only part of the built-in predicates generate exceptions. In general, exceptions are implemented for I/O and arithmetic. ccaattcchh((_:_G_o_a_l_, _+_C_a_t_c_h_e_r_, _:_R_e_c_o_v_e_r)) Behaves as ccaallll//11 if no exception is raised when executing _G_o_a_l. If a exception is raised using tthhrrooww//11 while _G_o_a_l executes, and the _G_o_a_l is the innermost goal for which _C_a_t_c_h_e_r unifies with the argument of tthhrrooww//11, all choicepoints generated by _G_o_a_l are cut, and _R_e_c_o_v_e_r is called as in ccaallll//11. The overhead of calling a goal through ccaattcchh//33 is very comparable to ccaallll//11. Recovery from an exception has a similar overhead. tthhrrooww((_+_E_x_c_e_p_t_i_o_n)) Raise an exception. The system will look for the innermost ccaattcchh//33 ancestor for which _E_x_c_e_p_t_i_o_n unifies with the _C_a_t_c_h_e_r argument of the ccaattcchh//33 call. See ccaattcchh//33 for details. If there is no ccaattcchh//33 willing to catch the error in the current Prolog context, the toplevel (pprroolloogg//00) catches the error and prints a warning message. If an exception was raised in a callback from C (see chapter 5), PPLL__nneexxtt__ssoolluuttiioonn(())will fail and the exception context can be retrieved using PPLL__eexxcceeppttiioonn(()). 33..88..11 DDeebbuuggggiinngg aanndd eexxcceeppttiioonnss Before the introduction of exceptions in SWI-Prolog a runtime error was handled by printing an error message, after which the predicate failed. If the feature (see ffeeaattuurree//22) debug_on_error was in effect (default), the tracer was switched on. The combination of the error message and trace information is generally sufficient to locate the error. With exception handling, things are different. A programmer may wish to trap an exception using ccaattcchh//33 to avoid it reaching the user. If the exception is not handled by user-code, the interactive toplevel will trap it to prevent termination. If we do not take special precautions, the context information associated with an unexpected exception (i.e. a programming error) is lost. Therefore, if an exception is raised, which is not caught using ccaattcchh//33 and the toplevel is running, the error will be printed, and the system will enter trace mode. If the system is in an non-interactive callback from foreign code and there is no ccaattcchh//33 active in the current context, it cannot determine whether or not the exception will be caught by the external routine calling Prolog. It will then base its behaviour on the feature debug_on_error: o _f_e_a_t_u_r_e_(_d_e_b_u_g___o_n___e_r_r_o_r_, _f_a_l_s_e_) The exception does not trap the debugger and is returned to the foreign routine calling Prolog, where it can be accessed using PPLL__eexxcceeppttiioonn(()). This is the default. o _f_e_a_t_u_r_e_(_d_e_b_u_g___o_n___e_r_r_o_r_, _t_r_u_e_) If the exception is not caught by Prolog in the current context, it will trap the tracer to help analysing the context of the error. While looking for the context in which an exception takes place, it is adviced to switch on debug mode using the predicate ddeebbuugg//00. 33..88..22 TThhee eexxcceeppttiioonn tteerrmm Builtin predicates generates exceptions using a term error(_F_o_r_m_a_l_, _C_o_n_t_e_x_t). The first argument is the `formal' description of the error, specifying the class and generic defined context information. When applicable, the ISO error-term definition is used. The second part describes some additional context to help the programmer while debugging. In its most generic form this is a term of the form context(_N_a_m_e_/_A_r_i_t_y_, _M_e_s_s_a_g_e), where _N_a_m_e/_A_r_i_t_y describes the built-in predicate that raised the error, and _M_e_s_s_a_g_e provides an additional description of the error. Any part of this structure may be a variable if no information was present. 33..88..33 PPrriinnttiinngg aa mmeessssaaggee ffrroomm aann eexxcceeppttiioonn The predicate pprriinntt__mmeessssaaggee//22 may be used to print an exception term in a human readable format: pprriinntt__mmeessssaaggee((_+_K_i_n_d_, _+_T_e_r_m)) This predicate is modelled after the Quintus predicate with the same name, though its current implementation is incomplete. It is used only for printing messages from exceptions from built-in predicates. _K_i_n_d is one of informational, warning, consterror, help or silent. Currently only error is defined. _T_e_r_m is an eerrrroorr((_2)) term described in section 3.8.2. A human-readable message is printed to the stream user_error. This predicate first obtains the `human translation' of _T_e_r_m and then calls mmeessssaaggee__hhooookk//33. If this fails the message is printed to the stream user_error. The pprriinntt__mmeessssaaggee//22 predicate and its rules are in the file <_p_l_h_o_m_e>/boot/messages.pl, which may be inspected for more information on the error messages and related error terms. mmeessssaaggee__hhooookk((_+_T_e_r_m_, _+_K_i_n_d_, _+_M_e_s_s_a_g_e)) Hook predicate that may be define in the module user to intercept messages from pprriinntt__mmeessssaaggee//22. _T_e_r_m and _K_i_n_d are the same as passed to pprriinntt__mmeessssaaggee//22. _M_e_s_s_a_g_e is a string containing the human readable translation of the message. If this predicate succeeds, pprriinntt__mmeessssaaggee//22 considers the message printed. This predicate should be defined dynamic and multifile to allow other modules defining clauses for it too. 33..99 AAddvvaanncceedd ccoonnttrrooll--ssttrruuccttuurreess:: bblloocckkss The predicates of this section form a tightly related set for realising premature successful or failing exits from a _b_l_o_c_k. These predicates are first of all useful for error-recovery. They were primarily implemented for compatibility reasons. bblloocckk((_+_L_a_b_e_l_, _+_G_o_a_l_, _-_E_x_i_t_V_a_l_u_e)) Execute _G_o_a_l in a _b_l_o_c_k. _L_a_b_e_l is the name of the block. _L_a_b_e_l is normally an atom, but the system imposes no type constraints and may even be a variable. _E_x_i_t_V_a_l_u_e is normally unified to the second argument of an eexxiitt//22 call invoked by _G_o_a_l. eexxiitt((_+_L_a_b_e_l_, _+_V_a_l_u_e)) Calling eexxiitt//22 makes the innermost _b_l_o_c_k which _L_a_b_e_l unifies exit. The block's _E_x_i_t_V_a_l_u_e is unified with _V_a_l_u_e. If this unification fails the block fails. ffaaiill((_+_L_a_b_e_l)) Calling ffaaiill//11 makes the innermost _b_l_o_c_k which _L_a_b_e_l unifies fail immediately. Implemented as fail(Label) :- !(Label), fail. !((_+_L_a_b_e_l)) Cut all choice-points created since the entry of the innermost _b_l_o_c_k which _L_a_b_e_l unifies. The example below illustrate these constructs to immediately report a syntax-error from a `deep-down' procedure to the outside world without passing it as an argument `all-over-the-place'. parse(RuleSet, InputList, Rest) :- block(syntaxerror, phrase(RuleSet, InputList, Rest), Error), ( var(Error) -> true ; format('Syntax-error: ~w~n', Error), fail ). integer(N) --> digit(D1), !, digits(Ds), { name(N, [D1|Ds]) }. digits([D|R]) --> digit(D), digits(R). digits(_) --> letter(_), !, { exit(syntaxerror, 'Illegal number') }. digits([]) --> []. digit(D, [D|R], R) :- between(0'0, 0'9, D). letter(D, [D|R], R) :- between(0'a, 0'z, D). 33..1100 GGrraammmmaarr rruullee iinntteerrffaaccee ((pphhrraassee)) The predicates below may be called to activate a grammar-rule set: pphhrraassee((_+_R_u_l_e_S_e_t_, _+_I_n_p_u_t_L_i_s_t)) Equivalent to phrase(RuleSet, InputList, []). pphhrraassee((_+_R_u_l_e_S_e_t_, _+_I_n_p_u_t_L_i_s_t_, _-_R_e_s_t)) Activate the rule-set with given name. `InputList' is the list of tokens to parse, `Rest' is unified with the remaining tokens if the sentence is parsed correctly. 33..1111 DDaattaabbaassee 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 aasssseerrtt//11 or one of its derivatives become part of the program these predicates compile the term given to them. rreettrraacctt//11 and rreettrraaccttaallll//11 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 ddyynnaammiicc//11. The second way of storing arbitrary terms in the database is using the ``recorded database''. In this database terms are associated with a _k_e_y. A key can be an atom, integer or term. In the last case only the functor and arity determine the key. Each key has a chain of terms associated with it. New terms can be added either at the head or at the tail of this chain. This mechanism is considerably faster than the assert/retract mechanism as terms are not compiled, but just copied into the heap. The third mechanism is a special purpose one. It associates an integer or atom with a key, which is an atom, integer or term. Each key can only have one atom or integer associated with it. It again is considerably faster than the mechanisms described above, but can only be used to store simple status information like counters, etc. aabboolliisshh((_:_P_r_e_d_i_c_a_t_e_I_n_d_i_c_a_t_o_r)) Removes all clauses of a predicate with functor _F_u_n_c_t_o_r and arity _A_r_i_t_y from the database. Unlike version 1.2, all predicate attributes (dynamic, multifile, index, etc.) are reset to their defaults. Abolishing an imported predicate only removes the import link; the predicate will keep its old definition in its definition module. For `cleanup' of the dynamic database, one should use rreettrraaccttaallll//11 rather than aabboolliisshh//22. aabboolliisshh((_+_N_a_m_e_, _+_A_r_i_t_y)) Same as abolish(Name/Arity). The predicate aabboolliisshh//22 conforms to the Edinburgh standard, while aabboolliisshh//11 is ISO compliant. rreeddeeffiinnee__ssyysstteemm__pprreeddiiccaattee((_+_H_e_a_d)) This directive may be used both in module user and in normal modules to redefine any system predicate. If the system definition is redefined in module user, the new definition is the default definition for all sub-modules. Otherwise the redefinition is local to the module. The system definition remains in the module system. Redefining system predicate facilitates the definition of compatibility packages. Use in other context is discouraged. rreettrraacctt((_+_T_e_r_m)) When _T_e_r_m is an atom or a term it is unified with the first unifying fact or clause in the database. The fact or clause is removed from the database. rreettrraaccttaallll((_+_H_e_a_d)) All facts or clauses in the database for which the _h_e_a_d unifies with _H_e_a_d are removed. aasssseerrtt((_+_T_e_r_m)) Assert a fact or clause in the database. _T_e_r_m is asserted as the last fact or clause of the corresponding predicate. aasssseerrttaa((_+_T_e_r_m)) Equivalent to aasssseerrtt//11, but _T_e_r_m is asserted as first clause or fact of the predicate. aasssseerrttzz((_+_T_e_r_m)) Equivalent to aasssseerrtt//11. aasssseerrtt((_+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e)) Equivalent to aasssseerrtt//11, but _R_e_f_e_r_e_n_c_e is unified with a unique reference to the asserted clause. This key can later be used with ccllaauussee//33 or eerraassee//11. aasssseerrttaa((_+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e)) Equivalent to aasssseerrtt//22, but _T_e_r_m is asserted as first clause or fact of the predicate. aasssseerrttzz((_+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e)) Equivalent to aasssseerrtt//22. rreeccoorrddaa((_+_K_e_y_, _+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e)) Assert _T_e_r_m in the recorded database under key _K_e_y. _K_e_y is an integer, atom or term. _R_e_f_e_r_e_n_c_e is unified with a unique reference to the record (see eerraassee//11). rreeccoorrddaa((_+_K_e_y_, _+_T_e_r_m)) Equivalent to recorda(Key, Value, _). rreeccoorrddzz((_+_K_e_y_, _+_T_e_r_m_, _-_R_e_f_e_r_e_n_c_e)) Equivalent to rreeccoorrddaa//33, but puts the _T_e_r_m at the tail of the terms recorded under _K_e_y. rreeccoorrddzz((_+_K_e_y_, _+_T_e_r_m)) Equivalent to recordz(Key, Value, _). rreeccoorrddeedd((_+_K_e_y_, _-_V_a_l_u_e_, _-_R_e_f_e_r_e_n_c_e)) Unify _V_a_l_u_e with the first term recorded under _K_e_y which does unify. _R_e_f_e_r_e_n_c_e is unified with the memory location of the record. rreeccoorrddeedd((_+_K_e_y_, _-_V_a_l_u_e)) Equivalent to recorded(Key, Value, _). eerraassee((_+_R_e_f_e_r_e_n_c_e)) Erase a record or clause from the database. _R_e_f_e_r_e_n_c_e is an integer returned by rreeccoorrddaa//33 or rreeccoorrddeedd//33, ccllaauussee//33, aasssseerrtt//22, aasssseerrttaa//22 or aasssseerrttzz//22. 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. ffllaagg((_+_K_e_y_, _-_O_l_d_, _+_N_e_w)) _K_e_y is an atom, integer or term. Unify _O_l_d with the old value associated with _K_e_y. If the key is used for the first time _O_l_d is unified with the integer 0. Then store the value of _N_e_w, which should be an integer, float, atom or arithmetic expression, under _K_e_y. ffllaagg//33 is a very fast mechanism for storing simple facts in the database. Example: :- module_transparent succeeds_n_times/2. succeeds_n_times(Goal, Times) :- flag(succeeds_n_times, Old, 0), Goal, flag(succeeds_n_times, N, N+1), fail ; flag(succeeds_n_times, Times, Old). 33..1111..11 IInnddeexxiinngg ddaattaabbaasseess By default, SWI-Prolog, as most other implementations, indexes predicates on their first argument. SWI-Prolog allows indexing on other and multiple arguments using the declaration iinnddeexx//11. For advanced database indexing, it defines hhaasshh__tteerrmm//22: hhaasshh__tteerrmm((_+_T_e_r_m_, _-_H_a_s_h_K_e_y)) If _T_e_r_m is a ground term (see ggrroouunndd//11), _H_a_s_h_K_e_y is unified with a positive integer value that may be used as a hash-key to the value. If _T_e_r_m is not ground, the predicate succeeds immediately, leaving _H_a_s_h_K_e_y an unbound variable. This predicate may be used to build hash-tables as well as to exploit argument-indexing to find complex terms more quickly. The hash-key does not rely on temporary information like addresses of atoms and may be assumed constant over different invocations of SWI-Prolog. 33..1122 DDeeccllaarriinngg PPrrooppeerrttiieess ooff PPrreeddiiccaatteess This section describes directives which manipulate attributes of predicate definitions. The functors ddyynnaammiicc//11, mmuullttiiffiillee//11 and ddiissccoonnttiigguuoouuss//11 are operators of priority 1150 (see oopp//33), 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. ddyynnaammiicc _+_F_u_n_c_t_o_r_/_+_A_r_i_t_y_, _._._. Informs the interpreter that the definition of the predicate(s) may change during execution (using aasssseerrtt//11 and/or rreettrraacctt//11). Currently ddyynnaammiicc//11 only stops the interpreter from complaining about undefined predicates (see uunnkknnoowwnn//22). Future releases might prohibit aasssseerrtt//11 and rreettrraacctt//11 for not-dynamic declared procedures. mmuullttiiffiillee _+_F_u_n_c_t_o_r_/_+_A_r_i_t_y_, _._._. Informs the system that the specified predicate(s) may be defined over more than one file. This stops ccoonnssuulltt//11 from redefining a predicate when a new definition is found. ddiissccoonnttiigguuoouuss _+_F_u_n_c_t_o_r_/_+_A_r_i_t_y_, _._._. Informs the system that the clauses of the specified predicate(s) might not be together in the source file. See also ssttyyllee__cchheecckk//11. iinnddeexx((_+_H_e_a_d)) Index the clauses of the predicate with the same name and arity as _H_e_a_d on the specified arguments. _H_e_a_d is a term of which all arguments are either `1' (denoting `index this argument') or `0' (denoting `do not index this argument'). Indexing has no implications for the semantics of a predicate, only on its performance. If indexing is enabled on a predicate a special purpose algorithm is used to select candidate clauses based on the actual arguments of the goal. This algorithm checks whether indexed arguments might unify in the clause head. Only atoms, integers and functors (e.g. name and arity of a term) are considered. Indexing is very useful for predicates with many clauses representing facts. Due to the representation technique used at most 4 arguments can be indexed. All indexed arguments should be in the first 32 arguments of the predicate. If more than 4 arguments are specified for indexing only the first 4 will be accepted. Arguments above 32 are ignored for indexing. By default all predicates with <_a_r_i_t_y> 1 are indexed on their first argument. It is possible to redefine indexing on predicates that already have clauses attached to them. This will initiate a scan through the predicates clause list to update the index summary information stored with each clause. If---for example---one wants to represents sub-types using a fact list `sub_type(Sub, Super)' that should be used both to determine sub- and super types one should declare sub_type/2 as follows: :- index(sub_type(1, 1)). sub_type(horse, animal). ... ... 33..1133 EExxaammiinniinngg tthhee PPrrooggrraamm ccuurrrreenntt__aattoomm((_-_A_t_o_m)) Successively unifies _A_t_o_m with all atoms known to the system. Note that ccuurrrreenntt__aattoomm//11always succeeds if _A_t_o_m is instantiated to an atom. ccuurrrreenntt__ffuunnccttoorr((_?_N_a_m_e_, _?_A_r_i_t_y)) Successively unifies _N_a_m_e with the name and _A_r_i_t_y with the arity of functors known to the system. ccuurrrreenntt__ffllaagg((_-_F_l_a_g_K_e_y)) Successively unifies _F_l_a_g_K_e_y with all keys used for flags (see ffllaagg//33). ccuurrrreenntt__kkeeyy((_-_K_e_y)) Successively unifies _K_e_y with all keys used for records (see rreeccoorrddaa//33, etc.). ccuurrrreenntt__pprreeddiiccaattee((_?_N_a_m_e_, _?_H_e_a_d)) Successively unifies _N_a_m_e with the name of predicates currently defined and _H_e_a_d with the most general term built from _N_a_m_e and the arity of the predicate. This predicate succeeds for all predicates defined in the specified module, imported to it, or in one of the modules from which the predicate will be imported if it is called. pprreeddiiccaattee__pprrooppeerrttyy((_?_H_e_a_d_, _?_P_r_o_p_e_r_t_y)) Succeeds if _H_e_a_d refers to a predicate that has property _P_r_o_p_e_r_t_y. Can be used to test whether a predicate has a certain property, obtain all properties known for _H_e_a_d, find all predicates having _p_r_o_p_e_r_t_y or even obtaining all information available about the current program. _P_r_o_p_e_r_t_y is one of: iinntteerrpprreetteedd 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. bbuuiilltt__iinn Is true if the predicate is locked as a built-in predicate. This implies it cannot be redefined in its definition module and it can normally not be seen in the tracer. ffoorreeiiggnn Is true if the predicate is defined in the C language. ddyynnaammiicc Is true if the predicate is declared dynamic using the ddyynnaammiicc//11 declaration. mmuullttiiffiillee Is true if the predicate is declared multifile using the mmuullttiiffiillee//11 declaration. uunnddeeffiinneedd Is true if a procedure definition block for the predicate exists, but there are no clauses in it and it is not declared dynamic. This is true if the predicate occurs in the body of a loaded predicate, an attempt to call it has been made via one of the meta-call predicates or the predicate had a definition in the past. See the library package _c_h_e_c_k for example usage. ttrraannssppaarreenntt Is true if the predicate is declared transparent using the mmoodduullee__ttrraannssppaarreenntt//11declaration. eexxppoorrtteedd Is true if the predicate is in the public list of the context module. iimmppoorrtteedd__ffrroomm((_M_o_d_u_l_e)) Is true if the predicate is imported into the context module from module _M_o_d_u_l_e. iinnddeexxeedd((_H_e_a_d)) Predicate is indexed (see iinnddeexx//11) according to _H_e_a_d. _H_e_a_d is a term whose name and arity are identical to the predicate. The arguments are unified with `1' for indexed arguments, `0' otherwise. ffiillee((_F_i_l_e_N_a_m_e)) Unify _F_i_l_e_N_a_m_e with the name of the sourcefile in which the predicate is defined. See also ssoouurrccee__ffiillee//22. lliinnee__ccoouunntt((_L_i_n_e_N_u_m_b_e_r)) Unify _L_i_n_e_N_u_m_b_e_r with the line number of the first clause of the predicate. Fails if the predicate is not associated with a file. See also ssoouurrccee__ffiillee//22. nnuummbbeerr__ooff__ccllaauusseess((_C_l_a_u_s_e_C_o_u_n_t)) Unify _C_l_a_u_s_e_C_o_u_n_t to the number of clauses associated with the predicate. Fails for foreign predicates. ddwwiimm__pprreeddiiccaattee((_+_T_e_r_m_, _-_D_w_i_m)) `Do What I Mean' (`dwim') support predicate. _T_e_r_m is a term, which name and arity are used as a predicate specification. _D_w_i_m is instantiated with the most general term built from _N_a_m_e and the arity of a defined predicate that matches the predicate specified by _T_e_r_m in the `Do What I Mean' sense. See ddwwiimm__mmaattcchh//22for `Do What I Mean' string matching. Internal system predicates are not generated, unless style_check(+dollar) is active. Backtracking provides all alternative matches. ccllaauussee((_?_H_e_a_d_, _?_B_o_d_y)) Succeeds when _H_e_a_d can be unified with a clause head and _B_o_d_y with the corresponding clause body. Gives alternative clauses on backtracking. For facts _B_o_d_y is unified with the atom _t_r_u_e. Normally ccllaauussee//22 is used to find clause definitions for a predicate, but it can also be used to find clause heads for some body template. ccllaauussee((_?_H_e_a_d_, _?_B_o_d_y_, _?_R_e_f_e_r_e_n_c_e)) Equivalent to ccllaauussee//22, but unifies _R_e_f_e_r_e_n_c_e with a unique reference to the clause (see also aasssseerrtt//22, eerraassee//11). If _R_e_f_e_r_e_n_c_e is instantiated to a reference the clause's head and body will be unified with _H_e_a_d and _B_o_d_y. nntthh__ccllaauussee((_?_P_r_e_d_, _?_I_n_d_e_x_, _?_R_e_f_e_r_e_n_c_e)) Provides access to the clauses of a predicate using their index number. Counting starts at 1. If _R_e_f_e_r_e_n_c_e is specified it unifies _P_r_e_d with the most general term with the same name/arity as the predicate and _I_n_d_e_x with the index-number of the clause. Otherwise the name and arity of _P_r_e_d are used to determine the predicate. If _I_n_d_e_x is provided _R_e_f_e_r_e_n_c_e will be unified with the clause reference. If _I_n_d_e_x is unbound, backtracking will yield both the indices and the references of all clauses of the predicate. The following example finds the 2nd clause of mmeemmbbeerr//22: ?- nth_clause(member(_,_), 2, Ref), clause(Head, Body, Ref). Ref = 160088 Head = system : member(G575, [G578|G579]) Body = member(G575, G579) ccllaauussee__pprrooppeerrttyy((_+_C_l_a_u_s_e_R_e_f_, _-_P_r_o_p_e_r_t_y)) Queries properties of a clause. _C_l_a_u_s_e_R_e_f is a reference to a clause as produced by ccllaauussee//33, nntthh__ccllaauussee//33 or pprroolloogg__ffrraammee__aattttrriibbuuttee//33. _P_r_o_p_e_r_t_y is one of the following: ffiillee((_F_i_l_e_N_a_m_e)) Unify _F_i_l_e_N_a_m_e with the name of the sourcefile in which the clause is defined. Fails if the clause is not associated to a file. lliinnee__ccoouunntt((_L_i_n_e_N_u_m_b_e_r)) Unify _L_i_n_e_N_u_m_b_e_r with the line number of the clause. Fails if the clause is not associated to a file. ffaacctt True if the clause has no body. eerraasseedd True if the clause has been erased, but not yet reclaimed because it is referenced. 33..1144 IInnppuutt aanndd OOuuttppuutt SWI-Prolog provides two different packages for input and output. One confirms to the Edinburgh standard. This package has a notion of `current-input' and `current-output'. The reading and writing predicates implicitly refer to these streams. In the second package, streams are opened explicitly and the resulting handle is used as an argument to the reading and writing predicate to specify the source or destination. Both packages are fully integrated; the user may switch freely between them. 33..1144..11 IInnppuutt aanndd OOuuttppuutt UUssiinngg IImmpplliicciitt SSoouurrccee aanndd DDeessttiinnaattiioonn 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 tteellll//11 or aappppeenndd//11. The current input stream is changed using sseeee//11. The streams current value can be obtained using tteelllliinngg//11 for output- and sseeeeiinngg//11 for input streams. The table below shows the valid stream specifications. The reserved names user_input, user_output and user_error are for neat integration with the explicit streams. ___________________________________________________ | user |This reserved name refers to the| | |terminal | | user_input I|nput from the terminal | | user_output O|utput to the terminal | | user_error U|nix error stream (output only) | | <_A_t_o_m> N|ame of a Unix file | |_pipe(<_A_t_o_m>)N|ame_of_a_Unix_command_____________|_ Source and destination are either a file, one of the reserved words above, or a term `pipe(_C_o_m_m_a_n_d)'. In the predicate descriptions below we will call the source/destination argument `_S_r_c_D_e_s_t'. Below are some examples of source/destination specifications. ?- see(data). % Start reading from file `data'. ?- tell(stderr). % Start writing on the error stream. ?- tell(pipe(lpr)). % Start writing to the printer. Another example of using the ppiippee//11 construct is shown below. Note that the ppiippee//11 construct is not part of Prolog's standard I/O repertoire. getwd(Wd) :- seeing(Old), see(pipe(pwd)), collect_wd(String), seen, see(Old), atom_chars(Wd, String). collect_wd([C|R]) :- get0(C), C \== -1, !, collect_wd(R). collect_wd([]). sseeee((_+_S_r_c_D_e_s_t)) Make _S_r_c_D_e_s_t the current input stream. If _S_r_c_D_e_s_t was already opened for reading with sseeee//11 and has not been closed since, reading will be resumed. Otherwise _S_r_c_D_e_s_t will be opened and the file pointer is positioned at the start of the file. tteellll((_+_S_r_c_D_e_s_t)) Make _S_r_c_D_e_s_t the current output stream. If _S_r_c_D_e_s_t was already opened for writing with tteellll//11 or aappppeenndd//11 and has not been closed since, writing will be resumed. Otherwise the file is created or---when existing---truncated. See also aappppeenndd//11. aappppeenndd((_+_F_i_l_e)) Similar to tteellll//11, but positions the file pointer at the end of _F_i_l_e rather than truncating an existing file. The pipe construct is not accepted by this predicate. sseeeeiinngg((_?_S_r_c_D_e_s_t)) Unify the name of the current input stream with _S_r_c_D_e_s_t. tteelllliinngg((_?_S_r_c_D_e_s_t)) Unify the name of the current output stream with _S_r_c_D_e_s_t. sseeeenn Close the current input stream. The new input stream becomes _u_s_e_r. ttoolldd Close the current output stream. The new output stream becomes _u_s_e_r. 33..1144..22 EExxpplliicciitt IInnppuutt aanndd OOuuttppuutt SSttrreeaammss The predicates below are part of the Quintus compatible stream-based I/O package. In this package streams are explicitly created using the predicate ooppeenn//33. 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. ooppeenn((_+_S_r_c_D_e_s_t_, _+_M_o_d_e_, _-_S_t_r_e_a_m_, _+_O_p_t_i_o_n_s)) ISO compliant predicate to open a stream. _S_r_c_D_e_s is either an atom, specifying a Unix file, or a term `pipe(Command)', just like sseeee//11 and tteellll//11. _M_o_d_e is one of read, write, append or update. Mode append opens the file for writing, positioning the file-pointer at the end. Mode update opens the file for writing, positioning the file-pointer at the beginning of the file without truncating the file. See also ssttrreeaamm__ppoossiittiioonn//33. _S_t_r_e_a_m is either a variable, in which case it is bound to an integer identifying the stream, or an atom, in which case this atom will be the stream identifier. The _O_p_t_i_o_n_s list can contain the following options: ttyyppee((_T_y_p_e)) Using type text (default), Prolog will write a text-file in an operating-system compatible way. Using type binary the bytes will be read or written without any translation. Note there is no difference between the two on Unix systems. aalliiaass((_A_t_o_m)) Gives the stream a name. The following two calls are identical, but only the latter is allowed in ISO Prolog. ?- open(foo, read, in, []). ?- open(foo, read, S, [alias(in)]). eeooff__aaccttiioonn((_A_c_t_i_o_n)) Defines what happens if the end of the input stream is reached. Action eof_code makes ggeett00//11 and friends return -1 and rreeaadd//11 and friends return the atom end_of_file. Repetitive reading keeps yielding the same result. Action error is like eof_code, but repetitive reading will raise an error. With action reset, Prolog will examine the file again and return more data if the file has grown. bbuuffffeerr((_B_u_f_f_e_r_i_n_g)) Defines output buffering. The atom fullf (default) defines full buffering, line buffering by line, and false implies the stream is fully unbuffered. Smaller buffering is useful if another process or the user is waiting for the output as it is being produced. See also fflluusshh//00 and fflluusshh__oouuttppuutt//11. This option is not an ISO option. cclloossee__oonn__aabboorrtt((_B_o_o_l)) If true (default), the stream is closed on an abort (see aabboorrtt//00). If false, the stream is not closed. If it is an output stream, it will be flushed however. Useful for logfiles and if the stream is associated to a process (using the ppiippee//11 construct). The option reposition is not supported in SWI-Prolog. All streams connected to a file may be repositioned. ooppeenn((_+_S_r_c_D_e_s_t_, _+_M_o_d_e_, _?_S_t_r_e_a_m)) Equivalent to ooppeenn//44 with an empty option-list. ooppeenn__nnuullll__ssttrreeaamm((_?_S_t_r_e_a_m)) Open a stream that produces no output. All counting functions are enabled on such a stream. An attempt to read from a null-stream will immediately signal end-of-file. Similar to Unix /dev/null. _S_t_r_e_a_m can be an atom, giving the null-stream an alias name. cclloossee((_+_S_t_r_e_a_m)) Close the specified stream. If _S_t_r_e_a_m is not open an error message is displayed. If the closed stream is the current input or output stream the terminal is made the current input or output. ccuurrrreenntt__ssttrreeaamm((_?_F_i_l_e_, _?_M_o_d_e_, _?_S_t_r_e_a_m)) Is true if a stream with file specification _F_i_l_e, mode _M_o_d_e and stream identifier _S_t_r_e_a_m is open. The reserved streams user and user_error are not generated by this predicate. If a stream has been opened with mode append this predicate will generate mode write. ssttrreeaamm__ppoossiittiioonn((_+_S_t_r_e_a_m_, _-_O_l_d_, _+_N_e_w)) Unify the position parameters of _S_t_r_e_a_m with _O_l_d and set them to _N_e_w. A position is represented by the following term: '$stream_position'(CharNo, LineNo, LinePos). It is only possible to change the position parameters if the stream is connected to a disk file. If the position is changed, the _C_h_a_r_N_o field determines the new position in the file. The _L_i_n_e_N_o and _L_i_n_e_P_o_s are copied in the stream administration. 33..1144..33 SSwwiittcchhiinngg BBeettwweeeenn IImmpplliicciitt aanndd EExxpplliicciitt II//OO The predicates below can be used for switching between the implicit- and the explicit stream based I/O predicates. sseett__iinnppuutt((_+_S_t_r_e_a_m)) Set the current input stream to become _S_t_r_e_a_m. Thus, open(file, read, Stream), set_input(Stream) is equivalent to see(file). sseett__oouuttppuutt((_+_S_t_r_e_a_m)) Set the current output stream to become _S_t_r_e_a_m. ccuurrrreenntt__iinnppuutt((_-_S_t_r_e_a_m)) Get the current input stream. Useful to get access to the status predicates associated with streams. ccuurrrreenntt__oouuttppuutt((_-_S_t_r_e_a_m)) Get the current output stream. dduupp__ssttrreeaamm((_+_F_r_o_m_, _+_T_o)) Duplicate the underlying data from stream _F_r_o_m to streamTo, so actions performed on either stream have the same effect. The primary goal of this predicate is to facilitate redirection of the user interaction to allow for `interactor' windows. For example, the following code will redirect output to user_output and user_error to an XPCE text window: ..., pce_open(Window, append, Fd), dup_stream(user_output, Fd), dup_stream(user_error, Fd), ... The old status of a stream can be stored by duplicating to a null-stream as obtained using ooppeenn__nnuullll__ssttrreeaamm//11. This predicate is SWI-Prolog specific. 33..1155 SSttaattuuss ooff IInnppuutt aanndd OOuuttppuutt SSttrreeaammss wwaaiitt__ffoorr__iinnppuutt((_+_L_i_s_t_O_f_S_t_r_e_a_m_s_, _-_R_e_a_d_y_L_i_s_t_, _+_T_i_m_e_O_u_t)) Wait for input on one of the streams in _L_i_s_t_O_f_S_t_r_e_a_m_s and return a list of streams on which input is available in _R_e_a_d_y_L_i_s_t. wwaaiitt__ffoorr__iinnppuutt//33 waits for at most _T_i_m_e_O_u_t seconds. _T_i_m_e_o_u_t may be specified as a floating point number to specify fractions of a second. If _T_i_m_e_o_u_t equals 0, wwaaiitt__ffoorr__iinnppuutt//33waits indefinitely. This predicate can be used to implement timeout while reading and to handle input from multiple sources. The following example will wait for input from the user and an explicitly opened second terminal. On return, _I_n_p_u_t_s may hold user or _P_4 or both. ?- open('/dev/ttyp4', read, P4), wait_for_input([user, P4], Inputs, 0). cchhaarraacctteerr__ccoouunntt((_+_S_t_r_e_a_m_, _-_C_o_u_n_t)) Unify _C_o_u_n_t with the current character index. For input streams this is the number of characters read since the open, for output streams this is the number of characters written. Counting starts at 0. lliinnee__ccoouunntt((_+_S_t_r_e_a_m_, _-_C_o_u_n_t)) Unify _C_o_u_n_t with the number of lines read or written. Counting starts at 1. lliinnee__ppoossiittiioonn((_+_S_t_r_e_a_m_, _-_C_o_u_n_t)) Unify _C_o_u_n_t with the position on the current line. Note that this assumes the position is 0 after the open. Tabs are assumed to be defined on each 8-th character and backspaces are assumed to reduce the count by one, provided it is positive. ffiilleeeerrrroorrss((_-_O_l_d_, _+_N_e_w)) Define error behaviour on errors when opening a file for reading or writing. Valid values are the atoms on (default) and off. First _O_l_d is unified with the current value. Then the new value is set to _N_e_w. 33..1166 PPrriimmiittiivvee CChhaarraacctteerr IInnppuutt aanndd OOuuttppuutt nnll Write a newline character to the current output stream. On Unix systems nnll//00 is equivalent to put(10). nnll((_+_S_t_r_e_a_m)) Write a newline to _S_t_r_e_a_m. ppuutt((_+_C_h_a_r)) Write _C_h_a_r to the current output stream, _C_h_a_r is either an integer-expression evaluating to an ASCII value (0 _C_h_a_r 255) or an atom of one character. ppuutt((_+_S_t_r_e_a_m_, _+_C_h_a_r)) Write _C_h_a_r to _S_t_r_e_a_m. ttaabb((_+_A_m_o_u_n_t)) Writes _A_m_o_u_n_t spaces on the current output stream. _A_m_o_u_n_t should be an expression that evaluates to a positive integer (see section 3.22). ttaabb((_+_S_t_r_e_a_m_, _+_A_m_o_u_n_t)) Writes _A_m_o_u_n_t spaces to _S_t_r_e_a_m. fflluusshh Flush pending output on current output stream. fflluusshh//00 is automatically generated by rreeaadd//11 and derivatives if the current input stream is user and the cursor is not at the left margin. fflluusshh__oouuttppuutt((_+_S_t_r_e_a_m)) Flush output on the specified stream. The stream must be open for writing. ttttyyfflluusshh Flush pending output on stream _u_s_e_r. See also fflluusshh//00. ggeett00((_-_C_h_a_r)) Read the current input stream and unify the next character with _C_h_a_r. _C_h_a_r is unified with -1 on end of file. ggeett00((_+_S_t_r_e_a_m_, _-_C_h_a_r)) Read the next character from _S_t_r_e_a_m. ggeett((_-_C_h_a_r)) Read the current input stream and unify the next non-blank character with _C_h_a_r. _C_h_a_r is unified with -1 on end of file. ggeett((_+_S_t_r_e_a_m_, _-_C_h_a_r)) Read the next non-blank character from _S_t_r_e_a_m. ppeeeekk__bbyyttee((_-_C_h_a_r)) Reads the next input character like ggeett00//11, but does not remove it from the input stream. This predicate is ISO compliant. ppeeeekk__bbyyttee((_+_S_t_r_e_a_m_, _-_C_h_a_r)) Reads the next input character like ggeett00//22, but does not remove it from the stream. This predicate is ISO compliant. sskkiipp((_+_C_h_a_r)) Read the input until _C_h_a_r or the end of the file is encountered. A subsequent call to ggeett00//11 will read the first character after _C_h_a_r. sskkiipp((_+_S_t_r_e_a_m_, _+_C_h_a_r)) Skip input (as sskkiipp//11) on _S_t_r_e_a_m. ggeett__ssiinnggllee__cchhaarr((_-_C_h_a_r)) Get a single character from input stream `user' (regardless of the current input stream). Unlike ggeett00//11 this predicate does not wait for a return. The character is not echoed to the user's terminal. This predicate is meant for keyboard menu selection etc.. If SWI-Prolog was started with the -tty option this predicate reads an entire line of input and returns the first non-blank character on this line, or the ASCII code of the newline (10) if the entire line consisted of blank characters. aatt__eenndd__ooff__ssttrreeaamm Succeeds after the last character of the current input stream has been read. Also succeeds if there is no valid current input stream. aatt__eenndd__ooff__ssttrreeaamm((_+_S_t_r_e_a_m)) Succeeds after the last character of the named stream is read, or _S_t_r_e_a_m is not a valid input stream. 33..1177 TTeerrmm RReeaaddiinngg aanndd WWrriittiinngg This section describes the basic term reading and writing predicates. The predicates tteerrmm__ttoo__aattoomm//22 and aattoomm__ttoo__tteerrmm//33 provide means for translating atoms and strings to terms. The predicates ffoorrmmaatt//[[11,,22]] and wwrriitteeff//22 provide formatted output. There are two ways to manipulate the output format. The predicate pprriinntt//[[11,,22]] may be programmed using ppoorrttrraayy//11. The format of floating point numbers may be manipulated using the feature (see ffeeaattuurree//22) float_format. Reading is sensitive to the feature character_escapes, which controls the interpretation of the \ character in quoted atoms and strings. wwrriittee__tteerrmm((_+_T_e_r_m_, _+_O_p_t_i_o_n_s)) The predicate wwrriittee__tteerrmm//22 is the generic form of all Prolog term-write predicates. Valid options are: qquuootteedd((true _o_r false)) If true, atoms and functors that needs quotes will be quoted. The default is false. iiggnnoorree__ooppss((true _o_r false)) If true, the generic term-representation (<_f_u_n_c_t_o_r>(<_a_r_g_s> ...)) will be used for all terms, Otherwise (default), operators, list-notation and {}/1 will be written using their special syntax. nnuummbbeerrvvaarrss((true _o_r false)) If true, terms of the format $VAR(N), where <_N> is a positive integer, will be written as a variable name. The default is false. ppoorrttrraayy((true _o_r false)) If true, the hook ppoorrttrraayy//11 is called before printing a term that is not a variable. If ppoorrttrraayy//11 succeeds, the term is considered printed. See also pprriinntt//11. The default is false. This option is an extension to the ISO write_term options. wwrriittee__tteerrmm((_+_S_t_r_e_a_m_, _+_T_e_r_m_, _+_O_p_t_i_o_n_s)) As wwrriittee__tteerrmm//22, but output is sent to _S_t_r_e_a_m rather than the current output. wwrriittee__ccaannoonniiccaall((_+_T_e_r_m)) Write _T_e_r_m on the current output stream using standard parenthe- sised prefix notation (i.e. ignoring operator declarations). Atoms that need quotes are quoted. Terms written with this predicate can always be read back, regardless of current operator declarations. Equivalent to wwrriittee__tteerrmm//22 using the options ignore_ops and quoted. wwrriittee__ccaannoonniiccaall((_+_S_t_r_e_a_m_, _+_T_e_r_m)) Write _T_e_r_m in canonical form on _S_t_r_e_a_m. wwrriittee((_+_T_e_r_m)) Write _T_e_r_m to the current output, using brackets and operators where appropriate. See ffeeaattuurree//22 for controlling floating point output format. wwrriittee((_+_S_t_r_e_a_m_, _+_T_e_r_m)) Write _T_e_r_m to _S_t_r_e_a_m. wwrriitteeqq((_+_T_e_r_m)) Write _T_e_r_m to the current output, using brackets and operators where appropriate. Atoms that need quotes are quoted. Terms written with this predicate can be read back with rreeaadd//11 provided the currently active operator declarations are identical. wwrriitteeqq((_+_S_t_r_e_a_m_, _+_T_e_r_m)) Write _T_e_r_m to _S_t_r_e_a_m, inserting quotes. pprriinntt((_+_T_e_r_m)) Prints _T_e_r_m on the current output stream similar to wwrriittee//11, but for each (sub)term of _T_e_r_m first the dynamic predicate ppoorrttrraayy//11 is called. If this predicate succeeds _p_r_i_n_t assumes the (sub)term has been written. This allows for user defined term writing. pprriinntt((_+_S_t_r_e_a_m_, _+_T_e_r_m)) Print _T_e_r_m to _S_t_r_e_a_m. ppoorrttrraayy((_+_T_e_r_m)) A dynamic predicate, which can be defined by the user to change the behaviour of pprriinntt//11 on (sub)terms. For each subterm encountered that is not a variable pprriinntt//11 first calls ppoorrttrraayy//11 using the term as argument. For lists only the list as a whole is given to ppoorrttrraayy//11. If portray succeeds pprriinntt//11 assumes the term has been written. rreeaadd((_-_T_e_r_m)) Read the next Prolog term from the current input stream and unify it with _T_e_r_m. On a syntax error rreeaadd//11 displays an error message, attempts to skip the erroneous term and fails. On reaching end-of-file _T_e_r_m is unified with the atom end_of_file. rreeaadd((_+_S_t_r_e_a_m_, _-_T_e_r_m)) Read _T_e_r_m from _S_t_r_e_a_m. rreeaadd__ccllaauussee((_-_T_e_r_m)) Equivalent to rreeaadd//11, 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 ccoonnssuulltt//11). New code should use rreeaadd__tteerrmm//22 with the option singletons(warning). rreeaadd__ccllaauussee((_+_S_t_r_e_a_m_, _-_T_e_r_m)) Read a clause from _S_t_r_e_a_m. See rreeaadd__ccllaauussee//11. rreeaadd__vvaarriiaabblleess((_-_T_e_r_m_, _-_B_i_n_d_i_n_g_s)) Similar to rreeaadd//11, but _B_i_n_d_i_n_g_s is unified with a list of `_N_a_m_e = _V_a_r' tuples, thus providing access to the actual variable names. New code should use rreeaadd__tteerrmm//22 using the option variables(X). rreeaadd__vvaarriiaabblleess((_+_S_t_r_e_a_m_, _-_T_e_r_m_, _-_B_i_n_d_i_n_g_s)) Read, returning term and bindings from _S_t_r_e_a_m. See rreeaadd__vvaarriiaabblleess//22. rreeaadd__tteerrmm((_-_T_e_r_m_, _+_O_p_t_i_o_n_s)) Read a term from the current input stream and unify the term with _T_e_r_m. The reading is controlled by options from the list of _O_p_t_i_o_n_s. If this list is empty, the behaviour is the same as for rreeaadd//11. The options are upward compatible to Quintus Prolog. The argument order is according to the ISO standard. Options: ssyynnttaaxx__eerrrroorrss((_a_t_o_m _o_r _v_a_r_i_a_b_l_e)) Define the behaviour for when a syntax error occurs. The possible values are: ffaaiill Default behaviour. The error is reported as a warning and the predicate fails. qquuiieett Quietly fails if a syntax error has occurred. VVaarriiaabbllee If no error occurs, the variable is unified with none, otherwise _V_a_r_i_a_b_l_e is unified with a term of the form '$stream_position'(CharNo, LineNo, LinePos):Message This behaviour is a SWI-Prolog extension. vvaarriiaabbllee__nnaammeess((_V_a_r_s)) Unify _V_a_r_s with a list of `_N_a_m_e = _V_a_r', where _N_a_m_e is an atom describing the variable name and _V_a_r is a variable that shares with the corresponding variable in _T_e_r_m. ssiinngglleettoonnss((_V_a_r_s)) As variable_names, but only reports the variables occurring only once in the _T_e_r_m read. Variables starting with an underscore (`_') are not included in this list. tteerrmm__ppoossiittiioonn((_P_o_s)) Unifies _P_o_s with the starting position of the term read. _P_o_s if of the same format as use by ssttrreeaamm__ppoossiittiioonn//33. ssuubbtteerrmm__ppoossiittiioonnss((_T_e_r_m_P_o_s)) Describes the detailed layout of the term. The formats for the various types of terms if given below. All positions are character positions. If the input is related to a normal stream, these positions are relative to the start of the input, when reading from the terminal, they are relative to the start of the term. FFrroomm--TToo Used for primitive types (atoms, numbers, variables). ssttrriinngg__ppoossiittiioonn((_F_r_o_m_, _T_o)) Used to indicate the position of a string enclosed in double quotes ("). bbrraaccee__tteerrmm__ppoossiittiioonn((_F_r_o_m_, _T_o_, _A_r_g)) Term of the form {...}, as used in DCG rules. _A_r_g describes the argument. lliisstt__ppoossiittiioonn((_F_r_o_m_, _T_o_, _E_l_m_s_, _T_a_i_l)) A list. _E_l_m_s describes the positions of the elements. If the list specifies the tail as |<_T_a_i_l_T_e_r_m>, _T_a_i_l is unified with the term-position of the tail, otherwise with the atom none. tteerrmm__ppoossiittiioonn((_F_r_o_m_, _T_o_, _F_F_r_o_m_, _F_T_o_, _S_u_b_P_o_s)) Used for a compound term not matching one of the above. _F_F_r_o_m and _F_T_o describe the position of the functor. _S_u_b_P_o_s is a list, each element of which describes the term-position of the corresponding subterm. rreeaadd__tteerrmm((_+_S_t_r_e_a_m_, _-_T_e_r_m_, _+_O_p_t_i_o_n_s)) Read term with options from _S_t_r_e_a_m. See rreeaadd__tteerrmm//22. rreeaadd__hhiissttoorryy((_+_S_h_o_w_, _+_H_e_l_p_, _+_S_p_e_c_i_a_l_, _+_P_r_o_m_p_t_, _-_T_e_r_m_, _-_B_i_n_d_i_n_g_s)) Similar to rreeaadd__vvaarriiaabblleess//22, but allows for history substitutions. rreeaadd__hhiissttoorryy//66 is used by the top level to read the user's actions. _S_h_o_w is the command the user should type to show the saved events. _H_e_l_p is the command to get an overview of the capabilities. _S_p_e_c_i_a_l is a list of commands that are not saved in the history. _P_r_o_m_p_t is the first prompt given. Continuation prompts for more lines are determined by pprroommpptt//22. A %w in the prompt is substituted by the event number. See section 2.4 for available substitutions. SWI-Prolog calls rreeaadd__hhiissttoorryy//66 as follows: read_history(h, '!h', [trace], '%w ?- ', Goal, Bindings) pprroommpptt((_-_O_l_d_, _+_N_e_w)) Set prompt associated with rreeaadd//11 and its derivatives. _O_l_d is first unified with the current prompt. On success the prompt will be set to _N_e_w if this is an atom. Otherwise an error message is displayed. A prompt is printed if one of the read predicates is called and the cursor is at the left margin. It is also printed whenever a newline is given and the term has not been terminated. Prompts are only printed when the current input stream is _u_s_e_r. pprroommpptt11((_+_P_r_o_m_p_t)) Sets the prompt for the next line to be read. Continuation lines will be read using the prompt defined by pprroommpptt//22. 33..1188 AAnnaallyyssiinngg aanndd CCoonnssttrruuccttiinngg TTeerrmmss ffuunnccttoorr((_?_T_e_r_m_, _?_F_u_n_c_t_o_r_, _?_A_r_i_t_y)) Succeeds if _T_e_r_m is a term with functor _F_u_n_c_t_o_r and arity _A_r_i_t_y. If _T_e_r_m is a variable it is unified with a new term holding only variables. ffuunnccttoorr//33 silently fails on instantiation faults If _T_e_r_m is an atom or number, _F_u_n_c_t_o_r will be unified with _T_e_r_m and arity will be unified with the integer 0 (zero). aarrgg((_?_A_r_g_, _?_T_e_r_m_, _?_V_a_l_u_e)) _T_e_r_m should be instantiated to a term, _A_r_g to an integer between 1 and the arity of _T_e_r_m. _V_a_l_u_e is unified with the _A_r_g-th argument of _T_e_r_m. _A_r_g may also be unbound. In this case _V_a_l_u_e will be unified with the successive arguments of the term. On successful unification, _A_r_g is unified with the argument number. Backtracking yields alternative solutions. The predicate aarrgg//33 fails silently if _A_r_g= 0 or _A_r_g > _a_r_i_t_y and raises the exception domain_error(not_less_then_zero, Arg)if _A_r_g <0. sseettaarrgg((_+_A_r_g_, _+_T_e_r_m_, _+_V_a_l_u_e)) Extra-logical predicate. Assigns the _A_r_g-th argument of the compound term _T_e_r_m with the given _V_a_l_u_e. The assignment is undone if backtracking brings the state back into a position before the sseettaarrgg//33 call. This predicate may be used for destructive assignment to terms, using them as and extra-logical storage bin. _?_T_e_r_m =.. _?_L_i_s_t _L_i_s_t is a list which head is the functor of _T_e_r_m and the remaining arguments are the arguments of the term. Each of the arguments may be a variable, but not both. This predicate is called `Univ'. Examples: ?- foo(hello, X) =.. List. List = [foo, hello, X] ?- Term =.. [baz, foo(1)] Term = baz(foo(1)) nnuummbbeerrvvaarrss((_+_T_e_r_m_, _+_F_u_n_c_t_o_r_, _+_S_t_a_r_t_, _-_E_n_d)) Unify the free variables of _T_e_r_m with a term constructed from the atom _F_u_n_c_t_o_r with one argument. The argument is the number of the variable. Counting starts at _S_t_a_r_t. _E_n_d is unified with the number that should be given to the next variable. Example: ?- numbervars(foo(A, B, A), this_is_a_variable, 0, End). A = this_is_a_variable(0) B = this_is_a_variable(1) End = 2 In Edinburgh Prolog the second argument is missing. It is fixed to be $VAR. ffrreeee__vvaarriiaabblleess((_+_T_e_r_m_, _-_L_i_s_t)) Unify _L_i_s_t with a list of variables, each sharing with a unique variable of _T_e_r_m. For example: ?- free_variables(a(X, b(Y, X), Z), L). L = [G367, G366, G371] X = G367 Y = G366 Z = G371 ccooppyy__tteerrmm((_+_I_n_, _-_O_u_t)) Make a copy of term _I_n and unify the result with _O_u_t. Ground parts of _I_n are shared by _O_u_t. Provided _I_n and _O_u_t have no sharing variables before this call they will have no sharing variables afterwards. ccooppyy__tteerrmm//22 is semantically equivalent to: copy_term(In, Out) :- recorda(copy_key, In, Ref), recorded(copy_key, Out, Ref), erase(Ref). 33..1199 AAnnaallyyssiinngg aanndd CCoonnssttrruuccttiinngg AAttoommss These predicates convert between Prolog constants and lists of ASCII values. The predicates aattoomm__cchhaarrss//22, nnuummbbeerr__cchhaarrss//22 and nnaammee//22 behave the same when converting from a constant to a list of ASCII values. When converting the other way around, aattoomm__cchhaarrss//22 will generate an atom, number_chars will generate a number or fail and nnaammee//22 will return a number if possible and an atom otherwise. aattoomm__cchhaarrss((_?_A_t_o_m_, _?_S_t_r_i_n_g)) Convert between an atom and a list of ASCII values. If _A_t_o_m is instantiated, if will be translated into a list of ASCII values and the result is unified with _S_t_r_i_n_g. If _A_t_o_m is unbound and _S_t_r_i_n_g is a list of ASCII values, it will _A_t_o_m will be unified with an atom constructed from this list. aattoomm__cchhaarr((_?_A_t_o_m_, _?_A_S_C_I_I)) Convert between character and ASCII value for a single character. nnuummbbeerr__cchhaarrss((_?_N_u_m_b_e_r_, _?_S_t_r_i_n_g)) Similar to aattoomm__cchhaarrss//22, but converts between a number and its representation as a list of ASCII values. Fails silently if _N_u_m_b_e_r is unbound and _S_t_r_i_n_g does not describe a number. nnaammee((_?_A_t_o_m_O_r_I_n_t_, _?_S_t_r_i_n_g)) _S_t_r_i_n_g is a list of ASCII values describing _A_t_o_m. Each of the arguments may be a variable, but not both. When _S_t_r_i_n_g is bound to an ASCII value list describing an integer and _A_t_o_m is a variable _A_t_o_m will be unified with the integer value described by _S_t_r_i_n_g (e.g. `name(N, "300"), 400 is N + 100' succeeds). iinntt__ttoo__aattoomm((_+_I_n_t_, _+_B_a_s_e_, _-_A_t_o_m)) Convert _I_n_t to an ascii representation using base _B_a_s_e and unify the result with _A_t_o_m. If _B_a_s_e 6=10 the base will be prepended to _A_t_o_m. _B_a_s_e= 0 will try to interpret _I_n_t as an ASCII value and return 0'<_c>. Otherwise 2 _B_a_s_e 36. Some examples are given below. int_to_atom(45, 2, A) -! A= 20101101 int_to_atom(97, 0, A) -! A= 00a int_to_atom(56, 10, A) -! A= 56 iinntt__ttoo__aattoomm((_+_I_n_t_, _-_A_t_o_m)) Equivalent to int_to_atom(Int, 10, Atom). tteerrmm__ttoo__aattoomm((_?_T_e_r_m_, _?_A_t_o_m)) Succeeds if _A_t_o_m describes a term that unifies with _T_e_r_m. When _A_t_o_m is instantiated _A_t_o_m is converted and then unified with _T_e_r_m. Otherwise _T_e_r_m is ``written'' on _A_t_o_m using wwrriittee//11. aattoomm__ttoo__tteerrmm((_+_A_t_o_m_, _-_T_e_r_m_, _-_B_i_n_d_i_n_g_s)) Use _A_t_o_m as input to rreeaadd__vvaarriiaabblleess//22and return the read term in _T_e_r_m and the variable bindings in _B_i_n_d_i_n_g_s. _B_i_n_d_i_n_g_s is a list of _N_a_m_e = _V_a_r couples, thus providing access to the actual variable names. See also rreeaadd__vvaarriiaabblleess//22. ccoonnccaatt((_?_A_t_o_m_1_, _?_A_t_o_m_2_, _?_A_t_o_m_3)) _A_t_o_m_3 forms the concatenation of _A_t_o_m_1 and _A_t_o_m_2. At least two of the arguments must be instantiated to atoms, integers or floating point numbers. ccoonnccaatt__aattoomm((_+_L_i_s_t_, _-_A_t_o_m)) _L_i_s_t is a list of atoms, integers or floating point numbers. Succeeds if _A_t_o_m can be unified with the concatenated elements of _L_i_s_t. If _L_i_s_t has exactly 2 elements it is equivalent to ccoonnccaatt//33, allowing for variables in the list. ccoonnccaatt__aattoomm((_+_L_i_s_t_, _+_S_e_p_a_r_a_t_o_r_, _-_A_t_o_m)) Creates an atom just like ccoonnccaatt__aattoomm//22, but inserts _S_e_p_a_r_a_t_o_r between each pair of atoms. For example: ?- concat_atom([gnu, gnat], ', ', A). A = 'gnu, gnat' aattoomm__lleennggtthh((_+_A_t_o_m_, _-_L_e_n_g_t_h)) Succeeds if _A_t_o_m is an atom of _L_e_n_g_t_h characters long. This predicate also works for integers and floats, expressing the number of characters output when given to wwrriittee//11. aattoomm__pprreeffiixx((_+_A_t_o_m_, _+_P_r_e_f_i_x)) Succeeds if _A_t_o_m starts with the characters from _P_r_e_f_i_x. Its behaviour is equivalent to ?- concat(Prefix, _, Atom), but avoids the construction of an atom for the `remainder'. 33..2200 RReepprreesseennttiinngg TTeexxtt iinn SSttrriinnggss SWI-Prolog supports the data type _s_t_r_i_n_g. Strings are a time and space efficient mechanism to handle text in Prolog. Atoms are under some circumstances not suitable because garbage collection on them is next to impossible (Although it is possible: BIM_prolog does it). Representing text as a list of ASCII values is, from the logical point of view, the cleanest solution. It however has two drawbacks: 1) they cannot be distinguished from a list of (small) integers; and 2) they consume (in SWI-Prolog) 12 bytes for each character stored. Within strings each character only requires 1 byte storage. Strings live on the global stack and their storage is thus reclaimed on backtracking. Garbage collection can easily deal with strings. The ISO standard proposes " ..." is transformed into a string object by rreeaadd//11 and derivatives. This poses problems as in the old convention " ..." is transformed into a list of ascii characters. For this reason the style check option `string' is available (see ssttyyllee__cchheecckk//11). 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. ssttrriinngg__ttoo__aattoomm((_?_S_t_r_i_n_g_, _?_A_t_o_m)) Logical conversion between a string and an atom. At least one of the two arguments must be instantiated. _A_t_o_m can also be an integer or floating point number. ssttrriinngg__ttoo__lliisstt((_?_S_t_r_i_n_g_, _?_L_i_s_t)) Logical conversion between a string and a list of ASCII characters. At least one of the two arguments must be instantiated. ssttrriinngg__lleennggtthh((_+_S_t_r_i_n_g_, _-_L_e_n_g_t_h)) Unify _L_e_n_g_t_h with the number of characters in _S_t_r_i_n_g. This predicate is functionally equivalent to aattoomm__lleennggtthh//22 and also accepts atoms, integers and floats as its first argument. ssttrriinngg__ccoonnccaatt((_?_S_t_r_i_n_g_1_, _?_S_t_r_i_n_g_2_, _?_S_t_r_i_n_g_3)) Similar to ccoonnccaatt//33, but the unbound argument will be unified with a string object rather than an atom. Also, if both _S_t_r_i_n_g_1 and _S_t_r_i_n_g_2 are unbound and _S_t_r_i_n_g_3 is bound to text, it breaks _S_t_r_i_n_g_3, unifying the start with _S_t_r_i_n_g_1 and the end with _S_t_r_i_n_g_2 as append does with lists. Note that this is not particularly fast on long strings as for each redo the system has to create two entirely new strings, while the list equivalent only creates a single new list-cell and moves some pointers around. ssuubbssttrriinngg((_+_S_t_r_i_n_g_, _+_S_t_a_r_t_, _+_L_e_n_g_t_h_, _-_S_u_b)) Create a substring of _S_t_r_i_n_g that starts at character _S_t_a_r_t (1 base) and has _L_e_n_g_t_h characters. Unify this substring with _S_u_b. 33..2211 OOppeerraattoorrss oopp((_+_P_r_e_c_e_d_e_n_c_e_, _+_T_y_p_e_, _+_N_a_m_e)) Declare _N_a_m_e to be an operator of type _T_y_p_e with precedence _P_r_e_c_e_d_e_n_c_e. _N_a_m_e can also be a list of names, in which case all elements of the list are declared to be identical operators. _P_r_e_c_e_d_e_n_c_e is an integer between 0 and 1200. Precedence 0 removes the declaration. _T_y_p_e is one of: xf, yf, xfx, xfy, yfx, yfy, fy or fx. The `f' indicates the position of the functor, while x and y indicate the position of the arguments. `y' should be interpreted as ``on this position a term with precedence lower or equal to the precedence of the functor should occur''. For `x' the precedence of the argument must be strictly lower. The precedence of a term is 0, unless its principal functor is an operator, in which case the precedence is the precedence of this operator. A term enclosed in brackets (...) has precedence 0. The predefined operators are shown in table 3.1. Note that all operators can be redefined by the user. ______________________________________________________________ | 1200 |xfx |-->, :- | | 1200 | fx |:-, ?- | | 1150 | fx |dynamic, multifile, module_transparent, discon-| | | |tiguous, volatile, initialization | | 1100 |xfy |;, | | | 1050 |xfy |-> | | 1000 |xfy |, | | 954 |xfy |\ | | 900 | fy |\+, not | | 900 | fx |~ | | 700 |xfx |<, =, =.., =@=, =:=, =<, ==, =\=, >, >=, @<, | | | |@=<, @>, @>=, \=, \==, is | | 600 |xfy |: | | 500 | yfx |+, -, /\, \/, xor | | 500 | fx |+, -, ?, \ | | 400 | yfx |*, /, //, <<, >>, mod, rem | | 200 |xfx |** | |__200_|xfy__|^______________________________________________|_ Table 3.1: System operators ccuurrrreenntt__oopp((_?_P_r_e_c_e_d_e_n_c_e_, _?_T_y_p_e_, _?_N_a_m_e)) Succeeds when _N_a_m_e is currently defined as an operator of type _T_y_p_e with precedence _P_r_e_c_e_d_e_n_c_e. See also oopp//33. 33..2222 AArriitthhmmeettiicc Arithmetic can be divided into some special purpose integer predicates and a series of general predicates for floating point and integer arithmetic as appropriate. The integer predicates are as ``logical'' as possible. Their usage is recommended whenever applicable, resulting in faster and more ``logical'' programs. The general arithmetic predicates are optionally compiled now (see pplleeaassee//33 and the -O command line option). Compiled arithmetic reduces global stack requirements and improves performance. Unfortunately compiled arithmetic cannot be traced, which is why it is optional. The general arithmetic predicates all handle _e_x_p_r_e_s_s_i_o_n_s. An expression is either a simple number or a _f_u_n_c_t_i_o_n. The arguments of a function are expressions. The functions are described in section 3.23. bbeettwweeeenn((_+_L_o_w_, _+_H_i_g_h_, _?_V_a_l_u_e)) _L_o_w and _H_i_g_h are integers, _H_i_g_h _L_o_w. If _V_a_l_u_e is an integer, _L_o_w _V_a_l_u_e _H_i_g_h. When _V_a_l_u_e is a variable it is successively bound to all integers between _L_o_w and _H_i_g_h. ssuucccc((_?_I_n_t_1_, _?_I_n_t_2)) Succeeds if _I_n_t_2= _I_n_t_1+ 1. At least one of the arguments must be instantiated to an integer. pplluuss((_?_I_n_t_1_, _?_I_n_t_2_, _?_I_n_t_3)) Succeeds if _I_n_t_3= _I_n_t_1+_I_n_t_2. At least two of the three arguments must be instantiated to integers. _+_E_x_p_r_1 > _+_E_x_p_r_2 Succeeds when expression _E_x_p_r_1 evaluates to a larger number than _E_x_p_r_2. _+_E_x_p_r_1 < _+_E_x_p_r_2 Succeeds when expression _E_x_p_r_1 evaluates to a smaller number than _E_x_p_r_2. _+_E_x_p_r_1 =< _+_E_x_p_r_2 Succeeds when expression _E_x_p_r_1 evaluates to a smaller or equal number to _E_x_p_r_2. _+_E_x_p_r_1 >= _+_E_x_p_r_2 Succeeds when expression _E_x_p_r_1 evaluates to a larger or equal number to _E_x_p_r_2. _+_E_x_p_r_1 =\= _+_E_x_p_r_2 Succeeds when expression _E_x_p_r_1 evaluates to a number non-equal to _E_x_p_r_2. _+_E_x_p_r_1 =:= _+_E_x_p_r_2 Succeeds when expression _E_x_p_r_1 evaluates to a number equal to _E_x_p_r_2. _-_N_u_m_b_e_r iiss _+_E_x_p_r Succeeds when _N_u_m_b_e_r has successfully been unified with the number _E_x_p_r evaluates to. If _E_x_p_r evaluates to a float that can be represented using an integer (i.e. the value is integer and within the range that can be described by Prolog's integer representation), _E_x_p_r is unified with the integer value. Note that normally, iiss//22 will be used with unbound left operand. If equality is to be tested, =:=/2 should be used. For example: ?- 1.0 is sin(pi/2). Fails!. sin(pi/2) evaluates to 1.0, but iiss//22 will represent this as the integer 1, after which unify will fail. ?- 1.0 is float(sin(pi/2)). Succeeds, as the ffllooaatt//11 function forces the result to be float. ?- 1.0 =:= sin(pi/2). Succeeds as expected. 33..2233 AArriitthhmmeettiicc FFuunnccttiioonnss Arithmetic functions are terms which are evaluated by the arithmetic predicates described above. SWI-Prolog tries to hide the difference between integer arithmetic and floating point arithmetic from the Prolog user. Arithmetic is done as integer arithmetic as long as possible and converted to floating point arithmetic whenever one of the arguments or the combination of them requires it. If a function returns a floating point value which is whole it is automatically transformed into an integer. There are three types of arguments to functions: _E_x_p_r Arbitrary expression, returning either a floating point value or an integer. _I_n_t_E_x_p_r Arbitrary expression that should evaluate into an integer. _I_n_t An integer. In case integer addition, subtraction and multiplication would lead to an integer overflow the operands are automatically converted to floating point numbers. The floating point functions (ssiinn//11, eexxpp//11, etc.) form a direct interface to the corresponding C library functions used to compile SWI-Prolog. Please refer to the C library documentation for details on precision, error handling, etc. - _+_E_x_p_r _R_e_s_u_l_t =-_E_x_p_r _+_E_x_p_r_1 + _+_E_x_p_r_2 _R_e_s_u_l_t =_E_x_p_r_1 +_E_x_p_r_2 _+_E_x_p_r_1 - _+_E_x_p_r_2 _R_e_s_u_l_t =_E_x_p_r_1 -_E_x_p_r_2 _+_E_x_p_r_1 * _+_E_x_p_r_2 _R_e_s_u_l_t =_E_x_p_r_1_*Expr2 _+_E_x_p_r_1 / _+_E_x_p_r_2 _R_e_s_u_l_t =_E_x_p_r_1=_E_x_p_r_2 _+_I_n_t_E_x_p_r_1 mmoodd _+_I_n_t_E_x_p_r_2 _R_e_s_u_l_t =_E_x_p_r_1mod_E_x_p_r_2 (remainder of division). _+_I_n_t_E_x_p_r_1 rreemm _+_I_n_t_E_x_p_r_2 _R_e_s_u_l_t =_E_x_p_r_1rem_E_x_p_r_2 (remainder of division). _+_I_n_t_E_x_p_r_1 // _+_I_n_t_E_x_p_r_2 _R_e_s_u_l_t =_E_x_p_r_1 _E_x_p_r_2 (integer division). aabbss((_+_E_x_p_r)) Evaluate _E_x_p_r and return the absolute value of it. ssiiggnn((_+_E_x_p_r)) Evaluate to -1 if _E_x_p_r <0, 1 if _E_x_p_r >0 and 0 if _E_x_p_r =0. mmaaxx((_+_E_x_p_r_1_, _+_E_x_p_r_2)) Evaluates to the largest of both _E_x_p_r_1 and _E_x_p_r_2. mmiinn((_+_E_x_p_r_1_, _+_E_x_p_r_2)) Evaluates to the smallest of both _E_x_p_r_1 and _E_x_p_r_2. .((_+_I_n_t_, _[_])) A list of one element evaluates to the element. This implies "a" evaluates to the ASCII value of the letter `a' (97). This option is available for compatibility only. It will not work if `style_check(+string)' is active as "a" will then be transformed into a string object. The recommended way to specify the ASCII value of the letter `a' is 0'a. rraannddoomm((_+_I_n_t)) Evaluates to a random integer _i for which 0 i< _I_n_t. The seed of this random generator is determined by the system clock when SWI-Prolog was started. rroouunndd((_+_E_x_p_r)) Evaluates _E_x_p_r and rounds the result to the nearest integer. iinntteeggeerr((_+_E_x_p_r)) Same as rroouunndd//11 (backward compatibility). ffllooaatt((_+_E_x_p_r)) Translate the result to a floating point number. Normally, Prolog will use integers whenever possible. When used around the 2nd argument of iiss//22, the result will be returned as a floating point number. In other contexts, the operation has no effect. ffllooaatt__ffrraaccttiioonnaall__ppaarrtt((_+_E_x_p_r)) Fractional part of a floating-point number. Negative if _E_x_p_r is negative, 0 if _E_x_p_r is integer. ffllooaatt__iinntteeggeerr__ppaarrtt((_+_E_x_p_r)) Integer part of floating-point number. Negative if _E_x_p_r is negative, _E_x_p_r if _E_x_p_r is integer. ttrruunnccaattee((_+_E_x_p_r)) Truncate _E_x_p_r to an integer. Same as ffllooaatt__iinntteeggeerr__ppaarrtt//11. fflloooorr((_+_E_x_p_r)) Evaluates _E_x_p_r and returns the largest integer smaller or equal to the result of the evaluation. cceeiilliinngg((_+_E_x_p_r)) Evaluates _E_x_p_r and returns the smallest integer larger or equal to the result of the evaluation. cceeiill((_+_E_x_p_r)) Same as cceeiilliinngg//11 (backward compatibility). _+_I_n_t_E_x_p_r >> _+_I_n_t_E_x_p_r Bitwise shift _I_n_t_E_x_p_r_1 by _I_n_t_E_x_p_r_2 bits to the right. _+_I_n_t_E_x_p_r << _+_I_n_t_E_x_p_r Bitwise shift _I_n_t_E_x_p_r_1 by _I_n_t_E_x_p_r_2 bits to the left. _+_I_n_t_E_x_p_r \/ _+_I_n_t_E_x_p_r Bitwise `or' _I_n_t_E_x_p_r_1 and _I_n_t_E_x_p_r_2. _+_I_n_t_E_x_p_r /\ _+_I_n_t_E_x_p_r Bitwise `and' _I_n_t_E_x_p_r_1 and _I_n_t_E_x_p_r_2. _+_I_n_t_E_x_p_r xxoorr _+_I_n_t_E_x_p_r Bitwise `exclusive or' _I_n_t_E_x_p_r_1 and _I_n_t_E_x_p_r_2. \ _+_I_n_t_E_x_p_r Bitwise negation. ssqqrrtt((_+_E_x_p_r)) _R_e_s_u_l_t =square root of _E_x_p_r ssiinn((_+_E_x_p_r)) _R_e_s_u_l_t =sine of _E_x_p_r. _E_x_p_r is the angle in radians. ccooss((_+_E_x_p_r)) _R_e_s_u_l_t =cosine of _E_x_p_r. _E_x_p_r is the angle in radians. ttaann((_+_E_x_p_r)) _R_e_s_u_l_t =tangus of _E_x_p_r. _E_x_p_r is the angle in radians. aassiinn((_+_E_x_p_r)) _R_e_s_u_l_t =inverse sine of _E_x_p_r. _R_e_s_u_l_t is the angle in radians. aaccooss((_+_E_x_p_r)) _R_e_s_u_l_t =inverse cosine of _E_x_p_r. _R_e_s_u_l_t is the angle in radians. aattaann((_+_E_x_p_r)) _R_e_s_u_l_t =inverse tangus of _E_x_p_r. _R_e_s_u_l_t is the angle in radians. aattaann((_+_Y_E_x_p_r_, _+_X_E_x_p_r)) _R_e_s_u_l_t = inverse tangus of _Y_E_x_p_r / _X_E_x_p_r. _R_e_s_u_l_t is the angle in radians. The return value is in the range [-pi:::pi]. Used to convert between rectangular and polar coordinate system. lloogg((_+_E_x_p_r)) _R_e_s_u_l_t =natural logarithm of _E_x_p_r lloogg1100((_+_E_x_p_r)) _R_e_s_u_l_t =10 base logarithm of _E_x_p_r eexxpp((_+_E_x_p_r)) _R_e_s_u_l_t =e to the power _E_x_p_r _+_E_x_p_r_1 ** _+_E_x_p_r_2 _R_e_s_u_l_t =_E_x_p_r_1 to the power _E_x_p_r_2 _+_E_x_p_r_1 ^ _+_E_x_p_r_2 Same as **/2. (backward compatibility). ppii Evaluates to the mathematical constant pi (3.141593). ee Evaluates to the mathematical constant e (2.718282). ccppuuttiimmee Evaluates to a floating point number expressing the cpu time (in seconds) used by Prolog up till now. See also ssttaattiissttiiccss//22 and ttiimmee//11. 33..2244 AAddddiinngg AArriitthhmmeettiicc FFuunnccttiioonnss 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 aarriitthhmmeettiicc__ffuunnccttiioonn//11, which takes the head as its argument. Arithmetic functions are module sensitive, that is they are only visible from the module in which the function is defined and declared. Global arithmetic functions should be defined and registered from module user. Global definitions can be overruled locally in modules. The builtin functions described above can be redefined as well. aarriitthhmmeettiicc__ffuunnccttiioonn((_+_H_e_a_d)) Register a Prolog predicate as an arithmetic function (see iiss//22, >//22 , etc.). The Prolog predicate should have one more argument than specified by _H_e_a_d, which it either a term _N_a_m_e_/_A_r_i_t_y, an atom or a complex term. This last argument is an unbound variable at call time and should be instantiated to an integer or floating point number. The other arguments are the parameters. This predicate is module sensitive and will declare the arithmetic function only for the context module, unless declared from module user. Example: 1 ?- [user]. :- arithmetic_function(mean/2). mean(A, B, C) :- C is (A+B)/2. user compiled, 0.07 sec, 440 bytes. Yes 2 ?- A is mean(4, 5). A = 4.500000 ccuurrrreenntt__aarriitthhmmeettiicc__ffuunnccttiioonn((_?_H_e_a_d)) Successively unifies all arithmetic functions that are visible from the context module with _H_e_a_d. 33..2255 LLiisstt MMaanniippuullaattiioonn iiss__lliisstt((_+_T_e_r_m)) Succeeds if _T_e_r_m is bound to the empty list ([]) or a term with functor `.' and arity 2. pprrooppeerr__lliisstt((_+_T_e_r_m)) Equivalent to iiss__lliisstt//11, but also requires the tail of the list to be a list (recursively). Examples: is_list([x|A]) % true proper_list([x|A]) % false aappppeenndd((_?_L_i_s_t_1_, _?_L_i_s_t_2_, _?_L_i_s_t_3)) Succeeds when _L_i_s_t_3 unifies with the concatenation of _L_i_s_t_1 and _L_i_s_t_2. The predicate can be used with any instantiation pattern (even three variables). mmeemmbbeerr((_?_E_l_e_m_, _?_L_i_s_t)) Succeeds when _E_l_e_m can be unified with one of the members of _L_i_s_t. The predicate can be used with any instantiation pattern. mmeemmbbeerrcchhkk((_?_E_l_e_m_, _+_L_i_s_t)) Equivalent to mmeemmbbeerr//22, but leaves no choice point. ddeelleettee((_+_L_i_s_t_1_, _?_E_l_e_m_, _?_L_i_s_t_2)) Delete all members of _L_i_s_t_1 that simultaneously unify with _E_l_e_m and unify the result with _L_i_s_t_2. sseelleecctt((_?_L_i_s_t_1_, _?_E_l_e_m_, _?_L_i_s_t_2)) Select an element of _L_i_s_t_1 that unifies with _E_l_e_m. _L_i_s_t_2 is unified with the list remaining from _L_i_s_t_1 after deleting the selected element. Normally used with the instantiation pattern _+_L_i_s_t_1_, _-_E_l_e_m_, _-_L_i_s_t_2, but can also be used to insert an element in a list using _-_L_i_s_t_1_, _+_E_l_e_m_, _+_L_i_s_t_2. nntthh00((_?_I_n_d_e_x_, _?_L_i_s_t_, _?_E_l_e_m)) Succeeds when the _I_n_d_e_x-th element of _L_i_s_t unifies with _E_l_e_m. Counting starts at 0. nntthh11((_?_I_n_d_e_x_, _?_L_i_s_t_, _?_E_l_e_m)) Succeeds when the _I_n_d_e_x-th element of _L_i_s_t unifies with _E_l_e_m. Counting starts at 1. llaasstt((_?_E_l_e_m_, _?_L_i_s_t)) Succeeds if _E_l_e_m unifies with the last element of _L_i_s_t. rreevveerrssee((_+_L_i_s_t_1_, _-_L_i_s_t_2)) Reverse the order of the elements in _L_i_s_t_1 and unify the result with the elements of _L_i_s_t_2. ffllaatttteenn((_+_L_i_s_t_1_, _-_L_i_s_t_2)) Transform _L_i_s_t_1, possibly holding lists as elements into a `flat' list by replacing each list with its elements (recursively). Unify the resulting flat list with _L_i_s_t_2. Example: ?- flatten([a, [b, [c, d], e]], X). X = [a, b, c, d, e] lleennggtthh((_?_L_i_s_t_, _?_I_n_t)) Succeeds if _I_n_t represents the number of elements of list _L_i_s_t. Can be used to create a list holding only variables. mmeerrggee((_+_L_i_s_t_1_, _+_L_i_s_t_2_, _-_L_i_s_t_3)) _L_i_s_t_1 and _L_i_s_t_2 are lists, sorted to the standard order of terms (see section 3.5). _L_i_s_t_3 will be unified with an ordered list holding both the elements of _L_i_s_t_1 and _L_i_s_t_2. Duplicates are nnoott removed. 33..2266 SSeett MMaanniippuullaattiioonn iiss__sseett((_+_S_e_t)) Succeeds if _S_e_t is a proper list (see pprrooppeerr__lliisstt//11) without duplicates. lliisstt__ttoo__sseett((_+_L_i_s_t_, _-_S_e_t)) Unifies _S_e_t with a list holding the same elements as _L_i_s_t in the same order. If _l_i_s_t contains duplicates, only the first is retained. See also ssoorrtt//22. Example: ?- list_to_set([a,b,a], X) X = [a,b] iinntteerrsseeccttiioonn((_+_S_e_t_1_, _+_S_e_t_2_, _-_S_e_t_3)) Succeeds if _S_e_t_3 unifies with the intersection of _S_e_t_1 and _S_e_t_2. _S_e_t_1 and _S_e_t_2 are lists without duplicates. They need not be ordered. ssuubbttrraacctt((_+_S_e_t_, _+_D_e_l_e_t_e_, _-_R_e_s_u_l_t)) Delete all elements of set `Delete' from `Set' and unify the resulting set with `Result'. uunniioonn((_+_S_e_t_1_, _+_S_e_t_2_, _-_S_e_t_3)) Succeeds if _S_e_t_3 unifies with the union of _S_e_t_1 and _S_e_t_2. _S_e_t_1 and _S_e_t_2 are lists without duplicates. They need not be ordered. ssuubbsseett((_+_S_u_b_s_e_t_, _+_S_e_t)) Succeeds if all elements of _S_u_b_s_e_t are elements of _S_e_t as well. mmeerrggee__sseett((_+_S_e_t_1_, _+_S_e_t_2_, _-_S_e_t_3)) _S_e_t_1 and _S_e_t_2 are lists without duplicates, sorted to the standard order of terms. _S_e_t_3 is unified with an ordered list without duplicates holding the union of the elements of _S_e_t_1 and _S_e_t_2. 33..2277 SSoorrttiinngg LLiissttss ssoorrtt((_+_L_i_s_t_, _-_S_o_r_t_e_d)) Succeeds if _S_o_r_t_e_d can be unified with a list holding the elements of _L_i_s_t, sorted to the standard order of terms (see section 3.5). Duplicates are removed. Implemented by translating the input list into a temporary array, calling the C-library function qqssoorrtt((3)) using PPLL__ccoommppaarree(()) for comparing the elements, after which the result is translated into the result list. mmssoorrtt((_+_L_i_s_t_, _-_S_o_r_t_e_d)) Equivalent to ssoorrtt//22, but does not remove duplicates. kkeeyyssoorrtt((_+_L_i_s_t_, _-_S_o_r_t_e_d)) _L_i_s_t is a list of Key-Value pairs (e.g. terms of the functor `-' with arity 2). kkeeyyssoorrtt//22 sorts _L_i_s_t like mmssoorrtt//22, but only compares the keys. Can be used to sort terms not on standard order, but on any criterion that can be expressed on a multi-dimensional scale. Sorting on more than one criterion can be done using terms as keys, putting the first criterion as argument 1, the second as argument 2, etc. The order of multiple elements that have the same _K_e_y is not changed. pprreeddssoorrtt((_+_P_r_e_d_, _+_L_i_s_t_, _-_S_o_r_t_e_d)) Sorts similar to mmssoorrtt//22, but determines the order of two terms by applying _P_r_e_d to pairs of elements from _L_i_s_t (see aappppllyy//22). The predicate should succeed if the first element should be before the second. 33..2288 FFiinnddiinngg aallll SSoolluuttiioonnss ttoo aa GGooaall ffiinnddaallll((_+_V_a_r_, _+_G_o_a_l_, _-_B_a_g)) Creates a list of the instantiations _V_a_r gets successively on backtracking over _G_o_a_l and unifies the result with _B_a_g. Succeeds with an empty list if _G_o_a_l has no solutions. ffiinnddaallll//33 is equivalent to bbaaggooff//33 with all free variables bound with the existence operator (^), except that bbaaggooff//33 fails when goal has no solutions. bbaaggooff((_+_V_a_r_, _+_G_o_a_l_, _-_B_a_g)) Unify _B_a_g with the alternatives of _V_a_r, if _G_o_a_l has free variables besides the one sharing with _V_a_r bagof will backtrack over the alternatives of these free variables, unifying _B_a_g with the corresponding alternatives of _V_a_r. The construct +Var^Goal tells bagof not to bind _V_a_r in _G_o_a_l. bbaaggooff//33 fails if _G_o_a_l has no solutions. The example below illustrates bbaaggooff//33 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 ?- sseettooff((_+_V_a_r_, _+_G_o_a_l_, _-_S_e_t)) Equivalent to bbaaggooff//33, but sorts the result using ssoorrtt//22 to get a sorted list of alternatives without duplicates. 33..2299 IInnvvookkiinngg PPrreeddiiccaatteess oonn aallll MMeemmbbeerrss ooff aa LLiisstt 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 aappppllyy//22, which implies common arguments can be put in front of the arguments obtained from the list(s). For example: ?- maplist(plus(1), [0, 1, 2], X). X = [1, 2, 3] we will phrase this as ``_P_r_e_d_i_c_a_t_e is applied on ...'' cchheecckklliisstt((_+_P_r_e_d_, _+_L_i_s_t)) _P_r_e_d is applied successively on each element of _L_i_s_t until the end of the list or _P_r_e_d fails. In the latter case the cchheecckklliisstt//22 fails. mmaapplliisstt((_+_P_r_e_d_, _?_L_i_s_t_1_, _?_L_i_s_t_2)) Apply _P_r_e_d on all successive pairs of elements from _L_i_s_t_1 and _L_i_s_t_2. Fails if _P_r_e_d can not be applied to a pair. See the example above. ssuubblliisstt((_+_P_r_e_d_, _+_L_i_s_t_1_, _?_L_i_s_t_2)) Unify _L_i_s_t_2 with a list of all elements of _L_i_s_t_1 to which _P_r_e_d applies. 33..3300 FFoorraallll ffoorraallll((_+_C_o_n_d_, _+_A_c_t_i_o_n)) For all alternative bindings of _C_o_n_d _A_c_t_i_o_n can be proven. The example verifies that all arithmetic statements in the list _L are correct. It does not say which is wrong if one proves wrong. ?- forall(member(Result = Formula, [2 = 1 + 1, 4 = 2 * 2]), Result =:= Formula). 33..3311 FFoorrmmaatttteedd WWrriittee The current version of SWI-Prolog provides two formatted write predicates. The first is wwrriitteeff//[[11,,22]], which is compatible with Edinburgh C-Prolog. The second is ffoorrmmaatt//[[11,,22]], which is compatible with Quintus Prolog. We hope the Prolog community will once define a standard formatted write predicate. If you want performance use ffoorrmmaatt//[[11,,22]] as this predicate is defined in C. Otherwise compatibility reasons might tell you which predicate to use. 33..3311..11 WWrriitteeff wwrriittee__llnn((_+_T_e_r_m)) Equivalent to write(Term), nl. wwrriitteeff((_+_A_t_o_m)) Equivalent to writef(Atom, []). wwrriitteeff((_+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s)) Formatted write. _F_o_r_m_a_t is an atom whose characters will be printed. _F_o_r_m_a_t may contain certain special character sequences which specify certain formatting and substitution actions. _A_r_g_u_m_e_n_t_s then provides all the terms required to be output. Escape sequences to generate a single special character: __________________________________________________ | \n |Output a nemline character (see also | | |nnll//[[00,,11]]) | | \l |Output a line separator (same as \n) | | \r |Output a carriage-return character | | |(ASCII 13) | | \t |Output the ASCII character TAB (9) | | \\ |The character \ is output | | \% |The character % is output | | \nnn |where <_n_n_n> is an integer (1-3 digits) | | |the character with ASCII code <_n_n_n> is | |______|output_(NB_:_<_n_n_n>_is_read_as_ddeecciimmaall)____| Note that \l, \\bnfmeta{nnn} and \\ are interpreted differently when character-escapes are in effect. See section 2.11.1.1. Escape sequences to include arguments from _A_r_g_u_m_e_n_t_s. Each time a % escape sequence is found in _F_o_r_m_a_t the next argument from _A_r_g_u_m_e_n_t_s is formatted according to the specification. _________________________________________________%t | %w pprriinntt//11 the next item (mnemonic: term) | | | %q |wwrriittee//11the next item | | %d |wwrriitteeqq//11the next item | | %p |ddiissppllaayy//11the next item | | |pprriinntt//11the 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 ttttyyfflluusshh//00 (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.__________|_ sswwrriitteeff((_-_S_t_r_i_n_g_, _+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s)) Equivalent to wwrriitteeff//22, but ``writes'' the result on _S_t_r_i_n_g instead of the current output stream. Example: ?- swritef(S, '%15L%w', ['Hello', 'World']). S = "Hello World" sswwrriitteeff((_-_S_t_r_i_n_g_, _+_F_o_r_m_a_t)) Equivalent to swritef(String, Format, []). 33..3311..22 FFoorrmmaatt ffoorrmmaatt((_+_F_o_r_m_a_t)) Defined as `format(Format) :- format(Format, []).' ffoorrmmaatt((_+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s)) _F_o_r_m_a_t is an atom, list of ASCII values, or a Prolog string. _A_r_g_u_m_e_n_t_s provides the arguments required by the format specification. If only one argument is required and this is not a list of ASCII values the argument need not be put in a list. Otherwise the arguments are put in a list. Special sequences start with the tilde (~), followed by an optional numeric argument, followed by a character describing the action to be undertaken. A numeric argument is either a sequence of digits, representing a positive decimal number, a sequence `<_c_h_a_r_a_c_t_e_r>, representing the ASCII value of the character (only useful for ~t) or a asterisk (*), in when the numeric argument is taken from the next argument of the argument list, which should be a positive integer. Actions are: ~ Output the tilde itself. a Output the next argument, which should be an atom. This option is equivalent to ww. Compatibility reasons only. c Output the next argument as an ASCII value. This argument should be an integer in the range [0, ..., 255] (including 0 and 255). d Output next argument as a decimal number. It should be an integer. If a numeric argument is specified a dot is inserted _a_r_g_u_m_e_n_t positions from the right (useful for doing fixed point arithmetic with integers, such as handling amounts of money). D Same as dd, but makes large values easier to read by inserting a comma every three digits left to the dot or right. e Output next argument as a floating point number in exponential notation. The numeric argument specifies the precision. Default is 6 digits. Exact representation depends on the C library function printf(). This function is invoked with the format %.<_p_r_e_c_i_s_i_o_n>e. E Equivalent to ee, but outputs a capital E to indicate the exponent. f Floating point in non-exponential notation. See C library function printf(). g Floating point in ee or ff notation, whichever is shorter. G Floating point in EE or ff notation, whichever is shorter. i Ignore next argument of the argument list. Produces no output. k Give the next argument to ddiissppllaayyqq//11 (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 pprriinntt//11. q Give the next argument to wwrriitteeqq//11. 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 rr, but uses upper case letters for digits above 9. s Output a string of ASCII characters or a string (see ssttrriinngg//11 and section 3.20) from the next argument. t All remaining space between 2 tabs tops is distributed equally over ~t statements between the tabs tops. This space is padded with spaces by default. If an argument is supplied this is taken to be the ASCII value of the character used for padding. This can be used to do left or right alignment, centering, distributing, etc. See also ~| and ~+ to set tab stops. A tabs top is assumed at the start of each line. | Set a tabs top on the current position. If an argument is supplied set a tabs top on the position of that argument. This will cause all ~t's to be distributed between the previous and this tabs top. + Set a tabs top relative to the current position. Further the same as ~|. w Give the next argument to wwrriittee//11. 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 ffoorrmmaatt((_+_S_t_r_e_a_m_, _+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s)) As ffoorrmmaatt//22, but write the output on the given _S_t_r_e_a_m. ssffoorrmmaatt((_-_S_t_r_i_n_g_, _+_F_o_r_m_a_t_, _+_A_r_g_u_m_e_n_t_s)) Equivalent to ffoorrmmaatt//22, but ``writes'' the result on _S_t_r_i_n_g instead of the current output stream. Example: ?- sformat(S, '~w~t~15|~w', ['Hello', 'World']). S = "Hello World" ssffoorrmmaatt((_-_S_t_r_i_n_g_, _+_F_o_r_m_a_t)) Equivalent to `sformat(String, Format, []).' 33..3311..33 PPrrooggrraammmmiinngg FFoorrmmaatt ffoorrmmaatt__pprreeddiiccaattee((_+_C_h_a_r_, _+_H_e_a_d)) If a sequence ~c (tilde, followed by some character) is found, the format derivatives will first check whether the user has defined a predicate to handle the format. If not, the built in formatting rules described above are used. _C_h_a_r is either an ascii value, or a one character atom, specifying the letter to be (re)defined. _H_e_a_d is a term, whose name and arity are used to determine the predicate to call for the redefined formatting character. The first argument to the predicate is the numeric argument of the format command, or the atom default if no argument is specified. The remaining arguments are filled from the argument list. The example below redefines ~n to produce _A_r_g times return followed by linefeed (so a (Grr.) DOS machine is happy with the output). :- format_predicate(n, dos_newline(_Arg)). dos_newline(Arg) :- between(1, Ar, _), put(13), put(10), fail ; true. 33..3322 TTeerrmmiinnaall CCoonnttrrooll The following predicates form a simple access mechanism to the Unix termcap library to provide terminal independent I/O for screen terminals. The library package library(tty) builds on top of these predicates. ttttyy__ggeett__ccaappaabbiilliittyy((_+_N_a_m_e_, _+_T_y_p_e_, _-_R_e_s_u_l_t)) Get the capability named _N_a_m_e from the termcap library. See termcap(5) for the capability names. _T_y_p_e specifies the type of the expected result, and is one of string, number or bool. String results are returned as an atom, number result as an integer and bool results as the atom on or off. If an option cannot be found this predicate fails silently. The results are only computed once. Successive queries on the same capability are fast. ttttyy__ggoottoo((_+_X_, _+_Y)) Goto position (_X, _Y) on the screen. Note that the predicates lliinnee__ccoouunntt//22 and lliinnee__ppoossiittiioonn//22 will not have a well defined behaviour while using this predicate. ttttyy__ppuutt((_+_A_t_o_m_, _+_L_i_n_e_s)) Put an atom via the termcap library function tputs(). This function decodes padding information in the strings returned by ttttyy__ggeett__ccaappaabbiilliittyy//33 and should be used to output these strings. _L_i_n_e_s is the number of lines affected by the operation, or 1 if not applicable (as in almost all cases). sseett__ttttyy((_-_O_l_d_S_t_r_e_a_m_, _+_N_e_w_S_t_r_e_a_m)) Set the output stream, used by ttttyy__ppuutt//22 and ttttyy__ggoottoo//22 to a specific stream. Default is user_output. 33..3333 OOppeerraattiinngg SSyysstteemm IInntteerraaccttiioonn sshheellll((_+_C_o_m_m_a_n_d_, _-_S_t_a_t_u_s)) Execute _C_o_m_m_a_n_d on the operating system. _C_o_m_m_a_n_d is given to the Bourne shell (/bin/sh). _S_t_a_t_u_s is unified with the exit status of the command. On _W_i_n_3_2 systems, sshheellll//[[11,,22]] executes the command using the CreateProcess() API and waits for the command to terminate. If the command ends with a & sign, the command is handed to the WinExec() API, which does not wait for the new task to terminate. See also wwiinn__eexxeecc//22. sshheellll((_+_C_o_m_m_a_n_d)) Equivalent to `shell(Command, 0)'. sshheellll Start an interactive Unix shell. Default is /bin/sh, the environment variable SHELL overrides this default. Not available for Win32 platforms. wwiinn__eexxeecc((_+_C_o_m_m_a_n_d_, _+_S_h_o_w)) Win32 systems only. Spawns a Windows task without waiting for its completion. _S_h_o_w is either iconic or normal and dictates the initial status of the window. The iconic option is notably handy to start (DDE) servers. ggeetteennvv((_+_N_a_m_e_, _-_V_a_l_u_e)) Get Unix environment variable (see csh(1) and sh(1)). Fails if the variable does not exist. sseetteennvv((_+_N_a_m_e_, _+_V_a_l_u_e)) Set Unix environment variable. _N_a_m_e and _V_a_l_u_e should be instantiated to atoms or integers. The environment variable will be passed to sshheellll//[[00--22]] and can be requested using ggeetteennvv//22. uunnsseetteennvv((_+_N_a_m_e)) Remove Unix environment variable from the environment. ggeett__ttiimmee((_-_T_i_m_e)) Return the number of seconds that elapsed since the epoch of Unix, 1 January 1970, 0 hours. _T_i_m_e is a floating point number. Its granularity is system dependent. On sun, this is 1/60 of a second. ccoonnvveerrtt__ttiimmee((_+_T_i_m_e_, _-_Y_e_a_r_, _-_M_o_n_t_h_, _-_D_a_y_, _-_H_o_u_r_, _-_M_i_n_u_t_e_, _-_S_e_c_o_n_d_, _-_M_i_l_l_i_S_e_c_o_n_d_s)) Convert a time stamp, provided by ggeett__ttiimmee//11, ttiimmee__ffiillee//22, etc. _Y_e_a_r is unified with the year, _M_o_n_t_h with the month number (January is 1), _D_a_y with the day of the month (starting with 1), _H_o_u_r with the hour of the day (0--23), _M_i_n_u_t_e with the minute (0--59). _S_e_c_o_n_d with the second (0--59) and _M_i_l_l_i_S_e_c_o_n_d with the milliseconds (0--999). Note that the latter might not be accurate or might always be 0, depending on the timing capabilities of the system. 33..3344 FFiillee SSyysstteemm IInntteerraaccttiioonn aacccceessss__ffiillee((_+_F_i_l_e_, _+_M_o_d_e)) Succeeds if _F_i_l_e exists and can be accessed by this prolog process under mode _M_o_d_e. _M_o_d_e is one of the atoms read, write, append, exist, none or execute. _F_i_l_e may also be the name of a directory. Fails silently otherwise. access_file(File, none)simply succeeds without testing anything. If `Mode' is write or append, this predicate also succeeds if the file does not exist and the user has write-access to the directory of the specified location. eexxiissttss__ffiillee((_+_F_i_l_e)) Succeeds when _F_i_l_e exists. This does not imply the user has read and/or write permission for the file. ffiillee__ddiirreeccttoorryy__nnaammee((_+_F_i_l_e_, _-_D_i_r_e_c_t_o_r_y)) Extracts the directory-part of _F_i_l_e. The resulting _D_i_r_e_c_t_o_r_y name ends with the directory separator character /. If _F_i_l_e is an atom that does not contain any directory separator characters, the empty atom '' is returned. See also ffiillee__bbaassee__nnaammee//22. ffiillee__bbaassee__nnaammee((_+_F_i_l_e_, _-_B_a_s_e_N_a_m_e)) Extracts the filename part from a path specification. If _F_i_l_e does not contain any directory separators, _F_i_l_e is returned. ssaammee__ffiillee((_+_F_i_l_e_1_, _+_F_i_l_e_2)) Succeeds if both filenames refer to the same physical file. That is, if _F_i_l_e_1 and _F_i_l_e_2 are the same string or both names exist and point to the same file (due to hard or symbolic links and/or relative vs. absolute paths). eexxiissttss__ddiirreeccttoorryy((_+_D_i_r_e_c_t_o_r_y)) Succeeds if _D_i_r_e_c_t_o_r_y exists. This does not imply the user has read, search and or write permission for the directory. ddeelleettee__ffiillee((_+_F_i_l_e)) Unlink _F_i_l_e from the Unix file system. rreennaammee__ffiillee((_+_F_i_l_e_1_, _+_F_i_l_e_2)) Rename _F_i_l_e_1 into _F_i_l_e_2. Currently files cannot be moved across devices. ssiizzee__ffiillee((_+_F_i_l_e_, _-_S_i_z_e)) Unify _S_i_z_e with the size of _F_i_l_e in characters. ttiimmee__ffiillee((_+_F_i_l_e_, _-_T_i_m_e)) Unify the last modification time of _F_i_l_e with _T_i_m_e. _T_i_m_e is a floating point number expressing the seconds elapsed since Jan 1, 1970. aabbssoolluuttee__ffiillee__nnaammee((_+_F_i_l_e_, _-_A_b_s_o_l_u_t_e)) Expand Unix file specification into an absolute path. User home directory expansion (~ and ~<_u_s_e_r>) and variable expansion is done. The absolute path is canonised: references to . and .. are deleted. SWI-Prolog uses absolute file names to register source files independent of the current working directory. See also aabbssoolluuttee__ffiillee__nnaammee//33. aabbssoolluuttee__ffiillee__nnaammee((_+_S_p_e_c_, _+_O_p_t_i_o_n_s_, _-_A_b_s_o_l_u_t_e)) Converts the given file specification into an absolute path. _O_p_t_i_o_n is a list of options to guide the conformation process: eexxtteennssiioonnss((_L_i_s_t_O_f_E_x_t_e_n_s_i_o_n_s)) List of file-extensions to try. Default is ''. For each extension, aabbssoolluuttee__ffiillee__nnaammee//33will first add the extension and then verify the conditions imposed by the other options. If the condition fails, the next extension of the list is tried. Extensions may be specified both as ..ext or plain ext. aacccceessss((_M_o_d_e)) Imposes the condition access_file(_F_i_l_e, _M_o_d_e). _M_o_d_e is on of read, write, append, exist or none. See also aacccceessss__ffiillee//22. ffiillee__ttyyppee((_T_y_p_e)) Defines extensions. Current mapping: txt implies [''], prolog implies ['.pl', ''], executable implies ['.so', ''], qlf implies ['.qlf', ''] and directory implies ['']. ffiillee__eerrrroorrss((_f_a_i_l_/_t_r_u_e)) Report if the path cannot be resolved or be silent. The default is to stay silent. ssoolluuttiioonnss((_f_i_r_s_t_/_a_l_l)) If first (default), the predicates leaves no choice-point. Otherwise a choice-point will be left and backtracking may yield more solutions. iiss__aabbssoolluuttee__ffiillee__nnaammee((_+_F_i_l_e)) True if _F_i_l_e specifies and absolute path-name. On Unix systems, this implies the path starts with a `/'. For Microsoft based systems this implies the path starts with <_l_e_t_t_e_r>:. This predicate is intended to provide platform-independent checking for absolute paths. See also aabbssoolluuttee__ffiillee__nnaammee//22 and pprroolloogg__ttoo__ooss__ffiilleennaammee//22. ffiillee__nnaammee__eexxtteennssiioonn((_?_B_a_s_e_, _?_E_x_t_e_n_s_i_o_n_, _?_N_a_m_e)) This predicate is used to add, remove or test filename extensions. The main reason for its introduction is to deal with different filename properties in a portable manner. If the file system is case-insensitive, testing for an extension will be done case-insensitive too. _E_x_t_e_n_s_i_o_n may be specified with or without a leading dot (.). If an _E_x_t_e_n_s_i_o_n is generated, it will not have a leading dot. eexxppaanndd__ffiillee__nnaammee((_+_W_i_l_d_C_a_r_d_, _-_L_i_s_t)) Unify _L_i_s_t with a sorted list of files or directories matching _W_i_l_d_C_a_r_d. The normal Unix wildcard constructs `?', `*', `[...]' and `{...}' are recognised. The interpretation of `{...}' is interpreted slightly different from the C shell (csh(1)). The comma separated argument can be arbitrary patterns, including `{...}' patterns. The empty pattern is legal as well: `{.pl,}' matches either `.pl' or the empty string. pprroolloogg__ttoo__ooss__ffiilleennaammee((_?_P_r_o_l_o_g_P_a_t_h_, _?_O_s_P_a_t_h)) Converts between the internal Prolog pathname conventions and the operating-system pathname conventions. The internal conventions are Unix and this predicates is equivalent to =/2 (unify) on Unix systems. On DOS systems it will change the directory-separator, limit the filename length map dots, except for the last one, onto underscores. rreeaadd__lliinnkk((_+_F_i_l_e_, _-_L_i_n_k_, _-_T_a_r_g_e_t)) If _F_i_l_e points to a symbolic link, unify _L_i_n_k with the value of the link and _T_a_r_g_e_t to the file the link is pointing to. _T_a_r_g_e_t points to a file, directory or non-existing entry in the file system, but never to a link. Fails if _F_i_l_e is not a link. Fails always on systems that do not support symbolic links. ttmmpp__ffiillee((_+_B_a_s_e_, _-_T_m_p_N_a_m_e)) Create a name for a temporary file. _B_a_s_e is an identifier for the category of file. The _T_m_p_N_a_m_e is guaranteed to be unique. If the system halts, it will automatically remove all created temporary files. cchhddiirr((_+_P_a_t_h)) Change working directory to _P_a_t_h. 33..3355 UUsseerr TToopplleevveell MMaanniippuullaattiioonn bbrreeaakk Recursively start a new Prolog top level. This Prolog top level has its own stacks, but shares the heap with all break environments and the top level. Debugging is switched off on entering a break and restored on leaving one. The break environment is terminated by typing the system's end-of-file character (control-D). If the -t toplevel command line option is given this goal is started instead of entering the default interactive top level (pprroolloogg//00). aabboorrtt Abort the Prolog execution and start a new top level. If the -t toplevel command line options is given this goal is started instead of entering the default interactive top level. Break environments are aborted as well. All open files except for the terminal related files are closed. The input- and output stream again refers to _u_s_e_r. hhaalltt 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 aatt__hhaalltt//11. hhaalltt//00 is equivalent to halt(0). hhaalltt((_+_S_t_a_t_u_s)) Terminate Prolog execution with given status. Status is an integer. See also hhaalltt//00. pprroolloogg This goal starts the default interactive top level. Queries are read from the stream user_input. See also the history feature (ffeeaattuurree//22). The pprroolloogg//00 predicate is terminated (succeeds) by typing the end-of-file character (Unix: control-D). The following two hooks allow for expanding queries and handling the result of a query. These hooks are used by the toplevel variable expansion mechanism described in section 2.5. eexxppaanndd__qquueerryy((_+_Q_u_e_r_y_, _-_E_x_p_a_n_d_e_d_, _+_B_i_n_d_i_n_g_s_, _-_E_x_p_a_n_d_e_d_B_i_n_d_i_n_g_s)) Hook in module user, normally not defined. _Q_u_e_r_y and _B_i_n_d_i_n_g_s represents the query read from the user and the names of the free variables as obtained using rreeaadd__tteerrmm//33. If this predicate succeeds, it should bind _E_x_p_a_n_d_e_d and _E_x_p_a_n_d_e_d_B_i_n_d_i_n_g_s to the query and bindings to be executed by the toplevel. This predicate is used by the toplevel (pprroolloogg//00). See also eexxppaanndd__aannsswweerr//22 and tteerrmm__eexxppaannssiioonn//22. eexxppaanndd__aannsswweerr((_+_B_i_n_d_i_n_g_s_, _-_E_x_p_a_n_d_e_d_B_i_n_d_i_n_g_s)) Hook in module user, normally not defined. Expand the result of a successfully executed toplevel query. _B_i_n_d_i_n_g_s is the query <_N_a_m_e>= <_V_a_l_u_e>binding list from the query. _E_x_p_a_n_d_e_d_B_i_n_d_i_n_g_s must be unified with the bindings the toplevel should print. 33..3366 CCrreeaattiinngg aa PPrroottooccooll ooff tthhee UUsseerr IInntteerraaccttiioonn 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. pprroottooccooll((_+_F_i_l_e)) Start protocolling on file _F_i_l_e. If there is already a protocol file open then close it first. If _F_i_l_e exists it is truncated. pprroottooccoollaa((_+_F_i_l_e)) Equivalent to pprroottooccooll//11, but does not truncate the _F_i_l_e if it exists. nnoopprroottooccooll Stop making a protocol of the user interaction. Pending output is flushed on the file. pprroottooccoolllliinngg((_-_F_i_l_e)) Succeeds if a protocol was started with pprroottooccooll//11 or pprroottooccoollaa//11 and unifies _F_i_l_e with the current protocol output file. 33..3377 DDeebbuuggggiinngg aanndd TTrraacciinngg PPrrooggrraammss ttrraaccee Start the tracer. ttrraaccee//00 itself cannot be seen in the tracer. Note that the Prolog toplevel treats ttrraaccee//00 special; it means `trace the next goal'. ttrraacciinngg Succeeds when the tracer is currently switched on. ttrraacciinngg//00 itself can not be seen in the tracer. nnoottrraaccee Stop the tracer. nnoottrraaccee//00 itself cannot be seen in the tracer. ttrraaccee((_+_P_r_e_d)) Equivalent to trace(Pred, +all). ttrraaccee((_+_P_r_e_d_, _+_P_o_r_t_s)) Put a trace-point on all predicates satisfying the predicate specification _P_r_e_d. _P_o_r_t_s is a list of portnames (call, redo, exit, fail). The atom all refers to all ports. If the port is preceded by a - sign the trace-point is cleared for the port. If it is preceded by a + the trace-point is set. The predicate ttrraaccee//22 activates debug mode (see ddeebbuugg//00). Each time a port (of the 4-port model) is passed that has a trace-point set the goal is printed as with ttrraaccee//00. Unlike ttrraaccee//00 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 ddeebbuuggggiinngg//00 shows all currently defined trace-points. nnoottrraaccee((_+_G_o_a_l)) Call _G_o_a_l, but suspend the debugger while _G_o_a_l is executing. The current implementation cuts the choicepoints of _G_o_a_l after successful completion. See oonnccee//11. Later implementations may have the same semantics as ccaallll//11. ddeebbuugg Start debugger (stop at spy points). nnooddeebbuugg Stop debugger (do not trace, nor stop at spy points). ddeebbuuggggiinngg Print debug status and spy points on current output stream. ssppyy((_+_P_r_e_d)) Put a spy point on all predicates meeting the predicate specification _P_r_e_d. See section 3.3. nnoossppyy((_+_P_r_e_d)) Remove spy point from all predicates meeting the predicate specification _P_r_e_d. nnoossppyyaallll Remove all spy points from the entire program. lleeaasshh((_?_P_o_r_t_s)) Set/query leashing (ports which allow for user interaction). _P_o_r_t_s is one of _+_N_a_m_e, _-_N_a_m_e, _?_N_a_m_e or a list of these. _+_N_a_m_e enables leashing on that port, _-_N_a_m_e disables it and _?_N_a_m_e succeeds or fails according to the current setting. Recognised ports are: call, redo, exit, fail and unify. The special shorthand all refers to all ports, full refers to all ports except for the unify port (default). half refers to the call, redo and fail port. vviissiibbllee((_+_P_o_r_t_s)) Set the ports shown by the debugger. See lleeaasshh//11 for a description of the port specification. Default is full. uunnkknnoowwnn((_-_O_l_d_, _+_N_e_w)) Unify _O_l_d with the current value of the unknown system flag. On success _N_e_w will be used to specify the new value. _N_e_w should be instantiated to either fail or trace and determines the interpreters action when an undefined predicate which is not declared dynamic is encountered (see ddyynnaammiicc//11). fail implies the predicate just fails silently. trace implies the tracer is started. Default is trace. The unknown flag is local to each module and uunnkknnoowwnn//22 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 eexxcceeppttiioonn//33 and will nnoott try to resolve the predicate via the dynamic library system. The system will still try to import the predicate from the public module. ssttyyllee__cchheecckk((_+_S_p_e_c)) Set style checking options. _S_p_e_c is either +<_o_p_t_i_o_n>, -<_o_p_t_i_o_n>, ?<_o_p_t_i_o_n> or a list of such options. +<_o_p_t_i_o_n> sets a style checking option, -<_o_p_t_i_o_n>clears it and ?<_o_p_t_i_o_n> succeeds or fails according to the current setting. ccoonnssuulltt//11 and derivatives resets the style checking options to their value before loading the file. If---for example---a file containing long atoms should be loaded the user can start the file with: :- style_check(-atom). Currently available options are: ____________________________________________________________________ |_Name__________|Default_|Description_______________________________||singletonon| || | rreeaadd__ccllaauussee//11 (used by ccoonnssuulltt//11) warns | || | on variables only appearing once in a | || | term (clause) which have a name not | || ||atom | on |starting with an underscore. || || | | |rreeaadd//11 and derivatives will produce an | | | |error message on quoted atoms or strings | | | |longer than 5 lines. | | dollar | off |Accept dollar as a lower case character, | | | |thus avoiding the need for quoting atoms | | | |with dollar signs. System maintenance | | | |use only. | | discontiguous | on |Warn if the clauses for a predicate are | | | |not together in the same source file. | | string | off |Read and derivatives transform "..." | | | |into a prolog string instead of a list | |_______________|________|of_ASCII_characters.______________________| 33..3388 OObbttaaiinniinngg RRuunnttiimmee SSttaattiissttiiccss ssttaattiissttiiccss((_+_K_e_y_, _-_V_a_l_u_e)) Unify system statistics determined by _K_e_y with _V_a_l_u_e. The possible keys are given in the table 3.2. _______________________________________________________________ | cputime |(User) cpu time since Prolog was started in| | |seconds | | inferences |Total number of passes via the call and redo| | |ports since Prolog was started. | | heap |Estimated total size of the heap (see| | |section 2.12.1.1) | | heapused |Bytes heap in use by Prolog. | | heaplimit |Maximum size of the heap (see sec-| | |tion 2.12.1.1) | | local |Allocated size of the local stack in bytes. | | localused |Number of bytes in use on the local stack. | | locallimit |Size to which the local stack is allowed to| | |grow | | global |Allocated size of the global stack in bytes. | | globalused |Number of bytes in use on the global stack. | | globallimit |Size to which the global stack is allowed to| | |grow | | trail |Allocated size of the trail stack in bytes. | | trailused |Number of bytes in use on the trail stack. | | traillimit |Size to which the trail stack is allowed to| | |grow | | atoms |Total number of defined atoms. | | functors |Total number of defined name/arity pairs. | | predicates |Total number of predicate definitions. | | modules |Total number of module definitions. | |_codes_______|Total_amount_of_byte_codes_in_all_clauses._____|_ Table 3.2: Keys for ssttaattiissttiiccss//22 ssttaattiissttiiccss Display a table of system statistics on the current output stream. ttiimmee((_+_G_o_a_l)) Execute _G_o_a_l just like oonnccee//11 (i.e. leaving no choice points), but print used time, number of logical inferences and the average number of _l_i_p_s (logical inferences per second). Note that SWI-Prolog counts the actual executed number of inferences rather than the number of passes through the call- and redo ports of the theoretical 4-port model. 33..3399 FFiinnddiinngg PPeerrffoorrmmaannccee BBoottttlleenneecckkss SWI-Prolog offers a statistical program profiler similar to Unix prof(1) for C and some other languages. A profiler is used as an aid to find performance pigs in programs. It provides information on the time spent in the various Prolog predicates. The profiler is based on the assumption that if we monitor the functions on the execution stack on time intervals not correlated to the program's execution the number of times we find a procedure on the environment stack is a measure of the time spent in this procedure. It is implemented by calling a procedure each time slice Prolog is active. This procedure scans the local stack and either just counts the procedure on top of this stack (plain profiling) or all procedures on the stack (cumulative profiling). To get accurate results each procedure one is interested in should have a reasonable number of counts. Typically a minute runtime will suffice to get a rough overview of the most expensive procedures. pprrooffiillee((_+_G_o_a_l_, _+_S_t_y_l_e_, _+_N_u_m_b_e_r)) Execute _G_o_a_l just like ttiimmee//11. Collect profiling statistics according to style (see pprrooffiilleerr//22) and show the top _N_u_m_b_e_r procedures on the current output stream (see sshhooww__pprrooffiillee//11). The results are kept in the database until rreesseett__pprrooffiilleerr//00 or pprrooffiillee//33 is called and can be displayed again with sshhooww__pprrooffiillee//11. pprrooffiillee//33 is the normal way to invoke the profiler. The predicates below are low-level predicates that can be used for special cases. sshhooww__pprrooffiillee((_+_N_u_m_b_e_r)) Show the collected results of the profiler. Stops the profiler first to avoid interference from sshhooww__pprrooffiillee//11. It shows the top _N_u_m_b_e_r predicates according the percentage cpu-time used. pprrooffiilleerr((_-_O_l_d_, _+_N_e_w)) Query or change the status of the profiler. The status is one of off, plain or cumulative. plain implies the time used by children of a predicate is not added to the time of the predicate. For status cumulative the time of children is added (except for recursive calls). Cumulative profiling implies the stack is scanned up to the top on each time slice to find all active predicates. This implies the overhead grows with the number of active frames on the stack. Cumulative profiling starts debugging mode to disable tail recursion optimisation, which would otherwise remove the necessary parent environments. Switching status from plain to cumulative resets the profiler. Switching to and from status off does not reset the collected statistics, thus allowing to suspend profiling for certain parts of the program. rreesseett__pprrooffiilleerr Switches the profiler to off and clears all collected statistics. pprrooffiillee__ccoouunntt((_+_H_e_a_d_, _-_C_a_l_l_s_, _-_P_r_o_m_i_l_a_g_e)) Obtain profile statistics of the predicate specified by _H_e_a_d. _H_e_a_d is an atom for predicates with arity 0 or a term with the same name and arity as the predicate required (see ccuurrrreenntt__pprreeddiiccaattee//22). _C_a_l_l_s is unified with the number of `calls' and `redos' while the profiler was active. _P_r_o_m_i_l_a_g_e is unified with the relative number of counts the predicate was active (cumulative) or on top of the stack (plain). _P_r_o_m_i_l_a_g_e is an integer between 0 and 1000. 33..4400 MMeemmoorryy MMaannaaggeemmeenntt Note: lliimmiitt__ssttaacckk//22and ttrriimm__ssttaacckkss//00have no effect on machines that do not offer dynamic stack expansion. On these machines these predicates simply succeed to improve portability. ggaarrbbaaggee__ccoolllleecctt Invoke the global- and trail stack garbage collector. Normally the garbage collector is invoked automatically if necessary. Explicit invocation might be useful to reduce the need for garbage collections in time critical segments of the code. After the garbage collection ttrriimm__ssttaacckkss//00 is invoked to release the collected memory resources. lliimmiitt__ssttaacckk((_+_K_e_y_, _+_K_b_y_t_e_s)) Limit one of the stack areas to the specified value. _K_e_y is one of local, global or trail. The limit is an integer, expressing the desired stack limit in K bytes. If the desired limit is smaller than the currently used value, the limit is set to the nearest legal value above the currently used value. If the desired value is larger than the maximum, the maximum is taken. Finally, if the desired value is either 0 or the atom unlimited the limit is set to its maximum. The maximum and initial limit is determined by the command line options -L, -G and -T. ttrriimm__ssttaacckkss Release stack memory resources that are not in use at this moment, returning them to the operating system. Trim stack is a relatively cheap call. It can be used to release memory resources in a backtracking loop, where the iterations require typically seconds of execution time and very different, potentially large, amounts of stack space. Such a loop should be written as follows: loop :- generator, trim_stacks, potentially_expensive_operation, stop_condition, !. The prolog top level loop is written this way, reclaiming memory resources after every user query. ssttaacckk__ppaarraammeetteerr((_+_S_t_a_c_k_, _+_K_e_y_, _-_O_l_d_, _+_N_e_w)) Query/set a parameter for the runtime stacks. _S_t_a_c_k is one of local, global, trail or argument. The table below describes the _K_e_y/_V_a_l_u_e pairs. Old is first unified with the current value. ____________________________________________________________ | limit |Maximum size of the stack in bytes | |_min_free_|Minimum_free_space_at_entry_of_foreign_predicate_| This predicate is currently only available on versions that use the stack-shifter to enlarge the runtime stacks when necessary. It's definition is subject to change. 33..4411 WWiinnddoowwss DDDDEE iinntteerrffaaccee The predicates in this section deal with MS-Windows `Dynamic Data Exchange' or DDE protocol. A Windows DDE conversation is a form of interprocess communication based on sending reserved window-events between the communicating processes. See also section 5.4 for loading Windows DLL's into SWI-Prolog. 33..4411..11 DDDDEE cclliieenntt iinntteerrffaaccee The DDE client interface allows Prolog to talk to DDE server programs. We will demonstrate the use of the DDE interface using the Windows PROGMAN (Program Manager) application: 1 ?- open_dde_conversation(progman, progman, C). C = 0 2 ?- dde_request(0, groups, X) --> Unifies X with description of groups 3 ?- dde_execute(0, '[CreateGroup("DDE Demo")]'). Yes 4 ?- close_dde_conversation(0). Yes For details on interacting with progman, use the SDK online manual section on the Shell DDE interface. See also the Prolog library(progman), which may be used to write simple Windows setup scripts in Prolog. ooppeenn__ddddee__ccoonnvveerrssaattiioonn((_+_S_e_r_v_i_c_e_, _+_T_o_p_i_c_, _-_H_a_n_d_l_e)) Open a conversation with a server supporting the given service name and topic (atoms). If successful, _H_a_n_d_l_e may be used to send transactions to the server. If no willing server is found this predicate fails silently. cclloossee__ddddee__ccoonnvveerrssaattiioonn((_+_H_a_n_d_l_e)) Close the conversation associated with _H_a_n_d_l_e. All opened conversations should be closed when they're no longer needed, although the system will close any that remain open on process termination. ddddee__rreeqquueesstt((_+_H_a_n_d_l_e_, _+_I_t_e_m_, _-_V_a_l_u_e)) Request a value from the server. _I_t_e_m is an atom that identifies the requested data, and _V_a_l_u_e will be a string (CF_TEXT data in DDE parlance) representing that data, if the request is successful. If unsuccessful, _V_a_l_u_e will be unified with a term of form error(<_R_e_a_s_o_n>), identifying the problem. This call uses SWI-Prolog string objects to return the value rather then atoms to reduce the load on the atom-space. See section 3.20 for a discussion on this data type. ddddee__eexxeeccuuttee((_+_H_a_n_d_l_e_, _+_C_o_m_m_a_n_d)) Request the DDE server to execute the given command-string. Succeeds if the command could be executed and fails with error message otherwise. ddddee__ppookkee((_+_H_a_n_d_l_e_, _+_I_t_e_m_, _+_C_o_m_m_a_n_d)) Issue a POKE command to the server on the specified _I_t_e_m. Command is passed as data of type CF_TEXT. 33..4411..22 DDDDEE sseerrvveerr mmooddee The (autoload) library(dde) defines primitives to realise simple DDE server applications in SWI-Prolog. These features are provided as of version 2.0.6 and should be regarded prototypes. The C-part of the DDE server can handle some more primitives, so if you need features not provided by this interface, please study library(dde). ddddee__rreeggiisstteerr__sseerrvviiccee((_+_T_e_m_p_l_a_t_e_, _+_G_o_a_l)) Register a server to handle DDE request or DDE execute requests from other applications. To register a service for a DDE request, _T_e_m_p_l_a_t_e is of the form: +Service(+Topic, +Item, +Value) _S_e_r_v_i_c_e is the name of the DDE service provided (like progman in the client example above). _T_o_p_i_c is either an atom, indicating _G_o_a_l only handles requests on this topic or a variable that also appears in _G_o_a_l. _I_t_e_m and _V_a_l_u_e are variables that also appear in _G_o_a_l. The example below registers the Prolog ffeeaattuurree//22 predicate to be accessible from other applications. The request may be given from the same Prolog as well as from another application. ?- dde_register_service(prolog(feature, F, V), feature(F, V)). ?- open_dde_conversation(prolog, feature, Handle), dde_request(Handle, home, Home), close_dde_conversation(Handle). Home = '/usr/local/lib/pl-2.0.6/' Handling DDE execute requests is very similar. In this case the template is of the form: +Service(+Topic, +Item) Passing a _V_a_l_u_e argument is not needed as execute requests either succeed or fail. If _G_o_a_l fails, a `not processed' is passed back to the caller of the DDE request. ddddee__uunnrreeggiisstteerr__sseerrvviiccee((_+_S_e_r_v_i_c_e)) Stop responding to _S_e_r_v_i_c_e. If Prolog is halted, it will automatically call this on all open services. ddddee__ccuurrrreenntt__sseerrvviiccee((_-_S_e_r_v_i_c_e_, _-_T_o_p_i_c)) Find currently registered services and the topics served on them. ddddee__ccuurrrreenntt__ccoonnnneeccttiioonn((_-_S_e_r_v_i_c_e_, _-_T_o_p_i_c)) Find currently open conversations. 33..4422 MMiisscceellllaanneeoouuss ddwwiimm__mmaattcchh((_+_A_t_o_m_1_, _+_A_t_o_m_2)) Succeeds if _A_t_o_m_1 matches _A_t_o_m_2 in `Do What I Mean' sense. Both _A_t_o_m_1 and _A_t_o_m_2 may also be integers or floats. The two atoms match if: o They are identical o They differ by one character (spy spu) o One character is inserted/deleted (debug deug) o Two characters are transposed (trace tarce) o `Sub-words' are glued differently (existsfile existsFile exists_file) o Two adjacent sub words are transposed (existsFile fileExists) ddwwiimm__mmaattcchh((_+_A_t_o_m_1_, _+_A_t_o_m_2_, _-_D_i_f_f_e_r_e_n_c_e)) Equivalent to ddwwiimm__mmaattcchh//22, but unifies _D_i_f_f_e_r_e_n_c_e with an atom identifying the the difference between _A_t_o_m_1 and _A_t_o_m_2. The return values are (in the same order as above): equal, mismatched_char, inserted_char, transposed_char, separated and transposed_word. wwiillddccaarrdd__mmaattcchh((_+_P_a_t_t_e_r_n_, _+_S_t_r_i_n_g)) Succeeds if _S_t_r_i_n_g matches the wildcard pattern _P_a_t_t_e_r_n. _P_a_t_t_e_r_n is very similar the the Unix csh pattern matcher. The patterns are given below: ? Matches one arbitrary character. * Matches any number of arbitrary characters. [...] Matches one of the characters specified between the brackets. <_c_h_a_r_1>-<_c_h_a_r_2>indicates a range. {...} Matches any of the patterns of the comma separated list between the braces. Example: ?- wildcard_match('[a-z]*.{pro,pl}[%~]', 'a_hello.pl%'). Yes. ggeennssyymm((_+_B_a_s_e_, _-_U_n_i_q_u_e)) Generate a unique atom from base _B_a_s_e and unify it with _U_n_i_q_u_e. _B_a_s_e should be an atom. The first call will return <_b_a_s_e>1, the next <_b_a_s_e>2, etc. Note that this is no warrant that the atom is unique in the system. sslleeeepp((_+_T_i_m_e)) Suspend execution _T_i_m_e seconds. _T_i_m_e is either a floating point number or an integer. Granularity is dependent on the system's timer granularity. A negative time causes the timer to return immediately. On most non-realtime operating systems we can only ensure execution is suspended for aatt lleeaasstt _T_i_m_e seconds. CChhaapptteerr 44.. UUSSIINNGG MMOODDUULLEESS 44..11 WWhhyy UUssiinngg MMoodduulleess?? In traditional Prolog systems the predicate space was flat. This approach is not very suitable for the development of large applications, certainly not if these applications are developed by more than one programmer. In many cases, the definition of a Prolog predicate requires sub-predicates that are intended only to complete the definition of the main predicate. With a flat and global predicate space these support predicates will be visible from the entire program. For this reason, it is desirable that each source module has it's own predicate space. A module consists of a declaration for it's name, it's _p_u_b_l_i_c _p_r_e_d_i_c_a_t_e_s and the predicates themselves. This approach allow the programmer to use short (local) names for support predicates without worrying about name conflicts with the support predicates of other modules. The module declaration also makes explicit which predicates are meant for public usage and which for private purposes. Finally, using the module information, cross reference programs can indicate possible problems much better. 44..22 NNaammee--bbaasseedd vveerrssuuss PPrreeddiiccaattee--bbaasseedd MMoodduulleess Two approaches to realize a module system are commonly used in Prolog and other languages. The first one is the _n_a_m_e _b_a_s_e_d module system. In these systems, each atom read is tagged (normally prefixed) with the module name, with the exception of those atoms that are defined _p_u_b_l_i_c. In the second approach, each module actually implements its own predicate space. A critical problem with using modules in Prolog is introduced by the meta-predicates that transform between Prolog data and Prolog predicates. Consider the case where we write: :- module(extend, [add_extension/3]). add_extension(Extension, Plain, Extended) :- maplist(extend_atom(Extension), Plain, Extended). extend_atom(Extension, Plain, Extended) :- concat(Plain, Extension, Extended). In this case we would like maplist to call extend_atom/3 in the module extend. A name based module system will do this correctly. It will tag the atom extend_atom with the module and maplist will use this to construct the tagged term extend_atom/3. A name based module however, will not only tag the atoms that will eventually be used to refer to a predicate, but aallll atoms that are not declared public. So, with a name based module system also data is local to the module. This introduces another serious problem: :- module(action, [action/3]). action(Object, sleep, Arg) :- .... action(Object, awake, Arg) :- .... :- module(process, [awake_process/2]). awake_process(Process, Arg) :- action(Process, awake, Arg). This code uses a simple object-oriented implementation technique were atoms are used as method selectors. Using a name based module system, this code will not work, unless we declare the selectors public atoms in all modules that use them. Predicate based module systems do not require particular precautions for handling this case. It appears we have to choose either to have local data, or to have trouble with meta-predicates. Probably it is best to choose for the predicate based approach as novice users will not often write generic meta-predicates that have to be used across multiple modules, but are likely to write programs that pass data around across modules. Experienced Prolog programmers should be able to deal with the complexities of meta-predicates in a predicate based module system. 44..33 DDeeffiinniinngg aa MMoodduullee Modules normally are created by loading a _m_o_d_u_l_e _f_i_l_e. A module file is a file holding a mmoodduullee//22 directive as its first term. The mmoodduullee//22 directive declares the name and the public (i.e. externally visible) predicates of the module. The rest of the file is loaded into the module. Below is an example of a module file, defining rreevveerrssee//22. :- module(reverse, [reverse/2]). reverse(List1, List2) :- rev(List1, [], List2). rev([], List, List). rev([Head|List1], List2, List3) :- rev(List1, [Head|List2], List3). 44..44 IImmppoorrttiinngg PPrreeddiiccaatteess iinnttoo aa MMoodduullee As explained before, in the predicate based approach adapted by SWI-Prolog, each module has it's own predicate space. In SWI-Prolog, a module initially is completely empty. Predicates can be added to a module by loading a module file as demonstrated in the previous section, using assert or by _i_m_p_o_r_t_i_n_g them from another module. Two mechanisms for importing predicates explicitly from another module exist. The uussee__mmoodduullee//[[11,,22]] predicates load a module file and import (part of the) public predicates of the file. The iimmppoorrtt//11 predicate imports any predicate from any module. uussee__mmoodduullee((_+_F_i_l_e)) Load the file(s) specified with _F_i_l_e just like eennssuurree__llooaaddeedd//11. The files should all be module files. All exported predicates from the loaded files are imported into the context module. The difference between this predicate and eennssuurree__llooaaddeedd//11 becomes apparent if the file is already loaded into another module. In this case eennssuurree__llooaaddeedd//11 does nothing; use_module will import all public predicates of the module into the current context module. uussee__mmoodduullee((_+_F_i_l_e_, _+_I_m_p_o_r_t_L_i_s_t)) Load the file specified with _F_i_l_e (only one file is accepted). _F_i_l_e should be a module file. _I_m_p_o_r_t_L_i_s_t is a list of name/arity pairs specifying the predicates that should be imported from the loaded module. If a predicate is specified that is not exported from the loaded module a warning will be printed. The predicate will nevertheless be imported to simplify debugging. iimmppoorrtt((_+_H_e_a_d)) Import predicate _H_e_a_d into the current context module. _H_e_a_d should specify the source module using the <_m_o_d_u_l_e>:<_t_e_r_m>construct. Note that predicates are normally imported using one of the directives uussee__mmoodduullee//[[11,,22]]. iimmppoorrtt//11 is meant for handling imports into dynamically created modules. It would be rather inconvenient to have to import each predicate referred to by the module, including the system predicates. For this reason each module is assigned a _d_e_f_a_u_l_t _m_o_d_u_l_e. All predicates in the default module are available without extra declarations. Their definition however can be overruled in the local module. This schedule is implemented by the exception handling mechanism of SWI-Prolog: if an undefined predicate exception is raised for a predicate in some module, the exception handler first tries to import the predicate from the module's default module. On success, normal execution is resumed. 44..44..11 RReesseerrvveedd MMoodduulleess SWI-Prolog contains two special modules. The first one is the module system. This module contains all built-in predicates described in this manual. Module system has no default module assigned to it. The second special module is the module user. This module forms the initial working space of the user. Initially it is empty. The default module of module user is system, making all built-in predicate definitions available as defaults. Built-in predicates thus can be overruled by defining them in module user before they are used. All other modules default to module user. This implies they can use all predicates imported into user without explicitly importing them. 44..55 UUssiinngg tthhee MMoodduullee SSyysstteemm The current structure of the module system has been designed with some specific organisations for large programs in mind. Many large programs define a basic library layer on top of which the actual program itself is defined. The module user, acting as the default module for all other modules of the program can be used to distribute these definitions over all program module without introducing the need to import this common layer each time explicitly. It can also be used to redefine built-in predicates if this is required to maintain compatibility to some other Prolog implementation. Typically, the loadfile of a large application looks like this: :- use_module(compatibility). % load XYZ prolog compatibility :- use_module( % load generic parts [ error % errors and warnings , goodies % general goodies (library extensions) , debug % application specific debugging , virtual_machine % virtual machine of application , ... % more generic stuff ]). :- ensure_loaded( [ ... % the application itself ]). The `use_module' declarations will import the public predicates from the generic modules into the user module. The `ensure_loaded' directive loads the modules that constitute the actual application. It is assumed these modules import predicates from each other using uussee__mmoodduullee//[[11,,22]]as far as necessary. In combination with the object-oriented schema described below it is possible to define a neat modular architecture. The generic code defines general utilities and the message passing predicates (invoke/3 in the example below). The application modules define classes that communicate using the message passing predicates. 44..55..11 OObbjjeecctt OOrriieenntteedd PPrrooggrraammmmiinngg Another typical way to use the module system is for defining classes within an object oriented paradigm. The class structure and the methods of a class can be defined in a module and the explicit module-boundary overruling describes in section 4.6.2 can by used by the message passing code to invoke the behaviour. An outline of this mechanism is given below. % Define class point :- module(point, []). % class point, no exports % name type, default access % value variable(x, integer, 0, both). variable(y, integer, 0, both). % method name predicate name arguments behaviour(mirror, mirror, []). mirror(P) :- fetch(P, x, X), fetch(P, y, Y), store(P, y, X), store(P, x, Y). The predicates fetch/3 and store/3 are predicates that change instance variables of instances. The figure below indicates how message passing can easily be implemented: % invoke(+Instance, +Selector, ?ArgumentList) % send a message to an instance invoke(I, S, Args) :- class_of_instance(I, Class), Class:behaviour(S, P, ArgCheck), !, convert_arguments(ArgCheck, Args, ConvArgs), Goal =.. [P|ConvArgs], Class:Goal. The construct <_M_o_d_u_l_e>:<_G_o_a_l> explicitly calls _G_o_a_l in module _M_o_d_u_l_e. It is discussed in more detail in section 3.7. 44..66 MMeettaa--PPrreeddiiccaatteess iinn MMoodduulleess As indicated in the introduction, the problem with a predicate based module system lies in the difficulty to find the correct predicate from a Prolog term. The predicate `solution(Solution)' can exist in more than one module, but `assert(solution(4))' in some module is supposed to refer to the correct version of solution/1. Various approaches are possible to solve this problem. One is to add an extra argument to all predicates (e.g. `assert(Module, Term)'). Another is to tag the term somehow to indicate which module is desired (e.g. `assert(Module:Term)'). Both approaches are not very attractive as they make the user responsible for choosing the correct module, inviting unclear programming by asserting in other modules. The predicate aasssseerrtt//11 is supposed to assert in the module it is called from and should do so without being told explicitly. For this reason, the notion _c_o_n_t_e_x_t _m_o_d_u_l_e has been introduced. 44..66..11 DDeeffiinniittiioonn aanndd CCoonntteexxtt MMoodduullee Each predicate of the program is assigned a module, called it's _d_e_f_i_n_i_t_i_o_n _m_o_d_u_l_e. The definition module of a predicate is always the module in which the predicate was originally defined. Each active goal in the Prolog system has a _c_o_n_t_e_x_t _m_o_d_u_l_e assigned to it. The context module is used to find predicates from a Prolog term. By default, this module is the definition module of the predicate running the goal. For meta-predicates however, this is the context module of the goal that invoked them. We call this _m_o_d_u_l_e___t_r_a_n_s_p_a_r_e_n_t in SWI-Prolog. In the `using maplist' example above, the predicate mmaapplliisstt//33 is declared module_transparent. This implies the context module remains extend, the context module of add_extension/3. This way mmaapplliisstt//33 can decide to call extend_atom in module extend rather than in it's own definition module. All built-in predicates that refer to predicates via a Prolog term are declared module_transparent. Below is the code defining maplist. :- module(maplist, maplist/3). :- module_transparent maplist/3. % maplist(+Goal, +List1, ?List2) % True if Goal can successfully be applied to all succes- sive pairs % of elements of List1 and List2. maplist(_, [], []). maplist(Goal, [Elem1|Tail1], [Elem2|Tail2]) :- apply(Goal, [Elem1, Elem2]), maplist(Goal, Tail1, Tail2). 44..66..22 OOvveerrrruulliinngg MMoodduullee BBoouunnddaarriieess The mechanism above is sufficient to create an acceptable module system. There are however cases in which we would like to be able to overrule this schema and explicitly call a predicate in some module or assert explicitly in some module. The first is useful to invoke goals in some module from the user's toplevel or to implement a object-oriented system (see above). The latter is useful to create and modify _d_y_n_a_m_i_c _m_o_d_u_l_e_s (see section 4.7). For this purpose, the reserved term ://22 has been introduced. All built-in predicates that transform a term into a predicate reference will check whether this term is of the form `<_M_o_d_u_l_e>:<_T_e_r_m>'. If so, the predicate is searched for in _M_o_d_u_l_e instead of the goal's context module. The : operator may be nested, in which case the inner-most module is used. The special calling construct <_M_o_d_u_l_e>:<_G_o_a_l>pretends _G_o_a_l is called from _M_o_d_u_l_e instead of the context module. Examples: ?- assert(world:done). % asserts done/0 into module world ?- world:assert(done). % the same ?- world:done. % calls done/0 in module world 44..77 DDyynnaammiicc MMoodduulleess So far, we discussed modules that were created by loading a module-file. These modules have been introduced on facilitate the development of large applications. The modules are fully defined at load-time of the application and normally will not change during execution. Having the notion of a set of predicates as a self-contained world can be attractive for other purposes as well. For example, assume an application that can reason about multiple worlds. It is attractive to store the data of a particular world in a module, so we extract information from a world simply by invoking goals in this world. Dynamic modules can easily be created. Any built-in predicate that tries to locate a predicate in a specific module will create this module as a side-effect if it did not yet exist. Example: ?- assert(world_a:consistent), world_a:unknown(_, fail). These calls create a module called `world_a' and make the call `world_a:consistent' succeed. Undefined predicates will not start the tracer or autoloader for this module (see uunnkknnoowwnn//22). Import and export from dynamically created world is arranged via the predicates iimmppoorrtt//11 and eexxppoorrtt//11: ?- world_b:export(solve(_,_)). % exports solve/2 from world_b ?- world_c:import(world_b:solve(_,_)). % and import it to world_c 44..88 MMoodduullee HHaannddlliinngg PPrreeddiiccaatteess This section gives the predicate definitions for the remaining built-in predicates that handle modules. ::-- mmoodduullee((_+_M_o_d_u_l_e_, _+_P_u_b_l_i_c_L_i_s_t)) This directive can only be used as the first term of a source file. It declares the file to be a _m_o_d_u_l_e _f_i_l_e, defining _M_o_d_u_l_e and exporting the predicates of _P_u_b_l_i_c_L_i_s_t. _P_u_b_l_i_c_L_i_s_t is a list of name/arity pairs. mmoodduullee__ttrraannssppaarreenntt _+_P_r_e_d_s _P_r_e_d_s is a comma separated list of name/arity pairs (like ddyynnaammiicc//11). Each goal associated with a transparent declared predicate will inherit the _c_o_n_t_e_x_t _m_o_d_u_l_e from its parent goal. mmeettaa__pprreeddiiccaattee _+_H_e_a_d_s This predicate is defined in library(quintus) and provides a partial emulation of the Quintus predicate. See section 4.9.1 for details. ccuurrrreenntt__mmoodduullee((_-_M_o_d_u_l_e)) Generates all currently known modules. ccuurrrreenntt__mmoodduullee((_?_M_o_d_u_l_e_, _?_F_i_l_e)) Is true if _F_i_l_e is the file from which _M_o_d_u_l_e was loaded. _F_i_l_e is the internal canonical filename. See also ssoouurrccee__ffiillee//[[11,,22]]. ccoonntteexxtt__mmoodduullee((_-_M_o_d_u_l_e)) Unify _M_o_d_u_l_e with the context module of the current goal. ccoonntteexxtt__mmoodduullee//11 itself is transparent. eexxppoorrtt((_+_H_e_a_d)) Add a predicate to the public list of the context module. This implies the predicate will be imported into another module if this module is imported with uussee__mmoodduullee//[[11,,22]]. Note that predicates are normally exported using the directive mmoodduullee//22. eexxppoorrtt//11 is meant to handle export from dynamically created modules. eexxppoorrtt__lliisstt((_+_M_o_d_u_l_e_, _?_E_x_p_o_r_t_s)) Unifies _E_x_p_o_r_t_s with a list of terms. Each term has the name and arity of a public predicate of _M_o_d_u_l_e. The order of the terms in _E_x_p_o_r_t_s is not defined. See also pprreeddiiccaattee__pprrooppeerrttyy//22. ddeeffaauulltt__mmoodduullee((_+_M_o_d_u_l_e_, _-_D_e_f_a_u_l_t)) Succesively unifies _D_e_f_a_u_l_t with the module names from which a call in _M_o_d_u_l_e attempts to use the definition. For the module user, this will generate user and system. For any other module, this will generate the module itself, followed by user and system. mmoodduullee((_+_M_o_d_u_l_e)) The call module(Module) may be used to switch the default working module for the interactive toplevel (see pprroolloogg//00). This may be used to when debugging a module. The example below lists the clauses of file_of_label/2 in the module tex. 1 ?- module(tex). Yes tex: 2 ?- listing(file_of_label/2). ... 44..99 CCoommppaattiibbiilliittyy ooff tthhee MMoodduullee SSyysstteemm The principles behind the module system of SWI-Prolog differ in a number of aspects from the Quintus Prolog module system. o The SWI-Prolog module system allows the user to redefine system predicates. o All predicates that are available in the system and user modules are visible in all other modules as well. o Quintus has the `mmeettaa__pprreeddiiccaattee//11' declaration were SWI-Prolog has the mmoodduullee__ttrraannssppaarreenntt//11 declaration. The mmeettaa__pprreeddiiccaattee//11 declaration causes the compiler to tag arguments that pass module sensitive information with the module using the ://22 operator. This approach has some disadvantages: o Changing a meta_predicate declaration implies all predicates ccaalllliinngg the predicate need to be reloaded. This can cause serious consistency problems. o It does not help for dynamically defined predicates calling module sensitive predicates. o It slows down the compiler (at least in the SWI-Prolog architecture). o At least within the SWI-Prolog architecture the run-time overhead is larger than the overhead introduced by the transparent mechanism. Unfortunately the transparent predicate approach also has some disadvantages. If a predicate A passes module sensitive information to a predicate B, passing the same information to a module sensitive system predicate both A and B should be declared transparent. Using the Quintus approach only A needs to be treated special (i.e. declared with mmeettaa__pprreeddiiccaattee//11). A second problem arises if the body of a transparent predicate uses module sensitive predicates for which it wants to refer to its own module. Suppose we want to define ffiinnddaallll//33 using aasssseerrtt//11 and rreettrraacctt//11. The example in figure 4.1 gives the solution. :- module(findall, [findall/3]). :- dynamic solution/1. :- module_transparent findall/3, store/2. findall(Var, Goal, Bag) :- assert(findall:solution('$mark')), store(Var, Goal), collect(Bag). store(Var, Goal) :- Goal, % refers to context module of % caller of findall/3 assert(findall:solution(Var)), fail. store(_, _). collect(Bag) :- ..., Figure 4.1: ffiinnddaallll//33 using modules 44..99..11 EEmmuullaattiinngg mmeettaa__pprreeddiiccaattee//11 The Quintus mmeettaa__pprreeddiiccaattee//11 directive can in many cases be replaced by the transparent declaration. Below is the definition of mmeettaa__pprreeddiiccaattee//11as available from library(quintus). :- op(1150, fx, (meta_predicate)). meta_predicate((Head, More)) :- !, meta_predicate1(Head), meta_predicate(More). meta_predicate(Head) :- meta_predicate1(Head). meta_predicate1(Head) :- Head =.. [Name|Arguments], member(Arg, Arguments), module_expansion_argument(Arg), !, functor(Head, Name, Arity), module_transparent(Name/Arity). meta_predicate1(_). % just a mode declaration module_expansion_argument(:). module_expansion_argument(N) :- integer(N). The discussion above about the problems with the transparent mechanism show the two cases in which this simple transformation does not work. CChhaapptteerr 55.. FFOORREEIIGGNN LLAANNGGUUAAGGEE IINNTTEERRFFAACCEE SWI-Prolog offers a powerful interface to C [Kernighan & Ritchie, 1978]. The main design objectives of the foreign language interface are flexibility and performance. A foreign predicate is a C-function that has the same number of arguments as the predicate represented. C-functions are provided to analyse the passed terms, convert them to basic C-types as well as to instantiate arguments using unification. Non-deterministic foreign predicates are supported, providing the foreign function with a handle to control backtracking. C can call Prolog predicates, providing both an query interface and an interface to extract multiple solutions from an non-deterministic Prolog predicate. There is no limit to the nesting of Prolog calling C, calling Prolog, etc. It is also possible to write the `main' in C and use Prolog as an embedded logical engine. 55..11 OOvveerrvviieeww ooff tthhee IInntteerrffaaccee A special include file called SWI-Prolog.h should be included with each C-source file that is to be loaded via the foreign interface. The installation process installs this file in the directory include in the SWI-Prolog home directory (?- feature(home, Home).). This C-header file defines various data types, macros and functions that can be used to communicate with SWI-Prolog. Functions and macros can be divided into the following categories: o Analysing Prolog terms o Constructing new terms o Unifying terms o Returning control information to Prolog o Registering foreign predicates with Prolog o Calling Prolog from C o Global actions on Prolog (halt, break, abort, etc.) 55..22 LLiinnkkiinngg FFoorreeiiggnn MMoodduulleess Foreign modules may be linked to Prolog in three ways. Using _s_t_a_t_i_c _l_i_n_k_i_n_g, the extensions, a small description file and the basic SWI-Prolog object file are linked together to form a new executable. Using _d_y_n_a_m_i_c _l_i_n_k_i_n_g, the extensions are linked to a shared library (.so file on most Unix systems) or dynamic-link library (.DLL file on Microsoft platforms) and loaded into the the running Prolog process.. 55..22..11 WWhhaatt lliinnkkiinngg iiss pprroovviiddeedd?? The _s_t_a_t_i_c _l_i_n_k_i_n_g schema can be used on all versions of SWI-Prolog. The ffeeaattuurree//22 predicate may be used to find out what other linking methods are provided for this version. o _f_e_a_t_u_r_e_(_o_p_e_n___s_h_a_r_e_d___o_b_j_e_c_t_, _t_r_u_e_) If this succeeds the system provides the ooppeenn__sshhaarreedd__oobbjjeecctt//22and related predicates that allow for handling Unix shared object files based on the Unix library functions ddllooppeenn((2)) and friends. See section 5.4. o _f_e_a_t_u_r_e_(_d_l_l_, _t_r_u_e_) If this succeeds the system provides an interface for loading .DLL files by means of ooppeenn__ddllll//22 and friends. See section 5.4. If either the feature open_shared_object or dll is true, the library library(shlib) provides a common interface for loading foreign files from Prolog. 55..22..22 WWhhaatt kkiinndd ooff llooaaddiinngg sshhoouulldd II bbee uussiinngg?? All described approaches have their advantages and disadvantages. Static linking is portable and allows for debugging on all platforms. It is relatively cumbersome and the libraries you need to pass to the linker may vary from system to system. Loading shared objects or DLL files provides sharing and protection and is generally the best choice. The old (and also badly portable) ssaavvee//[[11,,22]] and ssaavvee__pprrooggrraamm//[[11,,22]] do not cooperate with this mechanism, but the more recent qqssaavvee__pprrooggrraamm//[[11,,22]]can be used to created programs that load the appropriate library at startup. Note that the definition of the foreign predicates is the same, regardless of the linking type used. 55..33 DDyynnaammiicc LLiinnkkiinngg ooff sshhaarreedd lliibbrraarriieess The interface defined in this section allows the user to load shared libraries (.so files on most Unix systems). This interface is portable to all machines providing the function ddllooppeenn((2)) or an equivalent, normally from the library -ldl. These functions provide the basic interface layer. It is advised to use the predicates from section 5.4 in your application. ooppeenn__sshhaarreedd__oobbjjeecctt((_+_F_i_l_e_, _-_H_a_n_d_l_e)) _F_i_l_e is the name of a .so file (see your C programmers documenta- tion on how to create a .so file). This file is attached to the current process and _H_a_n_d_l_e is unified with a handle to the shared object. Equivalent to open_shared_object(File, [global], Handle). See also llooaadd__ffoorreeiiggnn__lliibbrraarryy//[[11,,22]]. ooppeenn__sshhaarreedd__oobbjjeecctt((_+_F_i_l_e_, _+_O_p_t_i_o_n_s_, _-_H_a_n_d_l_e)) As ooppeenn__sshhaarreedd__oobbjjeecctt//22, but allows for additional flags to be passed. _O_p_t_i_o_n_s is a list of atoms. now implies the symbols are resolved immediately rather than lazy (default). global implies symbols of the loaded object are visible while loading other shared objects (by default they are local). Note that these flags may not be supported by your operating system. Check the documentation of dlopen() or equivalent on your operating system. cclloossee__sshhaarreedd__oobbjjeecctt((_+_H_a_n_d_l_e)) Detach the shared object identified by _H_a_n_d_l_e. ccaallll__sshhaarreedd__oobbjjeecctt__ffuunnccttiioonn((_+_H_a_n_d_l_e_, _+_F_u_n_c_t_i_o_n)) Call the named function in the loaded shared library. The function is called without arguments and the return-value is ignored. Normally this function installs foreign language predicates using calls to PPLL__rreeggiisstteerr__ffoorreeiiggnn(()). 55..44 UUssiinngg tthhee lliibbrraarryy sshhlliibb ffoorr .DLL aanndd .so ffiilleess This section discusses the functionality of the (autoload) library shlib.pl, providing an interface to shared libraries. Currently it supports MS-Windows DLL (.DLL) libraries and Unix .so (shared object) files. llooaadd__ffoorreeiiggnn__lliibbrraarryy((_+_L_i_b)) Equivalent to load_foreign_library(Lib, install). llooaadd__ffoorreeiiggnn__lliibbrraarryy((_+_L_i_b_, _+_E_n_t_r_y)) Search for the given foreign library and link it to the current SWI-Prolog instance. The library may be specified with or without the extension. First, aabbssoolluuttee__ffiillee__nnaammee//33is used to locate the file. If this succeeds, the full path is passed to the low-level function to open the library. Otherwise, the plain library name is passed, exploiting the operating-system defined search mechanism for the shared library. The ffiillee__sseeaarrcchh__ppaatthh//22 alias mechanism defines the alias foreign, which refers to the directories <_p_l_h_o_m_e>/lib/<_a_r_c_h>and <_p_l_h_o_m_e>/lib, in this order. If the library can be loaded, the function called _E_n_t_r_y will be called without arguments. The return value of the function is ignored. The _E_n_t_r_y function will normally call PPLL__rreeggiisstteerr__ffoorreeiiggnn(()) to declare functions in the library as foreign predicates. uunnllooaadd__ffoorreeiiggnn__lliibbrraarryy((_+_L_i_b)) If the foreign library defines the function uninstall(), this function will be called without arguments and its return value is ignored. Next, aabboolliisshh//22 is used to remove all known foreign predicates defined in the library. Finally the library itself is detached from the process. ccuurrrreenntt__ffoorreeiiggnn__lliibbrraarryy((_-_L_i_b_, _-_P_r_e_d_i_c_a_t_e_s)) Query the currently loaded foreign libraries and their predicates. _P_r_e_d_i_c_a_t_e_s is a list with elements of the form _M_o_d_u_l_e_:_H_e_a_d, indicating the predicates installed with PPLL__rreeggiisstteerr__ffoorreeiiggnn(())when the entry-point of the library was called. Figure 5.1 connects a Windows message-box using a foreign function. This example was tested using Windows NT and Microsoft Visual C++ 2.0. #include #include static foreign_t pl_say_hello(term_t to) { char *a; if ( PL_get_atom_chars(to, &a) ) { MessageBox(NULL, a, "DLL test", MB_OK|MB_TASKMODAL); PL_succeed; } PL_fail; } install_t install() { PL_register_foreign("say_hello", 1, pl_say_hello, 0); } Figure 5.1: MessageBox() example in Windows NT 55..44..11 SSttaattiicc LLiinnkkiinngg Below is an outline of the files structure required for statically linking SWI-Prolog with foreign extensions. .../pl refers to the SWI-Prolog home directory (see ffeeaattuurree//22). <_a_r_c_h> refers to the architecture identifier that may be obtained using ffeeaattuurree//22. .../pl/runtime/<_a_r_c_h>/libpl.a SWI-Library .../pl/include/SWI-Prolog.h Include file .../pl/include/SWI-Stream.h Stream I/O include file .../pl/include/SWI-Exports Export declarations (AIX only) .../pl/include/stub.c Extension stub The definition of the foreign predicates is the same as for dynamic linking. Unlike with dynamic linking however, there is no initialisation function. Instead, the file .../pl/include/stub.c may be copied to your project and modified to define the foreign extensions. Below is stub.c, modified to link the lowercase example described later in this chapter: /* Copyright (c) 1991 Jan Wielemaker. All rights reserved. jan@swi.psy.uva.nl Purpose: Skeleton for extensions */ #include #include extern foreign_t pl_lowercase(term, term); PL_extension predicates[] = { /*{ "name", arity, function, PL_FA_ },*/ { "lowercase", 2 pl_lowercase, 0 }, { NULL, 0, NULL, 0 } /* terminating line */ }; int main(int argc, char **argv) { PL_register_extensions(predicates); if ( !PL_initialise(argc, argv) ) PL_halt(1); PL_install_readline(); /* delete if not required */ PL_halt(PL_toplevel() ? 0 : 1); } Now, a new executable may be created by compiling this file and linking it to libpl.a from the runtime directory and the libraries required by both the extensions and the SWI-Prolog kernel. This may be done by hand, or using the plld utility described in secrefplld. 55..44..22 DDyynnaammiicc LLiinnkkiinngg bbaasseedd oonn llooaadd__ffoorreeiiggnn//[[22,,55]] The predicates below are considered obsolete. They are briefly described here for compatibility purposes. New code should use the predicates from the library(shlib). llooaadd__ffoorreeiiggnn((_+_F_i_l_e_, _+_E_n_t_r_y)) Load a foreign file or list of files specified by _F_i_l_e. The files are searched for similar to ccoonnssuulltt//11. Except that the `.o' extension is used rather than `.pl'. _E_n_t_r_y defines the entry point of the resulting executable. The entry point will be called by Prolog to install the foreign predicates. llooaadd__ffoorreeiiggnn((_+_F_i_l_e_, _+_E_n_t_r_y_, _+_O_p_t_i_o_n_s_, _+_L_i_b_r_a_r_i_e_s_, _+_S_i_z_e)) The first two arguments are identical to those of llooaadd__ffoorreeiiggnn//22. _O_p_t_i_o_n_s is (a list of) additional option to be given to the loader. The options are inserted just before the files. _L_i_b_r_a_r_i_e_s is (a list of) libraries to be passed to the loader. They are inserted just after the files. If _S_i_z_e is specified Prolog first assumes that the resulting executable will fit in _S_i_z_e bytes and do the loading in one pass. ffoorreeiiggnn__ffiillee((_?_F_i_l_e)) Is true if _F_i_l_e is the absolute path name of a file loaded as foreign file. 55..55 IInntteerrffaaccee DDaattaa ttyyppeess 55..55..11 TTyyppee term_t:: aa rreeffeerreennccee ttoo aa PPrroolloogg tteerrmm The principal data-type is term_t. Type term_t is what Quintus calls QP_term_ref. This name indicates better what the type represents: it is a _h_a_n_d_l_e for a term rather than the term itself. Terms can only be represented and manipulated using this type, as this is the only safe way to ensure the Prolog kernel is aware of all terms referenced by foreign code and thus allows the kernel to perform garbage-collection and/or stack-shifts while foreign code is active, for example during a callback from C. A term reference is a C unsigned long, representing the offset of a variable on the Prolog environment-stack. A foreign function is passed term references for the predicate-arguments, one for each argument. If references for intermediate results are needed, such references may be created using PPLL__nneeww__tteerrmm__rreeff(())or PPLL__nneeww__tteerrmm__rreeffss(()). These references normally live till the foreign function returns control back to Prolog. Their scope can be explicitly limited using PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())and PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(())/PPLL__ddiissccaarrdd__ffoorreeiiggnn__ffrraammee(()). A term_t always refers to a valid Prolog term (variable, atom, integer, float or compound term). A term lives either until backtracking takes us back to a point before the term was created, the garbage collector has collected the term or the term was created after a PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())and PPLL__ddiissccaarrdd__ffoorreeiiggnn__ffrraammee(())has been called. The foreign-interface functions can either _r_e_a_d, _u_n_i_f_y or _w_r_i_t_e to term-references. In the this document we use the following notation for arguments of type term_t: term_t +t Accessed in read-mode. The `+' indicates the argument is `input'. term_t -t Accessed in write-mode. term_t ?t Accessed in unify-mode. Term references are obtained in any of the following ways. o _P_a_s_s_e_d _a_s _a_r_g_u_m_e_n_t The C-functions implementing foreign predicates are passed their arguments as term-references. These references may be read or unified. Writing to these variables causes undefined behaviour. o _C_r_e_a_t_e_d _b_y PPLL__nneeww__tteerrmm__rreeff(()) A term created by PPLL__nneeww__tteerrmm__rreeff(())is normally used to build temporary terms or be written by one of the interface functions. For example, PPLL__ggeett__aarrgg(())writes a reference to the term-argument in its last argument. o _C_r_e_a_t_e_d _b_y PPLL__nneeww__tteerrmm__rreeffss((_i_n_t _n)) This function returns a set of term refs with the same characteristics as PPLL__nneeww__tteerrmm__rreeff(()). See PPLL__ooppeenn__qquueerryy(()). o _C_r_e_a_t_e_d _b_y PPLL__ccooppyy__tteerrmm__rreeff((_t_e_r_m___t _t)) Creates a new term-reference to the same term as the argument. The term may be written to. See figure 5.3. Term-references can safely be copied to other C-variables of type term_t, but all copies will always refer to the same term. _t_e_r_m___t PPLL__nneeww__tteerrmm__rreeff(()) Return a fresh reference to a term. The reference is allocated on the _l_o_c_a_l stack. Allocating a term-reference may trigger a stack-shift on machines that cannot use sparse-memory management for allocation the Prolog stacks. The returned reference describes a variable. _t_e_r_m___t PPLL__nneeww__tteerrmm__rreeffss((_i_n_t _n)) Return _n new term references. The first term-reference is returned. The others are _t +1, _t +2, etc. There are two reasons for using this function. PPLL__ooppeenn__qquueerryy(())expects the arguments as a set of consecutive term references and _v_e_r_y time-critical code requiring a number of term-references can be written as: pl_mypredicate(term_t a0, term_t a1) { term_t t0 = PL_new_term_refs(2); term_t t1 = t0+1; ... } _t_e_r_m___t PPLL__ccooppyy__tteerrmm__rreeff((_t_e_r_m___t _f_r_o_m)) Create a new term reference and make it point initially to the same term as _f_r_o_m. This function is commonly used to copy a predicate argument to a term reference that may be written. _v_o_i_d PPLL__rreesseett__tteerrmm__rreeffss((_t_e_r_m___t _a_f_t_e_r)) Destroy all term references that have been created after _a_f_t_e_r, including _a_f_t_e_r itself. Any reference to the invalidated term references after this call results in undefined behaviour. Note that returning from the foreign context to Prolog will reclaim all references used in the foreign context. This call is only necessary if references are created inside a loop that never exits back to Prolog. See also PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(()), PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(())and PPLL__ddiissccaarrdd__ffoorreeiiggnn__ffrraammee(()). 55..55..11..11 IInntteerraaccttiioonn wwiitthh tthhee ggaarrbbaaggee ccoolllleeccttoorr aanndd ssttaacckk--sshhiifftteerr Prolog implements two mechanisms for avoiding stack overflow: garbage collection and stack expansion. On machines that allow for it, Prolog will use virtual memory management to detect stack overflow and expand the runtime stacks. On other machines Prolog will reallocate the stacks and update all pointers to them. To do so, Prolog needs to know which data is referenced by C-code. As all Prolog data known by C is referenced through term references (term_t), Prolog has all information necessary to perform its memory management without special precautions from the C-programmer. 55..55..22 OOtthheerr ffoorreeiiggnn iinntteerrffaaccee ttyyppeess aattoomm__tt An atom in Prologs internal representation. Atoms are pointers to an opaque structure. They are a unique representation for represented text, which implies that atom A represents the same text as atom B if-and-only-if A and B are the same pointer. Atoms are the central representation for textual constants in Prolog The transformation of C a character string to an atom implies a hash-table lookup. If the same atom is needed often, it is advised to store its reference in a global variable to avoid repeated lookup. ffuunnccttoorr__tt A functor is the internal representation of a name/arity pair. They are used to find the name and arity of a compound term as well as to construct new compound terms. Like atoms they live for the whole Prolog session and are unique. pprreeddiiccaattee__tt Handle to a Prolog predicate. Predicate handles live forever (although they can loose their definition). qqiidd__tt Query Identifier. Used by PPLL__ooppeenn__qquueerryy(())/PPLL__nneexxtt__ssoolluuttiioonn(())/PPLL__cclloossee__qquueerryy(()) to handle back- tracking from C. ffiidd__tt Frame Identifier. Used by PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())/PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(()). mmoodduullee__tt A module is a unique handle to a Prolog module. Modules are used only to call predicates in a specific module. ffoorreeiiggnn__tt Return type for a C-function implementing a Prolog predicate. ccoonnttrrooll__tt Passed as additional argument to non-deterministic foreign functions. See PL_retry*() and PL_foreign_context*(). iinnssttaallll__tt Type for the install() and uninstall() functions of shared or dynamic link libraries. See secrefshlib. 55..66 TThhee FFoorreeiiggnn IInncclluuddee FFiillee 55..66..11 AArrgguummeenntt PPaassssiinngg aanndd CCoonnttrrooll If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1;:::; <_a_r_i_t_y>pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog: _v_o_i_d PPLL__ssuucccceeeedd(()) Succeed deterministically. PL_succeed is defined as return TRUE. _v_o_i_d PPLL__ffaaiill(()) Fail and start Prolog backtracking. PL_fail is defined as return FALSE. 55..66..11..11 NNoonn--ddeetteerrmmiinniissttiicc FFoorreeiiggnn PPrreeddiiccaatteess By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PPLL__rreeggiisstteerr__ffoorreeiiggnn(())) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate: quotient_below_n(Q, N) :- natural_number_below_n(N, N1), natural_number_below_n(N, N2), Q =:= N1 / N2, !. In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations. Non-deterministic foreign functions should be prepared to handle three different calls from Prolog: o _I_n_i_t_i_a_l _c_a_l_l _(PL_FIRST_CALL_) Prolog has just created a frame for the foreign function and asks it to produce the first answer. o _R_e_d_o _c_a_l_l _(PL_REDO_) The previous invocation of the foreign function associated with the current goal indicated it was possible to backtrack. The foreign function should produce the next solution. o _T_e_r_m_i_n_a_t_e _c_a_l_l _(PL_CUTTED_) The choice point left by the foreign function has been destroyed by a cut. The foreign function is given the opportunity to clean the environment. Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PPLL__ffoorreeiiggnn__ccoonnttrrooll(()) extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro. _v_o_i_d PPLL__rreettrryy((_l_o_n_g)) The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PPLL__ffoorreeiiggnn__ccoonntteexxtt(())will return the handle passed via PPLL__rreettrryy(()). This handle is a 30 bits signed value (two bits are used for status indication). _v_o_i_d PPLL__rreettrryy__aaddddrreessss((_v_o_i_d _*)) As PPLL__rreettrryy(()), but ensures an address as returned by malloc() is correctly recovered by PPLL__ffoorreeiiggnn__ccoonntteexxtt__aaddddrreessss(()). _i_n_t PPLL__ffoorreeiiggnn__ccoonnttrrooll((_c_o_n_t_r_o_l___t)) Extracts the type of call from the control argument. The return values are described above. Note that the function should be prepared to handle the PL_CUTTED case and should be aware that the other arguments are not valid in this case. _l_o_n_g PPLL__ffoorreeiiggnn__ccoonntteexxtt((_c_o_n_t_r_o_l___t)) Extracts the context from the context argument. In the call type is PL_FIRST_CALL the context value is 0L. Otherwise it is the value returned by the last PPLL__rreettrryy(()) associated with this goal (both if the call type is PL_REDO as PL_CUTTED). _v_o_i_d _* PPLL__ffoorreeiiggnn__ccoonntteexxtt__aaddddrreessss((_c_o_n_t_r_o_l___t)) Extracts an address as passed in by PPLL__rreettrryy__aaddddrreessss(()). Note: If a non-deterministic foreign function returns using PL_succeed or PL_fail, Prolog assumes the foreign function has cleaned its environment. NNoo call with control argument PL_CUTTED will follow. The code of figure 5.2 shows a skeleton for a non-deterministic foreign predicate definition. typedef struct /* define a context structure */ { ... } context; foreign_t my_function(term_t a0, term_t a1, foreign_t handle) { struct context * ctxt; switch( PL_foreign_control(handle) ) { case PL_FIRST_CALL: ctxt = malloc(sizeof(struct context)); ... PL_retry_address(ctxt); case PL_REDO: ctxt = PL_foreign_context_address(handle); ... PL_retry_address(ctxt); case PL_CUTTED: free(ctxt); PL_succeed; } } Figure 5.2: Skeleton for non-deterministic foreign functions 55..66..22 AAttoommss aanndd ffuunnccttoorrss The following functions provide for communication using atoms and functors. _a_t_o_m___t PPLL__nneeww__aattoomm((_c_o_n_s_t _c_h_a_r _*)) Return an atom handle for the given C-string. This function always succeeds. The returned handle is valid for the entire session. _c_o_n_s_t _c_h_a_r _* PPLL__aattoomm__cchhaarrss((_a_t_o_m___t _a_t_o_m)) Return a C-string for the text represented by the given atom. The returned text will not be changed by Prolog. It is not allowed to modify the contents, not even `temporary' as the string may reside in read-only memory. _f_u_n_c_t_o_r___t PPLL__nneeww__ffuunnccttoorr((_a_t_o_m___t _n_a_m_e_, _i_n_t _a_r_i_t_y)) Returns a _f_u_n_c_t_o_r _i_d_e_n_t_i_f_i_e_r, a handle for the name/arity pair. The returned handle is valid for the entire Prolog session. _a_t_o_m___t PPLL__ffuunnccttoorr__nnaammee((_f_u_n_c_t_o_r___t _f)) Return an atom representing the name of the given functor. _i_n_t PPLL__ffuunnccttoorr__aarriittyy((_f_u_n_c_t_o_r___t _f)) Return the arity of the given functor. 55..66..33 AAnnaallyyssiinngg TTeerrmmss vviiaa tthhee FFoorreeiiggnn IInntteerrffaaccee Each argument of a foreign function (except for the control argument) is of type term_t, an opaque handle to a Prolog term. Three groups of functions are available for the analysis of terms. The first just validates the type, like the Prolog predicates vvaarr//11, aattoomm//11, etc and are called PL_is_*(). The second group attempts to translate the argument into a C primitive type. These predicates take a term_t and a pointer to the appropriate C-type and return TRUE or FALSE depending on successful or unsuccessful translation. If the translation fails, the pointed-to data is never modified. 55..66..33..11 TTeessttiinngg tthhee ttyyppee ooff aa tteerrmm _i_n_t PPLL__tteerrmm__ttyyppee((_t_e_r_m___t)) Obtain the type of a term, which should be a term returned by one of the other interface predicates or passed as an argument. The function returns the type of the Prolog term. The type identifiers are listed below. Note that the extraction functions PL_ge_t*() also validate the type and thus the two sections below are equivalent. if ( PL_is_atom(t) ) { char *s; PL_get_atom_chars(t, &s); ...; } or char *s; if ( PL_get_atom_chars(t, &s) ) { ...; } ___________________________________________________________________ | PL_VARIABLE |An unbound variable. The value of term| | |as such is a unique identifier for the| | |variable. | | PL_ATOM |A Prolog atom. | | PL_STRING |A Prolog string. | | PL_INTEGER |A Prolog integer. | | PL_FLOAT |A Prolog floating point number. | | PL_TERM |A compound term. Note that a list is a| |________________________|compound_term_.//22._______________________| The functions PL_is_<_t_y_p_e> are an alternative to PPLL__tteerrmm__ttyyppee(()). The test PPLL__iiss__vvaarriiaabbllee((_t_e_r_m))is equivalent to PPLL__tteerrmm__ttyyppee((_t_e_r_m))== PL_VARIABLE, but the first is considerably faster. On the other hand, using a switch over PPLL__tteerrmm__ttyyppee(())is faster and more readable then using an if-then-else using the functions below. All these functions return either TRUE or FALSE. _i_n_t PPLL__iiss__vvaarriiaabbllee((_t_e_r_m___t)) Returns non-zero if _t_e_r_m is a variable. _i_n_t PPLL__iiss__aattoomm((_t_e_r_m___t)) Returns non-zero if _t_e_r_m is an atom. _i_n_t PPLL__iiss__ssttrriinngg((_t_e_r_m___t)) Returns non-zero if _t_e_r_m is a string. _i_n_t PPLL__iiss__iinntteeggeerr((_t_e_r_m___t)) Returns non-zero if _t_e_r_m is an integer. _i_n_t PPLL__iiss__ffllooaatt((_t_e_r_m___t)) Returns non-zero if _t_e_r_m is a float. _i_n_t PPLL__iiss__ccoommppoouunndd((_t_e_r_m___t)) Returns non-zero if _t_e_r_m is a compound term. _i_n_t PPLL__iiss__ffuunnccttoorr((_t_e_r_m___t_, _f_u_n_c_t_o_r___t)) Returns non-zero if _t_e_r_m is compound and its functor is _f_u_n_c_t_o_r. This test is equivalent to PPLL__ggeett__ffuunnccttoorr(()), followed by testing the functor, but easier to write and faster. _i_n_t PPLL__iiss__lliisstt((_t_e_r_m___t)) Returns non-zero if _t_e_r_m is a compound term with functor ./2 or the atom []. _i_n_t PPLL__iiss__aattoommiicc((_t_e_r_m___t)) Returns non-zero if _t_e_r_m is atomic (not variable or compound). _i_n_t PPLL__iiss__nnuummbbeerr((_t_e_r_m___t)) Returns non-zero if _t_e_r_m is an integer or float. 55..66..33..22 RReeaaddiinngg ddaattaa ffrroomm aa tteerrmm The functions PL_get_*() read information from a Prolog term. Most of them take two arguments. The first is the input term and the second is a pointer to the output value or a term-reference. _i_n_t PPLL__ggeett__aattoomm((_t_e_r_m___t _+_t_, _a_t_o_m___t _*_a)) If _t is an atom, store the unique atom identifier over _a. See also PPLL__aattoomm__cchhaarrss(())and PPLL__nneeww__aattoomm(()). If there is no need to access the data (characters) of an atom, it is advised to manipulate atoms using their handle. _i_n_t PPLL__ggeett__aattoomm__cchhaarrss((_t_e_r_m___t _+_t_, _c_h_a_r _*_*_s)) If _t is an atom, store a pointer to a 0-terminated C-string in _s. It is explicitly nnoott allowed to modify the contents of this string. Some built-in atoms may have the string allocated in read-only memory, so `temporary manipulation' can cause an error. _i_n_t PPLL__ggeett__ssttrriinngg((_t_e_r_m___t _+_t_, _c_h_a_r _*_*_s_, _i_n_t _*_l_e_n)) If _t is a string object, store a pointer to a 0-terminated C-string in _s and the length of the string in _l_e_n. Note that this pointer is invalidated by backtracking, garbage-collection and stack-shifts, so generally the only save operations are to pass it immediately to a C-function that doesn't involve Prolog. _i_n_t PPLL__ggeett__cchhaarrss((_t_e_r_m___t _+_t_, _c_h_a_r _*_*_s_, _u_n_s_i_g_n_e_d _f_l_a_g_s)) Convert the argument term _t to a 0-terminated C-string. _f_l_a_g_s is a bitwise disjunction from two groups of constants. The first specifies which term-types should converted and the second how the argument is stored. Below is a specification of these constants. BUF_RING implies, if the data is not static (as from an atom), the data is copied to the next buffer from a ring of four (4) buffers. This is a convenient way of converting multiple arguments passed to a foreign predicate to C-strings. If BUF_MALLOC is used, the data must be freed using free() when not needed any longer. ___________________________________________________________________ | CVT_ATOM |Convert if term is an atom | | CVT_STRING |Convert if term is a string | | CVT_LIST |Convert if term is a list of integers| | |between 1 and 255 | | CVT_INTEGER |Convert if term is an integer (using %d) | | CVT_FLOAT |Convert if term is a float (using %f) | | CVT_NUMBER |Convert if term is a integer or float | | CVT_ATOMIC |Convert if term is atomic | | CVT_VARIABLE |Convert variable to print-name | | CVT_ALL |Convert if term is any of the above,| |________________________|except_for_variables_____________________| | BUF_DISCARDABLE |Data must copied immediately | | BUF_RING |Data is stored in a ring of buffers | | BUF_MALLOC |Data is copied to a new buffer returned|| |________________________________________________|by__mmaalllloocc((3))__________________________________________________________|| _i_n_t PPLL__ggeett__lliisstt__cchhaarrss((_+_t_e_r_m___t _l_, _c_h_a_r _*_*_s_, _u_n_s_i_g_n_e_d _f_l_a_g_s)) Same as PPLL__ggeett__cchhaarrss((_l_, _s_, _C_V_T___L_I_S_T___f_l_a_g_s)), provided _f_l_a_g_s contains no of the CVT_* flags. _i_n_t PPLL__ggeett__iinntteeggeerr((_+_t_e_r_m___t _t_, _i_n_t _*_i)) If _t is a Prolog integer, assign its value over _i. On 32-bit machines, this is the same as PPLL__ggeett__lloonngg(()), but avoids a warning from the compiler. See also PPLL__ggeett__lloonngg(()). _i_n_t PPLL__ggeett__lloonngg((_t_e_r_m___t _+_t_, _l_o_n_g _*_i)) If _t is a Prolog integer, assign its value over _i. Note that Prolog integers have limited value-range. If _t is a floating point number that can be represented as a long, this function succeeds as well. _i_n_t PPLL__ggeett__ppooiinntteerr((_t_e_r_m___t _+_t_, _v_o_i_d _*_*_p_t_r)) In the current system, pointers are represented by Prolog integers, but need some manipulation to make sure they do not get truncated due to the limited Prolog integer range. PPLL__ppuutt__ppooiinntteerr(())/PPLL__ggeett__ppooiinntteerr(())guarantees pointers in the range of malloc() are handled without truncating. _i_n_t PPLL__ggeett__ffllooaatt((_t_e_r_m___t _+_t_, _d_o_u_b_l_e _*_f)) If _t is a float or integer, its value is assigned over _f. _i_n_t PPLL__ggeett__ffuunnccttoorr((_t_e_r_m___t _+_t_, _f_u_n_c_t_o_r___t _*_f)) If _t is compound or an atom, the Prolog representation of the name-arity pair will be assigned over _f. See also PPLL__ggeett__nnaammee__aarriittyy(())and PPLL__iiss__ffuunnccttoorr(()). _i_n_t PPLL__ggeett__nnaammee__aarriittyy((_t_e_r_m___t _+_t_, _a_t_o_m___t _*_n_a_m_e_, _i_n_t _*_a_r_i_t_y)) If _t is compound or an atom, the functor-name will be assigned over _n_a_m_e and the arity over _a_r_i_t_y. See also PPLL__ggeett__ffuunnccttoorr(())and PPLL__iiss__ffuunnccttoorr(()). _i_n_t PPLL__ggeett__mmoodduullee((_t_e_r_m___t _+_t_, _m_o_d_u_l_e___t _*_m_o_d_u_l_e)) If _t is an atom, the system will lookup or create the corresponding module and assign an opaque pointer to it over _m_o_d_u_l_e,. _i_n_t PPLL__ggeett__aarrgg((_i_n_t _i_n_d_e_x_, _t_e_r_m___t _+_t_, _t_e_r_m___t _-_a)) If _t is compound and index is between 1 and arity (including), assign _a with a term-reference to the argument. 55..66..33..33 RReeaaddiinngg aa lliisstt The functions from this section are intended to read a Prolog list from C. Suppose we expect a list of atoms, the following code will print the atoms, each on a line: foreign_t pl_write_atoms(term_t l) { term_t head = PL_new_term_ref(); /* variable for the elements */ term_t list = PL_copy_term_ref(); /* copy as we need to write */ while( PL_get_list(list, head, list) ) { char *s; if ( PL_get_atom_chars(head, &s) ) Sprintf("%s\n", s); else PL_fail; } return PL_get_nil(list); /* test end for [] */ } _i_n_t PPLL__ggeett__lliisstt((_t_e_r_m___t _+_l_, _t_e_r_m___t _-_h_, _t_e_r_m___t _-_t)) If _l is a list and not [] assign a term-reference to the head to _h and to the tail to _t. _i_n_t PPLL__ggeett__hheeaadd((_t_e_r_m___t _+_l_, _t_e_r_m___t _-_h)) If _l is a list and not [] assign a term-reference to the head to _h. _i_n_t PPLL__ggeett__ttaaiill((_t_e_r_m___t _+_l_, _t_e_r_m___t _-_t)) If _l is a list and not [] assign a term-reference to the tail to _t. _i_n_t PPLL__ggeett__nniill((_t_e_r_m___t _+_l)) Succeeds if represents the atom []. 55..66..33..44 AAnn eexxaammppllee:: ddeeffiinniinngg ddiissppllaayy//11 iinn CC Figure 5.3 shows a definition of ddiissppllaayy//11 to illustrate the described functions. foreign_t pl_display(term_t t) { functor_t functor; int arity, len, n; char *s; switch( PL_term_type(t) ) { case PL_VARIABLE: case PL_ATOM: case PL_INTEGER: case PL_FLOAT: PL_get_chars(t, &s, CVT_ALL); Sprintf("%s", s); break; case PL_STRING: PL_get_string_chars(t, &s, &len); Sprintf("\"%s\"", s); break; case PL_TERM: { term_t a = PL_new_term_ref(); PL_get_name_arity(t, &name, &arity); Sprintf("%s(", PL_atom_chars(name)); for(n=1; n<=arity; n++) { PL_get_arg(n, t, a); if ( n > 1 ) Sprintf(", "); pl_display(a); } Sprintf(")"); break; default: PL_fail; /* should not happen */ } PL_succeed; } Figure 5.3: A Foreign definition of ddiissppllaayy//11 55..66..44 CCoonnssttrruuccttiinngg TTeerrmmss Terms can be constructed using functions from the PL_put_*() and PL_cons_*() families. This approach builds the term `inside-out', starting at the leaves and subsequently creating compound terms. Alternatively, terms may be created `top-down', first creating a compound holding only variables and subsequently unifying the arguments. This section discusses functions for the first approach. This approach is generally used for creating arguments for PPLL__ccaallll(()) and PL_open_query. _v_o_i_d PPLL__ppuutt__vvaarriiaabbllee((_t_e_r_m___t _-_t)) Put a fresh variable in the term. The new variable lives on the global stack. Note that the initial variable lives on the local stack and is lost after a write to the term-references. After using this function, the variable will continue to live. _v_o_i_d PPLL__ppuutt__aattoomm((_t_e_r_m___t _-_t_, _a_t_o_m___t _a)) Put an atom in the term reference from a handle. See also PPLL__nneeww__aattoomm(())and PPLL__aattoomm__cchhaarrss(()). _v_o_i_d PPLL__ppuutt__aattoomm__cchhaarrss((_t_e_r_m___t _-_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s)) Put an atom in the term-reference constructed from the 0-terminated string. The string itself will never be references by Prolog after this function. _v_o_i_d PPLL__ppuutt__ssttrriinngg__cchhaarrss((_t_e_r_m___t _-_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s)) Put a string in the term-reference. The data will be copied. _v_o_i_d PPLL__ppuutt__lliisstt__cchhaarrss((_t_e_r_m___t _-_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s)) Put a list of ASCII values in the term-reference. _v_o_i_d PPLL__ppuutt__iinntteeggeerr((_t_e_r_m___t _-_t_, _l_o_n_g _i)) Put a Prolog integer in the term reference. _v_o_i_d PPLL__ppuutt__ppooiinntteerr((_t_e_r_m___t _-_t_, _v_o_i_d _*_p_t_r)) Put a Prolog integer in the term-reference. Provided ptr is in the `malloc()-area', PPLL__ggeett__ppooiinntteerr(())will get the pointer back. _v_o_i_d PPLL__ppuutt__ffllooaatt((_t_e_r_m___t _-_t_, _d_o_u_b_l_e _f)) Put a floating-point value in the term-reference. _v_o_i_d PPLL__ppuutt__ffuunnccttoorr((_t_e_r_m___t _-_t_, _f_u_n_c_t_o_r___t _f_u_n_c_t_o_r)) Create a new compound term from _f_u_n_c_t_o_r and bind _t to this term. All arguments of the term will be variables. To create a term with instantiated arguments, either instantiate the arguments using the PL_unify_*() functions or use PPLL__ccoonnss__ffuunnccttoorr(()). _v_o_i_d PPLL__ppuutt__lliisstt((_t_e_r_m___t _-_l)) Same as PPLL__ppuutt__ffuunnccttoorr((_l_, _P_L___n_e_w___f_u_n_c_t_o_r_(_P_L___n_e_w___a_t_o_m_(_"_._")), 2)). _v_o_i_d PPLL__ppuutt__nniill((_t_e_r_m___t _-_l)) Same as PPLL__ppuutt__aattoomm__cchhaarrss((_"_[_]_")). _v_o_i_d PPLL__ppuutt__tteerrmm((_t_e_r_m___t _-_t_1_, _t_e_r_m___t _+_t_2)) Make _t_1 point to the same term as _t_2. _v_o_i_d PPLL__ccoonnss__ffuunnccttoorr((_t_e_r_m___t _-_h_, _f_u_n_c_t_o_r___t _f_, _._._.)) Create a term, whose arguments are filled from variable argument list holding the same number of term_t objects as the arity of the functor. To create the term animal(gnu, 50), use: term_t a1 = PL_new_term_ref(); term_t a2 = PL_new_term_ref(); term_t t; PL_put_atom_chars(a1, "gnu"); PL_put_integer(a2, 50); PL_cons_functor(t, PL_new_functor(PL_new_atom("animal"), 2), a1, a2); After this sequence, the term-references _a_1 and _a_2 may be used for other purposes. _v_o_i_d PPLL__ccoonnss__lliisstt((_t_e_r_m___t _-_l_, _t_e_r_m___t _+_h_, _t_e_r_m___t _+_t)) Create a list (cons-) cell in _l from the head and tail. The code below creates a list of atoms from a char **. The list is built tail-to-head. The PL_unify_*() functions can be used to build a list head-to-tail. void put_list(term_t l, int n, char **words) { term_t a = PL_new_term_ref(); PL_put_nil(l); while( --n >= 0 ) { PL_put_atom_chars(a, words[n]); PL_put_list(l, a, l); } } 55..66..55 UUnniiffyyiinngg ddaattaa The functions of this sections _u_n_i_f_y terms with other terms or translated C-data structures. Except for PPLL__uunniiffyy(()), the functions of this section are specific to SWI-Prolog. They have been introduced to make translation of old code easier, but also because they provide for a faster mechanism for returning data to Prolog that requires less term-references. Consider the case where we want a foreign function to return the host name of the machine Prolog is running on. Using the PL_get_*() and PL_put_*() functions, the code becomes: foreign_t pl_hostname(term_t name) { char buf[100]; if ( gethostname(buf, sizeof(buf)) ) { term_t tmp = PL_new_term_ref(); PL_put_atom_chars(tmp, buf); return PL_unify(name, buf); } PL_fail; } Using PPLL__uunniiffyy__aattoomm__cchhaarrss(()), this becomes: foreign_t pl_hostname(term_t name) { char buf[100]; if ( gethostname(buf, sizeof(buf)) ) return PL_unify_atom_chars(name, buf); PL_fail; } _i_n_t PPLL__uunniiffyy((_t_e_r_m___t _?_t_1_, _t_e_r_m___t _?_t_2)) Unify two Prolog terms and return non-zero on success. _i_n_t PPLL__uunniiffyy__aattoomm((_t_e_r_m___t _?_t_, _a_t_o_m___t _a)) Unify _t with the atom _a and return non-zero on success. _i_n_t PPLL__uunniiffyy__aattoomm__cchhaarrss((_t_e_r_m___t _?_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s)) Unify _t with an atom created from _c_h_a_r_s and return non-zero on success. _i_n_t PPLL__uunniiffyy__lliisstt__cchhaarrss((_t_e_r_m___t _?_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s)) Unify _t with a list of ASCII characters constructed from _c_h_a_r_s. _i_n_t PPLL__uunniiffyy__ssttrriinngg__cchhaarrss((_t_e_r_m___t _?_t_, _c_o_n_s_t _c_h_a_r _*_c_h_a_r_s)) Unify _t with a Prolog string object created from _c_h_a_r_s. _i_n_t PPLL__uunniiffyy__iinntteeggeerr((_t_e_r_m___t _?_t_, _l_o_n_g _n)) Unify _t with a Prolog integer from _n. _i_n_t PPLL__uunniiffyy__ffllooaatt((_t_e_r_m___t _?_t_, _d_o_u_b_l_e _f)) Unify _t with a Prolog float from _f. _i_n_t PPLL__uunniiffyy__ppooiinntteerr((_t_e_r_m___t _?_t_, _v_o_i_d _*_p_t_r)) Unify _t with a Prolog integer describing the pointer. See also PPLL__ppuutt__ppooiinntteerr(())and PPLL__ggeett__ppooiinntteerr(()). _i_n_t PPLL__uunniiffyy__ffuunnccttoorr((_t_e_r_m___t _?_t_, _f_u_n_c_t_o_r___t _f)) If _t is a compound term with the given functor, just succeed. If it is unbound, create a term and bind the variable, else fails. Not that this function does not create a term if the argument is already instantiated. _i_n_t PPLL__uunniiffyy__lliisstt((_t_e_r_m___t _?_l_, _t_e_r_m___t _-_h_, _t_e_r_m___t _-_t)) Unify _l with a list-cell (./2). If successful, write a reference to the head of the list to _h and a reference to the tail of the list in _t. This reference may be used for subsequent calls to this function. Suppose we want to return a list of atoms from a char **. We could use the example described by PPLL__ppuutt__lliisstt(()), followed by a call to PPLL__uunniiffyy(()), or we can use the code below. If the predicate argument is unbound, the difference is minimal (the code based on PPLL__ppuutt__lliisstt(())is probably slightly faster). If the argument is bound, the code below may fail before reaching the end of the word-list, but even if the unification succeeds, this code avoids a duplicate (garbage) list and a deep unification. foreign_t pl_get_environ(term_t env) { term_t l = PL_copy_term_ref(env); term_t a = PL_new_term_ref(); extern char **environ; while(*environ) { if ( !PL_unify_list(l, a, l) || !PL_unify_atom_chars(a, *environ) ) PL_fail; } return PL_unify_nil(l); } _i_n_t PPLL__uunniiffyy__nniill((_t_e_r_m___t _?_l)) Unify _l with the atom []. _i_n_t PPLL__uunniiffyy__aarrgg((_i_n_t _i_n_d_e_x_, _t_e_r_m___t _?_t_, _t_e_r_m___t _?_a)) Unifies the _i_n_d_e_x_-_t_h argument (1-based) of _t with _a. _i_n_t PPLL__uunniiffyy__tteerrmm((_t_e_r_m___t _?_t_, _._._.)) Unify _t with a (normally) compound term. The remaining arguments is a sequence of a type identifier, followed by the required arguments. This predicate is an extension to the Quintus and SICStus foreign interface from which the SWI-Prolog foreign interface has been derived, but has proved to be a powerful and comfortable way to create compound terms from C. Due to the vararg packing/unpacking and the required type-switching this interface is slightly slower than using the primitives. Please note that some bad C-compilers have fairly low limits on the number of arguments that may be passed to a function. The type identifiers are: PL_VARIABLE nnoonnee No op. Used in arguments of PL_FUNCTOR. PL_ATOM aattoomm__tt Unify the argument with an atom, as in PPLL__uunniiffyy__aattoomm(()). PL_INTEGER lloonngg Unify the argument with an integer, as in PPLL__uunniiffyy__iinntteeggeerr(()). PL_FLOAT ddoouubbllee Unify the argument with a float, as in PPLL__uunniiffyy__ffllooaatt(()). Note that, as the argument is passed using the C vararg conventions, a float must be casted to a double explicitly. PL_STRING ccoonnsstt cchhaarr ** Unify the argument with a string object, as in PPLL__uunniiffyy__ssttrriinngg__cchhaarrss(()). PL_TERM tteerrmm__tt Unify a subterm. Note this may the return value of a PPLL__nneeww__tteerrmm__rreeff(())call to get access to a variable. PL_CHARS ccoonnsstt cchhaarr ** Unify the argument with an atom, constructed from the C char *, as in PPLL__uunniiffyy__aattoomm__cchhaarrss(()). PL_FUNCTOR ffuunnccttoorr__tt,, ...... Unify the argument with a compound term. This specification should be followed by exactly as many specifications as the number of arguments of the compound term. PL_LIST iinntt lleennggtthh,, ...... Create a list of the indicated length. The following arguments contain the elements of the list. For example, to unify an argument with the term language(dutch), the following skeleton may be used: static functor_t FUNCTOR_language1; static void init_constants() { FUNCTOR_language1 = PL_new_functor(PL_new_atom("language"), 1); } foreign_t pl_get_lang(term_t r) { return PL_unify_term(r, PL_FUNCTOR, FUNCTOR_language1, PL_CHARS, "dutch"); } install_t install() { PL_register_foreign("get_lang", 1, pl_get_lang, 0); init_constants(); } 55..66..66 CCaalllliinngg PPrroolloogg ffrroomm CC The Prolog engine can be called from C. There are to interfaces for this. For the first, a term is created that could be used as an argument to ccaallll//11 and next PPLL__ccaallll(()) is used to call Prolog. This system is simple, but does not allow to inspect the different answers to a non-deterministic goal and is relatively slow as the runtime system needs to find the predicate. The other interface is based on PPLL__ooppeenn__qquueerryy(()), PPLL__nneexxtt__ssoolluuttiioonn(())and PPLL__ccuutt__qquueerryy(())or PPLL__cclloossee__qquueerryy(()). This mechanism is more powerful, but also more complicated to use. 55..66..66..11 PPrreeddiiccaattee rreeffeerreenncceess This section discusses the functions used to communicate about predicates. Though a Prolog predicate may defined or not, redefined, etc., a Prolog predicate has a handle that is not destroyed, nor moved. This handle is known by the type predicate_t. _p_r_e_d_i_c_a_t_e___t PPLL__pprreedd((_f_u_n_c_t_o_r___t _f_, _m_o_d_u_l_e___t _m)) Return a handle to a predicate for the specified name/arity in the given module. This function always succeeds, creating a handle for an undefined predicate if no handle was available. _p_r_e_d_i_c_a_t_e___t PPLL__pprreeddiiccaattee((_c_o_n_s_t _c_h_a_r _*_n_a_m_e_, _i_n_t _a_r_i_t_y_, _c_o_n_s_t _c_h_a_r_* _m_o_d_u_l_e)) Same a PPLL__pprreedd(()), but provides a more convenient interface to the C-programmer. _v_o_i_d PPLL__pprreeddiiccaattee__iinnffoo((_p_r_e_d_i_c_a_t_e___t _p_, _a_t_o_m___t _*_n_, _i_n_t _*_a_, _m_o_d_u_l_e___t _*_m)) Return information on the predicate _p. The name is stored over _n, the arity over _a, while _m receives the definition module. Note that the latter need not be the same as specified with PPLL__pprreeddiiccaattee(()). If the predicate was imported into the module given to PPLL__pprreeddiiccaattee(()), this function will return the module where the predicate was defined. 55..66..66..22 IInniittiiaattiinngg aa qquueerryy ffrroomm CC This section discusses the functions for creating and manipulating queries from C. Note that a foreign context can have at most one active query. This implies it is allowed to make strictly nested calls between C and Prolog (Prolog calls C, calls Prolog, calls C, etc., but it is nnoott allowed to open multiple queries and start generating solutions for each of them by calling PPLL__nneexxtt__ssoolluuttiioonn(()). Be sure to call PPLL__ccuutt__qquueerryy(()) or PPLL__cclloossee__qquueerryy(())on any query you opened before opening the next or returning control back to Prolog. _q_i_d___t PPLL__ooppeenn__qquueerryy((_m_o_d_u_l_e___t _c_t_x_, _i_n_t _f_l_a_g_s_, _p_r_e_d_i_c_a_t_e___t _p_, _t_e_r_m___t _+_t_0)) Opens a query and returns an identifier for it. This function always succeeds, regardless whether the predicate is defined or not. _c_t_x is the _c_o_n_t_e_x_t _m_o_d_u_l_e of the goal. When NULL, the context module of the calling context will be used, or user if there is no calling context (as may happen in embedded systems). Note that the context module only matters for _m_o_d_u_l_e___t_r_a_n_s_p_a_r_e_n_t predicates. See ccoonntteexxtt__mmoodduullee//11 and mmoodduullee__ttrraannssppaarreenntt//11. The _p argument specifies the predicate, and should be the result of a call to PPLL__pprreedd(()) or PPLL__pprreeddiiccaattee(()). Note that it is allowed to store this handle as global data and reuse it for future queries. The term-reference _t_0 is the first of a vector of term-references as returned by PPLL__nneeww__tteerrmm__rreeffss((_n)). The _f_l_a_g_s arguments provides some additional options concerning debugging and exception handling. It is a bitwise or of the following values: PL_Q_NORMAL Normal operation. The debugger inherits its settings from the environment. If an exception occurs that is not handled in Prolog, a message is printed and the tracer is started to debug the error. PL_Q_NODEBUG Switch off the debugger while executing the goal. This option is used by many calls to hook-predicates to avoid tracing the hooks. An example is pprriinntt//11 calling ppoorrttrraayy//11 from foreign code. PL_Q_CATCH_EXCEPTION If an exception is raised while executing the goal, do not report it, but make it available for PPLL__eexxcceeppttiioonn(()). PL_Q_PASS_EXCEPTION As PL_Q_CATCH_EXCEPTION, but do not invalidate the exception- term while calling PPLL__cclloossee__qquueerryy(()). This option is experimental. The example below opens a query to the predicate is_a/2 to find the ancestor of for some name. char * ancestor(const char *me) { term_t a0 = PL_new_term_refs(2); static predicate_t p; if ( !p ) p = PL_predicate("is_a", 2, "database"); PL_put_atom_chars(a0, me); PL_open_query(NULL, PL_Q_NORMAL, p, a0); ... } _i_n_t PPLL__nneexxtt__ssoolluuttiioonn((_q_i_d___t _q_i_d)) Generate the first (next) solution for the given query. The return value is TRUE if a solution was found, or FALSE to indicate the query could not be proven. This function may be called repeatedly until it fails to generate all solutions to the query. _v_o_i_d PPLL__ccuutt__qquueerryy((_q_i_d)) Discards the query, but does not delete any of the data created by the query. It just invalidate _q_i_d, allowing for a new call to PPLL__ooppeenn__qquueerryy(())in this context. _v_o_i_d PPLL__cclloossee__qquueerryy((_q_i_d)) As PPLL__ccuutt__qquueerryy(()), but all data and bindings created by the query are destroyed. _i_n_t PPLL__ccaallll__pprreeddiiccaattee((_m_o_d_u_l_e___t _m_, _i_n_t _d_e_b_u_g_, _p_r_e_d_i_c_a_t_e___t _p_r_e_d_, _t_e_r_m___t _+_t_0)) Shorthand for PPLL__ooppeenn__qquueerryy(()), PPLL__nneexxtt__ssoolluuttiioonn(()), PPLL__ccuutt__qquueerryy(()), generating a single solution. The arguments are the same as for PPLL__ooppeenn__qquueerryy(()), the return value is the same as PPLL__nneexxtt__ssoolluuttiioonn(()). _i_n_t PPLL__ccaallll((_t_e_r_m___t_, _m_o_d_u_l_e___t)) Call term just like the Prolog predicate oonnccee//11. _T_e_r_m is called in the specified module, or in the context module if module_t = NULL. Returns TRUE if the call succeeds, FALSE otherwise. Figure 5.4 shows an example to obtain the number of defined atoms. All checks are omitted to improve readability. 55..66..77 DDiissccaarrddiinngg DDaattaa The Prolog data created and term-references needed to setup the call and/or analyse the result can in most cases be discarded right after the call. PPLL__cclloossee__qquueerryy(())allows for destructing the data, while leaving the term-references. The calls below may be used to destroy term-references and data. See figure 5.4 for an example. _f_i_d___t PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(()) Created a foreign frame, holding a mark that allows the system to undo bindings and destroy data created after it as well as providing the environment for creating term-references. This function is called by the kernel before calling a foreign predicate. _v_o_i_d PPLL__cclloossee__ffoorreeiiggnn__ffrraammee((_f_i_d___t _i_d)) Discard all term-references created after the frame was opened. All other Prolog data is retained. This function is called by the kernel whenever a foreign function returns control back to Prolog. _v_o_i_d PPLL__ddiissccaarrdd__ffoorreeiiggnn__ffrraammee((_f_i_d___t _i_d)) Same as PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(()), but also undo all bindings made since the open and destroy all Prolog data. It is obligatory to call either of the two closing functions to discard a foreign frame. Foreign frames may be nested. int count_atoms() { fid_t fid = PL_open_foreign_frame(); term_t goal = PL_new_term_ref(); term_t a1 = PL_new_term_ref(); term_t a2 = PL_new_term_ref(); functor_t s2 = PL_new_functor(PL_new_atom("statistics"), 2); int atoms; PL_put_atom_chars(a1, "atoms"); PL_cons_functor(goal, s2, a1, a2); PL_call(goal, NULL); /* call it in current module */ PL_get_integer(a2, &atoms); PL_discard_foreign_frame(fid); return atoms; } Figure 5.4: Calling Prolog 55..66..88 FFoorreeiiggnn CCooddee aanndd MMoodduulleess Modules are identified via a unique handle. The following functions are available to query and manipulate modules. _m_o_d_u_l_e___t PPLL__ccoonntteexxtt(()) Return the module identifier of the context module of the currently active foreign predicate. _i_n_t PPLL__ssttrriipp__mmoodduullee((_t_e_r_m___t _+_r_a_w_, _m_o_d_u_l_e___t _*_m_, _t_e_r_m___t _-_p_l_a_i_n)) Utility function. If _r_a_w is a term, possibly holding the module construct <_m_o_d_u_l_e>:<_r_e_s_t>this function will make _p_l_a_i_n a reference to <_r_e_s_t> and fill _m_o_d_u_l_e _* with <_m_o_d_u_l_e>. For further nested module constructs the inner most module is returned via _m_o_d_u_l_e _*. If _r_a_w is not a module construct _a_r_g will simply be put in _p_l_a_i_n. If _m_o_d_u_l_e _* is NULL it will be set to the context module. Otherwise it will be left untouched. The following example shows how to obtain the plain term and module if the default module is the user module: { module m = PL_new_module(PL_new_atom("user")); term_t plain = PL_new_term_ref(); PL_strip_module(term, &m, plain); ... _a_t_o_m___t PPLL__mmoodduullee__nnaammee((_m_o_d_u_l_e___t)) Return the name of _m_o_d_u_l_e as an atom. _m_o_d_u_l_e___t PPLL__nneeww__mmoodduullee((_a_t_o_m___t _n_a_m_e)) Find an existing or create a new module with name specified by the atom _n_a_m_e. 55..66..99 PPrroolloogg eexxcceeppttiioonnss iinn ffoorreeiiggnn ccooddee This section discusses PPLL__eexxcceeppttiioonn(()) and PPLL__tthhrrooww(()), the interface functions to detect and generate Prolog exceptions from C-code. PPLL__tthhrrooww(())is similar to tthhrrooww//11, and may be used to return an exception from a foreign predicate. After calling PPLL__tthhrrooww(()), the function implementing a foreign predicate should return failure. If success is returned, the exception is simply discarded. Calling PPLL__tthhrrooww(()) outside the context of a function implementing a foreign predicate results in undefined behaviour. PPLL__eexxcceeppttiioonn(()) may be used after a call to PPLL__nneexxtt__ssoolluuttiioonn(())fails, and returns a term reference to an exception term if an exception was raised, and 0 otherwise. If a C-function, implementing a predicate calls Prolog and detects an exception using PPLL__eexxcceeppttiioonn(()), it can handle this exception, or return with the exception. Some caution is required though. It is nnoott allowed to call PPLL__cclloossee__qquueerryy(())or PPLL__ddiissccaarrdd__ffoorreeiiggnn__ffrraammee(())afterwards, as this will invalidate the exception term. Below is the code that calls a Prolog defined arithmetic function (see aarriitthhmmeetthhiicc__ffuunnccttiioonn//11). If PPLL__nneexxtt__ssoolluuttiioonn(()) succeeds, the result is analysed and translated to a number, after which the query is closed and all Prolog data created after PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())is destroyed. On the other hand, if PPLL__nneexxtt__ssoolluuttiioonn(())fails and if an exception was raised, just pass it. Otherwise generate an exception (PPLL__eerrrroorr(()) is an internal call for building the standard error terms and calling PPLL__tthhrrooww(())). After this, the Prolog environment should be discarded using PPLL__ccuutt__qquueerryy(()) and PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(())to avoid invalidating the exception term. static int prologFunction(ArithFunction f, term_t av, Number r) { int arity = f->proc->definition->functor->arity; fid_t fid = PL_open_foreign_frame(); qid_t qid; int rval; qid = PL_open_query(NULL, PL_Q_NORMAL, f->proc, av); if ( PL_next_solution(qid) ) { rval = valueExpression(av+arity-1, r); PL_close_query(qid); PL_discard_foreign_frame(fid); } else { term_t except; if ( (except = PL_exception(qid)) ) { rval = PL_throw(except); /* pass exception */ } else { char *name = stringAtom(f->proc->definition->functor->name); /* generate exception */ rval = PL_error(name, arity-1, NULL, ERR_FAILED, f->proc); } PL_cut_query(qid); /* donot destroy data */ PL_close_foreign_frame(fid); /* same */ } return rval; } _i_n_t PPLL__tthhrrooww((_t_e_r_m___t _e_x_c_e_p_t_i_o_n)) Generate an exception (as tthhrrooww//11) and return FALSE. Below is an example returning an exception from foreign predicate: foreign_t pl_hello(term_t to) { char *s; if ( PL_get_atom_chars(to, &s) ) { Sprintf("Hello \"%s\"\n", s); PL_succeed; } else { term_t except = PL_new_term_ref(); PL_unify_term(except, PL_FUNCTOR, PL_new_functor(PL_new_atom("type_error"), 2), PL_ATOM, "atom", PL_TERM, to); return PL_throw(except); } } _t_e_r_m___t PPLL__eexxcceeppttiioonn((_q_i_d___t _q_i_d)) If PPLL__nneexxtt__ssoolluuttiioonn(()) fails, this can be due to normal failure of the Prolog call, or because an exception was raised using tthhrrooww//11. This function returns a handle to the exception term if an exception was raised, or 0 if the Prolog goal simply failed.. 55..66..1100 MMiisscceellllaanneeoouuss _i_n_t PPLL__ccoommppaarree((_t_e_r_m___t _t_1_, _t_e_r_m___t _t_2)) Compares two terms using the standard order of terms and returns -1, 0 or 1. See also ccoommppaarree//33. 55..66..1111 CCaattcchhiinngg SSiiggnnaallss ((SSooffttwwaarree IInntteerrrruuppttss)) SWI-Prolog catches the Unix signals SIGINT, SIGFPE and SIGSEGV. To avoid problems with foreign code attempting to catch these signals foreign code should call PPLL__ssiiggnnaall(()) to install signal handlers rather than the Unix library function signal(). SWI-Prolog will always handle SIGINT itself. SIGFPE and SIGSEGV are passed to the foreign code handlers if Prolog did not expect that signal. _v_o_i_d _(_*_)_(_) PPLL__ssiiggnnaall((_s_i_g_, _f_u_n_c)) This function should be used to install signal handlers rather than the Unix library function signal(). It ensures consistent signal handling between SWI-Prolog and the foreign code and reinstalls signal handlers if a state created with ssaavvee__pprrooggrraamm//11 is restarted. 55..66..1122 EErrrroorrss aanndd wwaarrnniinnggss Two standard functions are available to print standard Prolog errors to the standard error stream. _i_n_t PPLL__wwaarrnniinngg((_f_o_r_m_a_t_, _a_1_, _._._.)) Print an error message starting with `[WARNING: ', followed by the output from _f_o_r_m_a_t, followed by a `]' and a newline. Then start the tracer. _f_o_r_m_a_t and the arguments are the same as for pprriinnttff((2)). Always returns FALSE. 55..66..1133 EEnnvviirroonnmmeenntt CCoonnttrrooll ffrroomm FFoorreeiiggnn CCooddee _i_n_t PPLL__aaccttiioonn((_i_n_t_, _C___t_y_p_e)) Perform some action on the Prolog system. _i_n_t describes the action, _C___t_y_p_e provides the argument if necessary. The actions are listed in table 5.1. ___________________________________________________________________ | PL_ACTION_TRACE |Start Prolog tracer | | PL_ACTION_DEBUG |Switch on Prolog debug mode | | PL_ACTION_BACKTRACE |Print backtrace on current output| | |stream. The argument (an int) is the| | |number of frames printed. | | PL_ACTION_HALT |Halt Prolog execution. This action| | |should be called rather than Unix exit()| | |to give Prolog the opportunity to clean| | |up. This call does not return. | | PL_ACTION_ABORT |Generate a Prolog abort. This call does| | |not return. | | PL_ACTION_BREAK |Create a standard Prolog break environ-| | |ment. Returns after the user types| | |control-D. | | PL_ACTION_SYMBOLFILE |The argument (a char *) is considered| | |to be hold the symbolfile for further| | |incremental loading. Should be| | |called by user applications that perform| | |incremental loading as well and want to| |________________________|inform_Prolog_of_the_new_symbol_table.___| Table 5.1: PPLL__aaccttiioonn(())options 55..66..1144 QQuueerryyiinngg PPrroolloogg _C___t_y_p_e PPLL__qquueerryy((_i_n_t)) Obtain status information on the Prolog system. The actual argument type depends on the information required. _i_n_t describes what information is wanted. The options are given in table 5.2. ___________________________________________________________________ | PL_QUERY_ARGC |Return an integer holding the number of| | |arguments given to Prolog from Unix. | | PL_QUERY_ARGV |Return a char ** holding the argument| | |vector given to Prolog from Unix. | | PL_QUERY_SYMBOLFILE |Return a char * holding the current| | |symbol file of the running process. | | PL_QUERY_ORGSYMBOLFILE |Return the initial symbol file (before| | |loading) of Prolog. By setting the| | |symbol file to this value no name| | |clashes can occur with previously loaded| | |foreign files (but no symbols can be| | |shared with earlier loaded modules as| | |well). | | PL_MAX_INTEGER |Return a long, representing the maximal| | |integer value represented by Prolog's| | |tagged integers. | | PL_MIN_INTEGER |Return a long, represented the minimal| | |integer value. | | PL_QUERY_VERSION |Return a long, representing the version| | |as 10; 000M* +100m* +p, where M is the | | |major, m the minor version number and | | |p the patch-level. For example, 20717| |________________________|means_2.7.17.____________________________| Table 5.2: PPLL__qquueerryy(()) options 55..66..1155 RReeggiisstteerriinngg FFoorreeiiggnn PPrreeddiiccaatteess _i_n_t PPLL__rreeggiisstteerr__ffoorreeiiggnn((_n_a_m_e_, _a_r_i_t_y_, _f_u_n_c_t_i_o_n_, _f_l_a_g_s)) Register a C-function to implement a Prolog predicate. After this call returns successfully a predicate with name _n_a_m_e (a char *) and arity _a_r_i_t_y (a C int) is created. When called in Prolog, Prolog will call _f_u_n_c_t_i_o_n. _f_l_a_g_s forms bitwise or'ed list of options for the installation. These are: ___________________________________________________________________ | PL_FA_NOTRACE |Predicate cannot be seen in the tracer | | PL_FA_TRANSPARENT |Predicate is module transparent | | PL_FA_NONDETERMINISTIC |Predicate is non-deterministic. See| |________________________|also_PPLL__rreettrryy(())._________________________| _v_o_i_d PPLL__rreeggiisstteerr__eexxtteennssiioonnss((_P_L___e_x_t_e_n_s_i_o_n _*_e)) Register foreign predicates from a table of structures. The type PL_extension is defined as: typedef struct _PL_extension { char *predicate_name; /* Name of the predicate */ short arity; /* Arity of the predicate */ pl_function_t function; /* Implementing functions */ short flags; /* Or of PL_FA_... */ } PL_extension; Here is an example of its usage: static PL_extension predicates[] = { { "foo", 1, pl_foo, 0 }, { "bar", 2, pl_bar, PL_FA_NONDETERMINISTIC }, { NULL, 0, NULL, 0 } }; main(int argc, char **argv) { PL_register_extensions(predicates); if ( !PL_initialise(argc, argv) ) PL_halt(1); ... } The function PPLL__rreeggiisstteerr__eexxtteennssiioonnss(())is the only PL_* function that may be called bbeeffoorree PPLL__iinniittiiaalliissee(()). The functions are registered after registration of the SWI-Prolog builtin foreign predicates and before loading the initial saved state. This implies that iinniittiiaalliizzaattiioonn//11 directives can refer to them. 55..66..1166 FFoorreeiiggnn CCooddee HHooookkss For various specific applications some hooks re provided. _P_L___d_i_s_p_a_t_c_h___h_o_o_k___t PPLL__ddiissppaattcchh__hhooookk((_P_L___d_i_s_p_a_t_c_h___h_o_o_k___t)) If this hook is not NULL, this function is called when reading from the terminal. It is supposed to dispatch events when SWI-Prolog is connected to a window environment. It can return two values: PL_DISPATCH_INPUT indicates Prolog input is available on file descriptor 0 or PL_DISPATCH_TIMEOUT to indicate a timeout. The old hook is returned. The type PL_dispatch_hook_t is defined as: typedef int (*PL_dispatch_hook_t)(void); _v_o_i_d PPLL__aabboorrtt__hhooookk((_P_L___a_b_o_r_t___h_o_o_k___t)) Install a hook when aabboorrtt//00 is executed. SWI-Prolog aabboorrtt//00 is implemented using C setjmp()/longjmp() construct. The hooks are executed in the reverse order of their registration after the longjmp() took place and before the Prolog toplevel is reinvoked. The type PL_abort_hook_t is defined as: typedef void (*PL_abort_hook_t)(void); _i_n_t PPLL__aabboorrtt__uunnhhooookk((_P_L___a_b_o_r_t___h_o_o_k___t)) Remove a hook installed with PPLL__aabboorrtt__hhooookk(()). Returns FALSE if no such hook is found, TRUE otherwise. _v_o_i_d PPLL__rreeiinniitt__hhooookk((_P_L___r_e_i_n_i_t___h_o_o_k___t)) Install a hook that is called when a saved program (using ssaavvee__pprrooggrraamm//[[11,,22]]) is restored. The hooks are called in reverse order. The type PL_reinit_hook_t is defined as: typedef void (*PL_reinit_hook_t)(int argc, char **argv); _i_n_t PPLL__rreeiinniitt__uunnhhooookk((_P_L___r_e_i_n_i_t___h_o_o_k___t)) Remove a hook installed with PPLL__rreeiinniitt__hhooookk(()). Returns FALSE if no such hook is found, TRUE otherwise. 55..66..1177 EEmmbbeeddddiinngg SSWWII--PPrroolloogg iinn aa CC--pprrooggrraamm As of version 2.1.0, SWI-Prolog may be embedded in a C-program. To reach at a compiled C-program with SWI-Prolog as an embedded application is very similar to creating a statically linked SWI-Prolog executable as described in section 5.4.1. The file .../pl/include/stub.c defines SWI-Prologs default main program: int main(int argc, char **argv) { if ( !PL_initialise(argc, argv) ) PL_halt(1); PL_install_readline(); /* delete if you don't want readline */ PL_halt(PL_toplevel() ? 0 : 1); } This may be replaced with your own main C-program. The interface function PPLL__iinniittiiaalliissee(()) mmuusstt be called before any of the other SWI-Prolog foreign language functions described in this chapter. PPLL__iinniittiiaalliissee(()) interprets all the command-line arguments, except for the -t toplevel flag that is interpreted by PPLL__ttoopplleevveell(()). _i_n_t PPLL__iinniittiiaalliissee((_i_n_t _a_r_g_c_, _c_h_a_r _*_*_a_r_g_v_, _c_h_a_r _*_*_e_n_v_i_r_o_n)) Initialises the SWI-Prolog heap and stacks, restores the boot QLF file, loads the system and personal initialisation files, runs the aatt__iinniittiiaalliizzaattiioonn//11 hooks and finally runs the -g goal hook. PPLL__iinniittiiaalliissee(()) returns 1 if all initialisation succeeded and 0 otherwise. Various fatal errors may cause PL_initialise to call PPLL__hhaalltt((_1)), preventing it from returning at all. _v_o_i_d PPLL__iinnssttaallll__rreeaaddlliinnee(()) Installs the GNU-readline line-editor. Embedded applications that do not use the Prolog toplevel should normally delete this line, shrinking the Prolog kernel significantly. _i_n_t PPLL__ttoopplleevveell(()) Runs the goal of the -t toplevel switch (default pprroolloogg//00) and returns 1 if successful, 0 otherwise. _v_o_i_d PPLL__hhaalltt((_i_n_t _s_t_a_t_u_s)) Cleanup the Prolog environment and calls exit() with the status argument. 55..77 LLiinnkkiinngg eemmbbeeddddeedd aapppplliiccaattiioonnss uussiinngg pplllldd The utility program plld (Win32: plld.exe) may be used to link a combination of C-files and Prolog files into a stand-alone executable. plld automates most of what is described in the previous sections. In the normal usage, a copy is made of the default embedding template .../pl/include/stub.c. The main() routine is modified to suit your application. PPLL__iinniittiiaalliissee(())mmuusstt be passed the program-name (_a_r_g_v_[_0_]) (Win32: the executing program can be obtained using GGeettMMoodduulleeFFiilleeNNaammee(())). The other elements of the command-line may be modified. Next, plld is typically invoked as: plld -o output stubfile.c [other-c-or-o-files] [plfiles] plld will first split the options into various groups for both the C-compiler and the Prolog compiler. Next, it will add various default options to the C-compiler and call it to create an executable holding the user's C-code and the Prolog kernel. Then, it will call the SWI-Prolog compiler to create a saved state from the provided Prolog files and finally, it will attach this saved state to the created emulator to create the requested executable. Below, it is described how the options are split and which additional options are passed. --hheellpp Print brief synopsis. --ppll _p_r_o_l_o_g Select the prolog to use. This prolog is used for two purposes: get the home-directory as well as the compiler/linker options and create a saved state of the Prolog code. --lldd _l_i_n_k_e_r Linker used to link the raw executable. Default is to use the C-compiler (Win32: link.exe). --cccc _C_-_c_o_m_p_i_l_e_r Compiler for .c files found on the commandline. Default is the compiler used to build SWI-Prolog (see ffeeaattuurree//22) (Win32: cl.exe). --cc++++ _C_+_+_-_c_o_m_p_i_l_e_r Compiler for C++ sources (extensions .cpp, .cxx, .cc or .C) files found on the commandline. Default is c++ or g++ if the C-compiler is gcc) (Win32: cl.exe). --nnoossttaattee Just relink the kernel, do not add any Prolog code to the new kernel. This is used to create a new kernel holding additional foreign predicates on machines that do not support the shared-library (DLL) interface, or if building the state cannot be handled by the default procedure used by plld. In the latter case the state is created seperately and appended to the kernel using cat <_k_e_r_n_e_l> <_s_t_a_t_e> > <_o_u_t>(Win32: copy /b <_k_e_r_n_e_l>+<_s_t_a_t_e> <_o_u_t>) --ppll--ooppttiioonnss _,_._._. Additional options passed to Prolog when creating the saved state. The first character immediately following pl-options is used as separator and translated to spaces when the argument is built. Example: -pl-options,-F,xpce passed -F xpce as additional flags to Prolog. --lldd--ooppttiioonnss _,_._._. Passes options to the linker, similar to -pl-options. --cccc--ooppttiioonnss _,_._._. Passes options to the C/C++ compiler, similar to -pl-options. --vv Select verbose operation, showing the various programs and their options. --oo _o_u_t_f_i_l_e Reserved to specify the final output file. --ll_l_i_b_r_a_r_y Specifies a library for the C-compiler. By default, -lpl (Win32: libpl.lib) and the libraries needed by the Prolog kernel are given. --LL_l_i_b_r_a_r_y_-_d_i_r_e_c_t_o_r_y Specifies a library directory for the C-compiler. By default the directory containing the Prolog C-library for the current architecture is passed. -g | -Iinclude-directory | -Ddefinition These options are passed to the C-compiler. By default, the include directory containing SWI-Prolog.h is passed. plld adds two additional * -Ddef flags: --DD____SWI_PROLOG__ Indicates the code is to be connected to SWI-Prolog. --DD____SWI_EMBEDDED__ Indicates the creation of an embedded program. _*_._o | _*_._c | _*_._C | _*_._c_x_x | _*_._c_p_p Passed as input files to the C-compiler _*_._p_l |_*_._q_l_f Passed as input files to the Prolog compiler to create the saved-state. * I.e. all other options. These are passed as linker options to the C-compiler. 55..77..11 AA ssiimmppllee eexxaammppllee The following is a very simple example going through all the steps outlined above. It provides an arithmetic expression evaluator. We will call the application calc and define it in the files calc.c and calc.pl. The Prolog file is simple: calc(Atom) :- term_to_atom(Expr, Atom), A is Expr, write(A), nl. The C-part of the application parses the command-line options, initialises the Prolog engine, locates the calc/1 predicate and calls it. The coder is in figure 5.5. #include #include PL_extension PL_extensions [] = { /*{ "name", arity, function, PL_FA_ },*/ { NULL, 0, NULL, 0 } /* terminating line */ }; #define MAXLINE 1024 int main(int argc, char **argv) { char expression[MAXLINE]; char *e = expression; char *program = argv[0]; char *plav[2]; int n; /* combine all the arguments in a single string */ for(n=1; n #include #include foreign_t pl_lowercase(term_t u, term_t l) { char *copy; char *s, *q; int rval; if ( !PL_get_atom_chars(u, &s) ) return PL_warning("lowercase/2: instantiation fault"); copy = malloc(strlen(s)+1); for( q=copy; *s; q++, s++) *q = (isupper(*s) ? tolower(*s) : *s); *q = '\0'; rval = PL_unify_atom_chars(l, copy); free(copy); return rval; } install_t install() { PL_register_foreign("lowercase", 2, pl_lowercase, 0); } Figure 5.6: Lowercase source file % gcc -I/usr/local/lib/pl-\plversion/include -fpic -c lowercase.c % gcc -shared -o lowercase.so lowercase.o % pl Welcome to SWI-Prolog (Version \plversion) Copyright (c) 1993-1996 University of Amsterdam. All rights reserved. For help, use ?- help(Topic). or ?- apropos(Word). 1 ?- load_foreign_library(lowercase). Yes 2 ?- lowercase('Hello World!', L). L = 'hello world!' Yes Figure 5.7: Compiling the C-source and loading the object file 55..99 NNootteess oonn UUssiinngg FFoorreeiiggnn CCooddee 55..99..11 MMeemmoorryy AAllllooccaattiioonn SWI-Prolog's memory allocation is based on the mmaalllloocc((3)) library routines. Foreign applications can safely use mmaalllloocc((3)), rreeaalllloocc((3)) and ffrreeee((3)). Memory allocation using bbrrkk((2)) or ssbbrrkk((2)) is not allowed as these calls conflict with mmaalllloocc((3)). 55..99..22 DDeebbuuggggiinngg FFoorreeiiggnn CCooddee Statically linked foreign code or embedded systems can be debugged normally. Most modern environments provide debugging tools for dynamically loaded shared objects or dynamic load libraries. The following example traces the code of lowercase using ggddbb((1)) in a Unix environment. % gcc -I/usr/local/lib/pl-2.2.0/include -fpic -c -g lowercase.c % gcc -shared -o lowercase.so lowercase.o % gdb pl (gdb) r Welcome to SWI-Prolog (Version \plversion) Copyright (c) 1993-1996 University of Amsterdam. All rights reserved. For help, use ?- help(Topic). or ?- apropos(Word). ?- load_foreign_library(lowercase). (gdb) shared % loads symbols for shared objects (gdb) break pl_lowercase (gdb) continue ?- lowercase('HELLO', X). 55..99..33 NNaammee CCoonnfflliiccttss iinn CC mmoodduulleess In the current version of the system all public C functions of SWI-Prolog are in the symbol table. This can lead to name clashes with foreign code. Someday I should write a program to strip all these symbols from the symbol table (why does Unix not have that?). For now I can only suggest to give your function another name. You can do this using the C preprocessor. If---for example---your foreign package uses a function warning(), which happens to exist in SWI-Prolog as well, the following macro should fix the problem. #define warning warning_ Note that shared libraries do not have this problem as the shared library loader will only look for symbols in the main executable for symbols that are not defined in the library itself. 55..99..44 CCoommppaattiibbiilliittyy ooff tthhee FFoorreeiiggnn IInntteerrffaaccee The term-reference mechanism was first used by Quintus Prolog version 3. SICStus Prolog version 3 is strongly based on the Quintus interface. The described SWI-Prolog interface is similar to using the Quintus or SICStus interfaces, defining all foreign-predicate arguments of type +term. SWI-Prolog explicitly uses type functor_t, while Quintus and SICStus uses <_n_a_m_e> and <_a_r_i_t_y>. As the names of the functions differ from Prolog to Prolog, a simple macro layer dealing with the names can also deal with this detail. For example: #define QP_put_functor(t, n, a) PL_put_functor(t, PL_new_functor(n, a)) The PL_unify_*() functions are lacking from the Quintus and SICStus interface. They can easily be emulated or the put/unify approach should be used to write compatible code. The PPLL__ooppeenn__ffoorreeiiggnn__ffrraammee(())/PPLL__cclloossee__ffoorreeiiggnn__ffrraammee(())combination is lacking from both other Prologs. SICStus has PPLL__nneeww__tteerrmm__rreeffss((_0)), followed by PPLL__rreesseett__tteerrmm__rreeffss(())that allows for discarding term references. The Prolog interface for the graphical user interface package XPCE shares about 90% of the code using a simple macro layer to deal with different naming and calling conventions of the interfaces. CChhaapptteerr 66.. GGEENNEERRAATTIINNGG RRUUNNTTIIMMEE AAPPPPLLIICCAATTIIOONNSS This chapter describes the features of SWI-Prolog for delivering applications that can run without the development version of the system installed. A SWI-Prolog built application consists of at least two parts: the emulator and the compiled application. The latter is in the same format as a SWI-Prolog boot-file and SWI-Prolog pre-compiled (QLF) file. This format is fast loadable and abstracted just far enough to be machine independent. This implies an application delivered in binary format can run on any computer for which an emulator is available without modification. qqssaavvee__pprrooggrraamm((_+_F_i_l_e_, _+_L_i_s_t_O_f_O_p_t_i_o_n_s)) Saves the current state of the program to the file _F_i_l_e. The result is an executable shell-script, that will start the emulator. _L_i_s_t_O_f_O_p_t_i_o_n_s is a list of <_K_e_y>=<_V_a_l_u_e> or <_K_e_y>(<_V_a_l_u_e>) pairs. The available keys are described in table 6.1. _______________________________________________________________________ |__KKeeyy________________||OOppttiioonn__||________TTyyppee__________||DDeessccrriippttiioonn______________________________________________||__ || local | --LL || K-bytes |Size (Limit) of local stack | | global | --GG || K-bytes |Size (Limit) of global stack | | trail | --TT || K-bytes |Size (Limit) of trail stack | | argument | --AA || K-bytes |Size (Limit) of argument stack | | goal | --gg || atom |Initialisation goal | | toplevel | --tt || atom |Prolog toplevel goal | |_init_file___|--ff___||_____atom_____|Personal_initialisation_file______|_ | autoload | | bool |If true, run aauuttoollooaadd//00 first | | map | | atom |File containing info on dump | | op | |save/standard |Save operator declarations? | |_stand_alone_|_____|_____bool_____|Include_the_emulator_in_the_state_|_ Table 6.1: <_K_e_y> = <_V_a_l_u_e> pairs for qqssaavvee__pprrooggrraamm//22 The /bin/sh script contains the following data: 1. The _s_h_e_l_l _s_c_r_i_p_t _h_e_a_d_e_r starts as: #!/bin/sh #SAVE-VERSION= #PROLOG-VERSION= exec ${SWIPL-/path-to-emulator} -x $0 "$@" 2. The _s_e_t_t_i_n_g_s _s_e_c_t_i_o_n contains the default values for the various command line options. 3. The _p_r_e_d_i_c_a_t_e_s _s_e_c_t_i_o_n contains all predicates from the currently running system. Clauses of predicates defined as _v_o_l_a_t_i_l_e (see vvoollaattiillee//11) are nnoott saved. Neither are foreign predicates (see also below). 4. The _r_e_c_o_r_d _s_e_c_t_i_o_n contains the database records saved with rreeccoorrddaa//33 and friends. The current version saves records using directives. 5. The _f_l_a_g _s_e_c_t_i_o_n contains the global flags saved using the ffllaagg//33 predicate. Flags are saved as directives. 6. The _f_e_a_t_u_r_e _s_e_c_t_i_o_n contains all features that do not originate from the emulator itself. See sseett__ffeeaattuurree//22. 7. The _i_m_p_o_r_t _s_e_c_t_i_o_n contains the imports as far as they are not handled by the auto-import system. That is, an import is stored if the module is user or the module user contains a different definition as the one imported in the target module.' Before writing the data to file, qqssaavvee__pprrooggrraamm//22 will run aauuttoollooaadd//00 to all required autoloading the system can discover. See aauuttoollooaadd//00. Provided the application does not require any of the Prolog libraries to be loaded at runtime, the only file from the SWI-Prolog development environment required is the emulator itself. The emulator may be built in two flavours. The default is the _d_e_v_e_l_o_p_m_e_n_t _e_m_u_l_a_t_o_r. The _r_u_n_t_i_m_e _e_m_u_l_a_t_o_r is similar, but lacks the tracer. The stand-alone program cchhppll((1)) may be used to change the default path to the emulator. If the option stand_alone(on)is present, the emulator is prepended for the state. If the emulator is started and no state is specified using the -x flag, it will test whether a boot-file (state) is attached to the emulator itself and load this state. Provided the application has all libraries loaded, the resulting file may be started anywhere. qqssaavvee__pprrooggrraamm((_+_F_i_l_e)) Equivalent to qsave_program(File, []). aauuttoollooaadd Check the current Prolog program for predicates that are referred to, are undefined and have a definition in the Prolog library. Load the appropriate libraries. This predicate is used by qqssaavvee__pprrooggrraamm//[[11,,22]] to ensure the saved state will not depend on one of the libraries. The predicate aauuttoollooaadd//00 will find all ddiirreecctt references to predicates. It does not find predicates referenced via meta-predicates. The predicate log/2 is defined in the library(quintus) to provide a quintus compatible means to compute the natural logarithm of a number. The following program will behave correctly if its state is executed in an environment where the library(quintus) is not available: logtable(From, To) :- From > To, !. logtable(From, To) :- log(From, Value), format('~d~t~8|~2f~n', [From, Value]), F is From + 1, logtable(F, To). However, the following implementation refers to log/2 through the meta-predicate mmaapplliisstt//33. Autoload will not be able to find the reference. This problem may be fixed either by loading the module libtary(quintus) explicitly or use rreeqquuiirree//11 to tell the system that the predicate log/2 is required by this module. logtable(From, To) :- findall(X, between(From, To, X), Xlist), maplist(log, Xlist, SineList), write_table(Xlist, SineList). write_table([], []). write_table([I|IT], [V|VT]) :- format('~d~t~8|~2f~n', [I, V]), write_table(IT, VT). vvoollaattiillee _+_N_a_m_e_/_A_r_i_t_y_, _._._. Declare that the clauses of specified predicates should nnoott be saved to the program. The volatile declaration is normally used to avoid that the clauses of dynamic predicates that represent data for the current session is saved in the state file. 66..11 LLiimmiittaattiioonnss ooff qqssaavvee__pprrooggrraamm There are three areas that require special attention when using qqssaavvee__pprrooggrraamm//[[11,,22]]. o If the program is an embedded Prolog application or uses the foreign language interface, care has to be taken to restore the appropriate foreign context. See section 6.2 for details. o If the program uses directives (:- goal. lines) that perform other actions then setting predicate attributes (dynamic, volatile, etc.) or loading files (consult, etc.), the directive may need to be prefixed with iinniittiiaalliizzaattiioonn//11. o `Database references as returned by ccllaauussee//33, rreeccoorrddeedd//33, etc. are not preserved and may thus not be part of the database when saved. 66..22 RRuunnttiimmeess aanndd FFoorreeiiggnn CCooddee Some applications may need to use the foreign language interface. Object code is by definition machine-dependent and thus cannot be part of the saved program file. To complicate the matter even further there are various ways of loading foreign code: o _U_s_i_n_g _t_h_e _l_i_b_r_a_r_y_(_s_h_l_i_b_) _p_r_e_d_i_c_a_t_e_s This is the preferred way of dealing with foreign code. It loads quickly and ensures an acceptable level of independence between the versions of the emulator and the foreign code loaded. It works on Unix machines supporting shared libraries and library functions to load them. Most modern Unixes satisfy this constraint.. It also works on the Win32 platform: Windows-NT, '95 and Windows 3.1 running win32s. o _S_t_a_t_i_c _l_i_n_k_i_n_g This mechanism works on all machines, but generally requires the same C-compiler and linker to be used for the external code as is used to build SWI-Prolog itself. This mechanism is the preferred way if shared libraries are not supported. o _U_s_i_n_g llooaadd__ffoorreeiiggnn//[[22,,55]] Basically only works on Unix system supporting the a.out format executables. This mechanism is slow and non-portable. It should be avoided whenever possible. To make a runtime executable that can run on multiple platforms one must make runtime checks to find the correct way of linking. Suppose we have a source-file myextension defining the installation function iinnssttaallll(()). If this file is compiled to a shared library, llooaadd__ffoorreeiiggnn__lliibbrraarryy//11 will load this library and call the installation function to initialise the foreign code. If it is loaded as a static extension, define iinnssttaallll(()) as the predicate iinnssttaallll//00: static foreign_t pl_install() { install(); PL_succeed; } PL_extension PL_extensions [] = { /*{ "name", arity, function, PL_FA_ },*/ { "install", 0, pl_install, 0 }, { NULL, 0, NULL, 0 } /* terminating line */ }; Now, use the following Prolog code to load the foreign library: load_foreign_extensions :- current_predicate(install, install), !, % static loaded install. load_foreign_extensions :- % shared library load_foreign_library(foreign(myextension)). :- initialization load_foreign_extensions. The path alias foreign is defined by ffiillee__sseeaarrcchh__ppaatthh//22. By default it searches the directories <_h_o_m_e>/lib/<_a_r_c_h> and <_h_o_m_e>/lib. The application can specify additional rules for ffiillee__sseeaarrcchh__ppaatthh//22. 66..33 FFiinnddiinngg AApppplliiccaattiioonn ffiilleess If your application uses files that are not part of the saved program such as database files, configuration files, etc., the runtime version has to be able to locate these files. The ffiillee__sseeaarrcchh__ppaatthh//22mechanism in combination with the -palias command-line argument is the preferred way to locate runtime files. The first step is to define an alias for the toplevel directory of your application. We will call this directory gnatdir in our examples. A good place for storing data associated with SWI-Prolog runtime systems is below the emulator's home-directory. swi is a predefined alias for this directory. The following is a useful default definition for the search path. user:file_search_path(gnatdir, swi(gnat)). The application should locate all files using absolute_file_name. Suppose gnatdir contains a file config.pl to define local configuration. Then use the code below to load this file: configure_gnat :- ( absolute_file_name(gnatdir('config.pl'), ConfigFile) -> consult(ConfigFile) ; format(user_error, 'gnat: Cannot locate config.pl~n'), halt(1) ). 66..44 UUssiinngg cchhppll ffoorr CCoonnffiigguurraattiioonn IInnffoorrmmaattiioonn 66..44..11 CChhaannggiinngg tthhee eemmuullaattoorr ooff aa rruunnttiimmee aapppplliiccaattiioonn The program chpl, may be used to manipulate the header of a SWI-Prolog bootfile or state created with qqssaavvee__pprrooggrraamm//[[11,,22]]. It will be used most commonly by the installer of a SWI-Prolog runtime application to specify the path to the emulator. If the end-user decided to install the SWI-Prolog runtime environment in /usr/local/lib/rt-pl-2.1.4 the gnat application can be told to use this emulator using: % /usr/local/lib/rtpl-2.1.4/bin/chpl -e /usr/local/lib/rt-pl- 2.1.4/bin/pl gnat Now, gnat may be installed in any public or private directory for binaries. 66..44..22 PPaassssiinngg aa ppaatthh ttoo tthhee aapppplliiccaattiioonn Suppose the system administrator has installed the SWI-Prolog runtime environment in /usr/local/lib/rt-pl-2.1.4. A user wants to install gnat, but gnat will look for its configuration in /usr/local/lib/rt-pl-2.1.4/gnat where the user cannot write. The user decides to install the gnat runtime files in /users/bob/lib/gnat. For one-time usage, the user may decide to start gnat using the command: % gnat -p gnatdir=/users/bob/lib/gnat For a more widely used executable, this is not very comfortable. The user may decide to edit the shell-script part of gnat. Upto the line holding # End Header gnat is a simple /bin/sh script. After this line, the file is binary and may contain long lines. Most editors are not capable of editing such files. Instead of editing the file directly, the program cchhppll((1)) may be used to extract and replace the header of gnat. The following editing sequence will work with any editor capable of editing ASCII files. % chpl -x gnat > gnat.hdr % emacs gnat.hdr % chpl -h gnat.hdr gnat The header may be changed to the following to install gnat properly: #!/bin/sh # SWI-Prolog version: 2.1.4 # SWI-Prolog save-version: 25 exec ${SWIPL-/usr/local/lib/rt-pl-2.1.4/bin/pl} -x $0 \ -p gnatdir=/users/bob/lib/gnat "$@" 66..55 TThhee RRuunnttiimmee EEnnvviirroonnmmeenntt 66..55..11 TThhee RRuunnttiimmee EEmmuullaattoorr The sources may be used to built two versions of the emulator. By default, the _d_e_v_e_l_o_p_m_e_n_t _e_m_u_l_a_t_o_r is built. This emulator contains all features for interactive development of Prolog applications. If the system is configured using --enable-runtime, mmaakkee((1)) will create a _r_u_n_t_i_m_e _v_e_r_s_i_o_n of the emulator. This emulator is equivalent to the development version, except for the following features: o _N_o _i_n_p_u_t _e_d_i_t_i_n_g The GNU library -lreadline that provides EMACS compatible editing of input lines will not be linked to the system. o _N_o _t_r_a_c_e_r The tracer and all its options are removed, making the system a little faster too. o _N_o _p_r_o_f_i_l_e_r pprrooffiillee//33 and friends are not supported. This saves some space and provides better performance. o _N_o _i_n_t_e_r_r_u_p_t Keyboard interrupt (Control-C normally) is not rebound and will normally terminate the application. o _f_e_a_t_u_r_e_(_r_u_n_t_i_m_e_, _t_r_u_e_) _s_u_c_c_e_e_d_s This may be used to verify your application is running in the runtime environment rather than the development environment. o ccllaauussee//[[22,,33]] _d_o _n_o_t _w_o_r_k _o_n _s_t_a_t_i_c _p_r_e_d_i_c_a_t_e_s This feature inhibits listing your program. It is only a very limited protection however. The following fragment is an example for building the runtime environment in HOME/lib/rt-pl-2.1.4. If possible, the shared-library interface should be configured to ensure it can serve a large number of applications. % cd pl-2.1.4 % mkdir runtime % cd runtime % ../src/configure --enable-runtime --prefix=$HOME % make % make rt-install The runtime directory contains the components listed below. This directory may be tar'ed and shipped with your application. ________________________________________________ |_README.RT__|Info_on_the_runtime_environment___| | bin/pl |The emulator itself | |_bin/chpl___|The_utility_to_change_the_runtime_| | man/chpl.1 |Manual page for chpl | |_man/pl.1___|Manual_page_for_pl________________| |_swipl______|pointer_to_the_home_directory_(.)_| | lib/ |directory for shared libraries | |_lib/<_a_r_c_h>/|machine-specific_shared_libraries_| CChhaapptteerr 77.. HHAACCKKEERRSS CCOORRNNEERR This appendix describes a number of predicates which enable the Prolog user to inspect the Prolog environment and manipulate (or even redefine) the debugger. They can be used as entry points for experiments with debugging tools for Prolog. The predicates described here should be handled with some care as it is easy to corrupt the consistency of the Prolog system by misusing them. 77..11 EExxaammiinniinngg tthhee EEnnvviirroonnmmeenntt SSttaacckk pprroolloogg__ccuurrrreenntt__ffrraammee((_-_F_r_a_m_e)) Unify _F_r_a_m_e with an integer providing a reference to the parent of the current local stack frame. A pointer to the current local frame cannot be provided as the predicate succeeds deterministically and therefore its frame is destroyed immediately after succeeding. pprroolloogg__ffrraammee__aattttrriibbuuttee((_+_F_r_a_m_e_, _+_K_e_y_, _-_V_a_l_u_e)) Obtain information about the local stack frame _F_r_a_m_e. _F_r_a_m_e is a frame reference as obtained through pprroolloogg__ccuurrrreenntt__ffrraammee//11, pprroolloogg__ttrraaccee__iinntteerrcceeppttiioonn//44or this predicate. The key values are described below. aalltteerrnnaattiivvee _V_a_l_u_e is unified with an integer reference to the local stack frame in which execution is resumed if the goal associated with _F_r_a_m_e fails. Fails if the frame has no alternative frame. hhaass__aalltteerrnnaattiivveess _V_a_l_u_e is unified with true if _F_r_a_m_e still is a candidate for backtracking. false otherwise. ggooaall _V_a_l_u_e is unified with the goal associated with _F_r_a_m_e. If the definition module of the active predicate is not user the goal is represented as <_m_o_d_u_l_e>:<_g_o_a_l>. Do not instantiate variables in this goal unless you kknnooww what you are doing! ccllaauussee _V_a_l_u_e is unified with a reference to the currently running clause. Fails if the current goal is associated with a foreign (C) defined predicate. See also nntthh__ccllaauussee//33 and ccllaauussee__pprrooppeerrttyy//22. lleevveell _V_a_l_u_e is unified with the recursion level of _F_r_a_m_e. The top level frame is at level `0'. ppaarreenntt _V_a_l_u_e is unified with an integer reference to the parent local stack frame of _F_r_a_m_e. Fails if _F_r_a_m_e is the top frame. ccoonntteexxtt__mmoodduullee _V_a_l_u_e is unified with the name of the context module of the environment. ttoopp _V_a_l_u_e is unified with true if _F_r_a_m_e is the top Prolog goal from a recursive call back from the foreign language. false otherwise. hhiiddddeenn _V_a_l_u_e is unified with true if the frame is hidden from the user, either because a parent has the hide-childs attribute (all system predicates), or the system has no trace-me attribute. ppcc _V_a_l_u_e is unified with the program-pointer saved on behalve of the parent-goal if the parent-goal is not owned by a foreign predicate. aarrgguummeenntt((_N)) _V_a_l_u_e is unified with the _N-th slot of the frame. Argument 1 is the first argument of the goal. Arguments above the arity refer to local variables. Fails silently if _N is out of range. 77..22 IInntteerrcceeppttiinngg tthhee TTrraacceerr pprroolloogg__ttrraaccee__iinntteerrcceeppttiioonn((_+_P_o_r_t_, _+_F_r_a_m_e_, _+_P_C_, _-_A_c_t_i_o_n)) Dynamic predicate, normally not defined. This predicate is called from the SWI-Prolog debugger just before it would show a port. If this predicate succeeds the debugger assumes the trace action has been taken care of and continues execution as described by _A_c_t_i_o_n. Otherwise the normal Prolog debugger actions are performed. _P_o_r_t is one of call, redo, exit, fail or unify. _F_r_a_m_e is an integer reference to the current local stack frame. _P_C is the current value of the program-counter, relative to the start of the current clause, or 0 if it is invalid, for example because the current frame runs a foreign predicate, or no clause has been selected yet. _A_c_t_i_o_n should be unified with one of the atoms continue (just continue execution), retry (retry the current goal) or fail (force the current goal to fail). Leaving it a variable is identical to continue. Together with the predicates described in section 3.37 and the other predicates of this chapter this predicate enables the Prolog user to define a complete new debugger in Prolog. Besides this it enables the Prolog programmer monitor the execution of a program. The example below records all goals trapped by the tracer in the database. prolog_trace_interception(Port, Frame, _PC, continue) :- prolog_frame_attribute(Frame, goal, Goal), prolog_frame_attribute(Frame, level, Level), recordz(trace, trace(Port, Level, Goal)). To trace the execution of `go' this way the following query should be given: ?- trace, go, notrace. pprroolloogg__sskkiipp__lleevveell((_-_O_l_d_, _+_N_e_w)) Unify _O_l_d with the old value of `skip level' and than set this level according to _N_e_w. New is an integer, or the special atom very_deep (meaning don't skip). The `skip level' is a global variable of the Prolog system that disables the debugger on all recursion levels deeper than the level of the variable. Used to implement the trace options `skip' (sets skip level to the level of the frame) and `up' (sets skip level to the level of the parent frame (i.e. the level of this frame minus 1). 77..33 EExxcceeppttiioonn HHaannddlliinngg A start has been made to make exception handling available to the Prolog user. On exceptions a dynamic and multifile defined predicate eexxcceeppttiioonn//33 is called. If this user defined predicate succeeds Prolog assumes the exception has been taken care of. Otherwise the system default exception handler is called. eexxcceeppttiioonn((_+_E_x_c_e_p_t_i_o_n_, _+_C_o_n_t_e_x_t_, _-_A_c_t_i_o_n)) Dynamic predicate, normally not defined. Called by the Prolog system on run-time exceptions. Currently eexxcceeppttiioonn//33 is only used for trapping undefined predicates. Future versions might handle signal handling, floating exceptions and other runtime errors via this mechanism. The values for _E_x_c_e_p_t_i_o_n are described below. uunnddeeffiinneedd__pprreeddiiccaattee If _E_x_c_e_p_t_i_o_n is undefined_predicate _C_o_n_t_e_x_t is instantiated to a term _N_a_m_e/_A_r_i_t_y. _N_a_m_e refers to the name and _A_r_i_t_y to the arity of the undefined predicate. If the definition module of the predicate is not _u_s_e_r, _C_o_n_t_e_x_t will be of the form <_M_o_d_u_l_e>:<_N_a_m_e>/<_A_r_i_t_y>. If the predicate fails Prolog will print the default error warning and start the tracer. If the predicate succeeds it should instantiate the last argument either to the atom fail to tell Prolog to fail the predicate or the atom retry to tell Prolog to retry the predicate. This only makes sense if the exception handler has defined the predicate. Otherwise it will lead to a loop. wwaarrnniinngg If prolog wants to give a warning while reading a file, it will first raise the exception _w_a_r_n_i_n_g. The context argument is a term of the form warning(<_P_a_t_h>, <_L_i_n_e_N_o>, <_M_e_s_s_a_g_e>), where _P_a_t_h is the absolute filename of the file prolog is reading; _L_i_n_e_N_o is an estimate of the line number where the error occurred and _M_e_s_s_a_g_e is a Prolog string indicating the message. The _A_c_t_i_o_n argument is ignored. The error is supposed to be presented to the user if the exception handler succeeds. Otherwise the standard Prolog warning message is printed. This exception is used by the library(emacs_interface), that integrates error handling with GNU Emacs. 77..44 RReeaaddlliinnee IInntteerraaccttiioonn The following predicates are available if feature(readline, true) succeeds. They allow for direct interaction with the GNU readline library. See also rreeaaddlliinnee((3)) rrll__rreeaadd__iinniitt__ffiillee((_+_F_i_l_e)) Read a readline initialisation file. Readline by default reads ~/.inputrc. This predicate may be used to read alternative readline initialisation files. rrll__aadddd__hhiissttoorryy((_+_L_i_n_e)) Add a line to the Control-P/Control-N history system of the readline library. CChhaapptteerr 88.. SSUUMMMMAARRYY 88..11 PPrreeddiiccaatteess The predicate summary is used by the Prolog predicate aapprrooppooss//11 to suggest predicates from a keyword. !/0 Cut (discard choicepoints) !/1 Cut block. See bblloocckk//33 ,/2 Conjunction of goals ->/2 If-then-else *->/2 Soft-cut ./2 Consult. Also list constructor ;/2 Disjunction of goals. Same as |//22 /2 Arithmetic larger >=/2 Arithmetic larger or equal @/2 Standard order larger @>=/2 Standard order larger or equal \+/1 Negation by failure. Same as nnoott//11 \=/2 Not unifyable \==/2 Not identical \=@=/2 Not structural identical ^/2 Existential quantification (bbaaggooff//33, sseettooff//33) |/2 Disjunction of goals. Same as ;//22 abolish/1 Remove predicate definition from the database abolish/2 Remove predicate definition from the database abort/0 Abort execution, return to top level absolute_file_name/2 Get absolute path name absolute_file_name/3 Get absolute path name with options access_file/2 Check access permissions of a file append/1 Append to a file append/3 Concatenate lists apply/2 Call goal with additional arguments apropos/1 library(online_help) Show related predicates and manual sections arg/3 Access argument of a term arithmetic_function/1 Register an evaluable function assert/1 Add a clause to the database assert/2 Add a clause to the database, give reference asserta/1 Add a clause to the database (first) asserta/2 Add a clause to the database (first) assertz/1 Add a clause to the database (last) assertz/2 Add a clause to the database (last) at_end_of_stream/0 Test for end of file on input at_end_of_stream/1 Test for end of file on stream at_halt/1 Register goal to run at hhaalltt//11 at_initialization/1 Register goal to run at start-up atom/1 Type check for an atom atom_char/2 Convert between atom and ASCII value atom_chars/2 Convert between atom and list of ASCII values atom_length/2 Determine length of an atom atom_prefix/2 Test for start of atom atom_to_term/3 Convert between atom and term atomic/1 Type check for primitive autoload/0 Autoload all predicates now bagof/3 Find all solutions to a goal between/3 Integer range checking/generating block/3 Start a block (`catch'/`throw') break/0 Start interactive toplevel call/1 Call a goal call/[2..] Call with additional arguments call_dll_function/2 Win32: Call function in dynamic link library (.dll file) call_shared_object_function/2 UNIX: Call C-function in shared (.so) file call_with_depth_limit/3 Prove goal with bounded depth catch/3 Call goal, watching for exceptions character_count/2 Get character index on a stream chdir/1 Change working directory checklist/2 Invoke goal on all members of a list clause/2 Get clauses of a predicate clause/3 Get clauses of a predicate clause_property/2 Get properties of a clause close/1 Close stream close_dde_conversation/1 Win32: Close DDE channel close_dll/1 Win32: Close dynamic link library (.dll file) close_shared_object/1 UNIX: Close shared library (.so file) compare/3 Compare, using a predicate to determine the order compiling/0 Is this a compilation run? compound/1 Test for compound term concat/3 Append two atoms concat_atom/2 Append a list of atoms concat_atom/3 Append a list of atoms with separator consult/1 Read (compile) a Prolog source file context_module/1 Get context module of current goal convert_time/8 Convert time stamp copy_term/2 Make a copy of a term current_arithmetic_function/1 Examine evaluable functions current_atom/1 Examine existing atoms current_flag/1 Examine existing flags current_foreign_library/2 library(shlib) Examine loaded shared libraries (.so files) current_functor/2 Examine existing name/arity pairs current_input/1 Get current input stream current_key/1 Examine existing database keys current_module/1 Examine existing modules current_module/2 Examine existing modules current_op/3 Examine current operator declarations current_output/1 Get the current output stream current_predicate/2 Examine existing predicates current_stream/3 Examine open streams dde_current_connection/2 Win32: Examine open DDE connections dde_current_service/2 Win32: Examine DDE services provided dde_execute/2 Win32: Execute command on DDE server dde_register_service/2 Win32: Become a DDE server dde_request/3 Win32: Make a DDE request dde_poke/3 Win32: POKE operation on DDE server dde_unregister_service/1 Win32: Terminate a DDE service debug/0 Test for debugging mode debugging/0 Show debugger status default_module/2 Get the default modules of a module delete/3 Delete all matching members from a list delete_file/1 Remove a file from the file system discontiguous/1 Indicate distributed definition of a predicate dup_stream/2 Duplicate I/O streams dwim_match/2 Atoms match in ``Do What I Mean'' sense dwim_match/3 Atoms match in ``Do What I Mean'' sense dwim_predicate/2 Find predicate in ``Do What I Mean'' sense dynamic/1 Indicate predicate definition may change ed/0 Edit last edited predicate ed/1 Edit a predicate edit/0 Edit last edited file edit/1 Edit a file edit_source/1 (hook) Intercept editing ensure_loaded/1 Consult a file if that has not yet been done erase/1 Erase a database record or clause exception/3 (hook) Handle runtime exceptions exists_directory/1 Check existence of directory exists_file/1 Check existence of file exit/2 Exit from named block. See bblloocckk//33 expand_answer/2 Expand answer of query expand_file_name/2 Wildcard expansion of file names expand_file_search_path/2 Wildcard expansion of file paths expand_query/4 Expanded entered query expand_term/2 Compiler: expand read term into clause(s) explain/1 library(explain) Explain argument explain/2 library(explain) 2nd argument is explanation of first export/1 Export a predicate from a module export_list/2 List of public predicates of a module fail/0 Always false fail/1 Immediately fail named block. See bblloocckk//33 feature/2 Get system configuration parameters file_base_name/2 Get file part of path file_directory_name/2 Get directory part of path file_name_extension/3 Add, remove or test file extensions file_search_path/2 Define path-aliases for locating files fileerrors/2 Do/Don't warn on file errors findall/3 Find all solutions to a goal flag/3 Simple global variable system flatten/2 Transform nested list into flat list float/1 Type check for a floating point number flush/0 Output pending characters on current stream flush_output/1 Output pending characters on specified stream forall/2 Prove goal for all solutions of another goal foreign_file/1 Examine loaded foreign files format/1 Formatted output format/2 Formatted output with arguments format/3 Formatted output on a stream format_predicate/2 Program ffoorrmmaatt//[[11,,22]] free_variables/2 Find unbound variables in a term functor/3 Get name and arity of a term or construct a term garbage_collect/0 Invoke the garbage collector gensym/2 Generate unique atoms from a base get/1 Read first non-blank character get/2 Read first non-blank character from a stream get0/1 Read next character get0/2 Read next character from a stream get_single_char/1 Read next character from the terminal get_time/1 Get current time getenv/2 Get shell environment variable ground/1 Verify term holds no unbound variables halt/0 Exit from Prolog halt/1 Exit from Prolog with status hash_term/2 Hash-value of ground term help/0 Give help on help help/1 Give help on predicates and show parts of manual ignore/1 Call the argument, but always succeed import/1 Import a predicate from a module index/1 Change clause indexing initialization/1 Initialization directive int_to_atom/2 Convert from integer to atom int_to_atom/3 Convert from integer to atom (non-decimal) integer/1 Type check for integer intersection/3 Set intersection is/2 Evaluate arithmetic expression is_absolute_file_name/1 True if arg defines an absolute path is_list/1 Type check for a list is_set/1 Type check for a set keysort/2 Sort, using a key last/2 Last element of a list leash/1 Change ports visited by the tracer length/2 Length of a list library_directory/1 (hook) Directories holding Prolog libraries limit_stack/2 Limit stack expansion line_count/2 Line number on stream line_position/2 Character position in line on stream list_to_set/2 Remove duplicates listing/0 List program in current module listing/1 List predicate load_files/2 Load source files with options load_foreign/2 Load foreign (C) module load_foreign/5 Load foreign (C) module load_foreign_library/1 library(shlib) Load shared library (.so file) load_foreign_library/2 library(shlib) Load shared library (.so file) make/0 Reconsult all changed source files make_fat_filemap/1 Win32: Create file containing non-FAT filenames make_library_index/1 Create autoload file INDEX.pl maplist/3 Transform all elements of a list member/2 Element is member of a list memberchk/2 Deterministic mmeemmbbeerr//22 merge/3 Merge two sorted lists merge_set/3 Merge two sorted sets message_hook/3 Intercept pprriinntt__mmeessssaaggee//22 meta_predicate/1 Quintus compatibility module/1 Query/set current type-in module module/2 Declare a module module_transparent/1 Indicate module based meta predicate msort/2 Sort, do not remove duplicates multifile/1 Indicate distributed definition of predicate name/2 Convert between atom and list of ASCII characters nl/0 Generate a newline nl/1 Generate a newline on a stream nodebug/0 Disable debugging nonvar/1 Type check for bound term noprotocol/0 Disable logging of user interaction nospy/1 Remove spy point nospyall/0 Remove all spy points not/1 Negation by failure (argument not provable). Same as \+//11 notrace/0 Stop tracing notrace/1 Do not debug argument goal nth0/3 N-th element of a list (0-based) nth1/3 N-th element of a list (1-based) nth_clause/3 N-th clause of a predicate number/1 Type check for integer or float number_chars/2 Convert between number and atom numbervars/4 Enumerate unbound variables of a term using a given base once/1 Call a goal deterministically op/3 Declare an operator open/3 Open a file (creating a stream) open/4 Open a file (creating a stream) open_dde_conversation/3 Win32: Open DDE channel open_null_stream/1 Open a stream to discard output open_shared_object/2 UNIX: Open shared library (.so file) open_shared_object/3 UNIX: Open shared library (.so file) peek_byte/1 Read character without removing peek_byte/2 Read character without removing phrase/2 Activate grammar-rule set phrase/3 Activate grammar-rule set (returning rest) please/3 Query/change environment parameters plus/3 Logical integer addition portray/1 (hook) Modify behaviour of pprriinntt//11 portray_clause/1 Pretty print a clause predicate_property/2 Query predicate attributes predsort/3 Sort, using a predicate to determine the order preprocessor/2 Install a preprocessor before the compiler print/1 Print a term print/2 Print a term on a stream print_message/2 Print message from (exception) term profile/3 Obtain execution statistics profile_count/3 Obtain profile results on a predicate profiler/2 Obtain/change status of the profiler prolog/0 Run interactive toplevel prolog_current_frame/1 Reference to goal's environment stack prolog_frame_attribute/3 Obtain information on a goal environment prolog_load_context/2 Context information for directives prolog_skip_level/2 Indicate deepest recursion to trace prolog_to_os_filename/2 Convert between Prolog and OS filenames prolog_trace_interception/4 library(user) Intercept the Prolog tracer prompt1/1 Change prompt for 1 line prompt/2 Change the prompt used by rreeaadd//11 proper_list/1 Type check for list protocol/1 Make a log of the user interaction protocola/1 Append log of the user interaction to file protocolling/1 On what file is user interaction logged put/1 Write a character put/2 Write a character on a stream qcompile/1 Compile source to Quick Load File qload/1 Load Quick Load File as ccoonnssuulltt//11 qsave_program/1 Create runtime application qsave_program/2 Create runtime application read/1 Read Prolog term read/2 Read Prolog term from stream read_clause/1 Read clause read_clause/2 Read clause from stream read_history/6 Read using history substitution read_link/3 Read a symbolic link read_term/2 Read term with options read_term/3 Read term with options from stream read_variables/2 Read clause including variable names read_variables/3 Read clause including variable names from stream recorda/2 Record term in the database (first) recorda/3 Record term in the database (first) recorded/2 Obtain term from the database recorded/3 Obtain term from the database recordz/2 Record term in the database (last) recordz/3 Record term in the database (last) redefine_system_predicate/1 Abolish system definition rename_file/2 Change name of file repeat/0 Succeed, leaving infinite backtrack points require/1 This file requires these predicates reset_profiler/0 Clear statistics obtained by the profiler restore/1 Restore saved-state (ssaavvee//11, ssaavvee__pprrooggrraamm//11) retract/1 Remove clause from the database retractall/1 Remove unifying clauses from the database reverse/2 Inverse the order of the elements in a list same_file/2 Succeeds if arguments refer to same file save/1 Save program including current goal save/2 Save program including current goal save_program/1 Save the current program on a file save_program/2 Save the current program on a file see/1 Change the current input stream seeing/1 Query the current input stream seen/0 Close the current input stream select/3 Select element of a list set_feature/2 Define a system feature set_input/1 Set current input stream from a stream set_output/1 Set current output stream from a stream set_tty/2 Set `tty' stream setarg/3 Destructive assignment on term setenv/2 Set shell environment variable setof/3 Find all unique solutions to a goal sformat/2 Format on a string sformat/3 Format on a string shell/0 Execute interactive subshell shell/1 Execute OS command shell/2 Execute OS command show_profile/1 Show results of the profiler size_file/2 Get size of a file in characters skip/1 Skip to character in current input skip/2 Skip to character on stream rl_add_history/1 Add line to readline(3) history rl_read_init_file/1 Read readline(3) init file sleep/1 Suspend execution for specified time sort/2 Sort elements in a list source_file/1 Examine currently loaded source files source_file/2 Obtain source file of predicate source_location/2 Location of last read term spy/1 Force tracer on specified predicate stack_parameter/4 Some systems: Query/Set runtime stack parameter statistics/0 Show execution statistics statistics/2 Obtain collected statistics stream_position/3 Get/seek to position in file string/1 Type check for string string_concat/3 ccoonnccaatt//33 for strings (non-deterministic) string_length/2 Determine length of a string string_to_atom/2 Conversion between string and atom string_to_list/2 Conversion between string and list of ASCII style_check/1 Change level of warnings sublist/3 Determine elements that meet condition subset/2 Generate/check subset relation substring/4 Get part of a string subtract/3 Delete elements that do not meet condition succ/2 Logical integer successor relation swritef/2 Formatted write on a string swritef/3 Formatted write on a string tab/1 Output number of spaces tab/2 Output number of spaces on a stream tell/1 Change current output stream telling/1 Query current output stream term_expansion/2 (hook) Convert term before compilation term_to_atom/2 Convert between term and atom throw/1 Raise an exception (see ccaattcchh//33) time/1 Determine time needed to execute goal time_file/2 Get last modification time of file tmp_file/2 Create a temporary filename told/0 Close current output trace/0 Start the tracer trace/1 Set trace-point on predicate trace/2 Set/Clear trace-point on ports tracing/0 Query status of the tracer trim_stacks/0 Release unused memory resources true/0 Succeed tty_get_capability/3 Get terminal parameter tty_goto/2 Goto position on screen tty_put/2 Write control string to terminal ttyflush/0 Flush output on terminal union/3 Union of two sets unknown/2 Trap undefined predicates unload_foreign_library/1 library(shlib) Detach shared library (.so file) unsetenv/1 Delete shell environment variable use_module/1 Import a module use_module/2 Import predicates from a module var/1 Type check for unbound variable visible/1 Ports that are visible in the tracer volatile/1 Predicates that are not saved wait_for_input/3 Wait for input with optional timeout wildcard_match/2 Csh(1) style wildcard match win_exec/2 Win32: spawn Windows task write/1 Write term write/2 Write term to stream write_ln/1 Write term, followed by a newline write_canonical/1 Write a term with quotes, ignore operators write_canonical/2 Write a term with quotes, ignore operators on a stream write_term/2 Write term with options write_term/3 Write term with options to stream writef/1 Formatted write writef/2 Formatted write on stream writeq/1 Write term, insert quotes writeq/2 Write term, insert quotes on stream 88..22 AArriitthhmmeettiicc FFuunnccttiioonnss */2 Multiplication **/2 Power function +/2 Addition -/1 Unary minus -/2 Subtraction //2 Division ///2 Integer division /\/2 Bitwise and <>/2 Bitwise right shift ./2 List of one character: character code \/1 Bitwise negation \//2 Bitwise or ^/2 Power function abs/1 Absolute value acos/1 Inverse (arc) cosine asin/1 Inverse (arc) sine atan/1 Inverse (arc) tangent atan/2 Rectangular to polar conversion ceil/1 Smallest integer larger than arg ceiling/1 Smallest integer larger than arg cos/1 Cosine cputime/0 Get CPU time e/0 Mathematical constant exp/1 Exponent (base e) float/1 Explicitly convert to float float_fractional_part/1 Fractional part of a float float_integer_part/1 Integer part of a float floor/1 Largest integer below argument integer/1 Round to nearest integer log/1 Natural logarithm log10/1 10 base logarithm max/2 Maximum of two numbers min/2 Minimum of two numbers mod/2 Remainder of division random/1 Generate random number rem/2 Remainder of division round/1 Round to nearest integer truncate/1 Truncate float to integer pi/0 Mathematical constant sign/1 Extract sign of value sin/1 Sine sqrt/1 Square root tan/1 Tangent xor/2 Bitwise exclusive or 88..33 OOppeerraattoorrss $ 1 fx Bind toplevel variable ^ 200 xfy Predicate ^ 200 xfy Arithmetic function mod 300 xfx Arithmetic function * 400 yfx Arithmetic function / 400 yfx Arithmetic function // 400 yfx Arithmetic function << 400 yfx Arithmetic function >> 400 yfx Arithmetic function xor 400 yfx Arithmetic function + 500 fx Arithmetic function - 500 fx Arithmetic function ? 500 fx XPCE: obtainer \ 500 fx Arithmetic function + 500 yfx Arithmetic function - 500 yfx Arithmetic function /\ 500 yfx Arithmetic function \/ 500 yfx Arithmetic function : 600 xfy module:term separator < 700 xfx Predicate = 700 xfx Predicate =.. 700 xfx Predicate =:= 700 xfx Predicate < 700 xfx Predicate == 700 xfx Predicate =@= 700 xfx Predicate =\= 700 xfx Predicate > 700 xfx Predicate >= 700 xfx Predicate @< 700 xfx Predicate @=< 700 xfx Predicate @> 700 xfx Predicate @>= 700 xfx Predicate is 700 xfx Predicate \= 700 xfx Predicate \== 700 xfx Predicate =@= 700 xfx Predicate not 900 fy Predicate \+ 900 fy Predicate , 1000 xfy Predicate -> 1050 xfy Predicate *-> 1050 xfy Predicate ; 1100 xfy Predicate | 1100 xfy Predicate discontiguous 1150 fx Predicate dynamic 1150 fx Predicate module_transparent 1150 fx Predicate multifile 1150 fx Predicate volatile 1150 fx Predicate initialization 1150 fx Predicate :- 1200 fx Introduces a directive ?- 1200 fx Introduces a directive --> 1200 xfx DCGrammar: rewrite :- 1200 xfx head :- body. separator Bibliography [Anjewierden & Wielemaker, 1989] A. Anjewierden and J. Wielemaker. Extensible objects. ESPRIT Project 1098 Technical Report UvA-C1-TR-006a, University of Amsterdam, March 1989. [BIM, 1989] _B_I_M _P_r_o_l_o_g _r_e_l_e_a_s_e _2_._4. Everberg, Belgium, 1989. [Bowen & Byrd, 1983] D. L. Bowen and L. M. Byrd. A portable Prolog compiler. In L. M. Pereira, editor, _P_r_o_c_e_e_d_i_n_g_s _o_f _t_h_e _L_o_g_i_n _P_r_o_g_r_a_m_m_i_n_g _W_o_r_k_s_h_o_p _1_9_8_3, Lisabon, Portugal, 1983. Universidade nova de Lisboa. [Bratko, 1986] I. Bratko. _P_r_o_l_o_g _P_r_o_g_r_a_m_m_i_n_g _f_o_r _A_r_- _t_i_f_i_c_i_a_l _I_n_t_e_l_l_i_g_e_n_c_e. Addison-Wesley, Reading, Massachusetts, 1986. [Clocksin & Melish, 1987] W. F. Clocksin and C. S. Melish. _P_r_o_g_r_a_m_m_i_n_g _i_n _P_r_o_l_o_g. Springer- Verlag, New York, Third, Revised and Extended edition, 1987. [Deransart _e_t _a_l_., 1996] P. Deransart, A. Ed-Dbali, and L. Cervoni. _P_r_o_l_o_g_: _T_h_e _S_t_a_n_d_a_r_d. Springer-Verlag, New York, 1996. [Kernighan & Ritchie, 1978] B. W. Kernighan and D. M. Ritchie. _T_h_e _C _P_r_o_g_r_a_m_m_i_n_g _L_a_n_g_u_a_g_e. Prentice-Hall, Englewood Cliffs, New Jersey, 1978. [OKeefe, 1990] R. A. OKeefe. _T_h_e _C_r_a_f_t _o_f _P_r_o_l_o_g. MIT Press, Massachussetts, 1990. [Pereira, 1986] F. Pereira. _C_-_P_r_o_l_o_g _U_s_e_r_'_s _M_a_n_u_a_l, 1986. [Qui, 1997] _Q_u_i_n_t_u_s _P_r_o_l_o_g_, _U_s_e_r _G_u_i_d_e _a_n_d _R_e_f_e_r_e_n_c_e _M_a_n_u_a_l. Berkhamsted, UK, 1997. [Sterling & Shapiro, 1986] L. Sterling and E. Shapiro. _T_h_e _A_r_t _o_f _P_r_o_l_o_g. MIT Press, Cambridge, Massachusetts, 1986. [Warren, 1983] D. H. D. Warren. The runtime environment for a prolog compiler using a copy algorithm. Technical Report 83/052, SUNY and Stone Brook, New York, 1983. Major revision March 1984. 722