A query succeeds if each of its goals succeeds.
mar
and date
and the structuredate(2004, mar, 21)
are terms. So are the numbers 2004
and 21
, for that matter. So in date(2004, mar, 21)
, the primary functor is date
, the arity is 3, and the arguments are 2004
, mar
, and 21
.
In general, a term of arity n can be an atom (the functor) followed by narguments, which will be enclosed in parentheses ( )
and separated by commas. Note that the arity might be 0, in which case there are no parentheses, commas, or arguments. A term can also be a number. Sometimes the term can use an infix operator like <
, in which case the functor appears between the arguments (if the arity is 2) or before the argument but without parentheses (if the arity is 1).
For +
and –
(and occasionally?
) signs in front of arguments, in procedure header comments, see comments.
atom
, atomic
, compound
, float
, integer
, nonvar
, number
, var
It may be useful to be able to test if a term is an number or a variable or something else. Prolog provides several such tests:
Goal | succeeds if X is ... |
var(X) | an uninstantiated variable |
nonvar(X) | not a variable, or is an instantiated variable |
compound(X) | a compound term - not an unbound variable, and not atomic (see below) |
atom(X) | an atom, or bound to an atom |
integer(X) | an integer, or bound to an integer |
float(X) | a floating point (fractional) number such as 3.5 or 1.0, or bound to one - but, if float(X) is evaluated using is , then you get thisfloat |
number(X) | a number, or bound to a number (integer or float) |
atomic(X) | a number, string, or atom, or bound to one |
To turn on tracing in Prolog, execute the "goal"
?- trace.true.
When you are finished with tracing, turn it off using the "goal"
?- notrace.
Here is an example of trace
in action. First some code, which computes factorial N - the product of the numbers from 1 to N. By convention, factorial 0 is 1. Factorial N is often written N!, where the exclamation mark signifies the "factorial operator". Here is the code:
factorial(0, 1). | rule 1 | factorial(0) = 1 |
The tables above and below may not display correctly if viewed in a narrow window. If the commentary doesn't seem to line up correctly with the text to the left of it, try making your browser window wider.
Prolog dialog/trace output | Commentary |
---|---|
prolog -s factorial.pl blah blah blah ... ?- trace.true. [trace] ?- factorial(3, X). Call: (7) factorial(3, _G284) ? creep* ^ Call: (8) 3>0 ? creep ^ Exit: (8) 3>0 ? creep ^ Call: (8) _L205 is 3-1 ? creep ^ Exit: (8) 2 is 3-1 ? creep Call: (8) factorial(2, _L206) ? creep ^ Call: (9) 2>0 ? creep ^ Exit: (9) 2>0 ? creep ^ Call: (9) _L224 is 2-1 ? creep ^ Exit: (9) 1 is 2-1 ? creep Call: (9) factorial(1, _L225) ? creep ^ Call: (10) 1>0 ? creep ^ Exit: (10) 1>0 ? creep ^ Call: (10) _L243 is 1-1 ? creep ^ Exit: (10) 0 is 1-1 ? creep Call: (10) factorial(0, _L244) ? creep Exit: (10) factorial(0, 1) ? creep ^ Call: (10) _L225 is 1*1 ? creep ^ Exit: (10) 1 is 1*1 ? creep Exit: (9) factorial(1, 1) ? creep ^ Call: (9) _L206 is 1*2 ? creep ^ Exit: (9) 2 is 1*2 ? creep Exit: (8) factorial(2, 2) ? creep ^ Call: (8) _G284 is 2*3 ? creep ^ Exit: (8) 6 is 2*3 ? creep Exit: (7) factorial(3, 6) ? creep X = 6 ; Redo: (10) factorial(0, _L244) ? creep ^ Call: (11) 0>0 ? creep ^ Fail: (11) 0>0 ? creep Fail: (9) factorial(1, _L225) ? creep Fail: (8) factorial(2, _L206) ? creep Fail: (7) factorial(3, _G284) ? creep false. [debug] ?- notrace. % turn off tracing true. [debug] ?- |
|
There are further tracing facilities in SWI Prolog. Do
?- help(trace).to start to find out about them.
Built-in Prolog functions are not traced - that is, the internals of calls to things like member
are not further explained by tracing them.
true
See also fail
, repeat
.
_
(underscore) is a "don't-care" variable, which will match anything (atom, number, structure, ...). For example, the rule
bad(Dog) :- bites(Dog, _).
says that something (Dog
) is bad if Dog
bites anything. The "anything" is represented by _
. Unlike other variables in Prolog, a bare _
can match different things in the same rule. So, for example, if gives(From, To, Gift)
is a three-place procedure that is true if From
gives Gift
to To
, then
giver(X) :- gives(X, _, _).
signifies that someone (X
) is a "giver" if X
gives something to anybody - the two _
s don't have to match the same thing. So if gives(fred, john, black_eye).
is stored in the Prolog database, then the rule above allows us to infer that fred
is a giver.
To be more explicit about the meaning of your rule, you could instead write:
bad(Dog) :- bites(Dog, _Anybody).This indicates what the
_
variable is actually representing, but has the feature that the binding of _Anybody
typically doesn't get reported when Prolog finds a solution. In Prolog interpreters that report singleton variables (variables that are only used once in a rule - often these are caused by typographical errors in the code, which is why Prolog warns you about them) do not report singleton variables that begin with _
. This is useful is you are trying to get rid of warning messages in your Prolog code.
The rule
bad(Dog) :- bites(Dog, _Anybody).in fact has a bug, in the sense that the _Anybody will match things (like dogfood) that a dog might bite without being "bad". Maybe the rule should say instead:
bad(Dog) :- bites(Dog, Something), is_person(Something). % add your own list of prohibitions - shoes, cats, ...
Prolog systems make internal use of variable names beginning with an underscore, e.g. _G157
. These are not "don't-care" variables, but are chosen to not clash with any variable name a Prolog programmer is likely to use.
Underscores may also be used in the middle of variable or atom names, as in Intermediate_solution
, likes_person
- again, these are not "don't-care" variables. The idea is to make the variable or atom name more readable.