问题
Probably a basic question related to Z3: i am trying to get all solutions of a boolean expression, e.g. for a OR b
, i want to get {(true, true),(false,true),(true,false)}
Based on other responses found, e.g. Z3: finding all satisfying models, i have the following code:
a = Bool('a')
b = Bool('b')
f1=Or(a,b)
s=Solver()
s.add(f1)
while s.check() == sat:
print s
s.add(Not(And(a == s.model()[a], b == s.model()[b])))
The issue is that it enters an infinite loop as at the second iteration: the constraint a == s.model()[a]
is evaluated to false b/c s.model()[a]
does not exist anymore.
Can someone tell what i am doing wrong?
回答1:
I would advice you to try writing your loop like this instead:
from z3 import *
a = Bool('a')
b = Bool('b')
f1 = Or(a,b)
s = Solver()
s.add(f1)
while s.check() == sat:
m = s.model()
v_a = m.eval(a, model_completion=True)
v_b = m.eval(b, model_completion=True)
print("Model:")
print("a := " + str(v_a))
print("b := " + str(v_b))
bc = Or(a != v_a, b != v_b)
s.add(bc)
The output is:
Model:
a := True
b := False
Model:
a := False
b := True
Model:
a := True
b := True
The argument model_completion=True
is necessary because otherwise m.eval(x)
behaves like the identity relation for any x
Boolean variable with a don't care value in the current model m
and it returns x
as a result instead of True/False
. (See related Q/A)
NOTE: since z3
kindly marks don't care Boolean variables, an alternative option would be to write your own model generator that auto-completes any partial model. This would reduce the number of calls to s.check()
. The performance impact of this implementation is hard to gauge, but it might be slightly faster.
来源:https://stackoverflow.com/questions/60866787/getting-all-solutions-of-a-boolean-expression-in-z3py-never-ends