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

Max*_*axB 2 prolog

封闭世界假设下

目前不知道是真的,是假的

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

Prolog 基于封闭世界假设 (CWA)——也就是说,如果一个命题不在事实数据库中并且不能从事实数据库中推导出来,那么它就不是真的。

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

?- a.
false.
Run Code Online (Sandbox Code Playgroud)

但相反,在 SWI-Prolog 中,我得到:

?- a.
ERROR: Undefined procedure: a/0 (DWIM could not correct goal)
Run Code Online (Sandbox Code Playgroud)

这是为什么?说 Prolog 基于 CWA 是错误的吗?

Pau*_*ura 5

在 Prolog 的上下文中谈论封闭世界假设 (CWA) 时,必须区分未知谓词与(运行时)系统的已知谓词。在这两种情况下,谓词都带有或不带有子句。

默认情况下,调用未知谓词会引发谓词存在错误。有一个标准标志 ,unknown其默认值为error,可以设置为fail。这会给你你显然正在寻找的行为。Sill,我强烈建议您将该标志设置为其默认值error,因为它可以更轻松地检测编程谓词(例如谓词名称或参数中的拼写错误)。

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

:- dynamic(foo/1).
Run Code Online (Sandbox Code Playgroud)

然后,在编译和加载之后,您可以预期:

?- foo(_).
no.
Run Code Online (Sandbox Code Playgroud)

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

因此,对于已知谓词,Prolog 中 CWA 的解释很简单:我们无法证明为真的就是假的。即否定的故障,这是一样的逻辑否定。Prolog 这个名字来自于逻辑编程,但 Prolog 也旨在成为一种务实和实用的编程语言。

Prolog 所缺少的(例如由Logtalk提供)能够声明谓词,而无需被迫将其声明为动态的、多文件的,或...或需要为其提供子句(参见例如此示例)。这提供了更简单、更清晰的 CWA 语义:调用没有子句的声明谓词失败(不需要弄乱有问题的unknown标志);调用未声明的谓词会引发谓词存在错误。

希望这可以帮助。搜索否定作为失败应该提供进一步的澄清。