I am new to logic programming and Prolog. The following Prolog program defines a predicate add/3 for multiplying the first argument to the second argument, which results in the third argument, based on the equation x + y = z which is equivalent to (x − 1) + y = (z − 1):
add(0, Y, Y) :-
number(Y).
add(X, Y, Z) :-
number(X),
number(Z),
succ(U, X),
succ(V, Z),
add(U, Y, V).
But it this query, supposed to solve the equation 1 + 0 = z, does not return the expected result (1):
?- add(1, 0, Z).
false.
How to fix this recursive addition?
The reason you get
falseis because the second clause ofadd/3callsnumber(Z)which only succeeds for ground number variables, but you are calling it withZuninstantiated.number/1cannot be used as a generator.Removing that goal will in turn give you another error, now in
succ(V, Z)as you end up calling it with both variables uninstantiated and that predicate requires that at least one of its arguments be instantiated.You can swap the goal with the recursive call to
add/3so thatVgets instantiated prior to callingsucc/2. Assucc/2already checks its arguments I will just remove the check forXbeing a number.This procedure now should work for mode +,+,?. It will not work right for other modes. You may want to check CLP(fd).
To make it work with at most 1 unbound variable within the three parameters you may split the recursive step on two different paths so as to ensure the first call to
succ/2has 1 bound variable and the second call tosucc/2has at least 1 bound variable.which essentially selects an equation which can be evaluated with Prolog arithmetics.