List 如何对列表中的第二个数字求和-Prolog?

List 如何对列表中的第二个数字求和-Prolog?,list,prolog,clpfd,List,Prolog,Clpfd,给定一些整数列表,我想使用Prolog计算列表中每一秒元素的和 例如: 有几种方法可以实现这一点,但为了让您了解使用累加器跟踪当前和的简单递归解决方案: % Sets accumulator to 0 for convenience sum_second(List,Result) :- sum_second(List,0,Result). sum_second([],A,A). % Empty list sum_second([_],A,A). %

给定一些整数列表,我想使用Prolog计算列表中每一秒元素的和

例如:


有几种方法可以实现这一点,但为了让您了解使用累加器跟踪当前和的简单递归解决方案:

% Sets accumulator to 0 for convenience
sum_second(List,Result) :- sum_second(List,0,Result).

sum_second([],A,A).             % Empty list
sum_second([_],A,A).            % One element left in list
sum_second([_,H|T],A,R) :-      % Accumulate sum of second element
    A2 is A+H,
    sum_second(T,A2,R).
用法示例:

?- sum_second([1],R).
R = 0.
?- sum_second([1,2],R).
R = 2.
?- sum_second([1,2,3,4,5,6],R).
R = 12.
我会使用library():

sum_every_nth1/3基于nth1/3的“关系”行为,它将列表中的一个位置(样本中的p)绑定到一个元素。因此,当使用P free调用时,它将其绑定到连续索引。目标
P mod I=:=0
然后过滤掉不满足要求的索引(导致连接失败-逗号表示AND)

编辑

库(聚合)有一个特定的用途,即提供SQL中缺少的聚合运算符。为了处理乘法运算,我建议将元素的“获取”与对其执行的实际操作分开:

every_nth1(L,I,Ns) :- findall(X, (nth1(P,L,X),P mod I=:=0), Ns).

mul_every_nth1(L,I,M) :-
    every_nth1(L,I,[N0|Ns]),
    foldl([N,M0,M1]>>(M1 is M0*N),Ns,N0,M).
每1/3得到一个选定元素的列表,foldl/4就会将它们相乘

?- mul_every_nth1([1,2,3,4],2,M).
M = 8.
编辑

如果您缺少图书馆(yall):

虽然情况还可以,但我想补充一点:

  • 用于声明性整数算术

    :- use_module(library(clpfd)). :-使用_模块()。
  • 使用第一个参数索引来避免无用的选择点

    list_evens_odds([], [], []). list_evens_odds([X|Xs], [X|Es], Os) :- list_evens_odds(Xs, Os, Es). 列出平均赔率([]、[]、[])。 列出平均赔率([X | Xs],[X | Es],Os):- 列出平均赔率(X、Os、Es)。
  • 就这样

    要汇总其他每一项(从第二项开始),请按如下方式查询:

    ?- list_evens_odds([1,2,3,4], _, Zs), sum(Zs, #=, Sum). Zs = [2,4], Sum = 6. ?列出_evens_赔率([1,2,3,4],_,Zs),(Zs,#=和)。 Zs=[2,4],和=6。
    ?-sum_second(Ls,u,u)。
    仅显示单个解决方案。当然,我们希望从一段关系中得到更多?为什么要削减?它们不是必需的,应该避免,除非有特定的、有意的需求。此外,您还可以提供一个更整洁的谓词来调用此谓词:
    sum_second(Ls,R):-sum_second(Ls,0,R)。
    这样调用者就不必提供初始累加器值。运算符“!”的用途是什么?我添加了剪切以确保显式终止,而不是保留(冗余)选择点这可能会让那些刚刚开始使用Prolog的人感到困惑——我知道这是为了我。但是我理解你的意思,我会从代码中删除它们,因为它们不是必需的。至于调用谓词的sum_second/2,我想写它,但认为它对于这个问题来说是微不足道的。无论如何,为了方便起见,我会修改我的答案,并确保将来总是包含“调用”谓词。感谢您的评论,这总是受欢迎的。库(聚合)通常是自动加载的,所以不需要任何东西。无论如何,
    ?-[library(aggregate)]。
    将加载它。在源文件中,改用
    :-use_模块(库(聚合))。
    库聚合,在SWI Prolog 7.2版的实现中:)是的,这个答案非常有帮助:)很抱歉如何操作mul这个列表?示例2*3*5 pleaseis不可能使用库(聚合),但请参阅我的editShow一些代码,以查看您迄今为止所尝试的内容。 :- use_module(library(clpfd)). list_evens_odds([], [], []). list_evens_odds([X|Xs], [X|Es], Os) :- list_evens_odds(Xs, Os, Es). ?- list_evens_odds([1,2,3,4], _, Zs), sum(Zs, #=, Sum). Zs = [2,4], Sum = 6.