pycosat_wrapper.py 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. from sympy.assumptions.cnf import EncodedCNF
  2. def pycosat_satisfiable(expr, all_models=False):
  3. import pycosat
  4. if not isinstance(expr, EncodedCNF):
  5. exprs = EncodedCNF()
  6. exprs.add_prop(expr)
  7. expr = exprs
  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. if not all_models:
  14. r = pycosat.solve(expr.data)
  15. result = (r != "UNSAT")
  16. if not result:
  17. return result
  18. return {expr.symbols[abs(lit) - 1]: lit > 0 for lit in r}
  19. else:
  20. r = pycosat.itersolve(expr.data)
  21. result = (r != "UNSAT")
  22. if not result:
  23. return result
  24. # Make solutions SymPy compatible by creating a generator
  25. def _gen(results):
  26. satisfiable = False
  27. try:
  28. while True:
  29. sol = next(results)
  30. yield {expr.symbols[abs(lit) - 1]: lit > 0 for lit in sol}
  31. satisfiable = True
  32. except StopIteration:
  33. if not satisfiable:
  34. yield False
  35. return _gen(r)