为什么Z3在线和Z3PY的结果有所不同?

时间:2016-04-14 13:30:05

标签: z3 z3py

以下代码我尝试了在线和离线Z3

(set-option :smt.mbqi true)
(declare-var X  Int)
(declare-var X_  Int)
(declare-var a_  Int)
(declare-var su_  Int)
(declare-var t_  Int)
(declare-var N1  Int)
(assert (>= X 0))
(assert (forall ((n1 Int)) (=> (< n1 N1) (>= X (* (+ n1 1) (+ n1 1))))))
(assert (= X_ X))
(assert (= a_ N1))
(assert (= su_ (* (+ N1 1) (+ N1 1))))
(assert (= t_ (* (+ N1 1) 2)))
(assert (< X (* (+ N1 1) (+ N1 1))))
(assert  (not (< X (* (+ a_ 1) (+ a_ 1)))))
(check-sat)

结果不满

以下代码我在Z3PY尝试过

set_option('smt.mbqi', True) 
s=Solver() 
s.add(X>=0) 
s.add(ForAll(n1,Implies(n1 < N1,((n1+1)**2)<=X))) 
s.add(((N1+1)**2)>X) 
s.add(X_==X) 
s.add(a_==N1) 
s.add(su_==((N1+1)**2)) 
s.add(t_==(2*(N1+1))) 
s.add(Not(((a_+1)**2)>X))

结果 - 未知

处理能力不同吗?

2 个答案:

答案 0 :(得分:2)

结果差异的原因是输入不同。例如,表达式

(N1+1)**2 

在语义上与

相同
(* (+ N1 1) (+ N1 1))

但由于语法差异,Z3不会将公式简化为可以轻松解决的问题。 Python中语法上等效的问题是

s.add(X>=0) 
s.add(ForAll(n1,Implies(n1 < N1,((n1+1)**2)<=X))) 
s.add(((N1+1)*(N1+1)) > X)
s.add(X_==X) 
s.add(a_==N1) 
s.add(su_==((N1+1)*(N1+1)))
s.add(t_==(2*(N1+1))) 
s.add(Not(((a_+1)*(a_+1))>X))

产生所需的结果。

答案 1 :(得分:0)

约束是否相同? 我没有看到python的变体:

 (assert (< X (* (+ N1 1) (+ N1 1))))