Прочитайте файл в строке в Prolog
Я хотел бы прочитать простой текстовый файл и применить предикат к каждой строке (предикаты содержат write
, который делает вывод). Как мне это сделать?
Ответы
Ответ 1
В SWI-Prolog самое чистое решение - написать DCG, который описывает, что такое "строка", а затем вызвать предикат для каждой строки. Используйте библиотеку (pio), чтобы применить DCG к файлу.
РЕДАКТИРОВАТЬ: в соответствии с запросом подумайте:
:- use_module(library(pio)).
lines([]) --> call(eos), !.
lines([Line|Lines]) --> line(Line), lines(Lines).
eos([], []).
line([]) --> ( "\n" ; call(eos) ), !.
line([L|Ls]) --> [L], line(Ls).
Использование образца: ?- phrase_from_file(lines(Ls), 'your_file.txt').
Ответ 2
Вы можете использовать read
для чтения потока. Не забудьте вызвать at_end_of_stream
, чтобы избежать синтаксических ошибок.
Пример:
readFile.pl
main :-
open('myFile.txt', read, Str),
read_file(Str,Lines),
close(Str),
write(Lines), nl.
read_file(Stream,[]) :-
at_end_of_stream(Stream).
read_file(Stream,[X|L]) :-
\+ at_end_of_stream(Stream),
read(Stream,X),
read_file(Stream,L).
Myfile.txt
'line 0'.
'line 1'.
'line 2'.
'line 3'.
'line 4'.
'line 5'.
'line 6'.
'line 7'.
'line 8'.
'line 9'.
Таким образом, вызывая main
, вы получите результат:
?- main.
[line 0,line 1,line 2,line 3,line 4,line 5,line 6,line 7,line 8,line 9]
true
Просто настройте main
. Результат здесь - пример, используя write
, конечно. Настройте соответствие вашему запросу.
Я предполагаю, что этот принцип может быть применен для ответа на ваш вопрос. Удачи.
Ответ 3
Существуют более вероятные по количеству и более разумные в производительности решения для получения неинтерпретируемых, то есть строк простого текста из файла:
SWI-Prolog:
read_line(S, X) :-
read_line_to_codes(S, L),
read_line2(L, X).
read_line2(end_of_file, _) :- !, fail.
read_line2(L, X) :-
atom_codes(X, L).
Пролог Йекеджеке:
:- use_module(library(stream/console)).
Вот несколько моментов времени чтения файла из 655 строк:
test :-
open('<path>', read, Stream),
test(Stream),
close(Stream).
test(Stream) :-
read_line(Stream, _), !,
test(Stream).
test(_).
SWI-Prolog:
̀?- time((between(1,100,_), test, fail; true)).
% 328,300 inferences, 0.125 CPU in 0.143 seconds (88% CPU, 2626400 Lips)
true.
Пролог Йекеджеке:
?- time((between(1,100,_), test, fail; true)).
% Up 121 ms, GC 2 ms, Thread Cpu 94 ms (Current 05/07/19 17:19:05)
Yes
Я полагаю, что решение SWI-Prolog, которое считывает строку вместо атома, может быть быстрее. Но в вышеупомянутом мы сравниваем атом против чтения атома.