知识库中的序言未知数

Prolog unknowns in the knowledge base

我正在学习Prolog,看来知识的完整性很重要,因为显然如果知识库没有事实,或者事实不正确,都会影响查询结果。我想知道如何最好地处理一个事实的未知细节。例如,

%life(<name>,<birth year>,<death year>)
%ruler(<name>,<precededBy>,<succeededBy>)

我添加到知识库中的一些人可能还活着,因此他们的死亡年份未知。在统治者的例子中,第一任统治者没有前任,现任统治者也没有继任者。如果存在这些未知数,我应该放置某种未知标志值还是可以忽略细节。统治者的话,不知道前任会是这样吗?

ruler(great_ruler,,second_ruler).

嗯,你有几个选择。

在这种特殊情况下,我会质疑你的设计。与其将上一个和下一个都放在标尺上,不如将下一个放在标尺上并使用规则查找上一个:

ruler(great_ruler, second_ruler).
ruler(second_ruler, third_ruler).

previous(Ruler, Previous) :- ruler(Previous, Ruler).

对于 great_ruler,这个谓词将简单地失败,这可能是合适的——毕竟在他们之前没有人。

在其他情况下,它可能并不简单。因此,您必须决定是要为 unknown 指定一个显式值还是使用一个变量。基本上,你想这样做吗:

ruler(great_ruler, unknown, second_ruler).

或者你想这样做:

ruler(great_ruler, _, second_ruler).

在第一种情况下,您可能会得到包含 unknown 的虚假答案,除非您编写一些自定义逻辑来捕捉它。但我实际上认为第二种情况更糟,因为那个空变量会与任何东西统一,所以很多查询会产生奇怪的结果:

ruler(_, SucceededHimself, SucceededHimself)

会成功,例如,统一 SucceededHimself = second_ruler,这可能不是您想要的。您可以使用 var/1ground/1 检查变量,但此时您正在篡改 Prolog 的搜索并且它会变得更加复杂。因此,空白变量并不像您希望的 SQL 中的 NULL 那样。

总结:

  • 更喜欢不会导致此问题的表述
  • 如果强制,使用特殊值