from sympy.assumptions.cnf import EncodedCNF def minisat22_satisfiable(expr, all_models=False, minimal=False): if not isinstance(expr, EncodedCNF): exprs = EncodedCNF() exprs.add_prop(expr) expr = exprs from pysat.solvers import Minisat22 # Return UNSAT when False (encoded as 0) is present in the CNF if {0} in expr.data: if all_models: return (f for f in [False]) return False r = Minisat22(expr.data) if minimal: r.set_phases([-(i+1) for i in range(r.nof_vars())]) if not r.solve(): return False if not all_models: return {expr.symbols[abs(lit) - 1]: lit > 0 for lit in r.get_model()} else: # Make solutions SymPy compatible by creating a generator def _gen(results): satisfiable = False while results.solve(): sol = results.get_model() yield {expr.symbols[abs(lit) - 1]: lit > 0 for lit in sol} if minimal: results.add_clause([-i for i in sol if i>0]) else: results.add_clause([-i for i in sol]) satisfiable = True if not satisfiable: yield False raise StopIteration return _gen(r)