问题
I have the following prolog program:
set_1(2).
p(X) :- set_1(X+1).
I'm using SWI-Prolog version 5.10.4 for i386 to run the query p(1) on this program.
The answer is 'false'.
I expect the answer to be 'true', because set_1(X+1) should be grounded as set_1(2) and resolved with the first fact.
Why the answer is false and how can I get 'true' ?
回答1:
If you want X+1
to unify with 2 in your example, you'll need to code this using is/2
.
By itself X+1
is a valid Prolog term, but even when X
is unified with 1
, the term becomes 1+1
, not the 2
you expected.
Try instead:
p(X) :- Y is X+1, set_1(Y).
Added: It's probably worth pointing out that the extreme "laziness" of Prolog in evaluating arithmetic expressions allows us to push down responsibility for evaluation from p/1
into set_1/1
, at the expense of having to make that predicate a rule rather than a simple fact.
1 ?- [user].
|: set_1(X) :- 2 is X.
|: p(X) :- set_1(X+1).
|: {Ctrl-D}
% user://1 compiled 0.00 sec, 3 clauses
true.
2 ?- p(1).
true.
Predicate is/2
is not the only SWI-Prolog built-in that compels arithmetic expression evaluation. See here for a complete rundown. In particular predicate =:=
(with infix notation), comparing whether two expressions have equal evaluations, might be useful in some cases.
来源:https://stackoverflow.com/questions/18690788/arithmetic-expression-in-swi-prolog