所以我有一个看起来像这样的数据库:
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).
但是,如果数据库为空,它将失败。如何使其返回空列表?
答案 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 = [].
这不是最干净的方法,但是它可以工作:)