Question

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?

Was it helpful?

Solution

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).

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