繁体   English   中英

SWI-Prolog和约束,库CLP(FD)

[英]SWI-Prolog and constraints, library CLP(FD)

我正在使用clpfd库来处理(swi)序言中的约束。

我试图确定一组约束何时封装或包含另一组约束,例如X <4封装X <7,只要前者为真,后者为真。 使用逻辑含义可以很容易地表示出来。 但是,我无法获得#==>运算符来提供所需的结果,因此我求助于使用not(Co1#/ \\#\\ Co2),其中Co1和Co2是约束。 这对于单独的约束来说很好,但是我随后想将约束的结合传递到Co1和Co2中。

现在这里是摩擦。 当我尝试

X#<7 #/\ #\X#<4.

我回来

X in 4..6,
X+1#=_G822,
X+1#=_G834,
_G822 in 5..7,
_G834 in 5..7.

(很奇怪,在Sicstus中执行此操作会导致分段错误)

当我通过时

X#<7,X#<4

我得到了想要的

X in inf..3.

显然,我不能将后者传递给not(Co1#/ \\#\\ Co2),但是前者不能给我我想要的结果。 谁能解释为什么两种方法会产生不同的结果,以及我如何才能使前者像后者一样行事?

一般而言,一般算术约束是否包含在整数上是无法确定的,因此所有正确的求解器都有其固有的局限性,超过这些固有的局限性,他们必须将其答案延迟直到知道更多为止。 如果您知道自己的域是有限的,则可以发布这些域,然后尝试使用约束求解器的labeling / 2谓词查找使蕴涵无效的反例。 还考虑Q上的线性不等式是可确定的,并且SWI-Prolog的库(clpq)已为它们完成。 因此,您可以使用以下方法在CLP(Q)中尝试约束:

?- use_module(library(clpq)).
true.

?- { X < 4, X >= 7 }.
false.

并且看到在Q中没有这样的反例(因此在Z中也不存在),因此含义成立。

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

在设置阶段,CLP(FD)求解器不能完全减少问题。 因为它有机会在贴标阶段减小可变范围。 因此,可能是在设置过程中出现了一个问题,可以通过其他求解器将其减少为“否”,但对于CLP(FD)求解器则不会。 仅在标记过程中会检测到“否”。

在设置阶段完成多少减少工作很大程度上取决于给定的CLP(FD)系统。 某些CLP(FD)系统在设置阶段可做更多的减少,而其他系统则做得更少。 例如,GNU Prolog使用一些索引传播,而SWI Prolog不使用。 因此,我们找到了一个例子,而不是您的例子:

SWI-Prolog:

?- X #< Y, Y #< Z, Z #< X.
Z#=<X+ -1,
X#=<Y+ -1,
Y#=<Z+ -1.

GNU序言:

?- X #< Y, Y #< Z, Z #< X.
(7842 ms) no

此外,由于您使用的是约束化约束,因此它还取决于实现约束的巧妙程度。 但我想在目前情况下,这仅是传播问题。 现在为您的示例查找:

SWI-Prolog:

?- 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.

GNU序言:

?- X #< 4 #==> X #< 7.
X = _#22(0..268435455)

在设置阶段进行更多的缩减与标签阶段进行更多的工作之间需要权衡。 整个问题还取决于给定的示例。 但是,当您还在设置旁边贴上标签时,您将看不到任何结果方面的差异:

SWI-Prolog:

?- 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.

GNU序言:

?- 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

我没有使用SICStus Prolog或B-Prolog进行测试。 但是我想它们将在SWI-Prolog和GNU Prolog的杰出表现中表现出来。

如果您的域是FD,则CLP(Q)并不是真正的替代选择,因为它会错过某些“ No”减少,而CLP(FD)不会错过。 例如,以下内容在CLP(FD)中无法满足,但在CLP(Q)中可以满足:

X = Y + 1, Y < Z, Z < X.

再见

暂无
暂无

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

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