minisat22_wrapper.py 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. from sympy.assumptions.cnf import EncodedCNF
  2. def minisat22_satisfiable(expr, all_models=False, minimal=False):
  3. if not isinstance(expr, EncodedCNF):
  4. exprs = EncodedCNF()
  5. exprs.add_prop(expr)
  6. expr = exprs
  7. from pysat.solvers import Minisat22
  8. # Return UNSAT when False (encoded as 0) is present in the CNF
  9. if {0} in expr.data:
  10. if all_models:
  11. return (f for f in [False])
  12. return False
  13. r = Minisat22(expr.data)
  14. if minimal:
  15. r.set_phases([-(i+1) for i in range(r.nof_vars())])
  16. if not r.solve():
  17. return False
  18. if not all_models:
  19. return {expr.symbols[abs(lit) - 1]: lit > 0 for lit in r.get_model()}
  20. else:
  21. # Make solutions SymPy compatible by creating a generator
  22. def _gen(results):
  23. satisfiable = False
  24. while results.solve():
  25. sol = results.get_model()
  26. yield {expr.symbols[abs(lit) - 1]: lit > 0 for lit in sol}
  27. if minimal:
  28. results.add_clause([-i for i in sol if i>0])
  29. else:
  30. results.add_clause([-i for i in sol])
  31. satisfiable = True
  32. if not satisfiable:
  33. yield False
  34. raise StopIteration
  35. return _gen(r)