Reputation: 33
I am trying to learn Prolog for an exam.
According to my slides arithmetic expressions do not unify with constants. Is there a reason for?
for example
even(0).
even(X) :- X>0, odd(X-1).
odd(1).
odd(X) :- X>1, even(X-1).
?-even(2).
=> false.
The 0
doesn't unify with (X-1)
.
So my Question is: Would it be a problem in some case if there was unification between constants and arithmetic expressions?
Upvotes: 2
Views: 776
Reputation: 58224
The problem with those clauses is that Prolog doesn't evaluate arithmetic expressions inline as arguments to queries to predicates.
So this:
even(X) :- X>0, odd(X-1).
odd(X) :- X>1, even(X-1).
If queried as even(2)
will result in:
2 > 0, % success
odd(2-1). % hmmm
Then odd(2-1)
(which really means odd('-'(2,1))
) won't match odd(1)
, it will go to odd(X)
and give:
2-1>1, % This will evaluate, but will fail because 1>1 is false
Since >/2
is an evaluating comparison, it does the evaluation. But it's too late for that, since the wrong clause has been selected. So you get failure.
You need to pre-evaluate:
even(0).
even(X) :- X>0, X1 is X-1, odd(X1).
odd(1).
odd(X) :- X>1, X1 is X-1, even(X1).
Prolog will evaluate expressions that are on the second argument of is/2
, such as:
Y is (X+1)/2.
Or if in comparison operators that compare numerically. For example, the following will evaluate the expressions before comparison:
Y+7 < X*2
X/2 =:= Y mod 2
Note that =/2
does not evaluate expressions. It is a unification operator. So:
X-2 = Y*2
Would fail because it attempts to unify '-'(X,2)
with '*'(Y,2)
.
Upvotes: 4