使用Z3 4.4.1或master,以下输入提供unknown
:
(declare-fun x () Int)
(declare-fun y () Int)
(declare-fun z () Int)
(assert (and (> x 0) (< x 10)))
(assert (and (> y 0) (< y 10)))
(assert (and (> z 0) (< z 10)))
(assert (= (* z z) (+ (* x x) (* y y))))
(check-sat-using (or-else qfnra-nlsat smt))
如果我切换qfnra-nlsat
和smt
策略的顺序,那么Z3将返回sat
,这是正确的解决方案。它现在的工作方式,我基本上被迫在我的策略的最后使用qfnra-nlsat
。但是,这对我来说不是最理想的。
上述行为是否是个错误?似乎qfnra-nlsat
会对模型留下一些不必要的更改,如果qfnra-nlsat
失败,我希望模型不会改变。
答案 0 :(得分:1)
尝试改为
(check-sat-using (and-then qfnra-nlsat smt))
这很微妙: qfnra-nlsat策略无法确定公式是否可满足,因为公式使用整数(并且模型qfnra-nlsat找到一个解决方案而不是实数)。因此它起到了无操作的作用,并产生了相同的子目标。 or-else列表中没有抛出异常的第一个策略成为决定结果的策略。所以qfnra-nlsat决定不能减少目标。
通过使用和 - 然后你基本上使用第一个qfnra-nlsat减少目标。如果成功,它会产生子目标或子目标,公式为“false”。 smt策略知道处理这些情况,其中sat和不满的情况被非常有效地处理。
还有其他选择。特别是,如果你想使用or-else作为一些更大的替代方案的一部分,那么方法是:
(check-sat-using (or-else (and-then qfnra-nlsat fail) (and-then smt fail)))
如果qfnra-nlsat创建非真实和非虚假子目标,则会导致无法发出信号。然后失败时,应用smt策略。