2011-11-27 3 views
6

Ho cercato di scorrere un elenco e scriverlo in un file, perché il seguente non funziona?Scrittura su file (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

Cerca nel file creato durante l'esecuzione di 'write_list_to_file/2'! Molto probabilmente non avrà solo gli elementi della lista, ma anche alcuni altri dati non voluti alla fine del file. Come altri hanno già osservato, l'uso di 'open/3' e' close/1' è molto più sicuro. – false

+0

Sono curioso di sapere dove si trovano le informazioni sull'affidabilità del racconto e del racconto, puoi gentilmente indicarmi la fonte? – chutsu

+1

Trovate una spiegazione [qui] (http://stackoverflow.com/questions/8269971/prolog-how-to-save-file-in-an-existing-file/8270091#8270091) – false

risposta

7

In primo luogo, perché non riesce:
Si utilizza riuscire a provocare backtracking, che può essere una buona tecnica, ma non c'è. Perché renderà falso il tuo predicato alla fine, quando il membro ha esaurito le soluzioni. Quindi, una volta che loop_through_list è falso, detto non viene raggiunto e la scrittura non viene eseguita correttamente (quando eseguo il test, il file viene creato ma non viene scritto nulla).
Se si utilizza:

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

invece, funziona.

Ma, anche con questo codice funzionante, è possibile utilizzare aperto (Nome file, scrittura, Stream), scrivere (Stream, Elemento) e chiudere (Stream) invece di raccontare e raccontare per i motivi spiegati nel collegamento in fondo a questa risposta.
Per esempio:

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

o

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

utilizzando il codice e trick joel76.

Vedere Prolog how to save file in an existing file
Riguarda la stessa questione.

+0

a proposito, che cos'è il '\ +'? non significa (ad es. "!" in C). – chutsu

+1

@chutsu: sì, lo fa. Almeno in SWI-pl (e altri potrebbero parlarvi di altre implementazioni), ** non/1 ** è deprecato e l'uso di ** \ +/1 ** è raccomandato come detto in questa [pagina di manuale] (http :? //www.swi-prolog.org/pldoc/doc_for oggetto = non/1) – m09

2

predicato loop_through_list (List), fallisce sempre, per così succed devi solo scrivere \ + loop_through_list (List),

3

Non vedo la ragione per fare uso questo metodo per scrivere un elenca un file.
La programmazione in prolog generalmente non dovrebbe coinvolgere cicli;
Inoltre, questa non è una struttura di loop, è più come un hack (o anche un abuso).
(e, proprio come il vostro caso porta ad errori inaspettati e problemi)

Basta usare la ricorsione e stampare gli elementi della lista:

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

più elegante e potrebbe essere più efficiente troppo.

diverso da quello, utilizzando open/4 ecc. (ISO IO) invece di tell/1 etc (Edinburgh IO) è generalmente migliore; controlla false's post