【问题标题】:Prolog query not terminatingProlog查询未终止
【发布时间】:2021-10-18 04:54:20
【问题描述】:

这是一个非常基本的查询,但我是 prolog 的新手,很难找到为什么这个查询没有终止:

% fact 
progeny(dexter, mark).
progeny(mark, bill).
progeny(bill, lisa).


% rule
progeny(X, Y) :- progeny(X, Z), progeny(Z, Y).

查询 progeny(dexter, X) 给出了 mark、bill 和 lisa,但没有终止。
而查询 progeny(Y, lisa) 给出了 bill 和 dexter 并且没有终止(这个查询答案也错过了提及标记)。
应该注意的是,我对事实和规则使用相同的名称来测试某些值。
对此问题的任何帮助或澄清将不胜感激。

【问题讨论】:

标签: prolog transitive-closure


【解决方案1】:

您需要定义另一个充当传递关系的谓词。下面的代码同样可以正常工作(注意谓词progenyt,它是实际的传递关系)。

progeny(dexter, mark).
progeny(mark, bill).
progeny(bill, lisa).

progenyt(X, Y) :- progeny(X, Y).
progenyt(X, Y) :- progeny(X, Z), progenyt(Z, Y).

澄清

当您编写 progeny(X, Y) :- progeny(X, Z), progeny(Z, Y). 时,您会在某个时候让 prolog 尝试匹配 progeny(dexter, Y) :- progeny(dexter, lisa), progeny(lisa, Y).,这就是 prolog 变得“混乱”的时刻。

也就是说,它将尝试将progeny(lisa, Y) 与某些事实相匹配,这对于所有条目都将失败。然后,prolog 将尝试规则progeny(lisa, Y) :- progeny(lisa, Z), progeny(Z, Y).,它要求评估progeny(lisa, Z)。这里你会遇到堆栈溢出,因为progeny(lisa, Y) 要成功,progeny(lisa, Z) 也必须成功,这会导致某种无限循环,这就是为什么你的查询永远不会终止的原因。

在我发布的解决方案中,这永远不会发生,因为progenyt(lisa, Y) 要成功,progeny(lisa, Z) 必须成功,而这永远不会发生(所有事实都失败了)。因此,它只会产生这三个结果,然后会立即终止。

请注意,如果progenyprogenyt 在最后一行交换,查询也会遇到与之前相同的问题(progenyt(lisa, Y) 要成功,progenyt(lisa, Z) 也必须成功首先,会导致无限循环)。

【讨论】:

  • 非常感谢您的澄清。循环发生的原因实际上是有道理的。我只是想找到一个解决方案,让事实和规则具有相同的名称,以及为什么这是不可能的。但这让我更了解到底发生了什么。再次感谢:))
【解决方案2】:

您也可以使用tabling。阅读我链接的文档以了解背景、解释和详细信息。

要修复您的程序,您只需为谓词 progeny/2 添加一个 table 指令。

:- table progeny/2.

% fact
progeny(dexter, mark).
progeny(mark, bill).
progeny(bill, lisa).


% rule
progeny(X, Y) :- progeny(X, Z), progeny(Z, Y).

你现在应该得到:

?- [progeny].
true.

?- progeny(dexter, X).
X = bill ;
X = mark ;
X = lisa. % query terminates

?- progeny(Y, lisa).
Y = bill ;
Y = dexter ;
Y = mark. % no missing solutions, query terminates.

【讨论】:

  • 非常感谢。我不知道 prolog 谓词有一个名为 table 的记忆功能。这真的很有帮助。
  • @No_Name 这仅适用于拥有它的 Prolog 实现,因此可能是 XSB 和 SWI-Prolog。似乎巧合的是,您已经在使用其中之一了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多