简体   繁体   English

哪些运算符和谓词可以与 clp(fd) 一起使用?

[英]Which operators and predicates can be used with clp(fd)?

Firstly, the clp(fd) documentation mentions:首先, clp(fd) 文档提到:

In modern Prolog systems, arithmetic constraints subsume and supersede low-level predicates over integers .在现代 Prolog 系统中,算术约束包含并取代整数上的低级谓词 The main advantage of arithmetic constraints is that they are true relations and can be used in all directions.算术约束的主要优点是它们是真实的关系并且可以在所有方向上使用。 For most programs, arithmetic constraints are the only predicates you will ever need from this library.对于大多数程序,算术约束是您唯一需要从这个库中获得的谓词。

Secondly, on a previously asked question , it was mentioned thatinclude/3 is incompatible with clp(fd).其次,在先前提出的问题中,提到include/3与 clp(fd) 不兼容。

Does that mean that only clp(fd) operators and clp(fd) predicates can be used when writing prolog with the clp(fd) library?这是否意味着在使用 clp(fd) 库编写 prolog 时只能使用clp(fd) 运算符clp(fd) 谓词

Furthermore, for example, why is include/3 incompatible with clp(fd)?此外,例如,为什么include/3与 clp(fd) 不兼容? Is it because it does not use clp(fd) operators ?是因为它不使用 clp(fd) 运算符吗? To use include/3 in clp(fd) code, would one need to rewrite a version that uses clp(fd) operators and constraints?要在 clp(fd) 代码中使用include/3 ,是否需要重写一个使用 clp(fd) 运算符和约束的版本?

include/3 doesn't have to be incompatible with clpfd (or any other use of attributed variables ) - depends on the safe (for the purposes of the program, rather than necessarily "logically pure") usage of the attributed variables . include/3不必与 clpfd(或属性变量的任何其他使用)不兼容 - 取决于属性变量安全使用(出于程序的目的,而不一定是“逻辑上纯”)。 Eg:例如:

:- use_module(library(clpfd)).

test_include(F) :-
    L = [N1, N2, N3, N4],
    N1 #< 2,
    N2 #> 5,
    N3 #< 3,
    N4 #> 8,
    include(gt_3_fd, L, F).

gt_3_fd(I) :-
    I #> 3.

Result in swi-prolog: swi-prolog 中的结果:

?- test_include(F).
F = [_A, _B],
_A in 6..sup,
_B in 9..sup.

The above code is safe, because the variables being used with clpfd are being used consistently with clpfd, and the specified constraints result in reification of gt_3_fd being unnecessary.上面的代码是安全的,因为与 clpfd 一起使用的变量与 clpfd一致地使用,并且指定的约束导致gt_3_fd的具体gt_3_fd是不必要的。

Once the variables are nonvar/ground depending on the use-case (clpfd deals with integers, rather than eg compound terms, so nonvar is good enough), then the variables can also be used outside of clpfd.一旦根据用例变量是 nonvar/ground(clpfd 处理整数,而不是复合项,因此 nonvar 就足够了),那么变量也可以在 clpfd 之外使用。 Example:例子:

?- I = 5,  I > 4, I @> 4, I #> 4.
I = 5.

An operator such as > uses the actual value of the variable, and ignores any attributes which might have been added to the variable by eg clpfd. >运算符使用变量的实际值,并忽略可能已由 clpfd 添加到变量的任何属性。

Logical purity , eg adding constraints to the elements in list L after the include/3 rather than before, is a separate issue, and applies to non-attributed variables also. 逻辑纯度,例如在include/3之后而不是之前向列表L中的元素添加约束是一个单独的问题,并且也适用于非属性变量。

In summary: A program may be using some integers with clpfd, and some integers outside of clpfd, ie a mixture.总结:一个程序可能在 clpfd 中使用一些整数,在 clpfd 之外使用一些整数,即混合。 That is OK, as long as the inside-or-outside distinction is consistently applied, while it is relevant (because eg labeling will produce actual values).这没关系,只要始终如一地应用内部或外部区别,同时它是相关的(因为例如标签将产生实际值)。

why is include/3 incompatible with clp(fd)?为什么include/3与 clp(fd) 不兼容?

?- X = 1, include(#\=(1),[0,X,2],Xs), X = 1.
   X = 1,
   Xs = [0,2].     % looks good
?-        include(#\=(1),[0,X,2],Xs), X = 1.
   false, unexpected.
?-        include(#\=(1),[0,X,2],Xs).   % generalization
   Xs = [0,X,2],
   X in inf..0\/2..sup. % missing second answer

So, (#\=)/2 works in this case only if it is sufficiently instantiated .因此, (#\=)/2只有在充分实例化的情况下才适用于这种情况。 How can you be sure it is?你怎么能确定它是? Well, there is no direct safe test.好吧,没有直接的安全测试。 And thus you will get incorrect results in certain cases.因此在某些情况下你会得到不正确的结果。 As long as these examples fit on a single line, it is rather easy to spot the error.只要这些示例适合一行,就很容易发现错误。 But with a larger program, this is practically impossible.但是对于更大的程序,这实际上是不可能的。 Because of this, constraints and include/3 are incompatible.因此,constraints 和include/3是不兼容的。

A way out would be to produce instantiation errors in cases with insufficient instantiation, but this is pretty hairy in the context of clpfd .一种解决方法是在实例化不充分的情况下产生实例化错误,但这在clpfd的上下文中非常棘手。 Other built-in predicates like (=\=)/2 do this, and are limited in their applicability.其他内置谓词如(=\=)/2执行此操作,但它们的适用性有限。

?- X = 1, include(=\=(1),[0,X,2],Xs), X = 1.
   X = 1,
   Xs = [0,2].
?-        include(=\=(1),[0,X,2],Xs), X = 1.
   instantiation_error.    % much better than an incorrect answer

A safe variant of include/3 is tfilter/3 of library(reif) . include/3的一个安全变体是library(reif)tfilter/3 But before using it, I recommend you read this .但在使用它之前,我建议您阅读这篇文章。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM