【问题标题】:Converting database to facts in Prolog在 Prolog 中将数据库转换为事实
【发布时间】:2019-01-24 15:45:59
【问题描述】:

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

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

但是如果数据库是空的,它就会失败。如何让它返回空列表?

【问题讨论】:

    标签: prolog


    【解决方案1】:

    在 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 调用将产生[]

    【讨论】:

      【解决方案2】:

      当然,使用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,但是如果你仍然运行查询,你会得到一个空列表:

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

      这不是最干净的方式,但它有效:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多