Prolog 让序言不重复答案

Prolog 让序言不重复答案,prolog,Prolog,当我问prologsmall(X,whale)时,它会吐出所有正确的动物,但会重复其中的几个。有人能告诉我为什么以及是否有办法阻止它重复吗?使用库解决方案 在SWI Prolog开发分支的最新版本中,这一点变得特别容易: bigger(whale,shark). bigger(shark,tiger). bigger(tiger,dog). bigger(dog,rat). bigger(rat,ant). bigger(rat,mouse). bigger(cat,rat). bigger(d

当我问prolog
small(X,whale)
时,它会吐出所有正确的动物,但会重复其中的几个。有人能告诉我为什么以及是否有办法阻止它重复吗?

使用库解决方案 在SWI Prolog开发分支的最新版本中,这一点变得特别容易:

bigger(whale,shark).
bigger(shark,tiger).
bigger(tiger,dog).
bigger(dog,rat).
bigger(rat,ant).
bigger(rat,mouse).
bigger(cat,rat).
bigger(dog,cat).

smaller(X,Y) :- bigger(Y,X).
smaller(X,Y) :- bigger(Z,X),smaller(Z,Y).
允许这样做的库已记录在案

使用库聚合 另一种实现方法(在较旧版本的SWI Prolog中也支持):

使用库解决方案 在SWI Prolog开发分支的最新版本中,这一点变得特别容易:

bigger(whale,shark).
bigger(shark,tiger).
bigger(tiger,dog).
bigger(dog,rat).
bigger(rat,ant).
bigger(rat,mouse).
bigger(cat,rat).
bigger(dog,cat).

smaller(X,Y) :- bigger(Y,X).
smaller(X,Y) :- bigger(Z,X),smaller(Z,Y).
允许这样做的库已记录在案

使用库聚合 另一种实现方法(在较旧版本的SWI Prolog中也支持):

使用库解决方案 在SWI Prolog开发分支的最新版本中,这一点变得特别容易:

bigger(whale,shark).
bigger(shark,tiger).
bigger(tiger,dog).
bigger(dog,rat).
bigger(rat,ant).
bigger(rat,mouse).
bigger(cat,rat).
bigger(dog,cat).

smaller(X,Y) :- bigger(Y,X).
smaller(X,Y) :- bigger(Z,X),smaller(Z,Y).
允许这样做的库已记录在案

使用库聚合 另一种实现方法(在较旧版本的SWI Prolog中也支持):

使用库解决方案 在SWI Prolog开发分支的最新版本中,这一点变得特别容易:

bigger(whale,shark).
bigger(shark,tiger).
bigger(tiger,dog).
bigger(dog,rat).
bigger(rat,ant).
bigger(rat,mouse).
bigger(cat,rat).
bigger(dog,cat).

smaller(X,Y) :- bigger(Y,X).
smaller(X,Y) :- bigger(Z,X),smaller(Z,Y).
允许这样做的库已记录在案

使用库聚合 另一种实现方法(在较旧版本的SWI Prolog中也支持):


可能的标准Prolog用法:

?- aggregate_all(set(X), smaller(X, whale), Xs), member(X, Xs).

我试图用符号的选择来证明“功能依赖性”。当您有一个列表时,可以使用member/2枚举元素。

可能的标准序言用法:

?- aggregate_all(set(X), smaller(X, whale), Xs), member(X, Xs).

我试图用符号的选择来证明“功能依赖性”。当您有一个列表时,可以使用member/2枚举元素。

可能的标准序言用法:

?- aggregate_all(set(X), smaller(X, whale), Xs), member(X, Xs).

我试图用符号的选择来证明“功能依赖性”。当您有一个列表时,可以使用member/2枚举元素。

可能的标准序言用法:

?- aggregate_all(set(X), smaller(X, whale), Xs), member(X, Xs).
我试图用符号的选择来证明“功能依赖性”。当您有一个列表时,您可以使用member/2枚举元素。

首先请注意:

谓词
biger/2
真的描述了什么样的关系

  • 由于名称,我们假设它是可传递的:
    biger(A,B)
    biger(B,C)
    ==>
    biger(A,C)

  • 我们也可以安全地假设它是严格的(而不是反身的):
    biger(A,A)
    永远不会是真的

  • 和不对称(非对称):
    biger(A,B)
    ==>
    biger(B,A)
    不正确

  • 从目前的程序中,我们无法知道的是,这种关系是否描述了一种总排序或弱排序:我们不知道(a)
    biger(mouse,ant)
    ,或者(b)not
    biger(mouse,ant)
    ,或者(c)
    mouse
    ant
    是等价的(我们假设它们绝对不相等)

所有这些只是为了说明,对于定义了
更大的
关系的所有元素,没有线性排序。如果有,您可以对所有动物进行排序(从大到小),并执行如下操作:

?- X=whale,setof(Y,smaller(Y,X),L).
X = whale,
L = [ant, cat, dog, mouse, rat, shark, tiger].
由于您没有线性排序,因此不可能对所有元素进行排序,并将问题“小/大”简化为“之前/之后是什么”。相反,我们需要遍历由
biger/2
描述的图。至少我们可以安全地假设它是一个有向的非循环图。我把它作为一个如何遍历图的练习。为了解决这个问题,我们可以改为使用(你可以看到源代码),并回答“哪些动物比X小”,我们可以问,“哪些节点可以从X访问”:

以下是完整的程序:

animal_bigger(A, Bigger) :-
    animal_list(Animals),
    append(Bigger, [A|_Smaller], Animals),
    member(A, Bigger).
如果您想找到所有较大的元素,则可以转置图形并查找可到达的节点

我希望你花点时间阅读这个答案

编辑

最后,信息是:

您的
biger/2
不描述列表(它不是线性排序),也不描述树(您有多条路径指向同一节点)。因此,一个适用于列表的算法在这里不起作用,而一个适用于树的算法也不起作用。因此,您要么必须实现
较小的/2
来处理图形,要么使用一个可以处理图形的库。

首先请注意:

谓词
biger/2
真的描述了什么样的关系

  • 由于名称,我们假设它是可传递的:
    biger(A,B)
    biger(B,C)
    ==>
    biger(A,C)

  • 我们也可以安全地假设它是严格的(而不是反身的):
    biger(A,A)
    永远不会是真的

  • 和不对称(非对称):
    biger(A,B)
    ==>
    biger(B,A)
    不正确

  • 从目前的程序中,我们无法知道的是,这种关系是否描述了一种总排序或弱排序:我们不知道(a)
    biger(mouse,ant)
    ,或者(b)not
    biger(mouse,ant)
    ,或者(c)
    mouse
    ant
    是等价的(我们假设它们绝对不相等)

所有这些只是为了说明,对于定义了
更大的
关系的所有元素,没有线性排序。如果有,您可以对所有动物进行排序(从大到小),并执行如下操作:

?- X=whale,setof(Y,smaller(Y,X),L).
X = whale,
L = [ant, cat, dog, mouse, rat, shark, tiger].
由于您没有线性排序,因此不可能对所有元素进行排序并将问题“什么更小/更大”简化为“什么在之前/之后”。相反,我们需要遍历由
biger/2
描述的图。至少我们可以安全地假设