到目前为止,我一直在Prolog程序中采取坚定性来表示:
如果对于查询
Q
,有一个子项S
,那么有一个词T
可使?- S=T, Q.
成功虽然?- Q, S=T.
失败,但Q
调用的其中一个谓词不坚定。
直观地说,我因此坚定地表示我们不能使用实例化来“欺骗”谓词来提供解决方案,否则这些解决方案不仅没有给出,而是被拒绝。注意非终止程序的区别!
特别是,至少在我看来,logical-purity始终暗示坚定不移。
示例即可。为了更好地理解坚定性的概念,考虑这个属性的几乎经典的反例,在将高级学生引入Prolog的操作方面时经常被引用,使用错误定义两个整数之间的关系及其最大值:
integer_integer_maximum(X, Y, Y) :- Y >= X, !. integer_integer_maximum(X, _, X).
这是一个明显的错误 - 我们应该说“摇摆” - 当然,定义是以下查询错误成功:
?- M = 0, integer_integer_maximum(0, 1, M). M = 0. % wrong!
而交换目标产生了正确的答案:
?- integer_integer_maximum(0, 1, M), M = 0. false.
这个问题的一个好的解决方案是依靠纯方法来描述关系,例如:
integer_integer_maximum(X, Y, M) :- M #= max(X, Y).
这在两种情况下都能正常工作,甚至可以在更多情况下使用:
?- integer_integer_maximum(0, 1, M), M = 0. false. ?- M = 0, integer_integer_maximum(0, 1, M). false. | ?- X in 0..2, Y in 3..4, integer_integer_maximum(X, Y, M). X in 0..2, Y in 3..4, M in 3..4 ? ; no
现在由Covington等人撰写的论文Coding Guidelines for Prolog,由理论家O'Keefe的发明家共同撰写,包含以下部分:
5.1谓词必须坚定。
任何体面的谓词必须是“坚定的”,即如果其输出变量已经恰好被实例化为输出值,则必须正常工作(O'Keefe 1990)。
即,
?- foo(X), X = x.
和
?- foo(x).
必须在完全相同的条件下成功并具有相同的副作用。 不这样做只能用于其呼叫模式为的辅助谓词 受主要谓词的强烈约束。
因此,引用文章中给出的定义比我上面所说的更严格。
例如,考虑纯 Prolog程序:
nat(s(X)) :- nat(X). nat(0).
现在我们处于以下情况:
?- nat(0). true. ?- nat(X), X = 0. nontermination
这显然违反了在完全相同条件下成功的属性,因为其中一个查询根本不再成功。
因此我的问题是:我们应该将上述程序不称为坚定吗?请证明你的答案,并在现有文献中解释坚定性背后的意图及其定义,与logical-purity的关系以及相关的终止概念。< / p>
答案 0 :(得分:3)
在'prolog的工艺'第96页Richard O'Keef说'即使查询具有意外形式(通常为我们通常认为的输入值提供值),我们也会拒绝给出错误的答案。坚定不移'
*我不确定这是否应该是输出。即在您的查询中?- M = 0, integer_integer_maximum(0, 1, M). M = 0. % wrong!
M用作输入,但该子句已设计为输出。
在nat(X), X = 0.
中我们使用X作为输出变量而不是输入变量,但它没有给出错误的答案,因为它没有给出任何答案。所以我认为根据这个定义,它可以是坚定的。
他给出的经验法则是“推迟输出统一直到削减后”。在这里,我们没有削减,但我们仍然想推迟统一。
但是我认为将基本案例放在首位而不是递归案例是明智的,这样nat(X), X = 0.
最初会成功..但你仍然会遇到其他问题..