我们遇到了Z3返回sat
的约束,但是如果我们随后添加某个命名的断言,则Z3返回unknown
。一个例子是:
(declare-fun a () Real)
(declare-fun b () Bool)
(assert (and (<= 0.1 a) (<= a 10.0)))
(assert (= b (= 1.0 (/ 1.0 a))))
(check-sat)
Z3报告这是可以满足的。我们还可以断言b
是true
或false
,都可以按预期满足。但是,如果我们对b
的值使用命名的断言,则可取性检查的结果可能取决于值而变为unknown
。使用值true
,Z3仍返回sat
:
(set-option :produce-unsat-cores true)
(declare-fun a () Real)
(declare-fun b () Bool)
(assert (and (<= 0.1 a) (<= a 10.0)))
(assert (= b (= 1.0 (/ 1.0 a))))
(assert (! (= b true) :named c))
(check-sat)
Z3使用值false
返回unknown
:
(set-option :produce-unsat-cores true)
(declare-fun a () Real)
(declare-fun b () Bool)
(assert (and (<= 0.1 a) (<= a 10.0)))
(assert (= b (= 1.0 (/ 1.0 a))))
(assert (! (= b false) :named c))
(check-sat)
检查unknown
结果的原因(使用(get-info :reason-unknown)
)将返回(incomplete (theory arithmetic))
。
答案 0 :(得分:0)
在后一种情况下,z3似乎选择了错误的策略。将您的check-sat
呼叫替换为:
(check-sat-using qfnra-nlsat)
在这两种情况下,z3都说sat
。
为什么z3最终会选择不同的策略是一个很难回答的问题。我建议在他们的github网站上将其作为票证提交;他们可能缺少启发式方法。
旁注:我发现这是通过用-v:10
运行两种情况并浏览详细输出来实现的。查看z3在短期基准测试中的作用并不是一个坏方法。