A Prolog Introduction For Hackers
A Prolog Introduction For Hackers
org/print/2004/2/25/124713/784
Prolog is, essentially, a query language for databases, like SQL. However,
unlike SQL, which is a limited query language for relational databases,
(tables of rows and columns, much like a spreadsheet) Prolog is a query
language for matching complicated patterns against a database of simple
facts.
Thus, all Prolog programs consist of three parts: a list of facts, a list of
pattern matching rules (sometimes also called predicates in Prolog jargon)
and a list of queries. (Also sometimes called goals in Prolog jargon.)
Prolog facts
Numbers.
Symbols, which are, for all intents and purposes, immutable strings
of lower-case letters without special characters or spaces. (We'll
explain why symbols must be lower-case later.)
Ex: [hello, cruel, world], [1, 2, 3], [1, hello, 2, world], [].
1 of 9 2/3/2010 7:59 AM
kuro5hin.org || technology and culture, from the trenches http://www.kuro5hin.org/print/2004/2/25/124713/784
Note that the following is illegal in Prolog: f(). Patterns without arguments
are written without parentheses, like this: f.
Also note that pattern arguments can have any of Prolog's datatypes, thus
symbol, number and list arguments are allowed.
f(hello, world).
g([hello, world]).
standard_greeting([hello, world], 2).
This simple program inserts five pre-defined patterns into Prolog's internal
database. (hello and world, two patterns without arguments; f(hello, world),
a pattern f with two arguments; g([hello, world]), a pattern g with one
argument, a list; and standard_greeting([hello, world], 2), a pattern
standard_greeting with 2 arguments, a list and a number)
When several patterns are defined with the same name and the same
number of arguments, Prolog will run through them, one after another in
a top-to-down fashion, when trying to match them. (You can think of this
as a short-circuited "OR" of pattern matching rules.)
Whenever Prolog sees the special symbol :-, Prolog creates a new pattern-
matching rule. The basic meaning of :- is very simple: to match whatever
is to left of the :-, the part to the right must be matched. This allows to
"decompose" complex patterns into smaller, more manageable ones.
To make the task practical, Prolog defines many operators that help us in
the task of composing pattern-matching rules. Some of the more
important and useful are:
2 of 9 2/3/2010 7:59 AM
kuro5hin.org || technology and culture, from the trenches http://www.kuro5hin.org/print/2004/2/25/124713/784
Ex:f :- a, b, c.
Ex:f :- p; q; r.
This code means that Prolog first tries to match pattern g; if the
pattern can be matched, try to match the pattern h. If g cannot be
matched, try to match the pattern i.
Note that the construct must be enclosed in parentheses, due to
strangeness in Prolog's syntax rules.
Ex:f :- \+ g.
This code means that the pattern f matches whenever the pattern g
cannot be matched.
Variables
A simple example will illustrate the concept better. Consider the following
Prolog program:
i_know(hello).
i_know(world).
3 of 9 2/3/2010 7:59 AM
kuro5hin.org || technology and culture, from the trenches http://www.kuro5hin.org/print/2004/2/25/124713/784
This program defines two facts (i_know(hello) and i_know(world)) and two
pattern-matching rules.
A=hello, B=hello
A=hello, B=world
A=world, B=world
A=world, B=hello
Finally, we can figure out what the pattern is_greeting(A, B) does. Here,
Prolog searches for substitutions for A and B such that a match against the
known facts is found.
Expanding all the pattern-matching rules, Prolog will find the following
substitutions:
A=hello, B=hello
A=hello, B=world
As you can see, using just a few basic Prolog operators and Prolog's
advanced search engine, we can build pattern-matching rules of arbitrary
complexity. It is here that Prolog's power really shines though: Prolog
allows to build very complicated matching rules very easily. Thus, Prolog is
designed for use in applications where we have just a few very simple
facts, but a lot of very complex search rules.
Contrast this with SQL, which has been designed for the opposite
situation: a great amount of very complex data with very simple, very
basic search rules.
Programming in Prolog
4 of 9 2/3/2010 7:59 AM
kuro5hin.org || technology and culture, from the trenches http://www.kuro5hin.org/print/2004/2/25/124713/784
Input and output in Prolog is done with special pattern rules that always
match, and produce output or return input as a side effect. Since there are
a great number of implementation-specific input and output functions, I
will describe two of the most basic, to give the general idea. If you want to
learn more, consult the manual of your Prolog implementation.
Basic input is equally simple: the pattern-matching rule read(A) will ask the
user to input a value, using Prolog syntax, substitute the typed value for A
and match successfully. For example, this simple pattern-matching rule of
zero arguments will simply output whatever value the user typed: echo :-
read(A), write(A), nl.
For arithmetic, Prolog uses a special operator called is. This operator is
just like the = operator, except that on the right side must be an
arithmetic expression, not a pattern. For example, A is B + 1 will substitute
a value for A that is equal to B + 1. Due to the special syntax of the is
command, it is not commutative. Thus, B + 1 is A will give an error. This
means that there is always a variable to the left of the is.
Note, however, that the is operator is still nothing but a special pattern-
matching rule; so, for example, A is A + 1 is an invalid expression that will
likely give an error, since no number can be substituted such that the
number becomes equal to itself incremented by one. If this makes little
sense, try making some simple substitutions in your head: 5 is 5 + 1
violates the basic rules of arithmetic.
Prolog queries
5 of 9 2/3/2010 7:59 AM
kuro5hin.org || technology and culture, from the trenches http://www.kuro5hin.org/print/2004/2/25/124713/784
Queries, or goals, are a way for the user to interact with Prolog's internal
database and pattern-matching rules. Almost all Prolog implementations
include an interactive shell where the user can type arbitrary patterns;
Prolog then tries to match the given pattern, outputting whatever variable
substitutions are needed to match the pattern. This provides an easy and
powerful way to interact with Prolog in real-time, typing in search queries
and getting back results immediately.
yes
?- f(hello).
yes
?- f(foo).
no
?- is_phrase(hello, world).
yes
?- is_phrase(hello, _).
yes
?- is_greeting(A, B).
A = hello,
B = hello ? ;
A = hello,
B = world ? ;
no
?- is_greeting(_, B).
B = hello ? ;
B = world ? ;
no
?- hello.
yes
?- foo.
{ERROR: user:foo/0 - undefined predicate}
no
?-
The ?- is the standard Prolog prompt; it means that the user is invited to
type in a Prolog pattern, ending with a period, as all Prolog statements.
Note, also, that Prolog returns either a yes or a no after each query; a yes
means that Prolog was able to match the query against its internal
database; a no means, respectively, that Prolog was unable to find a
match. (Notice that trying to use an undefined pattern foo caused a Prolog
error.) When Prolog encounters variables in the query (like A and B in this
example) Prolog prompts us before returning each found value for the
variable, one by one. Finally, there is a special variable called _, which
means that we do not care about the values of this variable and do not
want them printed.
6 of 9 2/3/2010 7:59 AM
kuro5hin.org || technology and culture, from the trenches http://www.kuro5hin.org/print/2004/2/25/124713/784
An extended example
fac(0,1).
fac(N,R) :- P is N-1, fac(P,Q), R is N*Q.
Using this pattern is simple: typing the query fac(5,R)., for example, gives
the result: R = 120. When playing around a little, though, many deficiencies
start becoming apparent, including unwanted infinite loops and the fact
that fac(N,120) doesn't give the expected result. The reason for this is the
fact that Prolog is very ill-suited for numerical computation; arithmetic in
Prolog is a hack, and doesn't integrate well into the Prolog search engine
too well.
fac2(0,R,R).
fac2(N,Acc,R) :- P is N-1, Q is N*Acc, fac2(P,Q,R).
Usage: fac2(5,1,R).
Reversing a list:
% cat(A, B, C) : C is the concatenation of lists A and B.
cat([], R, R).
cat([H|T1], Z, [H|T2]) :- cat(T1, Z, T2).
rev([], []).
rev([H|T], Q) :- rev(T,P), cat(P,[H],Q).
(Here we first encounter the special Prolog syntax for handling lists; the
special system pattern [H|T] matches any list whose first element is H with
T being the rest of the list without the first element.)
Using this pattern is simple: rev([1, 2, 3],R). In other words, find all such R
that rev([1, 2, 3],R) matches the Prolog pattern-match rule database.
Notice, however, that rev(R,[1,2,3]) gives us the same result! This is
obvious if you think a little bit about the nature of Prolog's pattern-
matching engine.
rev2([], R, R).
rev2([H|T], Z, R) :- rev2(T, [H|Z], R).
7 of 9 2/3/2010 7:59 AM
kuro5hin.org || technology and culture, from the trenches http://www.kuro5hin.org/print/2004/2/25/124713/784
when it processes lists and other symbolic data: not only does rev2(A, [],
[1, 2, 3]) produce the expected results, but rev2([1, 2, 3], B, [3, 2, 1])
produces B = [], and rev2([1, 2, 3], A, [3, 2]) returns us a pattern-match
failure.
Addendum
No, it is not. Prolog has several system patterns that were (very) loosely
inspired by formal logic; these were designed to ease the use of Prolog for
those people that are already familiar with formal logic. However, if you
persist with your delusion that Prolog is a language for "handling logic
predicates", you will get bitten sooner or later! (And probably sooner than
later.)
Standard Prolog
Strange language
Open-Source Prolog
Try it yourself
You can try interacting with a Prolog shell without installing a Prolog
implementation here. (The link points to tuProlog, an Open-Source Prolog
written on top of the JVM and embeddable into standard Java
applications.)
For fun
Just in case you are wondering how Prolog can be used in the "real world",
8 of 9 2/3/2010 7:59 AM
kuro5hin.org || technology and culture, from the trenches http://www.kuro5hin.org/print/2004/2/25/124713/784
Warning to Americans
Despite this, do not be afraid; Prolog is a very useful tool in its own right.
Good luck.
All trademarks and copyrights on this page are owned by their respective companies. The Rest © 2000 - 2006 Kuro5hin.org Inc.
9 of 9 2/3/2010 7:59 AM