从Logtalk访问SWI-Prolog库



我有很多乐趣使用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的封装性。

谢谢!

我正在为Logtalk 3设计一个通用解决方案。以支持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.

我不能测试,因为你只发布了部分目标代码。

相关内容

  • 没有找到相关文章

最新更新