如何计算谓词

时间:2019-05-10 19:03:23

标签: prolog

我正在寻找一种计算谓词数量的方法。 示例:

%facts

has_subclass(thing,animal).
has_subclass(thing,tree).
has_subclass(thing,object).

%,我问

count_has_subclass(thing,X).

%的结果

X = 3。

4 个答案:

答案 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.