SWI Prolog 聚合的使用

SWI Prolog usage of agregation

我在 SWI Prolog 上创建了一个简单的数据库。我的任务是根据生产计划计算每个部门将工作多长时间。我快完成了,但我不知道如何总结我的结果。至于现在我得到这样的东西

部门金额

b 20

一个 5

c 50

c 30

如何将它转换成这个?

b 20

一个 5

c 80

我的代码https://gist.github.com/senioroman4uk/d19fe00848889a84434b

由于格式错误,所提供的代码不会解释 count 谓词。您应该将其重写为 count:- 而不是 count():-。据我所知,所有零元谓词都需要这样定义。

其次,您的计数谓词不会将结果收集到您可以操作的列表中。以下是如何更改它以收集列表中的所有部门数量对 findall:

count_sum(DepAmounts):-
    findall((Department,Sum),
            (   productionPlan(FinishedProduct, Amount),
                resultOf(FinishedProduct, Operation),
                executedIn(Operation, Department, Time),
                Sum is Amount * Time
            ),
            DepAmounts
    ).

然后,在该列表上,您可以使用类似 SWI-Prolog 的 aggregate:

 ?- count_sum(L), aggregate(sum(A),L,member((D,A),L),X).

这将通过回溯产生 D 中的部门和 X 中的金额总和:

D = a,
X = 15 ;
D = b,
X = 20 ;
D = c,
X = 80.

顺便说一句,如果我是你,为了简单起见,我会将部门名称和操作等的所有双引号字符串替换为原子。

你应该考虑库(aggregate):例如,调用data/2有趣的数据库子集,你得到

?- aggregate(set(K-A),aggregate(sum(V),data(K,V),A),L).
L = [a-5, b-20, c-80]