I'm trying to retract and assert a fact in another file. One (fruit1.pl) contains a couple of facts, and another (fruit.pl) contains a predicate start
which designates which fact that another predicate insert_fruit
will update:
fruit1.pl
fruit(apple, [[2, yellow], [1, brown]]).
fruit(orange, [[3, orange], [2, orange]]).
fruit.pl
:- dynamic fruit/2.
start :-
consult('fruit1.pl'),
File = 'fruit1.pl',
Name = apple,
Price = 2,
Color = red,
insert_fruit(File, Name, Price, Color).
insert_fruit(File, Name, Price, Color) :-
open(File, update, Stream),
retract(fruit(Name, Information)),
assert(fruit(Name, [[Price, Color]|Information])),
close(Stream).
However insert_fruit
is not working as intended, as I believe it needs to include Stream to modify the other file, although I have no idea how (retract(Stream, ...)
doesn't work). Is there some I would be able to get the retract and assert predicates to function in the other file?
In SWI-Prolog you can assert/retract facts from a file that is used as a persistent fact store by using library persistency
:
fruit/3
as persistent. Optionally: you annotate the arguments with a type for automatic type checking.fruit
module (in this case fruit1.pl
).add_fruit/3
) and querying (i.e., current_fruit/3
) fruity facts. Retraction is handled similarly.with_mutex/2
(especially useful when you start retracting facts as well).:- module(
fruit,
[
add_fruit/3, % +Name:atom, +Price:float, +Color:atom
current_fruit/3 % ?Name:atom, ?Price:float, ?Color:atom
]
).
:- use_module(library(persistency)).
:- persistent(fruit(name:atom, price:float, color:atom)).
:- initialization(db_attach('fruit1.pl', [])).
add_fruit(Name, Price, Color):-
with_mutex(fruit_db, assert_fruit(Name, Price, Color)).
current_fruit(Name, Price, Color):-
with_mutex(fruit_db, fruit(Name, Price, Color)).
Start Prolog, load fruit.pl
, execute:
?- add_fruit(apple, 1.10, red).
Close Prolog, start Prolog (again), execute:
?- current_fruit(X, Y, Z).
X = apple,
Y = 1.1,
Z = red
You are now reading facts from fruit1.pl
!
As mentioned before, the library also performs type checking for you, e.g.:
?- add_fruit(pear, expensive, green).
ERROR: Type error: `float' expected, found `expensive' (an atom)