假设我有知识库
likes(john,mary).
person(mary).
person(john).
如果我们问prolog是否
|?- likes(mary,john)
它会回答没有,因为我们没有断言。有没有办法让prolog回答未知,除非我们明确说明。
\+ likes(mary,john)
换句话说,我们可以要求prolog将未绑定的表达式视为可能而不是假。我一直在使用IDP系统,该系统允许存在量化并将非断言关系视为未绑定而非虚假,但我想使用更主流的东西。 http://adams.cs.kuleuven.be/idp/server.html
例如,在IDP中,您可以发表声明
vocabulary V{
type Person
Likes(Person,Person)
}
theory T: V{
//Everyone might like someone and disallow narcisiscm
!x : ?y: Likes(x,y) & ~Likes(x,x).
}
//some instance without special meaning
structure S:V{
Person={A..C}
}
procedure main(){
//Print all possible solutions
printmodels(allmodels(T,S))
}
哪个收益
Number of models: 27
Model 1
=======
structure : V {
Person = { "A"; "B"; "C" }
Likes = { "A","B"; "A","C"; "B","A"; "B","C"; "C","A"; "C","B" }
}
//...
答案 0 :(得分:2)
如上所述,Prolog正在使用封闭世界的假设,即询问事实是否为真意味着我们问我们是否知道它是真的 - no
意味着我们不知道它是否属实,不是这是假的。当然,作为一种图灵完备语言,你可以模拟一个开放的世界 - 比如:
like(true, mary, john).
like(false, mary, nick).
like(unknown, X, Y).
可能最好有一些额外的包装来处理边缘情况(例如,对一对都有true和false),并且可能使用一些高阶谓词技巧来避免编写大量样板 - 但实现的核心是你明确地声明什么是假的,什么是真的,其余的是未知的。
答案 1 :(得分:1)
到目前为止所说的内容非常正确:Prolog在所谓的封闭世界假设(CWA)下运作。不过,除了已经发布的内容之外,我还想提供一个补充的视角。
首先,Prolog程序甚至可能终止,因此我们可能永远不会 您提及的可能答案。
但即使程序 终止,我们仍然获得的答案既不等同于true
也不到{ {1}}。
例如,使用GNU Prolog:
| ?- X #\= 3. X = _#2(0..2:4..127@)
在这里,答案是一个待定的约束,这个目标被称为 flounder ,因为它的真相并未明确决定。
此类答案可能会或可能不会描述解决方案。
例如:
| ?- fd_all_different([X,Y,Z]), fd_domain([X,Y,Z], 0, 1). X = _#2(0..1) Y = _#20(0..1) Z = _#50(0..1) yes
在这种情况下,不存在解决方案!要看到这一点,我们需要明确搜索:
| ?- fd_all_different([X,Y,Z]), fd_domain([X,Y,Z], 0, 1), fd_labeling([X,Y,Z]). no
因此,在上面的示例中,使用false
而不是maybe
回答可能更合适。
此外,我们从基本逻辑定理中知道,当推理整数时,这些问题是不可避免的。
从这个意义上讲,Prolog系统可以真正给出答案,其真实不仅不是,而且不能确定。