Z3真正的算术和统计

时间:2012-06-08 13:18:06

标签: performance encoding statistics z3 real-datatype

鉴于使用Z3的实数编码的问题,Z3 /smt2 /st生成的统计数据可能有助于判断实际引擎是否“存在问题/做了大量工作”?

在我的情况下,我有两个大致相同的问题编码,都使用实数。然而,编码中的“小”差异在运行时产生很大差异,即编码A需要2:30分钟并且编码B 13分钟。 Z3统计数据显示,conflictsquant-instantiations大部分是等效的,但其他则不是,例如grobnerpivotsnonlinear-horner

两种不同的统计数据以gist提供。


编辑(以解决Leo的评论):

两个版本生成的SMT2编码约为30k行,并且使用实数的断言遍及代码。主要的区别在于编码B使用了大量的0.01.0范围内的不明确的实数常数,这些常数由不等式限定,例如: 0.0 < r1 < 1.00.0 < r3 < 0.75 - r1 - r2,而在编码中,许多这些未指定的常量已被替换为来自相同范围的固定实数值,例如0.10.75 - 0.01。两种编码都使用非线性实数算术,例如, r1 * (1.0 - r2)

这两个编码中的一些随机示例可用作gist。如上所述,所有发生的变量都是未指定的实数。


PS:为固定的实际值引入别名,例如,

(define-sort $Perms () Real)
(declare-const $Perms.$Full $Perms)
(declare-const $Perms.$None $Perms)
(assert (= $Perms.Zero 0.0))
(assert (= $Perms.Write 1.0))

会造成重大的性能损失吗?

1 个答案:

答案 0 :(得分:4)

新的非线性算术求解器仅用于仅包含算术的问题。由于您的问题使用量词,因此不会使用新的非线性求解器。因此,Z3将使用基于以下组合的旧方法:Simplex(pivotots stat),Groebner Basis(groebner stat)和Interval Propagation(horner stat)。这不是一个完整的方法。 而且,根据你在gist中发布的片段,Groebner的基础不会很有效。这种方法通常对包含许多等式的问题有效。 所以,它可能只是开销。您可以使用选项NL_ARITH_GB=false将其停用。 当然,这只是基于您发布的问题片段的猜测。

编码AB之间的差异很大。编码A本质上是一个线性问题,因为几个常量被固定为实数值。对于线性算术问题,Z3总是完整的。所以,这应该可以解释性能上的差异。

关于别名的问题,引入别名的首选方法是:

(define-const $Perms.$Zero $Perms 0.0)
(define-const $Perms.$Write $Perms 1.0)

Z3还包含一个使用线性方程消除变量的预处理器。 默认情况下,此预处理器在包含量词的问题中处于禁用状态。该设计决策的动机是程序验证工具,这些工具广泛使用量词中的触发器/模式。变量消除过程可以修改精心设计的触发器/模式,并影响总运行时间。您可以在Z3中使用新的策略/策略框架来强制它应用此预处理器。您可以替换命令

(check-sat)

(check-sat-using (then simplify solve-eqs smt))

这个策略告诉Z3执行简化器,然后求解方程(并消除变量),然后执行默认的求解器引擎smt。 您可以在以下tutorial中找到有关策略和策略的更多信息。