将数据库转换为Prolog中的事实

时间:2019-01-24 15:46:00

标签: prolog

所以我有一个看起来像这样的数据库:

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])
]

我想将DB保存为事实。然后,我们应该创建一个关系db_to_facts来查找所有事实。

示例:

data([true, false]).
data([dog,cat]).

输出:

db_to_facts(DB).
DB = [data([true, false]), data([dog, cat])].

最干净的方法是什么?

编辑:

我想我明白了

db_to_facts(L) :- findall(data(X),data(X),L).

但是,如果数据库为空,它将失败。如何使其返回空列表?

2 个答案:

答案 0 :(得分:0)

在Prolog程序的开头,使用伪指令dynamic(data/1).。这告诉Prolog您有一个动态数据库,该数据库可以随时间变化,即使没有数据,该数据库仍然可以识别data(X)查询。

没有指令:

1 ?- data(X).
ERROR: Undefined procedure: data/1 (DWIM could not correct goal)
2 ?-

使用指令:

2 ?- dynamic(data/1).
true.

3 ?- data(X).
false.

然后如果没有数据,您的findall/3呼叫将产生[]

答案 1 :(得分:0)

可以肯定,使用dynamic(data/1)是最好的方法。只是让您知道,还有另一种检查data/1是否存在的方法。您可以通过以下方式使用current_predicate/2

db_to_facts(L):-
    ( current_predicate(data,_) -> findall(data(X),data(X),L) ; L = []).

如果您对其进行编译(无法在线使用swish,它会给No permission to call sandboxed ...),则会出现警告,提示您应定义data/1,但如果仍然运行查询,则会得到一个空列表:< / p>

?- db_to_facts(L).
L = [].

这不是最干净的方法,但是它可以工作:)