我怎样才能将这个简单的Prolog谓词变为"返回"正确的方式?

时间:2014-03-13 16:26:24

标签: prolog

所以我正在学习Prolog。我需要编写一个谓词来查找整数列表的最小值/最大值。例如,查询minmaxArray([4,-1,5,4,1,2,3,-2],X,Y)将返回X = -2 Y = 5.这是我到目前为止:< / p>

    %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.

假设mymin和mymax谓词正常工作。它们返回最多和最多2个数字。

这里的问题是,例如当我查询minmaxArray([4,-1,5],X,Y)时,它返回X = -1 Y = 5然后再次X = -1 Y = 5.我知道这必须是因为它在递归调用时遇到第二个条件。我只希望它一次返回X = -1 Y = 5。我试着用这个替换条件3:

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.

但是这会导致程序崩溃。我该怎么做才能解决这个问题?

注意:我知道我可能没有正确使用这个术语,因为我应该在规则时回复并说出谓词等,所以我提前道歉。

3 个答案:

答案 0 :(得分:2)

您提供了两种解决案例的方法,其中有2个项目:一个明确地针对2个项目,以及您的一般案例,然后使用1个元素案例。

解决方案:删除不需要的2元素案例。

答案 1 :(得分:2)

似乎您的代码可能更简单。这个谓词可以满足所有需要,并尝试展示如何使用一些标准构造(if / then / else)

minmaxArray([X], X, X).
minmaxArray([X|R], Min, Max) :-
    minmaxArray(R, Tmin, Tmax),
    ( X < Tmin -> Min = X ; Min = Tmin ), % or mymin(X,Tmin,Min)
    ( X > Tmax -> Max = X ; Max = Tmax ).

答案 2 :(得分:1)

或者,尾递归:

minmax([X|Xs],Min,Max) :- % we can only find the min/max of a non-empty list.
  minmax(Xs,(X,X),Min,Max)  % invoke the helper with the min/max accumulators seeded with the first item
  .

minmax([],(Min,Max),Min,Max).    % when the source list is exhausted, we're done: unify the accumulators with the result
minmax([X|Xs],(M,N),Min,Max) :-  % when the source list is non-empty
  min(X,M,M1) ,                  % - get a new min value for the accumulator
  max(X,N,N1) ,                  % - get a new max value for the accumulator
  minmax(Xs,(M1,N1),Min,Max)     % - recurse down on the tail.
  .

min(X,Y,X) :- X =< Y . % X is the min if it's less than or equal to Y.
min(X,Y,Y) :- X >  Y . % Y is the min if it's greater than X.

max(X,Y,X) :- X >= Y . % X is the max if it's greater than or equal to Y.
max(X,Y,Y) :- X <  Y . % Y is the max if it's greater than X.