Prolog最佳实践:检查变量是否已绑定。

时间:2010-06-10 13:44:06

标签: prolog

我发布了this solution个问题,但ony给我留言:

  

预测检查“变量”是否为   自由或已经绑定应该改变   推导权利的策略   其他“变量”的统一   (即加速,或使其成为可能   得出它们)。动态相同   谓词 - 他们可以习惯   加快某些事情,但他们不应该   被用作改变的触发器   某事的行为。

我想知道为什么会这样。为什么检查是否已将某些内容定义为其他内容是不好的做法?你认为这是不好的做法吗?还有其他选择可以“更好地练习”。

这是我的解决方案:

% ================================
% Ensures that all variables are unique.  
% ================================

% Base case: Assigned variables unique values
used([], Nin, Nin).

% Have already assigned a value to this variable
used([A|B], Nin, Nout) :-
        integer(A), % <----------------- THIS IS THE LINE IN QUESTION
        helper(B,Nin,Nout).

% Have not assigned a value to this variable yet
% Assign it and remove it from the list.  
used( [A|B] , Nin, Nout) :-
        member(A,Nin),
        delete(Nin,A,Temp),
        helper(B,Temp,Nout).

1 个答案:

答案 0 :(得分:8)

integer/1atom/1等谓词的基本问题是不是单调的

以成功的?- integer(5).为例。但更一般目标?- integer(X).失败

对于声明性调试和自动生成的解释,我们希望如果目标成功,那么该目标的每次推广都不会失败。

“{正确”(即,如果你想要具有声明性意义的好单调谓词)要做的事情是integer/1在像{{1}这样的查询上引发实例化错误因为它目前没有足够的信息来回答这个问题。您应该使用?- integer(X).中的integer/1来获取此声音行为,而不是must_be/2

library(error)

?- must_be(integer, X). ERROR: Arguments are not sufficiently instantiated 表现单调,这通常是一个不错的属性。

扩展ony的评论:问题是(至少如果上面的样本结果是正确的)你的谓词不再是真正的关系,因为目标现在不是可交换的:must_be/2成功,但只是交换顺序目标不会产生相同的结果,因为?- X = 0, X = Y, addUnique([X,Y,3],3).失败。

这种现象是使用元逻辑谓词的常见后果。这些问题的声明性解决方案是约束,例如参见 ?- X = Y, addUnique([X,Y,3], 3), X = 0. 。它们是单调的,可交换的,通常更容易理解。