TTaJTa4
TTaJTa4

Reputation: 840

Converting database to facts in Prolog

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

Answers (2)

damianodamiano
damianodamiano

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

lurker
lurker

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

Related Questions