在两者之间声明相同的属性时,会有不同的check-sat答案

时间:2015-03-20 12:32:08

标签: z3

给出以下输入

(set-option :auto_config false)
(set-option :smt.mbqi false)

(declare-fun len (Int) Int)
(declare-fun idx (Int Int) Int)
(declare-const x Int)

(define-fun FOO () Bool
  (forall ((i Int)) (!
    (implies
      (and (<= 0 i) (< i (len x)))
      (exists ((j Int)) (!
        (implies
          (and (<= 0 j) (< j (len x)))
          (> (idx x j) 0))))))))

(assert FOO)

; (push)
(assert (not FOO))
(check-sat)
; (pop)

; (push)
(assert (not FOO))
(check-sat)
; (pop)

Z3 4.3.2 x64报告unsat表示第一个check-sat(正如预期的那样),但unknown表示第二个push。如果评论的pop / check-sat已取消注释,则unknown生成check-sat

我的猜测是,这是一个错误,或者是Z3在达到第二个check-sat时切换到增量模式的结果。后者也可以解释为什么unknown如果使用push / pop会产生push,因为Z3(据我所知)会在第一个{切换到增量模式{ {1}}。

问题:这是错误还是预期后果?

2 个答案:

答案 0 :(得分:2)

很好的例子。

这是Z3如何处理公式的限制: 1.当使用push / pop时,它不会检测断言的公式之间的矛盾,而是将公式转换为否定的正规形式,并将量化的公式简化。 2.当第二次呼叫check-sat时,它不会跟踪状态是否从先前不可满足的状态撤回。

这不是一个不健全的错误,但确定行为不是用户期望的行为。

答案 1 :(得分:2)

除了Nikolaj的回答:是的,这是因为Z3切换到另一个解算器,这将更早放弃。我们可以通过设置(set-option :combined_solver.ignore_solver1 true)来获得相同的效果。