I'm sorry, this has probably been asked before but I can't find a good answer.
I'm writing a Prolog assignment, in which we must write a database with insert, delete, etc. I'm currently stuck on the insert part. I'm trying to use tell, listing and told for this, but the results are often unpredictable, deleting random parts of the file. Here's the full code of my database,
:- dynamic progenitor/2. progenitor(maria,joao). progenitor(jose,joao). progenitor(maria,ana). progenitor(jose,ana). insere(X,Y) :- dynamic progenitor/2, assert(progenitor(X,Y)). tell('banco.pl'), listing(progenitor), told.
I then run the following on SWI-Prolog:
And get the following result on
:- dynamic progenitor/2. progenitor(maria, joao). progenitor(jose, joao). progenitor(maria, ana). progenitor(jose, ana).
Note that the clause I tried to insert isn't even in the file, and the lines defining commit and insere are missing.
How would I do this correctly?Answer1:
tell starts writing to the beginning of the file. so you're overwriting everything else that was in the file. you have these options:
progenitor predicate (and just that) in another file.
append/1 to write to the end of the file with
portray_clause. this only helps for
insert, but you stated that you want
read the other clauses into a list and reprint them, then use
(text for formatting)
read_all_other_clauses(All_Other_Clauses):- see('yourfilename.pl'), read_all_other_clauses_(All_Other_Clauses,), seen. read_all_other_clauses_(Other,Acc0):- (read(Clause) -> (Clause = progenitor(_,_) -> % omit those clauses, because they'll be printed with listing/1 read_all_other_clauses_(Other,Acc0); read_all_other_clauses_(Other,[Clause|Acc0])); Other = Acc0). % read failed, we're done operation(Insert, X,Y):- (call,(Insert) -> assert(progenitor(X,y)); retract(progenitor(X,y))), read_all_other_clauses(Others), tell('yourfilename.pl'), % After the reading! maplist(portray_clause,Others), %Maplist is a SWI built-in, easy to rewrite, if you don't have it. listing(progenitor/2), told. insert(X,Y):- operation(true,X,Y). delete(X,Y):- operation(fail,X,Y).
Note that you could use the
read_all_other_clauses for your
delete only, if you change the line with the omit comment. Then you could use the solution proposed in #2 for your