求max,需要list的所有元素都是绝对值

Finding max, need all elements of list to be absolute value

这是我的代码,问题是列表的最后一个元素不是绝对值。有人可以帮忙吗?

maxlist( [X], X ).
maxlist( [X,Y|Rest], AbsMax ) :-
  abs( [X], AbsX ),
  maxlist( [Y|Rest], AbsMaxRest ),
  max( AbsX, AbsMaxRest, AbsMax ).


max( X, Y, X ) :- X >= Y.
max( X, Y, Y ) :- X <  Y.

abs( [X], Y ) :-
  X < 0 -> Y is -X ; Y = X.

对于这样的列表:

maxlist( [-4110,-11,-885,-45,-154,-995] , X )

我得到 X = 4110,但对于最后一项

maxlist( [-995,-11,-885,-45,-154,-4110], X )j

我得到 X = 995,而我应该得到 4110

您的代码中的根本问题是列表的最后一个元素从未采用其绝对值。此外,您不需要为绝对值或最大值实现谓词:它们已融入 Prolog。

Prolog 中的一个常见习语是使用带有“私有”辅助谓词的 public 谓词,该辅助谓词采用一个或多个附加参数,这些参数携带计算所需的状态。这也有助于将事情转化为尾递归优化所需的形式,其中通过允许重用堆栈框架将递归转换为简单的迭代。

尝试这样的事情:

max_list( [X|Xs] , M ) :-     % to compute the maximum absolute value of a list ...
  A is abs( X ) ,             % * Pop the head of the list and take its absolute value, then...
  max_list( Xs, A, M ) .      % * Invoke the helper, seeding the accumulator with A

max_list( []     , M , M ) .  % If the source list is empty, we're done.
max_list( [X|Xs] , T , M ) :- % Otherwise...
  X1 is abs(X) ,              % * Take the absolute value of X
  T1 is max(X1,T) ,           % * Determine the max of X1 and T
  max_list(Xs, T1, M )        % * Recurse down with the remainder of the list and the new accumulator value
  .                           % Easy!

如果您需要自己弄清楚 maxabs,这很简单:


max( X , Y , Max ) :- X >  Y -> Max is X ; Max is  Y .
abs( X ,     Abs ) :- X >= 0 -> Abs is X ; Abs is -X .
maxlist([X],X).
maxlist([X,Y|Rest],AbsMax) :- 
abs(X,AbsX),
abs(Y,AbsY), 
maxlist([AbsY | Rest],AbsMaxRest),
max(AbsX,AbsMaxRest,AbsMax).
max(X,Y,X) :- X>= Y.
max(X,Y,Y) :- X < Y.
abs(X,Y) :- X < 0 -> Y is -X ; Y = X.

这解决了整个整数列表