I'm trying to define the function int(?X)
in prolog which is a non-zero integer number generator which works like this:
?- int(X). X = 1 ; X = -1 ; X = 2 ; X = -2 ;
I tried the following with no luck:
int(X):- positives(Y), Y is abs(X).
positives(1).
positives(X):- positives(Y), X is Y+1.
but I'm getting the following error:
ERROR: is/2: Arguments are not sufficiently instantiated
How can I make this work? Thanks!
There is an easy way to find and correct such problems.
Step one: Put clpfd constraints in your program. To do this, simply1 replace (is)/2
by the CLP(FD) constraint (#=)/2
, i.e.:
int(X) :- positives(Y), Y #= abs(X).
positives(1).
positives(X):- positives(Y), X #= Y+1.
Step two: The query now completes without errors, and shows you what you are describing:
?- int(X).
X in -1\/1 ;
X in -2\/2 ;
X in -3\/3 ;
X in -4\/4 .
So, from the above, you see that what you are describing is not sufficient to obtain ground solutions: There is still a certain degree of freedom in your relations.
Step three: To actually fix the problem, we think about what we actually want to describe. Here is a start:
int(X) :- positives(Y), ( X #= Y ; X #= -Y).
Step four: We try it out:
?- int(X).
X = 1 ;
X = -1 ;
X = 2 ;
X = -2 ;
X = 3 ;
etc.
Seems to work OK, except for the fact that natural numbers are actually never negative. I leave fixing this discrepancy between the title of your question and the relation you are describing as an exercise for you.
TL;DR: When reasoning over integers, use your system's CLP(FD) constraints, then take it from there.
I am assuming that you have already put :- use_module(library(clpfd)).
somewhere in your initial file, so that you can use CLP(FD) constraints in all your programs.