Domanda

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?

È stato utile?

Soluzione

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top