简体   繁体   中英

Predicate in prolog

I need to define a predicate in prolog which takes a list as input and sums the squares of numbers >= 5 and subtract sum of absolute value of numbers <=2.

This is what I have currently :-

pred([], 0).
pred([Head|Tail], Result) :-
    gr85(Head),
    pred(Tail, Total),
    Result is Head*Head + Total.

pred([Head|Tail], Result) :-
    leq2(Head),
    pred(Tail, Total),
    Result is Total - Head.

gr85(Number):-
    Number >= 5.

leq2(Number):-
    Number =< 2.

My question is how do I exclude anything between 2 and 5. If I input 3 in the list, it returns false.

Expected input

pred([3,6,2,-1], Result).

Expected output

Result= 33 (6*6 -2-1)

Maybe it is simpler if you keep it more simple, you can use accumulator to make it simpler. And also it is maybe less typing if you move the condiditional out, like this;

weird_sum(List, Sum) :-
    weird_sum(List, 0, Sum).

weird_sum([], Acc, Sum) :- Sum is Acc.
weird_sum([X|Xs], Sum0, Sum) :-
    once( weird_sum_helper(X, Sum0, Sum1) ),
    weird_sum(Xs, Sum1, Sum).

weird_sum_helper(X, Acc, Acc + X*X) :- X >= 5.
weird_sum_helper(X, Acc, Acc - abs(X)) :- X =< 2.
weird_sum_helper(X, Acc, Acc) :- X < 5, X > 2.

But the actual answer to your original question is in the last line above, just say that when X is smaller than 5 AND X is larger than 2 than you don't do anything.

But I get different answer from 33 because when number is negative and you subtract you get positive not negative but I am not sure if this is what you mean.

I used once once just because you want to do this only once since the three conditions are excluding each other but somehow Prolog doesn't know that it should only take one and tries the others too.

add a 'skip all' clause:

weird_sum([_|Tail], Result) :- weird_sum(Tail, Result).

I think you will gain some insight into Prolog working when you analyze where this clause should be added.

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