I ran into a problem where Z3Py does not enumerate all possible solutions for the given Boolean clauses. I was wondering if anyone knows why this is happening.
Here
Note that a model will only contain assignments to variables that do matter in the sat
outcome. Any variable that doesn't matter will not get assigned explicitly. To avoid this problem, loop over the variables in your domain and use the parameter model_completion=True
to the eval
method, like this:
from z3 import *
a,b,c,d,e = Bools('1 2 3 4 5')
solver = Solver()
solver.add(Or(Not(a), Not(b)))
solver.add(Or(Not(b), Not(c)))
solver.add(Or(Not(c), Not(d)))
solver.add(Or(Not(d), Not(e)))
while solver.check() == sat:
model = solver.model()
block = []
solution = []
for var in [a, b, c, d, e]:
v = model.eval(var, model_completion=True)
block.append(var != v)
solution.append(str(var) if is_true(v) else '-' + str(var))
solver.add(Or(block))
solution.sort()
print(solution)
This prints:
['-1', '-2', '-3', '-4', '-5']
['-2', '-3', '-4', '-5', '1']
['-2', '-3', '-5', '1', '4']
['-1', '-2', '-3', '-5', '4']
['-1', '-2', '-3', '-4', '5']
['-1', '-2', '-4', '3', '5']
['-2', '-4', '-5', '1', '3']
['-2', '-4', '1', '3', '5']
['-2', '-3', '-4', '1', '5']
['-1', '-3', '-4', '2', '5']
['-1', '-3', '-4', '-5', '2']
['-1', '-2', '-4', '-5', '3']
['-1', '-3', '-5', '2', '4']
which I believe is what you're looking for.
The other thing is that not all the solutions in Z3Py contain all the defined variables.
That means that the unmentioned variables do not affect the result. So having ['-2', '-4', '3', '5']
as a solution is equivalent to having both ['1', '-2', '-4', '3', '5']
and ['-1', '-2', '-4', '3', '5']
.
If you take that into account when comparing the solutions, the sets of solutions provided by both solvers are equivalent.