[英]CLP(FD) variable domains & propagation
在上学期的 Prolog 课程中,我在引入 CLP 时落后了一点。 现在我正在努力追赶,并尝试了教授提供给所有学生的过去考试。
特别是,有这样一个问题:
以下查询后,CLP(FD) 中决策变量 Z 的域是什么:
?- X in 1..7, Y in -3..100, Y #> X, Z #\\= 0, Z #= Y - X.
在我看来答案应该是
Z in 1..99
但是当我在 SWI-Prolog 安装中运行它进行仔细检查时,我得到了
Z in -5.. -1\/1..99
这似乎是基于对X
& Y
的最大值和最小值的简单比较,而不考虑链接它们的约束( Y #> X
)。
我意识到必须在此处对可行性做出让步,并且返回的域有时会比它们应有的限制更少,但我很惊讶地看到它在这样一个简单的例子中失败了。
我的问题
Y #> X
,但这并没有改变任何变量域。在我看来答案应该是
Z in 1..99
你怎么能确定你是对的? 这是约束的一个很好的属性:您可以最轻松地验证这一点:
?- X in 1..7, Y in -3..100, Y #> X, Z #\= 0, Z #= Y -X.
X in 1..7,
Z+X#=Y,
X#=<Y+ -1,
Z in -5.. -1\/1..99,
Y in 2..100.
?- X in 1..7, Y in -3..100, Y #> X, Z #\= 0, Z #= Y -X, Z #< 0.
false.
好的,现在我相信你说的了。
所以,你在这里发现的不一致是在SICStus'本土也存在library(clpfd)
以及library(clpz)
首先请注意,给出的答案没有错误! 它说:是的, X in 1..7, Z+X#=Y, X#=<Y+ -1, Z in -5.. -1\\/1..99, Y in 2..100.
提供了X in 1..7, Z+X#=Y, X#=<Y+ -1, Z in -5.. -1\\/1..99, Y in 2..100.
是真的。 嘿,这不是真的。
所以这个答案有点像许多保险合同中的法律术语,他们说,是的,我们将支付,前提是所有这些微小的无法阅读的印刷品都保留了下来,但实际上,您可以用一个巨大的false
代替那堵缩微文本墙。
通常,这种不一致是不可避免的,因为在上述系统中定义的 CLP(FD)/CLP(Z) 允许制定无法确定的问题。 因此,无论您的约束求解器如何进化,我们都可以保证总会有我们无法解决的情况。 这是一个科学的数学定律,比重力或速度限制等经验定律可靠得多。
这里的不一致实际上是一种工程权衡。 只要没有人抱怨并且没有令人信服的用例,此类系统的开发人员就不会看到改进的理由。 毕竟,这样的改进可能会减慢现有用例的速度。
- CLP 如何准确地(或近似地失败)传播其约束?
实际上,对于任何实际大小的问题,没有人知道。 但这也不是必须的。 在 CLP(FD) 的情况下,基本元素是附加到逻辑变量的域。 您将它们视为(in)/2
个目标,例如Z in -5.. -1\\/1..99
。 它们之间连接的是实际的约束。 在你的情况下Y #> X
和Z #= YX
。 这些约束现在只看到变量的域并尝试保持它们之间的一致性。 作为更粗略的近似,域被视为区间,因此Z in -5 .. 99
而不是上面。 (他们中的大多数)没有看到的是其他约束。 在这种情况下, Y #> X
和Z #= YX
之间没有直接联系。 因此不一致。 这种有限的一致性检查更容易实现,而且速度也非常快,并且通常优于更完整的算法。 随着更好算法的发现,事情也在发展。 一个很好的例子是all_distinct/1
,它使用 Regin 算法保持所有变量之间的一致性,而all_different/1
只保持每对变量之间的一致性。 但无论如何:这些事情不断发展,这是一道考试题,这有点令人惊讶。
- 有什么方法可以让 CLP(FD) 适当地应用约束......?
?- X in 1..7, Y in -3..100, Y #> X, Z #\= 0, Z #= Y -X, clpfd:contracting([X,Y,Z]).
X in 1..7,
Z+X#=Y,
X#=<Y+ -1,
Z in 1..99,
Y in 2..100.
但大多数人会忽略这个问题,只添加labeling([],[X,Y])
Z
的域是什么?
这是一个模棱两可的问题。 给出两者作为答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.