List Prolog中奇数的偶和积

List Prolog中奇数的偶和积,list,prolog,clpfd,meta-predicate,List,Prolog,Clpfd,Meta Predicate,我有一个数字列表,我需要计算列表的偶数和同一列表的奇数的乘积之和。我是Prolog新手,到目前为止我的搜索没有成功。有人能帮我解决吗 l_奇偶([])。 l|u奇偶([H|T],奇数[H|Etail]):- H rem 2=:=0, 分裂(T,奇数,Etail)。 l|u奇偶([H|T],[H|Otail],偶数):- H rem 2=:=1, 拆分(T、Otail、偶数)。 下面是一个关于列表中偶数总和的建议: 偶数(X):- Y是mod(X,2),%使用“is”计算为数字 Y=:=0。 奇数

我有一个数字列表,我需要计算列表的偶数和同一列表的奇数的乘积之和。我是Prolog新手,到目前为止我的搜索没有成功。有人能帮我解决吗

l_奇偶([])。
l|u奇偶([H|T],奇数[H|Etail]):-
H rem 2=:=0,
分裂(T,奇数,Etail)。
l|u奇偶([H|T],[H|Otail],偶数):-
H rem 2=:=1,
拆分(T、Otail、偶数)。

下面是一个关于列表中偶数总和的建议:

偶数(X):-
Y是mod(X,2),%使用“is”计算为数字
Y=:=0。
奇数(X):-%使用偶数
Y是X+1,
偶数(Y)。
和偶数(0,[])。%空列表的和为零
和偶数(X[H | T]):-
偶数(H),
求和偶数(Y,T),
X是Y+H。
和偶数(X[H | T]):-
奇数(H),
求和偶数(X,T)。%忽略奇数
注意:我的Prolog已被氧化,因此可能有更好的解决方案。:-)

注意:天哪!似乎没有Prolog支持语法突出显示(请参阅),所以我使用了Erlang语法。 哈,真的很管用。:-)

在GNU Prolog中运行一些查询,我得到:

|?-sum_偶数(X,[])。
X=0?
对
|?-sum_偶数(X,[2])。
X=2?
对
|?-sum_偶数(X,[3])。
X=0?
对
|-和_偶数(X[5,4,3,2,1,0])。
X=6?
对
这里应用的想法应该能让你想出所需的产品。

未经测试

sum_odd_product_even([], S, P, S, P).
sum_odd_product_even([H|T], S0, P0, S, P) :-
    S1 is S0 + H,
    sum_even_product_odd(T, S1, P0, S, P).

sum_even_product_odd([], S, P, S, P).
sum_even_product_odd([H|T], S0, P0, S, P) :-
    P1 is P0 * H,
    sum_odd_product_even(T, S0, P1, S, P).

sum_odd_product_even(L, S, P) :-
    sum_odd_product_even(L, 0, 1, S, P).

sum_even_product_odd(L, S, P) :-
    sum_even_product_odd(L, 0, 1, S, P).

它不应该比

%
% invoke the worker predicate with the accumulators seeded appropriately.
%
odds_and_evens( [O]      , P , S ) :- odds_and_evens( [] , O , 0 , P , S ) .
odds_and_evens( [O,E|Ns] , P , S ) :- odds_and_evens( Ns , O , E , P , S ) .

odds_and_evens( []       , P , S , P , S  ) . % if the list is exhausted, we're done.
odds_and_evens( [O]      , X , X , P , S ) :- % if it's a single element list, we've only an odd element...
  P is X*O ,                                  % - compute it's product
  .                                           % - and we're done.
odds_and_evens( [O,E|Ns] , X , Y , P , S ) :- % if the list is at least two elements in length'e both an odd and an even:
  X1 is X*O ,                                 % - increment the odd accumulator
  Y1 is Y+E ,                                 % - increment the even accumulator
  odds_and_evens( Ns , X1 , Y1 , P , S )      % - recurse down (until it coalesces into one of the two special cases)
  .                                           % Easy!
使用

foldl/4
的基础上,我们只需要定义一个折叠步骤:

sumprod_(Z,S0,S) :-
   M #= Z mod 2,
   rem_sumprod_(M,Z,S0,S).

rem_sumprod_(0,Z,S0-P,S-P) :- 
   S0 + Z #= S.
rem_sumprod_(1,Z,S-P0,S-P) :- 
   P0 * Z #= P.
让我们在列表上折叠
sumprod\u3

l_odd_even(Zs,ProductOfOdds,SumOfEvens) :-
   foldl(sumprod_,Zs,0-1,SumOfEvens-ProductOfOdds).
示例查询:

?- l_odd_even([1,2,3,4,5,6,7],Odd,Even).
Odd = 105,
Even = 12.

或者,我们可以使用和更简洁地定义
sumprod\u3


你能展示一下你已经尝试过的吗?首先,你需要尝试一下。我知道你对Prolog还不熟悉,但到目前为止你对Prolog了解多少?因为你处理的是一个数字列表,所以你需要操纵一个列表。你可以在谷歌上搜索“prolog列表处理”,并获得一些关于如何管理列表的好信息。首先,
[]
是一个空列表,
[H | T]
是一个包含第一个元素
H
的列表,列表的其余部分(尾部)是
T
。这是我到目前为止的代码“l_奇偶([])。l_奇偶([H | T],奇数,[H | Etail:-((H rem 2)==0),split(T,奇数,Etail l)。l_奇偶([H | T],[H]:=1),split(T、Otail、偶数)我只是不知道如何实现这之后的和和和积,所以,零的积是1?@Boris:是的,乘法的中性元素。我不确定,但我想你得到的是奇偶位置的数的和和和积,但OP似乎在试图得到偶数和o的和和和积dd编号。
?- l_odd_even([1,2,3,4,5,6,7],Odd,Even).
Odd = 105,
Even = 12.
sumprod_(Z,S0-P0,S-P) :-
   if_(zeven_t(Z), (S0+Z #= S, P0=P),
                   (P0*Z #= P, S0=S)).