Prolog Sum value numbers smaller than limit

Viewed 149

Define predicate summy(List, Limit, N), where List is a list of absolute value numbers, and N is the sum of such numbers from List lists whose value is smaller than Limit.

This is what I have: *

abx([],[]).
abx([H|T], [H|T1]):-
    H >= 0,!,
    abx(T,T1).
abx([M|T], [M1|T1]):-
    M < 0,
    M1 is M * (-1),
    abx(T,T1).

summy([], [], []).
summy([H|T], L, N):-
    abx([H|T], [X|Y]),
     X < L,
    sumlist([X|Y], N).

If I run the example it shows X=26, not X=11.

1 Answers

The filtering part is wrong. The X < L will check if X, the first element of the list is less than L. If it is, it will calculate the sum of all absolute values, if it is not, the entire predicate will fail.

You should thus filter, for example with:

filterless([], L, []).
filterless([H|T], L, [H|T2]) :-
    H < L,
    filterless(T, L, T2).
filterless([H|T], L, T2) :-
    H > L,
    filterless(T, L, T2).

Then the summary is thus:

summy(Xs, L, R) :-
    abx(Xs, As),
    filterless(As, L, Bs),
    sumlist(Bs, R).

We can however make use of maplist/3 [swi-doc] to do a mapping, and include/3 [swi-doc] to filter the list, so we can rewrite summy/3 to:

summy(Xs, L, R) :-
    maplist(abs, Xs, As),
    include(>(L), As, Bs),
    sumlist(Bs, R).
Related