来自可追溯谓词或事实的总和

时间:2014-10-10 10:20:43

标签: prolog

我试图将不同的值加在一起,假设我有这个:

%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*

有人对如何解决这个问题有任何想法吗?

2 个答案:

答案 0 :(得分:2)

您可以轻松使用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.

答案 1 :(得分:1)

请参阅prolog实现的内置谓词bagof/3的文档,以及一个或多或少的标准库谓词,它对列表中的数字求和(在SWI-Prolog中,以{{1}形式提供}):

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

如果您使用SWI-Prolog,还有?- findall(W, fact(meat, _, W), Ws), sumlist(Ws, Sum). Ws = [], Sum = 0.

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