1

这对我来说有些事情retract/1没有意义。

根据 ISO/IEC 13211-1:1995:

8.9.3 收回/1

8.9.3.1 说明

retract(Clause)如果数据库包含至少一个带有与Clause 结合的子句的动态过程,则为真Head :- Body

在程序retract(Clause)上,执行如下:

a) 如果Clause与 结合':-'(Head, Body),则进行到 8.9.3.1 c,

b) ElseHeadClausetrue结合Body

c) 依次搜索数据库中的每个动态用户定义过程,并创建一个包含所有术语的列表Lclause(H, B) ,使得 1) 数据库包含一个子句,其头部可以转换为术语H(7.6.3),其主体可以被转换为一个项B(7.6.4),并且 2)H与 一致Head,并且 3)B与 一致Body

d) 如果找到非空列表,则进行到 8.9.3.1 f,

e) 否则目标失败。

f) 选择列表L的第一个元素,从数据库中删除与其对应的子句,目标成功。

g) 如果列表L的所有元素都已被选择,则目标失败。

h) Else 选择列表L中尚未选择的第一个元素,如果存在,则从数据库中删除与其对应的子句,目标成功。

retract(Clause)是可以重新执行的。回溯时,继续 8.9.3.1 g。[...]

如果它存在”?重新执行后怎么可能不存在了?

数据库更新语义表明“它”始终存在:

7.5.4 逻辑数据库更新

由于执行目标而发生的数据库中的任何更改(例如,当子目标的激活器是对assertz/1or的调用时retract/1)应仅影响随后开始执行的激活。此更改不应影响当前正在执行的任何激活。

注意——因此数据库在目标执行期间被冻结,并且定义谓词的子句列表在其执行时是固定的(见 7.7.7 e)。

下面,我尝试在重新执行之前使用retract(f(3))to make 子句消失:f(3)retract(f(X))

?- abolish(f/1), maplist(assertz,[f(1),f(2),f(3)])。
真的。% 设置完成

?- 缩回(f(X)),(X = 2 -> 缩回(f(3));真)。
   X = 1
; X = 2
; X = 3。% <----------------^^^^^^^^^^^^^

...但是,唉,我失败了:SICStus Prolog、GNU Prolog 和 SWI-Prolog 给出了相同的(以上)答案。

那么为什么在这种情况下使用“如果它存在”这个短语呢?对我来说这是多余的。和令人费解的......请帮助!

4

0 回答 0