コード例 #1
0
    def test_trivial_conflict_clause(self):
        x = self.new_lit()
        a = Assignment(self.__mem, x)

        a.make_decision(x)
        c = self.new_clause(x)
        self.assertTrue(c.is_conflict(a))
        self.assertIsNone(c.derive(a))
コード例 #2
0
    def test_conflict_analysis_v1(self):
        x = self.new_lit()
        a = Assignment(self.__mem, x)

        a.make_decision(x)
        conflict = self.new_clause(x)
        self.assertTrue(conflict.is_conflict(a))

        self.assertEqual([x], a.analyze_conflict(conflict))
コード例 #3
0
    def test_binary_unit_clause(self):
        x = self.new_lit()
        y = self.new_lit()
        a = Assignment(self.__mem, x, y)

        a.make_decision(y)
        c = self.new_clause(x, y)
        self.assertFalse(c.is_conflict(a))
        self.assertEqual(x, c.derive(a))
コード例 #4
0
    def test_binary_conflict_clause(self):
        x = self.new_lit()
        y = self.new_lit()
        a = Assignment(self.__mem, x, y)

        a.make_decision(x)
        a.make_decision(y)
        c = self.new_clause(x, y)
        self.assertTrue(c.is_conflict(a))
        self.assertIsNone(c.derive(a))
コード例 #5
0
    def test_trivial_unit_clause(self):
        x = self.new_lit()
        a = Assignment(self.__mem, x)

        c = self.new_clause(x)
        self.assertFalse(c.is_conflict(a))
        self.assertEqual(x, c.derive(a))
コード例 #6
0
    def test_conflict_analysis_v2(self):
        x, y, z = self.new_lit(), self.new_lit(), self.new_lit()
        a = Assignment(self.__mem, x, y, z)

        a.make_decision(z)
        a.make_implication(x, self.new_clause(x.negated, z))
        a.make_implication(y, self.new_clause(y.negated, z))

        conflict = self.new_clause(x, y)
        self.assertTrue(conflict.is_conflict(a))

        self.assertEqual([z], a.analyze_conflict(conflict))
コード例 #7
0
    def test_conflict_analysis_v3(self):
        u, v, x, y = self.new_lit(), self.new_lit(), self.new_lit(
        ), self.new_lit()
        a = Assignment(self.__mem, u, v, x, y)

        a.make_decision(v)
        a.make_decision(y)
        a.make_implication(x, self.new_clause(x.negated, v, y))
        a.make_implication(u, self.new_clause(u.negated, v, x))

        conflict = self.new_clause(u)
        self.assertTrue(conflict.is_conflict(a))

        self.assertEqual([u], a.analyze_conflict(conflict))
コード例 #8
0
    def __dpll(self, xs: 'List[Literal]', f: 'Set[Clause]') -> 'Status':
        a = Assignment(self.__mem, *xs)
        while True:
            while True:
                clause = a.get_suspicious_clause()
                if clause is None:
                    break
                if clause.is_conflict(a):
                    literals = a.analyze_conflict(clause)
                    x = literals[0]
                    if len(literals) == 1:
                        if x.link == a.sentinel:
                            return Status.UNSAT
                        backtrack_lit = a.sentinel.link
                        if backtrack_lit != a.sentinel:
                            a.backtrack(backtrack_lit)
                    else:
                        y = literals[1]
                        backtrack_lit = y.link if y.antecedent is None else y.link.link
                        assert backtrack_lit != a.sentinel
                        a.backtrack(backtrack_lit)
                    asserting_clause = self.new_clause(*literals)
                    self.assertEqual(x, asserting_clause.derive(a))
                    a.make_implication(x.negated, asserting_clause)
                else:
                    z = clause.derive(a)
                    if z is not None:
                        a.make_implication(z.negated, clause)
            if a.border.value == len(xs) + 1:
                break
            d = a.literals[a.border.value]
            a.make_decision(d.negated)

        self.assertTrue(all((a[x] is not None) for x in xs))
        for c in f:
            self.assertTrue(any((a[x.negated] is True) for x in c.literals))
        return Status.SAT
コード例 #9
0
    def test_dpll_steps(self):
        x1 = self.new_lit()
        x2 = self.new_lit()
        x3 = self.new_lit()
        x4 = self.new_lit()
        x5 = self.new_lit()
        x6 = self.new_lit()
        a = Assignment(self.__mem, x1, x2, x3, x4, x5, x6)

        c1 = self.new_clause(x1.negated, x2)
        c2 = self.new_clause(x3.negated, x4)
        c3 = self.new_clause(x5.negated, x6.negated)
        c4 = self.new_clause(x6, x5.negated, x2.negated)

        # DECIDE
        a.make_decision(x1.negated)

        # UNIT PROPAGATION
        self.assertEqual(c1, a.get_suspicious_clause())
        self.assertIsNone(a.get_suspicious_clause())
        self.assertEqual(x2, c1.derive(a))
        a.make_implication(x2.negated, c1)

        # DECIDE
        a.make_decision(x3.negated)

        # UNIT PROPAGATION
        self.assertEqual(c2, a.get_suspicious_clause())
        self.assertIsNone(a.get_suspicious_clause())
        self.assertEqual(x4, c2.derive(a))
        a.make_implication(x4.negated, c2)

        # DECIDE
        a.make_decision(x5.negated)

        # UNIT PROPAGATION
        self.assertEqual(c3, a.get_suspicious_clause())
        self.assertEqual(x6.negated, c3.derive(a))
        a.make_implication(x6, c3)

        # BACKJUMP & LEARN
        self.assertEqual(c4, a.get_suspicious_clause())
        self.assertTrue(c4.is_conflict(a))

        analysis = a.analyze_conflict(c4)
        self.assertEqual([x5.negated, x2.negated], analysis)
        c5 = self.new_clause(*analysis)

        self.assertEqual(x3.negated, analysis[1].link.link)
        a.backtrack(x3.negated)
        self.assertEqual(x5.negated, c5.derive(a))
        a.make_implication(x5, c5)

        # DECIDE
        a.make_decision(x3.negated)

        # UNIT PROPAGATION
        self.assertEqual(c2, a.get_suspicious_clause())
        self.assertIsNone(a.get_suspicious_clause())
        self.assertEqual(x4, c2.derive(a))
        a.make_implication(x4.negated, c2)

        # DECIDE
        a.make_decision(x6.negated)

        # verdict: SAT
        while True:
            c = a.get_suspicious_clause()
            if c is None:
                break
            self.assertFalse(c.is_conflict(a))
            self.assertIsNone(c.derive(a))
コード例 #10
0
    def test_conflict_analysis_v4(self):
        x1, x2, x3 = self.new_lit(), self.new_lit(), self.new_lit()
        x4, x5, x6 = self.new_lit(), self.new_lit(), self.new_lit()
        x7, x8, x9 = self.new_lit(), self.new_lit(), self.new_lit()
        a = Assignment(self.__mem, x1, x2, x3, x4, x5, x6, x7, x8, x9)

        a.make_decision(x1)
        a.make_implication(x5, self.new_clause(x5.negated, x1))
        a.make_decision(x6)
        a.make_decision(x9)
        a.make_implication(x8, self.new_clause(x8.negated, x9))
        a.make_implication(x7, self.new_clause(x7.negated, x6, x9, x8))
        a.make_implication(x4, self.new_clause(x4.negated, x7))
        a.make_implication(x2, self.new_clause(x2.negated, x4, x7))
        a.make_implication(x3, self.new_clause(x3.negated, x4, x5))

        conflict = self.new_clause(x1, x2, x3)
        self.assertTrue(conflict.is_conflict(a))

        self.assertEqual([x7, x5, x1], a.analyze_conflict(conflict))
コード例 #11
0
    def test_assignment(self):
        u = self.new_lit()
        v = self.new_lit()
        x = self.new_lit()
        y = self.new_lit()
        z = self.new_lit()
        a = Assignment(self.__mem, u, v, x, y, z)

        self.assertEqual(a.sentinel, a.sentinel.link)
        self.assertEqual(a.sentinel, a.top_decision.value)

        a.make_decision(u)
        a.make_decision(v)
        self.assertFalse(a[u])
        self.assertFalse(a[v])
        self.assertIsNone(a[x])
        self.assertIsNone(a[y])
        self.assertIsNone(a[z])

        a.make_decision(x)
        a.make_decision(y)
        self.assertFalse(a[u])
        self.assertFalse(a[v])
        self.assertFalse(a[x])
        self.assertFalse(a[y])
        self.assertIsNone(a[z])

        self.assertEqual(u, a.sentinel.link)
        self.assertEqual(v, u.link)
        self.assertEqual(x, v.link)
        self.assertEqual(y, x.link)
        self.assertEqual(y, y.link)
        self.assertEqual(y, a.top_decision.value)

        a.backtrack(x)
        self.assertFalse(a[u])
        self.assertFalse(a[v])
        self.assertIsNone(a[x])
        self.assertIsNone(a[y])
        self.assertIsNone(a[z])

        a.make_decision(y)
        a.make_decision(z)
        self.assertFalse(a[u])
        self.assertFalse(a[v])
        self.assertIsNone(a[x])
        self.assertFalse(a[y])
        self.assertFalse(a[z])

        self.assertEqual(u, a.sentinel.link)
        self.assertEqual(v, u.link)
        self.assertEqual(y, v.link)
        self.assertEqual(z, y.link)
        self.assertEqual(z, a.top_decision.value)

        a.backtrack(u)
        self.assertEqual(a.sentinel, a.top_decision.value)
        self.assertEqual(a.sentinel, a.sentinel.link)
コード例 #12
0
    def test_update_to_conflict_v2(self):
        x = self.new_lit()
        y = self.new_lit()
        z = self.new_lit()
        a = Assignment(self.__mem, x, y, z)

        c = self.new_clause(x, y, z)
        self.assertIsNone(a.get_suspicious_clause())
        self.assertFalse(c.is_conflict(a))
        self.assertIsNone(c.derive(a))

        a.make_decision(x)
        self.assertIsNone(a.get_suspicious_clause())
        self.assertFalse(c.is_conflict(a))
        self.assertIsNone(c.derive(a))

        a.make_decision(y)
        self.assertEqual(c, a.get_suspicious_clause())
        self.assertIsNone(a.get_suspicious_clause())
        self.assertFalse(c.is_conflict(a))
        self.assertEqual(z, c.derive(a))

        a.make_decision(z)
        self.assertEqual(c, a.get_suspicious_clause())
        self.assertIsNone(a.get_suspicious_clause())
        self.assertTrue(c.is_conflict(a))
        self.assertIsNone(c.derive(a))