2011-11-27 54 views
6

我一直試圖循環遍歷一個列表並將其寫入一個文件,爲什麼下面不起作用?寫入文件(Prolog)

loop_through_list(List) :- 
    member(Element, List), 
    write(Element), 
    write(' '), 
    fail. 

write_list_to_file(Filename,List) :- 
    tell(Filename),  % open file to be written 
    loop_through_list(List), 
    told.    % flush buffer 
+1

查看運行'write_list_to_file/2'時創建的文件!很可能它不僅包含列表中的元素,還包含文件末尾的其他一些非預期數據。正如其他人已經指出的那樣,使用'open/3'和'close/1'更安全。 – false

+0

我很好奇在哪裏可以找到關於告訴和告訴的不可靠性的信息,你可以指點我嗎? – chutsu

+1

你找到一個解釋[這裏](http://stackoverflow.com/questions/8269971/prolog-how-to-save-file-in-an-existing-file/8270091#8270091) – false

回答

7

首先,失敗的原因:
您使用不惹回溯,它可以是一個很好的技術,但不存在。因爲當成員用完解決方案時,它最終會使謂詞錯誤。然後,一旦loop_through_list爲false,告知未達到,寫入不正確(當我測試它時,文件被創建但沒有寫入)。
如果你使用:

loop_through_list([]). 
loop_through_list([Head|Tail]) :- 
    write(Head), 
    write(' '), 
    loop_through_list(Tail). 

相反,它的工作原理。

但是,即使使用此代碼工作,您可能也希望使用 打開(文件名,寫入,流),寫入(流,元素)和關閉(流),而不是告訴並告知鏈接中解釋的原因在這個答案的底部。
例如:

loop_through_list(_File, []) :- !. 
loop_through_list(File, [Head|Tail]) :- 
    write(File, Head), 
    write(File, ' '), 
    loop_through_list(File, Tail). 

write_list_to_file(Filename,List) :- 
    open(Filename, write, File), 
    loop_through_list(File, List), 
    close(File). 

loop_through_list(File, List) :- 
    member(Element, List), 
    write(File, Element), 
    write(File, ' '), 
    fail. 

write_list_to_file(Filename,List) :- 
    open(Filename, write, File), 
    \+ loop_through_list(File, List), 
    close(File). 

使用您的代碼和joel76伎倆。

請參閱Prolog how to save file in an existing file
它涵蓋了同樣的問題。

+0

順便說一句,什麼是'\ +'?它是不是意思(例如C中的'!')。 – chutsu

+1

@chutsu:是的,它的確如此。至少在SWI-pl中(其他人可能會告訴你其他的實現),** not/1 **已被棄用,並且推薦使用** \ +/1 **,如本手冊頁所述(http ://www.swi-prolog.org/pldoc/doc_for對象=未/ 1) – m09

2

謂詞loop_through_list(列表),總是失敗,所以要贏得成功,你只需要編寫\ + loop_through_list(列表),

3

我看不出做使用這種方法寫的理由列表到文件。
在prolog編程通常不應該涉及循環;另外,這不是一個循環結構,它更像是一個黑客(甚至是濫用)。
(以及就像你的情況下,會導致意想不到的錯誤和問題)

只需使用遞歸和打印列表中的元素:

write_list([]). 
write_list([H|T]):- 
    write(H), 
    write(' '), 
    write_list(T). 

更優雅,可以更有效的了。

除此之外,使用open/4 etc(ISO IO)而不是tell/1 etc(Edinburgh IO)通常更好;檢查false's post