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)またはを使用しても同じですpio:phrase_from_file(scan_parser::scanlist(Scans), Filename)。SWI のモジュール機能のエミュレーションで代わりに 1 つのコロンを使用すると、次のようなメッセージが表示されますERROR: phrase/3: Undefined procedure: scan_parser:scanlist/3

ここでの問題は、SWI の PIO ライブラリーが渡すべきものを構築しようとしていてphrase、それが十分に知的ではないことだと思います。しかし、これは私が を使用してよく思いつくものでphrase_from_file/2あり、SWI のライブラリから何かを発掘して借りたいと思うこともあると思います。今後の正しい道は何ですか?Logtalk のカプセル化を可能な限り維持したいと思います。

ありがとう!

4

1 に答える 1

3

クロージャーをメタ引数として受け取る Prolog モジュールのメタ述語をサポートするために、Logtalk 3.x の一般的なソリューションを設計しています。それまでの間、次の (醜い) 回避策を試していただけますか。

% 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 に答える