So I am learning Prolog. I need to write a predicate that finds the min/max value of an integer list. For example, the query minmaxArray([4,-1,5,4,1,2,3,-2],X,Y) would return X = -2 Y = 5. Here is what I have so far:
%min/max element of a 1 item list is that item.
minmaxArray([X], X, X).
%when there is only 2 items, put the smaller element in A and the
%larger element in B
minmaxArray([X,Y], A, B) :- mymin(X,Y,Min),
A is Min, mymax(X,Y,Max), B is Max.
%when there is more than two items make a recursive call to find the min/max
%of the rest of the list.
minmaxArray([X,Y|T], A, B) :- minmaxArray([Y|T], M, K),
mymin(X,M,Temp), A is Temp, mymax(X,K,Temp2), B is Temp2.
Assume mymin and mymax predicates work properly. They return the min and max of 2 numbers.
The issue here is that for example when I query minmaxArray([4,-1,5],X,Y) it returns X = -1 Y = 5 and then again X = -1 Y = 5. I know this must be because it hits the 2nd condition on the recursive call. I only want it to return X = -1 Y = 5 one time. I tried replacing condition 3 with this:
minmaxArray([X,Y,_|T], A, B) :- minmaxArray([Y,_|T], M, K),
mymin(X,M,Temp), A is Temp, mymax(X,K,Temp2), B is Temp2.
but that crashes the program. What can I do to fix this?
Note: I know that I may not be using the terminology correctly by saying returning and saying predicate when it should be rule, etc so I apologize in advance.
is/2
at all--you're not doing any arithmetic. You can just sayminmaxArray([X,Y], Min, Max) :- mymin(X,Y,Min), mymax(X,Y,Max).
– Daniel Lyonsmin(X,Y)
built in as,Min is min(X,Y)
to obtain the minimum of two values. Likewise formax
. That might make your life a little simpler. And to build on @DanielLyons comment, don't useis
to unify terms. Use=/2
. So for example,B = Temp2
, notB is Temp2
. Also as pointed out, you can avoid that step altogether by unifying them right in the argument list, as his example shows. – lurkerpredicate/N
is the name of the predicate with the arity (number of arguments).=/2
is=
andis/2
isis
(that's easy to read!). You use=/2
when you want to explicitly unify two terms and you useis/2
when you want to unify the variable or value on the left side with the result of evaluating the arithmetic expression on the right side. – Daniel Lyons