考虑以下SMTLIB程序(在rise4fun here上):
(set-option :auto_config false)
(set-option :smt.mbqi false)
(set-option :smt.arith.nl.gb false)
(declare-const n Int)
(declare-const i Int)
(declare-const r Int)
(assert (= i n))
(assert (= r (* i n)))
(push)
(assert (not (= r (* n n))))
(check-sat) ; unknown
(pop)
虽然看起来只需要语法上的平等推理,但Z3(4.3.2官方发布,以及4.4.0 b6c40c6c0eaf)仍未能证明最终断言是unsat
。
出乎意料地(至少对我来说),将smt.arith.nl.gb
设置为true
会使示例验证(即check-sat
产生unsat
)。
对于它的价值,这里有一些进一步的观察:
如果乘法分别更改为unsat
或(* i n)
(* n i)
>
如果将乘法更改为unsat
(* i i)
(push)
和(pop)
似乎不会影响该示例,即可以在不影响所述观察结果的情况下删除它们
这是一个错误,还是因为显示此示例smt.arith.nl.gb
需要unsat
?
答案 0 :(得分:2)
这不一定是个错误。基于Groebner的计算解决了这个问题,因此可以快速找到不满意的结果(这很好,因此默认情况下启用)。此外,禁用auto_config还意味着根据问题没有设置许多其他选项(但在这种特殊情况下它没有区别)。
请注意,一些策略,解算器或简化器只会在看到乘法表达式时放弃,无论问题是否易于为人类或其他解算器解决。在这种特殊情况下,非线性解算器在smt.arith.nl.rounds耗尽(默认为1024)后放弃,因此返回未知。
快速解决这个问题的一个策略是解决方案,但这不是默认策略的一部分(在这种情况下,它运行qfnia策略)。如果它能解决您的问题,您可以通过用
替换check-sat命令来轻松添加(check-sat-using (then solve-eqs qfnia))
这是否应该是默认值是有争议的,直到基准测试,但它不是一个真正的错误。
快速解决这个问题的另一种策略是NLSAT解算器,例如
(check-sat-using nlsat)