def solve(self, cnf): s = Solution() infile = NamedTemporaryFile(mode='w') outfile = NamedTemporaryFile(mode='r') io = DimacsCnf() infile.write(io.tostring(cnf)) infile.flush() ret = call(self.command % (infile.name, outfile.name), shell=True) infile.close() if ret != 10: return s s.success = True lines = outfile.readlines()[1:] for line in lines: varz = line.split(" ")[:-1] for v in varz: v = v.strip() value = v[0] != '-' v = v.lstrip('-') vo = io.varobj(v) s.varmap[vo] = value # Close deletes the tmp files outfile.close() return s
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, cnf): s = Solution() # NamedTemporaryFile doesn't work on Windows, see https://stackoverflow.com/questions/15169101/how-to-create-a-temporary-file-that-can-be-read-by-a-subprocess infile, infilename = tempfile.mkstemp(suffix="cnf") try: io = DimacsCnf() os.write(infile, io.tostring(cnf)) os.close(infile) try: cmd = self.command % (infilename.replace("\\", "/")) check_output(cmd, stderr=STDOUT, shell=True) # Lingeling and most SAT-solvers use a non-zero return code, which in most POSIX command indicates an error. # That's why python raises an exception, but here it's expected except CalledProcessError as call: if call.returncode != 10 and call.returncode != 20: s.error = call.output return s finally: os.remove(infilename) if call.returncode != 10: return s s.success = True for line in call.output.split("\n"): # Solution line example: v 1 -2 3 -4 5 6 0 if len(line) > 0 and line[0] == 'v': varz = line.split(" ")[1:-1] for v in varz: v = v.strip() value = v[0] != '-' v = v.lstrip('-') vo = io.varobj(v) s.varmap[vo] = value return s
def solve(self, cnf): s = Solution() with NamedTemporaryFile(mode='w') as infile, \ NamedTemporaryFile(mode='r') as outfile: io = DimacsCnf() infile.write(io.tostring(cnf)) infile.flush() try: output = check_output( [self.command, infile.name, outfile.name], universal_newlines=True, timeout=self.timeout) except CalledProcessError as ex: s.success = (ex.returncode == 10) output = ex.output s.stats = parse_stats(output) if not s.success: return s lines = outfile.readlines()[1:] for line in lines: varz = line.split(" ")[:-1] for v in varz: v = v.strip() value = v[0] != '-' v = v.lstrip('-') vo = io.varobj(v) s.varmap[vo] = value return s
from satispy import Variable, Cnf from satispy.solver import Minisat from satispy.io import DimacsCnf with open("example.dimacs", "r") as satfile: s = satfile.read().rstrip("\n") exp = DimacsCnf().fromstring(s) print(exp) solver = Minisat() solution = solver.solve(exp) if solution.success: print("Found a solution:") for v in solution.varmap: print(v.name + ": " + str(solution[v])) else: print("The expression cannot be satisfied")
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]))
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.')
for i in range(args.clause): c = Cnf() k = sample(v, args.literal) for j in k: if random() >= 0.5: c |= j else: c |= -j exp &= c solver = Minisat() solution = solver.solve(exp) dimacsCnf = DimacsCnf() print(dimacsCnf.tostring(exp)) if solution.error != False: print("Error:") print(solution.error) elif solution.success: print("Success:") for i in range(args.variable): print(v[i], solution[v[i]]) fo = open('%s.in' % (args.file_name), "w") fo.write(dimacsCnf.tostring(exp)) fo.close() fo = open('answer.dat', "w")