在Prolog中创建谓词,该谓词仅对列表中偶数的平方进行求和

Rob*_*ung 5 prolog clpfd

我试图弄清楚如何在prolog中创建一个谓词,它只对给定列表中偶数的平方进行求和.

预期产量:

?- sumsq_even([1,3,5,2,-4,6,8,-7], Sum).

Sum = 120 ;

false.
Run Code Online (Sandbox Code Playgroud)

我知道怎么做是从列表中删除所有奇数:

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).
Run Code Online (Sandbox Code Playgroud)

这给了我:

Sum = [2, -4, 6, 8]
Run Code Online (Sandbox Code Playgroud)

而且我也知道如何将列表中所有数字的平方加起来:

sumsq_even([], 0)
sumsq_even([Head | Tail], Sum) :-
    sumsq_even(Tail, Tail_Sum),
    Sum is Head * Head + Tail_Sum.
Run Code Online (Sandbox Code Playgroud)

但我似乎无法弄清楚如何将这两者连接在一起.我想我可能走错了路,但我不确定如何定义正确的关系以使其有意义.

谢谢!

Ulu*_*kai 3

将你的问题分成更小的部分。正如您已经说过的,您有两种不同的功能应该结合起来:

  • 从列表中删除奇数 ( 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.
Run Code Online (Sandbox Code Playgroud)

在第三个谓词中,您现在可以组合两个后续的较小步骤:

sumsq_even(List, Sum) :-
    even(List, Even_List),
    sumsq(Even_List, Sum).
Run Code Online (Sandbox Code Playgroud)

在此规则中,首先将(输入)列表缩减为偶数元素 ( Even_List),然后计算平方和。

这是您的示例的结果:

sumsq_even([1,3,5,2,-4,6,8,-7], Sum).
S = 120.
Run Code Online (Sandbox Code Playgroud)