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:
successor-arithmetics, 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!