Z3 SMT 2.0 vs Z3 py implementation

旧巷老猫 提交于 2019-12-11 12:08:25

问题


I'm trying to encode an arithmetic for positive reals with a constant infinity in Z3. I successfully obtained the result in SMT2 with the following pair encoding

(declare-datatypes (T1 T2) ((Pair (mk-pair (first T1) (second T2)))))
(declare-const infty (Pair Bool Real))
(assert (= infty (mk-pair true 0.)))
(define-fun inf-sum ((p1 (Pair Bool Real)) (p2 (Pair Bool Real))) (Pair Bool Real)
  ( ite
     (first p1)
     p1
     (ite
       (first p2)
       p2
       (mk-pair false (+ (second p1) (second p2)))
      )
  )
)

where a pair (true, _) encodes infinity while (false, 5.0) encodes the real 5. This works and I can solve constraints over it very fast.

I tried a similar approach with Z3py using z3 axioms over the following datatype:

MyR = Datatype('MyR')
MyR.declare('inf');
MyR.declare('num',('r',RealSort()))

MyR = MyR.create()
inf = MyR.inf
num  = MyR.num
r  = MyR.r

r1,r2,r3,r4,r5 = Consts('r1 r2 r3 r4 r5', MyR)
n1,n2,n3 = Reals('n1 n2 n3')

msum = Function('msum', MyR, MyR, MyR)

s = Solver()

s.add(ForAll(r1, msum(MyR.inf,r1)== MyR.inf))
s.add(ForAll(r1, msum(r1,MyR.inf)== MyR.inf))
s.add(ForAll([n1,n2,n3], Implies(n1+n2==n3, 
  msum(MyR.num(n1),MyR.num(n2))== MyR.num(n3))))
s.add(msum(r2,r4)==MyR.num(Q(1,2)))
print s.sexpr()
print s.check()

I can't get it to work (it times out). I guess the problem is in trying to prove the consistency axioms. However I couldn't find another way to encode my arithmetic in Z3py.

Is anyone aware of what is the equivalent of the Z3 SMT2 approach of above in z3py?

Thank you


回答1:


In Z3Py, you should define msum as:

def msum(a, b):
    return If(a == inf, a, If(b == inf, b, num(r(a) + r(b))))

This is equivalent to what you did in the SMT2 frontend. After you do that and remove the universal axioms, Z3Py will also find the solution.

Here is the complete example (available online at http://rise4fun.com/Z3Py/Lu3):

MyR = Datatype('MyR')
MyR.declare('inf');
MyR.declare('num',('r',RealSort()))

MyR = MyR.create()
inf = MyR.inf
num = MyR.num
r   = MyR.r

r1,r2,r3,r4,r5 = Consts('r1 r2 r3 r4 r5', MyR)
n1,n2,n3 = Reals('n1 n2 n3')

def msum(a, b):
    return If(a == inf, a, If(b == inf, b, num(r(a) + r(b))))

s = Solver()
s.add(msum(r2,r4) == MyR.num(Q(1,2)))
print s.sexpr()
print s.check()
print s.model()


来源:https://stackoverflow.com/questions/13826217/z3-smt-2-0-vs-z3-py-implementation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!