Prolog最佳实践: checking if a variable is already bound.

标签 prolog

我发布了this solution一个问题但是ony给我留言说:

Predicates to check if "variable" is free or already bound should change strategy for deriving right unifications for other "variables" (i.e. speed up, or make possible to derive them). The same for dynamic predicates - they can be used to speed-up something, but they shouldn't be used as trigger of changing behaviour of something.

我想知道这是为什么。为什么检查某些内容是否已经定义为其他内容是不好的做法?您认为这是不好的做法吗?是否有其他选择是“更好的做法”。

这是我的解决方案:

% ================================
% 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).

最佳答案

integer/1atom/1等谓词的根本问题是它们不是单调的

?-integer(5).为例,成功。但是更笼统的目标,?-整数(X)。失败!

对于声明式调试和自动生成的解释,我们期望如果目标成功,则该目标的每个泛化都不能失败。

“正确的”(即,如果您想要具有声明意义的漂亮单调谓词)要做的事情是让 integer/1 引发实例化错误诸如 ?-integer(X). 之类的查询,因为目前没有足够的信息来回答该问题。您应该使用 library(error) 中的 must_be/2 来代替 integer/1 来获取此声音行为:

?- must_be(integer, X).
ERROR: Arguments are not sufficiently instantiated

must_be/2 表现单调,这通常是一个很好的属性。

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

此类现象是使用元逻辑谓词的常见结果。此类问题的声明式解决方案是约束,例如dif/2。它们是单调的、可交换的并且通常更容易理解。

关于Prolog最佳实践: checking if a variable is already bound.,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3014933/

相关文章:

machine-learning - prolog作为智能语言是如何工作的?

prolog - "open-ended lists"和 "difference lists"的区别

javascript - Tau Prolog 的行为与沙箱不同

prolog - 检查 List 中是否有任何元素以特定字符开头

prolog - 图中从 X 到 Y 的两条不同路径

prolog - 从 (swi) prolog 中的文件读取整数的谓词

lambda - 在 Prolog 查询中隐藏变量

prolog - 为什么 SWI-Prolog 将带引号和不带引号的字符串(不带空格)统一为同一规则?

Prolog - 数组数组,返回数组长度大于一的条目

string - Prolog DCG 从字母数字字符构建/识别字符串