2011-11-27 13 views
6

He estado tratando de recorrer una lista y escribirla en un archivo, ¿por qué no funciona lo siguiente?Escribiendo en el archivo (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

¡Busca en el archivo que creaste al ejecutar 'write_list_to_file/2'! Es probable que no solo contenga los elementos de la lista, sino también otros datos no deseados al final del archivo. Como otros ya han comentado, usar 'open/3' y' close/1' es mucho más seguro. – false

+0

Tengo curiosidad por saber dónde se puede encontrar la información sobre la falta de fiabilidad de contar y contar, ¿me puede indicar amablemente la fuente? – chutsu

+1

Encontrará una explicación [aquí] (http://stackoverflow.com/questions/8269971/prolog-how-to-save-file-in-an-existing-file/8270091#8270091) – false

Respuesta

7

En primer lugar, por qué no funciona:
Utiliza dejar de provocar el retroceso, que puede ser una buena técnica, pero no existe. Porque al final hará que su predicado sea falso, cuando el miembro se haya quedado sin soluciones. Entonces, una vez que loop_through_list es falso, no se ha contactado y la escritura no se ha realizado correctamente (cuando lo pruebo, se crea el archivo pero no se escribe nada).
Si utiliza:

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

lugar, funciona.

Pero, incluso con este código funcionando, es posible que desee utilizar abierto (Nombre de archivo, escritura, Stream), escribir (Stream, Element) y cerrar (Stream) en lugar de decir y contar por los motivos explicados en el enlace en la parte inferior de esta respuesta.
Por ejemplo:

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

utilizando su código y truco joel76.

Ver Prolog how to save file in an existing file
Cubre el mismo asunto.

+0

por cierto, ¿qué es? el '\ +'? ¿significa que no (por ejemplo, '!' en C). – chutsu

+1

@chutsu: sí, lo hace. En SWI-pl al menos (y otros pueden informarle sobre otras implementaciones), ** not/1 ** está en desuso y se recomienda el uso de ** \ +/1 ** como se indica en esta [página del manual] (http : //www.swi-prolog.org/pldoc/doc_for? object = not/1) – m09

2

predicado loop_through_list (Lista), siempre falla, por lo que succed sólo hay que escribir \ + loop_through_list (Lista),

3

no veo la razón para hacer uso de este método para escribir una lista a un archivo.
La programación en prolog generalmente no debe incluir bucles;
Además, esta no es una estructura de bucle, es más como un truco (o incluso abuso).
(y al igual que su caso conduce a errores inesperados y problemas)

Sólo tiene que utilizar la recursividad e imprimir los elementos de la lista:

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

más elegante y podría ser más eficiente.

que no sea eso, usar open/4 etc (ISO IO) en lugar de tell/1 etc. (Edinburgh IO) es generalmente mejor; check false's post