I'm still new to SWI-Prolog and I'm not sure how to do this two questions.
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
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.
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) .
?- prime(1) .
true
?- prime(2) .
true
?- prime(3) .
true
?- prime(4) .
false
?- prime(5) .
true
?- prime(7) .
true
%! 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 .
?- prime(1) . true ?- prime(2) . true ?- prime(3) . true ?- prime(4) . false ?- prime(5) . true ?- prime(7) . true
?- 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.
%! 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) .
?- 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 = [] .
%! 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) .
?- 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.