3

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?

false
  • 10,264
  • 13
  • 101
  • 209
pt12lol
  • 2,332
  • 1
  • 22
  • 48
  • 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 May 17 '14 at 17:49

2 Answers2

2

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.
CapelliC
  • 59,646
  • 5
  • 47
  • 90
1

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.

Paulo Moura
  • 18,373
  • 3
  • 23
  • 33
  • `abs` also. I try to express if/else construction from procedural language using multiple functors. – pt12lol May 17 '14 at 18:52