来自可回溯谓词或事实的总和 [英] Sum from backtrackable predicates or facts

查看:32
本文介绍了来自可回溯谓词或事实的总和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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?

推荐答案

有关内置谓词 bagof/3 以及对数字求和的或多或少的标准库谓词,请参阅 prolog 实现的文档在列表中(在 SWI-Prolog 中,可作为 sumlist/2):

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.

第二个查询失败,因为您的数据库中没有肉类产品.您可以保持原样(因为您可能想知道是否没有某种类型的产品),或者使用 findall/3:

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.

如果你使用SWI-Prolog,还有library(aggregate):

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

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

您可以使用 aggregate_all/3 作为上述 findall/3 的行为:

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.

如果您不想使用 sumlist/2(或不允许使用),您可以通过以下方式将两个数字(整数或浮点数)相加:

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.

因此,要制作一个谓词 type_totalweight/2,例如使用findall/3:

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

这篇关于来自可回溯谓词或事实的总和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆