def test_2_theory(self): """Tests that the theory itself is correct. """ solver = sat.SatSolver() w = sat.DimacsWriter(ti) MM.MurderMystery().writeTheory(w) w.close() cnf = readCnf(ti) rev = {} for ((pred, predName), x, y) in predicates(): rev[pred(x, y)] = predString(predName, x, y) rev[-pred(x, y)] = '-' + predString(predName, x, y) def revModel(m: Set[int]) -> Set[str]: return frozenset(rev[x] for x in m) M = set(frozenset(m) for m in models.M) for m in self.models(): rm = revModel(m) if rm not in M: self.fail("Wrong model:\n %s" % (formatModel(rm), )) M.remove(rm) if len(M) > 0: self.fail("Some models are missing, for example:\n %s" % (formatModel(M.pop()), ))
def models(self): while True: s, sol = sat.SatSolver().solve(ti, 'testoutput.txt') if not s: break yield sol w = sat.DimacsWriter(ti, 'a') w.writeClause(-x for x in sol) w.close()
def solve(self, N): self.N = N solver = sat.SatSolver() w = sat.DimacsWriter('nqueens_cnf_in.txt') w.writeComment("v kazdom riadku aspon jedna dama") # v kazdom riadku for r in range(N): # je aspon jedna dana for c in range(N): w.writeLiteral(self.q(r, c)) w.finishClause() w.writeComment("nie su 2 damy v tom istom riadku") # v kazdom riadku for r in range(N): # na dvoch roznych poziciach for c1 in range(N): for c2 in range(c1): # nie je na oboch dama # q(r,c1) => -q(r,c2) w.writeImpl(self.q(r, c1), -self.q(r, c2)) w.writeComment("nie su 2 damy v tom istom stlpci") # v kazdom stlpci for c in range(N): # na dvoch roznych miestach for r1 in range(N): for r2 in range(r1): # nie je na oboch dama w.writeImpl(self.q(r1, c), -self.q(r2, c)) w.writeComment("uhlopriecky") # uhlopriecky # trochu neefektivnejsie, ale rychlejsie na napisanie for c1 in range(N): for c2 in range(N): for r1 in range(N): for r2 in range(N): # rozne pozicie if (self.q(r1, c1) != self.q(r2, c2)): # r1,c1 a r2,c2 su na uhlopriecke if (r1 + c1 == r2 + c2) or (r1 + c2 == r2 + c1): w.writeImpl(self.q(r1, c1), -self.q(r2, c2)) w.close() ok, sol = solver.solve(w, 'nqueens_cnf_out.txt') ret = [] if ok: for x in sol: if x > 0: x -= 1 ret.append((x // N, x % N)) return ret