问题
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