在Prolog中逐行读取文件

Igo*_*sky 18 io prolog swi-prolog dcg

我想读取纯文本文件并将谓词应用于每一行(谓词包含write输出的内容).我该怎么办?

Ish*_*shq 21

您可以使用它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).
Run Code Online (Sandbox Code Playgroud)

MYFILE.TXT

'line 0'.
'line 1'.
'line 2'.
'line 3'.
'line 4'.
'line 5'.
'line 6'.
'line 7'.
'line 8'.
'line 9'.
Run Code Online (Sandbox Code Playgroud)

因此,通过调用,main您将收到输出:

?- main.
[line 0,line 1,line 2,line 3,line 4,line 5,line 6,line 7,line 8,line 9]
true 
Run Code Online (Sandbox Code Playgroud)

只需配置main.write当然,这里的输出是一个例子.配置以匹配您的请求.

我认为这个原则可以用来回答你的问题.祝好运.


mat*_*mat 14

在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).
Run Code Online (Sandbox Code Playgroud)

样品用法: ?- phrase_from_file(lines(Ls), 'your_file.txt').

  • `call // 1`(然后,`eos/2`)用于从DCG规则中可移植地引用*whole*隐式DCG参数.您不能使用DCG规则,因为DCG规则受转换规则的约束,这些规则只允许它们引用这些参数的某些部分."可移植"意味着这与任何特定的Prolog系统实际上将DCG规则转换为Prolog规则的方式无关,因此它适用于支持当前由ISO起草的DCG的所有系统. (5认同)
  • 我知道已经过去很长时间了,但我正在尝试这种方法,而且似乎花了很长时间。您能否提供一些使用 DCG 和库(pio)的高性能代码示例,这些代码将按行读取文件?谢谢! (2认同)
  • 我添加了一个示例,希望对您有所帮助. (2认同)