在封闭世界假设下,
目前不知道是真的,是假的
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 是错误的吗?
在 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/1和discontiguous/1,假设这是符合 Prolog 实现的标准!)。
因此,对于已知谓词,Prolog 中 CWA 的解释很简单:我们无法证明为真的就是假的。即否定的故障,这是不一样的逻辑否定。Prolog 这个名字来自于逻辑编程,但 Prolog 也旨在成为一种务实和实用的编程语言。
Prolog 所缺少的(例如由Logtalk提供)能够声明谓词,而无需被迫将其声明为动态的、多文件的,或...或需要为其提供子句(参见例如此示例)。这提供了更简单、更清晰的 CWA 语义:调用没有子句的声明谓词失败(不需要弄乱有问题的unknown标志);调用未声明的谓词会引发谓词存在错误。
希望这可以帮助。搜索否定作为失败应该提供进一步的澄清。