prolog - Prolog 的逻辑更新 View 如何用于断言和收回?

标签 prolog iso-prolog prolog-assert

有人可以详细解释有关断言和撤回的 Prolog 逻辑 View 吗?

例如在下面的代码中,在第一次运行时 Prolog 返回 true,在后续运行中返回 false。我不知道为什么因为 Prolog 逻辑 View 时 asserta(nextBound(100))满足,nice(X) 在启动时仍然被值卡住,因此应该忽略此更改并且 nextbound(100)一定是假的。

nextBound(10000).

nice(X) :-
   asserta(nextBound(100)),
   retract(nextBound(10000)),
   nextBound(100).

最佳答案

从历史角度来看,逻辑更新 View 首先在 Quintus 2.0(其当前的继任者是 SICStus)中实现并在 1987 年的文献中进行了描述。它已被 ISO Prolog ISO/IEC 13211-1:1995 采纳。主要思想是,动态谓词的任何目标都将准确地考虑在执行目标时出现的那些子句。任何进一步的变化——无论是添加还是删除——都不会被考虑到执行那个目标。

在逻辑更新 View 之前,已经有各种或多或少一致的实现,大多数与 Prolog 系统的各种优化不兼容。请注意,差异仅在您的目标可能有多个答案时显示。无论是作为一个简单的目标,还是在使用回缩时 您正在使用 retract/1assertz/1 .使用asserta/1时不显示差异只要。所以你的例子无法澄清差异。

考虑一个动态谓词 p/1 .由于以下交互仅使用顶层,我将制作 p/1通过断言事实并立即撤回 p/1 的所有事实而被系统知晓.另外,我将使用 retractall(p(_)) 删除所有事实。在开始下一个查询之前。

?- asserta(p(1)).
true.  % now p/1 is known to the system.

?- retractall(p(_)), assertz(p(1)), p(X), assertz(p(2)).
X = 1.  % only one answer!

?- retractall(p(_)), assertz(p(1)), p(X), assertz(p(2)), p(Y).
X = 1, Y = X ;
X = 1,
Y = 2.

所以第一个目标p(X)只能看到 p(1) ,而第二个目标 p(Y)两者都看到。这适用于任何事件目标:
?- retractall(p(_)), assertz(p(1)), assertz(p(2)), p(X), assertz(p(3)), p(Y).
X = 1, Y = X ;
X = 1,
Y = 2 ;
X = 1,
Y = 3 ;
X = 2,
Y = 1 ;
X = 2, Y = X ;
X = 2,
Y = 3 ;
X = 2,
Y = 3 ;
false.

再次注意 X只有 1 或 2 但不是 3。

或者,您可以想象每个目标 p(X)被替换为:
... findall(Xi, p(Xi), Xis), member(X, Xis) ...

这向您展示了背后的想法:从概念上讲,所有答案都是临时存储的,然后才显示每个答案。

呃,上面说的不太对,只针对p/1的子句是这样处理的。也就是说,只要你只存储事实,上面的解释是完美的,但如果你还存储规则,你需要一个更复杂的解释,大致:
 ... findall(Xi-Bi, clause(p(Xi),Bi), XiBis), member(X-B,XiBis), B ...

而且,再一次,这不是简单的事实,因为一些更奇特的问题,如削减可能会干预。我暂时就这样吧1。

同样,retract/1还将查看和删除它在执行时看到的子句。对于大多数情况,这是非常直观的并且符合我们的预期。然而,也有一些非常荒谬的情况如下:
?- retractall(p(_)),
   assertz(p(1)), assertz(p(2)),
   retract(p(X)), ( X = 1, retract(p(Y)) ; X = 2, Y = none ).
X = 1,
Y = 2 ;
X = 2,
Y = none.

在这里,事实p(2)被删除了两次,尽管数据库只包含一个事实 p(2).
脚注

1 实际上,替换
... p(X) ...

经过
... findall(Xi-Bi, clause(p(Xi),Bi), XiBis), answs_goal_x(XiBis,X, G), G ...


answs_goal_x([], _, true).
answs_goal_x([Xi-Bi|XiBis], X, ( X = Xi, Bi ; G) ) :-
   answs_goal_x(XiBis, X, G).

关于prolog - Prolog 的逻辑更新 View 如何用于断言和收回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28116244/

相关文章:

prolog - 错误: Unhandled exception: Out of local stack - Prolog

prolog - 列出给定库模块中的谓词

floating-point - “float”对Prolog的实现意味着什么?

prolog - 如何避免在Prolog中使用assert和retractall来实现全局(或状态)变量

prolog - 在 SICStus Prolog/SWI-Prolog REPL 中定义谓词

loops - 序言,无限循环

list - 将列表 1 中的特定数字与列表 2 中的特定数字交换

prolog - abolish/1和retractall/1有什么区别?

prolog - 在序言中多次避免相同的答案

prolog - 为什么 SWI-Prolog 将带引号和不带引号的字符串(不带空格)统一为同一规则?