1

I want to separate the data file into list of facts like functor(arg1, arg2, ..., argN) which the name of functor is the uppercase line and the arguments are the lowercase lines that follow them, subsequently, new clauses are saved in a prolog file created at the execution

file.txt

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

result :

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

file.pl

"." will be appended as the last

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

after building and compiling the new prolog file file.pl:

?- functor2(X,Y,Z).
X=arg1,
Y=arg2,
Z=arg3;
yes
Ans Piter
  • 573
  • 1
  • 5
  • 17
  • 1
    Have you tried anything? – lurker Jan 18 '16 at 14:53
  • i try to parse file and puting data into List – Ans Piter Jan 18 '16 at 15:11
  • 1
    Where did you get stuck? You can make use of the `=../2` operator. For example, `X =.. [functor, a, b]` is `X = functor(a, b)`. – lurker Jan 18 '16 at 17:13
  • the list is like :List=['FUNCTOR1','arg1','arg2','FUNCTOR2','arg1','arg2','arg3'|...] – Ans Piter Jan 18 '16 at 17:31
  • You will need to split up your list first. You should be able to write a little, very simple, list processing code to do that. Or, split it up while you're reading it in from the file so that the functors are separate. – lurker Jan 18 '16 at 17:33
  • u know how to convert uppercase atom to lowercase in `sicstus-prolog` ? – Ans Piter Jan 18 '16 at 17:37
  • I don't use sicstus Prolog, but if you look in the documentation, I'm sure it should be easy to find. Look for atom and string processing predicates. – lurker Jan 18 '16 at 17:46
  • sadly I find nothing but I attempting to use to use char_codes/2 and adding 32 like `X=a, to_upper(X,Y) :- char_code(X,N),N1 is N-32,char_code(Y,N1)` – Ans Piter Jan 18 '16 at 17:55

1 Answers1

1

Let's assume a builtin read_line_to_codes/2 is available: then you could apply a lookahead of one line:

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.

running a test in SWI-Prolog (where we have by default available read_line_to_codes/2 and between/3):

?- process_file('/home/carlo/test/file.txt').
functor1(arg1 ,arg2)
functor2(arg1,arg2,arg3)
functor3(arg1,arg2,arg3,arg4)
true 
CapelliC
  • 59,646
  • 5
  • 47
  • 90