Question

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' ?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top