Solving formulas in parallel with z3

Let's say I have a z3 solver with a certain number of approved constraints that are doable. Let S be a set of constraints, I would like to check for each constraint in S whether the formula is still feasible when adding constraints to the solver. This can easily be done sequentially as follows:

results = []

for constraint in S:
  solver.push()
  solver.add(constraint)
  results.append(solver.check() == z3.sat)
  solver.pop()

print all(results)

Now I would like to parallelize this to speed up the process, but I'm not sure how to do it correctly with z3.

Here is an attempt. Consider the following simple example. All variables are non-negative integers and should be summed with 1. Now I would like to check whether each variable x can be made independently. 0. Obviously, this is so; let x = 1 and assign 0 to other variables. Here is a possible parallel implementation:

from multiprocessing import Pool
from functools import partial
import z3

def parallel_function(f):
    def easy_parallize(f, sequence):
        pool   = Pool(processes=4)
        result = pool.map(f, sequence)

        pool.close()
        pool.join()

        return result

    return partial(easy_parallize, f)

def check(v):
    global solver
    global variables

    solver.push()
    solver.add(variables[v] > 0)
    result = solver.check() == z3.sat
    solver.pop()

    return result

RANGE = range(1000)
solver = z3.Solver()
variables = [z3.Int('x_{}'.format(i)) for i in RANGE]

solver.add([var >= 0 for var in variables])
solver.add(z3.Sum(variables) == 1)

check.parallel = parallel_function(check)
results = check.parallel(RANGE)
print all(results)

, : , . , , , , push/pops . - / z3py?

+4
1

, , . , segfault.

Python Context , , , ( ). , , , .. , , , (. (...) AstRef ..).

. Z3? ​​ Z3?

+3

All Articles