Copyright © 1989, 1995, 2012 by David Matuszek
All rights reserved.
read, get, get0, see, seen.Output predicates --
write, writeq, tab, nl, put, tell, told.Control predicates --
X ; Y, (X -> Y), (X -> Y ; Z), not X, true, repeat, fail, !, abort.Database manipulation predicates --
assert, asserta, assertz, retract, abolish, clause, save, restore.Arithmetic predicates --
is, +, -, *, /, mod, =:=, =\=, >, <, >=, =<.Listing and debugging predicates --
listing, trace, notrace, spy P, nospy P, nospyall, debug, nodebug,Tests --
atom, atomic, number, integer, float, var, nonvar, ==, \==.
The following is a simple Prolog program:
The first line can be read, "Socrates is a man.'' It is a base clause, which represents a simple fact.
man(socrates). mortal(X) :- man(X).
The second line can be read, "X is mortal if X is a man;'' in other words, "All men are mortal.'' This is a clause, or rule, for determining when its input X is "mortal.'' (The symbol ":-'', sometimes called a turnstile, is pronounced "if''.) We can test the program by asking the question:
that is, "Is Socrates mortal?'' (The "
| ?- mortal(socrates).
| ?-'' is the computer's prompt for a question.) Prolog will respond "
yes''. Another question we may ask is:
That is, "Who (X) is mortal?'' Prolog will respond "
| ?- mortal(X).
X = socrates''.
Two clauses belong to the same predicate if they have the same functor (name) and the same arity (number of arguments). Thus,
<program> ::= <predicate> | <program><predicate> <predicate> ::= <clause> | <predicate><clause> <clause> ::= <base clause> | <nonbase clause>
mother(jane, jim)are different predicates.
A structure is a functor followed by zero or more arguments; the arguments are enclosed in parentheses and separated by commas. There must be no space between the functor and the opening parenthesis! If there are no arguments, the parentheses are omitted.
<base clause> ::= <structure> . <nonbase clause> ::= <structure> :- <structures> . <structures> ::= <structure> | <structure> , <structures>
Arguments may be any legal Prolog values or variables.
<structure> ::= <name> | <name> ( <arguments> ) <arguments> ::= <argument> | <argument> , <arguments>
A variable is written as a sequence of letters and digits, beginning with a capital letter. The underscore (_) is considered to be a capital letter.
An atom is any sequence of letters and digits, beginning with a
lowercase letter. Alternatively, an atom is any sequence of
characters, enclosed by single quotes ('); an internal single quote
must be doubled. Examples:
As syntactic sugar, Prolog allows certain infix operators: ','
(comma), ';' (semicolon), ':-' (turnstile), +, -, *, /, =, ==, and
many others. These are the same as the operator written as the
functor of a structure; for example,
2+2 is the same as
Comments begin with the characters
/* and end with
*/. Comments are not restricted to a single line, but may
not be nested.
/* This is a comment. */
mother(john) = mother(john).
X = Y, X = 2, write(Y). /* Writes the value 2. */
X = foo(bar, [1, 2, 3]). /* X is fully instantiated. */
Pa = husband(Ma). /* Pa is partially instantiated. */
mother(mary, X) = mother(Y, father(Z)).
[Also results in the unifications
X = foo(X, Y).
Prolog variables are similar to "unknowns'' in algebra: Prolog tries to find values for the variables such that the entire clause can succeed. Once a value has been chosen for a variable, it cannot be altered by subsequent code; however, if the remainder of the clause cannot be satisfied, Prolog may backtrack and try another value for that variable.
The anonymous variable consists of a single underscore. Each occurrence of the anonymous variable is considered to be a new, distinct variable (i.e. different occurrences may have different values).
The scope of a variable name is the clause in which it occurs. There are no "global'' variables.
mother(X, Y) :- parent(X, Y), female(X).
Xis the mother of
Xis a parent of
Approximate procedural reading: To show that
X is the
Y, first show that
X is a parent
Y, then show that
X is female.
Suppose we have the additional base clauses:
Now if we inquire:
parent(john, bill). parent(jane, bill). female(jane).
the clause of
| ?- mother(M, bill).
mother/2will be located, and the unifications
X=M, Y=billwill occur. (Parameter transmission is by unification.) Then
parent(M, bill)will be attempted, resulting in the unification
female(john)will be attempted, but will fail. Prolog will backtrack to
parent(M, bill)and look for another solution for this; it will succeed and unify
M=jane. Finally, it will attempt
female(jane), and succeed; so the inquiry will succeed, having performed the unification
Typically Prolog predicates work regardless of which arguments are
instantiated, and may instantiate the others. Thus
mother/2 works equally well for the calls
mother(jane,bill) [but the procedural reading is different in
each case.] Injudicious use of control predicates, particularly
"cut,'', can destroy this property.
is the empty list;
[a, 2+2, ]is the list containing the three elements
[Head | Tail]is the list whose first element is
Headand whose tail (list of remaining elements) is
[a, X, c | Tail]is the list whose first three elements are
c, and whose remaining elements are given by the list
Tail. Only one term may follow the "
[a | X, Y]and
[a | X | Y]are syntactic nonsense.
Unification can be performed on lists:
In most (but not all) Prolog systems, the list notation is syntactic sugar for the '.' functor, with the equivalence:[a, b, c] = [Head | Tail]. /* a = Head, [b, c] = Tail. */ [a, b] = [A, B | T]. /* a = A, b = B,  = Tail. */ [a, B | C] = [X | Y]. /* a = X, [B | C] = Y. */
'.'(Head, Tail) = [Head | Tail].
Two useful predicates are
member/2, which succeeds when
its first argument is a member of the list that is its second
append/3, which is true when the third
argument is the list formed by appending the first two lists.
Neither is predefined. Definitions are:
The operator "member(A, [A | _]). member(A, [_ | B]) :- member(A, B). append([A | B], C, [A | D]) :- append(B, C, D). append(, A, A).
=..'', pronounced "univ,'' succeeds when its left argument is a structure and its right argument is the corresponding list [Functor | Args].
mother(M, bill) =.. [mother, M, bill].
A double-quoted character string is syntactic sugar for a list of the ASCII codes for those characters.
"abc" = [97,98,99].
name/2 succeeds if its first argument is
the atom formed from the string that is its second argument.
prologat the top-level prompt. Prolog should respond with the "|
To load in predicates from file, use
or reconsult([FileName1, FileName2, ...]). If
one of the files contains a predicate that already occurs in the
database, it replaces the old definition. [The similar predicate
consult adds the new clauses after the existing
predicates, rather than replacing them.]
To type in predicates directly, use
prompt will change from "
| ?-'' to "|''. Enter
predicates as you would on a file. To quit this mode, enter an
end-of-file (probably ^D).
"Run'' the program by typing in inquiries at the Prolog prompt. You may call any predicate with any arguments, and you may make multiple calls in one inquiry by separating them with commas. Use a period at the end of each inquiry. There is no "main'' program.
When Prolog does not give you a new prompt after it answers an inquiry, that means there may be other answers. Enter
to tell it to get the next answer, or just
<return>to tell it you have seen enough.
To begin tracing, use
trace; to end tracing, use
notrace. To exit Prolog, use
A Prolog predicate consists of multiple clauses. It is useful to think of each clause as coding a separate "case''--first describe what constitutes the case, then describe the result for that case. For example, the absolute value of a number is (1) the negation of the number, if it is negative, or (2) the number itself, if it isn't negative.
If a case has subcases, feel free to invent another predicate to deal with the subcases.abs(X, Y) :- X < 0, Y is -X. abs(X, X) :- X >= 0.
Remember that parameter transmission is by unification. You can do a lot of your work right in the parameter list. For example:
You can often simplify code by writing parameters that match only the specific case you are interested in. See
second([_, X | _], X). /* 2nd argument is 2nd element of list. */
appendfor examples. (Note: when you must program procedurally, by convention the "result'' is the last argument.)
Recursion is fully supported. In other languages you must always test
for the base case first; in Prolog, the base case can (and should) go
last, if it is such that the more general clauses will fail--see
append. If the predicate is to fail in the base case, it
can (and should) be omitted; for example, the base case for
member is the unnecessary clause:
You can't keep a value for future use by "assigning it to a variable.'' If it is temporary, local information, you can pass it around as a parameter; if it is relatively permanent information that should be globally accessible, you can put it in the database (see
member(_, ) :- fail. /* No 1st parameter is a member of  */
retractbelow). Prolog has no functions, so "results'' must be returned by instantiating one or more parameters.
Many predicates can be used as generators, to generate one solution after another until later conditions are met. For example,
succeeds and instantiates
member(X, [1, 2, 3, 4, 5]), X > 3.
4. If backed into, it re-instantiates
5. (But if you think declaratively, this just says "
Xis a member of the list
[1, 2, 3, 4, 5]that is greater than
When one clause fails, the next one is tried. If you want the failure of a clause to cause the failure of the entire predicate, you can use a cut-fail combination:
This is a procedural shortcut that avoids the necessity of having
sqrt(X, RootX) :- X < 0, !, fail.(more clauses of sqrt should follow)
X <= 0in every clause; it is justified only if the test is complex and there are many clauses.
Arithmetic is performed only upon request. For example,
2+2=4 will fail, because
4 is a number but
2+2 is a structure with functor '+'. Prolog cannot work
arithmetic backwards; the following definition of square root ought to
work when called with
sqrt(25, R), but it doesn't.
Arithmetic is procedural because Prolog isn't smart enough to solve equations, even simple ones. This is a research area.
sqrt(X, Y) :- X is Y * Y. /* Requires that Y be instantiated. */
It is possible to build a so-called fail loop in Prolog. Such a loop has the form generate-process-test; the loop repeats if the test fails. For example, the following will print the elements of a list, one per line:
However, if the processing is at all complex, it may be difficult to backtrack over it safely. Tail recursion is safer, cleaner, and usually more efficient:
print_elements(List) :- member(Element, List), write(Element), nl, fail.
Both of these fail after printing the list. If this is undesirable (and it probably is), a simple idiom is to add another clause whose purpose is to unconditionally succeed after the first clause is done:
print_elements([Head | Tail]) :- write(Head), nl, print_elements(Tail).
X. If there is no further input,
Xis unified with
Fileas the current input file.
Xto the current output file.
Xwith quotes as needed so it can be read in again.
Nblanks to the current output file.
Xto the current output file.
Fileas the current output file.
X ; Y
Xfirst; if it fails (possibly after being backtracked into), try
(X -> Y)
X, then try
Y, otherwise fail.
Ywill not be backtracked into.
(X -> Y ; Z)
X, then try
Y, else try
Xwill not be backtracked into.
not(X)) Succeed only when X fails.
true, but cannot be backtracked past, and prevents any other clauses of the predicate it occurs in from being tried.
Xto the database. For syntactic reasons, if
Xis not a base clause, use
Xto the database in front of other clauses of this predicate.
Xto the database after other clauses of this predicate.
Xis not a base clause, use
Afrom the database.
Xand whose body (right hand side) matches
V. To find a base clause, use
F (usu. as a binary image).
X is E
Eand unify the result with
X + Y
X - Y
X * Y
X / Y
X mod Y
X =:= Y
Yand compare them for equality.
X =\= Y
Yand succeed if they are not equal.
...and similarly for
Pmay be a predicate name, a structure of the form
Name/Arity, or a bracked list of the above.
Pmay be a predicate name, a structure of the form
Name/Arity, or a non-bracked list of the above.
Control over tracing is very system-dependent, but is probably like this:
Xis an atom (an empty list is considered an atom).
Xis an atom or number.
Xis a number.
Xis an integer.
Xis a real number.
Xis unbound (a non-instantiated variable).
X == Y
Yare identical (but do not unify them).
X \== Y
Yare not identical.