【问题标题】:Sum of elements in list - Prolog列表中元素的总和 - Prolog
【发布时间】:2014-05-07 13:51:14
【问题描述】:

我还是 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
    

这是我目前所拥有的:

sum_list([],0). //empty list. 

sum_list([First|Tail],Sum) :- 
       sumlist(Tail, SumTail).

【问题讨论】:

  • 我只设法得出整数列表中的整数总和。 sum_list([],0)。 //空列表。 sum_list([First|Tail],Sum) :- sumlist(Tail, SumTail)。
  • 因此,您需要在某处添加一个测试来检查一个数字是否是复合数(无论这意味着什么)并有条件地求和。请参阅有关 if-then-else 控制结构的 SWI-Prolog 文档。
  • 哦,好吧。当然!谢谢。
  • 对于素数检查,您可以搜索 SO for [prolog] prime。这是one example

标签: list prolog


【解决方案1】:

在 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 留作练习,但它非常适合上述模式。

【讨论】:

    【解决方案2】:
    问题
    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.
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多