Prolog SWI序言和约束,库CLP(FD)

Prolog SWI序言和约束,库CLP(FD),prolog,constraints,clpfd,clpq,Prolog,Constraints,Clpfd,Clpq,我正在使用clpfd库处理(swi)prolog中的约束 我试图确定一组约束何时封装或包含另一组约束,例如,X对整数的一般算术约束的包含通常是不可判定的,因此所有正确的解算器都有固有的限制,超过这些限制,他们必须延迟其解算,直到知道更多。如果您知道您的域是有限的,您可以发布域,然后使用约束解算器的labeling/2谓词,尝试查找可能使蕴涵无效的反例。还考虑Q上的线性不等式是可判定的,并且SWIPROlog的库(CLPQ)是为它们完成的。因此,您可以在CLP(Q)中尝试以下约束: ?-使用_模块

我正在使用clpfd库处理(swi)prolog中的约束


我试图确定一组约束何时封装或包含另一组约束,例如,X对整数的一般算术约束的包含通常是不可判定的,因此所有正确的解算器都有固有的限制,超过这些限制,他们必须延迟其解算,直到知道更多。如果您知道您的域是有限的,您可以发布域,然后使用约束解算器的labeling/2谓词,尝试查找可能使蕴涵无效的反例。还考虑Q上的线性不等式是可判定的,并且SWIPROlog的库(CLPQ)是为它们完成的。因此,您可以在CLP(Q)中尝试以下约束:

?-使用_模块(库(clpq))。
对。
?-{X<4,X>=7}。
错。

请注意,在Q中不存在这样的反例(因此在Z中也不存在),因此其含义成立。

似乎您正在处理CLP(FD)。这些解算器区分了解决约束问题的设置阶段和标记阶段

CLP(FD)解算器不能完全减少设置阶段的问题。因为它有机会在标记阶段减少可变范围。因此,在设置过程中可能会出现问题,其他解算器可能会将该问题减少为“否”,但CLP(FD)解算器不会出现该问题。只有在标记期间,才会检测到“否”

在设置阶段,减少的程度在很大程度上取决于给定的CLP(FD)系统。一些CLP(FD)系统在安装阶段减少的次数较多,而其他系统减少的次数较少。例如,GNU Prolog使用一些索引传播,而SWI Prolog不使用。因此,我们发现,例如,不是你的例子:

SWI序言:

?- X #< Y, Y #< Z, Z #< X.
Z#=<X+ -1,
X#=<Y+ -1,
Y#=<Z+ -1.
?- X #< 4 #==> X #< 7.
X+1#=_G1330,
X+1#=_G1342,
7#>=_G1330#<==>_G1354,
_G1354 in 0..1,
_G1377#==>_G1354,
_G1377 in 0..1,
4#>=_G1342#<==>_G1377.
?- X in 0..9, X #< 4 #==> X #< 7, label([X]).
X = 0 ;
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
X = 5 ;
X = 6 ;
X = 7 ;
X = 8 ;
X = 9.
?-X#=_G1342#u G1377。
GNU序言:

?- X #< Y, Y #< Z, Z #< X.
(7842 ms) no
?- X #< 4 #==> X #< 7.
X = _#22(0..268435455)
?- fd_domain(X,0,9), X #< 4 #==> X #< 7, fd_labeling([X]).
X = 0 ? ;
X = 1 ? ;
X = 2 ? ;
X = 3 ? ;
X = 4 ? ;
X = 5 ? ;
X = 6 ? ;
X = 7 ? ;
X = 8 ? ;
X = 9
?-X#<4#=>X#<7。
X=22(0..268435455)
在设置阶段进行更多的缩减和将更多的工作留给标记阶段之间存在权衡。整个事情也取决于给定的例子。但是,当您在设置旁边添加标签时,您将不会看到结果方面的任何差异:

SWI序言:

?- X #< Y, Y #< Z, Z #< X.
Z#=<X+ -1,
X#=<Y+ -1,
Y#=<Z+ -1.
?- X #< 4 #==> X #< 7.
X+1#=_G1330,
X+1#=_G1342,
7#>=_G1330#<==>_G1354,
_G1354 in 0..1,
_G1377#==>_G1354,
_G1377 in 0..1,
4#>=_G1342#<==>_G1377.
?- X in 0..9, X #< 4 #==> X #< 7, label([X]).
X = 0 ;
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
X = 5 ;
X = 6 ;
X = 7 ;
X = 8 ;
X = 9.
?-X在0..9中,X#<4#=>X#<7,标签([X])。
X=0;
X=1;
X=2;
X=3;
X=4;
X=5;
X=6;
X=7;
X=8;
X=9。
GNU序言:

?- X #< Y, Y #< Z, Z #< X.
(7842 ms) no
?- X #< 4 #==> X #< 7.
X = _#22(0..268435455)
?- fd_domain(X,0,9), X #< 4 #==> X #< 7, fd_labeling([X]).
X = 0 ? ;
X = 1 ? ;
X = 2 ? ;
X = 3 ? ;
X = 4 ? ;
X = 5 ? ;
X = 6 ? ;
X = 7 ? ;
X = 8 ? ;
X = 9
?-fd#u域(X,0,9),X#<4#==>X#<7,fd#u标签([X])。
X=0;
X=1;
X=2;
X=3;
X=4;
X=5;
X=6;
X=7;
X=8;
X=9
我没有使用SICStus Prolog或B-Prolog进行测试。但我猜他们会在SWI Prolog和GNU Prolog的长相中表现出来

如果您的域是真正的FD,CLP(Q)就不是真正的替代方案,因为它将错过一些CLP(FD)不会错过的“否”缩减。例如,以下内容在CLP(FD)中不可满足,但在CLP(Q)中可满足:

X=Y+1,Y

再见

非常感谢,我正在处理线性不等式问题。我正在尝试自动查找一组合取(可能为否定)约束的范围。因此,我希望能够传入(例如)X#2),这是有效的。我还想传入更复杂的内容,例如X#2,X#要否定连词,必须使用#/\,例如:#\(a#/\B)。