根据可回溯谓词或事实求和



我正在尝试将不同的值添加到一起,假设我有这样的值:

%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).

最新更新