3

我得到了以下程序:

edge(a,b).
edge(b,c).
edge(a,d).

path(N,M):- path(N,New),edge(New,M).
path(N,M):- edge(N,M).

并询问是否将证明树算法应用于以下查询:

?- path(a,X). 

证明树是无限成功树,还是无限失败树?

现在我看到了,在树的构建过程中,你会一遍又一遍地应用路径规则 1,创建一棵无限的树,而永远不会达到路径规则 2。

从而创建一个无限的故障树。但是我的解决方案说这是一棵无限的成功树,我的问题是:我是对的还是我的教授是对的?:]

4

2 回答 2

4

不确定您使用的是什么术语,但 Lloyd 使用的通用术语,逻辑编程基础,是SLD-tree,它可能包含成功无限失败分支。我假设你使用标准的 Prolog 计算规则(= 选择最左边的原子)。

您示例中的 SLD 树是无限的,并且包含与三个答案替换相对应的有限多个成功分支:X = b ; X = c ; X = d. 需要注意的是,虽然这棵树有一个无限的失败分支,但它仍然包含所有解决方案!

计算规则的选择可能会影响 SLD 树的大小和结构。但好的是:无论你的计算规则是什么,我们都会得到我们的成功分支!保证!嗯,保证为那些以聪明的方式绘制无限 SLD-tree,并且知道如何使用......明智的人。但对于拥有无限资源和睿智的人来说,没问题。

另一个观察结果是这个 SLD 树的形状完全独立于子句的顺序。因此,无论非递归规则是最后(如您的情况)还是首先编写,对树的形状都没有太大影响:它将具有相同的大小(无论是无限的还是都是有限的),将包含相同数量的节点,但某些分支会以不同的顺序出现。

Prolog 尝试以增量方式生成该 SLD-tree,但它使用最原始的方式来执行此操作。它开始探索一个分支,并在扩展其他分支之前完全探索它。这意味着,Prolog 可以使用 SLD-tree(或者更准确地说:仅 SLD-tree 的一部分)的一种非常节省空间的表示,实际上它本质上是一个堆栈,但要付出的代价是一旦遇到无限分支,您就会被卡住 - 除非您确实拥有无限资源。无论是否找到成功分支(=答案)或它们是否会被某个无限分支掩埋,子句的顺序都会产生影响。

在实践中,很难想象所有这些无限的树,我们不太习惯它们。

但是还有其他方法可以让您更好地理解 Prolog 如何执行其证明。

这里的中心概念是查询/目标的通用终止,在 SLD 树中表示:所有分支的有限性。

观察目标的普遍终止非常容易:只需执行即可Goal,false

那么这false对我们的 SLD 树做了什么?本质上,我们现在只有一个无限或有限的故障分支。所有的答案都没有了。

现在,事情变得更好了:我们甚至可以将false其引入您的程序。生成的程序称为失败切片。尽管该程序不再与原始程序相同,但以下性质成立:如果故障片没有终止(= 具有无限分支),则原始程序也不会终止(= 具有无限分支)。

故障片通常要短得多,因此理解起来要快得多。参加你的计划:

?- 路径(a,X),边缘(a,b):-边缘(b,c):-边缘(a,d):-。

路径(N,M):- 路径(N,新),边缘(新,M)路径(N,M):-,边缘(N,M)

有经验的 Prolog 程序员只看到程序的这个小片段,这更容易理解。他们没有花时间想象无限的分支,也没有想象实际的 Prolog 执行——嗯,也许有一点,但只针对片段,而不是整个程序。

从某种意义上说,false已经向我们展示了计算规则: 右侧的所有内容都false被划过。

您也可以学习“看到”这个,只需点击此链接即可。

于 2013-07-08T18:31:02.887 回答
2

我称之为无限循环。看轨迹:

?- trace, path(a,X).
Call: (7) path(a, _G394) ? 
Call: (8) path(a, _G511) ? 
Call: (9) path(a, _G511) ? 
Call: (10) path(a, _G511) ? 
...
Call: (147) path(a, _G511) ? 
Call: (148) path(a, _G511) ? 
...
ERROR: Out of local stack

我不熟悉这些术语,但我也许可以驾驭它。没有产生解决方案,所以我很难说这是一棵无限的成功树。即使给定无限的时间和空间,它也永远不会产生成功的解决方案。同时,Prolog 意义上的失败是立竿见影的,这也不会发生。我不确定是否存在无限故障树之类的东西,除非您称其为产生无限数量选择点的东西,所有选择点都失败了。但这里没有任何失败。将其称为它的真正含义会更诚实:无限循环。这样的事情存在于成功和失败的领域之外。这就是为什么在 Haskell 中,⊥ 属于所有类型。也许从这个意义上说,你们俩都是对的。

于 2013-07-08T14:36:02.297 回答