我正在尝试将不同的值添加到一起,假设我有这样的值:
%fact(Type, Name, Weight).
fact(fruit, apple, 10).
fact(fruit, pear, 20).
fact(vegetable, tomato, 15).
现在,我的问题是,如果我想把所有水果的重量加在一起。到目前为止我所做的:
printWeight(Type):-
fact(Type,_,R),
(Type = 'fruit'
-> true
; false
),
*Here I want to add the weight of all the fruits, in case Type = fruit*
有人知道怎么解决这个问题吗?
您可以很容易地使用findall/3
来获得所有权重,然后使用sumlist
或其他简单函数来求和所有权重:
findall(W, fact(Type, _, W), L),
sumlist(L, Weight).
并且Weight
将保持权重的总和。用法示例:
?- Type = fruit, findall(W, fact(Type, _, W), L), sumlist(L, Weight).
Type = fruit,
L = [10, 20],
Weight = 30.
请参阅您的prolog实现文档中的内置谓词bagof/3
,以及一个或多或少标准的库谓词(在SWI-prolog中,可用作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.
第二个查询失败,因为数据库中没有肉制品。您可以保持原样(因为您可能想知道是否没有特定类型的产品),也可以使用findall/3
:
?- findall(W, fact(meat, _, W), Ws), sumlist(Ws, Sum).
Ws = [],
Sum = 0.
如果您使用SWI Prolog,还有library(aggregate)
:
?- aggregate(sum(W), Name^fact(fruit, Name, W), W_sum).
W_sum = 30.
您可以使用aggregate_all/3
作为上面的findall/3
的行为:
?- 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.
如果你不想使用sumlist/2
(或者不允许使用),这就是你添加两个数字(整数或浮点)的方法:
Sum is A + B
因此,你必须弄清楚如何"折叠"一个列表。
编辑:
因此,要生成谓词type_totalweight/2
,请使用例如findall/3
:
type_totalweight(Type, Weight) :-
findall(W, fact(Type, _, W), Ws),
sumlist(Ws, Weight).