def original_solver(constraints): variables = {} def get_variable(name): if name in variables: var = variables[name] else: var = Variable(name) variables[name] = var return var exp = Cnf() for constraint in constraints: a, b, c = constraint x_1 = get_variable('%s<%s' % (a, c)) x_2 = get_variable('%s<%s' % (c, a)) x_3 = get_variable('%s<%s' % (b, c)) x_4 = get_variable('%s<%s' % (c, b)) exp &= (x_1 | x_2) & (x_3 | x_4) & (-x_1 | -x_4) & (-x_2 | -x_3) solver = Minisat() solution = solver.solve(exp) valid = [] if solution.success: for var in variables: key = variables[var] if solution[key]: valid.append(var) else: print('No solution') return [] return valid
def solve(self): # Build CNF cnf = Cnf() for clause in self.formula: # Build DNF dnf = Cnf() for literal in clause: # Get variable using literal index variable = self.variables[literal / 2] # Again, negate variable as described above dnf |= variable if literal % 2 == 0 else -variable # Append DNF clause cnf &= dnf solver = Minisat() solution = solver.solve(cnf) # TODO: consider external representation for 'formula' if solution.success: self.solution = [(i, solution[self.variables[i]]) for i in self.variablesInFormula] else: self.solution = [] return self.solution
def __init__(self, instance): self._instance = instance self.global_expr = Cnf() #self.solver = Minisat('minisat %s %s') self.solver = Minisat()
def test_sat_basic(self): """Tests the case when Dumbledore is not between Harry and Hermione and Harry is not between Dumbledore and Hermione. So Dumbledore > Hermione > Harry.""" cnf = sat.reduce_satispy([("Hermione", "Harry", "Dumbledore"), ("Hermione", "Dumbledore", "Harry")]) solver = Minisat() solution = solver.solve(cnf) if not solution.success: self.fail( "SAT failed to return a solution! This should not happen...") true_literals = [ "Harry < Dumbledore", "Hermione < Dumbledore", "Harry < Dumbledore", "Harry < Hermione" ] false_literals = [ "Dumbledore < Harry", "Dumbledore < Hermione", "Dumbledore < Harry", "Hermione < Harry" ] for lit in true_literals: self.assertTrue(solution[lit]) for lit in false_literals: self.assertFalse(solution[lit])
def _solve(systemConstraints, entityConstraints): options = [] for opt in systemConstraints: if not opt: continue options.append(opt) domain = opt + "=" + "Variable('" + opt + "')" exec(domain) solver = Minisat() entityConstraintsStr = "&".join(entityConstraints) output = solver.solve(eval(entityConstraintsStr)) if output.error: raise SystemExit("Solver error!") if not output.success: return [] testCase = {} for opt in output.varmap: result = output.varmap[opt] testCase[ opt. name] = "(" + opt.name + ")" if result else "(-" + opt.name + ")" for opt in options: if opt not in testCase: randBool = bool(randint(0, 1)) testCase[opt] = "(" + opt + ")" if randBool else "(-" + opt + ")" solution = testCase.values() return solution
def synthesize(S_plus, S_minus, k): """Infers an NFA A consistent with the sample Input: the sets of examples and counter-examples, k > 0 Output: a k-states NFA or None""" formula, y, z = encode(S_plus, S_minus, k) solver = Minisat() sol = solver.solve(formula) return decode(sol, y, z, k) if sol.success else None
def generate_test_suite(conditions: list, expressions: list): """ :param conditions: list of conditions in string form :param expressions: list of boolean expression corresponding to each condition existing :return: returns list of lists containing row values for test suite table """ expression_problems = list() for c in conditions: if c.count('-') > 0: # if there is any don't care condition expanded_conditions = expand_all_conditions([c]) rule_expression = "" for exp_c in expanded_conditions: for char_index in range(len(exp_c)): if exp_c[char_index] == 'T': # condition is true rule_expression += "(" + expressions[char_index] + ") & " elif exp_c[char_index] == 'F': # condition is false rule_expression += "-(" + expressions[char_index] + ") & " rule_expression += "(" + rule_expression[:-3] + ") | " expression_problems.append(rule_expression[:-3]) else: # there is no don't care condition rule_expression = "" for char_index in range(len(c)): if c[char_index] == 'T': # condition is true rule_expression += "(" + expressions[char_index] + ") & " elif c[char_index] == 'F': # condition is false rule_expression += "-(" + expressions[char_index] + ") & " expression_problems.append(rule_expression[:-3]) solver = Minisat() symbols = dict() table = list() for p in range(len(expression_problems)): exp, symbols = CnfFromString.create(expression_problems[p]) solution = solver.solve(exp) rule_name = "r" + str(p + 1) boolean_values = [rule_name] if solution.success: for symbol_name in sorted(symbols.keys()): boolean_values.append(str(solution[symbols[symbol_name]])[0]) table.append(boolean_values) # use this line if you want not to generate test suite for non-unique rules # if p + 1 not in discarded_conditions: # table.append(boolean_values) headers = ["rules"] + sorted(symbols.keys()) print(tabulate(table, headers, tablefmt="fancy_grid"))
def rev_step(x): exp = satify_bit(x & 1, vs[0], vs[1], vs[2]) for i in range(1, N): exp = exp & satify_bit( (x >> i) & 1, vs[i], vs[(i + 1) % N], vs[(i + 2) % N]) return sat_to_number(Minisat().solve(exp), vs)
def list_all(expr, verbose = True): solutions = [] solver = Minisat() solution = solver.solve(expr) while solution.success: for v in solution.varmap: if solution[v] and verbose: print(v, end=" ", flush = True) expr = expr & -cnf_and([x if solution.varmap[x] else -x for x in solution.varmap]) solution = solver.solve(expr) str_solution = {c.name: solution.varmap[c] for c in solution.varmap} solutions.append(str_solution) if verbose: print() else: print("No more solutions") return solutions
def reversedStep(x): variables = [] for i in range(N): variables.append(Variable(str(i))) exp = Variable('None') for i in range(N): if (x >> i) & 1: exp &= (variables[i] & -variables[(i + 1) % N] & -variables[(i + 2) % N]) | (-variables[i] & variables[(i + 1) % N]) | (-variables[i] & variables[(i + 2) % N]) else: exp &= (-variables[i] & -variables[(i + 1) % N] & -variables[(i + 2) % N]) | (variables[i] & variables[(i + 1) % N]) | (variables[i] & variables[(i + 2) % N]) solver = Minisat() solution = solver.solve(exp) if solution.success: return arrayToInt(solution, variables)
def solve(eq): solution = Minisat().solve(eq) assert solution.success and not solution.error, 'ERR: Failed to solve' result = 1 << N - 1 if solution[Variable('0')] else 0 for i in range(1, N): result |= 1 << i - 1 if (solution[Variable(str(i))]) else 0 return result
def generate(numVariables, k, numClauses): # TODO: assert numVariables < k * numClauses? # Total number of possible literals numLiterals = 2 * numVariables # Literal 2n represents variable n, whereas literal (2n + 1) represents variable -n formula = [sample(range(numLiterals), k) for _ in range(numClauses)] # Get total number of variables actually used in formula variablesInFormula = set([literal / 2 for clause in formula for literal in clause]) variables = [Variable(str(i)) for i in range(numVariables)] # Build CNF cnf = Cnf() for clause in formula: # Build DNF dnf = Cnf() for literal in clause: # Get variable using literal index variable = variables[literal / 2] # Again, negate variable as described above dnf |= variable if literal % 2 == 0 else -variable # Append DNF clause cnf &= dnf solver = Minisat() solution = solver.solve(cnf) for dis in cnf.dis: for var in dis: print var.name print var.inverted # TODO: consider external representation for 'formula' if solution.success: return (formula, [solution[variables[i]] for i in variablesInFormula]) else: return (formula, None)
def test_sat_lib(self): """Sanity check: (x1 v -x2), (-x2), (-x1), (x3 v x1 x x2)""" cnf = Cnf() x1 = Variable('x1') x2 = Variable('x2') x3 = Variable('x3') solver = Minisat() solution = solver.solve(cnf) if not solution.success: self.fail("Something seriously wrong with this library.") true_literals = [x3] false_literals = [x1, x2] for lit in true_literals: self.assertTrue(solution[lit]) for lit in false_literals: self.assertFalse(solution[lit])
def do_search(self): print('Start linear search...') solver = Minisat() solution = solver.solve(self.encoder.do_encode()) solution_list = list() if solution.error != False: print("Error:") print(solution.error) elif solution.success: print("The expression can be satisfied...") for action in self.encoder.action_variables.values(): if solution.varmap[action]: [action, step] = str(action).split("@") solution_list.append([int(step), action]) self.found = True planning = plan.Plan(sorted(solution_list), self.horizon) return planning else: print("The expression cannot be satisfied, it's UNSAT...") return False
def main(): all_origin_number = {} for i in range(9): while True: row_input = input('please input ' + str(i + 1) + ' row: ') if valid_input(row_input): break for j in range(9): if row_input[j] != 'n': all_origin_number[(i, j)] = int(row_input[j]) - 1 all_variable = [[[ Variable('v' + str(i) + str(j) + str(k)) for k in range(9) ] for j in range(9)] for i in range(9)] true_var = Variable('v_true') exp = true_var exp = exp & all_element(all_variable, true_var) exp = exp & valid_all(all_variable, true_var) for keys in all_origin_number.keys(): exp = exp & all_variable[keys[0]][keys[1]][all_origin_number[keys]] solver = Minisat() solution = solver.solve(exp) if solution.success: for i in range(9): print('row' + str(i + 1) + ': ', end='') for j in range(9): for index, var in enumerate(all_variable[i][j]): if solution[var]: print(index + 1, end='') break print('\n', end='') else: print('no solution')
def SATSolver(dontCareSuites, testCaseExpressions): FoundedIndex = -1 parameters = [] parametersValues = [] for i in range(0, len(dontCareSuites)): tempValues = [] if (FoundedIndex != dontCareSuites[i][0]): # print(int(dontCareSuites[i][0]) + 1, " rule expression ----->", dontCareSuites[i][1]) # finds the satisfiable rules and writes test suite for them by using CnfFromString method exp, symbols = CnfFromString.create(dontCareSuites[i][1]) solver = Minisat() solution = solver.solve(exp) if solution.success: FoundedIndex = dontCareSuites[i][0] # print("Rule :", int(dontCareSuites[i][0]) + 1) for symbol_name in symbols.keys(): # print("%s is %s" % (symbol_name, solution[symbols[symbol_name]])) parameters.append( (symbol_name, solution[symbols[symbol_name]], (int(dontCareSuites[i][0]) + 1))) else: # print("The expression cannot be satisfied") FoundedIndex = dontCareSuites[i][0] parametersValues.append(parameters) parameters = [] for i in range(0, len(testCaseExpressions)): tempValues = [] # print("Rule ", (int(testCaseExpressions[i][0])+1)) # finds the satisfiable rules and writes test suite for them by using CnfFromString method exp, symbols = CnfFromString.create(testCaseExpressions[i][1]) solver = Minisat() solution = solver.solve(exp) if solution.success: for symbol_name in symbols.keys(): # print("%s is %s" % (symbol_name, solution[symbols[symbol_name]])) parameters.append((symbol_name, solution[symbols[symbol_name]], (int(testCaseExpressions[i][0]) + 1))) parametersValues.append(parameters) parameters = [] ##----------suitable test order operation ---------## for m in range(0, len(parametersValues)): parametersValues[m] = sorted(parametersValues[m]) return parametersValues
class Solver: '''SAT solver interface. Call solve() on a CNF object to solve it.''' def __init__(self): self.solver = Minisat() def solve(self, cnf): '''Solve a SAT problem in CNF form. Internally calls Minisat. Returns a Solution object.''' if type(cnf) is Clause: return self.solve(Cnf({cnf})) elif type(cnf) is SatVar: return self.solve(Clause({cnf})) def literal(lit): v = satispy.Variable(lit.name) if lit: return v else: return -v def clause(cls): lits = [literal(l) for l in cls.literals] c = lits.pop() for l in lits: c = c | l return c clauses = [clause(c) for c in cnf.clauses] expr = clauses.pop() for c in clauses: expr = expr & c solution = self.solver.solve(expr) if solution.success: assignment = { x: solution[satispy.Variable(x)] for x in cnf.variables } return Solution(True, assignment) else: return Solution(False)
def solve(num_wizards, num_constraints, wizards, constraints, constraintDiction): """ Write your algorithm here. Input: num_wizards: Number of wizards num_constraints: Number of constraints wizards: An array of wizard names, in no particular order constraints: A 2D-array of constraints, where constraints[0] may take the form ['A', 'B', 'C']i Output: An array of wizard names in the ordering your algorithm returns """ maxVal = 0 maxRet = wizards #constraintDict = {} iteration = 0 while True: constraintToVariable = dict() exp = None g1 = Graph(num_wizards) g2 = Graph(num_wizards) for constraint in constraints: wiz1 = constraint[0] wiz2 = constraint[1] wiz3 = constraint[2] clause1 = wiz3 + " " + wiz1 clause2 = wiz3 + " " + wiz2 clause3 = wiz1 + " " + wiz3 clause4 = wiz2 + " " + wiz3 g1.addEdge(wiz3, wiz1) g1.addEdge(wiz3, wiz2) g2.addEdge(wiz1, wiz3) g2.addEdge(wiz2, wiz3) if clause1 in constraintToVariable: v1 = constraintToVariable[clause1] else: constraintToVariable[clause1] = Variable(clause1) v1 = constraintToVariable[clause1] if clause2 in constraintToVariable: v2 = constraintToVariable[clause2] else: constraintToVariable[clause2] = Variable(clause2) v2 = constraintToVariable[clause2] if clause3 in constraintToVariable: v3 = constraintToVariable[clause3] else: constraintToVariable[clause3] = Variable(clause3) v3 = constraintToVariable[clause3] if clause4 in constraintToVariable: v4 = constraintToVariable[clause4] else: constraintToVariable[clause4] = Variable(clause4) v4 = constraintToVariable[clause4] literal = ((v1 & v2 & -v3 & -v4) ^ (v3 & v4 & -v1 & -v2)) if exp is None: exp = literal else: exp = exp & literal solver = Minisat() solution = solver.solve(exp) if solution.success: graph = dict() g = Graph(num_wizards) for wizard in wizards: graph[wizard] = set() for constraint in constraintToVariable: v = constraintToVariable[constraint] if solution[v] == True: # print(v) w = str(v).split() vertexU = w[0] vertexV = w[1] graph[vertexU].add(vertexV) g.addEdge(vertexU, vertexV) cycle = False try: topological(graph) except ValueError: cycle = True if cycle: graph[vertexU].remove(vertexV) graph[vertexV].add(vertexU) cycle = False try: topSortGraph = topological(graph) except ValueError: cycle = True graph = {} if not cycle: ans = list(topSortGraph) comp = checkConstraintsWithList(constraints, ans) if comp > maxVal: maxVal = comp maxRet = ans if iteration > 100: return az(maxRet,constraintDiction) #maxRet # print(comp) iteration += 1 shuffle(wizards) shuffle(constraints)
def propositional_nqueens(n): rules = 0 t1 = time() exprs = Cnf() queens_by_point = {} queens_by_name = {} points_by_name = {} by_rows = [[] for x in xrange(n)] by_cols = [[] for x in xrange(n)] for point in points(n): name = 'queen_%d_%d' % point by_rows[point[1]].append(name) by_cols[point[0]].append(name) queen = Variable(name) queens_by_point[point] = queen queens_by_name[name] = queen points_by_name[name] = point for row_of_names in by_rows: orexp = Cnf() for name in row_of_names: orexp = orexp | queens_by_name[name] rules += 1 exprs &= orexp for col_of_names in by_cols: orexp = Cnf() for name in col_of_names: orexp |= queens_by_name[name] rules += 1 exprs &= orexp for row in xrange(n): for col in xrange(n): antecedent_name = by_rows[row][col] consequent_names = [by_rows[row][a] for a in xrange(n) if a != col] # queen_X_Y => (not(queen_X1_Y1) & not(queen_X2_Y2)) # translates to # (not(queen_X_Y) or not(queen_X1_Y1)) and (not(queen_X_Y) or not(queen_X2_Y2)) #andexpr = Cnf() #for name in consequent_names: #andexpr &= (-queens_by_name[name]) #exprs &= (queens_by_name[antecedent_name] >> andexpr) for name in consequent_names: rules += 1 exprs &= -queens_by_name[antecedent_name] | -queens_by_name[name] for col in xrange(n): for row in xrange(n): antecedent_name = by_cols[col][row] consequent_names = [by_cols[col][a] for a in xrange(n) if a != row] # queen_X_Y => (not(queen_X1_Y1) & not(queen_X2_Y2)) # translates to # (not(queen_X_Y) or not(queen_X1_Y1)) and (not(queen_X_Y) or not(queen_X2_Y2)) #andexpr = Cnf() #for name in consequent_names: #andexpr &= (-queens_by_name[name]) #exprs &= (queens_by_name[antecedent_name] >> andexpr) for name in consequent_names: rules += 1 exprs &= -queens_by_name[antecedent_name] | -queens_by_name[name] for point1 in points(n): for point2 in points(n): if point1 == point2: continue if are_diagonal(point1, point2): rules += 1 #exprs &= (queens_by_point[point1] >> (-queens_by_point[point2])) exprs &= -queens_by_point[point1] | -queens_by_point[point2] for point in points(n): for slope in points(n, 1, 1): if slope == (1,1): continue lines = [ ] line = points_along_line(point, slope[0], slope[1], n) if len(line) >= 2: lines.append(line) line = points_along_line(point, -slope[0], slope[1], n) if len(line) >= 2: lines.append(line) if len(lines) == 0: continue for points1 in lines: for point1 in points1: #andexpr = Cnf() for point2 in points1: if point2 != point1: #andexpr &= (-queens_by_point[point2]) rules += 1 exprs &= -queens_by_point[point] | -queens_by_point[point1] | -queens_by_point[point2] #exprs &= ((queens_by_point[point] & queens_by_point[point1]) >> andexpr) t2 = time() print('# defined %d rules in %f seconds' % (rules, t2 - t1)) t1 = time() with open('/media/rust/%d.cnf' % n, 'w') as f: io = DimacsCnf() f.write(io.tostring(exprs)) t2 = time() print('# wrote rules in %f seconds' % (t2 - t1)) t1 = time() #return s = Minisat() #s = Lingeling(command='/home/bburns/projects/nqueens-solver/lingeling-bal-2293bef-151109/lingeling --witness=1 --verbose=1 %s') solution = s.solve(exprs) t2 = time() print('# solved in %f seconds' % (t2 - t1)) if solution.error: raise Exception(solution.error) if solution.success: results = [] #for a in solution.varmap: #if solution.varmap[a]: #results.append(points_by_name[a.name]) for point in queens_by_point: if solution[queens_by_point[point]]: results.append(point) results.sort() return results else: raise Exception('Unsat.')
def solve(num_wizards, num_constraints, wizards, constraints, zakiFirst): """ Write your algorithm here. Input: num_wizards: Number of wizards num_constraints: Number of constraints wizards: An array of wizard names, in no particular order constraints: A 2D-array of constraints, where constraints[0] may take the form ['A', 'B', 'C']i Output: An array of wizard names in the ordering your algorithm returns """ sameDictionary = [] constraintToVariable = dict() exp = None for constraint in constraints: wiz1 = constraint[0] wiz2 = constraint[1] wiz3 = constraint[2] clause1 = wiz3 + " " + wiz1 clause2 = wiz3 + " " + wiz2 clause3 = wiz1 + " " + wiz3 clause4 = wiz2 + " " + wiz3 if clause1 in constraintToVariable: v1 = constraintToVariable[clause1] else: constraintToVariable[clause1] = Variable(clause1) v1 = constraintToVariable[clause1] if clause2 in constraintToVariable: v2 = constraintToVariable[clause2] else: constraintToVariable[clause2] = Variable(clause2) v2 = constraintToVariable[clause2] if clause3 in constraintToVariable: v3 = constraintToVariable[clause3] else: constraintToVariable[clause3] = Variable(clause3) v3 = constraintToVariable[clause3] if clause4 in constraintToVariable: v4 = constraintToVariable[clause4] else: constraintToVariable[clause4] = Variable(clause4) v4 = constraintToVariable[clause4] literal = ((v1 & v2 & -v3 & -v4) ^ (v3 & v4 & -v1 & -v2)) if exp is None: exp = literal else: exp = exp & literal solver = Minisat() solution = solver.solve(exp) if solution.success: graph = dict() for wizard in wizards: graph[wizard] = set() for constraint in constraintToVariable: v = constraintToVariable[constraint] if solution[v] == True: w = str(v).split() vertexU = w[0] vertexV = w[1] graph[vertexU].add(vertexV) cycle = False try: topSortGraph = topological(graph) except ValueError: cycle = True iteration = 0 graph = {} if not cycle: return list(topSortGraph) else: while True: dictCompare = {} g = Graph(num_wizards) for wiz, neighbors in graph.items(): for n in neighbors: g.addEdge(wiz, n) badOnes = [] sccs = g.getSCCs() for scc in sccs: badGroup = set() if len(scc) > 1: for u in scc: for v in scc: if g.containsEdge(u, v): badGroup.add(u + " " + v) g.removeEdge(u, v) badOnes.append(badGroup) print("number of cycles:", len(badOnes)) for count, i in enumerate(badOnes): print("length of cycle", count + 1, ":", len(i)) for group in badOnes: lit = None for b in group: v = constraintToVariable[b] if lit is None: lit = v else: lit = lit & v exp = -(lit) & exp solver = Minisat() solution = solver.solve(exp) if solution.success: graph = dict() for wizard in wizards: graph[wizard] = set() for constraint in constraintToVariable: v = constraintToVariable[constraint] dictCompare[v] = solution[v] if solution[v] == True: w = str(v).split() vertexU = w[0] vertexV = w[1] graph[vertexU].add(vertexV) cycle = False try: topSortGraph = topological(graph) except ValueError: cycle = True else: print("SOMETHING WENT HORRIBLY WRONG") if not cycle: return list(topSortGraph) print("iteration: ", iteration) if iteration == 100: return solveAlt(num_wizards, num_constraints, wizards, constraints, zakiFirst) iteration += 1 if dictCompare in sameDictionary: print("YOU'VE BEEN IN THIS STATE BEFORE") else: print("new state :)") sameDictionary.append(dictCompare)
class SATSolver: """ Wrapper class for 'Satispy' library. """ def __init__(self): self.solver = Minisat() def solve(self, expr): """Takes a list of dependent and conflicting packages and returns whether the current configuration is satisfiable.""" dependent = [p for p in expr if '-' not in p] conflicting = [p[1:] for p in expr if '-' in p] # Generate set of unique package variables. variables = {} for var in set(dependent + conflicting): variables[var] = Variable(var) # Generate 'CNF' logical expression from dependencies # and conflicts. expr = Cnf() for con in dependent: v = variables[con] expr = expr & v for con in conflicting: v = variables[con] expr = expr & -v # Calculate the satisfiability of the input variables. valid, param = self._check_satisfiability(variables, expr) if valid: logging.debug( "Logical expression, {}, is satisfiable with parameters, {}.". format(expr, param)) else: logging.debug( "Logical expression, {} , is unsatisfiable.".format(expr)) return valid, param def _check_satisfiability(self, variables, logic_expr): """Given a 'CNF' logical expression returns a boolean stating if valid and the configuration of variables achieving this.""" # Case expression is empty. if str(logic_expr) == '()': logging.debug( "Logical expression, {}, is empty and therefore satisfiable.". format(logic_expr)) return True, None solution = self.solver.solve(logic_expr) # No satisifiable path. if not solution.success: return False, None # Build satisfiable solution output. param = [] for k, v in variables.items(): if solution[v] == True: param.append(k) else: param.append('-{}'.format(k)) return True, param
from satispy import Variable, Cnf from satispy.solver import Minisat solver = Minisat() file = open('testes.txt') x = [[[0 for k in range(4)] for j in range(4)] for i in range(4)] for i in range(4): for j in range(4): for k in range(4): x[i][j][k] = Variable('x_'+str(i)+str(j)+'_'+str(k)) sudoku = file.readline() n = 1 while sudoku != '': ######################################################################################## ######################################################################################## ## Escreva aqui o código gerador da formula CNF que representa o Sudoku codificado na ## ## variavel 'sudoku'. Nao se esqueca que o codigo deve estar no escopo do 'while' ## ## acima e deve guardar a formula CNF na variavel 'cnf'. ## ######################################################################################## ######################################################################################## cnf = Cnf() #Configurando o sudoku como uma matriz dos números passados
V = [[[Variable("V" + str(i) + str(j) + str(k)) for k in range(SIZE)] for j in range(SIZE)] for i in range(SIZE)] sq = int(sqrt(SIZE)) for i in range(SIZE): for n in range(SIZE): ExactlyOnce([V[i][j][n] for j in range(SIZE)]) ExactlyOnce([V[j][i][n] for j in range(SIZE)]) ExactlyOnce([V[i][n][j] for j in range(SIZE)]) y = (i // sq) * sq x = (i % sq) * sq ExactlyOnce([V[y + r][x + c][n] for c in range(sq) for r in range(sq)]) for r, row in enumerate(mat): for c, el in enumerate(row): if el != 0: expression &= V[r][c][el - 1] solver = Minisat() solution = solver.solve(expression) for i in range(SIZE): for j in range(SIZE): num = 0 for k in range(SIZE): if solution[V[i][j][k]]: num = k + 1 print(num, end=" ") print()
def get_sat_solution(self): solver = Minisat() solution = solver.solve(self.cnf()) return solution
from satispy import Variable from satispy.solver import Minisat v1 = Variable('v1') v2 = Variable('v2') v3 = Variable('v3') exp = v1 & v2 | v3 solver = Minisat() solution = solver.solve(exp) if solution.error != False: print "Error:" print solution.error elif solution.success: print "Found a solution:" print v1, solution[v1] print v2, solution[v2] print v3, solution[v3] else: print "The expression cannot be satisfied"
#C2 Pas deux fois le même match dans une Periode et une semaine différente for w in range(week): for w2 in range(w+1, week): for p in range(period): for p2 in range( period): for t in range(team): for t2 in range(t+1, team): if p != p2: #exp &= ( (sol[w][p][t] & sol[w][p][t2]) >> -(sol[w][p2][t] & sol[w][p2][t2])) #C2 exp &= ( (sol[w][p][t] & sol[w][p][t2]) >> -(sol[w2][p2][t] & sol[w2][p2][t2])) solver = Minisat() solution = solver.solve(exp) if solution.success: print ("Found a solution:\n")#, solution) #for key in solution.varmap: # print(key) for w in range(week): for p in range(period): for length_team in range(team): #print(w,p,number_team, length_team) #print(solution["w0p0nt0lt0"])
class SAT1(SAT): def __init__(self, instance): self._instance = instance self.global_expr = Cnf() #self.solver = Minisat('minisat %s %s') self.solver = Minisat() def build_model(self): nproc = self._instance.nproc nmach = self._instance.nmach nserv = self._instance.nserv nneigh = len(self._instance.N) nloc = len(self._instance.L) P = self._instance.P M = self._instance.M S = self._instance.S N = self._instance.N L = self._instance.L io = DimacsCnf() self.x = np.empty((nproc, nmach), dtype=object) for p in P: for m in M: self.x[p, m] = Variable('x[%d,%d]' % (p, m)) # proc alloc all_proc_expr = Cnf() for p in P: p_expr1 = Cnf() p_expr2 = Cnf() p_expr3 = Cnf() for m1 in M: if any(self._instance.R[p] > self._instance.C[m1]): p_expr1 &= -self.x[p, m1] else: p_expr1 |= self.x[p, m1] for m2 in range(m1 + 1, nmach): p_expr2 &= self.x[p, m1] >> -self.x[p, m2] all_proc_expr &= p_expr1 & p_expr2 & p_expr3 self.global_expr &= all_proc_expr # conflict all_conflict_expr = Cnf() for m in M: for s in S: if len(S[s]) == 1: continue conflict_expr = Cnf() for p1 in range(len(S[s])): for p2 in range(p1 + 1, len(S[s])): conflict_expr &= self.x[S[s][p1], m] >> -self.x[S[s][p2], m] all_conflict_expr &= conflict_expr self.global_expr &= all_conflict_expr def solve(self): sat_sol = self.solver.solve(self.global_expr) if not sat_sol.success: return SATSolution(False, None) assignment = np.zeros((self._instance.nproc, self._instance.nmach), dtype=np.int32) for p in self._instance.P: for m in self._instance.M: assignment[p, m] = sat_sol[self.x[p, m]] return SATSolution(True, assignment) def exclude_column(self, mach, col): expr = Cnf() for p in self._instance.P: if col[p] == 1: expr |= -self.x[p, mach] else: expr |= self.x[p, mach] self.global_expr &= expr def exclude_solution(self, solution): expr = Cnf() for p in self._instance.P: for m in self._instance.P: if solution.assignment[p, m] == 1: expr |= -self.x[p, m] else: expr |= self.x[p, m] self.global_expr &= expr
def knight(N=8): white_knight_at = [[ Variable("W_{" + str(i) + str(j) + "}") for i in range(N) ] for j in range(N)] black_knight_at = [[ Variable("B_{" + str(i) + str(j) + "}") for i in range(N) ] for j in range(N)] formula = Cnf() # the overall formula # at least one black and white knight in each row for i in range(N): oneinthisrow_w = Cnf() oneinthisrow_b = Cnf() for j in range(N): oneinthisrow_w |= white_knight_at[i][j] oneinthisrow_b |= black_knight_at[i][j] formula &= (oneinthisrow_w & oneinthisrow_b) # at least one black and white knight in each column for j in range(N): oneinthiscolumn_w = Cnf() oneinthiscolumn_b = Cnf() for i in range(N): oneinthiscolumn_w |= white_knight_at[i][j] oneinthiscolumn_b |= black_knight_at[i][j] & ( -white_knight_at[i][j]) formula &= (oneinthiscolumn_w & oneinthiscolumn_b) # Each row and column has exactly 1 black and white knight for i1 in range(N): for j1 in range(N): for i2 in range(N): for j2 in range(N): if N * i1 + j1 < N * i2 + j2: # Eliminate mirrors if (i1 == i2) | ( j1 == j2 ): # If two possible placements share the same row or column formula &= ((-white_knight_at[i1][j1]) | (-white_knight_at[i2][j2])) & ( (-black_knight_at[i1][j1]) | (-black_knight_at[i2][j2])) # Can't attack same color for i1 in range(N): for j1 in range(N): for i2 in range(N): for j2 in range(N): if N * i1 + j1 < N * i2 + j2: # Eliminate mirrors if ((i1 - i2)**2 + (j1 - j2)**2 == 5) & ( (i1 - i2 <= 2) & (j1 - j2 <= 2)): # "L" shape attack formula &= ((-white_knight_at[i1][j1]) | (-white_knight_at[i2][j2])) & ( (-black_knight_at[i1][j1]) | (-black_knight_at[i2][j2])) # White must attack at least one enemy for i1 in range(N): for j1 in range(N): white_must_attack_one = Cnf() for i2 in range(N): for j2 in range(N): if ((i1 - i2)**2 + (j1 - j2)**2 == 5) & ( (i1 - i2 <= 2) & (j1 - j2 <= 2)): # "L" shape attack white_must_attack_one |= (white_knight_at[i1][j1]) & ( black_knight_at[i2][j2]) formula &= (white_knight_at[i1][j1] >> white_must_attack_one) # Black must attack at least one enemy for i1 in range(N): for j1 in range(N): black_must_attack_one = Cnf() for i2 in range(N): for j2 in range(N): if ((i1 - i2)**2 + (j1 - j2)**2 == 5) & ( (i1 - i2 <= 2) & (j1 - j2 <= 2)): # "L" shape attack black_must_attack_one |= (black_knight_at[i1][j1]) & ( white_knight_at[i2][j2]) formula &= (black_knight_at[i1][j1] >> black_must_attack_one) solution = Minisat().solve(formula) if solution.error is True: print("Error: " + solution.error) elif solution.success: chessboard = "" for i in range(N): for j in range(N): if solution[white_knight_at[i][j]]: chessboard += "1" elif solution[black_knight_at[i][j]]: chessboard += "2" else: chessboard += "0" chessboard += "\n" print(chessboard) else: print("No valid solution")
def printEquisatisfiableSatFormula(): #create variables variables = [] varCount = 1 for i in range(n): #for each vertex, append one variable for each position in the path #the number of positions equals the number of vertices in the graph for n^2 total variables for j in range(n): variables.append(Position(varCount, i, j)) varCount += 1 if verbose: printVariables(variables) printEdges(edges) clauses = [] for i in range(n): #loop over rooms #enforce that every room must be visited #get all the variables corresponding to this position and ensure one of them is true vars = [j.varNum for j in variables if j.vertex == i] #create an or clause of these variables and add it clauses.append('enforce at least one visit') clause = [] for j in vars: clause.append(j) clauses.append(clause) clauses.append('enforce only one visit') #enforce that no room can be visited more than once #loop over positions for this room and ensure it has no more that 1 position for j in range(n): for k in range(n): #for each pair of position variable ensure that at most of them is true if j < k: clause = [] clause.append(-vars[j]) clause.append(-vars[k]) clauses.append(clause) #enforce every path position is used clauses.append('enforce all path positions used') for i in range(n): vars = [j.varNum for j in variables if j.pos == i] clause = [] for j in vars: clause.append(j) clauses.append(clause) clauses.append('each position used only once') for i in range(n): vars = [j.varNum for j in variables if j.pos == i] for j in range(n): for k in range(n): #for each pair of position variable ensure that at most of them is true if j < k: clause = [] clause.append(-vars[j]) clause.append(-vars[k]) clauses.append(clause) #use edges to determine which transitions are not allowed #for example, if no edge exists between room 3 and room4, we must insert a condition that #room3 cannot be adjacent to room 4 (room3 in position i implies room 4 cannot be in position 5 or 3) clauses.append('Enforce no path if no edge') #loop through all possible connections for i in range(n): for j in range(n): if i != j: #determine if edge exists edgeExists = False for edge in edges: if i + 1 == edge[0] and j + 1 == edge[1]: edgeExists = True if i + 1 == edge[1] and j + 1 == edge[0]: edgeExists = True #print(edgeExists) #if no edge, add a clause excluding this connection for each step if not edgeExists: for step in range(1, n): #get variable for these edges and these steps var1 = [ k.varNum for k in variables if k.vertex == i and k.pos == step ][0] var2 = [ k.varNum for k in variables if k.vertex == j and k.pos == step - 1 ][0] #print(var1) #print(var2) clause = [] clause.append(-var1) clause.append(-var2) clauses.append(clause) printClauses(clauses, len(variables), verbose) #print(genExpression(clauses)) if verbose2: solver = Minisat() solution = solver.solve(eval(genExpression(clauses))) if solution.success: print('Found a solution:') else: print('The expression cannot be satisfied')
def solve(num_wizards, num_constraints, wizards, constraints): """ Write your algorithm here. Input: num_wizards: Number of wizards num_constraints: Number of constraints wizards: An array of wizard names, in no particular order constraints: A 2D-array of constraints, where constraints[0] may take the form ['A', 'B', 'C']i Output: An array of wizard names in the ordering your algorithm returns """ sameDictionary = [] constraintToVariable = dict() exp = None for constraint in constraints: wiz1 = constraint[0] wiz2 = constraint[1] wiz3 = constraint[2] clause1 = wiz3 + " " + wiz1 clause2 = wiz3 + " " + wiz2 clause3 = wiz1 + " " + wiz3 clause4 = wiz2 + " " + wiz3 if clause1 in constraintToVariable: v1 = constraintToVariable[clause1] else: constraintToVariable[clause1] = Variable(clause1) v1 = constraintToVariable[clause1] if clause2 in constraintToVariable: v2 = constraintToVariable[clause2] else: constraintToVariable[clause2] = Variable(clause2) v2 = constraintToVariable[clause2] if clause3 in constraintToVariable: v3 = constraintToVariable[clause3] else: constraintToVariable[clause3] = Variable(clause3) v3 = constraintToVariable[clause3] if clause4 in constraintToVariable: v4 = constraintToVariable[clause4] else: constraintToVariable[clause4] = Variable(clause4) v4 = constraintToVariable[clause4] literal = ((v1 & v2 & -v3 & -v4) ^ (v3 & v4 & -v1 & -v2)) # literal = (((v1 & v2) | (v3 & v4)) & v1 >> -v3 & v2 >> -v4 & v3 >> -v1 & v4 >> -v2) if exp is None: exp = literal else: exp = exp & literal solver = Minisat() solution = solver.solve(exp) maxVal = 0 maxRet = wizards cycle = False if solution.success: graph = dict() for wizard in wizards: graph[wizard] = set() for constraint in constraintToVariable: v = constraintToVariable[constraint] if solution[v] == True: # print(v) w = str(v).split() vertexU = w[0] vertexV = w[1] graph[vertexU].add(vertexV) cycle = False try: topological(graph) except ValueError: cycle = True if cycle: graph[vertexU].remove(vertexV) graph[vertexV].add(vertexU) try: topSortGraph = topological(graph) except ValueError: cycle = True # print(topSortGraph) iteration = 0 graph = {} if not cycle: return list(topSortGraph) else: while True: dictCompare = {} g = Graph(num_wizards) for wiz, neighbors in graph.items(): for n in neighbors: g.addEdge(wiz, n) # print(str(g.graph)) # print(sccs) badOnes = [] # print(graph.items()) # print(g.getSCCs()) sccs = g.getSCCs() for scc in sccs: badGroup = set() if len(scc) > 1: for u in scc: for v in scc: # if u == v: # continue if g.containsEdge(u, v): badGroup.add(u + " " + v) g.removeEdge(u, v) badOnes.append(badGroup) # print("number of cycles:", len(badOnes)) # for count, i in enumerate(badOnes): # print("length of cycle", count + 1, ":", len(i)) # while True: # sccs = g.getSCCs() # # print(sccs) # biggestScc = max([len(scc) for scc in sccs]) # if biggestScc == 1: # break # for scc in sccs: # if len(scc) > 1: # stop = False # for u in scc: # if stop == True: # break # for v in scc: # if u == v: # continue # if g.containsEdge(u, v): # badOnes.add(u + " " + v) # g.removeEdge(u, v) # stop = True # break # print(sccs) # print(g.graph) # print("badOnes", badOnes) for group in badOnes: lit = None for b in group: v = constraintToVariable[b] if lit is None: lit = v else: lit = lit & v exp = -(lit) & exp # inverse = b.split() # inverse = inverse[1] + " " + inverse[0] # if inverse in constraintToVariable: # # print("AND I SAYYYY") # v2 = constraintToVariable[inverse] # exp = exp & v2 solver = Minisat() solution = solver.solve(exp) if solution.success: graph = dict() for wizard in wizards: graph[wizard] = set() for constraint in constraintToVariable: v = constraintToVariable[constraint] # print(v, solution[v]) dictCompare[v] = solution[v] if solution[v] == True: # print(v) w = str(v).split() vertexU = w[0] vertexV = w[1] graph[vertexU].add(vertexV) # if iteration > 10: # cycle = False # try: topological(graph) # except ValueError: cycle = True # if cycle: # graph[vertexU].remove(vertexV) # graph[vertexV].add(vertexU) cycle = False try: topSortGraph = topological(graph) except ValueError: cycle = True # print(topSortGraph) else: print("SOMETHING WENT HORRIBLY WRONG") if not cycle: return list(topSortGraph) # print("iteration: ", iteration) iteration += 1 if dictCompare in sameDictionary: print("YOU'VE BEEN IN THIS STATE BEFORE") else: # print("new state :)") sameDictionary.append(dictCompare)
def sat(instance): expr = Cnf() nproc = instance.nproc nmach = instance.nmach nserv = instance.nserv nneigh = len(instance.N) nloc = len(instance.L) P = instance.P M = instance.M S = instance.S N = instance.N L = instance.L print(" %10.3f creating vars - x" % (time() - all_start)) x = np.empty((nproc, nmach), dtype=object) for p in P: for m in M: x[p, m] = Variable('x[%d,%d]' % (p, m)) print(" %10.3f creating vars - h" % (time() - all_start)) h = np.empty((nserv, nneigh), dtype=object) for s in S: for n in N: h[s, n] = Variable('h[%d,%d]' % (s, n)) print(" %10.3f creating vars - o" % (time() - all_start)) o = np.empty((nserv, nloc), dtype=object) for s in S: for l in L: o[s, l] = Variable('o[%d,%d]' % (s, l)) print(" %10.3f H[s,n]" % (time() - all_start)) for s in S: #print(" %10.3f H[%6d,n]" %( time() - all_start,s)) for n in N: pres_expr = Cnf() for p in S[s]: for m in N[n]: pres_expr |= x[p, m] expr &= h[s, n] >> pres_expr expr &= pres_expr >> h[s, n] for sd in instance.sdep[s]: expr &= h[s, n] >> h[sd, n] print(" %10.3f O[s,l]" % (time() - all_start)) for s in S: #print(" %10.3f O[%6d,l]" %( time() - all_start,s)) if instance.delta[s] == 1: continue for l in L: pres_expr = Cnf() for p in S[s]: for m in L[l]: pres_expr |= x[p, m] expr &= o[s, l] >> pres_expr expr &= pres_expr >> o[s, l] print(" %10.3f X[p,m]" % (time() - all_start)) for p in P: #print(" %10.3f X[%6d, m]" %( time() - all_start, p)) p_constr1 = Cnf() p_constr2 = Cnf() for m in M: p_constr1 |= x[p, m] for m2 in range(m + 1, nmach): p_constr2 &= x[p, m] >> -x[p, m2] expr &= p_constr1 & p_constr2 print(" %10.3f X[p,m] - conflito" % (time() - all_start)) for m in M: for s in S: conf_constr = Cnf() if len(S[s]) == 1: continue for i1 in range(len(S[s])): for i2 in range(i1 + 1, len(S[s])): conf_constr &= x[S[s][i1], m] >> -x[S[s][i2], m] expr &= conf_constr print(" %10.3f solving" % (time() - all_start)) io = DimacsCnf() #s = io.tostring(expr) #print(s) solver = Minisat('minisat %s %s') solution = solver.solve(expr) print(" %10.3f done" % (time() - all_start)) if not solution.success: print(" %10.3f sem solucao" % (time() - all_start)) exit(0) print(" %10.3f solucao" % (time() - all_start)) xsol = np.empty((nproc, nmach), dtype=np.int32) for p in P: for m in M: #print(p,m,solution[x[p,m]]) #print(io.varname(x[p,m])) xsol[p, m] = solution[x[p, m]] print(xsol) print(np.all(xsol.sum(axis=1) == 1)) for m in M: print(instance.mach_validate(m, xsol[:, m]))
for j1 in gnodes: for j2 in gnodes: if i1 != i2: exp &= -varz[i][j1] | -varz[i][j2] # Edge print("Adding edge clauses...") for j in range(lennodes): print(j) for i in gnodes: for k in gnodes: if i != k and k not in g.neighbors(i): exp &= -varz[i][j] | -varz[k][(j + 1) % lennodes] # Enabling minisat to write to stdout solver = Minisat('minisat %s %s') print("Solving...") solution = solver.solve(exp) if not solution.success: print("There is no Hamilton cycle in the graph.") exit() print("Extracting solution...") path = [] for n in g.nodes(): nodepos = -1 for j in range(lennodes): if solution[varz[n][j]]: nodepos = j
def __init__(self): self.solver = Minisat()