Getting all solutions of a boolean expression in Z3Py never ends

风格不统一 提交于 2021-02-05 08:43:05

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!