使用多个附加构建 Prolog (swipl) 知识库

Building Prolog (swipl) knowledge base using multiple appends

我是 Prolog 的新手,我正在尝试创建一个知识库,该知识库由通过多个附加的列表组成。可能吗? 如果从命令行我写:

append([a,b],[c,d],L0), append(L0,[e,f],L1).

输出为:

L0 = [a, b, c, d],
L1 = [a, b, c, d, e, f].

如果我在 .pl 文件中编写相同的代码,它会显示:

Full stop in clause-body? Cannot redefine ,/2

有没有办法告诉 Prolog 应用追加,然后使用 L1 作为知识库?

编辑: 我找到了一种方法:

list(L1) :- append([a,b],[c,d],L0), append(L0, [e,f], L1).

但这样一来,每次我调用 list(L) 时,它都会从头开始重新创建列表。 有没有更好的方法,或者这是要走的路?

你想要什么?没看懂。

你的谓词工作正常。

您的编辑回答了问题,这通常是解决问题的方法。

但是,如果您出于性能原因希望保存谓词的结果(即不必再次 运行 多个追加),您可以使用 asserta/1assertz/1 谓词。例如,假设您有一个主谓词 运行ning,并且您希望执行追加过程并将其保存在 saved_list/1 谓词中,您可以这样做:

main :- 
    append([a,b],[c,d],L0), 
    append(L0,[e,f],L1), 
    asserta(saved_list(L1)).

(如果您想尝试一下,可以在命令行上尝试)

现在,如果您稍后 运行 saved_list(X),X 将与 [a, b, c, d, e, f] 统一,而无需 运行 追加。如果 saved_list/1 已经在代码中的某处定义,则必须声明它 as dynamic

但是,警告:通常不鼓励使用各种 assert 和 retract 谓词,因为它们是副作用。如果使用不当,它们会使代码更难理解和推理,并可能导致细微的错误。

此外,动态谓词通常不如硬编码的快(即,将谓词硬编码为 saved_list([a,b,c,d,e,f]). 比动态断言调用它更快)。使用它来缓存值,这样你就不必一遍又一遍地计算它们(即本质上使用记忆)通常是可以的,但如果可能的话仍然应该避免。

除非您附加的列表庞大,否则我建议您使用您提供的解决方案。使用断言是一个不必要的笨蛋,除非做追加需要很长时间。