0

I found this post that gives a way of checking for overflow in solutions when adding bitVecs z3 bitvector overflow checking from python?

However, it only works when only adding 2 bitVecs, is there any way of extending it so it works for adding an arbitrary number of bitVecs? As far as I can tell, the problem is that "z3._coerce_exprs(x, y)" in

def bvadd_no_overflow(x, y, signed=False):
    assert x.ctx_ref()==y.ctx_ref()
    a, b = z3._coerce_exprs(x, y)
    return BoolRef(Z3_mk_bvadd_no_overflow(a.ctx_ref(), a.as_ast(), 
         b.as_ast(), signed))

Only can take 2 inputs.

maja
  • 5
  • 2

1 Answers1

0

You can program this yourself, on top of the 2-place predicate z3 provides:

from z3 import *

def addition_does_not_overflow(xs, signed):
    sofar      = 0
    noOverflow = True
    for x in xs:
      noOverflow = And(noOverflow, BVAddNoOverflow(x, sofar, signed))
      sofar += x
    return noOverflow

xs = [BitVec('x' + str(i), 2) for i in range(5)]
s = Solver()

s.add(addition_does_not_overflow(xs, False))
if s.check() == sat:
    print(s.model())
else:
    print("No solution")

This prints:

[x3 = 1, x2 = 2, x1 = 0, x4 = 0, x0 = 0]

and indeed, those numbers don't overflow when added as unsigned 2-bit vectors, i.e., those that range from 0 to 3. Note that second argument of the predicate: You should pass True if you want signed-arithmetic, and False if otherwise.

alias
  • 28,120
  • 2
  • 23
  • 40