hisoka
hisoka

Reputation: 354

Prolog - Arguments insufficiently instantiated

I am new to prolog, and I have built the following sample function:

bar(Fruit) :-
   Fruit = fruit(apple, X),
   A is abs(X) + 0,
   between(0,10,A).

foo(L) :-
   findall(X, bar(fruit(apple, X)), L).

Calling foo(L) gives the error : ERROR: is/2: Arguments are not sufficiently instantiated.

Now, I've read around multiple threads in which the recurring solution is to use clpfd where A #= abs(X) + 0. However, when using that solution I do not necessarily get the list I want :

L = [0, _G9407, _G9410, _G9413, _G9416, _G9419, _G9422, _G9425, _G9428|...],
clpfd:in(_G9407, -1\/1),
clpfd:in(_G9410, -2\/2),
clpfd:in(_G9413, -3\/3),
clpfd:in(_G9416, -4\/4),
clpfd:in(_G9419, -5\/5),
clpfd:in(_G9422, -6\/6),
clpfd:in(_G9425, -7\/7),
clpfd:in(_G9428, -8\/8),
clpfd:in(_G9431, -9\/9),
clpfd:in(_G9434, -10\/10).

Especially when using a more complex function it becomes very hard to read as well.. The output I was expecting is essentially a clear and simple list : [-10...10]. Is there any alternative to this without clpfd? I have also learned through the process that I get the similar errors using logical operators such as <, >, >=, =< which pushes me to use between. I am coming from an OOP background, and I have a hard time grasping what the logical flaw is..

Thanks for the help,

Upvotes: 1

Views: 192

Answers (1)

Tomas By
Tomas By

Reputation: 1394

Prolog is mostly relational in the sense that you can often calculate in both directions, but not with maths. is/2 requires that the RHS is a value (no uninstantiated variables). And you cannot use abs(X) to get both +X and -X, which is what you seem to expect. + 0 is not useful, but I guess you have just simplified from something else.

This works:

bar(Fruit) :-
  Fruit = fruit(apple, X),
  between(0,5,A),
  ( X = A ; X is -A ).

giving

?- foo(L).
L = [0, 0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5].

But it sounds like you may want to use CLP(FD) for what you want to do.

Upvotes: 1

Related Questions