问题描述
是否存在发生检查的差异? 这在这里有效:
Welcome to SWI-Prolog (threaded,64 bits,version 8.3.7)
?- set_prolog_flag(occurs_check,true).
true.
?- dif(X,f(Y)),X = Y.
X = Y.
但是上述方法不可行,因为会进行检查 是全局标志,我得到以下信息:
SWI-Prolog console for thread 3
?- X=f(X).
false.
解决方法
现在,Scryer 支持 dif/2
,并在设置相应标志时进行发生检查:
?- use_module(library(dif)).
true.
?- set_prolog_flag(occurs_check,true).
true.
?- dif(-X,X).
true.
?- dif(-X,Y).
dif:dif(- X,Y).
?- dif(-X,X),X = a.
X = a.
,
在我的系统中,我做了一个新的谓词dif_with_occurs_check/2
。顾名思义,它是dif/2
,带有发生检查,因此不需要设置标志。但是还有一个额外的好处,dif/2
经过优化,可以侦听更少的变量:
/* listens only to changes in X */
?- dif(X,f(Y)).
/* listens to changes in X and Y */
?- dif_with_occurs_check(X,f(Y)).
这是必需的,以便在将变量dif_with_occurs_check/2
例如更改为Y
时可以唤醒Y = X
。 dif_with_occurs_check/2
随后将删除其自己的约束X = f(Y)
,该约束已变为X = f(X)
,因此已过时。
?- dif(X,f(Y)),X = Y.
X = Y,dif(Y,f(Y))
?- dif_with_occurs_check(X,X = Y.
X = Y
开源:模块“ herbrand”
https://github.com/jburse/jekejeke-devel/blob/master/jekmin/headless/jekmin/reference/term/herbrand.p