1

functor(arg1, arg2, ..., argN)データファイルを、ファンクターの名前が大文字の行で、引数がそれに続く小文字の行であるような事実のリストに分割したい、その後、新しい句は実行時に作成されたプロローグファイルに保存されます

file.txt

FUNCTOR1
arg1 
arg2
FUNCTOR2
arg1
arg2
arg3
FUNCTOR3
arg1
arg2
arg3
arg4

結果 :

?- split_data_to_facts('file.txt',List,'file.pl').
List = ['functor1(arg1,arg2)','functor2(arg1,arg2,arg3)','functor3(arg1,arg2,arg3,arg4)'].

file.pl

「。」最後に追加されます

functor1(arg1,arg2).        
functor2(arg1,arg2,arg3).
functor3(arg1,arg2,arg3,arg4).

新しいプロローグ ファイルをビルドしてコンパイルした後file.pl:

?- functor2(X,Y,Z).
X=arg1,
Y=arg2,
Z=arg3;
yes
4

1 に答える 1

1

組み込みの read_line_to_codes/2 が利用可能であると仮定しましょう: その場合、1 行の先読みを適用できます:

process_file(Path) :-
  open(Path, read, In),
  read_line_to_codes(In, Line1),
  read_line_to_codes(In, Line2), % assume not empty
  process_lines(Line2, [Line1], In, Facts),
  maplist(writeln, Facts).  % just for test

process_lines(end_of_file, LastFactDef, In, [LastFact]) :-
  lines_fact(LastFactDef, LastFact),
  close(In).
process_lines([U|Us], LastFactDef, In, [LastFact|Facts]) :-
  upper_lower(U, _),
  lines_fact(LastFactDef, LastFact),
  read_line_to_codes(In, Line),
  process_lines(Line, [[U|Us]], In, Facts).
process_lines(Last, Lines, In, Facts) :-
  read_line_to_codes(In, Line),
  process_lines(Line, [Last|Lines], In, Facts).

lines_fact(Lines, Fact) :-
  reverse(Lines, [FunctorUpper|ArgCodes]),
  maplist(make_lower, FunctorUpper, FunctorCodes),
  maplist(atom_codes, [Functor|Args], [FunctorCodes|ArgCodes]),
  Fact =.. [Functor|Args].

% if uppercase get lowercase
upper_lower(U, L) :-
  between(0'A, 0'Z, U), L is 0'a + U - 0'A.

make_lower(C, L) :- upper_lower(C, L) ; L = C.

SWI-Prolog でテストを実行します (デフォルトで read_line_to_codes/2 と between/3 が利用可能です):

?- process_file('/home/carlo/test/file.txt').
functor1(arg1 ,arg2)
functor2(arg1,arg2,arg3)
functor3(arg1,arg2,arg3,arg4)
true 
于 2016-01-18T17:53:05.187 に答える