Prolog 真的基于封闭世界假设吗?

Is Prolog really based on the closed-world assumption?

closed-world assumption,

what is not currently known to be true, is false

Prolog 的语义通常被认为遵循封闭世界假设,例如,here:

Prolog is based on closed world assumption (CWA) -- that is, if a proposition is not in the fact database and not derivable from the fact database, then it is not true.

但是,它的行为并不完全如此。在 CWA 下,我希望

?- a.
false.

但是,在 SWI-Prolog 中,我得到:

?- a.
ERROR: Undefined procedure: a/0 (DWIM could not correct goal)

这是为什么?说Prolog基于CWA是不是错了?

您的查询必须使用语言本身,因为 a 是命题 a/0 必须使用语言,即定义为谓词。语言中的所有无效谓词都是命题。如果不先将新术语添加到语言中,则不能将其作为谓词进行查询。

对于 a/1,当您将它定义为 a(b). 它在语言中时,查询 a(X), dif(X,b) 将失败,因为 prolog 系统不知道任何其他满足条件的术语它并假设没有其他世界。

在 Prolog 上下文中讨论封闭世界假设 (CWA) 时,必须区分 unknown 谓词与 known[=49] 谓词=] 到(运行时)系统。在这两种情况下,谓词都有或没有子句。

默认情况下,调用 unknown 谓词会引发谓词存在错误。有一个标准标志,unknown (https://www.swi-prolog.org/pldoc/man?section=flags#flag:unknown),其默认值为 error,可以设置为 fail(或 warning)。这将为您提供您显然正在寻找的行为。不过,我强烈建议您将标志设置为默认值 error,因为它可以更容易地检测编程错误(例如谓词名称或元数中的拼写错误)。

什么使谓词 为运行时所知?谓词指令或谓词子句。最熟悉的例子是 dynamic/1 指令。如果您的代码仅包含以下文本:

:- dynamic(foo/1).

那么,编译加载后,可以得到:

?- foo(_).
no.

但其他指令具有相同的效果(例如 multifile/1discontiguous/1,假设这是符合标准的 Prolog 实现!)。

因此,对于 known 谓词,CWA 在 Prolog 中的解释很简单:我们无法证明为真的东西就是假的。 IE。 失败否定,与逻辑否定相同。 Prolog 这个名字来自 programming in logic 但 Prolog 也旨在成为一种实用的编程语言。

Prolog 中缺少的内容(由 Logtalk) is being able to declare a predicate without being forced to declare it as dynamic, or multifile, or ... or requiring providing clauses for it (see e.g. this example 等提供)。这提供了更简单和更清晰的 CWA 语义:调用没有子句的已声明谓词失败(不需要弄乱有问题的 unknown 标志);调用未声明的谓词会引发谓词存在错误。

希望这对您有所帮助。搜索 negation as failure 应该会提供进一步的说明。