本文介绍了Prolog 最佳实践:检查变量是否已绑定.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发布了 这个解决方案 一个问题,但ony给我留下了一条评论说:

I posted this solution to an question but ony left me a comment saying:

检查变量"是否为谓词免费或已经绑定应该改变获取权利的策略其他变量"的统一(即加速,或使导出它们).动态也一样谓词 - 它们可用于加速某些事情,但他们不应该用作改变的触发器某事的行为.

我想知道这是为什么.为什么检查某些东西是否已经定义为其他东西是不好的做法?你认为这是不好的做法吗?是否有其他选择可以是更好的做法".

I am wondering why this is. Why is it bad practice to check if something is already defined to something else? Do you think it is bad practice? Are there other options that would be 'better practice'.

这是我的解决方案:

% ================================
% 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 等谓词的根本问题在于它们是不是单调的.

The fundamental problem of predicates like integer/1, atom/1 etc. is that they are not monotonic.

?- integer(5).为例,它成功了.但是一个更一般的目标,?- integer(X).失败

Take for example ?- integer(5)., which succeeds. But a more general goal, ?- integer(X)., fails!

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

For declarative debugging and automatically generated explanations, we expect that if a goal succeeds, every generalization of that goal must not fail.

正确"(即,如果您想要具有声明意义的漂亮单调谓词)要做的事情是 integer/1 引发 实例化错误在像 ?- integer(X). 这样的查询上,因为它目前没有足够的信息来回答问题.您应该使用 library(error) 中的 must_be/2 而不是 integer/1 来获得这种声音行为:

The "proper" (i.e., if you want nice monotonic predicates that make declarative sense) thing to do would be for integer/1 to raise an instantiation error on queries like ?- integer(X). on the grounds that it does not have enough information to answer the question at this time. Instead of integer/1, you should use must_be/2 from library(error) to obtain this sound behaviour:

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

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

must_be/2 behaves monotonically, which is in general a nice property.

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

Extending ony's comment: The problem is that (at least if the sample results above are correct) your predicate is no longer a true relation because goals are now not commutative: ?- X = 0, X = Y, addUnique([X,Y,3],3). succeeds, but simply exchanging the order of goals does not yield the same result because ?- X = Y, addUnique([X,Y,3], 3), X = 0. fails.

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

Such phenomena are common consequence of using meta-logical predicates. The declarative solution to such problems are constraints, see for example dif/2. They are monotonic, commutative and generally much easier to understand.

这篇关于Prolog 最佳实践:检查变量是否已绑定.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 17:52