使用Z3求解器执行以下查询:
(assert (exists ((c0_s Int) (c1_s Int) (c2_s Int))
(and
(= (+ c0 c1 c2) 5) (>= c0 0) (>= c1 1) (>= c2 1)
(= c0_s c0) (= c1_s (- c1 1)) (= c2_s (+ c2 1))
(= c2_s 3) (= (+ c0_s c1_s) 2)
))
)
(apply (then qe ctx-solver-simplify propagate-ineqs))
产生以下输出:
(goals
(goal
(>= c0 0)
(<= c0 2)
(>= c1 1)
(<= c1 3)
(<= (+ (* (- 1) c0) (* (- 1) c1)) (- 3))
(<= (+ c1 c0) 3)
(= c2 2)
:precision precise :depth 3)
)
我期待Z3求解器的结果如下:
(goals
(goal
(>= c0 0)
(<= c0 2)
(>= c1 1)
(<= c1 3)
(= (+ c1 c0) 3)
(= c2 2)
:precision precise :depth 3)
)
任何人都可以解释为什么Z3会产生如此复杂的结果而不是我的预期吗?有没有办法让Z3简化这个输出?
答案 0 :(得分:2)
你可能会从核心Z3团队的成员那里得到更详细的答案,但根据我在低级别使用Z3的整数解算器的经验,我可以直截了当地说明为什么会发生这种情况。
简而言之,为了求解整数方程,Z3的整数理论求解器期望它的所有约束都以非常特殊和受限的形式出现。不遵循此表单的表达式必须在呈现给解算器之前重写。通常这是由理论重写器在内部发生的,任何表达式都可以在输入约束集中使用而没有问题。
这里适用的限制(我知道)有助于解释为什么你会看到这种看起来很奇怪的输出,如下所示:
(= a b)
表示为两个单独的不等式约束(<= a b)
和(>= a b)
。这就是为什么你在模型中看到对变量的两个单独约束而不仅仅是一个相等。简而言之,您所看到的可能是算术理论求解器如何在内部表示约束的神器。
由于您的实例的输出是目标而不是模型或证明,这些表达式可能还没有完全简化,因为我认为中间目标并不总是简化(但我没有这方面的经验)解算器)。