我试图找出如何在prolog中创建一个谓词,该谓词只对给定列表中偶数的平方进行求和。
预期产出:
?- sumsq_even([1,3,5,2,-4,6,8,-7], Sum).
Sum = 120 ;
false.
我所知道的是从列表中删除所有奇数:
sumsq_even([], []).
sumsq_even([Head | Tail], Sum) :-
not(0 is Head mod 2),
!,
sumsq_even(Tail, Sum).
sumsq_even([Head | Tail], [Head | Sum]) :-
sumsq_even(Tail, Sum).
这给了我:
Sum = [2, -4, 6, 8]
而且我也知道如何将列表中所有数字的平方加起来:
sumsq_even([], 0)
sumsq_even([Head | Tail], Sum) :-
sumsq_even(Tail, Tail_Sum),
Sum is Head * Head + Tail_Sum.
但我似乎无法弄清楚如何将这两者连接在一起。我认为我可能对此采取了错误的方式,但我不确定如何定义适当的关系以使其有意义。
谢谢!
答案 0 :(得分:2)
将您的问题分成更小的部分。正如您已经说过的,您有两种不同的功能应该结合起来:
even
)sumsq
)因此,首先,为不同的功能使用不同的谓词名称:
even([], []).
even([Head | Tail], Sum) :-
not(0 is Head mod 2),
!,
even(Tail, Sum).
even([Head | Tail], [Head | Sum]) :-
even(Tail, Sum).
sumsq([], 0).
sumsq([Head | Tail], Sum) :-
sumsq(Tail, Tail_Sum),
Sum is Head * Head + Tail_Sum.
在第三个谓词中,您现在可以将两个后续较小的步骤组合在一起:
sumsq_even(List, Sum) :-
even(List, Even_List),
sumsq(Even_List, Sum).
在此规则中,首先将(输入)列表缩减为偶数元素(Even_List
),然后计算平方和。
这是您的示例的结果:
sumsq_even([1,3,5,2,-4,6,8,-7], Sum).
S = 120.
答案 1 :(得分:2)
您可以实际执行这两项任务(过滤偶数并将它们相加):
vec3 entryPoint = vec3(0.0f);
if(scaleCoeff >= 2.7f)
{
float tmp = min((scaleCoeff - 2.7f) * 0.1f, 1.0f);
entryPoint = EntryPoint + tmp * (exitPoint - EntryPoint);
}
else
{
entryPoint = EntryPoint;
}
//
查询谓词会得到所需的结果:
:- use_module(library(clpfd)).
nums_evensumsq([],0).
nums_evensumsq([X|Xs],S0) :-
X mod 2 #= 0,
nums_evensumsq(Xs,S1),
S0 #= S1 + X * X.
nums_evensumsq([X|Xs],S) :-
X mod 2 #= 1,
nums_evensumsq(Xs,S).
您可以使用if_ / 3定义here:
来编写更短的内容 ?- nums_evensumsq([1,3,5,2,-4,6,8,-7],S).
S = 120 ? ;
no
请注意,if_ / 3的第一个参数中的比较是使用= / 3定义的here。
答案 2 :(得分:2)
:- use_module(library(clpfd)). :- use_module(library(lambda)). zs_sumevensq(Zs, S) :- maplist(\Z^X^(X #= Z*Z*(1-(Z mod 2))), Zs, Es), sum(Es, #=, S).
OP给出的示例查询:
?- zs_sumevensq([1,3,5,2,-4,6,8,-7], S).
S = 120.
答案 3 :(得分:0)
掌握了基础知识后,您可能有兴趣了解内置函数。库aggregate提供了一种处理列表的简单方法,使用member / 2作为列表元素' accessor':
sumsq_even(Ints, Sum) :-
aggregate(sum(C), I^(member(I, Ints), (I mod 2 =:= 0 -> C is I*I ; C = 0)), Sum).