This manual documents SICStus Prolog 3.10.0, December 2002.
Prolog is a simple but powerful programming language developed at the University of Marseille, 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 Marseille [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. As of release 3.8, 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 is largely
compatible with e.g. C-Prolog and Quintus Prolog, supports code
written in earlier versions of SICStus Prolog.
The following people have contributed to the development of SICStus Prolog:
Jonas Almgren, Johan Andersson, Stefan Andersson, Nicolas Beldiceanu, Tamás Benko'', Kent Boortz, Dave Bowen, Per Brand, Göran Båge, Mats Carlsson, Per Danielsson, Jesper Eskilson, Lena Flood, György Gyaraki, Dávid Hanák, Seif Haridi, Ralph Haygood, Christian Holzbaur, Tom Howland, Key Hyckenberg, Per Mildner, Richard O'Keefe, Greger Ottosson, László Péter, Dan Sahlin, Peter Schachte, Rob Scott, Thomas Sjöland, Péter Szeredi, Tamás Szeredi, Peter Van Roy, Johan Widén, David Warren, 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.
Throughout, we will assume that ^D is the EOF character (it's
usually ^Z under Windows) and that ^C is the interrupt character.
In most contexts, the term end_of_file terminated by a full stop
(.) can be typed instead of the EOF character.
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.
Each Prolog atom is represented internally by a unique integer,
represented in C as an SP_atom.
:- 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 is the name, 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.
The functor of a constant is the term itself paired with zero.
For example, the constant nl is said to have "the functor
nl of arity zero", which is generally written nl/0.
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.
[-2^25,2^25-1] on 32-bit platforms, or
[-2^56,2^56-1] on 64-bit platforms.
sicstus
executable), or a runtime system. Both kinds are created by the
application builder. 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.
SP1 and SP2 refer to positions in the same
stream, SP1@<SP2 if and only if SP1 is before SP2
in the stream. You should not otherwise rely on their internal
representation.
"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
--iso
--sicstus
-m
-l prolog-file
-l argument is allowed.
-r saved-state
-r argument is allowed.
--goal Goal
call/1 after all files have been loaded. As usual Goal
should be terminated by a full stop (.).
Only one --goal argument is allowed.
-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.9.1 ... 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()). In most cases there is no need to use it.
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.
In addition the following environment variables are set automatically on startup.
SP_APP_DIR
application file search alias.
SP_RT_DIR
SP_RT_DIR
is the same as SP_APP_DIR.
Also available as the runtime file search alias.
SP_LIBRARY_DIR
library file search alias.
Send bug reports to sicstus-support@sics.se or use the form at http://www.sics.se/sicstus/bugreport/bugreport.html. 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 mailing list for communication among users and implementors. To subscribe, write a message to majordomo@sics.se with the following line in the message body:
subscribe sicstus-users
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/3 (see Stream Pred) to look up the file.
If no explicit extension is given,
this predicate will look for a file with the default extension .pl added
as well as for a file without extension. 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:
% consulted user in module user, 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.
While the variable bindings are displayed, all variables occurring in
the values are replaced by terms of the form '$VAR'(N) to
yield friendlier variable names. Such names come out as a sequence of
letters and digits preceded by _. The outcome of some queries is
shown below.
| ?- 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:
* 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 ! , or ) expected in arguments ! in line 5 ! 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
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 current character-conversion mapping,
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.
NOTE: Prolog object files can be created with any suffix, but cannot be
loaded unless the suffix is .po!
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 http://www.emacs.org. For information specific to GNU Emacs or XEmacs, see http://www.gnu.org and http://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.9.1/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 Prolog 3.9.1/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.9.1/doc/info/ on UNIX platforms and
C:/Program Files/SICStus Prolog 3.9.1/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 Prolog 3.9.1/doc/info/
(setq Info-default-directory-list
(append Info-default-directory-list '("INFO")))
for GNU Emacs, or
(setq Info-directory-list
(append Info-directory-list '("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 nondeterminate 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. Unless character escapes have been switched off, 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'.
{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'.
Unless character escapes have been switched off, backslashes in the
sequence denote escape sequences (see Escape Sequences). As for
quoted atoms, if a double quote character is included in the sequence it
must be escaped, e.g. "can\"t".
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 variabl