2

我在使用 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)or 也一样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 的封装。

谢谢!

4

1 回答 1

3

我正在为 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.

我无法测试,因为您只发布了部分目标代码。

于 2013-05-15T20:11:51.080 回答