这是一个更有趣的问题的减少,其中缺失的属性(对于正k
,M
和N
),((k % M) * N) < M*N
。下面是a <= b ==> (a*c) <= (b*c)
更简单问题的编码。这样的查询成功(我们得到unsat
),但如果表达式b
被b+1
替换(如下面的第二个查询中所示),那么我们得到unknown
,这似乎奇怪。这是预期的行为吗?有没有办法改善对这种不平等的处理?我尝试使用和不使用配置选项,以及各种版本的Z3,包括当前不稳定的分支。任何提示将不胜感激!
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(assert (> a 0))
(assert (> b 0))
(assert (> c 0))
(assert (<= a b))
(assert (not (<= (* a c) (* b c))))
(check-sat)
(assert (<= a (+ b 1)))
(assert (not (<= (* a c) (* (+ b 1) c))))
(check-sat)
答案 0 :(得分:2)
这属于非线性整数算术(它有一个不可判定的决策问题,参见例如How does Z3 handle non-linear integer arithmetic?),所以实际上并不太令人惊讶Z3在某些例子中返回未知,尽管我猜它有点令人惊讶对于非常相似的例子,在不满和未知之间。
如果它适用于您的应用程序,您可以尝试类型强制:将常量编码为Real
而不是Int
。这将允许您使用Z3的完整求解器进行非线性实数算术,并使用unsat
返回check-sat
。
或者,您可以强制Z3使用非线性求解器,即使对于(check-sat-using qfnra-nlsat)
的整数编码,如下所示,基于您的示例(rise4fun link:http://rise4fun.com/Z3/87GW):
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(assert (> a 0))
(assert (> b 0))
(assert (> c 0))
(assert (<= a b))
(assert (not (<= (* a c) (* b c))))
;(check-sat)
(check-sat-using qfnra-nlsat) ; unsat
(assert (<= a (+ b 1)))
(assert (not (<= (* a c) (* (+ b 1) c))))
; (check-sat)
(check-sat-using qfnra-nlsat) ; unsat
关于类似主题的更多问题和答案:
Combining nonlinear Real with linear Int
z3 fails with this system of equations
Using Z3Py online to prove that n^5 <= 5 ^n for n >= 5
Can z3 always give result when handling nonlinear real arithmetic
Z3 Theorem Prover: Pythagorean Theorem (Non-Linear Artithmetic)