Sum from backtrackable predicates or facts

泪湿孤枕 提交于 2019-12-25 02:47:29

问题


I am trying to add different values together, let's say I have this:

%fact(Type, Name, Weight).
fact(fruit, apple, 10).
fact(fruit, pear, 20).
fact(vegetable, tomato, 15).

Now, the problem I have is if I want to add the weight together from all the fruits. What I have done so far:

printWeight(Type):-
    fact(Type,_,R),
    (Type = 'fruit'
    -> true
    ; false
    ),
    *Here I want to add the weight of all the fruits, in case Type = fruit*

Anyone got any ideas on how to solve this?


回答1:


See your prolog implementation's documentation for the built-in predicate bagof/3, and a more or less standard library predicate that sums numbers in a list (in SWI-Prolog, available as sumlist/2):

?- bagof(W, Name^fact(fruit, Name, W), Ws), sumlist(Ws, Sum).
Ws = [10, 20],
Sum = 30.

?- bagof(W, Name^fact(meat, Name, W), Ws), sumlist(Ws, Sum).
false.

The second query fails, since there are no meat products in your database. You can either leave it as it is (since maybe you want to know if there are no products of a certain type), or use findall/3:

?- findall(W, fact(meat, _, W), Ws), sumlist(Ws, Sum).
Ws = [],
Sum = 0.

If you use SWI-Prolog, there is also library(aggregate):

?- aggregate(sum(W), Name^fact(fruit, Name, W), W_sum).
W_sum = 30.

You can use aggregate_all/3 for behavior as findall/3 above:

?- aggregate(sum(W), Name^fact(meat, Name, W), W_sum).
false.

?- aggregate_all(sum(W), Name^fact(meat, Name, W), W_sum).
W_sum = 0.

If you don't want to use sumlist/2 (or are not allowed to), this is how you add two numbers (integers or floats):

Sum is A + B

So you would have to figure out how to "fold" a list.

EDIT:

So, to make a predicate type_totalweight/2, using for example findall/3:

type_totalweight(Type, Weight) :-
    findall(W, fact(Type, _, W), Ws),
    sumlist(Ws, Weight).



回答2:


You can easily use findall/3 to get all the weights, then use sumlist or some other simple function to sum all the weights:

findall(W, fact(Type, _, W), L),
sumlist(L, Weight).

And Weight will hold the sum of the weights. Example of usage:

?- Type = fruit, findall(W, fact(Type, _, W), L), sumlist(L, Weight).
Type = fruit,
L = [10, 20],
Weight = 30.


来源:https://stackoverflow.com/questions/26297171/sum-from-backtrackable-predicates-or-facts

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!