Reputation: 1886
The below Python snippet illustrates a strage performance behavior of Z3. Without push()
call, the z3 checks the formula in 0.1s. With push()
(and no extra assertions), z3 takes 0.8s. A similar outcome occurs even after swapping s.append(f)
and s.push()
.
import time
import z3
f = z3.parse_smt2_file("smt-lib/QF_BV/RWS/Example_1.txt.smt2")
s = z3.Solver()
s.append(f)
t1 = time.time()
s.check() # 0.10693597793579102 seconds
print(time.time() - t1)
s = z3.Solver()
t1 = time.time()
s.append(f)
s.push()
s.check() # 0.830916166305542 seconds
print(time.time() - t1)
Any idea why does this slowdown occur? And, how can it be addressed?
I'm using z3-4.3.2.bb56885147e4-x64-osx-10.9.2.
Upvotes: 4
Views: 1024
Reputation: 8359
Your example uses "push" in the second instantiation. This makes a huge difference. Z3's bit-vector solver is (not yet) amenable to incremental use over the API. It works only for stand-along assertions and does not interoperate with scopes (push/pop). The first invocation uses the bit-vector SAT solver. There is no "push/pop" going on. The second invocation follows a call to "push". Z3 then determines that in order to track scope dependencies it has to use the incremental SMT core, which does not benefit from the more efficient bit-vector solver.
Upvotes: 5