得到了这种奇怪的行为。我正在运行这些测试用例:
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:
该错误已在 SWI-Prolog 8.3.17 (devel) 中修复,并且
也向后移植到 SWI-Prolog 8.2.4 (stable)。