Reputation: 840
So I have database which looks something like:
DB = [
data([table, keyboard,cup, box,watch]),
data([green,red, yellow,white,blue]),
data([alex, john,sasha, sabrina, ben]),
data([coffee, tea, syrup, vodka, beer]),
data([bookA, bookB, bookC, bookD, bookE])
]
I would like to save DB
as a fact. Then we should create a relation db_to_facts
which finds all the facts.
Example:
data([true, false]).
data([dog,cat]).
Output:
db_to_facts(DB).
DB = [data([true, false]), data([dog, cat])].
What would be the cleanest way possible to achieve it?
Edit:
I think I got it:
db_to_facts(L) :- findall(data(X),data(X),L).
But if the database is empty, it will fail. How to make it return empty list?
Upvotes: 3
Views: 316
Reputation: 2662
For sure, the usage of dynamic(data/1)
is the best way. Just to let you know, there is another way to check if data/1
exists. You can use current_predicate/2
in this way:
db_to_facts(L):-
( current_predicate(data,_) -> findall(data(X),data(X),L) ; L = []).
If you compile it (you cannot use swish online, it gives No permission to call sandboxed ...
) you get a warning saying that you should define data/1
but if you run the query anyway you get the empty list:
?- db_to_facts(L).
L = [].
It's not the cleanest way but it works :)
Upvotes: 0
Reputation: 58224
In the beginning of your Prolog program, use the directive, dynamic(data/1).
. This tells Prolog you have a dynamic database that can change over time and will still recognize the data(X)
query even if there is no data.
Without the directive:
1 ?- data(X).
ERROR: Undefined procedure: data/1 (DWIM could not correct goal)
2 ?-
With the directive:
2 ?- dynamic(data/1).
true.
3 ?- data(X).
false.
And then your findall/3
call will yield []
if there is no data.
Upvotes: 1