示例#1
0
    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()), ))
示例#2
0
 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()
示例#3
0
    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