Example: here is the definition of the built-in Prolog predicate member
:
member(X, [X | Rest]). % X is a member if its the first element member(X, [Y | Rest]) :- member(X, Rest). % otherwise, check if X is in the RestYou may not think of
member
as a backtracking predicate, but backtracking is built into Prolog, so in suitable circumstances, member
will backtrack:
?- member(X, [a, b, c]). X = a ; X = b ; X = c ; false.Here
member
backtracks to find every possible solution to the query given to it. Consider also:
?- member(X, [a, a, a]). X = a ; X = a ; X = a ; false.Here
member
backtracks even though it keeps on finding the same answer. What about
?- member(a, [a, a, a]). true ; true ; true ; false.This is because prolog has three ways of proving that
a
is a member of [a, a, a]
.
The term backtracking also applies to seeking several sets of variable bindings to satisfy a single goal.
In some circumstances, it may be desirable to inhibit backtracking, as when only a single solution is required. The Prolog cut goal allows this.
Tracing the execution of a piece of Prolog code that backtracks can be a good way to figure out what happens during backtracking. If you wanted to experiment with backtracking by tracing member
, you could achieve this by copying the code for member
, given above, changing the name from member
to say mem
in the three places where it appears, and then tracing your mem
procedure.
bagof
bagof(+Template, +Goal, -Bag)
is used to collect a list Bag
of all the items Template
that satisfy some goal Goal
. Example: assume
likes(mary, pizza). likes(marco, pizza). likes(Human, pizza) :- italian(Human). italian(marco).Then
?- bagof(Person, likes(Person, pizza), Bag). Person = _G180 Bag = [mary, marco, marco]
Notice that Bag
contains the item marco
twice, because there are two ways to prove that marco
likes pizza - the fact and via the rule. bagof
fails if Goal
has no solutions.
See also setof
, and, for differences between bagof
and findall
, see findall
.
Suppose that the Prolog database contains just the single fact likes(mary, pizza).
and that there is a query:
?- likes(mary, What).
Prolog will search the (tiny) database, find that the query can be satisfies if What = pizza
, do it will bind What
to pizza
and report success:
?- likes(mary, What). What = pizza ; false.
Now suppose that there is a rule and facts in Prolog's database:
teaches(Teacher, Student):- lectures(Teacher, Subject), studies(Student, Subject). lectures(codd, databases). studies(fiona, databases). studies(fred, databases).
and that the user issues the query:
?- teaches(codd, Who).
The Prolog interpreter first matches the head of the rule with the query, and so binds Teacher
to codd
. It then finds a fact that indicates a subject that Codd lectures - namely lectures(codd, databases)
. At this point, the variable Subject
is bound to databases
(Subject = databases
). In other words, Subject
, perhaps temporarily, has the value databases
. Then Prolog tries to satisfy the second goal studies(Student, Subject)
with Subject = databases
, i.e. it tries to satisfy studies(Student, databases)
. When it finds the solution, studies(fiona, databases)
it will bind Subject
to fiona
, and report the solution:
?- teaches(codd, Who). Who = fiona
Notice that the binding Subject = databases
was made in solving the query, but it is not reported, as it is not explicitly part of the query.
Then, if the user types ";"
, Prolog will backtrack and undo the binding Student = fiona
and look for another value for Subject
that satisfies studies(Student, databases)
, and find as Student = fred
. However, while binding (and unbinding) is involved in this step, it is properly treated under backtracking.
:-
. It has the form of a comma-separated list of goals, each of which is a functor, possibly followed by a comma-separated list of arguments, in parentheses. E.g. in the rule
sister_of(X,Y) :-
female(Y),
X == Y,
same_parents(X,Y).
the three goals female(Y), X == Y, same_parents(X,Y)
form the body.
abs
, atan
, ceiling
, cos
, exp
, float
, floor
, log
, round
, sign
, sin
, sqrt
, tan
, truncate
Function | Meaning |
abs(Exp) |
absolute value of Exp : i.e. Exp if Exp ≥ 0, –Exp if Exp < 0 |
atan(Exp) |
arctangent (inverse tangent) of Exp : result is in radians |
cos(Exp) |
cosine of the Exp : Exp is in radians |
exp(Exp) |
eExp : e is 2.71828182845... |
log(Exp) |
natural logarithm of Exp : i.e. logarithm to the base* e |
sin(Exp) |
sine of the Exp : Exp is in radians |
sqrt(Exp) |
square root of the Exp |
tan(Exp) |
tangent of the Exp: Exp is in radians |
sign(Exp) |
sign (+1 or –1) of the Exp: sign(–3) = –1 = sign(–3.7) |
float(Exp) |
float of the Exp: float(22) = 22.0 - see also float the predicate |
floor(Exp) |
largest integer ≤ Exp: floor(1.66) = 1 |