def sat(self, additional=None, includeIf=False, names=False, limit=0): """ Calculate a SAT solution for the current clause set. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. """ if self.unsat: return None if not self.m: return set() if names else [] if additional: additional = list(map(lambda x: tuple(map(self.varnum, x)), additional)) clauses = chain(self.clauses, additional) else: clauses = self.clauses try: solution = pycosat.solve(clauses, vars=self.m, prop_limit=limit) except TypeError: # pycosat 0.6.1 should not require this; pycosat 0.6.0 did, but we # have made conda dependent on pycosat 0.6.1. However, issue #2276 # suggests that some people are still seeing this behavior even when # pycosat 0.6.1 is installed. Until we can understand why, this # needs to stay. I still don't want to invoke it unnecessarily, # because for large clauses lists it is slow. clauses = list(map(list, clauses)) solution = pycosat.solve(clauses, vars=self.m, prop_limit=limit) if solution in ("UNSAT", "UNKNOWN"): return None if additional and includeIf: self.clauses.extend(additional) if names: return set(nm for nm in (self.indices.get(s) for s in solution) if nm and nm[0] != '!') return solution
def check_interaction(self, c, f, random_features): """ A function, which checks if an interaction (1) can occure in at least one variant but (2) won't occure in every variant of a model given the provided list of constrains. Args: c (list): The model's constrains f (dict): The model's features random_features (list): The features, which were generated by the new_interactions function Returns: True, if the interaction can occure in at least one but not all variants False, if the interaction can't occure or if the features are dependent on eachother """ constrains = list(c) for elem in random_features: index = list(f.keys()).index(elem) constrains.append([index]) if pycosat.solve(constrains) == "UNSAT": return False constrains = list(c) index = list(-list(f.keys()).index(elem) for elem in random_features) constrains.append(index) if pycosat.solve(constrains) == "UNSAT": return False return True
def is_proper(self, sudoku): rules = self.get_rules(9) + sudoku sol = pycosat.solve(rules) rules.append([-x for x in sol if x > 0]) if pycosat.solve(rules) == "UNSAT": return True return False
def test_literal(self, literal): result = self.UNKNOWN if pycosat.solve(self.game.clauses + [[literal]]) == 'UNSAT': result = self.FALSE elif pycosat.solve(self.game.clauses + [[-literal]]) == 'UNSAT': result = self.TRUE return result
def sat_ibea_mutate(ind): # ICSE 2015 mutate settings decs = [i for i in ind] if random.random() < 0.98: # apply standard mutation for x in range(len(decs)): if random.random( ) < 0.001 and x not in dead and x not in mandatory: decs[x] = str(1 - int(decs[x])) else: if random.random() < 0.5: # apply smart mutation for x in range(len(decs)): if random.random( ) < 0.001 and x not in dead and x not in mandatory: decs[x] = str(1 - int(decs[x])) false_list = list() for c_i, c in enumerate(fm.cnfs): corr = False for x in c: if (x > 0 and decs[abs(x) - 1] == '1') or (x < 0 and decs[abs(x) - 1] == '0'): corr = True break if not corr: false_list.extend([abs(x) for x in c]) if len(false_list) > 0: cnf = copy.deepcopy(fm.cnfs) for i, v in enumerate(decs): if i in false_list: continue if v == '1': cnf.append([i + 1]) else: cnf.append([-i - 1]) for x in cnf: random.shuffle(x) random.shuffle(cnf) sol = pycosat.solve(cnf, vars=fm.featureNum) if sol != 'UNSAT': new_ind = fm.Individual(''.join( ['1' if i > 0 else '0' for i in sol])) return new_ind, else: # apply smart replacement cnf = copy.deepcopy(fm.cnfs) for x in cnf: random.shuffle(x) random.shuffle(cnf) sol = pycosat.solve(cnf, vars=fm.featureNum) if sol != 'UNSAT': new_ind = fm.Individual(''.join( ['1' if i > 0 else '0' for i in sol])) return new_ind, return fm.Individual(''.join(decs)),
def sat(self, additional=None, includeIf=False, names=False, limit=0): """ Calculate a SAT solution for the current clause set. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. """ if self.unsat: return None if not self.m: return set() if names else [] clauses = self.clauses if additional: def preproc(eqs): def preproc_(cc): for c in cc: c = self.names.get(c, c) if c is False: continue yield c if c is True: break for cc in eqs: cc = tuple(preproc_(cc)) if not cc: yield cc break if cc[-1] is not True: yield cc additional = list(preproc(additional)) if additional: if not additional[-1]: return None clauses = chain(clauses, additional) try: solution = pycosat.solve(clauses, vars=self.m, prop_limit=limit) except TypeError: # pycosat 0.6.1 should not require this; pycosat 0.6.0 did, but we # have made conda dependent on pycosat 0.6.1. However, issue #2276 # suggests that some people are still seeing this behavior even when # pycosat 0.6.1 is installed. Until we can understand why, this # needs to stay. I still don't want to invoke it unnecessarily, # because for large clauses lists it is slow. clauses = list(map(list, clauses)) solution = pycosat.solve(clauses, vars=self.m, prop_limit=limit) if solution in ("UNSAT", "UNKNOWN"): return None if additional and includeIf: self.clauses.extend(additional) if names: return set(nm for nm in (self.indices.get(s) for s in solution) if nm and nm[0] != '!') return solution
def sat(self, additional=None, includeIf=False, names=False, limit=0): """ Calculate a SAT solution for the current clause set. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. """ if self.unsat: return None if not self.m: return set() if names else [] clauses = self.clauses if additional: def preproc(eqs): def preproc_(cc): for c in cc: c = self.names.get(c, c) if c is False: continue yield c if c is True: break for cc in eqs: cc = tuple(preproc_(cc)) if not cc: yield cc break if cc[-1] is not True: yield cc additional = list(preproc(additional)) if additional: if not additional[-1]: return None clauses = chain(clauses, additional) try: solution = pycosat.solve(clauses, vars=self.m, prop_limit=limit) except TypeError: # pycosat 0.6.1 should not require this; pycosat 0.6.0 did, but we # have made conda dependent on pycosat 0.6.1. However, issue #2276 # suggests that some people are still seeing this behavior even when # pycosat 0.6.1 is installed. Until we can understand why, this # needs to stay. I still don't want to invoke it unnecessarily, # because for large clauses lists it is slow. clauses = list(map(list, clauses)) solution = pycosat.solve(clauses, vars=self.m, prop_limit=limit) if solution in ("UNSAT", "UNKNOWN"): return None if additional and includeIf: self.clauses.extend(additional) if names: return set(nm for nm in (self.indices.get(s) for s in solution) if nm and nm[0] != "!") return solution
def solve2(sudoku): clauses = sudoku_clauses() global petunjuk petunjukC = 0 for i in range(1, n1): for j in range(1, n1): d = sudoku[i - 1][j - 1] # untuk setiap given. if d: petunjukC += 1 petunjuk = petunjukC clauses.append([v(i, j, d)]) def read_cell(i, j): # mengembalikan i,j for d in range(1, n1): if v(i, j, d) in sol: return d # memulai SAT solver sol = set(pycosat.solve(clauses)) checker = len(sol) counter = 0 global solusi global jumSol temp = [] for i in range(n2): temp.append([]) for j in range(n2): temp[i].append(0) tempSol = temp if checker == 5: jumSol = counter return False while (checker != 5): if (counter == 100): break counter += 1 jumSol = counter for i in range(1, n1): for j in range(1, n1): tempSol[i - 1][j - 1] = read_cell(i, j) ShowBoard(tempSol) #solusi[].append(tempSol) tempSol = temp clauses.append([-x for x in sol]) sol = set(pycosat.solve(clauses)) checker = len(sol) return True
def solve(grid): #solve a Sudoku problem clauses = sudoku_clauses() for i in range(1, 10): for j in range(1, 10): d = grid[i - 1][j - 1] # For each digit already known, a clause (with one literal). if d: clauses.append([v(i, j, d)]) # Print number SAT clause numclause = len(clauses) print "P CNF " + str(numclause) +"(number of clauses)" # solve the SAT problem start = time.time() sol = set(pycosat.solve(clauses)) end = time.time() print("Time: "+str(end - start)) def read_cell(i, j): # return the digit of cell i, j according to the solution for d in range(1, 10): if v(i, j, d) in sol: return d for i in range(1, 10): for j in range(1, 10): grid[i - 1][j - 1] = read_cell(i, j)
def solve(sudoku_mat, sudoku_sz): # Setting params (size, size-square, root-size) set_params(sudoku_sz) # Adding all clauses to the list clause_set clause_set = sudoku_vals(sudoku_mat); for i in range(sudo_size): row_clause(i, clause_set) col_clause(i, clause_set) element_clause(clause_set) for i in range(sudo_size_sqrt): for j in range(sudo_size_sqrt): block_clause(i*sudo_size_sqrt,j*sudo_size_sqrt,clause_set) print len(clause_set) # We would also like to print a cnf file 'sudoku.cnf' of the clauses so we canconveniently use it with other SAT solvers outfile = file('sudoku.cnf','w') outfile.write('p cnf '+str(sudo_size**3)+' '+str(len(clause_set))) for clause in clause_set: string = '' for var in clause: string = string + str(var) + ' ' string = string[:-1] outfile.write('\n'+string+' 0') # Solving the sudoku using pycosat SAT solver for python, which is based on PicoSAT sol = set(pycosat.solve(clause_set)) # Editing the original matrix to reflect the solved sudoku def read_cell(i,j): for d in range(1,sudo_size+1): if v(i,j,d) in sol: return d for i in range(sudo_size): for j in range(sudo_size): sudoku_mat[i][j] = read_cell(i,j)
def sat(self, additional=None, includeIf=False, names=False, limit=0): """ Calculate a SAT solution for the current clause set. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. """ if self.unsat: return None if not self.m: return set() if names else [] if additional: additional = list(map(lambda x: tuple(map(self.varnum, x)), additional)) clauses = chain(self.clauses, additional) else: clauses = self.clauses clauses = list(clauses) solution = pycosat.solve(clauses, vars=self.m, prop_limit=limit) if solution in ("UNSAT", "UNKNOWN"): return None if additional and includeIf: self.clauses.extend(additional) if names: return set(nm for nm in (self.indices.get(s) for s in solution) if nm and nm[0] != '!') return solution
def get_combinations(nVars, clauses, size, outputfile, combs): feasibleCombs = [] allComb = [] start = time.time() if size == 1: allComb = [[x] for x in range(-nVars, 0)] + [[x] for x in range(1, nVars + 1)] else: literals = list(map(lambda x: x[0], combs[0])) for precomb in combs[ -1]: # expected to be sorted, add only literals with greater value first = bisect.bisect_right(literals, precomb[-1]) for l in range(first, len(literals)): if -(literals[l]) not in precomb: newComb = precomb[:] + [literals[l]] allComb.append(newComb) f = open(outputfile, "w") total = len(allComb) print("Total combinations to check " + str(total)) #print("Time to generate combinations to check " + str(time.time() - start)) curPerc = 0.0 for i in range(len(allComb)): comb = allComb[i] cnf = clauses[:] + list(map(lambda x: [x], comb)) s = pycosat.solve(cnf) if s != 'UNSAT': f.write(','.join(map(str, comb)) + '\n') feasibleCombs.append(comb) if i / total > curPerc + 0.05: curPerc += 0.05 print(str(round(100 * curPerc)) + "% done") f.close() print("Time to get satisfiable combinations " + str(time.time() - start)) return feasibleCombs
def pycoSAT(expr_list): """Check satisfiability of an expression list. Given a list of CNF expressions, returns a model that causes all input expressions to be true. Returns false if it cannot find a satisfible model. A model is simply a dictionary with Expr symbols as keys with corresponding values that are booleans: True if that symbol is true in the model and False if it is false in the model. Each CNF expression in the input list should be relatively short. Long expression will cause this method to become incredibly slow. Calls the pycosat solver: https://pypi.python.org/pypi/pycosat >>> ppsubst(pycoSAT([A&~B])) {A: True, B: False} >>> pycoSAT([P&~P]) False """ clauses = [] for expr in expr_list: clauses += conjuncts(expr) # Load symbol dictionary symbol_dict = mapSymbolAndIndices(clauses) # Convert Expr to integers clauses_int = exprClausesToIndexClauses(clauses, symbol_dict) model_int = pycosat.solve(clauses_int) if model_int == 'UNSAT' or model_int == 'UNKNOWN': return False model = indexModelToExprModel(model_int, symbol_dict) return model
def get_combinations_t(dimacs_, t_, outfile_, vlist_): # get list of features _features, _clauses, _vcount = read_dimacs(dimacs_) # get t wise combinations raw = combinations(vlist_, t_) raw = list(raw) f = open(outfile_, "w") # filter out combinations that are invalid j = 0 while raw: c = raw.pop() assigned = list(map(int, c)) aclause = [assigned[i:i + 1] for i in range(0, len(assigned))] cnf = _clauses + aclause s = pycosat.solve(cnf) if s != 'UNSAT': for i in range(0, len(c)): f.write(str(c[i])) if i < len(c)-1: f.write(",") f.write("\n") j += 1 # print progress if j % 10000 == 0: print(str(j)) f.close() return
def coloring(graph, k): clauses = to_sat(graph, k) rclauses = flatten(clauses, k) solution = pycosat.solve(rclauses) if solution == u'UNSAT': return solution return solution_colors(solution, k)
def get_satisfiability_percent(k, var_list, sign, clause_number, T): counter = 0 for i in range(0, T): cnf = generate_cnf(k, var_list, sign, clause_number) if pycosat.solve(cnf) != 'UNSAT': counter += 1 return counter / T
def solve_puzzle(puzzle): assert len(puzzle) == 9 assert all(len(row) == 9 for row in puzzle) clauses = [] clauses += one_digit_in_every_cell() clauses += one_digit_in_every_row() clauses += one_digit_in_every_column() clauses += one_digit_in_every_block() for row, column in product(range(1, 10), repeat=2): if puzzle[row - 1][column - 1] != "*": digit = int(puzzle[row - 1][column - 1]) assert digit in range(1, 10) clauses += [[varnum(row, column, digit)]] solution = pycosat.solve(clauses) if isinstance(solution, str): print("No solution") exit() assert isinstance(solution, list) for row in range(1, 10): for column in range(1, 10): for digit in range(1, 10): if varnum(row, column, digit) in solution: print(digit, end="") print()
def doesnt_entail_false(SD, a, w_tag): """ SD ∧ a ∧ w′ 6|=⊥ :param SD: The rules that defines the connection between the components :param a: The observation :param w_tag: The diagnosis :return: True IFF the above expression is satisfied """ cnf_model = SD.get_model_cnf() healthy = w_tag[0] non_healthy = w_tag[1] for comp in healthy: cnf_model.append([comp.get_health().get_id()]) for comp in non_healthy: cnf_model.append([-1 * (comp.get_health().get_id())]) for observation in a: cnf_model.append([observation]) sol = sat_solver.solve(cnf_model) if sol == 'UNSAT': return False return True
def inconsistency_degree(knowledge_base_wc, clause): """ Return the inconsistency degree of knowledge_base_wc union the negation of clause using the refutation. :param knowledge_base_wc: A WeightedKnowledgeBase (Sigma). :param clause: A list containing variables (Phi). :return: The value of inconsistency Val(Sigma U neg(Phi)). """ assert isinstance(knowledge_base_wc, WeightedKnowledgeBase) r = 0 # Just an initialisation l = 0 u = len(knowledge_base_wc) while l < u: r = (l + u) // 2 # Integer division print('u =', u, 'l =', l, 'r =', r) union = [list(x) for x in knowledge_base_wc[r:u]] + negation(clause) print(_union_msg, union) results = pycosat.solve(union) print(_results_msg, results) if isinstance(results, list): # Picosat found a solution u = r - 1 else: l = r print() return knowledge_base_wc[r][0].weight # Weight of the clause
def solve(grid): """ solve a Sudoku grid inplace """ clauses = sudoku_clauses() for i in range(1, 10): for j in range(1, 10): d = grid[i - 1][j - 1] # For each digit already known, a clause (with one literal). # Note: # We could also remove all variables for the known cells # altogether (which would be more efficient). However, for # the sake of simplicity, we decided not to do that. if d: clauses.append([v(i, j, d)]) # solve the SAT problem start = time.clock() sol = set(pycosat.solve(clauses)) t = time.clock() - start print 'pycosat clauses:', len(clauses), ' solution time:', t def read_cell(i, j): # return the digit of cell i, j according to the solution for d in range(1, 10): if v(i, j, d) in sol: return d for i in range(1, 10): for j in range(1, 10): grid[i - 1][j - 1] = read_cell(i, j)
def SR(n): cnf = CNF(n) sat = True while sat: # Select a random k ~ Bernouilli(0.3) + Geo(0.4) k = np.random.binomial(1, 0.4) + np.random.geometric(0.4) # Create a clause with k randomly selected variables clause = [ int(np.random.randint(1, n + 1) * np.random.choice([-1, +1])) for i in range(k) ] # Append clause to cnf cnf.clauses.append(clause) # Check for satisfiability if pycosat.solve(cnf.clauses) == "UNSAT": sat = False # Create an identical copy of cnf cnf2 = copy.deepcopy(cnf) # Flip the polarity of a single literal in the last clause of cnf2 cnf2.clauses[-1][np.random.randint(0, len( cnf2.clauses[-1]))] *= -1 #end #end cnf.sat = False cnf2.sat = True cnf.m = cnf2.m = len(cnf.clauses) return cnf, cnf2
def sat(clauses): """ Calculate a SAT solution for `clauses`. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. """ try: import pycosat except ImportError: sys.exit('Error: could not import pycosat (required for dependency ' 'resolving)') 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)) solution = pycosat.solve(clauses) if solution == "UNSAT" or solution == "UNKNOWN": # wtf https://github.com/ContinuumIO/pycosat/issues/14 return [] # XXX: If solution == [] (i.e., clauses == []), the result will have # boolean value of False even though the clauses are not unsatisfiable) return solution
def solved(game): cnf = cnf_encoding(game) sol = pycosat.solve(cnf) n = game[0] m = game[1] k = game[2] game_sze = (n, m, k) solved_table = [] for i in range(n): row = [] for j in range(m): row.append(0) solved_table.append(row) cur_vtx = cell_to_vertex(game_sze, game[3]) row, column = vertex_to_cell(game_sze, cur_vtx) solved_table[row][column] = 1 for i in range(n * m - 1): nbhs = vertex_nbhs(game_sze, cur_vtx) for nbh in nbhs: if sol[exactly_before(game_sze, cur_vtx, nbh) - 1] > 0: nbh_r, nbh_c = vertex_to_cell(game_sze, nbh) solved_table[nbh_r][nbh_c] = i + 2 next_vtx = nbh cur_vtx = next_vtx return solved_table
def pycoSAT(expr): """Check satisfiability of an expression. Given a CNF expression, returns a model that causes the input expression to be true. Returns false if it cannot find a satisfible model. A model is simply a dictionary with Expr symbols as keys with corresponding values that are booleans: True if that symbol is true in the model and False if it is false in the model. Calls the pycosat solver: https://pypi.python.org/pypi/pycosat >>> ppsubst(pycoSAT(A&~B)) {A: True, B: False} >>> pycoSAT(P&~P) False """ assert is_valid_cnf(expr), "{} is not in CNF.".format(expr) clauses = conjuncts(expr) # Load symbol dictionary symbol_dict = mapSymbolAndIndices(clauses) # Convert Expr to integers clauses_int = exprClausesToIndexClauses(clauses, symbol_dict) model_int = pycosat.solve(clauses_int) if model_int == 'UNSAT' or model_int == 'UNKNOWN': return False model = indexModelToExprModel(model_int, symbol_dict) return model
def satPhaseTransition(n: int, k: int, T: int): S = [1, -1] V = range(1, n + 1) def randVar(): return random.choice(V) * random.choice(S) def genFormula(clausesNumber: int): return [[randVar() for _ in range(k)] for _ in range(clausesNumber)] inverse_step = 10 xs, ys = [], [] for i in range(1, 10 * inverse_step): a = (1 + i / inverse_step) clausesNumber = int(a * n) satisfiable = 0 for _ in range(T): formula = genFormula(clausesNumber) if pycosat.solve(formula) != u'UNSAT': satisfiable += 1 res = satisfiable / T xs.append(a) ys.append(res) print(a, res) plt.plot(xs, ys) plt.show()
def solve(sudoku, size_block, clauses): size = size_block**2 for i in range(1, size + 1): for j in range(1, size + 1): d = int(sudoku[(i - 1) * size + (j - 1)]) # For each digit already known, a clause (with one literal). if d: clauses.append([v(i, j, d, size_block)]) # solve the SAT problem sol = pycosat.solve(clauses) if sol == 'UNSAT' or sol == 'UNKNOWN' or not sol['solved']: print("Picosat unsuccessful: ", sol) return {'solved': False} sol_clauses = sol['clauses'] def read_cell(i, j): # return the digit of cell i, j according to the solution for d in range(1, size + 1): if v(i, j, d, size_block) in sol_clauses: return d sol_sudoku = [0 for i in range(size**2)] for i in range(1, size + 1): for j in range(1, size + 1): sol_sudoku[(i - 1) * size + (j - 1)] = read_cell(i, j) sol['solution'] = sol_sudoku return sol
def sat_solve(list_formulas): import pycosat solve = pycosat.solve(pycosat_input(list_formulas)) if type(solve) == list: print(list(filter(lambda x: x > 0, solve))) else: print(solve)
def query(self, literal): """ Query the KB to see if literal is satisfiable with it Returns solution (list of assignments) if (KB and literal) is satisfiable Returns "UNSAT" if (KB AND literal) is unsatisfiable Returns "UNKNOWN" if pycosat cannot determine a solution If KB and M(i, j) is unsatisfiable, then cell (i. j) is not a mine If KB and not M(i, j) is unsatisfiable, then cell (i. j) is a mine Note that the literal itself will have the truth value in it's .mine field. """ # If knowledgebase doesnt know about this literal, return IDK if (literal.i, literal.j) not in self.literals: return "IDK" # Create a copy of the KB to query against. query_cnf = list.copy(self.idx_representation) # Add the query literal to the copy query_cnf.append([literal.get_idx_representation()]) # Is the copy of the KB satisfiable? return pycosat.solve(query_cnf)
def main (): killerRules = readSudoku(sys.argv[1]) cnf = encode_to_cnf(killerRules) # #solve the encoded CNF start = time.time() result_list = pycosat.solve(cnf) end = time.time() #output the result # print result_list if result_list == 'UNSAT': print 'UNSAT' elif result_list !=[]: # print '\n\nFor a this killer sudoku, ', # print_matrix(matrix) result_matrix = decode_to_matrix(result_list) # uncomment these two lines if you want to print the sudoku # print 'one of the solutions found is\n' # print_matrix(result_matrix) if (verify_killer_sudoku(killerRules, result_matrix)): # print 'yes, it is a valid answer!' print 'CORRECT %04.5f %d %d'% ((end-start), countCNF_ari, countCNF_all) else: print 'ERROR' # print 'no, it is not a valid answer' else: print 'SYSTEM ERROR'
def solve(grid): #solve a Sudoku problem clauses = sudoku_clauses() for i in range(1, 10): for j in range(1, 10): d = grid[i - 1][j - 1] # For each digit already known, a clause (with one literal). if d: clauses.append([v(i, j, d)]) # Print number SAT clause numclause = len(clauses) print "P CNF " + str(numclause) + "(number of clauses)" # solve the SAT problem start = time.time() sol = set(pycosat.solve(clauses)) end = time.time() print("Time: " + str(end - start)) def read_cell(i, j): # return the digit of cell i, j according to the solution for d in range(1, 10): if v(i, j, d) in sol: return d for i in range(1, 10): for j in range(1, 10): grid[i - 1][j - 1] = read_cell(i, j)
def Exercise36misunderstood(): # 2 parts: first of all, how do I assert 2 nodes differ by k colors? # second, find all 3+cliques. For each u-v, if v is in a 3+clique with u, assert 1 diff, else assert 2 diff d = 10 n = 3 graphColorer = GraphColoring(nodeDict=McGregor(n, d).nodeDict, d=d, adjacentDifColor=0, minColors=1) graphColorer.defineNodeLiteralConversion(\ literalToID=(lambda x: (((x - 1) % (n + 1) ** 2) // (n + 1), (x - 1) % (n + 1))), literalToColor= (lambda x: (x-1) // (n+1)**2), GraphNodeToLiteral= (lambda indexTuple, color: indexTuple[0] * (n + 1) + indexTuple[1] + ((n + 1) ** 2) * color + 1)) graphColorer.generateClauses() for i, A in enumerate(graphColorer.nodeDict): for j, B in enumerate(graphColorer.nodeDict): if j <= i: continue if graphColorer.sharesNeighbor(A, B): if graphColorer.isAdjacent(A, B): graphColorer.assertRdiffColors(A, B, 1) else: graphColorer.assertRdiffColors(A, B, 2) pp.pprint(graphColorer.clauses) pp.pprint(list(pycosat.solve(graphColorer.clauses))) graphColorer.viewSolution()
def solve(self): """ Résoudre la grille, dessiner la solution et afficher le résultat dans le champs de texte prévu pour. """ # Rendre la grille non modifiable une fois qu'elle a été résolue self.tag_unbind("cell", "<ButtonPress-1>") # Afficher un message des fois que la recherche d'une solution mette # un peu de temps self.solvable_textvar.set("Looking for solution...") # rendre solides toutes les cases qui ne sont pas dans une zone ou solides self.dtag("selected", "selected") self.addtag_withtag("selected", "blank") self.toggle_selection_solid() # Générer les clauses cnf = gen_cnf( self.dimensions[0], self.dimensions[1], self.zones, self.black_cells ) # Convertir les clauses en 3-sat cnf = sat_3sat(cnf, self.dimensions[1], self.dimensions[0]) # Trouver une solution solution = sat.solve(cnf) # Si une solution a été trouvée, l'afficher et mettre à jour le texte if not (solution == "UNSAT" or solution == "UNKNOWN"): self.draw_solution(solution) self.solvable_textvar.set("Solution found!") # Sinon, juste mettre a jour le texte else: self.solvable_textvar.set("No solution found!")
def solve_sat(options, puzzle, colors, color_var, dir_vars, clauses): '''Solve the SAT now that it has been reduced to a list of clauses in CNF. This is an iterative process: first we try to solve a SAT, then we detect cycles. If cycles are found, they are prevented from recurring, and the next iteration begins. Returns the SAT solution set, the decoded puzzle solution, and the number of cycle repairs needed. ''' start = datetime.now() decoded = None all_decoded = [] repairs = 0 while True: sol = pycosat.solve(clauses) # pylint: disable=E1101 if not isinstance(sol, list): decoded = None all_decoded.append(decoded) break decoded = decode_solution(puzzle, colors, color_var, dir_vars, sol) all_decoded.append(decoded) extra_clauses = detect_cycles(decoded, dir_vars) if not extra_clauses: break clauses += extra_clauses repairs += 1 solve_time = (datetime.now() - start).total_seconds() if not options.quiet: if options.display_cycles: for cycle_decoded in all_decoded[:-1]: print 'intermediate solution with cycles:' print show_solution(options, colors, cycle_decoded) print if decoded is None: print 'solver returned {} after {:,} cycle '\ 'repairs and {:.3f} seconds'.format( str(sol), repairs, solve_time) else: print 'obtained solution after {:,} cycle repairs '\ 'and {:.3f} seconds:'.format( repairs, solve_time) print show_solution(options, colors, decoded) print return sol, decoded, repairs, solve_time
def solve(grid): """ solve a Sudoku grid inplace """ clauses = sudoku_clauses() for i in range(1, 10): for j in range(1, 10): d = grid[i - 1][j - 1] # For each digit already known, a clause (with one literal). # Note: # We could also remove all variables for the known cells # altogether (which would be more efficient). However, for # the sake of simplicity, we decided not to do that. if d: clauses.append([v(i, j, d)]) # solve the SAT problem # verbose = 1 --> see statistics (@ terminal, TBD: get statistics in python) sol = set(pycosat.solve(clauses, verbose=1, vars=729)) def read_cell(i, j): # return the digit of cell i, j according to the solution for d in range(1, 10): if v(i, j, d) in sol: return d for i in range(1, 10): for j in range(1, 10): grid[i - 1][j - 1] = read_cell(i, j) return sol
def sat(clauses): """ Calculate a SAT solution for `clauses`. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. """ try: import pycosat except ImportError: sys.exit('Error: could not import pycosat (required for dependency ' 'resolving)') 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)) solution = pycosat.solve(clauses) if solution == "UNSAT" or solution == "UNKNOWN": # wtf https://github.com/ContinuumIO/pycosat/issues/14 return [] # XXX: If solution == [] (i.e., clauses == []), the result will have # boolean value of False even though the clauses are not unsatisfiable) return solution
def sat(self, formula=None): if formula: added_clause, new_atoms = self._add(formula) ret = pycosat.solve(self.cnfs) if formula: self._roll_back(added_clause, new_atoms) # FIXME return ret not in ('UNSAT', 'UNKNOWN')
def solve_nqueen(board, NUM_ROWS, NUM_COLUMNS): nqueen_clauses = get_nqueen_clauses(NUM_ROWS, NUM_COLUMNS) solution = set(pycosat.solve(nqueen_clauses)) for row in range(1,NUM_ROWS+1): for column in range(1,NUM_COLUMNS+1): board[row-1][column-1] = get_cell_solution(solution,row, column)
def py_itersolve(clauses): while True: sol = pycosat.solve(clauses) if isinstance(sol, list): yield sol clauses.append([-x for x in sol]) else: # no more solutions -- stop iteration return
def solve(self): solution = pycosat.solve(self.clauses) if solution == 'UNSAT': return 'UNSAT' else: #print solution solution = [x for x in solution if -x not in self.all_units] solution.extend(list(self.all_units)) return sorted(list(set(solution)), key=abs)
def _solve_sat(self,cnf): """ Calls the SAT solver. """ start = time.time() sol = pycosat.solve(cnf) elapsed = time.time()-start if self.verbose: print('\t- Took %.3f ms to solve SAT problem.'%(1000.0*elapsed)) return sol
def solve(n): global N N = n clauses = queens_clauses() # solve the SAT problem sol = set(pycosat.solve(clauses)) for i in range(N): print ''.join('Q' if v(i, j) in sol else '.' for j in range(N)) print n, len(clauses)
def solution(self): """ Return arbitrary solution to the currently described satisfiability problem. """ solution = pycosat.solve(self.clauses) if solution == "UNSAT": raise UnsatisfiableConstraints("Constraints are unsatisfiable") elif solution == "UNKNOWN": raise SolutionNotFound("Search limits exhausted without solution") else: return self.remap_solution(solution)
def proper(self): global baseClauses totalClauses = baseClauses + self.givens_to_dimacs_list() sol = set(pycosat.solve(totalClauses)) def read_cell(i, j): for d in range(1, 10): if v(i, j, d) in sol: return [v(i, j, d),d] negation = [] for i in range(1, 10): for j in range(1, 10): negation.append(-read_cell(i, j)[0]) totalClauses.append(negation) res = pycosat.solve(totalClauses) if res == "UNSAT": return 1 else: return 0
def solve_sudoku(sudoku_board): """ Generate a sudoku clauses, apply in a pycosat and get sudoku solution """ sudoku_clauses = get_sudoku_clauses() single_clauses = get_single_clauses(sudoku_board) sudoku_clauses.extend(single_clauses) sudoku_solution = set(pycosat.solve(sudoku_clauses)) for row in range(1, NUM_DIGITS+1): for column in range(1, NUM_DIGITS+1): sudoku_board[row-1][column-1] = get_cell_solution( sudoku_solution, row, column) return sudoku_board
def sat(clauses, iterator=False): """ Calculate a SAT solution for `clauses`. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. """ if pycosat_prep: clauses = list(map(list,clauses)) if iterator: return pycosat.itersolve(clauses) solution = pycosat.solve(clauses) if solution == "UNSAT" or solution == "UNKNOWN": return None return solution
def sat(clauses): """ Calculate a SAT solution for `clauses`. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. """ try: import pycosat except ImportError: sys.exit('Error: could not import pycosat (required for dependency ' 'resolving)') solution = pycosat.solve(clauses) if solution == "UNSAT" or solution == "UNKNOWN": # wtf https://github.com/ContinuumIO/pycosat/issues/14 return [] return solution
def sat(self, additional=None, includeIf=False, names=False, limit=0): """ Calculate a SAT solution for the current clause set. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. """ if self.unsat: return None if not self.m: return set() if names else [] clauses = self.clauses if additional: def preproc(eqs): def preproc_(cc): for c in cc: c = self.names.get(c, c) if c is False: continue yield c if c is True: break for cc in eqs: cc = tuple(preproc_(cc)) if not cc: yield cc break if cc[-1] is not True: yield cc additional = list(preproc(additional)) if additional: if not additional[-1]: return None clauses = tuple(chain(clauses, additional)) log.debug("Invoking SAT with clause count: %s", len(clauses)) solution = pycosat.solve(clauses, vars=self.m, prop_limit=limit) if solution in ("UNSAT", "UNKNOWN"): return None if additional and includeIf: self.clauses.extend(additional) if names: return set(nm for nm in (self.indices.get(s) for s in solution) if nm and nm[0] != '!') return solution
def solve(grid,n): clauses = sudoku_clauses(n) for i in range(1, n+1): for j in range(1, n+1): d = grid[i - 1][j - 1] if d: clauses.append([v(i, j, d,n)]) # solve the SAT problem need sol = set(pycosat.solve(clauses)) def read_cell(i, j): # return the digit of cell i, j according to the solution for d in range(1, n+1): if v(i, j, d,n) in sol: return d for i in range(1, n+1): for j in range(1, n+1): grid[i - 1][j - 1] = read_cell(i, j)
def runSatoku(n): global id global lid id = {} lid = [''] start = time.clock() cnf = satokuCNF(n) cTime = (time.clock() - start) start = time.clock() sol = sat.solve(cnf) basTime = (time.clock() - start) if type(sol) == type([]): solExists = True else: solExists = False print ' satoku solution:', solExists, ' clauses:', len(cnf), ' construction time:', cTime, ' solution time:', basTime if(solExists): sud = satToSatoku(sol, n)
def runBasic(n): global id global lid id = {} lid = [''] start = time.clock() basic = basicCNF(n) cTime = (time.clock() - start) start = time.clock() basSol = sat.solve(basic) basTime = (time.clock() - start) if type(basSol) == type([]): basSolExists = True else: basSolExists = False print ' basic solution:', basSolExists, ' clauses:', len(basic), ' construction time:', cTime, ' solution time:', basTime if(basSolExists): sud = satToSud(basSol, n)
def test_sat(index): r = Resolve2(index) r.create_var_map() clauses = r.get_clauses() clauses.append(None) a_versions = set() for fn in sorted(index): name, version, build = nvb_fn(fn) if name != 'anaconda' or version < '1.5': continue a_versions.add(version) clauses[-1] = [r.v[fn]] sol = pycosat.solve(clauses) print fn, 'SAT' if isinstance(sol, list) else sol if not isinstance(sol, list): r.show_inconsistencies(fn) print 'size index', len(index) for es in [ ['numpy 1.7*', 'python 2.7*', 'conda'], ['numpy 1.7*', 'python 2.7*'], ['numpy 1.7*', 'python 2.6*'], ['numpy 1.7*', 'python 3.3*'], ['numpy 1.6*', 'python 2.7*'], ['numpy 1.6*', 'python 2.6*'], ]: for a_version in sorted(a_versions): specs = ['anaconda %s' % a_version] specs.extend(es) for features in set(), set(['mkl']): print specs, features r.msd_cache = {} try: assert r.solve(specs, features=features) except RuntimeError: print 'UNSAT'
def solve_sudoku(sudoku_grid, sudoku_clauses): ''' This method receive a sudoku grid an solve it using a sat solver. :param sudoku_grid: A 9 X 9 grid representing a sudoku game. :param sudoku_clauses: An array containing all the possible clauses for the sudoki board. :return: A 9 x 9 grid representing a sudoku solution for the given board. ''' single_clauses = get_single_clauses(sudoku_grid) sudoku_clauses.extend(single_clauses) sudoku_solution = set(pycosat.solve(sudoku_clauses)) for row in range(1, DIGITS + 1): for column in range(1, DIGITS + 1): sudoku_grid[row - 1][column - 1] = get_cell_solution( sudoku_solution, row, column) return sudoku_grid
def test_cnf3(self): self.assertEqual(solve(clauses3), [-1, -2])
def test_cnf1_prop_limit(self): for lim in range(1, 20): self.assertEqual(solve(clauses1, prop_limit=lim), "UNKNOWN" if lim < 8 else [1, -2, -3, -4, 5])
def test_cnf3_3vars(self): self.assertEqual(solve(clauses3, vars=3), [-1, -2, -3])
def test_cnf1_vars(self): self.assertEqual(solve(clauses1, vars=7), [1, -2, -3, -4, 5, -6, -7])