Keep getting the error "Arguments are not instantiated enough" can't figure out why
Keep getting error Arguments are not sufficiently instantiated
for the addition rule multiplication I wrote as shown below.
mult(_, 0, 0). %base case for multiplying by 0
mult(X, 1, X). % another base case
mult(X, Y, Z) :-
Y > 1,
Y1 is Y - 1,
mult(X, Y1, Z1),
Z is X + Z1.
I am new to Prolog and am really struggling with such simple problems.
Any recommendation for books or online tutorials would be great.
I am running it on SWI-Prolog on Ubuntu Linux.
source to share
I think you have removed the last two calls. You don't mean:
mult(X,Y,Z):- Y>1,Y1 is Y-1, Z1 is X+Z, mult(X,Y1,Z1).
Strike> Edit: It doesn't matter if you look at the code again, it doesn't make sense. I believe your original code is correct.
As for the reason behind this error, I need to know how you call the predicate. Can you provide an example of input?
The correct way to call the predicate is mult(+X, +Y, ?Z)
:
?- mult(5,0,X). X = 0 ?- mult(5,1,X). X = 5 ?- mult(5,5,X). X = 25 ?- mult(4,4,16). yes ?- mult(3,3,10). no
etc .. Calling this function with a free variable in the first two arguments will result in this error, because one of them will be used on the right side is
or on both sides of <
, and these predicates expect.
source to share
The mult/3
first two arguments must be known in your definition . If one of them is still a variable, a creation error will occur. For example. mult(2, X, 6)
will result in a creation error, although this X = 3
is the correct answer; in fact, the only answer.
There are several options:
successor-arithmetics, constraints, or meta-word predicates.
Here's a starting point with successor arithmetic:
add(0,Y,Y).
add(s(X),Y,s(Z)) :- add(X,Y,Z).
Another approach would be to use integer constraints. YAP and SWI have library(clpfd)
which can be used in a very flexible way: both for regular integer computation and for more general constraints. Of course, the multiplication is already predefined:
? - A * B # = C. A * B # = C. ? - A * B # = C, C = 6. C = 6, A in -6 .. -1 \ /1..6, A * B # = 6, B in -6 .. -1 \ /1..6. ? - A * B # = C, C = 6, A = 2. A = 2, B = 3, C = 6.
Meta-logic predicates: I can not recommend this option, in which you would use var/1
, nonvar/1
, ground/1
, to distinguish between different cases and handle them differently. These are so prone to errors that I have rarely seen the correct program using them. In fact, even very famous textbooks contain serious errors!
source to share