Фрагментация данных из текстового файла в список фактов в файл пролога
Я хочу разделить файл данных на список фактов, таких как 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
1 ответ
Давайте предположим, что встроенный read_line_to_codes/2 доступен: тогда вы можете применить просмотр одной строки:
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 и между /3):
?- process_file('/home/carlo/test/file.txt').
functor1(arg1 ,arg2)
functor2(arg1,arg2,arg3)
functor3(arg1,arg2,arg3,arg4)
true