Запись в файл (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

3 ответов


во-первых, почему это не удается :
Вы используете fail, чтобы спровоцировать отступление, что может быть хорошей техникой, но не там. Потому что это сделает ваш предикат ложным в конце, когда у члена закончатся решения. Затем, как только loop_through_list ложен, told не достигается, и запись сделана неправильно (когда я тестирую его, файл создается, но ничего не записывается).
Если вы используете :

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

вместо этого он работает.

но, даже с этим код, вы возможно, захотите использовать откройте (Filename, write, Stream), напишите(Stream, Element) и закройте(Stream) вместо tell и told по причинам, объясненным в ссылке внизу этого ответа.
Например :

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 как сохранить файл в существующем файле
Это касается того же вопроса.


Я не вижу причин использовать этот метод для записи списка в файл.
Программирование в prolog обычно не должно включать циклы;
кроме того, это не структура цикла, это больше похоже на взлом (или даже злоупотребление).
(и так же, как ваш случай приводит к неожиданным ошибкам и проблемам)

просто используйте рекурсию и распечатайте элементы списка:

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

более элегантный и может быть более эффективным.

кроме этого, используя открыть/4 и т. д. (ИСО ИО) вместо того, чтобы рассказать/1 и т. д. (Эдинбург ИО) вообще лучше; проверить сообщение false


loop_through_list(список), всегда терпит неудачу, поэтому для успеха вам просто нужно написать \+loop_through_list(список),