Question

Keep getting the error Arguments are not sufficiently instantiated for the multiplication by addition rule 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 really struggling with even such simple problems.

Any recommendations for books or online tutorials would be great.

I am running it on SWI-Prolog on Ubuntu Linux.

Was it helpful?

Solution

I think you got the last two calls reversed. Don't you mean:

mult(X,Y,Z):- Y>1,Y1 is Y-1, Z1 is X+Z, mult(X,Y1,Z1).

Edit: nevermind that, looked at the code again and it doesn't make sense. I believe your original code is correct.

As for why that error is occuring, I need to know how you're calling the predicate. Can you give an example input?

The correct way of calling your 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 it with a free variable in the first two arguments will produce that error, because one of them will be used in the right side of an is or in either side of the <, and those predicates expect ground terms to succeed.

OTHER TIPS

In your definition of mult/3 the first two arguments have to be known. If one of them is still a variable, an instantiation error will occur. Eg. mult(2, X, 6) will yield an instantiation error, although X = 3 is a correct answer ; in fact, the only answer.

There are several options you have:

, constraints, or meta-logical predicates.

Here is a starting point with successor arithmetics:

add(0,Y,Y).
add(s(X),Y,s(Z)) :- add(X,Y,Z).

Another approach would be to use constraints over the integers. YAP and SWI have a library(clpfd) that can be used in a very flexible manner: Both for regular integer computations and the more general constraints. Of course, 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-logical predicates: I cannot recommend this option in which you would use var/1, nonvar/1, ground/1 to distinguish various cases and handle them differently. This is so error prone that I have rarely seen a correct program using them. In fact, even very well known textbooks contain serious errors!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top