3
votes

I've just tried to implement absolute function in Prolog and I've got some strange behavior. My code was:

absval(X, RESULT) :- X >= 0, RESULT is X.
absval(X, RESULT) :- X < 0, RESULT is -X.

And when I try in SWI-Prolog absval(-2,X). I get

X = 2

yes

as expected. But otherwise when I invoke absval(2,X), I get X = 2 ? and I should insert another input. After pressing enter I get also yes.

What does mean the second one result? What's wrong with my solution?

2
The behavior you encounter can be explained by the fact that your program is not deterministic. There are two rules for absval/2. So, after Prolog satisfies absval(2,X) using the first rule, it backtracks in order to resatisfy the goal. The first subgoal (X < 0) of the second rule will fail and you will not get a second solution. In order to have a deterministic behavior, add a cut operator after X>=0 like this: absval(X, RESULT) :- X >= 0, !, RESULT is X..Tudor Berariu

2 Answers

2
votes

what you report doesn't match the behaviour I get here:

?- absval(2,X).
X = 2 ;
false.

that's actually what is expected.

If you need to make it deterministic, use a cut, or better, the 'if/then/else' construct:

absval(X, RESULT) :- X >= 0 -> RESULT is X ; RESULT is -X.
1
votes

A deterministic version using a single clause without cuts of if-then-else constructs:

absolute_value(Value, AbsoluteValue) :-
    AbsoluteValue is sign(Value) * Value.

Note that sign/1 is a standard built-in arithmetic function.