def min_sat(clauses, max_n=1000, N=None, alg='sorter', raise_on_max_n=False): """ Calculate the SAT solutions for the `clauses` for which the number of true literals from 1 to N is minimal. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. alg can be any algorithm supported by generate_constraints, or 'iterate", which iterates all solutions and finds the smallest. max_n is the maximum number of iterations the algorithm will run through. If raise_on_max_n=True, the function will raise MaximumIterationsError if max_n solutions were found. In other words, in this case, it is possible another minimal solution could be found if max_n were larger. """ log.debug("min_sat using alg: %s" % alg) try: import pycosat except ImportError: sys.exit('Error: could not import pycosat (required for dependency ' 'resolving)') if not clauses: return [] m = max(map(abs, chain(*clauses))) if not N: N = m if alg == 'iterate': min_tl, solutions = sys.maxsize, [] try: pycosat.itersolve({(1, )}) except TypeError: # Old versions of pycosat require lists. This conversion can be # very slow, though, so only do it if we need to. clauses = list(map(list, clauses)) i = -1 for sol, i in zip(pycosat.itersolve(clauses), range(max_n)): tl = sum(lit > 0 for lit in sol[:N]) # number of true literals if tl < min_tl: min_tl, solutions = tl, [sol] elif tl == min_tl: solutions.append(sol) log.debug("Iterate ran %s times" % (i + 1)) if i + 1 == max_n and raise_on_max_n: raise MaximumIterationsError("min_sat ran max_n times") return solutions else: solution = sat(clauses) if not solution: return [] eq = [(1, i) for i in range(1, N + 1)] def func(lo, hi): return list(generate_constraints(eq, m, [lo, hi], alg=alg)) evaluate_func = partial(evaluate_eq, eq) # Since we have a solution, might as well make use of that fact max_val = evaluate_func(solution) log.debug("Using max_val %s. N=%s" % (max_val, N)) constraints = bisect_constraints(0, min(max_val, N), clauses, func, evaluate_func=evaluate_func, increment=1000) return min_sat(list(chain(clauses, constraints)), max_n=max_n, N=N, alg='iterate')
def func(lo, hi): return list(generate_constraints([(1, i) for i in range(1, N+1)], m, [lo, hi], alg=alg))
def min_sat(clauses, max_n=1000, N=None, alg='sorter', raise_on_max_n=False): """ Calculate the SAT solutions for the `clauses` for which the number of true literals from 1 to N is minimal. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. alg can be any algorithm supported by generate_constraints, or 'iterate', which iterates all solutions and finds the smallest. max_n is the maximum number of iterations the algorithm will run through. If raise_on_max_n=True, the function will raise MaximumIterationsError if max_n solutions were found. In other words, in this case, it is possible another minimal solution could be found if max_n were larger. """ log.debug("min_sat using alg: %s" % alg) try: import pycosat except ImportError: sys.exit('Error: could not import pycosat (required for dependency ' 'resolving)') if not clauses: return [] m = max(map(abs, chain(*clauses))) if not N: N = m if alg == 'iterate': min_tl, solutions = sys.maxsize, [] try: pycosat.itersolve({(1,)}) except TypeError: # Old versions of pycosat require lists. This conversion can be # very slow, though, so only do it if we need to. clauses = list(map(list, clauses)) i = -1 for sol, i in zip(pycosat.itersolve(clauses), range(max_n)): tl = sum(lit > 0 for lit in sol[:N]) # number of true literals if tl < min_tl: min_tl, solutions = tl, [sol] elif tl == min_tl: solutions.append(sol) log.debug("Iterate ran %s times" % (i + 1)) if i + 1 == max_n and raise_on_max_n: raise MaximumIterationsError("min_sat ran max_n times") return solutions else: solution = sat(clauses) if not solution: return [] eq = [(1, i) for i in range(1, N+1)] def func(lo, hi): return list(generate_constraints(eq, m, [lo, hi], alg=alg)) evaluate_func = partial(evaluate_eq, eq) # Since we have a solution, might as well make use of that fact max_val = evaluate_func(solution) log.debug("Using max_val %s. N=%s" % (max_val, N)) constraints = bisect_constraints(0, min(max_val, N), clauses, func, evaluate_func=evaluate_func, increment=1000) return min_sat(list(chain(clauses, constraints)), max_n=max_n, N=N, alg='iterate')
if not N: N = m if alg == 'iterate': min_tl, solutions = sys.maxsize, [] <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD try: pycosat.itersolve({(1,)}) except TypeError: # Old versions of pycosat require lists. This conversion can be # very slow, though, so only do it if we need to. clauses = list(map(list, clauses)) i = -1 for sol, i in zip(pycosat.itersolve(clauses), range(max_n)): ======= for sol in islice(pycosat.itersolve(clauses), max_n): >>>>>>> conda/min_constraints ======= for sol in islice(pycosat.itersolve(clauses), max_n): >>>>>>> origin/min_constraints ======= for sol in islice(pycosat.itersolve(clauses), max_n): >>>>>>> princeofdarkness76/min_constraints ======= for sol in islice(pycosat.itersolve(clauses), max_n): >>>>>>> origin/min_constraints tl = sum(lit > 0 for lit in sol[:N]) # number of true literals if tl < min_tl: min_tl, solutions = tl, [sol]