简化表达式:Z3 SMT求解器

简化表达式:Z3 SMT求解器,z3,simplify,smt,Z3,Simplify,Smt,使用Z3解算器执行以下查询: (declare-const c0 Int) (declare-const c1 Int) (declare-const c2 Int) (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)

使用Z3解算器执行以下查询:

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

    (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)
    )
(目标
(目标
(>=C00)
(=c1 1)

(您可能会从核心Z3团队的一名成员那里得到更详细的答案,但根据我在较低级别上使用Z3的整数解算器的经验,我可以给出一点直觉来解释为什么会发生这种情况

简单地说,为了求解整数方程,Z3的整数理论解算器希望其所有约束以一种非常特殊和受限的形式出现。不遵循此形式的表达式必须在提交给解算器之前重写。通常,这是由理论重写器在内部发生的,任何表达式都可以在t中使用他毫无疑问地输入了约束集

这里应用的限制(我知道)有助于解释为什么会看到这种奇怪的输出,如下所示:

  • 整数解算器可以将等式约束
    (=ab)
    表示为两个独立的不等式约束
    (=ab)
    。这就是为什么您在模型中看到变量上的两个独立约束,而不仅仅是一个等式
  • 整数解算器将减法或求反的项重写为-1的乘法。这就是为什么您在第一个约束中看到这些求反,以及为什么运算符是加法而不是减法
  • 算术表达式被重写,以便比较运算符的第二个参数始终为常量值
简言之,您所看到的可能是算术理论解算器如何在内部表示约束的人工制品


由于实例的输出是一个目标,而不是一个模型或证明,这些表达式可能还没有完全简化,因为我相信中间目标并不总是简化的(但我对解算器的这一部分没有经验).

显然,Z3不知道如何简化否定。也许你应该在GitHub上发布一个功能请求。感谢你的快速响应,如果是这样的话,我会尽快请求。但是,我想知道为什么它首先会在不需要否定的情况下生成否定。
    (goals
     (goal
       (>= c0 0)
       (<= c0 2)
       (>= c1 1)
       (<= c1 3)
       (= (+ c1 c0) 3)
       (= c2 2)
       :precision precise :depth 3)
    )