在 SWI-Prolog 中聚合谓词 [英] aggregating predicates in SWI-Prolog

查看:77
本文介绍了在 SWI-Prolog 中聚合谓词的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要计算 some_predicate(X) 所持有的所有 X,而且确实有很多这样的 X.最好的方法是什么?

I need to count all X for which some_predicate(X) holds, and there really a lot of such X. What is the best way to do that?

第一条线索是findall,累加成一个列表,返回列表的长度.

First clue is to findall, accumulate to a list and return the length of the list.

countAllStuff( X ) :-
    findall( Y
           , permutation( [1,2,3,4,5,6,7,8,9,10], Y )
           , List
           ),
    length( List, X ).

(permutation/2 只是一个虚拟的占位符,表明有很多结果,而且计算计数的方法很糟糕)

(permutation/2 is only a dummy placeholder demonstrating that there are many results and that it's bad way to compute the count)

显然,对于真实数据,会有堆栈溢出.

Obviously, with real data, there will be a stack overflow.

?- countAllStuff( X ).
ERROR: Out of global stack

然后,我试图用 setof 替换 findall,但无济于事.

Then, I'm trying to replace findall with setof, to no avail.

最后,我找到了 [aggregate][1](可点击)系列谓词,并尝试使用 aggregate/3aggregate/4:

At last, I've found the [aggregate][1] (clickable) family of predicates, and trying to use aggregate/3 and aggregate/4:

?- aggregate(count, permutation([1,2,3,4], X), Y ).
X = [1, 2, 3, 4],
Y = 1 .

?- aggregate(count, [1,2,3,4], permutation([1,2,3,4], X), Y ).
X = [1, 2, 3, 4],
Y = 1 ;
X = [1, 2, 4, 3],
Y = 1 ;

我想,这一切都错了.我需要得到这样的东西:

It's all wrong, I think. I need to get something like this:

?- aggregate(count, permutation([1,2,3,4], X), Y ).
Y = 24 .

  1. 我做错了什么?

  1. What am I doing wrong?

我如何声明一个谓词来计算正确的答案?[1]:http://www.swi-prolog.org/pldoc/doc/home/vnc/prolog/lib/swipl/library/aggregate.pl

How can I declare a predicate to conpute the right answer? [1]: http://www.swi-prolog.org/pldoc/doc/home/vnc/prolog/lib/swipl/library/aggregate.pl

推荐答案

使用存在量化的变量,就像使用 setof 一样:

Use an existentially quantified variable, as you would with setof:

?- aggregate(count, X^permutation([1,2,3,4], X), N).
N = 24.

这篇关于在 SWI-Prolog 中聚合谓词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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