我使用Logtalk获得了很多乐趣,但使用phrase_from_file
遇到了问题。具体来说,我的案例看起来像这样:
:- object(scan_parser).
:- public(scanlist//1).
scanlist([Scan|Scans]) --> scan(Scan), dcg_basics:blanks, scanlist(Scans).
scanlist([]) --> [].
:- public(scan_file/2).
:- mode(scan_file(+filename, -scans), one).
scan_file(Filename, Scans) :- pio:phrase_from_file(scanlist(Scans), Filename).
...
:- end_object.
麻烦就在于对phrase_from_file
的调用。它无法找到scanlist
,大概是因为它是这个对象的本地,所以我得到了这个错误:
?- scan_parser::scan_file('input.txt', Scans).
ERROR: phrase/3: Undefined procedure: pio:scanlist/3
但是,如果我尝试使用模块引用来强化它,那么:
scan_file(Filename, Scans) :- pio:phrase_from_file(::scanlist(Scans), Filename).
我收到此错误:
?- scan_parser::scan_file('input.txt', Scans).
ERROR: phrase/3: Undefined procedure: pio: (::)/3
如果我使用pio:phrase_from_file(this::scanlist(Scans), Filename)
或pio:phrase_from_file(scan_parser::scanlist(Scans), Filename)
,则相同。如果我在模拟SWI的模块工具时使用单个冒号,我会收到ERROR: phrase/3: Undefined procedure: scan_parser:scanlist/3
之类的消息。
我认为这里的问题是SWI的PIO库试图构建一些东西交给phrase
而且它不够智能。但是这对我来说很多,使用phrase_from_file/2
,我相信还有其他时候我想从SWI的图书馆中挖掘出一些东西并借用它。什么是正确的前进方向?我想尽可能地保留Logtalk的封装。
谢谢!
答案 0 :(得分:2)
我正在为Logtalk 3.x设计一个通用解决方案,以支持将闭包作为元参数的Prolog模块元谓词。同时,您可以尝试以下(丑陋)解决方法:
% ensure the module is loaded
:- use_module(library(pio)).
:- object(scan_parser).
% override the non-standard meta-arguments declarations
:- meta_predicate(pio:phrase_from_file(2,*)).
:- public(scanlist//1).
scanlist([Scan|Scans]) --> scan(Scan), dcg_basics:blanks, scanlist(Scans).
scanlist([]) --> [].
:- public(scan_file/2).
:- mode(scan_file(+filename, -scans), one).
scan_file(Filename, Scans) :- pio:phrase_from_file(user:scan_parser_scanlist(Scans), Filename).
{scan_parser_scanlist(Scans, A, B)} :-
phrase(scanlist(Scans), A, B).
...
:- end_object.
我无法测试,因为您只发布了部分目标代码。