我正在寻找一种计算谓词数量的方法。 示例:
%facts
has_subclass(thing,animal).
has_subclass(thing,tree).
has_subclass(thing,object).
%,我问
count_has_subclass(thing,X).
%的结果
X = 3。
答案 0 :(得分:2)
对于像您的示例这样的事实:
count_has_subclass(What, Count):-
findall(1, call(has_subclass(What, _)), L),
length(L, Count).
答案 1 :(得分:1)
为此,我们可以使用findall/3
,然后使用length/2
获得列表的长度:
Provider<ContainerRequest>
如果给定键(例如count_has_subclass(What, N):-
findall(X, has_subclass(What, X), L),
length(L, N).
的{{1}}可能多次产生相同值,那么我们可以使用{{3} }作为重复过滤器,例如:
has_subclass/2
请注意,如果thing
是一个自由变量,那么您将计算count_has_subclass(What, N):-
findall(X, has_subclass(What, X), L),
sort(L, S), %% remove duplicates
length(S, N).
的所有产量(可以选择在第二个参数上使用唯一性过滤器)。
答案 2 :(得分:1)
使用标准setof/3
是更好的选择,因为它可以轻松定义更通用的谓词,该谓词可以在未绑定类参数时枚举解决方案。例如,假定以下数据库:
has_subclass(thing,animal).
has_subclass(thing,tree).
has_subclass(thing,object).
has_subclass(animal,cat).
has_subclass(animal,dog).
has_subclass(tree,pine).
has_subclass(tree,oak).
以及定义:
subclass_count(Class, Count) :-
setof(Subclass, has_subclass(Class, Subclass), Subclasses),
length(Subclasses, Count).
通话示例:
| ?- subclass_count(Class, Count).
Class = animal
Count = 2 ? ;
Class = thing
Count = 3 ? ;
Class = tree
Count = 2
yes
如果您尝试改用其他答案中的findall/3
个解决方案之一,则会得到:
| ?- count_has_subclass(What, Count).
Count = 7
但是请注意,此解决方案也具有明智的解释,即当未指定类时,返回所有现有子类的数量。
答案 3 :(得分:0)
建立一个仅计算解决方案的列表似乎是“旧样式”,但是在传统的Prolog中,只有DB(断言/缩回)替代方案可以克服计算的“无状态”本质。实际上,可以通过断言/收回来(幼稚地)重写findall / 3和好友的内置函数。但是自80年代初以来就出现了一些问题:)。我用SWI-Prolog进行了说明,但是-或多或少地天真-所有这些都可以通过断言/收回来实现。当然,大多数Prolog实现都具有“非逻辑”(或“命令性”或“不纯粹”)功能来实现这种基本任务,而无需借助重量级的DB接口-例如setarg / 3,{{3} } / 2和其他...
我离题...图书馆(nb_setval)应该首先显示:
?- aggregate(count, T^has_subclass(thing,T), C).
C = 3.
这个lib非常值得研究,其作用远远超过-有效-计数... 另一个最近添加的是库(aggregate)。猜想,它没有比setof / 3 + length / 2更有效,但它本身很有趣。计数会涉及更多点,并使用solution_sequences / 2:
?- order_by([desc(C)],call_nth(has_subclass(thing,T),C)).
C = 3,
T = object ;
...
基于call_nth / 3(并来自@false的帮助),code of mine要简单得多:
?- [carlo(snippets/lag)].
true.
?- integrate(count,has_subclass(thing,T),C).
C = 3.