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

声明模块本地化的运算符时,SWI-Prolog失败

如何解决声明模块本地化的运算符时,SWI-Prolog失败

当声明优先级大于1000的模块本地化的运算符时,由于“冲突”声明而动态加载模块时,最新版本的SWI-Prolog(例如8.2.1)失败。以test.pl为例:

:- module(test,[rule/1]).
:- use_module([library(lists),library(qsave)]).
test:set_ops :- test:op(1098,fx,prefix).
:- test:set_ops.
:- initialization test:set_ops.
rule(prefix F) :-
  atom(F),!,op(100,fy,F).
rule(A) :-
  atom(A),user:qsave_program(A,[goal = true,op = save]).

请注意,prefixprefix中的library(lists)冲突。但是,prefix是在test的模块范围内声明的运算符。作用域似乎不起作用:

?- [test].
?- apropos(append).
ERROR: /Applications/SWI-Prolog.app/Contents/swipl/library/lists.pl:40:16: Syntax error: Operator expected
ERROR: prolog_stack:find_subgoal/3: UnkNown procedure: prolog_stack:nth1/3

调用user:qsave_program/2失败,尽管事实上已经导入了library(qsave)

:- rule(saveme).
ERROR: /Applications/SWI-Prolog.app/Contents/swipl/library/lists.pl:40:16: Syntax error: Operator expected
ERROR: /Applications/SWI-Prolog.app/Contents/swipl/library/lists.pl:40:16: Syntax error: Operator expected
ERROR: /Applications/SWI-Prolog.app/Contents/swipl/library/lists.pl:76:
ERROR:    Domain error: `module_file' expected,found `'/Applications/SWI-Prolog.app/Contents/swipl/library/lists.pl''

任何想法如何解决此问题?

解决方法

显然,test:op(1098,fx,prefix)不会将prefix运算符放置在test模块中,但是op(1098,test:[prefix])会放置。 SWI-Prolog 8.2.1文档对此一无所知。

更正的程序:

:- module(test,[rule/1]).
:- use_module([library(lists),library(qsave)]).
set_ops :- op(1098,test:[prefix]).
:- set_ops.
:- initialization set_ops.
rule(prefix F) :-
  atom(F),!,op(100,fy,F).
rule(A) :-
  atom(A),qsave_program(A,[goal = true,op = save]).

但是,似乎有一个错误,该错误在调用qsave_program/2(通过rule(saveme))后“忘记”谓词:

?- [test].
?- rule(saveme).
?- apropos(append).
ERROR: Unknown procedure: apropos/1 (DWIM could not correct goal)

好吧,只要不使用qsave_program/2,也就是说,当不调用rule(saveme)时,至少其他一切似乎都可以正常工作。

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