Home > database >  How can I save and load data files in Prolog?
How can I save and load data files in Prolog?

Time:11-14

How can I quickly save and load data files in Prolog, for use with games?

Save files with save(File_name,Term), where File_name is the file name in folder folder_name and Term is a compound containing the data file.

?- save("file_name.txt",[[["player_name","Harold"],["score",10],["symbol",key_word]],[["player_name","Queenie"],["score",20],["symbol",schema]]]).

Load files with load(File_name,Term), where File_name is the file name in folder folder_name and Term is the contents loaded from the file.

?- load("file_name.txt",Term),writeln1(Term).
Term=[[["player_name","Harold"],["score",10],["symbol",key_word]],[["player_name","Queenie"],["score",20],["symbol",schema]]]

CodePudding user response:

Using the code below you can save and load data files in Prolog.

% save("file_name.txt",[[["player_name","Harold"],["score",10],["symbol",key_word]],[["player_name","Queenie"],["score",20],["symbol",schema]]]).

save(File_name,Term) :-
    string_concat("folder_name/",File_name,Path),
    term_to_atom(Term,Atom),
    string_atom(String,Atom),
    (open_s(Path,write,Stream1),
    write(Stream1,String),
    close(Stream1)),!.

% load("file_name.txt",Term).

load(File_name,Term) :-
    File_name="file_name.txt",
    string_concat("folder_name/",File_name,Path),
    phrase_from_file_s(string(Codes),Path),
    string_codes(String,Codes),
    atom_to_term(String,Term,[]).

open_s(File,Mode,Stream) :-
    atom_string(File1,File),
    open(File1,Mode,Stream),!.

string_atom(String,Atom) :-
    atom_string(Atom,String),!.

phrase_from_file_s(string(Output), String) :-
    atom_string(String1,String),
    phrase_from_file(string(Output), String1),!.

string(String) --> list(String).

list([]) --> [].
list([L|Ls]) --> [L], list(Ls).
    
writeln1(Term) :-
    term_to_atom(Term,Atom),
    writeln(Atom),!.    
    

See also string to list (Test 15) in List Prolog, which does the same thing as atom_to_term//3. The predicates above replace the need for using long grammars, however I have posted answers on My long SWI-Prolog grammar keeps on failing and I can't get my Prolog DCG working with atom concat for those who are interested.

CodePudding user response:

If you only want to save a single term, a basic version of what you want is the following:

save(Filename, Term) :-
    open(Filename, write, Stream),
    write_canonical(Stream, Term),
    write(Stream, '.'),
    close(Stream).

load(Filename, Term) :-
    open(Filename, read, Stream),
    read(Stream, Term),
    close(Stream).

For example:

?- save('hello.term', hello(world)).
true.

At this point the file hello.term (the name is arbitrary) contains this:

hello(world).

Then:

?- load('hello.term', Term).
Term = hello(world).

Notes:

  • The read predicates expect to read a term with a terminating period ('.'), but the write predicates don't write those out by themselves. Therefore save/2 needs to write it explicitly.
  • There is no error handling here.
  • There is also a write/2 predicate that could be used. The difference is relevant if you use operators: The term a b will be written as a b by write and as (a, b) by read. The latter can be read correctly even in cases where the write and the read happen with different operator declarations.
  • More work is needed if you want to write or read multiple terms.
  • Related