模数函数和变量域

时间:2016-08-11 12:38:06

标签: prolog clpfd

这是一个简单的CLPFD关系:

1 #= 81 mod X.

返回:

X in inf.. -1\/1..sup,
81 mod X#=1.

除非我的数学完全不正确,否则X的域名不应该是-80.. -1\/1..80

2 个答案:

答案 0 :(得分:4)

首先要做的事情:

  

约束求解器中是否存在错误

(必要),因为所有可接受的解决方案仍包含在推断的域中,并且未报告错误的解决方案。您推导出的域是解算器报告的正确子集

  

在这种情况下,约束求解器是否会传播?

没有,显然不是,因为你的强势界限已经显示出来了。事实上,可接受的域甚至比你推断的要小:X in 2..80 有效,因为X肯定是否定的,并且不能等于1。

练习X in 2..80 最小(关于集合包含)域,在这种情况下可以推断出来吗?为什么不)?在什么,如果有的话,感觉它是最小的?

  

那么,这里发生了什么?

解释相当简单:实施(mod)/2(rem)/2(div)/2以及 - 在更小程度上 - 甚至(*)/2以这样的方式传播在所有情况下尽可能残酷地才能做到正确,并且在这种情况下显然没有完成。

  

我们是否必须忍受这个缺点?

,因为我们可以改进约束求解器来处理这种情况!也就是说,我们可以添加逻辑,以便它更强烈地传播 !优雅而正确地执行此操作通常是未解决的问题,以及活跃研究的主题。参见例如Finite Domain Constraint Solver Learning,其中包含的参考文献以及其他几篇论文。当然,梦想是以某种方式直接从这些操作的规范中获得传播,这至少需要几十年的时间。在此之前,发现并改进了这些问题,而不是 ad hoc

答案 1 :(得分:1)

免责声明:我不知道我在说什么,我只想亲眼看看会发生什么,并认为分享可能会有用。

使用SWI-Prolog和库(clpfd):

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

?- 1 #= 81 rem X.
X in inf.. -1\/1..sup,
81 rem X#=1.

?- 1 #= 81 mod X.
X in inf.. -1\/1..sup,
81 mod X#=1.

?- 1 #= 81 - X * (81 // X ).
X in -80.. -1\/1..80,
X*_G1053#=80,
81//X#=_G1053,
_G1053 in -80.. -1\/1..80.

奇怪的是,上一个例子中的表达式是不是应该如何定义模除法?

如果你服用Gnu-Prolog(mod不直接支持):

| ?- 1 #= 81 rem X.

X = _#4(2..80)

yes
| ?- 1 #= 81 - X * (81 // X).

no

嗯。如果您只是重新排序表达式

,该怎么办?
| ?- 1 #= 81 - (81 // X) * X.

X = _#4(2..80)

yes

结论:是的,似乎写一个好的CLP(FD)库确实不容易。甚至可能会给人留下这样的印象,即这些图书馆表现出作者并不总是完全了解的紧急行为。