列表中的元素总和 - Prolog

时间:2014-05-07 13:51:15

标签: list prolog

我还是SWI-Prolog的新手,我不知道如何处理这两个问题。

  1. 编写一个谓词sum_composite(Numbers, Sum),它仅对非负整数列表的复合数进行求和。例如:

    ?- sumList([1,3,5,2,4,6,8,7],Sum).
    Sum=18.
    true
    
  2. 编写给定数字列表的谓词maxPrime(List, Min),返回列表中的最大素数元素。例如:

    ?- maxPrime([1, -4, 7, 4, 7, 9, -2, 3], Max).
    Max = 7
    true
    
  3. 这是我到目前为止所做的:

    sum_list([],0). //empty list. 
    
    sum_list([First|Tail],Sum) :- 
           sumlist(Tail, SumTail).
    

2 个答案:

答案 0 :(得分:0)

几乎总是在Prolog中,您可以使用两个子句在列表上编写谓词。

foo(L,R) :-
    foo(L,I,R).

foo([],F,F).
foo([H|T],F,R) :-
    F2 is f(F,H),
    foo(T,F2,R).

使用F当前结果,F2更新后的结果,H列表的头部,T列表的尾部,I }初始值,R结果。

此类模式使用 tail 递归和累加器(在本例中为F),这种模式被认为是Prolog中最有效的模式之一。 (中间递归或返回累加器会增加调用堆栈并需要更多簿记)。


如果是总和,则转换为:

sum(L,R) :-
    sum(L,0,R).

sum([],F,F).
sum([H|T],F,R) :-
    F2 is F+H,
    sum(T,F2,R).

我将离开maxPrime作为练习,但它很适合"很好地"进入上述模式。

答案 1 :(得分:0)

  1. 写一个谓词composites_sum(NUMBERs, SUM),该谓词只对非负整数列表中的所有组合数字求和。

(ed:“复合”数字不是“素”数字)。

示例:

?- composites_sum([1,3,5,2,4,6,8,7],Sum) .
Sum = 18 .
true
回答 ./src/parts/composites_sum.prolog

composites_sum(NUMBERs0,SUM)
:-
composites(NUMBERs0,NUMBERs) ,
sum(NUMBERs,SUM)
.


./demos/parts/composites_sum.prolog.console

?- composites_sum([1,3,5,2,4,6,8,7],SUM) .
SUM = 18 .

?- composites_sum([1,2,3],SUM) .
SUM = 0 .

?- sum([1,2,3],SUM) .
SUM = 6 .

?- sum([1,2,3,4],SUM) .
SUM = 10 .

?- composites_sum([1,2,3,4],SUM) .
SUM = 4 .

?- composites_sum([],SUM) .
SUM = 0 .


./src/parts/prime.prolog

%! prime(N0)
%
% true if `N0` is an prime number ;
% false if `N0` is not an prime number .
%
% this predicate can be used to generate prime numbers ;
% see the demos for the example using `between` .

/*
If an number is divisible by any other number less than it's sqrt then
the number is not prime ; otherwise it is prime .
*/

:- op(1,'xfy','prime_') .

prime(N0) :- [start] prime_ (N0) .

[start] prime_ (N0)
:-
[init] prime_ (N0)
.

[init] prime_ (N0)
:-
K is floor(sqrt(N0)) ,
[while] prime_ (N0,K)
.

[while] prime_ (_N0,K0)
:-
K0 = 1 ,
! ,
[finish] prime_ (true)
.

[while] prime_ (N0,K0)
:-
0 is mod(N0,K0) , % true if K0 multiplied by some value is N0 .
! ,
[finish] prime_ (false)
.

[while] prime_ (N0,K0)
:-
! ,
K is K0 - 1 ,
[while] prime_ (N0,K)
.

[finish] prime_ (true) .

[finish] prime_ (false) :- false .


./demos/parts/prime__1.prolog.console

?- prime(1) .
true
?- prime(2) .
true
?- prime(3) .
true
?- prime(4) .
false
?- prime(5) .
true
?- prime(7) .
true


./demos/parts/prime__2.prolog.console

?- between(1,1000,N) , prime(N) .
N = 1 ? ;
N = 2 ? ;
N = 3 ? ;
N = 5 ? ;
N = 7 ? ;
N = 11 ? ;
N = 13 ? ;
N = 17 ? ;
N = 19 ? ;
N = 23 ? ;
N = 29 ? ;
N = 31 ? ;
N = 37 ? ;
N = 41 ? ;
N = 43 ? ;
N = 47 ? ;
N = 53 ? ;
N = 59 ? ;
N = 61 ? ;
N = 67 ? ;
N = 71 ? %etcetera.


./src/parts/composites.prolog

%! composites(Xs0,Ys)
%
% `Ys` is those elements of `Xs0` that are not prime .

composites([],[]) :- ! .

composites([X0|Xs],[X0|Ys])
:-
+ prime(X0) ,
! ,
composites(Xs,Ys)
.

composites([_X0|Xs],Ys0)
:-
! ,
composites(Xs,Ys0)
.


./demos/parts/composites.prolog.console

?- composites([1,2,3,4,5,6,7,8,9,10,11,12],Cs) .
Cs = [4,6,8,9,10,12] .

?- composites([1],Cs) .
Cs = [] .

?- composites([],Cs) .
Cs = [] .


./src/parts/sum.prolog

%! sum(Xs,SUM)
%
% calculate the total sum of the items of list `Xs` .

sum(Xs,SUM)
:-
sum(Xs,0,SUM)
.

sum([],SUM0,SUM0) .

sum([X0|Xs],SUM0,SUM)
:-
SUM1 is SUM0 + X0 ,
sum(Xs,SUM1,SUM)
.


./demos/parts/sum.prolog.console

?- sum([1,2,3,4],SUM).
SUM = 10.

?- sum([1,2],SUM).
SUM = 3.

?- sum([1,2,-1],SUM).
SUM = 2.

?- sum([-1],SUM).
SUM = -1.

?- sum([],SUM).
SUM = 0.