我正在尝试使用z3 smt求解器将值分配给受约束的变量。除了硬约束外,我还有一些软约束(例如a != c
)。我希望能够用assert
指定硬约束,而将柔软约束指定为soft-assert
,如果我用(check-sat)
求解,则可以使用。
有些文件又大又复杂,并且只有在我使用(check-sat-using (then simplify solve-eqs bit-blast sat))
进行位冲击处理时才能解决。当我这样做时,软断言似乎被忽略了(下面或在rise4fun处的示例)。这是预期的吗?可以同时使用位冲击波求解和soft-assert
吗?
以下SMT代码定义了4个位向量a
,b
,c
和d
,它们都应该能够采用唯一的值,但只能这样做通过软断言。使用check-sat
(第39行)可以按预期工作,但是check-sat-using
(第38行)将b
和d
分配给相同的值。
(set-option :produce-models true)
(set-logic QF_BV)
;; Declaring all the variables
(declare-const a (_ BitVec 2))
(declare-const b (_ BitVec 2))
(declare-const c (_ BitVec 2))
(declare-const d (_ BitVec 2))
(assert (or (= a #b00)
(= a #b01)
(= a #b10)
(= a #b11)))
(assert (or (= b #b00)
(= b #b01)
(= b #b10)
(= b #b11)))
(assert (or (= c #b00)
(= c #b01)
(= c #b10)
(= c #b11)))
(assert (or (= d #b00)
(= d #b01)
(= d #b10)
(= d #b11)))
;; Soft constraints to limit reuse
(assert-soft (not (= a b)))
(assert-soft (not (= a c)))
(assert-soft (not (= a d)))
(assert-soft (not (= b c)))
(assert-soft (not (= b d)))
(assert-soft (not (= c d)))
(check-sat-using (then simplify solve-eqs bit-blast sat))
;;(check-sat)
(get-value (a
b
c
d))
答案 0 :(得分:2)
好问题!使用assert-soft
时,默认情况下,优化引擎会启动。通过将程序与(check-sat)
子句一起使用,并以较高的详细程度运行,可以看到此信息。我已将您的程序放在名为a.smt2
的文件中:
$ z3 -v:3 a.smt2
(optimize:check-sat)
(sat.solver)
(optimize:sat)
(maxsmt)
(opt.maxres [0:6])
(sat.solver)
(opt.maxres [0:0])
found optimum
sat
((a #b01)
(b #b00)
(c #b11)
(d #b10))
因此,我们可以看到z3将其视为优化问题,它考虑了软约束并为您提供了所要寻找的“脱节”。
我们做同样的事情,但是这次我们将使用check-sat
调用来指定要使用的策略。我们得到:
$ z3 -v:3 a.smt2
(smt.searching)
sat
((a #b11)
(b #b11)
(c #b11)
(d #b10))
这证实了您的怀疑:当您确切告诉z3该做什么时,它并没有执行优化过程。事后看来,这是可以预料的,但是我确实同意这很令人惊讶。
然后的问题是,我们是否可以告诉z3明确进行优化。但是我不确定在战术语言中这是否可能。我认为这个问题非常值得在他们的问题站点(https://github.com/Z3Prover/z3/issues)上询问,看看是否有魔术可以用来启动战术语言的maxres
引擎。 (由于多种原因,这可能是不可能的,但是没有理由在这里进行推测。)请在此处报告发现的内容!