用于序言文本处理和构建状态的模板

时间:2019-05-23 01:55:33

标签: prolog swi-prolog

我想打开一个文本文件,从中读取(任意)行,并从提取的信息中构造程序状态。特别是,我想在处理文件时跟踪行号。我已经在下面编写了代码,但是我在序言方面的经验有限,非常感谢社区提出的任何意见或建议。

我在堆栈溢出和网络上研究了类似的问题,发现Daniel Lyons(https://stackoverflow.com/a/16096728/11542361)的详细答案非常有帮助,但它无法跟踪行号。我也看过Anne Ogborn的教程(在SWI-Prolog中使用定句从句;从https://stackoverflow.com/a/14015035/11542361引用),但是我要处理的文本基本上是非结构化的(没有明确的语法规则)。

我写的代码是:

%% Text processing framework
%
% Idea is to open a file, read lines from it, and construct
% program state. The state below just counts the number of lines
% in the input file, along with the number of lines containing
% the substring "Added" [for illustrative purposes only].

source_file('logfile.txt').

main(_Argv) :-
  source_file(Source_File),
  open(Source_File, read, Input),
  % Sample state: count # lines containing 'Added'
  load_state(Input, state(added(0),lines(0)), State, 0),
  !,               % prohibit backtracking to load_state()
  close(Input),
  print(State).    % process loaded information

%% load_state(+Input, +Old_State, -New_State, +Previous_Line_Number)
load_state(Input, Old_State, New_State, Previous_Line_Number) :-
  Line_Number is Previous_Line_Number + 1,
  read_line_to_string(Input, Line),
  load_state_x(Input, Line, Old_State, New_State, Line_Number).

% load_state_x enforces termination at end_of_file, and also
% invokes recursion back to load_state() for the next line.
load_state_x(_, end_of_file, State, State, _).
load_state_x(Input, Line, Old_State, New_State, Line_Number) :-
  process_line(Line, Old_State, Next_State, Line_Number),
  load_state(Input, Next_State, New_State, Line_Number).

% process_line() has knowledge of the system state, and updates it.
process_line(Line, state(added(Count),lines(_)),
                   state(added(New_Count),lines(Line_Number)), Line_Number) :-
  sub_string(Line,_,_,_,"Added"),
  New_Count is Count + 1.

% "Added" not a substring of Line (per above)
process_line(_Line, state(added(Count),lines(_)),
                    state(added(Count),lines(Line_Number)), Line_Number).

上面的代码在SWI-Prolog中有效(在有限测试中);尚未在其他任何序言系统上尝试过。

0 个答案:

没有答案