简化表达会导致超时

时间:2015-07-19 00:20:29

标签: timeout z3 simplify java-api

如何使用Z3 Solver简化以下表达式?

(declare-const c0 Int)
(declare-const c1 Int)
(declare-const c2 Int)

(assert (let ((a!1 (to_real (+ (* (* 2 c0) c2)
                   (* (* 2 c0) c1)
                   (* 2 c1 c2)
                   (* c0 (- c0 1))
                   (* c1 (- c1 1))))))
  (let ((a!2 (/ (to_real (* (* 2 c0) c2)) a!1)))
  (and (or (and (<= c2 1) (>= c2 1) (<= c0 2) (>= c0 2) (<= c1 3) (>= c1 3))
           (and (<= c2 1) (>= c2 1) (<= c0 3) (>= c0 3) (<= c1 2) (>= c1 2)))
  (= (/ 2.0 15.0) a!2))))
)

(apply (then qe propagate-values (repeat (then ctx-solver-simplify propagate-ineqs) 10)))

链接:http://rise4fun.com/Z3/u7F7

我尝试了我所知道的所有可能的策略,但却最终导致了求解器的超时。有没有办法可以避免超时?是否假设在 Java API

中返回false

2 个答案:

答案 0 :(得分:1)

通过查看代码很难分辨出发生了什么。但我认为to_real可能是有问题的部分,因为域之间的转换往往会产生可能导致复杂性问题的非线性约束。

我会尝试使用纯粹的Reals(即声明c0c1 ..作为Real s;并删除对to_real的调用。)< / p>

如果你确实需要整数/实数混合;确保在叶子上进行混合(即,在常数处);或者在最顶端,尽可能多地推动转换;而不是中间值。

但我猜如果你的问题空间允许的话,那么坚持使用Reals将是你的理想选择。

答案 1 :(得分:1)

该示例使用非线性整数运算。不幸的是,很容易在Z3没有终止的域中生成示例。 ctx-solver-simplify例程多次调用SMT求解器,并且在每次调用时都必须检查某些非线性约束组合的可满足性。