Reputation: 27221
I am new to Prolog. I need to write an integer adder that will add numbers between 0-9 to other numbers 0-9 and produce a solution 0-18. This is what I want to do:
% pseudo code
add(in1, in2, out) :-
in1 < 10,
in2 < 10,
out < 18.
I would like to be able to call it like this:
To check if it is a valid addition:
?- add(1,2,3).
true.
?- add(1,2,4).
false.
With one missing variable:
?- add(X,2,3).
X = 1.
?- add(1,4,X).
X = 5.
With multiple missing variables:
?- add(X,Y,Z).
% Some output that would make sense. Some examples could be:
X=1, Y=1, Z=2 ;
X=2, Y=1, Z=3 ......
I realize that this is probably a pretty simplistic question and it is probably very straightforward. However, according to the Prolog tutorial I am using:
"Unlike unification Arithmetic Comparison Operators operators cannot be used to give values to a variable. The can only be evaluated when every term on each side have been instantiated."
Upvotes: 5
Views: 1375
Reputation: 27221
Solution:
lessThanTen(9).
lessThanTen(8).
lessThanTen(7).
lessThanTen(6).
lessThanTen(5).
lessThanTen(4).
lessThanTen(3).
lessThanTen(2).
lessThanTen(1).
lessThanTen(0).
addSimple(Add1,Add2,Sol) :-
lessThanTen(Add1),
lessThanTen(Add2),
Sol is Add1+Add2.
Upvotes: 0
Reputation: 40768
All modern Prolog systems provide finite domain constraints, which are true relations that can (in contrast to more low-level arithmetic predicates like is/2 and >/2) be used in all directions. In SWI-Prolog:
:- use_module(library(clpfd)).
plus(X, Y, Z) :-
[X,Y] ins 0..9,
X + Y #= Z.
Results for your examples:
?- plus(1,2,3).
true.
?- plus(1,2,4).
false.
?- plus(X,2,3).
X = 1.
?- plus(1,4,X).
X = 5.
?- plus(X,Y,Z).
X in 0..9,
X+Y#=Z,
Y in 0..9,
Z in 0..18.
Since the predicate can be used in all directions, it does no longer make sense to call it "add/3", as that would imply a direction, but the predicate truly describes when the relation holds and is thus more general.
Upvotes: 6
Reputation: 17132
What about this?:
add(X,Y,Z) :-
Z is X + Y,
X < 10,
Y < 10,
Z < 19.
Problem: this works nicely for queries of the form add(1,1,X)
because Z
's instantiated before the <
calls, but fails when you ask add(X,1,2)
. You could use var/1
to distinguish the kind of query (var/1
tells you whether a variable's uninstantiated or not), but that sounds like a lot of pain.
Upvotes: 1