Prolog inserts, modifies and deletes facts in a separate text database file

I have a prolog database file with a lot of facts knowledge.pl . For instance:

 father_of(joe,paul). father_of(joe,mary). mother_of(jane,paul). mother_of(jane,mary). male(paul). male(joe). female(mary). female(jane). % and so on. 

This file is advised (consult / 1) every time my program runs again.

I would like to be able to insert, modify and delete the facts that I want (some of them directly, some others that meet certain conditions) by writing or deleting directly in this text database file.

something like assertz, retract and retractall, but modifying this text file so that the changes stay on it all the time.

How can i do this?

+4
source share
2 answers

you can either create the necessary facts, or write them to the same file, or modify the database, and then save it in a file.

the difference is that in the first approach you will have db of the old downloaded file, while the second approach will change it at runtime.

From the way you formulated the question, I assume that you want to make the second; for this you need:

1) declare all the predicates you want to change as dynamic 2) state, retract, etc. At run time 3) write the new database to a file. you can use listing / 1

To write, you can do something like:

 tell(knowledge), ..... told. 

or you can use some other io predicates . perhaps using set_prolog_IO / 3 would be the easiest way.

Now, if you want to be the first, you should build predicates (possibly using a univ operator ) or other string manipulation predicates, and then write them to a file

EDIT:

There is a listing of / 0, but it will list all the loaded predicates (something you might not want). after some searching, I found source_file / 2 ; so you can do something like

 findall(X,source_file(X,FileName),L). 

note that the source_file / 2 file requires an absolute file name. you can use absolute_file_name / 2 to get it the way source_file / 2 formats the predicate, a little strange (I expected something like foo / 1), but it looks like you can pass it to the / 1 list, and it works fine so you can do something like:

 save(FileName):- absolute_file_name(FileName,Abs), findall(X,source_file(X,Abs),L), tell(FileName), maplist(listing,L), told. 

on the other hand, you can always have a list with predicates that you want to save somewhere in the file

+3
source

If you use SWI-Prolog, there are several options:

Finding short runs I ran into persistency : a module that might be useful at first glance.

Then there is a library for external tables , that is, it is stored in files and indexed. You should use this if you have data that cannot fit into memory, or if loading / saving the entire data set takes too much time.

Otherwise, the answer from thanosQR offers an “old-fashioned” way of handling perseverance.

+3
source

Source: https://habr.com/ru/post/1415654/


All Articles