微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 SICStus Prolog 中模拟发生_检查=错误

如何解决在 SICStus Prolog 中模拟发生_检查=错误

事实证明,SICStus Prolog 没有发生的检查 序言标志。至少我们找不到一个,而这个在这里 给出错误信息:

/* SICStus 4.6.0 (x86_64-win32-nt-4) */

?- set_prolog_flag(occurs_check,true).
Domain error in argument 1 of set_prolog_flag/2 

似乎值“true”不是问题, 关键的统一可以通过现有的 内置 unify_with_occurs_check/2一个有趣的值 发生_检查 Prolog 标志的值是“错误”。

如何实现谓词 unify_with_occurs_check_and_error/2 ? 请注意,unify_with_occurs_check_and_error/2 的解决方案 应该表现得像 unify_with_occurs_check/2,即不触发 归因变量。

以下是 Prolog 标志的示例用法

?- set_prolog_flag(occurs_check,error).
true.

?- X = f(X).
ERROR: ...

这就是在 SICStus Prolog 中会做的事情:

?- unify_with_occurs_check_and_error(X,f(X)).
ERROR: ...

解决方法

正在改编 here 中的代码并得到以下解决方案:

unify_with_error(X,Y) :- var(X),var(Y),!,X = Y.
unify_with_error(X,must_notin(X,Y),Y) :- var(Y),must_notin(Y,X),Y) :- functor(X,F,A),functor(Y,G,B),F/A = G/B,X =.. [_|L],Y =.. [_|R],maplist(unify_with_error,L,R).

must_notin(X,Y) :-
   term_variables(Y,L),maplist(\==(X),!.
must_notin(X,Y) :-
   throw(error(occurs_check(X,_)).

似乎有效并且不干扰属性变量:

/* SICStus 4.6.0 (x86_64-win32-nt-4) */

?- unify_with_error(X,f(X)). 
error(occurs_check(_413,f(_413)),_409)

?- freeze(X,throw(ball)),unify_with_error(X,f(X)).
error(occurs_check(_413,_409)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。