2013-05-15 148 views
0

我使用Logtalk有很多樂趣,但遇到了使用phrase_from_file的問題。具體來說,我的情況看起來像這樣:訪問Logtalk的SWI-Prolog庫

:- 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). 

如果我使用pio:phrase_from_file(this::scanlist(Scans), Filename)pio:phrase_from_file(scan_parser::scanlist(Scans), Filename)

?- scan_parser::scan_file('input.txt', Scans). 
ERROR: phrase/3: Undefined procedure: pio: (::)/3 

相同的:我得到這個錯誤。如果我在模擬SWI的模塊設施時使用單個冒號,則會收到類似ERROR: phrase/3: Undefined procedure: scan_parser:scanlist/3的消息。

我認爲這裏的問題在於SWI的PIO庫正在嘗試構建一些東西來交給phrase,但它不夠智能。但是這對我來說有很大的影響,使用phrase_from_file/2,我確信有時候我會從SWI的圖書館挖掘一些東西並借用它。什麼是正確的前進方向?我想盡可能保留Logtalk的封裝。

謝謝!

+0

嗨丹尼爾。你使用哪種Logtalk版本? –

+0

我使用的是2.44.1,但如果您認爲它可能不是問題,我會嘗試3.0。在錯誤變得明顯之前,您可能還需要創建'input.txt'。 –

+0

我強烈建議您轉移到Logtalk 3.x.但是,您偶然發現了Logtalk限制(與您使用的版本無關):不支持使用閉包的模塊元謂詞(請參閱用戶手冊中的Prolog遷移部分)。然而,讓我想一下另一種解決方案。 –

回答

1

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

我無法測試,你只發布對象代碼的一部分。

+0

謝謝!如果遇到其他類似情況,我很樂意提供解決方法。 –

+0

剛剛更新的Logtalk 3.x HEAD將爲您提供(:)/ 2非終端代碼更快的生成代碼,就像您發佈的代碼一樣。 –

+0

上述限制(關於調用Prolog模塊將閉包作爲元參數的元謂語)在最新的Logtalk 3.x HEAD中解除。 –