Prolog从列表中挑选并汇总特定值

时间:2014-12-12 18:12:06

标签: prolog

sumPicker([[]|_], Y, Z).
sumPicker([X|X1], Y, Z):-
   downList(Y, X, Sum),
   Total is Z,
   Z is Total + Sum,
   sumPicker(X1,Y, Z).
downList([Z|_], 1, Z).
downList([_|B],Count, Number):- Count > 1,
   SendCount is Count - 1,
   downList(B, SendCount, Number).

所以这段代码基本上假设接受两个列表sumPicker([3,5],[1,2,3,4,5,6],X)。程序然后取第一个列表并根据数字的值,所以在这种情况下3,它将在第二个列表中找到第三个数字,然后它将找到第二个列表的第5个数字并将它们加在一起。

错误:是/ 2:参数没有充分实例化是我得到的

1 个答案:

答案 0 :(得分:0)

我假设您的导师希望您自己计算递归,而不是使用内置列表操作。为此,您可以使用类似的方法,根本不使用内置函数。

一个常见的prolog习语是拥有一个简单的" public"谓词调用"帮助"携带状态的谓词(在这种情况下,列表中的当前位置和运行总和)。通常,那个"帮手"谓词将具有与公共谓词相同的仿函数(名称),具有更高的arity(参数数量)。

所以,首先我们有公共谓词sum_of_desired/3

sum_of_desired( Indices , Numbers , Sum ) :-      % to sum certain list elements,
  sum_of_desired( Indices , Numbers , 0 , Sum ) - % invoke the helper
  .                                               %

所有这一切都是调用助手sum_of_desired/4。这个辅助谓词带有一个额外的参数,即 state :一个包含运行总和的累加器。成功时,该运行总额与最终总数统一。这是因为,在Prolog中,您无法更改变量的值:一旦为变量赋值,就不再是变量。它成为统一的(它被称为统一)。撤消该分配的唯一方法是通过回溯

通常,递归问题有一些特殊情况和更一般的情况。所以,在这里,我们的帮助器谓词有两个子句:

  • 第一个子句是特殊情况:所需索引的列表为空,在这种情况下,finally sum是累加器的当前值(最初为0)。
  • 第二个子句是递归的一般情况:在这里我们找到所需的列表项,将其添加到运行总计并递减,然后转到所需列表项列表中的下一个项目。

    sum_of_desired( []     , _ , S , S ) .  % the list of desired indices is empty: unify the   accumulator with the result.
    sum_of_desired( [I|Is] , L , T , S ) :- % otherwise...
      get_nth_item(I,L,N) ,                 % - get the nth item from the list
      T1 is T+N ,                           % - add it to the running total
      sum_of_desired(Is,T1,S)               % - and recurse down
      .                                     %
    

最后,这个谓词get_nth_item/3简单地递归遍历列表,在列表中查找n th 项,其中n相对于1(例如,列表中的第一项是索引1)。当它找到它时,它将作为谓词的第三个参数返回。

同样,在这里你会注意到我们有一个终止特殊情况和更一般的递归特殊情况

get_nth_item( 1 , [X|_]  , X ) .  % found it!
get_nth_item( N , [_|Xs] , R ) :- % otherwise...
  N > 1 ,                         % - if N > 1 , 
  N1 is N-1 ,                     % - decrement N
  nth_item( N1 , Xs , R )         % - recurse down.
  .                               % - easy!