我正在努力学习Prolog,似乎知识的完整性非常重要,因为很明显,如果知识库没有事实,或者事实不正确,它将影响查询结果。我想知道如何最好地处理事实的未知细节。例如,
%life(<name>,<birth year>,<death year>)
%ruler(<name>,<precededBy>,<succeededBy>)
我加入知识库的一些人仍然活着,因此他们的死亡年份不得而知。在统治者的例子中,第一个统治者没有前任,而且当前的统治者没有后继者。如果存在这些未知数,我应该放置某种未知的标志值,还是可以省略细节。在统治者的情况下,不知道前任会是这样的事实吗?
ruler(great_ruler,,second_ruler).
答案 0 :(得分:1)
嗯,你有几个选择。
在这种特殊情况下,我会质疑你的设计。您可以放下一个并使用规则查找前一个,而不是将前一个和下一个放在标尺上:
ruler(great_ruler, second_ruler).
ruler(second_ruler, third_ruler).
previous(Ruler, Previous) :- ruler(Previous, Ruler).
这个谓词对于great_ruler
来说根本就失败了,这可能是合适的 - 毕竟在他们面前没有人。
在其他情况下,它可能不是直截了当的。因此,您必须决定是否要为未知值创建显式值或使用变量。基本上,你想这样做:
ruler(great_ruler, unknown, second_ruler).
或者你想这样做:
ruler(great_ruler, _, second_ruler).
在第一种情况下,除非您编写一些自定义逻辑来捕捉它,否则您可能会得到以unknown
为特色的虚假答案。但我实际上认为第二种情况更糟,因为空变量将与任何东西统一,因此大量查询会产生奇怪的结果:
ruler(_, SucceededHimself, SucceededHimself)
例如,会成功统一SucceededHimself = second_ruler
,这可能不是你想要的。您可以使用var/1
和ground/1
检查变量,但此时您将篡改Prolog的搜索,并且会变得更加复杂。因此,空白变量与SQL中的NULL
并不像您希望的那样。
总结: