我目前正在学习逻辑编程,并为此案例学习Prolog
。
我们可以有一个Knowledge Base
,它可以引导我们到某些results
,而Prolog
会进入无限循环,因为它扩展了谓词。
假设我们有以下logic program
p(X):- p(X).
p(X):- q(X).
q(X).
查询p(john)
将进入无限循环,因为Prolog
默认扩展统一的第一个谓词。但是,如果我们开始扩展第二个谓词,我们可以得出结论p(john)
为真。
那么为什么没有Prolog
扩展所有匹配谓词(像时间片一样实现线程/进程模型),以便在KB
能够得出结论的情况下得出结论?
在我们的例子中,例如,可以创建两个进程,一个用p(X)扩展,另一个用q(X)扩展。因此,当我们稍后扩展q(X)时,我们的程序将结束q(john)
。
答案 0 :(得分:5)
因为Prolog的匹配谓词的搜索算法是depth-first。因此,在您的示例中,一旦匹配第一个规则,它将再次匹配第一个规则,并且永远不会探索其他规则。
如果算法为breadth-first或iterative-deepening,则不会发生这种情况。
通常由您来重新排序KB,以便这些情况永远不会发生。
但是,可以使用更改搜索顺序的元解释器在Prolog中对breadth-first / iterative-deepening搜索进行编码。这是一种非常强大的技术,在Prolog世界之外并不为人所知。 'The Art of Prolog'详细描述了这种技术。