求和平方根列表元素

时间:2014-04-15 21:08:44

标签: prolog

所以我目前正在尝试使用Prolog计算公式。我目前已完成部分公式,但我无法实现下一部分,我需要添加列表的元素,然后将总和平方根。不知道我会怎么做。

我现在有什么:

formula([], [], []).
formula([], [H2|T2], [L|Ls]) :-
  L = H2,
  formula([], T2, Ls).
formula([H1|T1], [], [L|Ls]) :-
  L = H1,
  formula(T1, [], Ls).
formula([H1|T1], [H2|T2], [L|Ls]) :-
  L is (H1 - H2)*(H1 - H2),
  formula(T1, T2, Ls).

2 个答案:

答案 0 :(得分:3)

您的原始公式

formula([], [], []).
formula([], [H2|T2], [L|Ls]) :-
  L = H2,
  formula([], T2, Ls).
formula([H1|T1], [], [L|Ls]) :-
  L = H1,
  formula(T1, [], Ls).
formula([H1|T1], [H2|T2], [L|Ls]) :-
  L is (H1 - H2)*(H1 - H2),
  formula(T1, T2, Ls).
可以简化

以使模式匹配更明确:

formula( []     , []     , []     ) .
formula( []     , [Y|Ys] , [Y|Zs] ) :- formula( [] , Ys , Zs ) .
formula( [X|Xs] , []     , [X|Zs] ) :- formula( Xs , [] , Zs ) .
formula( [X|Xs] , [Y|Ys] , [Z|Zs] ) :-
  L is ( X - Y ) * ( X - Y ) ,
  formula(Xs,Ys,Zs)
  .

我认为你的导师希望你在这里自己动手并学习递归,而不是使用内置的谓词。所以,......你可以总结这样一个列表的元素(天真的实现):

sum_of( [] , 0 ) .      % the sum of the empty list is zero.
sum_of( [X|Xs] , S ) :- % the sum of an empty list is computed by
  sum(Xs,T) ,           % - computing the sum of the tail of the list
  S is T+X              % - and adding that to the value of the head of the list.
  .                     %

但是,一旦列表变得足够长,每次递归调用将新帧推送到堆栈时,堆栈溢出就会失败。 Prolog有一个漂亮的优化(尾递归优化),它通过识别何时可以重用堆栈帧来有效地将递归转换为迭代。要做到这一点,重复呼叫必须是最后完成的事情。

这引入了prolog编程中的常见模式:

  • 公共接口谓词(此处为sum_of/2),
  • 调用"私有" tail-recursize worker predicate(此处为sum_of/3),它使用 accumulator 参数来构建其结果。

使用该模式,我们得到了这个实现:

 sum_of(Xs,Sum) :- sum_of(Xs,0,Sum) .

 sum_of( []     , S , S ) .  % the sum of the empty list is 0.
 sum_of( [X|Xs] , T , S ) :- % the sum of a non-empty list is computed by
   T1 is T+X ,               % incrementing the accumulator by the value of the head of the list, and
   sum_of( Xs , T1 , S )     % recursing down on the tail.
   .                         % Easy!

这适用于任何长度的列表。

答案 1 :(得分:0)

使用SWI-Prolog库谓词sum_list/2

list_summed_and_square_rooted(List, Value) :-
    sum_list(List, Sum),
    Value is sqrt(Sum).

您可能不需要编写单独的谓词来将列表与其元素总和的平方根相关联,除非您经常需要使用该特定关系。你的formula/3列出了两个列表,但最终你似乎是在一个数值之后,所以你可能想要另一个谓词来描述两个列表之间的关系和结果数值

lists_processed_in_some_way(List1, List2, Value) :-
    formula(List1, List2, CombinedList),
    sum_list(CombinedList, Sum),
    Value is sqrt(Sum).

顺便说一句,您可以简化formula/3,因为您不需要L = H2

formula([], [H2|T2], [H2|Ls]) :-
    formula([], T2, Ls).

此外,通过良好的做法来仔细命名谓词,并使用描述性内容。它将帮助您推断谓词的作用,并帮助您将程序传达给他人。