我用Haskell编写了一个应用程序,它调用Z3求解器来用一些复杂的公式解决约束问题。多亏了Haskell,我可以快速切换我正在使用的数据类型。
当使用SBV的AlgReal类型进行计算时,我会在合理的时间内得到结果,但是切换到Float或Double类型会使Z3消耗~2Gb的内存,甚至在30分钟内也不会产生结果。
这是预期的,产生浮点解决方案需要更多的时间,或这是错误的一方?
发布于 2019-02-03 17:45:41
与任何有关求解器性能的问题一样,不可能进行泛化。Christoph (https://stackoverflow.com/users/869966/christoph-wintersteiger)将是这方面的专家,但我不确定他跟这个小组有多近。克里斯:如果你正在读这篇文章,我很想听听你的想法!
这里也有比较苹果和橘子的风险:真和浮动是两种完全不同的逻辑,有不同的决策过程、启发式、算法等等。我相信你会发现一个比另一个好的问题,没有明显的“表现”赢家。
话虽如此,以下是一些让浮点(FP)变得棘手的事情:
a * 1/a == 1不适用于浮点数。x + 1 /= x或(x + a == x) -> (a == 0)以及你想要做的许多其他“明显”的简化也是如此。所有这些都使推理复杂化。NaN值的存在使等式非自反性:任何事物都比不上NaN,包括它本身。因此,以等量替换也是有问题的,并且需要附加条件.+0和-0的存在,它们比较相等,但由于四舍五入而表现不同。典型的例子是x == 0 -> fma(a, b, x) == a * b不适用( fma是融合乘法加),因为根据零的符号,这两个表达式可以为不同的舍入模式产生不同的值。再一次,我想强调的是,在这两种不同的逻辑上比较求解者的表现是错误的,因为他们是完全不同的野兽。但希望以上各点说明了为什么浮点在实践中是棘手的.
关于IEEE754浮子在表面活性剂溶液中的处理的一篇很好的论文是:http://smtlib.cs.uiowa.edu/papers/BTRW14.pdf。您可以看到它所支持的无数操作,并了解到它的复杂性。
https://stackoverflow.com/questions/54502823
复制相似问题