z3 can solve optimisation problems using z3.Optimize. My goal is to apply it in the following way: Given a Boolean formula of propositional logic and a set of constraints, find all models that optimise the constraints, i.e. fulfil as many as possible. My ultimate goal is to select one of these models randomly.
Minimal example: Given the formula Or(x,y) and constraints Not(x) and Not(y), find the solutions [x: True, y: False] and [x: False, y: True].
While z3.Optimize.model() prints one optimal solution, it seems to be deterministic and to always print the solution [x: False, y: True]:
from z3 import * x, y = Bools('x y') s = Optimize() s.add(Or(x,y)) s.add_soft(Not(x), weight="1") s.add_soft(Not(y), weight="1") s.check() print(s.model()) When all_smt() provided by @alias is applied to this problem, list(all_smt(s, [x,y])) outputs:
[[x = False, y = True], [y = False, x = True], [y = True, x = True]] So all_smt() finds all solutions, including the non-optimal [x: True, y: True].
What is the best way to find all optimal solutions? Alternatively, is it possible to find an optimal solution in a random way without generating all optimal solutions first?