This manual documents SICStus Prolog 3.8, October 1999.
Prolog is a simple but powerful programming language developed at the University of Marseilles, as a practical tool for programming in logic. From a user's point of view the major attraction of the language is ease of programming. Clear, readable, concise programs can be written quickly with few errors.
Prolog is a simple but powerful programming language developed at the University of Marseilles [Roussel 75], as a practical tool for programming in logic [Kowalski 74]. From a user's point of view the major attraction of the language is ease of programming. Clear, readable, concise programs can be written quickly with few errors.
For an introduction to programming in Prolog, readers are recommended to consult [Sterling & Shapiro 86]. However, for the benefit of those who do not have access to a copy of this book, and for those who have some prior knowledge of logic programming, a summary of the language is included. For a more general introduction to the field of Logic Programming see [Kowalski 79]. See Prolog Intro.
This manual describes a Prolog system developed at the Swedish Institute of Computer Science. Parts of the system were developed by the project "Industrialization of SICStus Prolog" in collaboration with Ericsson Telecom AB, NobelTech Systems AB, Infologics AB and Televerket. The system consists of a WAM emulator written in C, a library and runtime system written in C and Prolog and an interpreter and a compiler written in Prolog. The Prolog engine is a Warren Abstract Machine (WAM) emulator [Warren 83]. Two modes of compilation are available: in-core i.e. incremental, and file-to-file. When compiled, a predicate will run about 8 times faster and use memory more economically. Implementation details can be found in [Carlsson 90] and in several technical reports available from SICS.
SICStus Prolog follows the mainstream Prolog tradition in terms of syntax and built-in predicates, and is largely compatible with DECsystem-10 Prolog and Quintus Prolog.
The following people have contributed to the development of SICStus Prolog:
Jonas Almgren, Johan Andersson, Stefan Andersson, Tamás Benkő, Kent Boortz, Per Brand, Göran Bĺge, Mats Carlsson, Jesper Eskilson, Lena Flood, György Gyaraki, Seif Haridi, Ralph Haygood, Christian Holzbaur, Key Hyckenberg, Per Mildner, Hans Nilsson, Mats Nylén, Greger Ottosson, László Péter, Dan Sahlin, Rob Scott, Thomas Sjöland, Péter Szeredi, Johan Widén, and Emil Ĺström.
The Industrialization of SICStus Prolog (1988-1991) was funded by
Ericsson Telecom AB, NobelTech Systems AB, Infologics AB and Televerket under the National Swedish Information Technology Program IT4.
The development of release 3 (1991-1995) was funded in part by
Ellemtel Utvecklings AB
This manual is based on DECsystem-10 Prolog User's Manual by
D.L. Bowen, L. Byrd, F.C.N. Pereira, L.M. Pereira, D.H.D. Warren
See CLPQR, for acknowledgments relevant to the clp(Q,R) constraint solver.
See CLPFD, for acknowledgments relevant to the clp(FD) constraint solver.
UNIX is a trademark of Bell Laboratories. MSDOS and Windows is a trademark of Microsoft Corp. OS/2 is a trademark of IBM Corp.
When referring to keyboard characters, printing characters are written thus: a, while control characters are written like this: ^A. Thus ^C is the character you get by holding down the <CTL> key while you type c. Finally, the special control characters carriage-return, line-feed and space are often abbreviated to <RET>, <LFD> and <SPC> respectively.
When introducing a built-in predicate, we shall present its usage with a mode spec which has the form name(arg, ..., arg) where each arg denotes how that argument should be instantiated in goals, and has one of the following forms:
Mode specs are not only used in the manual, but are part of the syntax of the language as well. When used in the source code, however, the ArgName part must be omitted. That is, arg must be either :, +, -, or ?.
The full Prolog system with top-level, compiler, debugger etc. is known as the development system.
It is possible to link user-written C code with a subset of SICStus Prolog to create runtime systems. When introducing a built-in predicate, any limitations on its use in runtime systems will be mentioned.
Whenever this manual documents a C function as part of SICStus Prolog's foreign language interface, the function prototype will be displayed in ANSI C syntax.
SICStus Prolog provides two execution modes: the iso mode, which
is fully compliant with the International Standard ISO/IEC 13211-1
(PROLOG: Part 1--General Core), and the sicstus mode, which
supports code written in earlier versions of SICStus Prolog. The
execution mode can be changed using the Prolog flag language;
see State Info. Note, however, that SICStus Prolog does not offer a
strictly conforming mode which rejects uses of implementation specific
features.
To aid programmers who wish to write standard compliant programs,
built-in predicates that are part of the ISO Prolog Standard are
annotated with [ISO] in this manual. If such a predicate behaves
differently in sicstus mode, an appropriate clarification is
given. For the few predicates that have a completely different meaning
in the two modes, two separate descriptions are given. The one for the
iso mode is annotated with [ISO only], while the
sicstus mode version is annotated with [SICStus only].
customer(jones,85) has an arity of 2.
hello * := '#$%' 'New York' 'don\'t'
See Atoms.
Atoms are recognized by the built-in predicate atom/1.
:- symbol.
callable/1.
char_conversion(In, Out), following which In
will be converted to Out. Character coversion can be switched off
by the char_conversion Prolog flag.
true.
,).
compiling Prolog flag.
father(X),
father/1 is the functor, and X is the first and only argument.
The argument to a compound term can be another compound term, as in
father(father(X)).
Compound terms are recognized by the built-in predicate compound/1.
atomic/1.
!. A built-in predicate that succeeds when
encountered; if backtracking should later return to the cut, the goal
that matched the head of the clause containing the cut fails
immediately.
compiling Prolog flag.
sicstus
executable is a development system; new development systems containing
pre-linked foreign resources can also be created.
:-, whose intuitive meaning is "execute this as a query,
but do not print out any variable bindings."
;).
king(louis, france). % Louis was king of France.
have_beaks(birds). % Birds have beaks.
employee(nancy, data_processing, 55000).
% Nancy is an employee in the
% data processing department.
compiling Prolog flag.
foo(a,b) is said to have "the functor foo of arity
two", which is generally written foo/2.
A compound goal is a formula consisting of simple goals connected by
connectives such as "and" (,) or "or" (;).
A goal typed at the top level is called a query.
ground/1.
:- symbol. The head of a
list is the first element of the list.
There are two kinds of importation: procedure-importation, in
which only specified procedures are imported from a module; and
module-importation, in which all the predicates made exported by
a module are imported.
:- initialization
Goal.
[aa, bb,cc] [X, Y] [Name] [[x, y], z]
In the second set of examples, only the first several members of each list are explicitly stated, while the rest of the list is represented by a variable on the right-hand side of the "rest of" operator, |:
[X | Y] [a, b, c | Y] [[x, y] | Rest]
| is also known as the "list constructor." The first element of
the list to the left of | is called the head of the list.
The rest of the list, including the variable following | (which
represents a list of any length), is called the tail of the list.
call/1.
user.
:- module(ModuleName, ExportedPredList).
which must appear as the first term in the file.
is_mutable/1.
likes in
| ?- likes(sue, cider).
is declared an infix operator, the query above could be written:
| ?- sue likes cider.
An operator does not have to be associated with a predicate. However, certain built-in predicates are declared as operators. For example,
| ?- =..(X, Y).
can be written as
| ?- X =.. Y.
because =.. has been declared an infix operator.
Those predicates which correspond to built-in operators are written using infix notation in the list of built-in predicates at the beginning of the part that contains the reference pages.
Some built-in operators do not correspond to built-in predicates; for
example, arithmetic operators. See Standard Operators for a list
of built-in operators.
K-V.
Pairs are used by the built-in predicate keysort/2 and by many
library modules.
< /2 is a built-in predicate
specifying the relationship of one number being less than another. In
contrast, the functor + /2 is not (normally used as) a predicate.
A predicate is either built-in or is implemented by a
procedure.
name/arity or
module:name/arity denoting a predicate.
connects(san_francisco, oakland, bart_train). connects(san_francisco, fremont, bart_train). connects(concord, daly_city, bart_train).
is identified as belonging to the procedure connects/3.
compiling Prolog flag.
save_files/2, save_modules/2, and
save_predicates/2.
fcompile/1.
| ?- father(edward, ralph).
refers to the predicate father/2. If a query has no variables
in it, the system will respond either yes or no. If a query contains
variables, the system will try to find values of those variables for which
the query is true. For example,
| ?- father(edward, X). X = ralph
After the system has found one answer, the user can direct the system to look
for additional answers to the query by typing ;.
has_stiff_neck(ralph) :- hacker(ralph).
This rule states that if the individual ralph is a hacker, then he must
also have a stiff neck. The constant ralph is replaced in
has_stiff_neck(X) :- hacker(X).
by the variable X. X unifies
with anything, so this rule can be used to prove that any hacker has a
stiff neck.
save_program/[1,2].
simple/1.
sicstus
executable), or a runtime system. Both kinds are created by the
spld utility. A stand-alone executable does not itself contain
any Prolog code; all Prolog code must be loaded upon startup.
user_input,
user_output and user_error.
"SICStus"
By setting the Prolog flag double_quotes, the meaning of strings
can be changed. With an appropriate setting, a string can be made
equivalent to a list of one-char atoms, or to an atom. Strings
are not a separate data type.
q, (r, s;
t) the subterm s is selected by the selector [2, 1, 2].
The rules governing the unification of terms are:
Variables may be written as any sequence of alphanumeric characters starting with either a capital letter or _; e.g.
X Y Z Name Position _c _305 One_stop
See Variables.
SICStus Prolog offers the user an interactive programming environment with tools for incrementally building programs, debugging programs by following their executions, and modifying parts of programs without having to start again from scratch.
The text of a Prolog program is normally created in a file or a number of files using one of the standard text editors. The Prolog interpreter can then be instructed to read in programs from these files; this is called consulting the file. Alternatively, the Prolog compiler can be used for compiling the file.
Under UNIX, SICStus Prolog is normally started from one of the shells. On other platforms, it is normally started by clicking on an icon. However, it is often convenient to run SICStus Prolog under GNU Emacs instead. A GNU Emacs interface for SICStus Prolog is described later (see Emacs Interface). From a shell, SICStus Prolog is started by typing:
% sicstus [options] [-a argument...]
where flags have the following meaning:
-f
~/.sicstusrc or
~/.sicstus.ini) on startup. If the flag is omitted and this file
exists, SICStus Prolog will consult it on startup after running any
initializations and printing the version banners.
-i
-m
malloc()/free() in the memory manager's bottom layer.
-l prolog-file
-r saved-state
-a argument...
prolog_flag(argv, Args), which will unify Args with
argument... represented as a list of atoms.
-B[abspath]
-R[abspath]
-B option, except that it builds a saved state
for a runtime system instead.
Under UNIX, a saved state file can be executed directly by typing:
% file argument...
This is equivalent to:
% sicstus -r file [-a argument...]
NOTE: As of release 3.7, saved-states do not
store the complete path of the binary sp.exe. Instead, they call
the main executable sicstus, which is assumed to be found in the
shell's path. If there are several versions of SICStus installed, it is
up to the user to make sure that the correct start-script is found.
Notice that the flags are not available when executing saved states--all the command-line arguments are treated as Prolog arguments.
The development system checks that a valid SICStus license exists and
responds with a message of identification and the prompt | ?-
as soon as it is ready to accept input, thus:
SICStus 3.8 (SunOS-5.5.1-sparc): Thu Aug 19 16:25:28 MET DST 1999 Licensed to SICS | ?-
At this point the top-level is expecting input of a query. You
cannot type in clauses or directives immediately (see Inserting Clauses). While typing in a query, the prompt (on following lines)
becomes . That is, the | ?- appears only for
the first line of the query, and subsequent lines are indented.
The following environment variables can be set before starting SICStus Prolog. Some of these override the default sizes of certain areas. The sizes are given in bytes, but may be followed by K or M meaning kilobytes or megabytes respectively.
SP_CSETLEN
SP_CTYPE
euc (for EUC), utf8 (for Unicode) and iso_8859_1
(for ISO 8859/1). The latter is the default. For the details, see WCX Environment Variables.
SP_PATH
SP_initialize()).
See Setting SP_PATH under UNIX,
for more information.
TMPDIR
/usr/tmp.
GLOBALSTKSIZE
LOCALSTKSIZE
CHOICESTKSIZE
TRAILSTKSIZE
PROLOGINITSIZE
PROLOGMAXSIZE
PROLOGINCSIZE
PROLOGKEEPSIZE
PROLOGKEEPSIZE is returned to the OS; the rest will be
kept.
Send bug reports to sicstus-support@sics.se. Bugs tend actually to be fixed if they can be isolated, so it is in your interest to report them in such a way that they can be easily reproduced.
The mailing list sicstus-users@sics.se is a moderated mailing list for communication among users and implementors. To [un]subscribe, write to sicstus-users-request@sics.se.
A program is made up of a sequence of clauses and directives. The clauses of a predicate do not have to be immediately consecutive, but remember that their relative order may be important (see Procedural).
To input a program from a file file, just type the filename inside list brackets (followed by . and <RET>), thus:
| ?- [file].
This instructs the interpreter to read in (consult) the program. Note that it may be necessary to enclose the filename file in single quotes to make it a legal Prolog atom; e.g.
| ?- ['myfile.pl']. | ?- ['/usr/prolog/somefile'].
The specified file is then read in. Clauses in the file are stored so that they can later be interpreted, while any directives are obeyed as they are encountered. When the end of the file is found, the system displays on the standard error stream the time spent. This indicates the completion of the query.
Predicates that expect the name of a Prolog source file as an argument use
absolute_file_name/2 (see Stream Pred) to look up the file.
This predicate will first search for a file with the suffix .pl added
to the name given as an argument. If this fails it will look for a file
with no extra suffix added. There is also support for libraries.
In general, this query can be any list of filenames, such as:
| ?- [myprog,extras,tests].
In this case all three files would be consulted.
The clauses for all the predicates in the consulted files will replace any existing clauses for those predicates, i.e. any such previously existing clauses in the database will be deleted.
Note that consult/1 in SICStus Prolog behaves like reconsult/1
in DEC-10 Prolog.
Clauses may also be typed in directly at the terminal, although this is only recommended if the clauses will not be needed permanently, and are few in number. To enter clauses at the terminal, you must give the special query:
| ?- [user]. |
and the new prompt | shows that the system is now in a state
where it expects input of clauses or directives. To return to top
level, type ^D. The system responds thus:
{user consulted, 20 msec 200 bytes}
Queries and directives are ways of directing the system to execute some goal or goals.
In the following, suppose that list membership has been defined by loading the following clauses from a file:
member(X, [X|_]). member(X, [_|L]) :- member(X, L).
(Notice the use of anonymous variables written _.)
The full syntax of a query is ?- followed by a sequence of goals.
The top level expects queries. This is signaled
by the initial prompt | ?- . Thus a query at top level looks like:
| ?- member(b, [a,b,c]).
Remember that Prolog terms must terminate with a full stop (., possibly followed by layout text), and that therefore Prolog will not execute anything until you have typed the full stop (and then <RET>) at the end of the query.
If the goal(s) specified in a query can be satisfied, and if there are no variables as in this example, then the system answers
yes
and execution of the query terminates.
If variables are included in the query, then the final value of each variable is displayed (except for variables whose names begin with _). Thus the query
| ?- member(X, [a,b,c]).
would be answered by
X = a
At this point the system is waiting for input of either just a
<RET> or else a ; followed by <RET>. Simply typing
<RET> terminates the query; the system responds with
yes. However, typing ; causes the system to
backtrack (see Procedural) looking for alternative solutions.
If no further solutions can be found it outputs no.
The outcome of some queries is shown below, where a number preceded by _ is a system-generated name for a variable.
| ?- member(X, [tom,dick,harry]). X = tom ; X = dick ; X = harry ; no | ?- member(X, [a,b,f(Y,c)]), member(X, [f(b,Z),d]). X = f(b,c), Y = b, Z = c yes | ?- member(X, [f(_),g]). X = f(_A) yes | ?-
Directives are like queries except that:
Directives start with the symbol :-. Any required output
must be programmed explicitly; e.g. the directive:
:- member(3, [1,2,3]), write(ok).
asks the system to check whether 3 belongs to the list
[1,2,3]. Execution of a directive terminates when all the goals in
the directive have been successfully executed. Other alternative solutions
are not sought. If no solution can be found, the system prints:
{Warning: Goal - goal failed}
as a warning.
The principal use for directives (as opposed to queries) is to allow files to contain directives which call various predicates, but for which you do not want to have the answers printed out. In such cases you only want to call the predicates for their effect, i.e. you don't want terminal interaction in the middle of consulting the file. A useful example would be the use of a directive in a file which consults a whole list of other files, e.g.
:- [ bits, bobs, main, tests, data, junk ].
If a directive like this were contained in the file myprog then typing
the following at top-level would be a quick way of reading in your entire
program:
| ?- [myprog].
When simply interacting with the top-level,
this distinction between queries and directives is not normally very
important.
At top-level you should just type queries normally. In a
file, queries are in fact treated as directives, i.e. if you wish to
execute some goals then the directive in the file must be preceded by
:- or ?-, otherwise it would be treated as a clause.
Syntax errors are detected during reading. Each clause, directive or in
general any term read in by the built-in predicate read/1 that
fails to comply with syntax requirements is displayed on the standard
error stream as soon as it is read, along with its position in the input
stream and a mark indicating the point in the string of symbols where
the parser has failed to continue analysis, e.g.:
| member(X, X$L).
{SYNTAX ERROR: in line 5 (within 5-6)}
** , or ) expected in arguments **
member ( X , X
** here **
$ L ) .
if $ has not been declared as an infix operator.
Note that any comments in the faulty line are not displayed with the error
message. If you are in doubt about which clause was wrong you can use the
listing/1 predicate to list all the clauses which were successfully
read in, e.g.
| ?- listing(member/2).
NOTE: The built in predicates read/[1,2] normaly raise an exception
on syntax errors (see Exception). The behavior is controlled by the
flag syntax_errors (see prolog_flag/3).
There is a difference between predicates that have no definition and predicates that have no clauses. The latter case is meaningful e.g. for dynamic predicates (see Declarations) that clauses are being added to or removed from. There are good reasons for treating calls to undefined predicates as errors, as such calls easily arise from typing errors.
The system can optionally catch calls to predicates that have no
definition. First the user defined predicate
user:unknown_predicate_handler/3 (see Exception) is called. If
undefined or if the call fails the action is governed by the state of
the unknown/2 flag which can be:
trace
error
warning
fail
Calls to predicates that have no clauses are not caught.
The built-in predicate unknown(?OldState, ?NewState)
unifies OldState with the current state and sets the state to
NewState. The built-in predicate debugging/0 prints the
value of this state along with its other information. This state is
also controlled by the flag unknown (see prolog_flag/3).
Execution of a program is started by giving the system a query which contains a call to one of the program's predicates.
Only when execution of one query is complete does the system become ready for another query. However, one may interrupt the normal execution of a query by typing ^C. This ^C interruption has the effect of suspending the execution, and the following message is displayed:
Prolog interruption (h or ? for help) ?
At this point, the development system accepts one-letter commands corresponding to certain actions. To execute an action simply type the corresponding character (lower or upper case) followed by <RET>. The available commands in development systems are:
If the standard input stream is not connected to the terminal, e.g. by redirecting standard input to a file or a pipe, the above ^C interrupt options are not available. Instead, typing ^C causes SICStus Prolog to exit, and no terminal prompts are printed.
To exit from the top-level and return to the shell, either type
^D at the top-level, or call the built-in predicate halt/0,
or use the e (exit) command following a ^C interruption.
The Prolog system provides a way to suspend the execution of your program and to enter a new incarnation of the top level where you can issue queries to solve goals etc. This is achieved by issuing the query (see Execution):
| ?- break.
This invokes a recursive top-level, indicated by the message:
{ Break level 1 }
You can now type queries just as if you were at top-level.
If another call of break/0 is encountered, it moves up to level 2,
and so on. To close the break and resume the execution which was
suspended, type ^D. The debugger state and current input and output
streams will be restored, and execution will be resumed at the predicate
call where it had been suspended after printing the message:
{ End break }
Alternatively, the suspended execution can be aborted by calling the
built-in predicate abort/0.
A suspended execution can be aborted by issuing the query:
| ?- abort.
within a break. In this case no ^D is needed to close the break;
all break levels are discarded and the system returns right back
to top-level. I/O streams remain open, but the debugger is switched off.
abort/0 may also be called from within a program.
Once a program has been read, the system will have available all the information necessary for its execution. This information is called a program state.
The state of a program may be saved on disk for future execution. The
state consists of all predicates and modules
except built-in predicates and clauses of volatile predicates,
the current operator declarations, the values of all writable Prolog
flags except debugging, source_info, and the user_*
stream aliases (see State Info), any blackboard data
(see Blackboard Primitives), internal database data
(see Database), and profiling data (see Profiling), but no
information for source-linked debugging.
To save a program into a file File, type the following query. On UNIX platforms, the file becomes executable:
| ?- save_program(File).
You can also specify a goal to be run when a saved program is restored. This is done by:
| ?- save_program(File, start).
where start/0 is the predicate to be called.
Once a program has been saved into a file File, the following query will restore the system to the saved state:
| ?- restore(File).
If a saved state has been moved or copied to another machine, the path names of foreign resources and other files needed upon restore are typically different at restore time from their save time values. To solve this problem, certain atoms will be relocated during restore as follows:
$SP_PATH/library (the name of the directory
containing the Prolog Library) as prefix at save time will have that
prefix replaced by the corresponding restore time value.
The purpose of this procedure is to be able to build and deploy an application consisting of a saved state and other files as a directory tree with the saved state at the root: as long as the other files maintain their relative position in the deployed copy, they can still be found upon restore.
NOTE: Foreign resources, see Calling C, are unloaded by
save_program/[1,2]. The names and paths of the
resources, typically $SP_PATH/library relative,
are however included in the saved state. After the save, and
after restoring a saved state, this information is used to reload
the foreign resources again. The state of the foreign resource in terms
of global C variables and allocated memory is thus not
preserved. Foreign resources may define init and deinit
functions to take special action upon loading and unloading, see Init and Deinit Functions.
As of SICStus Prolog 3.8, partial saved states corresponding to a set of
source files, modules, and predicates can be created by the built-in
predicates save_files/2, save_modules/2, and
save_predicates/2 respectively. These predicates create files in
a binary format, by default with the prefix .po (for Prolog
object file), which can be loaded by load_files/[1,2].
For example, to compile a program split into several source files into a
single object file, type:
| ?- compile(Files), save_files(Files, Object).
For each filename given, the first goal will try to locate a source file
with the default suffix .pl and compile it into memory. The
second goal will save the program just compiled into an object file
whose default suffix is .po. Thus the object file will contain a
partial memory image.
This section explains how to use the GNU Emacs interface for SICStus Prolog, and how to customize your GNU Emacs environment for it.
Emacs is a powerful programmable editor especially suitable for program development. It is available for free for many platforms, including various UNIX dialects, Windows and MacOS. For information on obtaining Emacs, see www.emacs.org. For information specific to GNU Emacs or XEmacs, see www.gnu.org and www.xemacs.org respectively.
The advantages of using SICStus in the Emacs environment are source-linked debugging, auto indentation, syntax highlighting, help on predefined predicates (requires the SICStus info files to be installed), loading code from inside Emacs, auto-fill mode, and more.
The Emacs interface is not part of SICStus Prolog proper, but is included in the distribution for convenience. It was written by Emil Ĺström and Milan Zamazal, based on an earlier version of the mode written by Masanobu Umeda. Contributions has also been made by Johan Andersson, Peter Olin, Mats Carlsson, Johan Bevemyr, Stefan Andersson, and Per Danielsson, Henrik Bĺkman, and Tamás Rozmán. Some ideas and also a few lines of code have been borrowed (with permission) from Oz.el by Ralf Scheidhauer and Michael Mehl, the Emacs major mode for the Oz programming language. More ideas and code have been taken from the SICStus debugger mode by Per Mildner.
See The Emacs Interface, for more information about installing the Emacs interface.
There are some differences between GNU Emacs and XEmacs. This will be indicated with Emacs-Lisp comments in the examples.
Version 20 of GNU Emacs and XEmacs introduced a new method for
editing and storing user settings. This feature is available from the
menu bar as Customize and particular Emacs variables can be
customized with M-x customize-variable. Using Customize is
the preferred way to modify the settings for emacs and
the appropriate customize commands will be indicated below, sometimes
together with the old method of directly setting Emacs variables.
Assuming the Emacs interface for SICStus Prolog has been installed in
the default location, inserting the following lines in your
~/.emacs will make Emacs use this mode automatically when editing
files with a .pl extension:
(setq load-path
(cons (expand-file-name "/usr/local/lib/sicstus-3.8/emacs")
load-path))
(autoload 'run-prolog "prolog" "Start a Prolog sub-process." t)
(autoload 'prolog-mode "prolog" "Major mode for editing Prolog programs." t)
(setq prolog-use-sicstus-sd t)
(setq auto-mode-alist (cons '("\\.pl$" . prolog-mode) auto-mode-alist))
where the path in the first line is the file system path to
prolog.el (the generic Prolog mode) and sicstus-support.el
(SICStus specific code). For example, ~/emacs means that the
file is in the user's home directory, in directory emacs. Windows paths
can be written like C:/Program Files/SICStus/emacs.
The last line above makes sure that files ending with .pl are
assumed to be Prolog files and not Perl, which is the default Emacs
setting. If this is undesirable, remove that line. It is then necessary
for the user to manually switch to prolog mode by typing M-x
prolog-mode after opening a prolog file, for an alternative approach,
see Mode Line.
If the shell command sicstus is not available in the default
path, then it is necessary to set the value of the environment variable
EPROLOG to a shell command to invoke SICStus Prolog. This is an
example for C Shell:
setenv EPROLOG /usr/local/bin/sicstus
It is possible to look up the documentation for any built in or library
predicate from within Emacs (using C-c ? or the menu). For this to
work Emacs must be told about the location of the info-files that
make up the documentation.
The default location for the info-files are
<prefix>/lib/sicstus-3.8/doc/info/ on UNIX platforms and
C:/Program Files/SICStus/doc/info/ on Windows.
Add the following to your ~/.emacs file, assuming INFO is the
path to the info files, e.g., C:/Program Files/SICStus/doc/info/
(setq Info-default-directory-path
(append Info-default-directory-path '("INFO")))
for GNU Emacs, or
(setq Info-directory-path
(append Info-directory-path '("INFO")))
for XEmacs. You can also use M-x customize-group <RET> info <RET> if your Emacs is new enough. You may have to quit and restart Emacs for these changes to take effect.
If the following lines are not present in ~/.emacs, we suggest
they are added, so that the font-lock mode (syntax coloring support) is
enabled for all major modes in Emacs that support it.
(global-font-lock-mode t) ; GNU Emacs (setq font-lock-auto-fontify t) ; XEmacs (setq font-lock-maximum-decoration t)
These settings and more are also available through M-x customize-group <RET> font-lock.
If one wants to add font-locking only to the prolog mode, the two lines above could be replaced by:
(add-hook 'prolog-mode-hook 'turn-on-font-lock)
Similarly, to turn it off only for prolog mode use:
(add-hook 'prolog-mode-hook 'turn-off-font-lock)
A prolog process can be started by choosing Run Prolog from the
Prolog menu, by typing C-c <RET>, or by typing M-x
run-prolog. It is however not strictly necessary to start a prolog
process manually since it is automatically done when consulting or
compiling, if needed. The process can be restarted (i.e. the old one is
killed and a new one is created) by typing C-u C-c <RET>.
Programs are run and debugged in the normal way, with terminal I/O
via the *prolog* buffer. The most common debugging predicates
are available from the menu or via key-bindings.
A particularly useful feature under the Emacs interface is source-linked
debugging. This is enabled or disabled using the Prolog/Source
level debugging menu entry. It can also be enabled by setting the Emacs
variable prolog-use-sicstus-sd to t in
~/.emacs. Both these methods set the Prolog flag
source_info to emacs. Its value should be emacs while
loading the code to be debugged and while debugging. If so, the debugger
will display the source code location of the current goal when it
prompts for a debugger command, by overlaying the beginning of the
current line of code with an arrow. If source_info was
off when the code was loaded, or if it was asserted or loaded
from user, the current goal will still be shown but out of
context.
Note that if the code has been modified since it was last loaded, Prolog's line number information may be invalid. If this happens, just reload the relevant buffer.
Consultation and compilation is either done via the menu or with the following key-bindings:
The boundaries used when consulting and compiling predicates are the first and last clauses of the predicate the cursor is currently in.
Other useful key-bindings are:
comment-column. This comment will always
stay at this position when the line is indented, regardless of changes
in the text earlier on the line, provided that
prolog-align-comments-flag is set to t.
prolog-electric-dot-flag variable
below.
Prolog/Transform/All variables to '_'
menu entry. See also the prolog-electric-underscore-flag
Emacs variable.
prolog-info-predicate-index.
If working with an application split into several modules, it is often useful to let files begin with a "mode line":
%%% -*- Mode: Prolog; Module: ModuleName; -*-
The Emacs interface will look for the mode line and notify the SICStus
Prolog module system that code fragments being incrementally
reconsulted or recompiled should be imported into the module
ModuleName. If the mode line is missing, the code fragment will
be imported into the type-in module. An additional benefit of the
mode line is that it tells Emacs that the file contains Prolog code,
regardless of the setting of the Emacs variable
auto-mode-alist. A mode line can be inserted by choosing
Insert/Module modeline in the Prolog menu.
The behavior of the Emacs interface can be controlled by a set of user-configurable settings. Some of these can be changed on the fly, while some require Emacs to be restarted. To set a variable on the fly, type M-x set-variable <RET> VariableName <RET> Value <RET>. Note that variable names can be completed by typing a few characters and then pressing <TAB>.
To set a variable so that the setting is used every time Emacs is
started, add lines of the following format to ~/.emacs:
(setq VariableName Value)
Note that the Emacs interface is presently not using the
Customize functionality to edit the settings.
The available settings are:
prolog-system
'sicstus, which will be assumed for the rest of this
chapter. See the on-line documentation for the meaning of other
settings. For other settings of prolog-system the variables below
named sicstus-something will not be used, in some cases
corresponding functionality is available through variables named
prolog-something.
sicstus-version
'(3 . 8).
Note that the spaces are significant!
prolog-use-sicstus-sd
t (the default) to enable the source-linked debugging
extensions by default. The debugging can be enabled via the
Prolog menu even if this variable is nil. Note that the
source-linked debugging only works if sicstus-version is
set correctly.
pltrace-port-arrow-assoc [Obsolescent]
'(("call" . ">>>") ("exit" . "+++") ("ndexit" . "?++")
("redo" . "<<<") ("fail" . "---") ("exception" . "==>"))
where ndexit is the non-determinate variant of the Exit port. Do
not rely on this variable. It will change in future releases.
prolog-indent-width
tab-width, normally 8.
prolog-paren-indent
p :-
( q1
; q2,
q3
).
Note that the spaces between the parentheses and the code are
automatically inserted when <TAB> is pressed at those positions.
prolog-align-comments-flag
nil to prevent single %-comments to be automatically
aligned. Defaults to t.
Note that comments with one % are indented to comment-column, comments
with two % to the code level, and that comments with three % are
never changed when indenting.
prolog-indent-mline-comments-flag
nil to prevent indentation of text inside /*
... */ comments. Defaults t.
prolog-object-end-to-0-flag
} of an object definition to
prolog-indent-width. Defaults to t.
sicstus-keywords
:- keyword). Defaults to
'((sicstus
("block" "discontiguous" "dynamic" "initialization"
"meta_predicate" "mode" "module" "multifile" "public" "volatile"))))
prolog-electric-newline-flag
nil to prevent Emacs from automatically indenting the next
line when pressing <RET>. Defaults to t.
prolog-hungry-delete-key-flag
t to enable deletion of all white space before the cursor
when pressing the delete key (unless inside a comment, string, or quoted
atom). Defaults to nil.
prolog-electric-dot-flag
t to enable the electric dot function. If enabled,
pressing . at the end of a non-empty line inserts a dot and a
newline. When pressed at the beginning of a line, a new head of the
last predicate is inserted. When pressed at the end of a line with only
whitespace, a recursive call to the current predicate is inserted. The
function respects the arity of the predicate and inserts parentheses and
the correct number of commas for separation of the arguments. Defaults
to nil.
prolog-electric-underscore-flag
t to enable the electric underscore function. When
enabled, pressing underscore (_) when the cursor is on a variable,
replaces the variable with the anynomous variable. Defaults to
nil.
prolog-old-sicstus-keys-flag
t to enable the key-bindings of the old Emacs interface. These
bindings are not used by default since they violate GNU Emacs
recommendations. Defaults to nil.
prolog-use-prolog-tokenizer-flag
nil to use built-in functions of Emacs for parsing the
source code when indenting. This is faster than the default but does not
handle some of the syntax peculiarities of Prolog. Defaults to t.
prolog-parse-mode
'beg-of-line and 'beg-of-clause. The first is
faster but may result in erroneous indentation in /* ... */
comments. The default is 'beg-of-line.
prolog-imenu-flag
t to enable a new Predicate menu which contains all
predicates of the current file. Choosing an entry in the menu moves the
cursor to the start of that predicate. Defaults to nil.
prolog-info-predicate-index
C-c ?, or
choosing the Prolog/Help on predicate menu entry). The default
setting is "(sicstus)Predicate Index".
prolog-underscore-wordchar-flag
nil to not make underscore (_) a word-constituent
character. Defaults to t.
Some general tips and tricks for using the SICStus mode and Emacs in general are given here. Some of the methods may not work in all versions of Emacs.
When editing large files, it might happen that font-locking is not done because the file is too large. Typing M-x lazy-lock-mode results in only the visible parts of the buffer being highlighted, which is much faster, see its Emacs on-line documentation for details.
If the font-locking seems to be incorrect, choose Fontify
Buffer from the Prolog menu.
Auto-fill mode is enabled by typing M-x auto-fill-mode. This enables automatic line breaking with some features. For example, the following multiline comment was created by typing M-; followed by the text. The second line was indented and a % was added automatically.
dynamics([]). % A list of pit furnace
% dynamic instances
There are several things to do if the speed of the Emacs environment is a problem:
prolog.el and sicstus-support.el
are compiled, i.e. that there is a prolog.elc and a
sicstus-support.elc file at the same location as the original
files. To do the compilation, start Emacs and type M-x
byte-compile-file <RET> path <RET>, where path is the path to the
*.el file. Do not be alarmed if there are a few warning messages
as this is normal. If all went well, there should now be a compiled
file which is used the next time Emacs is started.
prolog-use-prolog-tokenizer-flag to nil. This means that
Emacs uses built-in functions for some of the source code parsing, thus
speeding up indentation. The problem is that it does not handle all
peculiarities of the Prolog syntax, so this is a trade-off between
correctness and speed.
prolog-parse-mode variable also affects
the speed, 'beg-of-line being faster than 'beg-of-clause.
The prolog mode uses the default Emacs colors for font-locking as far as possible. The only custom settings are in the prolog process buffer. The default settings of the colors may not agree with your preferences, so here is how to change them.
If your emacs support it, use Customize, M-x
customize-group <RET> font-lock <RET> will show the
Customize settings for font locking and also contains pointers to
the Customize group for the font lock (type)faces. The rest of
this section outlines the more involved methods needed in older versions
of Emacs.
First of all, list all available faces (a face is a combined setting of foreground and background colors, font, boldness, etc.) by typing M-x list-faces-display.
There are several functions that change the appearance of a face, the ones you will most likely need are:
set-face-foreground
set-face-background
set-face-underline-p
make-face-bold
make-face-bold-italic
make-face-italic
make-face-unbold
make-face-unitalic
These can be tested interactively by typing M-x
function-name. You will then be asked for the name of the face to
change and a value. If the buffers are not updated according to the new
settings, then refontify the buffer using the Fontify Buffer menu entry
in the Prolog menu.
Colors are specified by a name or by RGB values. Available color names can be listed with M-x list-colors-display.
To store the settings of the faces, a few lines must be added to
~/.emacs. For example:
;; Customize font-lock faces
(add-hook 'font-lock-mode-hook
'(lambda ()
(set-face-foreground font-lock-variable-name-face "#00a000")
(make-face-bold font-lock-keyword-face)
(set-face-foreground font-lock-reference-face "Blue")
))
This chapter provides a brief introduction to the syntax and semantics of a certain subset of logic (definite clauses, also known as Horn clauses), and indicates how this subset forms the basis of Prolog.
The data objects of the language are called terms. A term is either a constant, a variable or a compound term.
The constants include integers such as
0 1 999 -512
Besides the usual decimal, or base 10, notation, integers may also be
written in other base notations. In sicstus mode, any base from
2 to 36 can be specified, while in iso mode bases 2 (binary), 8 (octal),
and 16 (hex) can be used. Letters A through
Z (upper or lower case) are used for bases greater than 10. E.g.
15 2'1111 8'17 16'f % sicstus mode 15 0b1111 0o17 0xf % iso mode
all represent the integer fifteen. Except for the first, decimal,
notation, the forms in the first line are only acceptable in
sicstus mode, while those in the second line are only valid in
iso mode.
There is also a special notation for character constants. E.g.
0'A 0'\x41 0'\101
are all equivalent to 65 (the character code for A).
0' followed by any character except \ (backslash) is thus
read as an integer. If 0' is followed by \, the \
denotes the start of an escape sequence with special meaning
(see Escape Sequences).
Constants also include floats such as
1.0 -3.141 4.5E7 -0.12e+8 12.0e-9
Note that there must be a decimal point in floats written with an exponent, and that there must be at least one digit before and after the decimal point.
Constants also include atoms such as
a void = := 'Algol-68' []
Atoms are definite elementary objects, and correspond to proper nouns in natural language. For reference purposes, here is a list of the possible forms which an atom may take:
'can\'t'. Backslashes in the sequence denote escape sequences
(see Escape Sequences).
{X}
is allowed as an alternative to {}(X). The form
[X] is the normal notation for lists, as an alternative to
.(X,[]).
Variables may be written as any sequence of alphanumeric characters (including _) starting with either a capital letter or _; e.g.
X Value A A1 _3 _RESULT
If a variable is only referred to once in a clause, it does not need to be named and may be written as an anonymous variable, indicated by the underline character _. A clause may contain several anonymous variables; they are all read and treated as distinct variables.
A variable should be thought of as standing for some definite but unidentified object. This is analogous to the use of a pronoun in natural language. Note that a variable is not simply a writable storage location as in most programming languages; rather it is a local name for some data object, cf. the variable of pure LISP and identity declarations in Algol68.
The structured data objects of the language are the compound terms. A
compound term comprises a functor (called the principal functor of
the term) and a sequence of one or more terms called arguments. A
functor is characterized by its name, which is an atom, and its arity
or number of arguments. For example the compound term whose functor is
named point of arity 3, with arguments X, Y and
Z, is written
point(X, Y, Z)
Note that an atom is considered to be a functor of arity 0.
Functors are generally analogous to common nouns in natural language. One may think of a functor as a record type and the arguments of a compound term as the fields of a record. Compound terms are usefully pictured as trees. For example, the term
s(np(john),vp(v(likes),np(mary)))
would be pictured as the compound term
s
/ \
np vp
| / \
john v np
| |
likes mary
Sometimes it is convenient to write certain functors as operators--2-ary functors may be declared as infix operators and 1-ary functors as prefix or postfix operators. Thus it is possible to write, e.g.
X+Y (P;Q) X<Y +X P;
as optional alternatives to
+(X,Y) ;(P,Q) <(X,Y) +(X) ;(P)
The use of operators is described fully below (see Operators).
Lists form an important class of data structures in Prolog. They are
essentially the same as the lists of LISP: a list either is the atom
[] representing the empty list, or is a compound term with
functor . and two arguments which are respectively the head and
tail of the list. Thus a list of the first three natural numbers is the
compound term
.
/ \
1 .
/ \
2 .
/ \
3 []
which could be written, using the standard syntax, as
.(1,.(2,.(3,[])))
but which is normally written, in a special list notation, as
[1,2,3]
The special list notation in the case when the tail of a list is a variable is exemplified by
[X|L] [a,b|L]
representing
. .
/ \ / \
X L a .
/ \
b L
respectively.
Note that this notation does not add any new power to the language; it simply makes it more readable. e.g. the above examples could equally be written
.(X,L) .(a,.(b,L))
For convenience, a further notational variant is allowed for lists of integers which correspond to character codes or one-char atoms. Lists written in this notation are called strings. E.g.
"SICStus"
which, by default, represents exactly the same list as
[83,73,67,83,116,117,115]
The Prolog flag double_quotes can be used to change the way
strings are interpreted. The default value of the flag is codes,
which implies the above interpretation. If the flag is set to
chars, a string is transformed to a list of one-char atoms.
E.g. with this setting the above string represents the list:
['S','I','C','S',t,u,s]
Finally if double_quotes has the value atom, then the string is
made equivalent to the atom formed from its characters: the above sample
string is then the same as the atom 'SICStus'.
As for quoted atoms, if a double quote character is included in the
sequence it must be escaped, e.g. "can\'t". Backslashes
in the sequence denote escape sequences (see Escape Sequences).
A fundamental unit of a logic program is the goal or procedure call. e.g.
gives(tom, apple, teacher) reverse([1,2,3], L) X<Y
A goal is merely a special kind of term, distinguished only by the context in which it appears in the program. The (principal) functor of a goal identifies what predicate the goal is for. It corresponds roughly to a verb in natural language, or to a procedure name in a conventional programming language.
A logic program consists simply of a sequence of statements called sentences, which are analogous to sentences of natural language. A sentence comprises a head and a body. The head either consists of a single goal or is empty. The body consists of a sequence of zero or more goals (i.e. it too may be empty). If the head is not empty, the sentence is called a clause.
If the body of a clause is empty, the clause is called a unit clause, and is written in the form
P.
where P is the head goal. We interpret this declaratively as
Goals matching P are true.
and procedurally as
Goals matching P are satisfied.
If the body of a clause is non-empty, the clause is called a rule, and is written in the form
P :- Q, R, S.
where P is the head goal and Q, R and S are the goals which make up the body. We can read such a clause either declaratively as
P is true if Q and R and S are true.
or procedurally as
To satisfy goal P, satisfy goals Q, R and S.
A sentence with an empty head is called a directive (see Directives), and is written in the form
:- P, Q.
where P and Q are the goals of the body. Such a query is read declaratively as
Are P and Q true?
and procedurally as
Satisfy goals P and Q.
Sentences generally contain variables. Note that variables in different sentences are completely independent, even if they have the same name--i.e. the lexical scope of a variable is limited to a single sentence. Each distinct variable in a sentence should be interpreted as standing for an arbitrary entity, or value. To illustrate this, here are some examples of sentences containing variables, with possible declarative and procedural readings:
employed(X) :- employs(Y,X).
"Any X is employed if any Y employs X."
"To find whether a person X is employed, find whether any Y employs X."
derivative(X,X,1).
"For any X, the derivative of X with respect to X is 1."
"The goal of finding a derivative for the expression X with respect to X itself is satisfied by the result 1."
?- ungulate(X), aquatic(X).
"Is it true, for any X, that X is an ungulate and X is aquatic?"
"Find an X which is both an ungulate and aquatic."
In any program, the predicate for a particular (principal) functor
is the sequence of clauses in the program whose head goals have that
principal functor. For example, the predicate for a 3-ary functor
concatenate/3 might well consist of the two clauses
concatenate([], L, L). concatenate([X|L1], L2, [X|L3]) :- concatenate(L1, L2, L3).
where concatenate(L1,L2,L3) means "the list
L1 concatenated with the list L2 is the list L3".
Note that for predicates with clauses corresponding to a base case and a
recursive case, the preferred style is to write the base case clause
first.
In Prolog, several predicates may have the same name but different
arities. Therefore, when it is important to specify a predicate
unambiguously, the form name/arity is used; e.g.
concatenate/3.
Certain predicates are predefined by built-in predicates supplied by the Prolog system. Such predicates are called built-in predicates.
As we have seen, the goals in the body of a sentence are linked by the
operator , which can be interpreted as conjunction ("and"). It
is sometimes convenient to use an additional operator ;, standing
for disjunction ("or"). (The precedence of ; is such that it
dominates , but is dominated by :-.) An example is the
clause
grandfather(X, Z) :-
(mother(X, Y); father(X, Y)),
father(Y, Z).
which can be read as
For any X, Y and Z, X has Z as a grandfather if either the mother of X is Y or the father of X is Y, and the father of Y is Z.
Such uses of disjunction can always be eliminated by defining an extra predicate--for instance the previous example is equivalent to
grandfather(X,Z) :- parent(X,Y), father(Y,Z). parent(X,Y) :- mother(X,Y). parent(X,Y) :- father(X,Y).
--and so disjunction will not be mentioned further in the following, more formal, description of the semantics of clauses.
The token |, when used outside a list, is an alias for ;.
The aliasing is performed when terms are read in, so that
a :- b | c.
is read as if it were
a :- b ; c.
Note the double use of the . character. On the one hand it is
used as a sentence terminator, while on the other it may be used in a
string of symbols which make up an atom (e.g. the list functor
./2). The rule used to disambiguate terms is that a .
followed by layout-text is regarded as a sentence terminator
(see Token String).
The semantics of definite clauses should be fairly clear from the informal interpretations already given. However it is useful to have a precise definition. The declarative semantics of definite clauses tells us which goals can be considered true according to a given program, and is defined recursively as follows.
A goal is true if it is the head of some clause instance and each of the goals (if any) in the body of that clause instance is true, where an instance of a clause (or term) is obtained by substituting, for each of zero or more of its variables, a new term for all occurrences of the variable.
For example, if a program contains the preceding procedure for
concatenate/3, then the declarative semantics tells us that
?- concatenate([a], [b], [a,b]).
is true, because this goal is the head of a certain instance of the
first clause for concatenate/3, namely,
concatenate([a], [b], [a,b]) :- concatenate([], [b], [b]).
and we know that the only goal in the body of this clause instance is
true, since it is an instance of the unit clause which is the second
clause for concatenate/3.
Note that the declarative semantics makes no reference to the sequencing of goals within the body of a clause, nor to the sequencing of clauses within a program. This sequencing information is, however, very relevant for the procedural semantics which Prolog gives to definite clauses. The procedural semantics defines exactly how the Prolog system will execute a goal, and the sequencing information is the means by which the Prolog programmer directs the system to execute the program in a sensible way. The effect of executing a goal is to enumerate, one by one, its true instances. Here then is an informal definition of the procedural semantics. We first illustrate the semantics by the simple query
?- concatenate(X, Y, [a,b]).
We find that it matches the head of the first clause for
concatenate/3, with X instantiated to [a|X1].
The new variable X1 is constrained by the new query produced,
which contains a single recursive procedure call:
?- concatenate(X1, Y, [b]).
Again this goal matches the first clause, instantiating X1 to
[b|X2], and yielding the new query:
?- concatenate(X2, Y, [])
Now the single goal will only match the second clause, instantiating
both X2 and Y to []. Since there are no further
goals to be executed, we have a solution
X = [a,b] Y = []
i.e. a true instance of the original goal is
concatenate([a,b], [], [a,b])
If this solution is rejected, backtracking will generate the further solutions
X = [a] Y = [b] X = [] Y = [a,b]
in that order, by re-matching, against the second clause for concatenate, goals already solved once using the first clause.
Thus, in the procedural semantics, the set of clauses
H :- B1, ..., Bm. H' :- B1', ..., Bm'. ...
are regarded as a procedure definition for some predicate H, and in a query
?- G1, ..., Gn.
each Gi is regarded as a procedure call. To execute a query, the system selects by its computation rule a goal, Gj say, and searches by its search rule a clause whose head matches Gj. Matching is done by the unification algorithm (see [Robinson 65] which computes the most general unifier, mgu, of Gj and H. The mgu is unique if it exists. If a match is found, the current query is reduced to a new query
?- (G1, ..., Gj-1, B1, ..., Bm, Gj+1, ..., Gn)mgu.
and a new cycle is started. The execution terminates when the empty query has been produced.
If there is no matching head for a goal, the execution backtracks to the most recent successful match in an attempt to find an alternative match. If such a match is found, an alternative new query is produced, and a new cycle is started.
In SICStus Prolog, as in other Prolog systems, the search rule is simple: "search forward from the beginning of the program".
The computation rule in traditional Prolog systems is also simple: "pick the leftmost goal of the current query". However, SICStus Prolog and other modern implementations have a somewhat more complex computation rule "pick the leftmost unblocked goal of the current query".
A goal can be blocked on one ore more uninstantiated variables, and a variable may block several goals. Thus binding a variable can cause blocked goals to become unblocked, and backtracking can cause currently unblocked goals to become blocked again. Moreover, if the current query is
?- G1, ..., Gj-1, Gj, Gj+1, ..., Gn.
where Gj is the first unblocked goal, and matching Gj against a clause head causes several blocked goals in G1, ..., Gj-1 to become unblocked, then these goals may become reordered. The internal order of any two goals that were blocked on the same variable is retained, however.
Another consequence is that a query may be derived consisting entirely of blocked goals. Such a query is said to have floundered. The top-level checks for this condition. If detected, the outstanding blocked subgoals are printed on the standard error stream along with the answer substitution, to notify the user that the answer (s)he has got is really a speculative one, since it is only valid if the blocked goals can be satisfied.
A goal is blocked if certain arguments are uninstantiated and its predicate definition is annotated with a matching block declaration (see Block Declarations). Goals of certain built-in may also be blocked if their arguments are not sufficiently instantiated.
When this mechanism is used, the control structure resembles that of coroutines, suspending and resuming different threads of control. When a computation has left blocked goals behind, the situation is analogous to spawning a new suspended thread. When a blocked goal becomes unblocked, the situation is analogous to temporarily suspending the current thread and resuming the thread to which the blocked goal belongs.
It is possible, and sometimes useful, to write programs which unify a variable to a term in which that variable occurs, thus creating a cyclic term. The usual mathematical theory behind Logic Programming forbids the creation of cyclic terms, dictating that an occurs-check should be done each time a variable is unified with a term. Unfortunately, an occurs-check would be so expensive as to render Prolog impractical as a programming language. Thus cyclic terms may be created and may cause loops trying to print them.
SICStus Prolog mitigates the problem by its ability to unify, compare
(see Term Compare), assert, and copy cyclic terms without looping.
The write_term/[2,3] built-in predicate can optionally handle cyclic
terms; see Term I/O. Unification with occurs-check is available as
a built-in predicate; see Misc Pred. Predicates
testing (a)cyclicity are available in a library package;
see Term Utilities. Other predicates usually do not handle
cyclic terms well.
Besides the sequencing of goals and clauses, Prolog provides one other
very important facility for specifying control information. This is the
cut symbol, written !. It is inserted in the program just
like a goal, but is not to be regarded as part of the logic of the
program and should be ignored as far as the declarative semantics is
concerned.
The effect of the cut symbol is as follows. When first encountered as a goal, cut succeeds immediately. If backtracking should later return to the cut, the effect is to fail the parent goal, i.e. that goal which matched the head of the clause containing the cut, and caused the clause to be activated. In other words, the cut operation commits the system to all choices made since the parent goal was invoked, and causes other alternatives to be discarded. The goals thus rendered determinate are the parent goal itself, any goals occurring before the cut in the clause containing the cut, and any subgoals which were executed during the execution of those preceding goals.
For example:
member(X, [X|_]). member(X, [_|L]) :- member(X, L).
This predicate can be used to test whether a given term is in a list. E.g.
| ?- member(b, [a,b,c]).
returns the answer yes. The predicate can also be used to extract
elements from a list, as in
| ?- member(X, [d,e,f]).
With backtracking this will successively return each element of the list. Now suppose that the first clause had been written instead:
member(X, [X|_]) :- !.
In this case, the above call would extract only the first element of the
list (d). On backtracking, the cut would immediately fail the whole
predicate.
x :- p, !, q. x :- r.
This is equivalent to
x := if p then q else r;
in an Algol-like language.
It should be noticed that a cut discards all the alternatives since the parent goal, even when the cut appears within a disjunction. This means that the normal method for eliminating a disjunction by defining an extra predicate cannot be applied to a disjunction containing a cut.
A proper use of the cut is usually a major difficulty for new Prolog programmers. The usual mistakes are to over-use cut, and to let cuts destroy the logic. A cut that doesn't destroy the logic is called a green cut; a cut that does is called a red cut. We would like to advise all users to follow these general rules. Also see Example Intro.
Operators in Prolog are simply a notational convenience. For
example, the expression 2+1 could also be written +(2,1).
This expression represents the compound term
+ / \ 2 1
and not the number 3. The addition would only be performed if
the term were passed as an argument to an appropriate predicate such as
is/2 (see Arithmetic).
The Prolog syntax caters for operators of three main kinds--infix, prefix and postfix. An infix operator appears between its two arguments, while a prefix operator precedes its single argument and a postfix operator is written after its single argument.
Each operator has a precedence, which is a number from 1 to 1200. The
precedence is used to disambiguate expressions where the structure of
the term denoted is not made explicit through the use of parentheses.
The general rule is that it is the operator with the highest
precedence that is the principal functor. Thus if + has a higher
precedence than /, then
a+b/c a+(b/c)
are equivalent and denote the term +(a,/(b,c)). Note that the
infix form of the term /(+(a,b),c) must be written with explicit
parentheses, i.e.
(a+b)/c
If there are two operators in the subexpression having the same highest precedence, the ambiguity must be resolved from the types of the operators. The possible types for an infix operator are
xfx xfy yfx
Operators of type xfx are not associative: it is a requirement
that both of the two subexpressions which are the arguments of the
operator must be of lower precedence than the operator itself,
i.e. their principal functors must be of lower precedence, unless the
subexpression is explicitly parenthesized (which gives it zero
precedence).
Operators of type xfy are right-associative: only the first
(left-hand) subexpression must be of lower precedence; the right-hand
subexpression can be of the same precedence as the main operator.
Left-associative operators (type yfx) are the other way around.
A functor named name is declared as an operator of type Type and precedence precedence by the directive:
:- op(precedence, type, name).
The argument name can also be a list of names of operators of the same type and precedence.
It is possible to have more than one operator of the same name, so long as they are of different kinds, i.e. infix, prefix or postfix. Note that the ISO Prolog standard contains a limitation that there should be no infix and postfix operators with the same name, however, SICStus Prolog lifts this restriction.
An
operator of any kind may be redefined by a new declaration of the same
kind. This applies equally to operators which are provided as standard,
except for the ',' operator.
Declarations of all the standard operators can be found elsewhere
(see Standard Operators).
For example, the standard operators + and - are declared by
:- op(500, yfx, [ +, - ]).
so that
a-b+c
is valid syntax, and means
(a-b)+c
i.e.
+ / \ - c / \ a b
The list functor . is not a standard operator, but if we declare it thus:
:- op(900, xfy, .).
then a.b.c would represent the compound term
. / \ a . / \ b c
Contrasting this with the diagram above for a-b+c shows the
difference between yfx operators where the tree grows to the
left, and xfy operators where it grows to the right. The tree
cannot grow at all for xfx operators; it is simply illegal to
combine xfx operators having equal precedences in this way.
The possible types for a prefix operator are
fx fy
and for a postfix operator they are
xf yf
The meaning of the types should be clear by analogy with those for infix
operators. As an example, if not were declared as a prefix
operator of type fy, then
not not P
would be a permissible way to write not(not(P)). If the type
were fx, the preceding expression would not be legal, although
not P
would still be a permissible form for not(P).
If these precedence and associativity rules seem rather complex, remember that you can always use parentheses when in any doubt.
Note that the arguments of a compound term written in standard syntax
must be expressions of precedence below 1000. Thus it is
necessary to parenthesize the expression P :- Q in
| ?- assert((P :- Q)).
Note carefully the following syntax restrictions, which serve to remove potential ambiguity associated with prefix operators.
point (X,Y,Z)
is invalid syntax.
:-(p;q),r.
(where :- is the prefix operator) is invalid syntax. The system
would try to interpret it as the compound term:
, / \ :- r | ; / \ p q
That is, it would take :- to be a functor of arity 1. However,
since the arguments of a functor are required to be expressions of
precedence below 1000, this interpretation would fail as soon as the
; (precedence 1100) was encountered.
In contrast, the term:
:- (p;q),r.
is valid syntax and represents the following compound term:
:-
|
,
/ \
; r
/ \
p q
Comments have no effect on the execution of a program, but they are very useful for making programs more readily comprehensible. Two forms of comment are allowed in Prolog:
By making use of the module systems facilities, programs can be divided into different modules. Each module has its own independent predicate name space. This is an important feature for the development of larger programs. The module system of SICStus Prolog is procedure based. This means that only the predicates are local to a module, whereas terms are global. The module system is flat, not hierarchical, so all modules are visible to one another. It is non-strict, i.e. the normal visibility rules can be overridden by special syntax. No overhead is incurred on compiled calls to predicates in other modules. It is modeled after and compatible with the Quintus Prolog module system. Finally, using the module system is optional, and SICStus Prolog may be used without the user being aware of the module system at all.
Modules in SICStus Prolog can also be used for object-oriented programming. See Obj Intro, for details.
Each predicate in the Prolog system, whether built-in or user defined, belongs to a module. A predicate is generally only visible in the module where it is defined. However a predicate may be imported by another module. It is thereby made visible in that module too. Built-in predicates are visible in every module. Predicates declared as public in a module declaration (see below) are exported. Normally only public predicates may be imported by another module.
For any given goal, the source module is the module in which the corresponding predicate must be visible. Similarly, for any given clause, the source module of its head is the module into which the clause is loaded.
For goals occurring in a source file with a module declaration, the
source module is the declared module. For goals occurring in a source
file without a module declaration, the source module is the module that
the file is being loaded into. For goals typed at the top level, the
source module is the type-in module. The type-in module is by
default the user module but may be changed by the built-in
predicate module/1.
The other predefined module is the prolog module where all the
built-in predicates reside. The exported built-in predicates are
automatically imported into each new module as it is created.
Notwithstanding the visibility rules, any predicate can be called from any other module by prefixing the goal with the module name and the colon operator, thus overriding the source module of the goal:
| ?- foo:bar(X).
This feature is intended mainly for debugging purposes, since it defies the purposes of the module system. If the prefixed goal is a meta-predicate, however, the prefixed module name may affect the module name expansion of the goal (see Meta Exp). If multiple module prefixes are used, the innermost one has priority.
It is also possible to override the source module of clauses and directives by module prefixing. For example,
:- dynamic mod:p/1. p(X) :- mod:(q(X), r(X)). mod:(q(X) :- r(X)). mod:s(X) :- t(X).
declares mod:p/1 as dynamic, whatever the source module is;
defines p/1 in the source module as calling mod:q/1 and
mod:r/1; defines mod:q/1 as calling mod:r/1; and
defines mod:s/1 as calling t/1 in the source module.
The latter technique is particularly useful when the prefix is
user and the predicate is a hook predicate such as
user:portray/1 which must be defined in the user module,
but the rest of the file consists of predicates belonging to some other
module.
A module is normally defined by putting a module declaration in a source file. A module declaration has the form:
:- module(ModuleName, ExportList[, Options]).
and should precede all other clauses and directives of that file.
When the file is loaded, all predicates in the file go into ModuleName and the predicates of the ExportList are exported. When a module declaration is processed, all existing predicates in the module are erased before the new ones are loaded. A file which contains a module declaration is henceforth called a module-file.
Options is an optional argument, and should be a list.
The only available option is hidden(Boolean), where
Boolean is false (the default) or true.
In the latter case, tracing of the predicates of the module
is disabled (although spypoints can be set), and no source information
is generated at compile time.
A module can also be defined dynamically by asserting or loading predicates to it:
| ?- assert(m:p(x)).
creates the module m, if it does not already exists, and asserts
p(x) to it.
| ?- compile(m:f).
creates the module m and loads f into m.
Dynamically created modules have no public predicates.
When a module-file is loaded by load_files/[1,2] or one of its
shorthands (see Read In), by default all the public predicates of the
module-file are imported by the receiving module. An explicit list of
predicates to import may also be specified.
Clashes with already existing predicates, local or imported from other
modules, are handled in two different ways: If the receiving module is
the user module, the user is asked for redefinition of the
predicate. For other receiving modules, a warning is issued and the
importation is canceled. In the first case redefinition silently takes
place if the flag redefine_warnings has the value off (see
prolog_flag/3). The binding of an imported predicate remains,
even if the origin is reloaded or deleted. However, abolish/[1,2]
break up the importation binding. When a module-file is reloaded, a
check is made that the predicates imported by other modules are still in
the public list. If that is not the case, a warning is issued. Note
that an imported predicate may be re-exported.
Some predicates take goals as arguments (i.e. meta-predicates).
These arguments must include a module specification stating which
module the goal refers. Some other predicates also need module
information i.e. compile/1. The property of needing module
information is declared with a meta-predicate declaration
(see Meta Decl). Goals for these predicates are module name
expanded to ensure the module information.
Goals appearing in queries and meta-calls are expanded prior to execution
while goals in the bodies of clauses and directives are expanded at compile time.
The expansion is made by preceding the relevant argument with
Module:. If the goal is prefixed by
Module:, Module is used for the expansion,
otherwise the source/type-in module is used. An argument is not
expanded if:
Some examples:
| ?- [user].
| :- meta_predicate p(:), q(:).
| r(X) :- p(X).
| q(X) :- p(X).
| ^D
{user consulted, 40 msec 1088 bytes}
yes
| ?- listing.
r(A) :-
p(user:A).
q(A) :-
p(A).
yes
Here, p/1 and q/1 are declared as meta-predicates while
r/1 is not. Thus the clause r(X) :- p(X) will be
transformed to r(X) :- p(M:X), by item 2 above, where
M is the type-in module, whereas q(X) :- p(X) will not.
| ?- m:assert(f(1)).
Here, assert/1 is called in the module m. However, this
does not ensure that f(1) is asserted into m. The fact
that assert/1 is a meta-predicate makes the system module name
expand the goal, transforming it to m:assert(m:f(1)) before
execution. This way, assert/1 is supplied the correct module
information.
The fact that a predicate needs module name expansion is declared in a meta-predicate declaration:
:- meta_predicate MetaPredSpec, ..., MetaPredSpec.
where each MetaPredSpec is a mode spec. E.g.
:- meta_predicate p(:, +).
which means that the first argument of p/2 shall be module name
expanded. The arguments in the mode spec are interpreted as:
:
An integer
Anything else e.g. +, - or ?
A number of built-in predicates have predefined meta-predicate
declarations, as indicated by the mode specs in this manual,
e.g. call(:Term).
Programs can be loaded in three different ways: consulted or compiled from source file, or loaded from object files. The latter is the fastest way of loading programs, but of course requires that the programs have been compiled to object files first. Object files may be handy when developing large applications consisting of many source files, but are not strictly necessary since it is possible to save and restore entire execution states (see Misc Pred).
Consulted, or interpreted, predicates are equivalent to, but slower than, compiled ones. Although they use different representations, the two types of predicates can call each other freely.
The SICStus Prolog compiler produces compact and efficient code, running about 8 times faster than consulted code, and requiring much less runtime storage. Compiled Prolog programs are comparable in efficiency with LISP programs for the same task. However, against this, compilation itself takes about twice as long as consulting, and tracing of goals that compile in-line are not available in compiled code.
The compiler operates in four different modes, controlled by the
"Compilation mode" flag (see prolog_flag/3). The possible
states of the flag are:
compactcode
fastcode
profiledcode
debugcode
The compilation mode can be changed by issuing the query:
| ?- prolog_flag(compiling, OldValue, NewValue).
A Prolog program consists of a sequence of sentences (see Sentence). Directives encountered among the sentences are executed immediately as they are encountered, unless they can be interpreted as declarations (see Declarations), which affect the treatment of forthcoming clauses, or as initializations, which build up a set of goals to be executed after the program has been loaded. Clauses are loaded as they are encountered.
A Prolog program may also contain a list of sentences (including the
empty list). This is treated as equivalent to those sentences occurring
in place of the list. This feature makes it possible to have
user:term_expansion/[2,4] (see Definite) "return" a list of
sentences, instead of a single sentence.
This section contains a summary of the relevant predicates. For a more precise description, see Read In.
To consult a program, issue the query:
| ?- consult(Files).
where Files is either a filename or a list of filenames, instructs the processor to read in the program which is in the files. For example:
| ?- consult([dbase,'extras.pl',user]).
When a directive is read it is immediately executed. Any predicate
defined in the files erases any clauses for that predicate already
present. If the old clauses were loaded from a different file than the
present one, the user will be queried first whether (s)he really wants
the new definition. However, if a multifile declaration
(see Declarations) is read and the corresponding predicate exists
and has previously been declared as multifile, new clauses will
be added to the predicate, rather than replacing the old clauses. If
clauses for some predicate appear in more than one file, the later set
will effectively overwrite the earlier set. The division of the program
into separate files does not imply any module structure--any predicate
can call any other (see Module Intro).
consult/1, used in conjunction with save_program/[1,2] and
restore/1, makes it possible to amend a program without having to
restart from scratch and consult all the files which make up the
program. The consulted file is normally a temporary "patch" file
containing only the amended predicate(s). Note that it is possible to
call consult(user) and then enter a patch directly on the
terminal (ending with ^D). This is only recommended for small,
tentative patches.
| ?- [File|Files].
This is a shorthand way of consulting a list of files. (The case where there is just one filename in the list was described earlier (see Reading In).
To compile a program in-core, use the built-in predicate:
| ?- compile(Files).
where Files is specified just as for consult/1.
The effect of compile/1 is very much like that of
consult/1, except all new procedures will be stored in compiled
rather than consulted form. However, predicates declared as dynamic
(see below) will be stored in consulted form, even though
compile/1 is used.
Programs can be compiled into an intermediate representation known as
.ql (for Quick Load file). As of SICStus Prolog 3.8, this
feature is obsolescent with the introduction of partial saved states
(.po files, see Saving), which can be handled much more efficiently.
To compile a program into a .ql file, use the built-in predicate:
| ?- fcompile(Files).
where Files is specified just as for consult/1. For each
filename in the list, the compiler will append the suffix .pl to it
and try to locate a source file with that name and compile it to a .ql
file. The filename is formed by appending the suffix .ql to
the specified name. The internal state of SICStus Prolog is not changed as
result of the compilation. See Considerations.
To load a program from a set of source or object files, use the built-in
predicates load_files/[1,2] (the latter is controlled by an options list):
| ?- load_files(Files).
where Files is either a single filename or a list of filenames,
optionally with .pl or .po or .ql extensions.
This
predicate takes the following action for each File in the list of
filenames:
user, compile(user) or [user] is
performed;
.po file is found, the file is loaded;
.ql file is found, the file is loaded;
load_files/1 was called
from a directive of a file being consulted.
Finally, to ensure that some files have been loaded, use the built-in predicate:
| ?- ensure_loaded(Files).
Same as load_files(Files), except if the file to be loaded
has already been loaded and has not been modified since that time,
in which case the file is not loaded again. If a source file has been
modified, ensure_loaded/1 does not cause any object file to
become recompiled.
When a program is to be loaded, it is sometimes necessary to tell the
system to treat some of the predicates specially. This information is
supplied by including declarations about such predicates in the
source file, preceding any clauses for the predicates which they
concern. A declaration is written just as a directive, beginning with
:-. A declaration is effective from its occurrence through the
end of file.
Although declarations that affect more than one predicate may be collapsed into a single declaration, the recommended style is to write the declarations for a predicate immediately before its first clause.
Operator declarations are not declarations proper, but rather directives that modify the global table of syntax operators. Operator declarations are executed as they are encountered while loading programs.
The rest of this section details the available forms of predicate declarations.
A declaration
:- multifile PredSpec, ..., PredSpec. [ISO]
where each PredSpec is a predicate spec, causes the specified predicates to become multifile. This means that if more clauses are subsequently loaded from other files for the same predicate, then the new clauses will not replace the old ones, but will be added at the end instead. As of release 3, multifile declarations are required in all files from where clauses to a multifile predicate are loaded.
An example when multifile declarations are particularly useful is in
defining hook predicates. A hook predicate is a user-defined
predicate that somehow alters or customizes the behavior of SICStus
Prolog. A number of such hook predicates are described in this manual.
Often, an application needs to combine the functionality of several
software modules, some of which define clauses for such hook predicates.
By simply declaring every hook predicates as multifile, the
functionality of the clauses for the hook predicates is automatically
combined. If this is not done, the last software module to define
clauses for a particular hook predicate will effectively supersede any
clauses defined for the same hook predicate in a previous module.
By default, hook predicates must be defined in the user module,
and only their first solution is relevant.
If a file containing clauses for a multifile predicate is reloaded, the old clauses from the same file are removed. The new clauses are added at the end.
If a multifile predicate is loaded from a file with no multifile declaration for it, the predicate is redefined as if it were an ordinary predicate (i.e. the user is asked for confirmation).
Clauses of multifile predicates are (currently) always loaded in interpreted form, even if they were processed by the compiler. If performance is an issue, define the multifile predicates as unit clauses or as clauses with a single goal that just calls an auxiliary compiled predicate to perform any time-critical computation.
If a multifile predicate is declared dynamic in one file, it must also be done so in the other files from where it is loaded. Hook predicates should always be declared as multifile and dynamic, as this is the convention followed in the library modules.
Multifile declarations must precede any other declarations for the same predicate(s)!
A declaration
:- dynamic PredSpec, ..., PredSpec. [ISO]
where each PredSpec is a predicate spec, causes the specified predicates to become dynamic, which means that other predicates may inspect and modify them, adding or deleting individual clauses. Dynamic predicates are always stored in consulted form even if a compilation is in progress. This declaration is meaningful even if the file contains no clauses for a specified predicate--the effect is then to define a dynamic predicate with no clauses.
A declaration
:- volatile PredSpec, ..., PredSpec.
where each PredSpec is a predicate spec, causes the specified predicates to become volatile.
A predicate should be declared as volatile if it refers to data that cannot or should not be saved in a saved state. In most cases a volatile predicate will be dynamic, and it will be used to keep facts about streams or memory references. When a program state is saved at run-time, the clauses of all volatile predicates will be left unsaved. The predicate definitions will be saved though, which means that the predicates will keep all properties, that is volatile and maybe dynamic or multifile, when the saved state is restored.
A declaration
:- discontiguous PredSpec, ..., PredSpec. [ISO]
where each PredSpec is a predicate spec, disables warnings about
clauses not being together for the specified predicates. By default,
such warnings are issued in development systems unless disabled
selectively for specific predicates, or globally by setting the
discontiguous_warnings flag to off.
The declaration
:- block BlockSpec, ..., BlockSpec.
where each BlockSpec is a mode spec, specifies conditions for
blocking goals of the predicate referred to by the mode spec (f/3
say). When a goal for f/3 is to be executed, the mode specs are
interpreted as conditions for blocking the goal, and if at least one
condition evaluates to true, the goal is blocked.
A block condition evaluates to true iff all arguments specified as
- are uninstantiated, in which case the goal is blocked until
at least one of those variables is instantiated. If several conditions
evaluate to true, the implementation picks one of them and
blocks the goal accordingly.
The recommended style is to write the block declarations in front of the source code of the predicate they refer to. Indeed, they are part of the source code of the predicate, and must precede the first clause. For example, with the definition:
:- block merge(-,?,-), merge(?,-,-). merge([], Y, Y). merge(X, [], X). merge([H|X], [E|Y], [H|Z]) :- H @< E, merge(X, [E|Y], Z). merge([H|X], [E|Y], [E|Z]) :- H @>= E, merge([H|X], Y, Z).
calls to merge/3 having uninstantiated arguments in the first
and third position or in the second and third
position will suspend.
The behavior of blocking goals for a given predicate on uninstantiated arguments cannot be switched off, except by abolishing or redefining the predicate.
Block declarations generalize the "wait declarations" of earlier
versions of SICStus Prolog. A declaration :- wait f/3
in the old syntax corresponds to :- block f(-,?,?) in the
current syntax. See Use Of Term Exp, for a simple way to extend
the system to accept the old syntax.
A declaration
:- meta_predicate MetaPredSpec, ..., MetaPredSpec.
where each MetaPredSpec is a mode spec, informs the compiler that certain arguments of the declared predicates are used for passing goals. To ensure the correct semantics in the context of multiple modules, clauses or directives containing goals for the declared predicates may need to have those arguments module name expanded. See Meta Exp, for details.
A declaration
:- module(ModuleName, ExportList[, Options]).
where ExportList is a list of predicate specs, declares that the forthcoming predicates should go into the module named ModuleName and that the predicates listed should be exported. See Def Modules, for details.
A declaration
:- public PredSpec, ..., PredSpec.
where each PredSpec is a predicate spec, has no effect whatsoever, but is accepted for compatibility reasons. In some Prologs, this declaration is necessary for making compiled predicates visible. In SICStus Prolog, predicate visibility is handled by the module system. This declaration is obsolescent. See Module Intro.
A declaration
:- mode ModeSpec, ..., ModeSpec.
where each ModeSpec is a mode spec, has no effect whatsoever, but is accepted for compatibility reasons. In some Prologs, this declaration helps reduce the size of the compiled code for a predicate, and may speed up its execution. Unfortunately, writing mode declarations can be error-prone, and since errors in mode declaration do not show up while running the predicates interpretively, new bugs may show up when predicates are compiled. However, mode declarations may be used as a commenting device, as they express the programmer's intention of data flow in predicates.
A declaration
:- include(Files). [ISO]
where Files is a file name or a list of file names, instructs the processor to literally embed the Prolog clauses and directives in Files into the file being loaded. This means that the effect of the include directive is such as if the include directive itself was replaced by the text in the Files. Including some files is thus different from loading them in several respects:
source_file/2;
see Read In.
SICStus Prolog uses the included file name (as opposed to the embedding
file name) only in source level debugging and error reporting. Note that
source level debugging information is not kept for included files which
are compiled to .ql format; in such cases the debugger will show
the include directive itself as the source information.
A directive
:- initialization :Goal. [ISO]
in a file includes Goal to the set of goals which shall be executed after that file has been loaded.
initialization/1 is actually callable at any point during loading of a
file. Initializations are saved by save_modules/2 and
save_program/[1,2], and so are executed after loading or
restoring such files too.
Goal is associated with the file loaded, and with a module, if applicable. When a file, or module, is going to be reloaded, all goals earlier installed by that file, or in that module, are removed first.
When compiling a source file to a .ql file, remember that clauses
are loaded and directives are executed at run time, not at
compile time. Only predicate declarations are processed at compile
time. For instance, it does not work to include operator declarations
or clauses of user:term_expansion/[2,4] or
user:goal_expansion/3 or any auxiliary predicates that they might
need, and rely on the new transformations to be effective for subsequent
clauses of the same file or subsequent files of the same compilation.
Any directives or clauses that affect the compile-time environment
must be loaded prior to compiling source files to .ql files. This
also holds for meta-predicates called by the source files but defined
elsewhere, for module name expansion to work correctly. If this
separation into files is unnatural or inconvenient, one can easily
ensure that the compile-time environment is up to date by doing:
| ?- ensure_loaded(Files), fcompile(Files).
Since module name expansion takes place at compile time, the module
into which the file is to be loaded must be known when compiling to
.ql files. This is no problem for module-files because the module
name is picked from the module declaration. When non-module-files are
compiled, the file name may be prefixed with the module name that is
to be used for expansion:
| ?- fcompile(Module:Files).
If an .ql file is loaded into a different module from which it was
compiled for, a warning is issued.
This chapter describes the debugging facilities that are available in development systems. The purpose of these facilities is to provide information concerning the control flow of your program.
The main features of the debugging package are as follows:
The Procedure Box model of execution is also called the Byrd Box model after its inventor, Lawrence Byrd.
Much of the information in this chapter is also in Chapter eight of [Clocksin & Mellish 81] which is recommended as an introduction.
Unless otherwise stated, the debugger prints goals using
write_term/3 with the value of the Prolog flag
debugger_print_options (see State Info).
The debugger is not available in runtime systems and the predicates defined in this chapter are undefined; see Runtime Systems.
During debugging, the debugger prints out a sequence of goals in various states of instantiation in order to show the state the program has reached in its execution. However, in order to understand what is occurring it is necessary to understand when and why the debugger prints out goals. As in other programming languages, key points of interest are predicate entry and return, but in Prolog there is the additional complexity of backtracking. One of the major confusions that novice Prolog programmers have to face is the question of what actually happens when a goal fails and the system suddenly starts backtracking. The Procedure Box model of Prolog execution views program control flow in terms of movement about the program text. This model provides a basis for the debugging mechanism in development systems, and enables the user to view the behavior of the program in a consistent way.
Let us look at an example Prolog predicate :
*--------------------------------------*
Call | | Exit
---------> + descendant(X,Y) :- offspring(X,Y). + --------->
| |
| descendant(X,Z) :- |
<--------- + offspring(X,Y), descendant(Y,Z). + <---------
Fail | | Redo
*-------------------+------------------*
|
<------------------------------+
Exception
The first clause states that Y is a descendant of X if Y is an offspring of X, and the second clause states that Z is a descendant of X if Y is an offspring of X and if Z is a descendant of Y. In the diagram a box has been drawn around the whole predicate and labeled arrows indicate the control flow in and out of this box. There are five such arrows which we shall look at in turn.
descendant(X,Y) is required to be satisfied, control
passes through the Call port of the descendant box with the
intention of matching a component clause and then satisfying the
subgoals in the body of that clause. Note that this is independent of
whether such a match is possible; i.e. first the box is called, and then
the attempt to match takes place. Textually we can imagine moving to
the code for descendant when meeting a call to descendant in some other
part of the code.
raise_exception/1 or by an error in a
built-in predicate. See Exception. Control now passes out of the
Exception port of the descendant box and the system continues to
pass the exception to outer levels. Textually we move back to the code
which called this predicate and keep moving backwards up the code
looking for a call to on_exception/3.
In terms of this model, the information we get about the procedure box is only the control flow through these five ports. This means that at this level we are not concerned with which clause matches, and how any subgoals are satisfied, but rather we only wish to know the initial goal and the final outcome. However, it can be seen that whenever we are trying to satisfy subgoals, what we are actually doing is passing through the ports of their respective boxes. If we were to follow this, then we would have complete information about the control flow inside the procedure box.
Note that the box we have drawn round the predicate should really be seen as an invocation box. That is, there will be a different box for each different invocation of the predicate. Obviously, with something like a recursive predicate, there will be many different Calls and Exits in the control flow, but these will be for different invocations. Since this might get confusing each invocation box is given a unique integer identifier.
In addition to the five basic ports discussed above, there are two more ports for invocations involving a blocked goal:
Development systems provide a range of built-in predicates for control of the debugging facilities. The most basic predicates are as follows:
debug
Switches the debugger on, and ensures that the next time control reaches
a spypoint, it will be activated. In basic usage this means that a
message will be produced and you will be prompted for a
command. In order for the full range of control flow information to be
available it is necessary to have the debugger on from the start. When it is
off the system does not remember invocations that are being executed.
(This is because it is expensive and not required for normal running of
programs.) You can switch Debug Mode on in the middle of
execution, either from within your program or after a ^C (see
trace/0 below), but information prior to this will just be
unavailable.
zip
Same as debug/0, except no debugging information is being
collected, and so is almost as fast as running with the debugger
switched off.
trace
Switches the debugger on, and ensures that the next time control enters an invocation box, a message will be produced and you will be prompted for a command. The effect of trace can also be achieved by typing t after a ^C interruption of a program.
At this point you have a number of options. See Debug Commands. In
particular, you can just type <RET> to creep (or single-step)
into your program. If you continue to creep through your program you
will see every entry and exit to/from every invocation box, including
compiled code, except for code belonging to hidden modules
(see Def Modules). You will
notice that the debugger stops at all ports. However, if this is not
what you want, the following built-in predicate gives full control over
the ports at which you are prompted:
leash(+Mode)
Leashing Mode is set to Mode. Leashing Mode determines the ports
of invocation boxes at which you are to be prompted when you Creep
through your program. At unleashed ports a tracing message is still
output, but program execution does not stop to allow user interaction.
Note that leash/1 does not apply to spypoints, the leashing mode
of these can be set using the advanced debugger features; see Breakpoints.
Mode can be a subset of the following, specified as a
list:
call
exit
redo
fail
exception
The initial value of Leashing Mode is
[call,exit,redo,fail,exception] (full leashing).
nodebug
notrace
nozip
Switches the debugger off. If there are any spypoints set then they
will be kept but will never be activated.
debugging
Prints information about the current debugging state. This will show:
For programs of any size, it is clearly impractical to creep through the entire program. Spypoints make it possible to stop the program whenever it gets to a particular predicate which is of interest. Once there, one can set further spypoints in order to catch the control flow a bit further on, or one can start creeping.
In this section we discuss the simplest form of spypoints, the plain spypoints. The more advanced forms, the conditional and generic spypoints will be discussed later; see Breakpoints.
Setting a plain spypoint on a predicate indicates that you wish to see all control flow through the various ports of its invocation boxes, except during skips. When control passes through any port of an invocation box with a spypoint set on it, a message is output and the user is asked to interact. Note that the current mode of leashing does not affect plain spypoints: user interaction is requested on every port.
Spypoints are set and removed by the following built-in predicates. The first two are also standard operators:
spy :Spec
Sets plain spypoints on all the predicates given by the generalized predicate spec Spec.
Examples:
| ?- spy [user:p, m:q/[2,3]]. | ?- spy m:[p/1, q/1].
If you set some
spypoints when the debugger is switched off then it will be
automatically switched on, entering zip mode.
nospy :Spec
Similar to spy Spec except that all the predicates given
by Spec will have all previously set spypoints removed from them
(including conditional spypoints; see Breakpoints).
nospyall
Removes all the spypoints, including the conditional ones, that have been set.
The commands available when you arrive at a spypoint are described later. See Debug Commands.
We shall now look at the exact format of the message output by the
system at a port. All trace messages are output to the standard error
stream, using the print_message/2 predicate; see Exception.
This allows you to trace programs while they are performing file I/O.
The basic format is as follows:
N S 23 6 Call: T foo(hello,there,_123) ?
N is only used at Exit ports and indicates whether the invocation
could backtrack and find alternative solutions. Unintended
non-determinism is a source of inefficiency, and this annotation can
help spot such efficiency bugs. It is printed as ?, indicating
that foo/3 could backtrack and find alternative solutions, or
otherwise.
S is a spypoint indicator. If there is a plain spypoint on
foo/3, it is printed as +. In case of conditional
and generic spypoints it takes the form * and #,
respectively. Finally, it is printed as , if there is no
spypoint on the predicate being traced.
The first number is the unique invocation identifier. It is nondecreasing regardless of whether or not you are actually seeing the invocations (provided that the debugger is switched on). This number can be used to cross correlate the trace messages for the various ports, since it is unique for every invocation. It will also give an indication of the number of procedure calls made since the start of the execution. The invocation counter starts again for every fresh execution of a command, and it is also reset when retries (see later) are performed.
The number following this is the current depth; i.e. the number of direct ancestors this goal has.
The next word specifies the particular port (Call, Exit, Redo, Fail, or Exception).
T is a subterm trace. This is used in conjunction with the
^ command (set subterm), described below. If a subterm has been
selected, T is printed as the sequence of commands used to select
the subterm. Normally, however, T is printed as ,
indicating that no subterm has been selected.
The goal is then printed so that you can inspect its current instantiation state.
The final ? is the prompt indicating that you should type in one of the
commands allowed (see Debug Commands). If this particular port is
unleashed then you will obviously not get this prompt since you have
specified that you do not wish to interact at this point.
At Exception ports, the trace message is preceded by a message about the pending exception, formatted as if it would arrive uncaught at the top level.
Note that calls that are compiled in-line and built-in predicates that are called directly from the top level are not traced.
Block and unblock ports are exceptions to the above debugger message format. A message
S - - Block: p(_133)
indicates that the debugger has encountered a blocked goal, i.e. one which is temporarily suspended due to insufficiently instantiated arguments (see Procedural). By default, no interaction takes place at this point, and the debugger simply proceeds to the next goal in the execution stream. The suspended goal will be eligible for execution once the blocking condition ceases to exist, at which time a message
S - - Unblock: p(_133)
is printed. Although Block and Unblock ports are unleashed by default in trace mode, you can make the debugger interact at these ports by using conditional spypoints.
This section gives an overview of the advanced debugger features. These center around the notion of breakpoint, a generalization of the plain spypoint introduced earlier. The details of built-in predicates dealing with breakpoints are given in Breakpoint Predicates and in Breakpoint Conditions.
A breakpoint is specified by providing the conditions under which the breakpoint applies and its effect on the execution. Syntactically, the breakpoint is given as a pair of two lists of conditions. The first list, the tests, contains the tests for the applicability of the breakpoint, the second, the actions describes the effects of the breakpoint on the execution. Example:
| ?- add_breakpoint([goal(foo(1,_)),port(call)]-
[show(display),command(proceed)],
BID).
This invocation of the add_breakpoint/2 built-in predicate
creates a breakpoint which will apply to goals which unify with foo(1,_)
and only to their call ports -- this is the test part. The
second list, the action part specifies that the debugger should show the
debugged goal using display/1 and should proceed without
stopping, whenever the breakpoint is applicable. The
add_breakpoint/2 built-in returns a BID, a numeric
breakpoint identifier.
There are two types of breakpoints, advice and
debugger. These are distinguished by the presence of conditions
advice and debugger, the latter being the default.
Debugger breakpoints are also called spypoints. Spypoints apply
only when the debugger is switched on. Advice breakpoints, or
advice-points, apply irrespectively of the debugger state. Advice is
checked even inside hook predicates.
The most important test condition is goal(M:Goal).
This makes the breakpoint applicable only to invocations whose goal and
module matches Goal and M. A breakpoint with a goal
condition where both the module and the goal are non-variable is called
a specific breakpoint. If any of these is a variable (or there is
no goal condition), the breakpoint is generic. The presence
of a generic breakpoint slows down the execution, as its conditions have
to be examined at every predicate invocation. Specific breakpoints, on
the other hand, are handled efficiently, as only the execution of the
specified predicate is affected.
The following example shows the creation of a generic breakpoint.
| ?- add_breakpoint([advice,port(call)]-
[line(L),true(assert(line_reached(L)))],
BID).
This advice-point will apply to all predicates (or more precisely to all
predicates in the module in question -- as the conditions argument is
subject to module name expansion; see Goal Tests). Whenever a
call port is reached, the action part of the breakpoint gets hold
of the source line number (if available) and asserts a fact with this
number. Here the condition true(PrologCondition) executes
PrologCondition as a Prolog goal and succeeds accordingly. An
advice breakpoint of this kind can be used for profiling or
branch-coverage analysis.
The pred condition is a variant of the goal condition:
pred(F/N) is equivalent to goal(Goal), where
Goal is the most general term with the functor F/N. A
specific spypoint whose conditions consist of a single pred
condition (or an equivalent goal condition) is the same as the
plain spypoint introduced earlier; see Plain Spypoint. Specific
spypoints which are not plain, are called conditional spypoints.
For example, the following three goals have the same effect, creating a
plain spypoint for predicate foo/2:
| ?- add_breakpoint(pred(foo/2), _). | ?- add_breakpoint(goal(foo(_,_)), _). | ?- spy foo/2.
The effect of the breakpoint on the execution is specified by the actions list. In the case of spypoints, the action part may specify values for the following three debugger action variables:
show, i.e. whether the debugger should display anything, and if
so, in what format. Examples: print, display,
silent, etc.
command, i.e. what should the debugger do. Examples:
ask (the normal query to the user), proceed (continue
the execution without stopping, as for unleashed ports), etc.
mode, i.e. in what mode should the debugger continue the
execution: trace (creeping), debug (leaping), zip
(zipping), etc.
If no actions are specified at a spypoint, the default
[command(ask),show(print)] is assumed.
In the case of advice-points only the command action can be
specified, its meaning will be explained later. Here the default is not
to apply any actions.
The action part can contain the other conditions allowed in the test
part, too. The advice-point example above uses the line(L)
condition in the action part, as the applicability of the breakpoint
does not depend on the line number. This can be contrasted with the
the following example, where the success of the conditions does depend
on the line number, and so the line condition appears in the test
part:
add_breakpoint([line(Line),true((Line>=20,Line=<40))], _).
This example introduces a generic spypoint which applies to invocations appearing between lines 20-40.
We have seen the true condition being used in both the test and
the action part. If it is used for testing (i.e. it can fail), it should
be placed in the test part. On the other hand, it should appear in the
action part if it has a side effect, e.g. asserts some clauses or writes
out a message. This is because the test part of spypoint conditions may
be evaluated multiple times for a single port.
Note that this distinction between the test part and the action part is not strictly enforced. If a condition in the action part fails, the breakpoint will not be applied, but, of course, the side effects preceding the failed condition will have already taken place.
Having created some breakpoints, you can use the built-in predicate
current_breakpoint/4 to enumerate all breakpoints together with
their properties. By reference to their identifiers breakpoints can be
removed, temporarily disabled, or enabled.
Naturally, there can be multiple breakpoints at any given time of execution. They are handled in a stack-like discipline, i.e. the most recent breakpoints (the ones with higher breakpoint identifiers) are tried first. At each port the debugger first looks for enabled advice-points, the first (most recent) one found applicable is then activated, i.e. its action part is executed. Subsequently the debugger scans the breakpoint stack again, looking for an enabled spypoint applicable for the current invocation, and again the first such spypoint is activated. For the details of how the breakpoints are processed, see Breakpoint Processing.
As explained earlier, when the system is in Debug Mode, the debugger
collects control flow information about the goals being executed. This
collection of information, the backtrace, includes the invocations
that were called but not exited yet, as well as those that exited
non-deterministically. For each invocation, the main data items present
in the backtrace are the following: the goal, the module, the invocation
number, the depth and the source information, if any. There is also a
field in the backtrace reserved for the user, initially an empty
variable. The goal_private(_) condition unifies its argument with
this field. We will show an example on how to use the
goal_private field to transfer instantiation information from the
call port to the exit port; see Breakpoint Example.
When an invocation is at the call port, the user can decide not to build
a procedure box for the invocation and not to put it on the backtrace.
This can be done by supplying the action command(flit). In this
case the execution continues
without building the procedure box, and with much smaller space overhead
then otherwise.1 This also means, of course, that
the execution will not stop at the remaining ports of this invocation.
The command(flit) is the only meaningful execution control action
that can be used for advice-points.
The backtrace can be accessed outside the debugger, too, via the
built-in predicates execution_state/[1,2]. The predicate
execution_state(Tests) accesses the current execution
state. Arbitrary tests can be used in this predicate, if it is called
from within a true condition in an add_breakpoint/2. For
example the advice breakpoint shown earlier can be simplified to:
[advice,call]-true(assert_line)
The current line number then can be accessed from within
assert_line:
assert_line :-
execution_state(line(L)), assert(line_reached(L)).
Note that we applied some syntactic simplifications in the above
texts. First, we simplified port(call) to call: for
certain tests, which have a pre-defined range of possible arguments, the
name of the test is automatically inserted if a concrete argument is
given. Second, we omitted the square brackets around the action part:
this is applicable to both tests and actions, if they contain a single
condition only.
Invoking execution_state/1 can also be useful inside the
user:debugger_command_hook/2 predicate, which serves for defining new
interactive debugger commands.
If execution_state/1 is called outside the debugger, only some
tests are available, e.g. those querying to data stored in the
backtrace.
The execution_state/2 predicate lets us examine past elements of
the backtrace. For example:
execution_state(inv(N), goal(Goal))
retrieves the Goal stored in the backtrace under invocation number N.
The debugger is also able to keep track of multiple backtraces
associated with different break levels. We can access data stored in
previous break levels, using execution_state/2, as e.g. in:
execution_state([break_level(0),inv(N)], goal(Goal))
This example accesses the Nth invocation of the outermost break level. Such use can be helpful if one enters a break during tracing, and wants to access the outer backtrace from within the break.
This section describes the particular commands that are available when the system prompts you after printing out a debugging message. All the commands are one or two letter mnemonics, some of which can be optionally followed by a decimal integer. They are read from the standard input stream with any blanks being completely ignored up to the end of the line (<RET>). Some commands only actually require the terminator; e.g. the creep command, as we have already seen, only requires <RET>.
The only command which you really have to remember is h (followed
by <RET>). This provides help in the form of the following list of
available commands.
<cr> creep c creep
l leap z zip
s skip s <i> skip i
o out o <n> out n
q q-skip q <i> q-skip i
r retry r <i> retry i
f fail f <i> fail i
j<p> jump to port j<p><i>jump to port i
d display w write
p print p <i> print partial
g ancestors g <n> ancestors n
t backtrace t <n> backtrace n
& blocked goals & <n> nth blocked goal
n nodebug = debugging
+ spy this * spy conditionally
- nospy this \ <i> remove brkpoint
D <i> disable brkpoint E <i> enable brkpoint
a abort b break
@ command u unify
e raise exception . find this
< reset printdepth < <n> set printdepth
^ reset subterm ^ <n> set subterm
? help h help
If you supply an integer argument, then this should denote an
invocation number of an ancestral goal. The system tries to get you
to the Exit or Fail port of the invocation box you have specified.
An integer argument can be supplied as for skip.
If you supply an integer argument, then this should denote an
invocation number of an ancestral goal.
The system tries to get you to the Call port of the box you have
specified. It does this by continuously failing until it reaches the
right place. Unfortunately this process cannot be guaranteed: it may be
the case that the invocation you are looking for has been cut out of the
search space by cuts (!) in your program. In this case the
system fails to the latest surviving Call port before the correct one.
If you supply an integer after the command, then this is taken as
specifying an invocation number and the system tries to get you to the
Fail port of the invocation box you have specified. It does this by
continuously failing until it reaches the right place. Unfortunately
this process cannot be guaranteed: it may be the case that the
invocation you are looking for has been cut out of the search space by
cuts (!) in your program. In this case the system fails to the
latest surviving Fail port before the correct one.
c, e, r,
f, standing for Call, Exit, Redo and Fail ports. Takes an
optional integer argument, an invocation number.
Jumping to a call port is the same as retrying it, i.e. jc
is the same as the r debugger command; and similarly jf is
the same as f.
The je jump to Exit port command transfers control back to
the Exit port of the box. It can be used at a Redo or an Exit port
(although at the latter it has no effect). This allows you to restart a
computation following an Exit port, which you first leapt over, but
because of its unexpected failure you arrived at the Redo port. When you
supply an integer argument, then this should denote an exact
invocation number of an exited invocation present in the backtrace, and
then the system will get you to the specified Exit port. The debugger
requires here an exact invocation number so that it does not jump too
far back in the execution (if an Exit port is not present in the
backtrace, it may be be a better choice to jump to the preceding Call port,
rather than to continue looking for another Exit port).
The jr jump to Redo port command transfers control back to
the Redo port of the box. It can be used at an Exit or a Redo port
(although at the latter it has no effect). This allows you to force the
goal in question to try to deliver another solution. When you supply an
integer argument, then this should denote an exact invocation
number of an exited invocation present in the backtrace, and then the
system will get you to the specified Redo port.
display/1.
See Write (below).
write/1.
Ancestors to the current goal are annotated with the Call: port,
as they have not yet exited, whereas goals that have exited are
annotated with the Exit: port. You can always be sure of jumping to the
Exit or Redo port of any goal shown to be exited in the backtrace listing.
The backtrace is a tree rather than a stack: to find the parent of a
given goal with depth indicator d, look for the closest goal above
it with depth indicator d-1.
debugging/0.
spy(Func, Conditions)command, where Func is the functor of the current invocation.
nospy Func, where Func is the
functor of the current invocation.
remove_breakpoints(BID), where BID is the
current breakpoint identifier, or the supplied argument.
disable_breakpoints(BID), where BID is the
current breakpoint identifier, or the supplied argument.
abort/0.)
break/0, thus putting you
at a recursive top-level with the execution so far sitting underneath you.
When you end the break (^D) you will be reprompted at the port at
which you broke. The new execution is completely separate from the
suspended one; the invocation numbers will start again from 1 during the
break. The debugger is temporarily switched off as you call the break and
will be re-switched on when you finish the break and go back to the old
execution. However, any changes to the leashing or to spypoints will
remain in effect.
| :- will be output on the standard error stream, and a command is then read
from the standard input stream and executed as if you were at top level.
Head :- Body, then Head will
be unified with the current goal, and Body will be executed in its
place.
The following hook predicate can be used to customize the behavior of the interactive debugger.
debugger_command_hook(+Char,?Actions) [Hook]
user:debugger_command_hook(+Char,?Actions)
This predicate is called each time the debugger has read the first character Char of a debugger command. If it succeeds, Actions is taken as the list of actions (see Action Conditions) to be done for the given debugger command. If it fails, further arguments are read in, and the debugger command is interpreted in the standard way.
The above hook makes it possible to extend the interactive debugger
with user-defined commands. The following example defines the S
interactive debugger command to behave as skip at Call and Redo ports,
and as creep otherwise:
debugger_command_hook(0'S, Actions) :-
ttyskip(0'\n), % skip till end of line
execution_state([port(P),inv(I)]),
Actions = [Mode,proceed,silent],
( P = call -> Mode = skip(I)
; P = redo -> Mode = skip(I)
; Mode = trace
).
Note that the silent action is needed above, otherwise the
debugger message will be printed a second time, before continuing the
execution.
This section describes the advanced built-in predicates for creating and removing breakpoints.
add_breakpoint(:Conditions, ?BID)
Adds a breakpoint with conditions Conditions, the breakpoint identifier assigned is unified with BID. Conditions is one of the following:
-Actions
-[]
-Actions
[]-Actions
Here Tests and Actions are lists of Conditions or a single Condition, see Breakpoint Conditions.
The add_breakpoint/2 predicate performs some transformations on
the Conditions before adding the breakpoint. The goal and
pred conditions are extracted from both the test and the action
part and their consistency is checked. A goal condition is then
inserted as the first element of the tests list, encapsulating all
supplied goal conditions as well as those pred conditions
which can be transformed to a goal condition. Furthermore the
debugger condition is removed, and the advice condition is
moved to the second element of the tests list. Finally a pred
condition is inserted in front of the remaining tests, in the rare cases
when it can not be made part of the preceding goal test. The
rest of the test part and the action part is the same as supplied, with
the extracted conditions removed.
There can only be a single plain spypoint for each predicate. If a plain spypoint is added, and there is already a plain spypoint for the given functor, then:
spy(:PredSpec, :Conditions)
Adds a conditional spypoint with conditions
[pred(Pred)|Conditions], for each predicate
Pred designated by the generalized
predicate spec PredSpec.
current_breakpoint(:Conditions, ?BID, ?Status, ?Kind)
There is a breakpoint with conditions Conditions, breakpoint
identifier BID, status Status and kind Kind.
Status is one of on or off, referring to enabled and
disabled breakpoints. Kind is one of plain,
conditional or generic. current_breakpoint/4
enumerates all breakpoints on backtracking.
The Conditions as returned by current_breakpoint/4 may not
be exactly the same as supplied at the creation of the breakpoint,
because of the transformations done at creation, see the description of
add_breakpoint/2 above.
remove_breakpoints(+BIDs)
disable_breakpoints(+BIDs)
enable_breakpoints(+BIDs)
Removes, disables or enables the breakpoints with identifiers specified by
BIDs. BIDs can be a number, a list of numbers or one of the
atoms: all, debugger, advice. The atoms specify all
breakpoints, debugger type breakpoints and advice type breakpoints
respectively.
execution_state(:Tests)
Tests are satisfied in the current state of the execution.
execution_state(+FocusConditions, :Tests)
Tests are satisfied in the state of the execution pointed to by FocusConditions.
Note that the built-in predicate arguments holding breakpoint conditions
(Conditions or Tests above) are subject to module name
expansion. The primitive conditions goal(_), pred(_),
ancestor(_), and true(_) will inherit the module name from
the (module name expanded) conditions argument, in the absence of
explicit module qualification within the primitive condition.
This section describes in detail how the debugger handles the breakpoints. For the purpose of this section disabled breakpoints are not taken into account: whenever we refer to the existence of some breakpoint(s), we always mean the existence of enabled breakpoint(s).
The Prolog engine can be in one of the following three states with respect to the debugger:
In the selective debugging state only those predicate invocations are examined, for which there exists a specific breakpoint. In the full debugging state all invocations are examined, except those calling a non-exported predicate of a hidden module (but even these will be examined, if there is a specific breakpoint for them). In the no debugging state the debugger is not entered at predicate invocations.
Now we describe what the debugger does when examining an invocation of a predicate, i.e. executing its Call port.
First the debugger tries to select an applicable advice-point. It does
this by considering all advice-points, most recent first, and evaluating
the conditions in its tests and actions, in the order as stored by
add_breakpoint/2; see Breakpoint Predicates. The first
advice-point, for which this process succeeds, is selected. If there was
no advice-point selected, or the variable command (initialized to
proceed) was re-set to flit in the course of the selection
process, then the debugger notes that the advice facility does not
require the creation of a procedure box.
Second, the search for spypoints takes place. This is started by
initializing the debugger action variables. The mode
variable is set to the current debugger mode. The values for
show and command depend on the hiddenness
of the predicate being invoked, the debugger mode and the leashing
status of the port. If the predicate is both defined in, and called from
a hidden module, then the defaults will be silent and
flit. An example of this is when a built-in predicate is called
from a hidden module, e.g. from a library. Otherwise, in trace mode, the
default values are print and ask for leashed ports, and
print and proceed for unleashed ports. In debug mode, the
variables default to silent and proceed, while in zip mode
to silent and flit. These default values reflect the
behaviour expected for the given debugger mode, e.g. in zip mode the
debugger does not print debugging information and does not build
procedure boxes.
Having initialized the debugger action variables, the system does the
spypoint search, unless the debugger mode is off or skip. Finding an
applicable spypoint is done in the same way as described for advice
points. The only difference is that, when the test part of a spypoint
succeeds and there is no action part, the [print,ask] actions are
executed.
The third stage is the interactive part. First, the goal in question is
displayed according to the value of show. Next, the value of
command is checked: if it is other than ask the
interactive stage ends. Otherwise, if it is ask, the debugger
prompts the user for a command which is interpreted either in the
standard way, or through user:debugger_command_hook/2. In both cases
the debugger action variables are modified as requested, and the
interactive part is repeated.
After the debugger went through all the three stages, it decides whether
to build a procedure box. This will happen if either the advice-point
stage or the other two stages require it. The latter is decided by
checking the functor of command: if that is flit, then no
procedure box is required by the spypoint part. In such a case, if the
advice-point does require the building of a procedure box, the
command variable is modified, by changing its functor to
proceed.
At the end of the process the value of mode will be the new
debugging mode, and command will determine what the debugger will
do; see Action Variables.
A similar three-stage process is carried out when the debugger arrives
at a non-Call port of a predicate. The only difference is that the
building of a procedure box is not considered (flit is equivalent
to proceed), and the hiddenness of the predicate is not taken
into account.
While the Prolog system is executing the above three-stage process for any of the ports, it is said to be inside the debugger. This is relevant, because some of the conditions can only be evaluated in this context.
This section describes the format of primitive breakpoint conditions. We first list the tests that can be used to enquire the state of execution. We then proceed to describe the conditions usable in the actions part and the options for focusing on past execution states. Finally we describe some simple condition macros and the valid values for the debugger action variables.
Unless noted otherwise, the tests are usable both inside the debugger,
and outside it. Most of the tests can also be used in queries about
past execution states, in execution_state/2. For the latter type
of usage, in the following descriptions the term current should
be interpreted as referring to the execution state focused on.
The test will fail if the given query is not
meaningful in the given context, e.g. if execution_state(goal(G))
is queried before any breakpoints were encountered.
The following tests give access to basic information about the current invocation.
inv(Inv)
depth(Depth)
goal(MGoal)
pred(MFunc)
:F/N) of the current goal. The
unification required for matching is carried out.
module(Module)
goal_private(GoalPriv)
last_port(LastPort)
exit(nondet) if the
invocation has been exited, and call otherwise.
parent_inv(Inv)
ancestor(AncGoal,Inv)
Notes:
The debugger-parent of a goal is the youngest ancestor of the goal present on the backtrace. This will differ from the ordinary parent if not all goals are traced, e.g. if the goal in question is reached in zip mode. A debugger-ancestor of a goal is any of its ancestors on the backtrace.
In the goal and ancestor tests above, there is a given
module qualified goal template, say ModT:GoalT, and it is
matched against a concrete goal term Mod:Goal in the
execution state. This matching is carried out as follows:
:Goal and ModT:Goal is an exported
variant of the other, or both are imported from the same module.
The above matching rules also apply for predicate functors, in the
pred condition.
These tests provide access to source related information.
The file and line tests will fail if no source information
is present. The parent_clause and parent_pred
tests are available for interpreted code only.
file(File)
line(File,Line)
line(Line)
parent_clause(Cl)
parent_clause(Cl,Sel)
parent_clause(Cl,Sel,I)
parent_pred(Pred)
parent_pred(Pred,N)
These tests can be used both inside and outside the condition evaluation process, and also can be used in queries about past break levels.
break_level(N)
max_inv(MaxInv)
private(Priv)
goal_private/1, this condition refers initially to an
uninstantiated variable and can be used to store an arbitrary Prolog
term.
These tests can only be used inside the debugger and only when focused
on the current invocation. If they appear in execution_state/2
or in execution_state/1 called outside the debugger, an exception
will be raised.
The notion of port in breakpoint handling is more general than outlined earlier in Procedure Box. Here the following terms are used to describe a port:
call, exit(nondet), exit(det), redo, fail, exception(Exception), block, unblock
Furthermore, the atoms exit and exception can be used in
the port condition (see below), to denote any of the two exit
ports and an arbitrary exception port, respectively.
port(Port)
port(exit) holds for both
exit(det) and exit(nondet) ports).
bid(BID)
none if no breakpoint was selected.)
mode(Mode)
command(Command)
show(Show)
The last three of the above tests access the debugger action
variables. For example, the condition mode(trace), if it occurs
in the tests, checks if the current debugger mode is
trace. On the other hand, if the same term occurs within the
action part, it sets the debugger mode to trace.
For the port, mode, command and show
conditions, the condition can be replaced by its argument, if that is
not a variable. For example the condition call can be used
instead of port(call). Conditions matching the templates listed
above as valid port values will be converted to a port
condition. Similarly, any valid value for the three debugger action
variables is converted to an appropriate condition. These valid values
are described below; see Action Variables.
The following conditions are for prescribing or checking the breakpoint type. They are only meaningful inside the debugger and only for the current invocation.
advice
debugger
The following construct converts an arbitrary Prolog goal into a condition.
true(Cond)
mode(Mode)
command(Command)
show(Show)
The values admissible for Mode, Command and Show are described below; see Action Variables.
Furthermore, any other condition can be used in the action part, except
for the ones specifying the type (advice or debugger).
The following terms can be used in the first argument of
execution_state/2 (see Breakpoint Predicates).
break_level(I)
inv(Inv)
There are a few condition macros expanding to a list of other conditions:
unleash
[show(print),command(proceed)]
hide
[show(silent),command(proceed)]
leash
[show(print),command(ask)]
We first list the possible values of the debugger action variables, and their meaning. We then discuss how these variables are initialized and changed.
Values allowed in the show condition:
print
debugger_print_options Prolog flag.
silent
display
display.
write
writeq.
write_term(Options)
Method-Sel
Values allowed in the command condition:
ask
proceed
flit
proceed.
proceed(Goal,New)
u (unify)
interactive debugger command.
flit(Goal,New)
proceed/2.
exception(E)
abort
retry(Inv)
r, retry; see Debug Commands.
reexit(Inv)
je, jump to exit port; see Debug Commands.
redo(Inv)
jr, jump to redo port; see Debug Commands.
fail(Inv)
f, fail; see Debug Commands.
Values allowed in the mode condition:
qskip(Inv)
skip(Inv)
qskip.
trace
debug
zip
off
It is possible, and sometimes useful, to consult a file whilst in the middle of program execution. Predicates, which have been successfully executed and are subsequently redefined by a consult and are later reactivated by backtracking, will not notice the change of their definitions. In other words, it is as if every predicate, when called, creates a virtual copy of its definition for backtracking purposes.
If SICStus Prolog is run via the Emacs interface, the commands for loading code (such as C-c C-p, consulting the current predicate) are not directly available when the system prompts you after printing out a debugging message. Press b followed by <RET> to get a recursive top-level, ready to accept the Emacs commands. Type ^D to return to the debugging port.
Usually, exceptions that occur during debugging sessions are displayed
only in trace mode and for invocation boxes for predicates with
spypoints on them, and not during skips. However, it is sometimes
useful to make exceptions trap to the debugger at the earliest
opportunity instead. The hook predicate user:error_exception/1
provides such a possibility:
error_exception(+Exception) [Hook]
user:error_exception(+Exception)
This predicate is called at all exception ports. If it succeeds, the debugger enters trace mode and prints an exception port message. Otherwise, the debugger mode is unchanged and a message is printed only in trace mode or if a spypoint is reached, and not during skips.
We will show two examples using the advanced features of the debugger.
The first example defines a hide_exit(Pred) predicate, which will
hide the exit port for Pred (i.e. it will silently proceed),
provided the current goal was already ground at the call port, and
nothing was traced inside the given invocation. The
hide_exit(Pred) creates two spypoints for predicate Pred:
:- meta_predicate hide_exit(:).
hide_exit(Pred) :-
add_breakpoint([pred(Pred),call]-
true(save_groundness), _),
add_breakpoint([pred(Pred),exit,true(hide_exit)]-hide, _).
The first spypoint is applicable at the call port, and it calls
save_groundness to check if the given invocation was ground, and
if so, it sets the goal_private attribute of the invocation to
ground.
save_groundness :-
execution_state([goal(_:G),goal_private(Priv)]),
ground(G), !, Priv = ground.
save_groundness.
The second spypoint created by hide_exit is applicable at the
exit port and it checks whether the hide_exit
condition is true. If so, it issues a hide action, which is an
abbreviation of [show(silent),command(proceed)].
hide_exit :-
execution_state([inv(I),max_inv(I),goal_private(Priv)]),
Priv == ground.
Here hide_exit encapsulates the tests that the invocation number
is the same as the last invocation number used (max_inv), and
that the goal_private attribute of the invocation is identical to
ground. The first test ensures that nothing was traced inside the
current invocation.
If we load the above code, as well as the small example below, then the
following interaction can take place. Note that the hide_exit is
called with the _:_ argument, resulting in generic spypoints
being created.
| ?- [user].
| cnt(0) :- !.
| cnt(N) :-
| N > 0, N1 is N-1, cnt(N1).
| {user consulted, 0 msec 424 bytes}
yes
| ?- hide_exit(_:_), trace, cnt(1).
{The debugger will first zip -- showing spypoints (zip)}
{Generic spypoint added, BID=1}
{Generic spypoint added, BID=2}
{The debugger will first creep -- showing everything (trace)}
# 1 1 Call: cnt(1) ?
# 2 2 Call: 1>0 ?
# 3 2 Call: _2019 is 1-1 ?
3 2 Exit: 0 is 1-1 ?
# 4 2 Call: cnt(0) ?
1 1 Exit: cnt(1) ?
yes
{trace}
| ?-
Our second example defines a predicate call_backtrace(Goal,
BTrace), which will execute Goal and build a backtrace showing
the successful invocations executed during the solution of Goal.
The advantages of such a special backtrace over the one incorporated in the debugger are the following:
The call_backtrace predicate is based on the advice facility. It
uses the variable accessible via the private(_) condition to
store a mutable holding the backtrace. Outside the call_backtrace
predicate the mutable will have the value off.
The example is a module-file, so that internal invocations can be identified by the module-name.
:- module(backtrace, [call_backtrace/2]).
call_backtrace/2 is a meta-predicate, which first sets up an
appropriate advice-point for building the backtrace. This step is
skipped if there already exists a breakpoint of this kind. Note the
careful formulation of the breakpoint condition Cond: a fully
spelled out form is used (e.g. port(call) instead of
call), so that Cond is good both for checking the presence
of a breakpoint with the given conditions in
current_breakpoint/4, and for creating a new breakpoint in
add_breakpoint/2.
Having ensured the appropriate advice-point exists,
call_backtrace/2 picks up the private field of the
execution state and calls call_backtrace/3 with a cleanup
operation ensuring that the breakpoint added is removed at the end.
:- meta_predicate call_backtrace(:, ?).
call_backtrace(Goal, BTrace) :-
Cond = [goal(M:G),advice,port(call),private(Priv),
true(backtrace:store_goal(M,G,Priv))]
-[command(flit)],
( current_breakpoint(Cond, _, on, _) -> B = []
; add_breakpoint(Cond, B)
),
execution_state(private(Priv)),
call_cleanup(call_backtrace(Goal, BTrace, Priv),
remove_breakpoints(B)).
The predicate call_backtrace/3 receives the private field of the
execution state in its Priv argument. It assumes that this is
either a mutable or a yet uninstantiated variable. In the latter case
the variable is set to a newly created mutable. In both cases the
mutable is initialized to [], and the Goal is called. In
the course of the execution of the Goal the debugger will
accumulate the backtrace in the mutable. Finally, the mutable is read,
its value returned in BTrace and it is restored to its old value
(or off).
:- meta_predicate call_backtrace(:, ?, ?).
call_backtrace(Goal, BTrace, Priv) :-
( is_mutable(Priv) -> get_mutable(Old, Priv),
update_mutable([], Priv)
; create_mutable([], Priv), Old = off
),
call(Goal),
get_mutable(BTrace, Priv), update_mutable(Old, Priv).
store_goal/3 is the predicate called by the advice-point, with
the module, the goal and the private mutable as arguments. The first
clause ensures that calls from within the backtrace module get
ignored. The second clause prepends the module qualified goal term to
the private mutable, provided the latter exists and its value is not
off.
store_goal(backtrace, _, _) :- !, fail.
store_goal(M, G, Priv) :-
is_mutable(Priv),
get_mutable(BTrace, Priv),
BTrace \== off,
update_mutable([M:G|BTrace], Priv).
Below is an example run, using a small program:
| ?- [user].
| cnt(N):- N =< 0, !.
| cnt(N) :-
N > 0, N1 is N-1, cnt(N1).
| {consulted user in module user, 0 msec 224 bytes}
yes
| ?- call_backtrace(cnt(1), B).
{Generic advice point added, BID=1}
{Generic advice point, BID=1, removed (last)}
B = [user:(0=<0),user:cnt(0),user:(0 is 1-1),user:(1>0),user:cnt(1)] ?
yes
| ?-
It is not possible to redefine built-in predicates. An attempt to do so will give an error message. See Pred Summary.
SICStus Prolog provides a wide range of built-in predicates to perform the following tasks:
Input / Output
Reading-in Programs
Term and Goal Expansion
Input and Output of Terms
Character I/O
Stream I/O
Dec-10 Prolog File I/O
Arithmetic
Comparison of Terms
Control
Error and Exception Handling
Information about the State of the Program
Meta-Logic
Modification of Terms
Modification of the Program
Internal Database
Blackboard Primitives
All Solutions
Coroutining
Debugging
Execution Profiling
Miscellaneous
When introducing a built-in predicate, we shall present its usage with a mode spec, and optionally with an annotation containing one or more of:
iso execution mode only.
sicstus execution
mode only.
The following descriptions of the built-in predicates are grouped according to the above categorization of their tasks.
There are two sets of file manipulation predicates in SICStus Prolog. One set is inherited from DEC-10 Prolog. These predicates always refer to a file by name. The other set of predicates is modeled after Quintus Prolog and refer to files as streams. Streams correspond to the file pointers used at the operating system level.
This second set of file manipulation predicates, the one involving streams, is supported by the ISO Prolog standard. Note that the notion of file is used here in a generalized sense; it may refer to a name file, the user's terminal, or some other device. The ISO Prolog standard refers to this generalized notion of file using the term source/sink.
A stream can be opened and connected to a filename or file descriptor
for input or output by calling the predicates open/[3,4]. These
predicates will return a reference to a stream which may then be passed
as an argument to various I/O predicates. Alternatively, a stream can
be assigned an alias at the time of opening, and referred to by this
alias afterwards. The predicate close/1 is used for closing a
stream.
There are two types of streams, binary or text. Binary streams are seen as a sequence of bytes, i.e. integers in the range 0-255. Text streams, on the other hand, are considered a sequence of characters, represented by their character codes. SICStus Prolog handles wide characters, i.e. characters with codes larger than 255. The WCX (Wide Character eXtension) component of SICStus Prolog allows selecting various encoding schemes via environment variables or hook procedures; see Handling Wide Characters.
The predicates current_stream/3 and stream_property/2 are
used for retrieving information about a stream, and for finding the
currently existing streams.
Prolog streams can be accessed from C functions as well. See SICStus Streams, for details.
The possible formats of a stream are:
'$stream'(X)
alias(Atom) option of open/4. There are also three
predefined aliases:
user_input
stdin stream.
The alias can be changed with prolog_flag/3 and accessed
by the C variable SP_stdin.
user_output
stdout stream.
The alias can be changed with prolog_flag/3 and accessed
by the C variable SP_stdout.
user_error
stderr stream.
The alias can be changed with prolog_flag/3 and accessed
by the C variable SP_stderr.
This stream is used by the Prolog top level and debugger, and for system messages.
Certain I/O predicates manipulate streams implicitly, by
maintaining the notion of a current input stream and a
current output stream. The current input and output streams are
set to the user_input and user_output initially and for
every new break (see Nested). The predicate see/1
(tell/1) can be used for setting the current input (output)
stream to newly opened streams for particular files. The predicate
seen/0 (told/0) closes the current input (output) stream,
and resets it to the standard input (output) stream. The predicate
seeing/1 (telling/1) is used for retrieving the filename
associated with the current input (output) streams.
The possible formats of a filename are:
The filename user stands for the standard input or output stream,
depending on context. Terminal output is only guaranteed to be displayed
if the output stream is explicitly flushed.
A filename other than user must be an atom or a compound term.
It is subject to four phases of rewriting:
~ or $ (see below).
General filenames are rewritten to atomic filenames as follows:
Alias(File) is
rewritten by first looking up a clause of the hook predicate
user:file_search_path(Alias,Expansion).
If such a clause is found, and
Expansion can be rewritten to the atomic filename FirstPart,
and File can be rewritten to the atomic filename SecondPart, then
F is rewritten to FirstPart/SecondPart.
Since it is possible to have multiple definitions for the same alias,
predicates such as load_files/1 may have to explore several
alternative expansions before they locate the file to load,
depending on the operation to be performed on the file.
Once an atomic filename has been obtained, it is subject to another
rewriting step if it begins with ~ or $.
For example,
~/sample.pl
/home/sics/al/sample.pl, if
/home/sics/al is the user's home directory. (This is also
equivalent to $HOME/sample.pl as explained below.)
~clyde/sample.pl
/home/sics/clyde/sample.pl, if
/home/sics/clyde is Clyde's home directory.
$UTIL/sample.pl
/usr/local/src/utilities/sample.pl, provided
the value of the environment variable UTIL is
/usr/local/src/utilities.
For example, given the clauses:
file_search_path(home, '$HOME'). file_search_path(demo, home(prolog(demo))). file_search_path(prolog, prolog).
the filename demo(mydemo) would be rewritten to
'$HOME/prolog/demo/mydemo', where '$HOME' is interpreted as
an environment variable (the user's home directory).
Failure to open a file normally causes an exception to be raised. This
behavior can be turned off and on by of the built-in predicates
nofileerrors/0 and fileerrors/0 described below.
When the predicates discussed in this section are invoked, filenames are relative to the current working directory. During the load, the current working directory is temporarily changed to the directory containing the file being read in. This has the effect that if one of these predicates is invoked recursively, the filename of the recursive load is relative to the directory of the enclosing load. See Load Intro, for an introduction to these predicates.
Directives will be executed in order of occurrence. Be aware of the
changed current working directory as it could have an effect on the
semantics of directives. Only the first solution of directives is
produced, and variable bindings are not displayed. Directives that fail
or raise exceptions give rise to warning or error messages, but do not
terminate the load. However, these warning or error messages can be
intercepted by the hook user:portray_message/2 which can call
abort/0 to terminate the load, if that is the desired behavior.
Predicates loading source code are affected by the character-conversion
mapping, cf. char_conversion/2; see Term I/O.
Most of the predicates listed below take an argument Files which
is a single file name or a list of file names. Source, object and QL
files usually end with a .pl, .po and .ql suffix
respectively. These suffixes are optional. Each file name may
optionally be prefixed by a module name. The module name specifies
where to import the exported predicates of a module-file, or where to
store the predicates of a non-module-file. The module is created if it
doesn't exist already.
absolute_file_name/2 (see Stream Pred) is used to look up the
files. The file name user is reserved and denotes the standard
input stream.
These predicates are available in runtime systems with the following limitations:
discontiguous_warnings, redefine_warnings
and single_var_warnings have no effect.
load_files(:Files)
load_files(:Files, +Options)
A generic predicate for loading files with a list of options to provide
extra control. This predicate in fact subsumes the other predicates
except use_module/3 which also returns the name of the loaded
module, or imports a set of predicates from an existing module.
Options is a list of zero or more of the following:
if(X)
true (the default) to always load, or changed
to load only if the file has not yet been loaded or if it has been
modified since it was last loaded. A non-module-file is not considered
to have been previously loaded if it was loaded into a different module.
The file user is never considered to have been previously loaded.
when(When)
always (the default) to always load, or compile_time to
load only if the goal is not in the scope of another
load_files/[1,2] directive occurring in a .po or .ql file.
The latter is intended for use when the file only defines predicates
that are needed for proper term or goal expansion during compilation of
other files.
load_type(LoadType)
source to load source files only,
object to load object (.po) files only,
ql (obsolescent) to load .ql files only,
or latest (the default) to load any type of file,
whichever is newest. If the file is user, source is forced.
imports(Imports)
all (the default) to import all exported predicates if the file
is a module-file, or a list of predicates to import.
compilation_mode(Mode)
compile to translate into compiled code, consult to
translate into static, interpreted code, or assert_all to
translate into dynamic, interpreted code.
The default is the compilation mode of any ancestor
load_files/[1,2] goal, or compile otherwise. Note that
Mode has no effect when an .po or .ql file is
loaded, and that it is recommended to use assert_all in
conjunction with load_type(source), to ensure that the source
file will be loaded even in the presence of a .po or .ql
file.
wcx(Wcx)
consult(:Files)
reconsult(:Files) [Obsolescent]
[]
[:File|+Files]
Consults the source file or list of files specified by File and
Files. Same as load_files(Files, [load_type(source),compilation_mode(consult)]).
compile(:Files)
Compiles the source file or list of files specified by Files. The
compiled code is placed in-core, i.e. is added incrementally to the
Prolog database.
Same as load_files(Files, [load_type(source),compilation_mode(compile)]).
load(:Files) [Obsolescent]
Loads the .ql file or list of files specified by Files.
Same as load_files(Files, [load_type(ql)]).
ensure_loaded(:Files) [ISO]
Compiles or loads the file or files specified by Files that
have been modified after the file was last loaded, or that have not
yet been loaded. The recommended style is to use this predicate for
non-module-files only, but if any module-files are encountered, their
public predicates are imported.
Same as load_files(Files, [if(changed)]).
use_module(:File)
Compiles or loads the module-file specified by File if it has been
modified after it was last loaded, or not yet been loaded. Its public
predicates are imported. The recommended style is to use this predicate
for module-files only, but any non-module-files encountered are simply
compiled or loaded. Same as load_files(File,
[if(changed)]).
use_module(:File, +Imports)
Loads the module-file File like ensure_loaded/1 and imports
the predicates in Imports. If any of these are not public,
a warning is issued. Imports may also be set to the atom
all in which case all public predicates are imported.
Same as load_files(File, [if(changed),imports(Imports)]).
use_module(-Module, :File, +Imports)
use_module(+Module, :File, +Imports)
If used with +Module, and that module already exists, this merely
imports Imports from that module. Otherwise, this is equivalent
to use_module(File, Imports) with the addition that
Module is unified with the loaded module.
fcompile(:Files) [Obsolescent]
Compiles the source file or list of files specified by Files. If
Files are prefixed by a module name, that module name will be used
for module name expansion during the compilation (see Considerations).
The suffix .pl is added to the given filenames to yield the real
source filenames. The compiled code is placed on the .ql file or
list of files formed by adding the suffix .ql to the given
filenames.
(This predicate is not available in runtime systems.)
source_file(?File)
File is the absolute name of a source file currently in the system.
source_file(:Head,?File)
source_file(-Head,?File)
Head is the most general goal for a predicate loaded
from File.
require(:PredSpecOrSpecs)
PredSpecOrSpecs is a predicate spec or a list or a
conjunction of such. The predicate will check if the specified
predicates are loaded and if not, will try to load or import them using
use_module/2. The file containing the predicate definitions will
be located in the following way:
user:library_directory/1 are
searched for a file INDEX.pl. This file is taken to contain
relations between all exported predicates of the module-files in the
library directory and its subdirectories. If an INDEX.pl is not
found, require/1 will try to create one by loading the library
package mkindex and calling
make_index:make_library_index(Directory)
(see The Prolog Library).
INDEX.pl is read, it is cached internally for use in
subsequent calls to require/1.
When a program is being read in, SICStus Prolog provides hooks that enable the terms being read in to be source-to-source transformed before the usual processing of clauses or directives. The hooks consist in user-defined predicates that define the transformations. One transformation is always available, however: definite clause grammars, a convenient notation for expressing grammar rules. See [Colmerauer 75] and [Pereira & Warren 80].
Definite clause grammars are an extension of the well-known context-free grammars. A grammar rule in Prolog takes the general form
head --> body.
meaning "a possible form for head is body". Both
body and head are sequences of one or more items linked by the
standard Prolog conjunction operator ,.
Definite clause grammars extend context-free grammars in the following ways:
[]. If the terminal symbols are character codes,
such lists can be written (as elsewhere) as strings. An empty sequence
is written as the empty list, [] or "".
{} brackets.
; (|), ->, and \+ as in a Prolog clause.
{} brackets.
As an example, here is a simple grammar which parses an arithmetic expression (made up of digits and operators) and computes its value.
expr(Z) --> term(X), "+", expr(Y), {Z is X + Y}.
expr(Z) --> term(X), "-", expr(Y), {Z is X - Y}.
expr(X) --> term(X).
term(Z) --> number(X), "*", term(Y), {Z is X * Y}.
term(Z) --> number(X), "/", term(Y), {Z is X / Y}.
term(Z) --> number(Z).
number(C) --> "+", number(C).
number(C) --> "-", number(X), {C is -X}.
number(X) --> [C], {"0"=<C, C=<"9", X is C - "0"}.
In the last rule, C is the character code of some digit.
The query
| ?- expr(Z, "-2+3*5+1", []).
will compute Z=14. The two extra arguments are explained below.
Now, in fact, grammar rules are merely a convenient "syntactic sugar" for ordinary Prolog clauses. Each grammar rule takes an input string, analyses some initial portion, and produces the remaining portion (possibly enlarged) as output for further analysis. The arguments required for the input and output strings are not written explicitly in a grammar rule, but the syntax implicitly defines them. We now show how to translate grammar rules into ordinary clauses by making explicit the extra arguments.
A rule such as
p(X) --> q(X).
translates into
p(X, S0, S) :- q(X, S0, S).
If there is more than one non-terminal on the right-hand side, as in
p(X, Y) -->
q(X),
r(X, Y),
s(Y).
then corresponding input and output arguments are identified, as in
p(X, Y, S0, S) :-
q(X, S0, S1),
r(X, Y, S1, S2),
r(Y, S2, S).
Terminals are translated using the built-in predicate
'C'(S1, X, S2), read as "point S1 is
connected by terminal X to point S2", and defined by the single
clause
'C'([X|S], X, S).
(This predicate is not normally useful in itself; it has been given the name upper-case c simply to avoid using up a more useful name.) Then, for instance
p(X) --> [go,to], q(X), [stop].
is translated by
p(X, S0, S) :-
'C'(S0, go, S1),
'C'(S1, to, S2),
q(X, S2, S3),
'C'(S3, stop, S).
Extra conditions expressed as explicit procedure calls naturally translate as themselves, e.g.
p(X) --> [X], {integer(X), X>0}, q(X).
translates to
p(X, S0, S) :-
'C'(S0, X, S1),
integer(X),
X>0,
q(X, S1, S).
Similarly, a cut is translated literally.
Terminals are translated using the built-in predicate
'C'(S1, X, S2), read as "point S1 is
connected by terminal X to point S2", and defined by the single
clause
Terminals on the left-hand side of a rule are also translated using
'C'/3, connecting them to the output argument of the head
non-terminal, e.g.
is(N), [not] --> [aint].
becomes
is(N, S0, S) :-
'C'(S0, aint, S1),
'C'(S, not, S1).
Disjunction has a fairly obvious translation, e.g.
args(X, Y) -->
( dir(X), [to], indir(Y)
; indir(Y), dir(X)
).
translates to
args(X, Y, S0, S) :-
( dir(X, S0, S1),
'C'(S1, to, S2),
indir(Y, S2, S)
; indir(Y, S0, S1),
dir(X, S1, S)
).
Similarly for if-then, if-then-else, and not-provable.
The built-in predicates which are concerned with grammar rules and other compile/consult time transformations are as follows:
expand_term(+Term1,?Term2)
If Term1 is a term that can be
transformed, Term2 is the result. Otherwise Term2 is just
Term1 unchanged. This transformation takes place automatically
when grammar rules are read in, but sometimes it is useful to be able to
perform it explicitly. Grammar rule expansion is not the only
transformation available; the user may define clauses for the predicate
user:term_expansion/[2,4] to perform other transformations.
user:term_expansion(Term1[,Layout1],Term2[,Layout2])
is called first, and
only if it fails is the standard expansion used.
term_expansion(+Term1,?TermOrTerms) [Hook]
term_expansion(+Term1,+Layout1,?TermOrTerms,?Layout2) [Hook]
user:term_expansion(+Term1,?TermOrTerms)
user:term_expansion(+Term1,+Layout1,?TermOrTerms,?Layout2)
Defines transformations on terms read
while a program is consulted or compiled. It is called for every
Term1 read, including at end of file, represented as the term
end_of_file. If it succeeds, TermOrTerms is used for further
processing, otherwise the default grammar rule expansion is attempted.
It is often useful to let a term expand to a list of directives and
clauses, which will then be processed sequentially.
The 4 arguments version also defines transformations on the layout of the term read, so that the source-linked debugger can display accurate source code lines if the transformed code needs debugging. Layout1 is the layout corresponding to Term1, and Layout2 should be a valid layout of TermOrTerms (see Term I/O).
For accessing aspects of the load context, e.g. the name of the file
being compiled, the predicate prolog_load_context/2 (see State Info) can be used.
user:term_expansion/[2,4] may also be used to transform queries
entered at the terminal in response to the | ?- prompt. In
this case, it will be called with Term1 = ?-(Query)
and should succeed with TermOrTerms = ?-(ExpandedQuery).
goal_expansion(+Goal,+Module,?NewGoal) [Hook]
user:goal_expansion(+Goal,+Module,?NewGoal)
Defines transformations on goals
while clauses are being consulted, compiled or asserted, after
any processing by user:term_expansion/[2,4] of the terms being read
in. It is called for every simple Goal encountered in the calling
context Module. If it succeeds, Goal is replaced by
NewGoal, otherwise Goal is left unchanged. NewGoal
may be an arbitrarily complex goal, and user:goal_expansion/3 is
recursively applied to its subgoals.
This predicate is also used to resolve meta-calls to Goal
at runtime via the same mechanism. If the transformation
succeeds, NewGoal is simply called instead of Goal.
Otherwise, if Goal is a goal of an existing predicate,
that predicate is invoked.
Otherwise, error recovery is attempted by
user:unknown_predicate_handler/3 as described below.
user:goal_expansion/3 can be regarded as a macro expansion facility.
It is used for this purpose to support the interface to attributed
variables in library(atts), which defines the predicates
M:get_atts/2 and M:put_atts/2 to access
module-specific variable attributes. These "predicates" are actually
implemented via the user:goal_expansion/3 mechanism. This has the
effect that calls to the interface predicates are expanded at compile
time to efficient code.
For accessing aspects of the load context, e.g. the name of the file
being compiled, the predicate prolog_load_context/2 (see State Info) can be used.
phrase(:Phrase,?List)
phrase(:Phrase,?List,+Remainder)
The list List is a phrase of type Phrase (according to the
current grammar rules), where Phrase is either a non-terminal or
more generally a grammar rule body. Remainder is what remains of
the list after a phrase has been found. If called with 2 arguments, the
remainder has to be the empty list.
'C'(?S1,?Terminal,?S2)
Not normally of direct use to the user, this built-in predicate is used
in the expansion of grammar rules (see above). It is defined as if by
the clause 'C'([X|S], X, S).
Most of the following predicates come in two versions, with or without a stream argument. Predicates without a stream argument operate on the current input or output stream, depending on context. Predicates with a stream argument can take stream reference or an alias in this argument position, the alias being replaced by the stream it was associated with.
Some of these predicates support a notation for terms containing
multiple occurrences of the same subterm (cycles and DAGs). The
notation is @(Template,Substitution) where
Substitution is a list of Var=Term pairs where the
Var occurs in Template or in one of the Terms.
This notation stands for the instance of Template obtained by
binding each Var to its corresponding Term. The purpose of
this notation is to provide a finite printed representation of cyclic
terms. This notation is not used by default, and @/2 has no
special meaning except in this context.
read(?Term) [ISO]
read(+Stream,?Term) [ISO]
The next term, delimited by a full-stop (i.e. a ., possibly
followed by layout text), is read from Stream and is unified with
Term. The syntax of the term must agree with current operator
declarations. If a call read(Stream, Term) causes the end
of Stream to be reached, Term is unified with the term
end_of_file. Further calls to read/2 for the same stream
will then raise an exception, unless the stream is connected to the
terminal. The characters read are subject to character-conversion, see
below.
read_term(?Term,+Options) [ISO]
read_term(+Stream,?Term,+Options) [ISO]
Same as read/[1,2] with a list of options to provide extra
control or information about the term. Options is a list of zero
or more of:
syntax_errors(+Val)
syntax_errors Prolog flag. The
default is set by that flag.
variables(?Vars)
variable_names(?Names)
singletons(?Names)
cycles(+Boolean)
true or false. If selected, any
occurrences of @/2 in the term read in are replaced by the
potentially cyclic terms they denote as described above. Otherwise (the
default), Term is just unified with the term read in.
layout(?Layout)
[], if no line number information is available for X.
| ?- read_term(T, [layout(L), variable_names(Va), singletons(S)]).
|: [
foo(X),
X = Y
].
L = [35,[36,36],[36,[37,37,37],38]],
S = ['Y'=_A],
T = [foo(_B),_B=_A],
Va = ['X'=_B,'Y'=_A]
char_conversion(+InChar, +OutChar) [ISO]
InChar and OutChar should be one-char atoms. If they are not
the same, then the mapping of InChar to OutChar is added to
the character-conversion mapping. This means that in all
subsequent term and program input operations any unquoted
occurrence of InChar will be replaced by OutChar. The
rationale for providing this facility is that in some extended character
sets (such as Japanese JIS character sets) the same character can appear
several times and thus have several codes, which the users normally
expect to be equivalent. It is advisable to always quote the arguments
of char_conversion/2.
If InChar and OutChar are the same, the effect of
char_conversion/2 is to remove any mapping of InChar from
the character-conversion mapping.
current_char_conversion(?InChar, ?OutChar) [ISO]
The character of one-char atom InChar is mapped to
that of the one-char atom OutChar in the current
character-conversion mapping. Enumerates all such pairs on backtracking.
write(?Term) [ISO]
write(+Stream,?Term) [ISO]
The term Term is written onto Stream according to current
operator declarations.
Same as write_term([Stream,] Term, [numbervars(true)]).
display(?Term)
The term Term is displayed onto the standard output stream
(which is not necessarily the current output stream) in standard
parenthesized prefix notation.
Same as write_term(user, Term, [ignore_ops(true)]).
write_canonical(?Term) [ISO]
write_canonical(+Stream,?Term) [ISO]
Similar to write(Stream,Term). The term will be
written according to the standard syntax. The output from
write_canonical/2 can be parsed by read/2 even if the term
contains special characters or if operator declarations have changed.
Same as write_term([Stream,] Term, [quoted(true),ignore_ops(true)]).
writeq(?Term) [ISO]
writeq(+Stream,?Term) [ISO]
Similar to write(Stream,Term), but the names of atoms
and functors are quoted where necessary to make the result acceptable as
input to read/2, provided the same operator declarations are in effect.
Same as write_term([Stream,] Term, [quoted(true),numbervars(true)]).
print(?Term) [Hookable]
print(+Stream,?Term) [Hookable]
Prints Term onto Stream. This predicate provides a handle for user defined pretty printing:
write(Stream,Term).
user:portray/1. If this succeeds then it is assumed that
Term has been output.
print/2 is called recursively on the components of
Term, unless Term is atomic in which case it is written via
write/2.
In particular, the debugging package prints the goals in the tracing messages, and the top-level prints the final values of variables. Thus you can vary the forms of these messages if you wish.
Note that on lists ([_|_]), print/2 will first give the
whole list to user:portray/1, but if this fails it will only give each
of the (top level) elements to user:portray/1. That is,
user:portray/1 will not be called on all the tails of the list.
Same as write_term([Stream,] Term, [portrayed(true),numbervars(true)]).
portray(+Term) [Hook]
user:portray(+Term)
This should either print the Term and
succeed, or do nothing and fail. In the latter case, the default
printer (write/1) will print the Term.
portray_clause(?Clause)
portray_clause(+Stream,?Clause)
Writes the clause Clause onto Stream
exactly as listing/[0,1] would have written it. Same as
write_term([Stream,] Term, [quoted(true),numbervars(true),indented(true)])
followed by a period and a newline, removing redundant module prefixes
and binding variables to terms of the form '$VAR'(N)
yielding friendlier variable names.
write_term(+Term,+Options) [ISO]
write_term(+Stream,+Term,+Options) [ISO]
Same as write/[1,2] etc. with a list of options to provide
extra control. This predicate in fact subsumes the above output
predicates except portray_clause/[1,2] which additionally prints a
period and a newline, and removes module prefixes that are redundant
wrt. the current type-in module. Options is a list of zero or
more of the following, where Boolean must be true or
false (false is the default).
quoted(+Boolean)
read/1. write_canonical/1,
writeq/1, and portray_clause/1 select this.
ignore_ops(+Boolean)
write_canonical/1 and
display/1 select this.
portrayed(+Boolean)
user:portray/1 is called for each subterm.
print/1 selects this.
numbervars(+Boolean)
'$VAR'(N) where N is an
integer >= 0 are treated specially (see numbervars/3).
print/1, write/1, writeq/1, and portray_clause/1
select this.
cycles(+Boolean)
@/2
notation, as discussed above.
indented(+Boolean)
portray_clause/1 and listing/[0,1].
max_depth(N)
format(+Format,:Arguments)
format(+Stream,+Format,:Arguments)
Prints Arguments onto Stream according to format Format. Format is a list of formatting characters or character codes. If Format is an atom then is will be used to translate it into a list of character codes. Thus:
| ?- format("Hello world!", []).
has the same effect as
| ?- format('Hello world!', []).
no matter which value the double_quotes Prolog flag has.
format/2 and format/3 is a Prolog interface to the C
stdio function printf(). It is modeled after and
compatible with Quintus Prolog.
Arguments is a list of items to be printed. If there are no items then an empty list should be supplied.
The default action on a format character is to print it. The character ~ introduces a control sequence. To print a ~ repeat it:
| ?- format("Hello ~~world!", []).
will result in
Hello ~world!
The escape sequence (see Escape Sequences) \c (c for continue) is useful when formatting a string for readability. It causes all characters up to, but not including, the next non-layout character to be ignored.
| ?- format("Hello \c
world!", []).
will result in
Hello world!
The general format of a control sequence is ~NC. The
character C determines the type of the control sequence. N
is an optional numeric argument. An alternative form of N is
*. * implies that the next argument in Arguments
should be used as a numeric argument in the control sequence. Example:
| ?- format("Hello~4cworld!", [0'x]).
and
| ?- format("Hello~*cworld!", [4,0'x]).
both produce
Helloxxxxworld!
The following control sequences are available.
~a
~Nc
~Ne
~NE
~Nf
~Ng
~NG
printf() function as
printf("%.Ne", Arg)
printf("%.NE", Arg)
printf("%.Nf", Arg)
printf("%.Ng", Arg)
printf("%.NG", Arg)
respectively.
If N is not supplied the action defaults to
printf("%e", Arg)
printf("%E", Arg)
printf("%f", Arg)
printf("%g", Arg)
printf("%G", Arg)
respectively.
~Nd
| ?- format("Hello ~1d world!", [42]).
Hello 4.2 world!
| ?- format("Hello ~d world!", [42]).
Hello 42 world!
~ND
~Nd except that , will separate groups of three
digits to the left of the decimal point. Example:
| ?- format("Hello ~1D world!", [12345]).
Hello 1,234.5 world!
~Nr
a-z will denote digits larger
than 9. Example:
| ?- format("Hello ~2r world!", [15]).
Hello 1111 world!
| ?- format("Hello ~16r world!", [15]).
Hello f world!
~NR
~Nr except that the letters A-Z will denote digits
larger than 9. Example:
| ?- format("Hello ~16R world!", [15]).
Hello F world!
~Ns
| ?- format("Hello ~4s ~4s!", ["new","world"]).
Hello new worl!
| ?- format("Hello ~s world!", ["new"]).
Hello new world!
~i
| ?- format("Hello ~i~s world!", ["old","new"]).
Hello new world!
~k
write_canonical/1 (see Term I/O). Example:
| ?- format("Hello ~k world!", [[a,b,c]]).
Hello .(a,.(b,.(c,[]))) world!
~p
print/1 (see Term I/O). Example:
| ?- assert((portray([X|Y]) :- print(cons(X,Y)))).
| ?- format("Hello ~p world!", [[a,b,c]]).
Hello cons(a,cons(b,cons(c,[]))) world!
~q
writeq/1 (see Term I/O). Example:
| ?- format("Hello ~q world!", [['A','B']]).
Hello ['A','B'] world!
~w
write/1 (see Term I/O). Example:
| ?- format("Hello ~w world!", [['A','B']]).
Hello [A,B] world!
~@
| ?- format("Hello ~@ world!", [write(new)]).
Hello new world!
~~
~. Example:
| ?- format("Hello ~~ world!", []).
Hello ~ world!
~Nn
| ?- format("Hello ~n world!", []).
Hello
world!
~N
The following control sequences set column boundaries and specify padding. A column is defined as the available space between two consecutive column boundaries on the same line. A boundary is initially assumed at line position 0. The specifications only apply to the line currently being written.
When a column boundary is set (~| or ~+) and there are
fewer characters written in the column than its specified width, the
remaining space is divided equally amongst the pad sequences
(~t) in the column. If there are no pad sequences, the column
is space padded at the end.
If ~| or ~+ specifies a position preceding the
current position, the boundary is set at the current position.
~N|
~N+
~Nt
`C where C is the fill
character. The default fill character is <SPC>. Any (~t)
after the last column boundary on a line is ignored.
| ?-
format("~`*t NICE TABLE ~`*t~61|~n", []),
format("*~t*~61|~n", []),
format("*~t~a~20|~t~a~t~20+~a~t~20+~t*~61|~n",
['Right aligned','Centered','Left aligned']),
format("*~t~d~20|~t~d~t~20+~d~t~20+~t*~61|~n",
[123,45,678]),
format("*~t~d~20|~t~d~t~20+~d~t~20+~t*~61|~n",
[1,2345,6789]),
format("~`*t~61|~n", []).
************************ NICE TABLE *************************
* *
* Right aligned Centered Left aligned *
* 123 45 678 *
* 1 2345 6789 *
*************************************************************
Most of character I/O predicates have several variants:
_byte, e.g. put_byte.
_code, e.g. put_code), and those using
one-char atoms (suffix _char, e.g. put_char).
put), with the exception
of peek_char.
put_byte(Stream, Byte)), or without the stream
argument, in which case the current input or output stream is used,
depending on the context (e.g. put_byte(Byte)).
tty, e.g. ttyput(Code).
nl [ISO]
nl(+Stream) [ISO]
A new line is started on the text stream Stream by printing an
<LFD>. If Stream is connected to the terminal, its buffer is
flushed.
get_code(?Code) [ISO]
get_code(+Stream,?Code) [ISO]
Code is the character code of the next character read from text
stream Stream. If all characters of Stream have been read,
Code is -1, and further calls to get_code/2 for the same
stream will normally raise an exception, unless the stream is connected to
the terminal (but see the eof_action option of open/4;
see Stream Pred).
get_char(?Char) [ISO]
get_char(+Stream,?Char) [ISO]
Char is the one-char atom naming the next character read from text
stream Stream. If all characters of Stream have been read,
Char is end_of_file, and further calls to get_char/2
for the same stream will normally raise an exception, unless the stream is
connected to the terminal (but see the eof_action option of
open/4; see Stream Pred).
get_byte(?Byte) [ISO]
get_byte(+Stream,?Byte) [ISO]
Byte is the next byte read from the binary stream Stream. It has
the same behavior at the end of stream as get_code.
get0(?Code) [Obsolescent]
get0(+Stream,?Code) [Obsolescent]
A combination of get_code and get_byte: Code is the
next character code or byte read from the arbitrary stream Stream.
get(?N) [Obsolescent]
get(+Stream,?N) [Obsolescent]
Same as get0/2, except N is the character code of the next
character that is not a layout-char (see Token String) read
from Stream.
peek_code(?Code) [ISO]
peek_code(+Stream,?Code) [ISO]
Code is the character code of the next character from text stream
Stream, or -1, if all characters of Stream have been read.
The character is not actually read, it is only looked at and is still
available for subsequent input.
peek_char(?Char) [ISO only]
peek_char(+Stream,?Char) [ISO only]
Char is the one-char atom naming the next character from text
stream Stream, or end_of_file, if all characters of
Stream have been read. The character is not actually
read.
peek_char(?Code) [SICStus only]
peek_char(+Stream,?Code) [SICStus only]
Identical to peek_code.
peek_byte(?Byte) [ISO]
peek_byte(+Stream,?Byte) [ISO]
Byte is the next byte from binary stream Stream, or -1, if
all bytes of Stream have been read. The byte is not actually
read.
skip(+Code) [Obsolescent]
skip(+Stream,+Code) [Obsolescent]
Skips just past the next character code Code from Stream.
Code may be an arithmetic expression.
skip_line [Obsolescent]
skip_line(+Stream) [Obsolescent]
Skips just past the next <LFD> from the text stream Stream.
put_code(+Code) [ISO]
put_code(+Stream,+Code) [ISO]
Character code Code is output onto text stream Stream.
Code may be an arithmetic expression.
put_char(+Char) [ISO]
put_char(+Stream,+Char) [ISO]
The character named by the one-char atom Char is output onto text
stream Stream.
put_byte(+Byte) [ISO]
put_byte(+Stream,+Byte) [ISO]
Byte Byte is output onto binary stream Stream.
Byte may be an arithmetic expression.
put(+Code) [Obsolescent]
put(+Stream,+Code) [Obsolescent]
A combination of put_code and put_byte: Code is
output onto (an arbitrary stream) Stream. Code may be an
arithmetic expression.
tab(+N) [Obsolescent]
tab(+Stream,+N) [Obsolescent]
N spaces are output onto text stream Stream. N may be an arithmetic expression.
The above predicates are the ones which are the most commonly used, as they can refer to any streams. The predicates listed below always refer to the standard input and output streams. They are provided for compatibility with DEC-10 character I/O, and are actually redundant and easily recoded in terms of the above predicates.
ttynl [Obsolescent]
Same as nl(user_output).
ttyflush [Obsolescent]
Same as flush_output(user_output).
ttyget0(?N) [Obsolescent]
Same as get0(user_input, N).
ttyget(?N) [Obsolescent]
Same as get(user_input, N).
ttyput(+N) [Obsolescent]
Same as put(user_output, N).
ttyskip(+N) [Obsolescent]
Same as skip(user_input, N).
ttytab(+N) [Obsolescent]
Same as tab(user_output, N).
The following predicates manipulate streams. Character, byte and line
counts are maintained per stream. All streams connected to the
terminal, however, share the same set of counts. For example, writing
to user_output will advance the counts for user_input, if
both are connected to the terminal. Bidirectional streams use the same
counters for input and output.
Wherever a stream argument appears as input (+Stream), an alias can be used instead.
open(+FileName,+Mode,-Stream) [ISO]
open(+FileName,+Mode,-Stream,+Options) [ISO]
If FileName is a valid file name, the file is opened in mode
Mode (invoking the UNIX function fopen) and the resulting
stream is unified with Stream. Mode is one of:
read
write
append
If FileName is an integer, it is assumed to be a file descriptor
passed to Prolog from C. The file descriptor is connected to a Prolog
stream (invoking the POSIX function fdopen) which is unified with
Stream.
Options is a list of zero or more of:
type(+T)
text or binary
stream. Default is text.
reposition(+Boolean)
true), or not (false). The latter is the default.
alias(+A)
eof_action(+Action)
end_of_file), and a further
attempt to input is made. Action can have the following values:
error
eof_code
end_of_file) is returned again.
reset
wcx(Wcx)
close(+X) [ISO]
close(+X, +Options) [ISO]
If X is a stream or alias, the stream is closed. If X is
the name of a file opened by see/1 or tell/1, the
corresponding stream is closed. Options is a list possibly
containing the following element:
force(Boolean)
true), or not (false). The
latter is the default. Currently this option has no effect.
absolute_file_name(+RelativeName,-AbsoluteName)
True if RelativeName can be expanded to an absolute file name
(an atom) AbsoluteName, according to the filename syntax rules
(see Input Output). This predicate will first search for a file
with the suffix .pl added to the name given as an argument. If
this fails, it will look for a file with no extra suffix added. If a
file is found AbsoluteName is its absolute file name is
returned. Otherwise, AbsoluteName is a valid expansion of
RelativeName.
absolute_file_name/2 does not produce alternative expansions via
backtracking.
If RelativeName is user, then AbsoluteName is
also unified with user; this "filename" stands for the standard
input or output stream, depending on context.
Variants of this predicate are used by all predicates that refer to
filenames for resolving these. Predicates that load code require that
the specified file exist, possibly with an extension.
file_search_path(+Alias,-Expansion) [Hook]
user:file_search_path(+Alias,-Expansion)
Specifies how to rewrite compound filenames to atomic ones, as described in Input Output. Alias should be an atom and Expansions a filename. The predicate may succeed non-deterministically in this search for an atomic filename.
The predicate exists as a dynamic, multifile predicate at startup with
the following clause, defining an expansion for the library and
system aliases. See State Info for more info on the
Prolog flag host_type.
file_search_path(library, Path) :-
library_directory(Path).
file_search_path(system, Platform) :-
prolog_flag(host_type, Platform).
library_directory(-Directory) [Hook]
user:library_directory(-Directory)
Specifies a directory to be searched when a filename of the form
library(Name) is used. The predicate exists as a dynamic,
multifile predicate at startup with a single clause defining the
location of the Prolog library. It may succeed non-deterministically in
this search for a library directory.
current_input(?Stream) [ISO]
Stream is the current input stream.
The current input stream is also accessed by the C variable SP_curin.
current_output(?Stream) [ISO]
Stream is the current output stream.
The current output stream is also accessed by the C variable SP_curout.
current_stream(?FileName,?Mode,?Stream)
Stream is a stream which was opened in mode Mode and which
is connected to the absolute file name Filename (an atom) or to
the file descriptor Filename (an integer). This predicate can be
used for enumerating all currently open streams through backtracking.
set_input(+Stream) [ISO]
Sets the current input stream to Stream.
set_output(+Stream) [ISO]
Sets the current output stream to Stream.
flush_output [ISO]
flush_output(+Stream) [ISO]
Flushes all internally buffered characters or bytes for Stream to the
operating system.
open_null_stream(-Stream)
Opens a text output stream. Everything written to this
stream will be thrown away.
character_count(+Stream,?N)
N is the number of characters read/written on text stream Stream.
byte_count(+Stream,?N)
N is the number of bytes read/written on stream
Stream. Meaningful for both binary and text streams. In the latter
case it will differ from the number returned by character_count/2
in the presence of wide characters.
line_count(+Stream,?N)
N is the number of lines read/written on text stream Stream.
line_position(+Stream,?N)
N is the number of characters read/written on the current line of
text stream Stream.
stream_position(+Stream,?Position)
Position is a term representing the current position of
Stream. The relative order of stream position terms can be tested
with standard term comparison predicates such as compare/3, but
you should not otherwise rely on their internal representation. This
operation is available for any Prolog stream.
stream_property(?Stream, ?Property)) [ISO]
Stream Stream has property Property. Enumerates through backtracking all currently open streams, including the standard input/output/error streams, and all their properties.
Property can be one of the following:
file_name(?F)
mode(?M)
input
output
alias(?A)
position(?P)
stream_position(Stream, P).
end_of_stream(?E)
not, otherwise (all characters read) but
no end of stream indicator (-1 or end_of_file) was reported
yet, then E is unified with at, otherwise E is
unified with past.
eof_action(?A)
eof_action option of open/4.
type(?T)
wcx(?Wcx)
set_stream_position(+Stream,+Position) [ISO]
Position is a term representing a new position of
Stream, which is then set to the new position. This operation is
only available for Prolog streams connected to "seekable devices"
(disk files, usually). If the option reposition(true) was
supplied at the successful opening of the stream, then
set_stream_position/2 is guaranteed to be successful.
seek(+Stream,+Offset,+Method,-NewLocation)
True if the stream Stream can be set to the byte offset Offset relative to Method, and NewLocation is the new byte offset from the beginning of the file after the operation. Method must be one of:
bof
current
eof
This operation is only available for Prolog streams connected to
"seekable devices" (disk files, usually) and is an interface to
the stdio functions fseek and ftell.
at_end_of_stream [ISO]
at_end_of_stream(+Stream) [ISO]
The end of stream has been reached for the input stream Stream.
An input stream reaches end of stream when all characters (except
EOF, i.e., -1) of the stream have been read. These
predicates peek ahead for next input character if there is no character
available on the buffer of Stream. Unless the stream is to be
treated as connected to the terminal (see SP_force_interactive,
Initializing the Prolog Engine), a stream remains at end of stream
after EOF has been read, and any further attempt to read from
the stream will raise an existence error (see Exception).
at_end_of_line
at_end_of_line(+Stream)
The end of stream or end of line has been reached for the input stream
Stream. An input stream reaches end of line when all the
characters except <LFD> of the current line have been read. These
predicates peek ahead for next input character if there is no character
available on the buffer of Stream.
fileerrors
Undoes the effect of nofileerrors/0.
nofileerrors
After a call to this predicate, failure to locate or open a file will
cause the operation to fail instead of the default action, which is to
raise an exception with an error message.
stream_select(+Streams,+TimeOut,-ReadStreams)
The list of streams in Streams is checked for readable characters.
A stream can be any stream associated with an I/O descriptor. The list
ReadStreams returns the streams with readable data. If
TimeOut is instantiated to off, the predicate waits until
something is available. If TimeOut is S:U the predicate
waits at most S seconds and U microseconds. Both S
and U must be integers >=0. If there is a timeout,
ReadStreams is [].
Not available in operating systems that do not support the
system() system call.
stream_interrupt(+Stream,?OldHandler,?NewHandler)
Installs NewHandler as an interrupt-handler which is invoked when
something is readable on Stream. OldHandler is the current
interrupt handler Stream must be associated with an I/O
descriptor. Interrupt handlers are specified as atoms. The atom
off indicates that the interrupt mechanism is turned off for
Stream. Any other atom is the name of a predicate invoked when
something is readable on Stream. The handler predicate has one
argument, the stream that is readable. For example,
stream_interrupt(Stream, _, int_handler).will enable the interrupt mechanism. Given the predicate
int_handler(Stream) :-
read(Stream, Data),
write(Data), nl.
the term read from Stream will be written to the current output.
NOTE: there is no guarantee that a complete Prolog term is available
yet. If not, read/2 will suspend as usual.
Not available in operating systems that do not provide the ability to generate signals when new data becomes available on a file descriptor.
The following predicates manipulate files.
see(+File)
The file File becomes the current input stream. File may be a
stream previously opened by see/1 or a filename. If it is a
filename, the following action is taken: If there is a stream opened by
see/1 associated with the same file already, then it becomes the
current input stream. Otherwise, the file File is opened for
input and made the current input stream.
seeing(?FileName)
FileName is unified with the name of the current input file, if it
was opened by see/1, with the current input stream, if it is not
user_input, otherwise with user.
seen
Closes the current input stream, and resets it to user_input.
tell(+File)
The file File becomes the current output stream. File may
be a stream previously opened by tell/1 or a filename. If it is a
filename, the following action is taken: If there is a stream
opened by tell/1 associated with the same file already, then it
becomes the current output stream. Otherwise, the file File
is opened for output and made the current output stream.
telling(?FileName)
FileName is unified with the name of the current output file, if
it was opened by tell/1, with the current output stream, if
it is not user_output, otherwise with user.
told
Closes the current output stream, and resets it to user_output.
Here is an example of a common form of file processing:
process_file(F) :-
seeing(OldInput),
see(F), % Open file F
repeat,
read(T), % Read a term
process_term(T), % Process it
T == end_of_file, % Loop back if not at end of file
!,
seen, % Close the file
see(OldInput).
The above is an example of a repeat loop. Nearly all sensible uses
of repeat/0 follow the above pattern. Note the use of a cut to
terminate the loop.
Arithmetic is performed by built-in predicates which take as arguments arithmetic expressions and evaluate them. An arithmetic expression is a term built from numbers, variables, and functors that represent arithmetic functions. At the time of evaluation, each variable in an arithmetic expression must be bound to a non-variable expression. An expression evaluates to a number, which may be an integer or a float.
The range of integers is [-2^2147483616, 2^2147483616). Thus for
all practical purposes, the range of integers can be considered
infinite.
The range of floats is the one provided by the C double type,
typically [4.9e-324, 1.8e+308] (plus or minus). In case of
overflow or division by zero, iso execution mode will raise an
evaluation error exception. In sicstus execution mode no
exceptions will be raised, instead appropriate infinity values, as
defined by the IEEE standard, will be used.
Only certain functors are permitted in an arithmetic expression.
These are listed below, together with an indication of the functions
they represent. X and Y are assumed to be arithmetic
expressions. Unless stated otherwise, the arguments of an expression
may be any numbers and its value is a float if any of its arguments is
a float, otherwise the value is an integer. Any implicit coercions
are performed with the integer/1 and float/1 functions.
The arithmetic functors are annotated with [ISO], [ISO only], or [SICStus only], with the same meaning as for the built-in predicates; see ISO Compliance.
+(X)
-X [ISO]
X+Y [ISO]
X-Y [ISO]
X*Y [ISO]
X/Y [ISO]
X//Y [ISO]
iso execution mode X and Y have to be integers.
X rem Y [ISO]
integer(X)-integer(Y)*(X//Y). The sign of
a nonzero remainder will thus be the same as that of the dividend.
In iso execution mode X and Y have to be integers.
X mod Y [ISO only]
integer(X)-integer(Y)*floor(X/Y).
The sign of
a nonzero remainder will thus be the same as that of the divisor.
X and Y have to be integers.
X mod Y [SICStus only]
integer(X)
float_integer_part(X) [ISO]
integer(X). In iso execution mode X has
to be a float.
float_fractional_part(X) [ISO]
X -
float_integer_part(X). In iso execution mode X has to be a
float.
float(X) [ISO]
X/\Y [ISO]
iso execution mode X and Y have to be integers.
X\/Y [ISO]
iso execution mode X and Y have to be integers.
X#Y
\(X) [ISO]
iso execution mode X has to be an integer.
X<<Y [ISO]
iso execution mode X and Y have to be integers.
X>>Y [ISO]
iso execution mode X and Y have to be integers.
[X]
"A" behaves within
arithmetic expressions as the integer 65.
SICStus Prolog also includes an extra set of functions listed below. These may not be supported by other Prologs. All trigonometric and transcendental functions take float arguments and deliver float values. The trigonometric functions take arguments or deliver values in radians.
abs(X) [ISO]
sign(X) [ISO]
gcd(X,Y)
iso execution mode X and Y have to be integers.
min(X,Y)
max(X,Y)
msb(X)
integer(log(2,X)).
In iso execution mode X has to be an integer.
round(X) [ISO only]
round(X) [SICStus only]
truncate(X) [ISO only]
truncate(X) [SICStus only]
floor(X) [ISO only]
floor(X) [SICStus only]
ceiling(X) [ISO only]
ceiling(X) [SICStus only]
sin(X) [ISO]
cos(X) [ISO]
tan(X)
cot(X)
sinh(X)
cosh(X)
tanh(X)
coth(X)
asin(X)
acos(X)
atan(X) [ISO]
atan2(X,Y)
acot(X)
acot2(X,Y)
asinh(X)
acosh(X)
atanh(X)
acoth(X)
sqrt(X) [ISO]
log(X) [ISO]
log(Base,X)
exp(X) [ISO]
X ** Y [ISO]
exp(X,Y)
inf [SICStus only]
nan [SICStus only]
Variables in an arithmetic expression which is to be evaluated may be bound to other arithmetic expressions rather than just numbers, e.g.
evaluate(Expression, Answer) :- Answer is Expression. | ?- evaluate(24*9, Ans). Ans = 216 ? yes
Arithmetic expressions, as described above, are just data structures.
If you want one evaluated you must pass it as an argument to one of the
built-in predicates listed below. Note that is/2 only evaluates
one of its arguments, whereas all the comparison predicates evaluate
both of theirs. In the following, X and Y stand for
arithmetic expressions, and Z for some term.
Z is X [ISO]
X, which must be an arithmetic expression, is evaluated and the
result is unified with Z.
X =:= Y [ISO]
The numeric values of X and Y are equal.
X =\= Y [ISO]
The numeric values of X and Y are not equal.
X < Y [ISO]
The numeric value of X is less than the numeric value of Y.
X > Y [ISO]
The numeric value of X is greater than the numeric value of
Y.
X =< Y [ISO]
The numeric value of X is less than or equal to the numeric value
of Y.
X >= Y [ISO]
The numeric value of X is greater than or equal to the numeric value of Y.
These built-in predicates are meta-logical. They treat uninstantiated variables as objects with values which may be compared, and they never instantiate those variables. They should not be used when what you really want is arithmetic comparison (see Arithmetic) or unification.
The predicates make reference to a standard total ordering of terms, which is as follows:
./2.
For example, here is a list of terms in standard order:
[ X, -1.0, -9, 1, fie, foe, X = Y, foe(0,2), fie(1,1,1) ]
NOTE: the standard order is only well-defined for finite (acyclic) terms. There are infinite (cyclic) terms for which no order relation holds. Furthermore, blocking goals (see Procedural) on variables or modifying their attributes (see Attributes) does not preserve their order.
These are the basic predicates for comparison of arbitrary terms:
Term1 == Term2 [ISO]
The terms currently instantiating Term1 and Term2 are literally identical (in particular, variables in equivalent positions in the two terms must be identical). For example, the query
| ?- X == Y.
fails (answers no) because X and Y are distinct
uninstantiated variables. However, the query
| ?- X = Y, X == Y.
succeeds because the first goal unifies the two variables
(see Misc Pred).
Term1 \== Term2 [ISO]
The terms currently instantiating Term1 and Term2
are not literally identical.
Term1 @< Term2 [ISO]
The term Term1 is before the term Term2 in the standard order.
Term1 @> Term2 [ISO]
The term Term1 is after the term Term2 in the standard order.
Term1 @=< Term2 [ISO]
The term Term1 is not after the term Term2 in the standard order.
Term1 @>= Term2 [ISO]
The term Term1 is not before the term Term2 in the standard order.
Some further predicates involving comparison of terms are:
?=(?X,?Y)
X and Y are either syntactically identical or
syntactically non-unifiable.
compare(?Op,?Term1,?Term2)
The result of comparing terms Term1 and Term2 is Op, where the possible values for Op are:
=
<
>
Thus compare(=,Term1,Term2) is equivalent to
Term1 == Term2.
sort(+List1,?List2)
The elements of the list List1 are sorted into the standard order
(see Term Compare) and any identical elements are merged, yielding
the list List2. (The time and space complexity of this operation
is at worst O(N lg N) where N is the length of List1.)
keysort(+List1,?List2)
The list List1 must consist of pairs of the form Key-Value.
These items are sorted into order according to the value of Key,
yielding the list List2. No merging takes place. This predicate
is stable, i.e. if K-A occurs before K-B in the
input, then K-A will occur before K-B in the output. (The
time and space complexity of this operation is at worst O(N lg N)
where N is the length of List1.)
+P , +Q [ISO]
P and Q.
+P ; +Q [ISO]
P or Q.
! [ISO]
See Cut.
\+ +P [ISO]
Fails if the goal P has a solution, and succeeds otherwise. This is not real negation ("P is false"), but a kind of pseudo-negation meaning "P is not provable". It is defined as if by
\+(P) :- P, !, fail. \+(_).
In sicstus execution mode no cuts are allowed in
P. In iso execution mode cuts are allowed in P and
their scope is the goal P.
Remember that with prefix operators such as this one it is necessary to be careful about spaces if the argument starts with a (. For example:
| ?- \+ (P,Q).
is this operator applied to the conjunction of P and Q, but
| ?- \+(P,Q).
would require a predicate \+ /2 for its solution. The prefix
operator can however be written as a functor of one argument; thus
| ?- \+((P,Q)).
is also correct.
+P -> +Q ; +R [ISO]
Analogous to
if P then Q else R
and defined as if by
(P -> Q; R) :- P, !, Q. (P -> Q; R) :- R.
except the scope of any cut in Q or R extends beyond the
if-then-else construct.
In sicstus execution mode no cuts are allowed in
P. In iso execution mode cuts are allowed in P and
their scope is the goal P.
Note that this form of if-then-else only explores the first solution to the goal P.
Note also that the ; is not read as a disjunction operator in this case; instead, it is part of the if-then-else construction.
The precedence of -> is less than that of ; (see Operators), so the expression is read as
;(->(P,Q),R)
+P -> +Q [ISO]
When occurring as a goal, this construction is read as equivalent to
(P -> Q; fail)
if(+P,+Q,+R)
Analogous to
if P then Q else R
but differs from P -> Q ; R in that if(P, Q, R) explores
all solutions to the goal P. There is a small time penalty
for this--if P is known to have only one solution of interest, the
form P -> Q ; R should be preferred.
In sicstus execution mode no cuts are allowed in
P. In iso execution mode cuts are allowed in P and
their scope is the goal P.
once(+P) [ISO]
Finds the first solution, if any, of goal P. Fails if no solutions are found. Will not explore further solutions on backtracking. Equivalent to
(P -> true; fail)
otherwise
true [ISO]
These always succeed. Use of otherwise/0 is discouraged, because
it is not as portable as true/0, and because the former may
suggest a completely different semantics than the latter.
false
fail [ISO]
These always fail. Use of false/0 is discouraged, because it is
not as portable as fail/0, and because the latter has a more
procedural flavor to it.
repeat [ISO]
Generates an infinite sequence of backtracking choices. In sensible code,
repeat/0 is hardly ever used except in repeat loops. A
repeat loop has the structure
Head :-
...
save(OldState),
repeat,
generate(Datum),
action(Datum),
test(Datum),
!,
restore(OldState),
...
The purpose is to repeatedly perform some action on elements which are somehow generated, e.g. by reading them from a stream, until some test becomes true. Usually, generate, action, and test are all determinate. Repeat loops cannot contribute to the logic of the program. They are only meaningful if the action involves side-effects.
The only reason for using repeat loops instead of a more natural
tail-recursive formulation is efficiency: when the test fails
back, the Prolog engine immediately reclaims any working storage
consumed since the call to repeat/0.
call(:Term) [ISO]
incore(:Term) [Obsolescent]
:Term
If Term is instantiated to a term which would be acceptable as the
body of a clause, then the goal call(Term) is executed
exactly as if that term appeared textually in its place, except that any
cut (!) occurring in Term only cuts alternatives in the
execution of Term. Use of incore/1 is not recommended.
If Term is not instantiated as described above, an error message
is printed and the call fails.
call_cleanup(:Goal,:Cleanup)
This construction can be used to ensure that Cleanup is executed as soon as Goal has completed execution, no matter how it finishes. In more detail:
When call_cleanup/2 with a continuation C is called or
backtracked into, first Goal is called or backtracked into. Then
there are four possibilities:
call_cleanup/2 Goal is raised,
Cleanup is executed with continuation
raise_exception(E).
fail.
raise_exception(E).
In a typical use of call_cleanup/2, Cleanup succeeds
deterministically after performing some side-effect; otherwise,
unexpected behavior may result.
Note that the Prolog top level operates as a read-execute-fail loop,
which backtracks into or cuts the query when the user types ; or
<RET> respectively. Also, the predicates halt/0,
abort/0, and reinitialise/0 are implemented in terms of
exceptions. All of these circumstances can trigger the execution of
Cleanup.
The built-in predicates described in this section are used to alter the
control flow to meet exception and error conditions. The equivalent of
a raise_exception/1 is also executed by the built-in predicates
when errors occur.
catch(:ProtectedGoal,?Pattern,:Handler) [ISO]
on_exception(?Pattern,:ProtectedGoal,:Handler)
throw(+Exception) [ISO]
raise_exception(+Exception)
catch/3 is the same as on_exception/3 (but note different
argument order), and throw/1 is the same as
raise_exception/1.
on_exception/3 calls ProtectedGoal. If this succeeds or
fails, so does the call to on_exception/3. If however, during
the execution of ProtectedGoal, there is a call to
raise_exception(Exception), then Exception is copied
and the stack is unwound back to the call to on_exception/3,
whereupon the copy of Exception is unified with Pattern. If
this unification succeeds, then on_exception/3 calls the goal
Handler in order to determine the success or failure of
on_exception/3. Otherwise, the stack keeps unwinding, looking
for an earlier invocation of on_exception/3. Exception may
be any term.
In a development system, any previously uncaught exception is caught and
an appropriate error message is printed before returning to the top
level. In recursive calls to Prolog from C, uncaught exceptions are
returned back to C instead. The printing of these and other messages in
a development system is handled by the predicate print_message/2.
The behavior of this predicate can be overridden by defining
user:portray_message/2, so as to suppress or alter the format of
certain messages. These predicates work as follows:
print_message(+Severity, +Message) [Hookable]
Most messages from the system are printed by calling
this predicate. Before anything is printed, however,
print_message/2 calls user:portray_message/2 with the same
arguments, so as to give the user a means of intercepting the message
before it is actually printed. If user:portray_message/2
succeeds, nothing is printed, otherwise Message is formatted and
printed using the default method. In runtime systems, the message is
printed unformatted.
Message is a term that encodes the message to be printed. The
format of message terms is subject to change, but can be inspected in
the file Bips/msgs.pl of the SICStus Prolog distribution.
Severity is a term denoting the severity of the message, and is
one of:
force(Severity)
user:portray_message/2 hook. This is useful if
user:portray_message/2 has intercepted the message, and now wants
to print a reformatted version of it using print_message/2.
error
warning
informational
user:portray_message/2.
help
portray_message(+Severity, +Message) [Hook]
user:portray_message(+Severity, +Message)
Called by print_message/2 before
printing the message. If this succeeds, the default message for
printing Message is overridden, and nothing more is printed.
The format of the exception raised by the built-in predicates depends on
the execution mode. In iso execution mode the format is
error(ISO_Error, SICStus_Error)
where ISO_Error is the error term prescribed by the ISO Prolog standard, while SICStus_Error is the part defined by the standard to be implementation dependent. In case of SICStus Prolog this is the SICStus error term, which normally contains additional information, such as the goal and the argument number causing the error.
In sicstus execution mode, the SICStus error term is
used when raising an exception in a built-in predicate.
The list below itemizes the error terms, showing the ISO_Error and SICStus_Error form of each one, in that order. Note that the SICStus and ISO error terms do not always belong to the same error class, and that the context and consistency error classes are extensions to the ISO Prolog standard.
The goal part of the error term may optionally have the form
$@(Callable,PC) where PC is an internal
encoding of the line of code containing the culprit goal or one of its
ancestors.
instantiation_error
instantiation_error(Goal,ArgNo)
type_error(TypeName,Culprit)
type_error(Goal,ArgNo,TypeName,Culprit)
domain_error(Domain,Culprit)
domain_error(Goal,ArgNo,Domain,Culprit)
existence_error(ObjectType,Culprit)
existence_error(Goal,ArgNo,ObjectType,Culprit,Reserved)
prolog_flag/3) is set to error, this
error is raised with ArgNo set to 0 when an undefined predicate is
called.
permission_error(Operation,ObjectType,Culprit)
permission_error(Goal,Operation,ObjectType,Culprit,Reserved)
context_error(ContextType,CommandType)
context_error(Goal,ContextType,CommandType)
syntax_error(Message)
syntax_error(Goal,Position,Message,Tokens,AfterError)
read/[1,2] or
assembling a number from its characters with number_chars/2. In
the former case this error is raised only if the syntax_errors
flag (see prolog_flag/3) is set to error.
evaluation_error(ErrorType,Culprit)
evaluation_error(Goal,ArgNo,ErrorType,Culprit)
iso execution mode.
representation_error(ErrorType)
representation_error(Goal,ArgNo,ErrorType)
consistency_error(Culprit1,Culprit2,Message)
consistency_error(Goal,Culprit1,Culprit2,Message)
resource_error(ResourceType)
resource_error(Goal,ResourceType)
system_error
system_error(Message)
It is possible to handle a particular kind of existence errors locally: calls to undefined predicates. This can be done by defining clauses for:
unknown_predicate_handler(+Goal,+Module,-NewGoal) [Hook]
user:unknown_predicate_handler(+Goal,+Module,-NewGoal)
Called as a result of a call
to an undefined predicate. Goal is bound to the goal of the
undefined predicate and Module to the module where the call was
made. If this predicate succeeds, Module:NewGoal is called;
otherwise, the action taken is governed by the unknown
Prolog flag.
The following example shows an auto-loader for library packages:
user:unknown_predicate_handler(Goal, Module, Goal) :-
functor(Goal, Name, Arity),
require(Module:(Name/Arity)).
listing
Lists onto the current output stream all the clauses in the current
interpreted program (in the type-in module; see Module Spec).
Clauses listed onto a file can be consulted back.
listing(:Spec)
Lists all interpreted predicates covered by the generalized predicate spec Spec. For example:
| ?- listing([concatenate/3, reverse, m:go/[2-3], bar:_]).
current_atom(?Atom)
Atom is an atom known to SICStus Prolog.
Can be used to enumerate (through backtracking) all currently
known atoms, and return each one as Atom.
current_predicate(?Name,:Head)
current_predicate(?Name,-Head)
Name is the name of a user defined or library predicate, and
Head is the most general goal for that predicate, possibly
prefixed by a module name. This predicate can be used to enumerate all
user defined or library predicates through backtracking.
current_predicate(?Name/?Arity) [ISO]
Name is the name of a user defined or library predicate, possibly
prefixed by a module name and Arity is its arity. This predicate
can be used to enumerate all user defined or library predicates through
backtracking.
predicate_property(:Head,?Property)
predicate_property(-Head,?Property)
Head is the most general goal for an existing predicate, possibly prefixed by a module name, and Property is a property of that predicate, where the possible properties are
built_in (for built-in predicates) or
compiled or interpreted (for user defined predicates) or
fd_constraint for FD predicates see Defining Primitive Constraints.
dynamic for
predicates that have been declared dynamic
(see Dynamic Declarations),
multifile for
predicates that have been declared multifile
(see Multifile Declarations),
volatile for
predicates that have been declared volatile
(see Volatile Declarations),
(block Term) for predicates that have
block declarations (see Block Declarations),
exported or terms imported_from(ModuleFrom)
for predicates exported or imported from modules (see Module Intro),
(meta_predicate Term) for predicates that have
meta-predicate declarations (see Meta Decl).
This predicate can be used to enumerate all existing predicates and
their properties through backtracking.
current_module(?Module)
Module is a module in the system. It can be used to backtrack
through all modules present in the system.
current_module(?Module, ?File)
Module is the module defined in File.
module(+Module)
The type-in module is set to Module.
set_prolog_flag(+FlagName,+NewValue) [ISO]
prolog_flag(+FlagName,?OldValue,?NewValue)
OldValue is the value of the Prolog flag FlagName, and the new value of FlagName is set to NewValue. The possible Prolog flag names and values are:
agc_margin
argv
% sicstus -a hello world 2001
then the value will be [hello,world,'2001'].
bounded [ISO]
false, indicating that the domain of
integers is practically unbounded.
char_conversion [ISO]
on, unquoted characters in terms and programs
read in will be converted, as specified by previous invocations of
char_conversion/2. If the flag is off no conversion will
take place. The default value is on.
compiling
compile/1 and fcompile/1
operate (see Load Intro).
compactcode
fastcode
profiledcode
debugcode
debugging
debug/0, nodebug/0,
trace/0, notrace/0, zip/0, nozip/0
(see Debug Pred). The flag describes
the mode the debugger is in, or is required to be switched to:
trace
debug
zip
off
debug [ISO]
debug, prescribed by the ISO Prolog standard, is a
simplified form of the debugging flag:
off
on
(The flags debugging and debug are not available in
runtime systems.)
double_quotes [ISO]
codes
chars
atom
character_escapes
on or off. If this flag is on,
a backslash occurring inside integers in 0' notation or inside
quoted atoms or strings has special meaning, and indicates the start of
an escape sequence (see Escape Sequences). This flag is relevant
when reading as well as when writing terms, and is initially on.
debugger_print_options
write_term/3 (see Term I/O),
to be used in the debugger's messages. Not available in runtime systems.
The initial value is
[quoted(true),numbervars(true),portrayed(true),max_depth(10)].
discontiguous_warnings
on or off. Enable or disable warning messages when
clauses are not together in source files. Initially on. (This
warning is always disabled in runtime systems.)
fileerrors
on or off. Enables or disables raising of file error
exceptions. Equivalent to fileerrors/0 and
nofileerrors/0, respectively (see Stream Pred). Initially
on (enabled).
gc
on or off. Enables or disables garbage collection of the
global stack. Initially on (enabled).
gc_margin
gc_trace
verbose
terse
off
host_type
'x86-linux-glibc2.1' or
'sparc-solaris-5.6'.
integer_rounding_function [ISO]
toward_zero, indicating that the
integer division ((//)/2) and integer remainder (rem/2)
arithmetic functions use rounding toward zero; see Arithmetic.
language
iso or sicstus. Selects the execution mode specified.
max_arity [ISO]
max_integer [ISO]
prolog_flag/3 and current_prolog_flag/2 will fail, when
accessing this flag.
min_integer [ISO]
prolog_flag/3 and current_prolog_flag/2 will fail, when
accessing this flag.
redefine_warnings
on or off. Enable or disable warning messages when :
.po file is being loaded.
Initially on. (This warning is always disabled in runtime
systems.)
single_var_warnings
on or off. Enable or disable warning messages when a
clause containing variables not beginning with _ occurring once
only is compiled or consulted. Initially on.
source_info
emacs or on or off.
If not off while source code is being loaded, information about line
numbers and filenames are stored with the loaded code.
If the value is on
while debugging, this information is used to print the source code location
while prompting for a debugger command.
If the value is on
while printing an uncaught error exception message,
the information is used to print the source code location
of the culprit goal or one of its ancestors, as far as it can be determined.
If the value is emacs in any of these cases, the appropriate
line of code is instead highlighted, and no extra text is printed.
The value is off initially, and that is its only available value
in runtime systems.
syntax_errors
read/[1,2].
dec10
error
fail
quiet
system_type
development in development
systems and runtime in runtime systems.
toplevel_print_options
write_term/3 (see Term I/O),
to be used when the top level displays variable bindings, answer
constraints, and uncaught exceptions. Not available in runtime systems.
The initial value is
[quoted(true),numbervars(true),portrayed(true),max_depth(10)].
typein_module
module/1.
unknown [ISO]
unknown/2 (see Debug Pred).
trace
fail
warning
error
user_input
user_input and SP_stdin. It is initially set to a stream
connected to UNIX stdin.
user_output
user_output and SP_stdout. It is initially set to a stream
connected to UNIX stdout.
user_error
user_error and SP_stderr. It is initially set to a stream
connected to UNIX stderr.
version
'SICStus 3 #0: Wed Mar 15 12:29:29 MET 1995'.
wcx
prolog_flag(?FlagName,?Value)
current_prolog_flag(?FlagName,?Value) [ISO]
Value is the current value of the Prolog flag
FlagName. Can be used to enumerate all Prolog flags and their
values by backtracking.
prolog_load_context(?Key,?Value)
This predicate gives access to context variables during compilation and loading of Prolog files. It unifies Value with the value of the variable identified by Key. Possible keys are:
source
.po or .ql file, the corresponding source file name is returned.
file
source key. In included files this is the absolute path
name of the file being included.
directory
module
user:term_expansion/[2,4] and need to access the
source module at compile time.
stream
term_position
statistics
Displays on the standard error stream statistics relating to memory
usage, run time, garbage collection of the global stack and stack
shifts.
statistics(?Key,?Value)
This allows a program to gather various execution statistics. For each of the possible keys Key, Value is unified with a list of values, as follows:
global_stack
[size used,free]local_stack
[size used,free]trail
[size used,free]choice
[size used,free]core
memory
[size used,0]heap
program
[size used,0]runtime
[since start of Prolog,since previous statistics]
These refer to CPU time used while executing, excluding time spent
garbage collecting, stack shifting, or in system calls.
walltime
[since start of Prolog,since previous statistics]
These refer to absolute time elapsed.
garbage_collection
[no. of GCs,bytes freed,time spent]
stack_shifts
[no. of local shifts,no. of trail shifts,time
spent]
atoms
[no. of atoms,bytes used,bytes free]
atom_garbage_collection
[no. of AGCs,bytes freed,time spent]
Times are in milliseconds, sizes of areas in bytes.
trimcore
Reclaims any dead clauses and predicates, defragmentizes Prolog's memory, and attempts to return any unused memory to the operating system. It is called automatically at every top level query.
The predicates in this section are meta-logical and perform operations that require reasoning about the current instantiation of terms or decomposing terms into their constituents. Such operations cannot be expressed using predicate definitions with a finite number of clauses.
var(?X) [ISO]
Tests whether X is currently uninstantiated (var is short
for variable). An uninstantiated variable is one which has not been
bound to anything, except possibly another uninstantiated variable.
Note that a compound term with some components which are uninstantiated
is not itself considered to be uninstantiated. Thus the query
| ?- var(foo(X, Y)).
always fails, despite the fact that X and Y are
uninstantiated.
nonvar(?X) [ISO]
Tests whether X is currently instantiated. This is the opposite of
var/1.
ground(?X)
Tests whether X is completely instantiated, i.e. free of
unbound variables. In this context, mutable terms are treated as
nonground, so as to make ground/1 a monotone predicate.
atom(?X) [ISO]
Checks that X is currently instantiated to an atom (i.e. a
non-variable term of arity 0, other than a number).
float(?X) [ISO]
Checks that X is currently instantiated to a float.
integer(?X) [ISO]
Checks that X is currently instantiated to an integer.
number(?X) [ISO]
Checks that X is currently instantiated to a number.
atomic(?X) [ISO]
Checks that X is currently instantiated to an atom or number.
simple(?X)
Checks that X is currently uninstantiated or instantiated to an
atom or number.
compound(?X) [ISO]
Checks that X is currently instantiated to a compound term.
callable(?X)
Checks that X is currently instantiated to a term valid as a goal
i.e. a compound term or an atom.
is_mutable(?X)
Checks that X is currently instantiated to a mutable term
(see Modify Term).
functor(+Term,?Name,?Arity) [ISO]
functor(?Term,+Name,+Arity) [ISO]
The principal functor of term Term has name Name and arity
Arity, where Name is either an atom or, provided Arity
is 0, a number. Initially, either Term must be instantiated, or
Name and Arity must be instantiated to, respectively, either
an atom and an integer in [0,255] or an atomic term and 0. In the case
where Term is initially uninstantiated, the result of the call is
to instantiate Term to the most general term having the principal
functor indicated.
arg(+ArgNo,+Term,?Arg) [ISO]
Arg is the argument ArgNo of the compound term Term. The
arguments are numbered from 1 upwards,
ArgNo must be instantiated to a positive integer and
Term to a compound term.
+Term =.. ?List [ISO]
?Term =.. +List [ISO]
List is a list whose head is the atom corresponding to the principal functor of Term, and whose tail is a list of the arguments of Term. e.g.
| ?- product(0, n, n-1) =.. L. L = [product,0,n,n-1] | ?- n-1 =.. L. L = [-,n,1] | ?- product =.. L. L = [product]
If Term is uninstantiated, then List must be instantiated
either to a list of determinate length whose head is an atom, or to a
list of length 1 whose head is a number. Note that this predicate is
not strictly necessary, since its functionality can be provided by
arg/3 and functor/3, and using the latter two is usually
more efficient.
name(+Const,?CharList) [Obsolescent]
name(?Const,+CharList) [Obsolescent]
If Const is an atom or number, CharList is a list of the character codes of the characters comprising the name of Const. e.g.
| ?- name(product, L).
L = [112,114,111,100,117,99,116]
| ?- name(product, "product").
| ?- name(1976, L).
L = [49,57,55,54]
| ?- name('1976', L).
L = [49,57,55,54]
| ?- name((:-), L).
L = [58,45]
If Const is uninstantiated, CharList must be instantiated to a list of character codes. If CharList can be interpreted as a number, Const is unified with that number, otherwise with the atom whose name is CharList. E.g.
| ?- name(X, [58,45]). X = :- | ?- name(X, ":-"). X = :- | ?- name(X, [49,50,51]). X = 123
Note that there atoms are for which
name(Const,CharList) is true, but which will not be
constructed if name/2 is called with Const uninstantiated.
One such atom is the atom '1976'. It is recommended that new
programs use atom_codes/2 or number_codes/2, as these
predicates do not have this inconsistency.
atom_codes(+Const,?CodeList) [ISO]
atom_codes(?Const,+CodeList) [ISO]
The same as name(Const,CodeList), but Const
is constrained to be an atom.
number_codes(+Const,?CodeList) [ISO]
number_codes(?Const,+CodeList) [ISO]
The same as name(Const,CodeList), but Const is
constrained to be a number.
atom_chars(+Const,?CharList) [ISO only]
atom_chars(?Const,+CharList) [ISO only]
Analogous to atom_codes/2, but CharList is a list of
one-char atoms, rather than of character codes.
atom_chars(+Const,?CodeList) [SICStus only]
atom_chars(?Const,+CodeList) [SICStus only]
The same as atom_codes(Const,CharList).
number_chars(+Const,?CharList) [ISO only]
number_chars(?Const,+CharList) [ISO only]
Analogous to number_codes/2, but CharList is a list of
one-char atoms, rather than of character codes.
number_chars(+Const,?CodeList) [SICStus only]
number_chars(?Const,+CodeList) [SICStus only]
The same as number_codes(Const,CharList).
char_code(+Char,?Code) [ISO]
char_code(?Char,+Code) [ISO]
Code is the character code of the one-char atom Char.
atom_length(+Atom,?Length) [ISO]
Length is the number of characters of the atom Atom.
atom_concat(+Atom1,+Atom2,?Atom12) [ISO]
atom_concat(?Atom1,?Atom2,+Atom12) [ISO]
The characters of the atom Atom1 concatenated with those of Atom2 are the same as the characters of atom Atom12. If the last argument is instantiated, nondeterministically enumerates all possible atom-pairs that concatenate to the given atom, e.g.
| ?- atom_concat(A, B, 'ab'). A = '', B = ab ? ; A = a, B = b ? ; A = ab, B = '' ? ; no
sub_atom(+Atom,?Before,?Length,?After,?SubAtom) [ISO]
The characters of SubAtom form a sublist of the characters of Atom, such that the number of characters preceding SubAtom is Before, the number of characters after SubAtom is After, and the length of SubAtom is Length. Capable of nondeterministically enumerating all sub-atoms and their all possible placements, e.g.
| ?- sub_atom(abrakadabra, Before, _, After, ab). After = 9, Before = 0 ? ; After = 2, Before = 7 ? ; no
copy_term(?Term,?CopyOfTerm) [ISO]
CopyOfTerm is a renaming of Term, such that brand new variables have been substituted for all variables in Term. If any of the variables of Term have goals blocked on them, the copied variables will have copies of the goals blocked on them as well. Similarly, independent copies are substituted for any mutable terms in term. It behaves as if defined by:
copy_term(X, Y) :-
assert('copy of'(X)),
retract('copy of'(Y)).
The implementation of copy_term/2 conserves space by not copying
ground subterms.
One of the tenets of logic programming is that terms are immutable objects of the Herbrand universe, and the only sense in which they can be modified is by means of instantiating non-ground parts. There are, however, algorithms where destructive assignment is essential for performance. Although alien to the ideals of logic programming, this feature can be defended on practical grounds.
SICStus Prolog provides an abstract datatype and three operations for efficient backtrackable destructive assignment. In other words, any destructive assignments are transparently undone on backtracking. Modifications that are intended to survive backtracking must be done by asserting or retracting dynamic program clauses instead. Unlike previous releases of SICStus Prolog, destructive assignment of arbitrary terms is not allowed.
A mutable term is represented as a compound terms with a reserved
functor: '$mutable'(Value,Timestamp) where Value
is the current value and Timestamp is reserved for bookkeeping
purposes [Aggoun & Beldiceanu 90].
Any copy of a mutable term created by copy_term/2, assert,
retract, an internal database predicate, or an all solutions
predicate, is an independent copy of the original mutable term. Any
destructive assignment done to one of the copies will not affect the
other copy.
The following operations are provided:
create_mutable(+Datum,-Mutable)
Mutable is a new mutable term with initial value Datum.
Datum must not be an unbound variable.
get_mutable(?Datum,+Mutable)
Datum is the current value of the mutable term Mutable.
update_mutable(+Datum,+Mutable)
Updates the current value of the mutable term Mutable to become
Datum. Datum must not be an unbound variable.
is_mutable(?Mutable)
Checks that Mutable is currently instantiated to a mutable term.
NOTE: the effect of unifying two mutables is undefined.
The predicates defined in this section allow modification of dynamic predicates. Dynamic clauses can be added (asserted) or removed from the program (retracted).
For these predicates, the argument Head must be instantiated to an
atom or a compound term, with an optional module prefix. The argument
Clause must be instantiated either to a term Head :-
Body or, if the body part is empty, to Head, with an
optional module prefix. An empty body part is represented as
true.
Note that a term Head :- Body must be enclosed in
parentheses when it occurs as an argument of a compound term, as
:- is a standard infix operator with precedence greater than 1000
(see Operators), e.g.:
| ?- assert((Head :- Body)).
Like recorded terms (see Database), the clauses of dynamic predicates have a unique implementation-defined identifier. Some of the predicates below have an additional argument which is this identifier. This identifier makes it possible to access clauses directly instead of requiring a normal database (hash-table) lookup.
assert(:Clause)
assert(:Clause,-Ref)
The current instance of Clause is interpreted as a clause and is
added to the current interpreted program. The predicate concerned must
currently be dynamic or undefined and the position of the new clause
within it is implementation-defined. Ref is a database reference
to the asserted clause. Any uninstantiated variables in the
Clause will be replaced by new private variables, along with
copies of any subgoals blocked on these variables (see Procedural).
asserta(:Clause) [ISO]
asserta(:Clause,-Ref)
Like assert/2, except that the new clause becomes the
first clause for the predicate concerned.
assertz(:Clause) [ISO]
assertz(:Clause,-Ref)
Like assert/2, except that the new clause becomes the last
clause for the predicate concerned.
clause(:Head,?Body) [ISO]
clause(:Head,?Body,?Ref)
clause(?Head,?Body,+Ref)
The clause (Head :- Body) exists in the current
interpreted program, and its database reference is Ref. The
predicate concerned must currently be dynamic. At the time of call,
either Ref must be instantiated, or Head must be
instantiated to an atom or a compound term. Thus clause/3 can
have two different modes of use.
retract(:Clause) [ISO]
The first clause in the current interpreted program that matches
Clause is erased. The predicate concerned must currently be
dynamic. retract/1 may be used in a non-determinate fashion,
i.e. it will successively retract clauses matching the argument through
backtracking. If reactivated by backtracking, invocations of the
predicate whose clauses are being retracted will proceed unaffected by
the retracts. This is also true for invocations of clause/[2,3] for
the same predicate. The space occupied by a retracted clause will be
recovered when instances of the clause are no longer in use.
retractall(:Head)
Erases all clauses whose head matches Head, where Head must be instantiated to an atom or a compound term. The predicate concerned must currently be dynamic. The predicate definition is retained.
NOTE: all predicates mentioned above first look for a predicate that is visible in the module in which the call textually appears. If no predicate is found, a new dynamic predicate (with no clauses) is created automatically. It is recommended to declare as dynamic predicates for which clauses will be asserted.
abolish(:Spec) [ISO]
abolish(:Name,+Arity)
Abolishes the procedures specified by the generalized predicate
spec Spec or Name/Arity. Name may be
prefixed by a module name (see Module Spec). In iso
execution mode only dynamic predicates can be abolished. In
sicstus execution mode only built-in predicates cannot be
abolished, the user-defined ones always can be, even when static.
erase(+Ref)
The dynamic clause or recorded term (see Database) whose
database reference is Ref is effectively erased
from the internal database or interpreted program.
instance(+Ref,?Term)
A (most general) instance of the dynamic clause or recorded term whose database reference is Ref is unified with Term.
The predicates described in this section were introduced in early implementations of Prolog to provide efficient means of performing operations on large quantities of data. The introduction of indexed dynamic predicates have rendered these predicates obsolete, and the sole purpose of providing them is to support existing code. There is no reason whatsoever to use them in new code.
These predicates store arbitrary terms in the database without interfering with the clauses which make up the program. The terms which are stored in this way can subsequently be retrieved via the key on which they were stored. Many terms may be stored on the same key, and they can be individually accessed by pattern matching. Alternatively, access can be achieved via a special identifier which uniquely identifies each recorded term and which is returned when the term is stored.
recorded(?Key,?Term,?Ref) [Obsolescent]
The internal database is searched for terms recorded under the key
Key. These terms are successively unified with Term in the
order they occur in the database. At the same time, Ref is
unified with the database reference to the recorded item. If the
key is instantiated to a compound term, only its principal functor is
significant. If the key is uninstantiated, all terms in the database
are successively unified with Term in the order they occur.
recorda(+Key,?Term,-Ref) [Obsolescent]
The term Term is recorded in the internal database as the first
item for the key Key, where Ref is its
database reference. The key must be given, and only its
principal functor is significant. Any uninstantiated variables in the
Term will be replaced by new private variables, along with copies
of any subgoals blocked on these variables (see Procedural).
recordz(+Key,?Term,-Ref) [Obsolescent]
Like recorda/3, except that the new term becomes the last
item for the key Key.
current_key(?KeyName,?KeyTerm) [Obsolescent]
KeyTerm is the most general form of the key for a currently recorded term, and KeyName is the name of that key. This predicate can be used to enumerate in undefined order all keys for currently recorded terms through backtracking.
The predicates described in this section store arbitrary terms in a
per-module repository known as the "blackboard". The main purpose of
the blackboard was initially to provide a means for communication between branches
executing in parallel, but the blackboard works equally well during
sequential execution. The blackboard implements a mapping from keys to
values. Keys are restricted to being atoms or integers in the range
[-33554432, 33554431], whereas values are arbitrary
terms. In contrast to the predicates described in the previous
sections, a given key can map to at most a single term.
Each Prolog module maintains its own blackboard, so as to avoid name clashes if different modules happen to use the same keys. The "key" arguments of these predicates are subject to module name expansion, so the module name does not have to be explicitly given unless multiple Prolog modules are supposed to share a single blackboard.
The predicates below implement atomic blackboard actions.
bb_put(:Key, +Term)
A copy of Term is stored under Key. Any previous term stored under
the same Key is simply deleted.
bb_get(:Key, ?Term)
If a term is currently stored under Key,
a copy of it is unified with Term. Otherwise, bb_get/2
silently fails.
bb_delete(:Key, ?Term)
If a term is currently stored under Key, the term is deleted, and
a copy of it is unified with Term. Otherwise,
bb_delete/2 silently fails.
bb_update(:Key, ?OldTerm, ?NewTerm)
If a term is currently stored under Key and unifies with
OldTerm, the term is replaced by a copy of NewTerm. Otherwise,
bb_update/3 silently fails. This predicate provides an atomic
swap operation.
The following example illustrates how these primitives may be used to
implement a "maxof" predicate that finds the maximum value computed
by some non-determinate goal, which may execute in parallel.
We use a single key max. Note the technique of using
bb_update/3 in a repeat-fail loop, since other execution
branches may be competing for updating the value, and we only want
to store a new value if it is greater than the old value.
We assume that Goal does not produce any "false" solutions that would be eliminated by cuts in a sequential execution. Thus, Goal may need to include redundant checks to ensure that its solutions are valid, as discussed above.
maxof(Value, Goal, _) :-
bb_put(max, -1), % initialize max-so-far
call(Goal),
update_max(Value),
fail.
maxof(_, _, Max) :-
bb_delete(max, Max),
Max > 1.
update_max(New):-
repeat,
bb_get(max, Old),
compare(C, Old, New),
update_max(C, Old, New), !.
update_max(<, Old, New) :- bb_update(max, Old, New).
update_max(=, _, _).
update_max(>, _, _).
When there are many solutions to a problem, and when all those solutions are required to be collected together, this can be achieved by repeatedly backtracking and gradually building up a list of the solutions. The following built-in predicates are provided to automate this process.
Note that the Goal argument to the predicates listed below is
called as if by call/1 at runtime. Thus if Goal is complex
and if performance is an issue, define an auxiliary predicate which
can then be compiled, and let Goal call it.
setof(?Template,:Goal,?Set) [ISO]
Read this as "Set is the set of all instances of Template
such that Goal is satisfied, where that set is non-empty". The
term Goal specifies a goal or goals as in call(Goal)
(see Control). Set is a set of terms represented as a list of
those terms, without duplicates, in the standard order for terms
(see Term Compare). If there are no instances of Template
such that Goal is satisfied then the predicate fails.
The variables appearing in the term Template should not appear anywhere else in the clause except within the term Goal. Obviously, the set to be enumerated should be finite, and should be enumerable by Prolog in finite time. It is possible for the provable instances to contain variables, but in this case the list Set will only provide an imperfect representation of what is in reality an infinite set.
If there are uninstantiated variables in Goal which do not also appear in Template, then a call to this built-in predicate may backtrack, generating alternative values for Set corresponding to different instantiations of the free variables of Goal. (It is to cater for such usage that the set Set is constrained to be non-empty.) Two instantiations are different iff no renaming of variables can make them literally identical. For example, given the clauses:
likes(bill, cider). likes(dick, beer). likes(harry, beer). likes(jan, cider). likes(tom, beer). likes(tom, cider).
the query
| ?- setof(X, likes(X,Y), S).
might produce two alternative solutions via backtracking:
S = [dick,harry,tom], Y = beer ? ; S = [bill,jan,tom], Y = cider ? ;
The query:
| ?- setof((Y,S), setof(X, likes(X,Y), S), SS).
would then produce:
SS = [(beer,[dick,harry,tom]),(cider,[bill,jan,tom])]
Variables occurring in Goal will not be treated as free if they are explicitly bound within Goal by an existential quantifier. An existential quantification is written:
Y^Q
meaning "there exists a Y such that Q is true", where Y is some Prolog variable.
For example:
| ?- setof(X, Y^(likes(X,Y)), S).
would produce the single result:
S = [bill,dick,harry,jan,tom]
in contrast to the earlier example.
Note that in iso execution mode, only outermost existential
quantification is accepted, i.e. if the Goal argument is of form
V1 ^ ... ^ N ^ SubGoal. In sicstus
execution mode existential quantification is handled also deeper inside
Goal.
bagof(?Template,:Goal,?Bag) [ISO]
This is exactly the same as setof/3 except that the list (or
alternative lists) returned will not be ordered, and may contain
duplicates. The effect of this relaxation is to save a call to
sort/2, which is invoked by setof/3 to return an ordered
list.
?X^:P
The all solution predicates recognize this as meaning "there exists an
X such that P is true", and treats it as equivalent to
P (see Control). The use of this explicit existential
quantifier outside the setof/3 and bagof/3 constructs is
superfluous and discouraged.
findall(?Template,:Goal,?Bag) [ISO]
Bag is a list of instances of Template in all proofs of
Goal found by Prolog. The order of the list corresponds to the
order in which the proofs are found. The list may be empty and all
variables are taken as being existentially quantified. This means that
each invocation of findall/3 succeeds exactly once, and
that no variables in Goal get bound. Avoiding the management of
universally quantified variables can save considerable time and space.
findall(?Template,:Goal,?Bag,?Remainder)
Same as findall/3, except Bag is the list of solution
instances appended with Remainder, which is typically unbound.
The coroutining facility can be accessed by a number of built-in predicates. This makes it possible to use coroutines in a dynamic way, without having to rely on block declarations:
when(+Condition,:Goal)
Blocks Goal until the Condition is true, where Condition is a Prolog goal with the restricted syntax:
nonvar(X)
ground(X)
?=(X,Y)
Condition,Condition
Condition;Condition
For example:
| ?- when(((nonvar(X);?=(X,Y)),ground(T)), process(X,Y,T)).
freeze(?X,:Goal)
Blocks Goal until nonvar(X) (see Meta Logic)
holds. This is defined as if by:
freeze(X, Goal) :- when(nonvar(X), Goal).
or
:- block freeze(-, ?). freeze(_, Goal) :- Goal.
frozen(-Var,?Goal)
If some goal is blocked on the variable Var, or Var has
attributes that can be interpreted as a goal (see Attributes),
then that goal is unified with Goal. If no goals are blocked,
Goal is unified with the atom true. If more than one
goal is blocked, a conjunction is unified with Goal.
dif(?X,?Y)
Constrains X and Y to represent different terms i.e. to be
non-unifiable. Calls to dif/2 either succeed, fail, or are
blocked depending on whether X and Y are sufficiently
instantiated. It is defined as if by:
dif(X, Y) :- when(?=(X,Y), X\==Y).
call_residue(:Goal,?Residue)
The Goal is executed as if by call/1. If after the
execution there are still some subgoals of Goal that are blocked
on some variables, then Residue is unified with a list of
VariableSet-Goal pairs, and those subgoals are no longer blocked
on any variables. Otherwise, Residue is unified
with the empty list [].
VariableSet is a set of variables such that when any of the variables is bound, Goal gets unblocked. Usually, a goal is blocked on a single variable, in which case VariableSet is a singleton.
Goal is an ordinary goal, sometimes module prefixed. For example:
| ?- call_residue((dif(X,f(Y)), X=f(Z)), Res). X = f(Z), Res = [[Y,Z]-(prolog:dif(f(Z),f(Y)))]
Debugging predicates are not available in runtime systems.
unknown(?OldState,?NewState)
OldState is the current state of the "Action on unknown
predicates" flag, and sets the flag to NewState. This flag
determines whether or not the system is to catch calls to undefined
predicates (see Undefined Predicates), when
user:unknown_predicate_handler/3 cannot handle the goal.
The possible states of the
flag are:
trace
fail
warning
error
debug
The debugger is switched on in leap mode. See Basic Debug.
trace
The debugger is switched on in creep mode. See Basic Debug.
zip
The debugger is switched on in zip mode. See Basic Debug.
nodebug
notrace
nozip
The debugger is switched off. See Basic Debug.
leash(+Mode)
Leashing Mode is set to Mode. See Basic Debug.
spy :Spec
Plain spypoints are placed on all the predicates given by Spec.
See Plain Spypoint.
spy(:Spec, :Conditions)
Spypoints with condition Conditions are placed on all the
predicates given by Spec.
See Breakpoint Predicates.
nospy :Spec
All spypoints (plain and conditional) are removed from all the
predicates given by Spec.
See Plain Spypoint.
nospyall
Removes all the spypoints (including the generic ones) that have been
set.
debugging
Displays information about the debugger. See Basic Debug.
add_breakpoint(:Conditions, ?BID)
Creates a breakpoint with Conditions and with identifier BID.
See Breakpoint Predicates.
current_breakpoint(:Conditions, ?BID, ?Status, ?Kind)
There is a breakpoint with conditions Conditions, identifier
BID, enabledness Status, and kind Kind.
See Breakpoint Predicates.
remove_breakpoints(+BIDs)
disable_breakpoints(+BIDs)
enable_breakpoints(+BIDs)
Removes, disables or enables the breakpoints specified by BIDs.
See Breakpoint Predicates.
execution_state(:Tests)
Tests are satisfied in the current state of the execution.
execution_state(+FocusConditions, :Tests)
Tests are satisfied in the state of the execution pointed to by
FocusConditions.
debugger_command_hook(+Char,?Actions) [Hook]
user:debugger_command_hook(+Char,?Actions)
Allows the interactive debugger to be extended with user-defined
commands. See Debug Commands.
error_exception(+Exception) [Hook]
user:error_exception(+Exception)
Tells the debugger to enter trace mode on certain exceptions. See Breakpoints.
Execution profiling is a common aid for improving software performance. The SICStus Prolog compiler has the capability of instrumenting compiled code with counters which are initially zero and incremented whenever the flow of control passes a given point in the compiled code. This way the number of calls, backtracks, choicepoints created, etc., can be counted for the instrumented predicates, and an estimate of the time spent in individual clauses and disjuncts can be calculated.
Gauge is a graphical user interface for inspecting execution profiles. It is available as a library module (see Gauge Intro).
The original version of the profiling package was written by M.M. Gorlick and C.F. Kesselman at the Aerospace Corporation [Gorlick & Kesselman 87].
Only compiled code can be instrumented. To get an execution profile of a program, the compiler must first be told to produce instrumented code. This is done by issuing the query:
| ?- prolog_flag(compiling,_,profiledcode).
after which the program to be analyzed can be compiled as usual. Any
new compiled code will be instrumented while the compilation mode flag
has the value profiledcode.
The profiling data is generated by simply running the program. The
predicate profile_data/4 (see below) makes available a selection
of the data as a Prolog term. The predicate profile_reset/1
zeroes the profiling counters for a selection of the currently
instrumented predicates.
profile_data(:Spec,?Selection,?Resolution,-Data)
Data is profiling data collected from the predicates covered by the generalized predicate spec Spec.
The Selection argument determines the kind of profiling data to be collected. If uninstantiated, the predicate will backtrack over its possible values, which are:
calls
backtracks
choice_points
shallow_fails
deep_fails
execution_time
The Resolution argument determines the level of resolution of the profiling data to be collected. If uninstantiated, the predicate will backtrack over its possible values, which are:
predicate
Module:PredName-Count, where
Count is a sum of the corresponding counts per clause.
clause
Module:ClauseName-Count, where
Count includes counts for any disjunctions occurring inside that
clause. Note, however, that the selections calls and
backtracks do not include counts for disjunctions.
all
Module:InternalName-Count.
This is the finest resolution level, counting individual clauses and
disjuncts.
Above, PredName is a predicate spec, ClauseName is a compound
term PredName/ClauseNumber, and InternalName is
either
ClauseName--corresponding to a clause, or
(ClauseName-DisjNo)/Arity/AltNo--corresponding
to a disjunct.
profile_reset(:Spec)
Zeroes all counters for predicates covered by the generalized predicate spec Spec.
?X = ?Y [ISO]
Defined as if by the clause Z=Z.; i.e. X and Y are
unified.
?X \= ?Y [ISO]
The same as \+ X = Y; i.e. X and Y are
not unifiable.
unify_with_occurs_check(?X, ?Y) [ISO]
True if X and Y unify to a finite (acyclic) term.
Runs in almost linear time.
length(?List,?Length)
If List is instantiated to a list of determinate length, then Length will be unified with this length.
If List is of indeterminate length and Length is instantiated to an integer, then List will be unified with a list of length Length. The list elements are unique variables.
If Length is unbound then Length will be unified with all
possible lengths of List.
numbervars(?Term,+N,?M)
Unifies each of the variables in term Term with a special term, so
that write(Term) (or writeq(Term))
(see Term I/O) prints those variables as (A + (i mod
26))(i/26) where i ranges from N to M-1.
N must be instantiated to an integer. If it is 0 you get the
variable names A, B, ..., Z, A1, B1, etc. This predicate is used by
listing/[0,1] (see State Info).
halt [ISO]
Causes Prolog to exit back to the shell. (In recursive calls to Prolog
from C, this predicate will return back to C instead.)
halt(+Code) [ISO]
Causes the Prolog process to immediately exit back to the shell with the
integer return code Code, even if it occurs in a recursive call from C.
op(+Precedence,+Type,+Name) [ISO]
Declares the atom Name to be an operator of the stated Type
and Precedence (see Operators). Name may also be a list
of atoms in which case all of them are declared to be operators. If
Precedence is 0 then the operator properties of Name (if
any) are cancelled.
current_op(?Precedence,?Type,?Op) [ISO]
The atom Op is currently an operator of type Type and
precedence Precedence. Neither Op nor the other arguments
need be instantiated at the time of the call; i.e. this predicate can
be used to generate as well as to test.
break
Invokes a recursive top-level. See Nested.
(This predicate is not available in runtime systems.)
abort
Aborts the current execution. See Nested. (In recursive calls to Prolog
from C, this predicate will return back to C instead.)
save_files(+SourceFiles, +File)
Any module declarations, predicates, multifile clauses, or
directives encountered in SourceFiles are saved in object format into
the file File. Source file information as provided by
source_file/[1,2] for the relevant predicates and modules is also
saved.
If File does not have an explicit suffix,
the suffix .po will be appended to it.
SourceFiles should denote a single file or a list of files.
File can later be loaded by load_files/[1,2], at which time
any saved directives will be re-executed.
If any of the SourceFiles declares a module, File too will
behave as a module-file and export the predicates listed in the first module
declaration encountered in SourceFiles.
See Saving.
save_modules(+Modules, +File)
The module declarations, predicates, multifile clauses and initializations belonging to Modules are saved in object format into the file File. Source file information and arbitrary directives are not saved.
If File does not have an explicit suffix, the suffix .po
will be appended to it. Modules should denote a single module or
a list of modules. File can later be loaded by
load_files/[1,2] and will behave as a module-file and export any
predicates exported by the first module in Modules.
See Saving.
save_predicates(:Spec, +File)
The predicates specified by the generalized predicate spec Spec are saved in object format into the file File. Source file information and directives are not saved. Thus, this predicate is intended for saving data represented as tables of dynamic facts, not for saving static code.
If File does not have an explicit suffix, the suffix .po
will be appended to it. File can later be loaded by
load_files/[1,2]. See Saving.
save_program(+File)
save_program(+File, :Goal)
The system saves the program state into file File.
When the program state is restored, Goal is executed.
Goal defaults to true.
See Saving.
restore(+File)
The system is returned to the program state previously saved to file
File with start-up goal Goal. restore/1 may succeed,
fail or raise an exception depending on Goal. See Saving.
reinitialise
This predicate can be used to force the reinitialization behavior to take place at any time. When SICStus Prolog is reinitialized it:
SP_reinit_hook
(see Hooks).
version/0 to write banners.
garbage_collect
Performs a garbage collection of the global stack immediately.
garbage_collect_atoms
Performs a garbage collection of the atoms immediately.
gc
Enables garbage collection of the global stack (the default).
nogc
Disables garbage collection of the global stack.
prompt(?Old,?New)
The sequence of characters (prompt) which indicates that the system is
waiting for user input is represented as an atom, and unified with
Old; the atom bound to New specifies the new prompt. In
particular, the goal prompt(X, X) unifies the current prompt with
X, without changing it. Note that this predicate only affects the
prompt given when a user's program is trying to read from the standard input stream
(e.g. by calling read/1). Note also that the prompt is reset to
the default |: on return to top-level.
version
Displays the introductory messages for all the component parts of the current system.
Prolog will display its own introductory message when initially run and
on reinitialization by calling version/0. If this message is
required at some other time it can be obtained using this predicate
which displays a list of introductory messages; initially this list
comprises only one message (Prolog's), but you can add more messages
using version/1. (This predicate is not available in runtime
systems.)
version(+Message)
Appends Message to the end of the message list which is output by
version/0. Message must be an atom.
(This predicate is not available in runtime systems.)
The idea of this message list is that, as systems are constructed on top
of other systems, each can add its own identification to the message
list. Thus version/0 should always indicate which modules make
up a particular package. It is not possible to remove messages from the
list.
help [Hookable]
Displays basic information, or a user defined help
message. It first calls user:user_help/0, and only if that call
fails is a default help message printed on the current output stream.
(This predicate is not available in runtime systems.)
user_help [Hook]
user:user_help
This may be defined by the user to print a help message on the current output stream.
SICStus Prolog provides a bi-directional, procedural interface for
program parts written in C and Prolog. The C side of the interface
defines a number of functions and macros for various operations. On the
Prolog side, you have to supply declarations specifying the names and
argument/value types of C functions being called as Prolog predicates.
These declarations are used by the predicate
load_foreign_resource/1, which performs the actual binding of C
functions to Prolog predicates.
In most cases, the argument/value type declaration suffice for making the necessary conversions of data automatically as they are passed between C and Prolog. However, it is possible to declare the type of an argument to be a Prolog term, in which case the receiving function will see it as a "handle" object, called an SP_term_ref, for which access functions are provided.
The C support routines are available in a development system as well as in runtime systems. The support routines include:
foreign/[2,3] declarations.
void * in the function definitions may
be changed to char * on non ANSI conforming C compilers.
SP_PATH is used as a shorthand
for the SICStus Prolog installation directory, whose default UNIX location is
/usr/local/lib/sicstus-3.8). See Environment Variables.
<sicstus/sicstus.h>.
The value of many support functions is a return code which is one of
SP_SUCCESS for success, SP_FAILURE for failure,
SP_ERROR if an error condition occurred. In particular, uncaught
exceptions resulting from calls from C to Prolog raise an error
condition. In error situations, the macro SP_errno will return a
value describing the error condition:
int SP_errno
The function SP_error_message returns a pointer to the diagnostic
message corresponding to a specified error number:
char *SP_error_message(int errno)
If a foreign function is specified to return an encoded string, an
exception will be raised if, on return to Prolog, the actual string is
ill-formed (is not a valid sequence of UTF-8 encoded characters). The
exception raised is
representation_error(...,...,mis_encoded_string).
Functions written in the C language may be called from Prolog using an interface in which automatic type conversions between Prolog terms and common C types are declared as Prolog facts. Calling without type conversion can also be specified, in which case the arguments and values are passed as SP_term_refs. This interface is partly modeled after Quintus Prolog.
The functions installed using this foreign language interface may invoke Prolog code and use the support functions described in the other sections of this chapter.
Functions, or their equivalent, in any other language having C compatible calling conventions may also be interfaced using this interface. When referring to C functions in the following, we also include such other language functions. Note however that a C compiler is needed since a small amount of glue code (in C) must be generated for interfacing purposes.
A foreign resource is a set of C functions, defined in one or more files, installed as an atomic operation. The name of a foreign resource, the resource name, is an atom, which should uniquely identify the resource. Thus, two foreign resources with the same name cannot be installed at the same time.
For each foreign resource, a foreign_resource/2 fact is used to
declare the interfaced functions. For each of these functions, a
foreign/[2,3] fact is used to specify conversions between predicate
arguments and C-types. These conversion declarations are used for
creating the necessary interface between Prolog and C.
The functions making up the foreign resource, the automatically
generated glue code, and any libraries, are compiled and linked, using
the program splfr (see The splfr utility) or
link_foreign_resource/6 (see Interface Predicates), to form a
linked foreign resource. A linked foreign resource exists in two
different flavors, static and dynamic. A static resource is
simply a relocatable object file containing the foreign code. A dynamic
resource is a shared library (.so under most UNIX dialects,
.dll under Windows) which is loaded into the Prolog executable at
runtime.
Foreign resources can be linked into the Prolog executable either when the executable is built (pre-linked), or at runtime. Pre-linking can be done using static or dynamic resources. Runtime-linking can only be done using dynamic resources. Dynamic resources can also be unlinked.
In all cases, the declared predicates are installed by the built-in
predicate load_foreign_resource/1. The resource name of a linked
foreign resource is derived from its filename by deleting any leading
path and the suffix. If the resource was pre-linked, only the predicate
names are bound, otherwise runtime-linking is attempted (using
dlopen(), LoadLibrary(), or similar).
Static and pre-linked resources are not supported under Windows. See Windows notes, for more information.
Conversion declaration predicates:
foreign_resource(+ResourceName,+Functions) [Hook]
Specifies that a set of foreign functions,
to be called from Prolog, are to be found in the resource named by
ResourceName. Functions is a list of functions exported by
the resource. Only functions that are to be called from Prolog and
optionally one init function and one deinit function should
be listed. The init and deinit functions are specified as
init(Function) and deinit(Function)
respectively (see Init and Deinit Functions). This predicate should
be defined entirely in terms of facts (unit clauses) and will be called
in the relevant module, i.e. not necessarily in the user module.
For example:
foreign_resource('terminal', [scroll,pos_cursor,ask]).
specifies that functions scroll(), pos_cursor() and
ask() are to be found in the resource terminal.
foreign(+CFunctionName, +Predicate) [Hook]
foreign(+CFunctionName, +Language, +Predicate) [Hook]
Specify the Prolog interface to a C function. Language is at
present constrained to the atoms c and java.
CFunctionName is the name of a C function. Predicate
specifies the name of the Prolog predicate that will be used to call
CFunction(). Predicate also specifies how the predicate
arguments are to be translated into the corresponding C arguments. These
predicates should be defined entirely in terms of facts (unit clauses)
and will be called in the relevant module, i.e. not necessarily in the
user module. For example:
foreign(pos_cursor, c, move_cursor(+integer, +integer)).
The above example says that the C function pos_cursor() has two
integer value arguments and that we will use the predicate
move_cursor/2 to call this function. A goal move_cursor(5,
23) would translate into the C call pos_cursor(5,23);.
The third argument of the predicate foreign/3 specifies how to
translate between Prolog arguments and C arguments. A call to a foreign
predicate will raise an exception if an input arguments is
uninstantiated (instantiation_error/2) or has the wrong type
(type_error/4) or domain (domain_error/4). The call will
fail upon return from the function if the output arguments do not unify
with the actual arguments.
The available conversions are listed in the next subsection.
The following table lists the possible values for the arguments in the
predicate specification of foreign/[2,3]. The value declares which
conversion between corresponding Prolog argument and C type will take
place. Note that the term chars below
refers to a list of character codes, rather than to one-char atoms.
Prolog: +integer
C: long
long and
passed to the C function.
Prolog: +float
C: double
double and
passed to the C function.
Prolog: +atom
C: unsigned long
Prolog: +chars
C: char *
Prolog: +string
C: char *
Prolog: +string(N)
C: char *
Prolog: +address
C: void *
SP_put_address()
(see Creating Prolog Terms). The value passed
will be a void * pointer.
Prolog: +address(TypeName)
C: TypeName *
SP_put_address()
(see Creating Prolog Terms).
The value passed will be a TypeName * pointer.
Prolog: +term
C: SP_term_ref
Prolog: -integer
C: long *
long.
The value returned will be converted to a Prolog integer.
Prolog: -float
C: double *
double.
The value returned will be converted to a Prolog float.
Prolog: -atom
C: unsigned long *
unsigned
long. The value returned should be the canonical representation of a
Prolog atom.
Prolog: -chars
C: char **
char *.
The returned encoded string will be converted to a Prolog list of
character codes.
Prolog: -string
C: char **
char *.
The returned encoded string will be converted to a Prolog atom. Prolog
will copy the string to a safe place, so the memory occupied by the
returned string may be reused during subsequent calls to foreign
code.
Prolog: -string(N)
C: char *
Prolog: -address
C: void **
void *.
The returned value,
which should be a valid second argument to SP_put_address()
(see Creating Prolog Terms),
will be converted to a Prolog integer.
Prolog: -address(TypeName)
C: TypeName **
TypeName *. The returned value,
which should be a valid second argument to SP_put_address()
(see Creating Prolog Terms), will be
converted to a Prolog integer.
Prolog: -term
C: SP_term_ref
Prolog: [-integer]
C: long F()
long. The value returned will be
converted to a Prolog integer.
Prolog: [-float]
C: double F()
double. The value returned will
be converted to a Prolog float.
Prolog: [-atom]
C: unsigned long F()
unsigned long. The value
returned must be the canonical representation of a Prolog atom.
Prolog: [-chars]
C: char *F()
char *. The returned encoded
string will be converted to a Prolog list of character codes.
Prolog: [-string]
C: char *F()
char *. The returned encoded
string will be converted to a Prolog atom. Prolog will copy the string
to a safe place, so the memory occupied by the returned string may be
reused during subsequent calls to foreign code.
Prolog: [-string(N)]
C: char *F()
char *. The first N bytes
of the encoded string (not necessarily NULL-terminated) will be copied
and the copied string will be stripped of trailing blanks. The stripped
string will be converted to a Prolog atom. C may reuse or destroy the
string buffer during later calls.
Prolog: [-address]
C: void *F()
void *. The returned value,
which should be a valid second argument to SP_put_address()
(see Creating Prolog Terms), will be converted to a Prolog integer.
Prolog: [-address(TypeName)]
C: TypeName *F()
TypeName *. The returned
value,
which should be a valid second argument to SP_put_address()
(see Creating Prolog Terms), will be converted to a Prolog integer.
Prolog: [-term]
C: SP_term_ref F()
link_foreign_resource(+Resource,+SourceFile,+Option,+CFiles,+ObjectFiles,+Libraries)
Builds a linked foreign resource, using the splfr
utility. Option can be either dynamic or static as
described in the alternative form shown below. The Resource
argument is an unsuffixed filename of a linked foreign resource. This
predicate is not available in runtime systems.
load_foreign_resource(:Resource)
Unless a foreign resource with the same name as Resource has been
statically linked, the linked foreign resource specified by
Resource is linked into the Prolog load image. In both cases, the
predicates defined by Resource are installed, and any init
function is called. Dynamic linking is not possible if the foreign
resource was linked using the +static option.
If a resource with the same name has been previously loaded, it will be
unloaded as if unload_foreign_resource(Resource) was
called, before Resource is loaded.
unload_foreign_resource(:Resource)
Any deinit function associated with Resource is called, and the predicates defined by Resource are uninstalled. If Resource has been dynamically linked, it is unlinked from the Prolog load image.
The following predicates are provided for backwards compatibility and should be avoided in new code:
foreign_file(+File,+Functions) [Hook,Obsolescent]
Specifies that a set of foreign functions,
to be called from Prolog, are to be found in File. This predicate
is only called from load_foreign_files/2.
load_foreign_files(:ObjectFiles,+Libraries) [Hookable,Obsolescent]
A resource name is derived from the first file name in ObjectFiles by stripping off the suffix. If this resource has been statically linked, the predicates defined by it are installed; otherwise, a linked foreign resource containing the declared functions is created and loaded. Not available in runtime systems.
The splfr utility is used to create foreign resources
(see Foreign Resources).
splfr reads terms from a Prolog file, applying op declarations and
extracting any foreign_resource/2 fact with first argument
matching the resource name and all foreign/[2,3] facts.
Based on this information, it generates the necessary glue code,
and combines it with any additional C or object files provided by the
user into a linked foreign resource. The output filename will be the
resource name with a suitable extension.
splfr is invoked as
% splfr [ Option | InputFile ] ...
The input to splfr can be divided into Options and
InputFiles and they can be arbitrarily mixed on the command
line. Anything not interpreted as an option will be interpreted as an
input file. Exactly one of the input files should be a Prolog file.
The following options are available:
--help
-v
--verbose
-version
splfr.
--resource=ResourceName
--manual
-S
--static
spld utility,
The spld utility.
--keep
--import
--cflag=CFlags
The key input to splfr is the SourceFile. The contents of
this file determines how the foreign resource's interface will look
like. When the source-file is read in, foreign_resource/2 facts
with first argument matching the name of this resource
(i.e. ResourceName) is extracted together with all
foreign/[2,3] facts.
An init function and/or a deinit function can be declared by
foreign_resource/2. If this is the case, these functions should
have the prototype:
void FunctionName (int when)
The init function is called by load_foreign_resource/1 after the
resource has been loaded and the interfaced predicates have been
installed.
The deinit function is called by unload_foreign_resource/1 before
the interfaced predicates have been uninstalled and the resource has
been unloaded.
The init and deinit functions may use the C-interface to call Prolog etc.
Foreign resources are unloaded before saving states, and reloaded
afterwards or when the saved state is restored;
see Saving. Foreign resources are also unloaded when
exiting Prolog execution. The parameter when reflects the context
of the (un)load_foreign_resource/1 and is set as follows for
init functions:
SP_WHEN_EXPLICIT
load_foreign_resource/1.
SP_WHEN_RESTORE
For deinit functions:
SP_WHEN_EXPLICIT
unload_foreign_resource/1.
SP_WHEN_SAVE
SP_WHEN_EXIT
Suppose we have a Prolog source file ex.pl containing:
foreign(f1, p1(+integer,[-integer])). foreign(f2, p2(+integer,[-integer])). foreign_resource(ex, [f1,f2]). :- load_foreign_resource(ex).
and a C source file ex.c with definitions of the functions
f1 and f2, both returning long and having a
long as only parameter. The conversion declarations in
ex.pl state that these functions form the foreign resource
ex.
To create the linked foreign resource, simply type (to Prolog):
| ?- link_foreign_resource(ex,'ex.pl',dynamic,['ex.c'],[],[]).
or alternatively (to the Shell):
% splfr ex.pl ex.c
The linked foreign resource ex.so (file suffix .so is
system dependent) has been created. It will be dynamically linked by the
directive :- load_foreign_resource(ex). when the file ex.pl
is loaded. Linked foreign resources can also be created manually
(see Runtime Utilities).
Dynamic linking of foreign resources can also be used by Runtime Systems. On some platforms, however, the executable must not be stripped for dynamic linking to work, i.e. its symbol table must remain.
The support functions include functions to manipulate SP_term_refs, functions to convert data between the basic C types and Prolog terms, functions to test whether a term can be converted to a specific C type, and functions to unify or compare two terms.
Normally, C functions only have indirect access to Prolog terms via
SP_term_refs. C functions may receive arguments as
unconverted Prolog terms, in which case the actual arguments received will
have the type SP_term_ref. Also, a C function may return an
unconverted Prolog term, in which case it must create an SP_term_ref.
Finally, any temporary Prolog terms created by C code must be handled
as SP_term_refs.
SP_term_refs are motivated by the fact that SICStus Prolog's memory manager must have a means of reaching all live Prolog terms for memory management purposes, including such terms that are being manipulated by the user's C code. Previous releases of SICStus Prolog provided direct access to Prolog terms and the ability to tell the memory manager that a given memory address points to a Prolog term, but this approach was too low level and highly error-prone. The current design is modeled after and largely compatible with Quintus Prolog release 3.
SP_term_refs are created dynamically. At any given time, an SP_term_ref has a value (a Prolog term). This value can be examined, accessed, and updated by the support functions described in this section.
It is important to understand the rules governing the scope of SP_term_refs in conjunction with calls from Prolog to C and vice versa:
A new SP_term_ref whose value is [] is created by calling:
SP_term_ref SP_new_term_ref(void)
The value of the SP_term_ref to is set to the value of the
SP_term_ref from by calling SP_put_term(to,from). The
previous value of to is lost:
void SP_put_term(SP_term_ref to, SP_term_ref from)
Each Prolog atom is represented internally by a unique integer,
represented in C as an unsigned long. This mapping between atoms
and integers depends on the execution history. Certain functions
require this representation as opposed to an SP_term_ref. It can be
obtained by a special argument type declaration when calling C from
Prolog, by calling SP_get_atom(), or by looking up an encoded
string s in the Prolog symbol table by calling
SP_atom_from_string(s):
unsigned long SP_atom_from_string(char *s)
The encoded string containing the characters of a Prolog atom a
can be obtained by calling:
char *SP_string_from_atom(unsigned long a)
The length of the encoded string representing a Prolog atom a
can be obtained by calling:
int SP_atom_length(unsigned long a)
Same as strlen(SP_string_from_atom(a)) but runs in O(1) time.
Prolog atoms, and the space occupied by their print names, are subject
to garbage collection when the number of atoms has reached a certain
threshold, under the control of the agc_margin Prolog flag
(see State Info), or when the atom garbage collector is called
explicitly. The atom garbage collector will find all references to
atoms from the Prolog specific memory areas, including SP_term_refs and
arguments passed from Prolog to foreign language functions. However, atoms
created by SP_atom_from_string and merely stored in a local variable
are endangered by garbage collection. The following functions make it
possible to protect an atom while it is in use. The operations are
implemented using reference counters to cater for multiple, independent
use of the same atom in different foreign resources:
int SP_register_atom(unsigned long a)
Registers the atom a with the Prolog memory manager by incrementing
its reference counter. Returns a nonzero value if the operation succeeds.
int SP_unregister_atom(unsigned long a)
Unregisters the atom a with the Prolog memory manager by decrementing
its reference counter. Returns a nonzero value if the operation succeeds.
These functions create a term and store it as the value of an
SP_term_ref, which must exist prior to the call. They return zero if
the conversion fails (as far as failure can be detected), and a nonzero
value otherwise, assigning to t the converted value.
Note that the term chars here
refers to a list of character codes, rather than to one-char atoms:
int SP_put_variable(SP_term_ref t)
t a new Prolog variable.
int SP_put_integer(SP_term_ref t, long l)
t a Prolog integer from a C long integer.
int SP_put_float(SP_term_ref t, double d)
t a Prolog float from a C double.
int SP_put_atom(SP_term_ref t, unsigned long a)
t a Prolog atom from a,
which must be the canonical representation of a Prolog atom.
(see Calling C).
int SP_put_string(SP_term_ref t, char *name)
t a Prolog atom from a encoded C string.
int SP_put_address(SP_term_ref t, void *pointer)
t a Prolog integer from a C pointer.
The pointer must be NULL or an address having the four most
significant bits consistent with the smallest non-NULL value returned
by the function malloc(). In particular, under Linux, these bits must be
zero. Furthermore, the address must be aligned on a four bytes boundary.
NULL is converted to the integer 0.
int SP_put_list_chars(SP_term_ref t, SP_term_ref tail, char *s)
t a Prolog list of the character codes represented by
the encoded string s, prepended to the value of tail.
int SP_put_list_n_chars(SP_term_ref t, SP_term_ref tail, long n, char *s)
t a Prolog list of the character codes represented by
the first n bytes in encoded string s, prepended
in front of the value of tail.
int SP_put_number_chars(SP_term_ref t, char *s)
t a Prolog number by parsing the string in s.
int SP_put_functor(SP_term_ref t, unsigned long name, int arity)
t a Prolog compound term with all the arguments
unbound variables. If arity is 0, assigns the Prolog atom whose
canonical representation is name to t. This is similar to
calling functor/3 with the first argument unbound and the second
and third arguments bound to an atom and an integer, respectively.
int SP_put_list(SP_term_ref t)
t a Prolog list whose head and tail are both unbound
variables.
int SP_cons_functor(SP_term_ref t, unsigned long name, int arity, SP_term_ref arg, ...)
t a Prolog compound term whose arguments are the
values of arg... If arity is 0, assigns the Prolog atom
whose canonical representation is name to t. This is
similar to calling =../2 with the first argument unbound and the
second argument bound.
int SP_cons_list(SP_term_ref t, SP_term_ref head, SP_term_ref tail)
t a Prolog list whose head and tail are the values of
head and tail.
These functions will take an SP_term_ref and convert it to C data.
They return zero if the conversion fails, and a nonzero value otherwise,
and (except the last one) store the C data in output arguments.
Note that the term chars here
refers to a list of character codes, rather than to one-char atoms:
int SP_get_integer(SP_term_ref t, long *l)
*l the C long corresponding to a Prolog
number. The value must fit in *l for the operation to succeed.
int SP_get_float(SP_term_ref t, double *d)
*d the C double corresponding to a Prolog
number.
int SP_get_atom(SP_term_ref t, unsigned long *a)
*a the canonical representation of a Prolog atom.
int SP_get_string(SP_term_ref t, char **name)
*name a pointer to the encoded string representing the
name of a Prolog atom. This string must not be modified.
int SP_get_address(SP_term_ref t, void **pointer)
*pointer a C pointer from a Prolog term. The term
should be an integer
whose value should be a valid second argument to SP_put_address()
(see Creating Prolog Terms).
int SP_get_list_chars(SP_term_ref t, char **s)
*s a zero-terminated array containing an encoded
string which corresponds to the given Prolog list of character codes.
The array is subject to reuse by other support functions, so if the
value is going to be used on a more than temporary basis, it must be
moved elsewhere.
int SP_get_list_n_chars(SP_term_ref t, SP_term_ref tail, long n, long *w, char *s)
s the encoded string representing the character codes
in the initial elements of list t, so that at most n bytes
are used. The number of bytes actually written is assigned to
*w. tail is set to the remainder of the list. The array
s must have room for at least n bytes.
int SP_get_number_chars(SP_term_ref t, char **s)
*s a zero-terminated array of characters
corresponding to the printed representation of a Prolog number. The
array is subject to reuse by other support functions, so if the value is
going to be used on a more than temporary basis, it must be moved
elsewhere.
int SP_get_functor(SP_term_ref t, unsigned long *name, int *arity)
*name and *arity the canonical representation
and arity of the principal functor of a Prolog compound term. If the
value of t is an atom, then that atom is assigned to
*name and 0 is assigned to *arity. This is similar to
calling functor/3 with the first argument bound to a compound
term or an atom and the second and third arguments unbound.
int SP_get_list(SP_term_ref t, SP_term_ref head, SP_term_ref tail)
head and tail the head and tail of a Prolog list.
int SP_get_arg(int i, SP_term_ref t, SP_term_ref arg)
arg the i:th argument of a Prolog compound
term. This is similar to calling arg/3 with the third argument
unbound.
There is one general function for type testing of Prolog terms and a set of specialized, more efficient, functions, one for each term type:
int SP_term_type(SP_term_ref t)
SP_TYPE_VARIABLE, SP_TYPE_INTEGER, SP_TYPE_FLOAT,
SP_TYPE_ATOM, or SP_TYPE_COMPOUND is returned.
int SP_is_variable(SP_term_ref t)
int SP_is_integer(SP_term_ref t)
int SP_is_float(SP_term_ref t)
int SP_is_atom(SP_term_ref t)
int SP_is_compound(SP_term_ref t)
int SP_is_list(SP_term_ref t)
int SP_is_atomic(SP_term_ref t)
int SP_is_number(SP_term_ref t)
int SP_unify(SP_term_ref x, SP_term_ref y)
int SP_compare(SP_term_ref x, SP_term_ref y)
-1 if x @< y, 0 if x ==
y and 1 if x @> y
The usual C library memory allocation functions (malloc, realloc,
and free) may not work properly in foreign code. The following
functions provide these services from SICStus Prolog's memory manager:
void *SP_malloc(unsigned int size)
size
bytes.
void *SP_realloc(void *ptr, unsigned int size)
ptr to size
bytes and returns a pointer to the (possibly moved) block. The contents
will be unchanged up to the lesser of the new and old sizes. The block
referenced by ptr must have been obtained by a call to
SP_malloc or SP_realloc, and must not have been released
by a call to SP_free or SP_realloc.
void SP_free(void *ptr)
ptr, which must have been
obtained by a call to SP_malloc or SP_realloc, and must
not have been released by a call to SP_free or SP_realloc.
SICStus Prolog caches the name of the current working directory. To
take advantage of the cache and to keep it consistent, foreign code
should call the following interface functions instead of calling
chdir() and getcwd() directly:
int SP_chdir(char *path)
path to become the current
working directory. Returns 0 upon successful completion. Otherwise, a
value of -1 is returned and errno is set to indicate the error.
char *SP_getcwd(char *buf, unsigned int size);
Returns a pointer to the current directory pathname. If buf is
not NULL, the pathname will be stored in the space pointed to by
buf. If buf is a NULL pointer, size bytes
of space will be obtained using SP_malloc(). In this case, the
pointer returned may be used as the argument in a subsequent call to
SP_free(). Returns NULL with errno set if
size is not large enough to store the pathname.
In development and runtime systems alike, Prolog and C code may call each other to arbitrary depths.
Before calling a predicate from C you must look up the predicate
definition by module, name, and arity. The function
SP_predicate() will return a pointer to this definition or return
NULL if the predicate is not visible in the module. This
definition could be used in more than one call to the same predicate.
The module specification is optional. If NULL or "" (the
empty string) is given then the default type-in module
(see Module Spec) is assumed:
SP_pred_ref SP_predicate(char *name_string,
long arity,
char *module_string)
Note that the first and third arguments point to encoded strings, representing the characters of the predicate and module name.
The function SP_pred() may be used as an alternative to the
above. The only difference is that the name and module arguments are
passed as Prolog atoms rather than strings, and the module argument is
mandatory. This saves the cost of looking up the two arguments in the
Prolog symbol table. This cost dominates the cost of
SP_predicate():
SP_pred_ref SP_pred(unsigned long name_atom,
long arity,
unsigned long module_atom)
The easiest way to call a predicate if you are only interested in the
first solution is to call the function SP_query(). It will
create a goal from the predicate definition and the arguments,
call it, and commit to the first solution found, if any.
Returns SP_SUCCESS if the goal succeeded, SP_FAILURE if it
failed, and SP_ERROR if an error condition occurred. Only when
the return value is SP_SUCCESS are the values in the query
arguments valid, and will remain so until backtracking into any
enclosing query:
int SP_query(SP_pred_ref predicate, SP_term_ref arg1, ...)
If you are only interested in the side effects of a predicate you can
call SP_query_cut_fail(). It will try to prove the predicate,
cut away the rest of the solutions, and finally fail. This will
reclaim the storage used after the call, and throw away any solution found:
int SP_query_cut_fail(SP_pred_ref predicate, SP_term_ref arg1, ...)
If you are interested in more than one solution a more complicated scheme is used. You find the predicate definition as above but you don't call the predicate directly.
SP_open_query()
SP_next_solution() to find a solution. Call this predicate
again to find more solutions if there are any.
SP_close_query() or SP_cut_query()
The function SP_open_query() will return an identifier of type
SP_qid that you use in successive calls, or NULL, if given
an invalid predicate reference. Note that if a new query is opened
while another is already open, the new query must be terminated before
exploring the solutions of the old one. That is, queries must be
strictly nested:
SP_qid SP_open_query(SP_pred_ref predicate, SP_term_ref arg1, ...)
The function SP_next_solution() will cause the Prolog engine to
backtrack over any current solution of an open query and look for a new
one. The given argument must be the innermost query that is still open,
i.e. it must not have been terminated explicitly by
SP_close_query() or SP_cut_query() or implicitly by an
unsuccessful call to SP_next_solution(). Returns
SP_SUCCESS for success, SP_FAILURE for failure,
SP_ERROR if an error condition occurred. Only when the return
value is SP_SUCCESS are the values in the query arguments valid,
and will remain so until backtracking into this query or an enclosing
one:
int SP_next_solution(SP_qid query)
A query must be terminated in either of two ways.
The function
SP_cut_query() will discard the choices created since the
corresponding SP_open_query(), like the goal !.
The current solution is retained in the arguments
until backtracking into any enclosing query.
The given argument does not have to be the innermost open query; any
open queries in its scope will also be cut. Returns SP_SUCCESS
for success and SP_ERROR for invalid usage:
int SP_cut_query(SP_qid query)
Alternatively, the function SP_close_query() will discard the
choices created since the corresponding SP_open_query(), and then
backtrack into the query, throwing away any current solution, like the
goal !, fail.
The given argument does not have to be the innermost open query; any
open queries in its scope will also be closed. Returns
SP_SUCCESS for success and SP_ERROR for invalid usage:
int SP_close_query(SP_qid query)
A Prolog execution may be interrupted by signals or similar
asynchronous events. If you wish to call Prolog back from a signal
handler you cannot use SP_query() etc. directly. The call to
Prolog has to be delayed until a time when the Prolog execution can
accept an interrupt. The function SP_event() serves this
purpose, and installs the function func to be called from Prolog
when the execution can accept a callback. Returns non-zero iff
installation succeeded. func is called with arg as first
argument.
A queue of functions, with corresponding arguments, is maintained; that
is, if several calls to SP_event() occur before Prolog can a
accept an interrupt, the functions are queued and executed in turn at
the next possible opportunity. Note that the queuing facility is only
safe for signal handlers installed using SP_signal() (see below).
Depending on the value returned from func, the interrupted Prolog
execution will just continue (SP_SUCCESS) or backtrack
(SP_FAILURE or SP_ERROR). An exception raised by
func will be processed in the interrupted Prolog execution. In
case of fail or exception the event queue is flushed:
int SP_event(int (*func)(), void *arg)
A signal handler having called SP_event() should call
SP_continue() as its last action, to ensure that the interrupt is
processed as early as possible:
void SP_continue()
To install a function, func, as a handler for the signal
sig, call:
void (*SP_signal (int sig, void (*func)()))()
SP_signal() will also, if permitted by the operating system, add
sig to a set of signals which are all blocked during the handling
of the event queue. Some operating systems require that:
void (*SP_reinstall_signal (int sig, void (*func)()))()
be called from a signal handler to unblock or reinstall the handler.
This function should be called before SP_continue().
The following piece of C code illustrates these facilities. The
function signal_init() installs the function
signal_handler() as the primary signal handler for the
signals USR1 and USR2. That function invokes the
predicate prolog_handler/1 as the actual signal handler, passing
the signal number as an argument to the predicate.
SP_pred_ref event_pred;
static int signal_event(signal_no)
void *signal_no;
{
SP_term_ref x=SP_new_term_ref();
int rc;
SP_put_integer(x, (int)signal_no);
rc = SP_query(event_pred, x);
if (rc == SP_ERROR && SP_exception_term(x))
SP_raise_exception(x); /* Propagate any raised exception */
return rc;
}
static void signal_handler(sig)
int sig;
{
SP_event(signal_event, (void *)sig);
SP_reinstall_signal(sig, signal_handler);
SP_continue();
}
void signal_init()
{
event_pred = SP_predicate("prolog_handler",1,"");
SP_signal(SIGUSR1, signal_handler);
SP_signal(SIGUSR2, signal_handler);
}
When an exception has been raised, the functions SP_query(),
SP_query_cut_fail() and SP_next_solution() return
SP_ERROR. To access the exception term (the argument of
the call to raise_exception/1), which is asserted when the
exception is raised, the function SP_exception_term() is used.
As a side effect, the exception term is retracted, so if your code wants
to pass the exception term back to Prolog, it must use the
SP_raise_exception() function below. If an exception term exists,
SP_exception_term() retracts it and stores it as the value of an
SP_term_ref which must exist prior to the call and returns nonzero.
Otherwise, it returns zero:
int SP_exception_term(SP_term_ref t)
To raise an exception from a C function called from Prolog,
just call SP_raise_exception(t) where t
is the SP_term_ref whose value is the exception term. The glue code
will detect that an exception has been raised, any value returned from
the function will be ignored, and the exception will be passed back to
Prolog:
void SP_raise_exception(SP_term_ref t)
With the SICStus Prolog C interface, the user can define his/her own streams as well as from C read or write on the predefined streams. The stream interface is modeled after Quintus Prolog release 2. It provides:
From the Prolog level there is a unique number that identifies a stream. This identifier can be converted from/to a Prolog stream:
stream_code(+Stream,?StreamCode)
stream_code(?Stream,+StreamCode)
StreamCode is the C stream identifier (an integer) corresponding to
the Prolog stream Stream. This predicate is only useful when
streams are passed between Prolog and C.
Note that StreamCode no longer has any relation to the
file descriptor.
The StreamCode is a Prolog integer representing a
SP_stream * pointer
whose value should be a valid second argument to SP_put_address()
(see Creating Prolog Terms).
To read or write on a Prolog stream from C, special versions of the most common standard C I/O functions are used:
int SP_getc(void)
int SP_fgetc(SP_stream *s)
void SP_putc(int c)
void SP_fputc(int c, SP_stream *s)
The above functions deliver or accept wide character codes.
void SP_puts(char *string)
void SP_fputs(char *string, SP_stream *s)
int SP_printf(char *format, ...)
int SP_fprintf(SP_stream *s, char *format, ...)
int SP_fflush(SP_stream *s)
int SP_fclose(SP_stream *s)
The above functions expect and deliver encoded strings in their
char * and char ** arguments. Specifically, in the
SP_printf() and SP_fprintf() functions, first the
formatting operation will be performed. The resulting string will be
assumed to be in internal encoding, and will be then output using the
SP_puts() or SP_fputs() function (see below). This means,
e.g., that the %c printf conversion specification can only be
used for ASCII characters, and the strings included using a %s
specification should also be ASCII strings, or already transformed to
the encoded form.
The SP_puts() and SP_fputs() functions first convert their
encoded string argument into a sequence of wide character codes, and
then output these on the required stream according to the external
encoding; see WCX Foreign Interface.
There are three predefined streams accessible from C:
SP_stdin
user_input in
Prolog. Which stream is referenced by user_input is controlled by the
flag user_input (see prolog_flag/3) .
SP_stdout
user_output in
Prolog. Which stream is referenced by user_output is controlled by
the flag user_output (see prolog_flag/3).
SP_stderr
user_error in
Prolog. Which stream is referenced by user_error is controlled by
the flag user_error (see prolog_flag/3).
SP_curin
SP_stdin.
It can be changed with the predicates see/1 and set_input/1.
SP_curout
SP_stdout.
It can be changed with the predicates tell/1 and set_output/1.
Note that these variables are read only. They are set but never read by the stream handling.
The following steps are required to define a new stream in C:
SP_make_stream().
SP_stream structure than the default values set by
SP_make_stream().