我有以下查询有效:
(set-info :status unknown)
(declare-fun n () Int)
(declare-fun b () Int)
(declare-fun c () Int)
(assert (= 0 (mod c 2))) ; c is even
(assert (= b (div c 2))) ; b = c/2
(assert (not (= c (* 2 b)))) ; c != 2*b
(check-sat)
正如所料,我感到不满。但是,如果我用(n *(n + 1))替换c,我会得到未知(本地z3建立自提交5068d2083dc0609801f572a0e3d14df753d36a03,大约4.5.1)或超时(http://rise4fun.com/Z3上):
(set-info :status unknown)
(declare-fun n () Int)
(declare-fun b () Int)
(declare-fun c () Int)
(assert (= 0 (mod (* n (+ 1 n)) 2)))
(assert (= b (div (* n (+ 1 n)) 2)))
(assert (not (= (* n (+ 1 n)) (* 2 b))))
(check-sat)
任何想法为什么在一个案例中它会弄清楚而不是在另一个案例中?
谢谢! 〜笛膜
答案 0 :(得分:1)
当您输入n * (n+1)
时,问题变为非线性。 (非线性意味着你乘以/除以非常数。)
在这种情况下,默认求解器不太可能产生结果,因为决策算法仅用于逻辑的线性片段。你基本上受启发式的支配:如果他们可以解决你的问题,那就太好了;如果没有,你会得到unknown
的答案。
话虽如此,你可以使用"策略"指导解算器。在这种情况下,以下似乎有效:
(check-sat-using (and-then qfnra-nlsat smt))
有了这个,z3成功返回unsat
查询。
有关详细信息,请参阅http://rise4fun.com/z3/tutorial/strategies。了解哪种策略适用于哪个问题是一门艺术,但如果您阅读本教程,您就可以很好地了解应该尝试的内容。