简体   繁体   中英

Sum of elements in list - Prolog

I'm still new to SWI-Prolog and I'm not sure how to do this two questions.

  1. Write a predicate sum_composite(Numbers, Sum) that sum ONLY COMPOSITE NUMBERS of a list of non-negative whole numbers. Example:

     ?- sumList([1,3,5,2,4,6,8,7],Sum). Sum=18. true
  2. Write a predicate maxPrime(List, Min) that given a list of numbers, returns the maximum prime element in the list. Example:

     ?- maxPrime([1, -4, 7, 4, 7, 9, -2, 3], Max). Max = 7 true

This is what I have so far:

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

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

As nearly always in Prolog, you can write predicates on lists using two clauses.

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

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

With F the current result, F2 the updated result, H the head of the list that far, T the tail of the list, I the initial value, and R the result.

Such patterns use tail recursion with an accumulator (in this case F ), this patterns are considered one of the most efficient in Prolog. (middle-recursion or return accumulators increase the call stack and require more bookkeeping).


In case of a sum, this is tranformed into:

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

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

I will leave the maxPrime as an exercise, but it fits "nicely" into the above described pattern.

question
  1. Write a predicate composites_sum(NUMBERs, SUM) that sums ONLY COMPOSITE NUMBERS of a list of non-negative whole numbers .

(ed: a "composite" number is an number that is not an "prime" number) .

Example :


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

answer ./src/parts/composites_sum.prolog
 composites_sum(NUMBERs0,SUM) :- composites(NUMBERs0,NUMBERs) , sum(NUMBERs,SUM) .

./demos/parts/composites_sum.prolog.console

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


./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

?- 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.


./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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM