【发布时间】:2021-01-01 19:21:15
【问题描述】:
得到了这个奇怪的行为。我正在运行这些测试用例:
s1 :-
Q=[[lambda,symbol(_3026),[cons,[quote,_3434],
[quote,_3514]]],[quote,_3206]],
P=[_3434|_3514],
freeze(_3434, (write(foo), nl)),
unify_with_occurs_check(P, Q).
s2 :-
Q=[[lambda,symbol(_3026),[cons,[quote,_3434],
[quote,_3514]]],[quote,_3206]],
P=[_3434|_3514],
freeze(_3434, (write(foo), nl)),
freeze(_3514, (write(bar), nl)),
unify_with_occurs_check(P, Q).
现在我得到了这些结果,其中s2 的结果是错误的。结果在两个方面是错误的,第一个_3434被触发,第二个unify_with_occurs_check成功:
SWI-Prolog (threaded, 64 bits, version 8.3.16)
?- s1.
false.
?- s2.
foo
bar
true.
_3434 不应被触发遵循 ISO 核心标准中的 7.3.2 Herband 算法。根据条款 7.3.2 f) 1) 将变量 X 实例化为术语 t 仅在其 X 不在 t 中出现时传播。
根据第 7.3.2 g) 条,统一应该失败。因此,在 SWI-Prolog 中,诸如 freeze/2、dif/2 等各种形式的属性变量似乎会干扰 unify_with_occurs_check。
有什么解决方法吗?
编辑 06.02.2021:
bug 已在 SWI-Prolog 8.3.17(开发)和
中修复
也被向后移植到 SWI-Prolog 8.2.4(稳定版)。
【问题讨论】:
-
如何减少示例的大小并提高其可读性?
-
在 Scryer 和 SICStus 中工作。
-
跟可怜的
dif/2无关:freeze(A,true),freeze(B,true),unify_with_occurs_check(A-B,s(A,B)-n). -
@false 那么这是一个错误吗?
-
@MaxB:确实,这是一个错误。最简单的论点(不涉及任何细节)是:获取上述查询并将其与相同的查询进行比较,但没有冻结目标之一。删除目标不应使查询失败,但确实如此。
标签: prolog swi-prolog logical-purity occurs-check