Search code examples
prolog

Prolog Sum value numbers smaller than limit


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.


Solution

  • 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).