【问题标题】:SWI Prolog backtracking behavior after `read/1` call`read/1` 调用后的 SWI Prolog 回溯行为
【发布时间】:2017-11-16 11:53:13
【问题描述】:

我在 StackOverflow 上查看another Prolog 问题,遇到了这种情况。

假设我有以下事实:

foo(1).
foo(2).
foo(3).
foo(4).

在 SWI Prolog(版本 7.4.2)提示符下,我执行了以下操作:

2 ?- write('Enter number: '), read(X), nl, foo(Y), Y > X.
Enter number: 1.

X = 1,
Y = 2.

3 ?-

如您所见,SWI Prolog 提供了一种解决方案,没有提示其他解决方案(确实存在)。它不会回溯。

在 GNU Prolog(版本 1.4.4)中,行为更符合我的预期:

| ?- write('Enter number: '), read(X), nl, foo(Y), Y > X.
Enter number: 1.

X = 1
Y = 2 ? ;

X = 1
Y = 3 ? ;

X = 1
Y = 4

yes
| ?-

感谢@trivelt 将问题简化为:

?- foo(X).           % Backtracks and finds all solutions for X
?- read(_), foo(X).  % Does not backtrack and finds only one solution for X


这是 SWI 版本 7.4.2 实现中的错误吗?或者这些替代的可接受/预期的行为?

【问题讨论】:

  • 您的问题甚至可以简化为read(_), foo(X).。当我们删除read 时,它会计算所有可能的答案。这很有趣,但不幸的是我不知道这种奇怪行为的原因。
  • SWI 6.6.6 版的行为类似于 GNU Prolog
  • @gusbro 很有趣。所以他们可能在随后的版本中破坏了一些东西。这似乎是一个基本场景,所以它偷偷溜过去有点令人惊讶。
  • @trivelt 感谢您的简化。我正在模仿引起我注意的原始问题,但我会将您的评论添加到帖子中,因为它可以很好地减少问题。
  • 仅作记录:Yap 6.2.2 的行为也与 GNU Prolog 相似,包括原始示例和简化。

标签: prolog


【解决方案1】:

至少,我认为与程序的交互可能会以这种意想不到的方式干扰 SWI 顶层的严重缺陷 >顶级控制。

在 SWI-Prolog 中,这被归档为 issue #166

Using read/1 on the toplevel commits unexpectedly

SWI 顶层的这一缺陷使用户无法在许多实际相关的情况下看到所有解决方案。

由于 ECLiPSe 已经修复了这个问题,也许有人会在某个时候在 SWI 中修复它。

【讨论】:

  • 谢谢,这基本上回答了这个问题,即它是否被官方认为是一个错误而不是一个可接受的“替代行为”(尽管这样的事情会很奇怪)。我应该搜索 SWI 问题数据库。
猜你喜欢
  • 2019-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-07
  • 1970-01-01
  • 2023-04-07
相关资源
最近更新 更多