Example #1
0
def test_odd_even_merge():
    for n in [1, 2, 4, 8, 16]:
        A = list(range(1, n + 1))
        B = list(range(n + 1, 2 * n + 1))
        C = Clauses(n)
        merged = C.odd_even_merge(A, B)
        for i in range(n + 1):
            for j in range(n + 1):
                # Test all possible mergings of sorted lists, like [1, 1, 0,
                # 0] and [1, 0, 0, 0] -> [1, 1, 1, 0, 0, 0, 0, 0].
                Asigns = [1] * i + [-1] * (n - i)
                Bsigns = [1] * j + [-1] * (n - j)
                As = {(s * a, ) for s, a in zip(Asigns, A)}
                Bs = {(s * b, ) for s, b in zip(Bsigns, B)}
                for sol in my_itersolve(C.clauses | As | Bs):
                    a = [i in sol for i in A]
                    b = [i in sol for i in B]
                    m = [i in sol for i in merged]
                    # Check we did the above correctly
                    assert a == sorted(a, reverse=True)
                    assert b == sorted(b, reverse=True)
                    # And check that the merge is correct
                    assert m == sorted(a + b, reverse=True)

    assert raises(ValueError,
                  lambda: Clauses(4).odd_even_merge([1, 2], [2, 3, 4]))
Example #2
0
def test_ITE():
    # Note, pycosat will automatically include all smaller numbers in models,
    # e.g., itersolve([[2]]) gives [[1, 2], [-1, 2]]. This should not be an
    # issue here.

    for c in [true, false, 1]:
        for t in [true, false, 2]:
            for f in [true, false, 3]:
                Cl = Clauses(3)
                x = Cl.ITE(c, t, f)
                if x in [true, false]:
                    if t == f:
                        # In this case, it doesn't matter if c is not boolizable
                        assert boolize(x) == boolize(t)
                    else:
                        assert boolize(x) == (boolize(t) if boolize(c) else
                            boolize(f)), (c, t, f)
                else:

                    for sol in my_itersolve({(x,)} | Cl.clauses):
                        C = boolize(c) if c in [true, false] else (1 in sol)
                        T = boolize(t) if t in [true, false] else (2 in sol)
                        F = boolize(f) if f in [true, false] else (3 in sol)
                        assert T if C else F, (T, C, F, sol, t, c, f)

                    for sol in my_itersolve({(-x,)} | Cl.clauses):
                        C = boolize(c) if c in [true, false] else (1 in sol)
                        T = boolize(t) if t in [true, false] else (2 in sol)
                        F = boolize(f) if f in [true, false] else (3 in sol)
                        assert not (T if C else F)
Example #3
0
def test_odd_even_merge():
    for n in [1, 2, 4, 8, 16]:
        A = list(range(1, n+1))
        B = list(range(n+1, 2*n+1))
        C = Clauses(n)
        merged = C.odd_even_merge(A, B)
        for i in range(n+1):
            for j in range(n+1):
                # Test all possible mergings of sorted lists, like [1, 1, 0,
                # 0] and [1, 0, 0, 0] -> [1, 1, 1, 0, 0, 0, 0, 0].
                Asigns = [1]*i + [-1]*(n - i)
                Bsigns = [1]*j + [-1]*(n - j)
                As = {(s*a,) for s, a in zip(Asigns, A)}
                Bs = {(s*b,) for s, b in zip(Bsigns, B)}
                for sol in my_itersolve(C.clauses | As | Bs):
                    a = [i in sol for i in A]
                    b = [i in sol for i in B]
                    m = [i in sol for i in merged]
                    # Check we did the above correctly
                    assert a == sorted(a, reverse=True)
                    assert b == sorted(b, reverse=True)
                    # And check that the merge is correct
                    assert m == sorted(a + b, reverse=True)

    assert raises(ValueError, lambda: Clauses(4).odd_even_merge([1, 2], [2, 3, 4]))
Example #4
0
    def gen_clauses(self, groups, trackers, specs):
        C = Clauses()

        def push_MatchSpec(ms):
            name = self.ms_to_v(ms)
            m = C.from_name(name)
            if m is None:
                libs = [fn for fn in self.find_matches_group(ms, groups, trackers)]
                m = C.Any(libs, polarity=None if ms.optional else True, name=name)
            return m

        # Create package variables
        for group in itervalues(groups):
            for fn in group:
                C.new_var(fn)

        # Create spec variables
        for ms in specs:
            push_MatchSpec(ms)

        # Create feature variables
        for name in iterkeys(trackers):
            push_MatchSpec(MatchSpec('@' + name))

        # Add dependency relationships
        for group in itervalues(groups):
            C.Require(C.AtMostOne_NSQ, group)
            for fn in group:
                for ms in self.ms_depends(fn):
                    if not ms.optional:
                        C.Require(C.Or, C.Not(fn), push_MatchSpec(ms))
        return C
Example #5
0
def test_cmp_clauses():
    # XXX: Is this i, j stuff necessary?
    for i in range(-1, 2, 2):  # [-1, 1]
        for j in range(-1, 2, 2):
            C = Clauses(2)
            x, y = C.Cmp(i * 1, j * 2)
            for sol in my_itersolve(C.clauses):
                f = i * 1 in sol
                g = j * 2 in sol
                M = x in sol
                m = y in sol
                assert M == max(f, g)
                assert m == min(f, g)

    C = Clauses(1)
    x, y = C.Cmp(1, -1)
    assert x, y == [true, false]  # true > false
    assert C.clauses == set([])

    C = Clauses(1)
    x, y = C.Cmp(1, 1)
    for sol in my_itersolve(C.clauses):
        f = 1 in sol
        M = x in sol
        m = y in sol
        assert M == max(f, f)
        assert m == min(f, f)
Example #6
0
def test_Cmp_bools():
    for f in [true, false]:
        for g in [true, false]:
            C = Clauses(2)
            x, y = C.Cmp(f, g)
            assert x == max(f, g)
            assert y == min(f, g)
            assert C.clauses == set([])

        C = Clauses(1)
        x, y = C.Cmp(f, 1)
        fb = boolize(f)
        # No better way to test this without defining true >= 1, which seems
        # like a bad idea. Should represent the order true >= 1 >= false.
        if fb:
            assert [x, y] == [true, 1]
        else:
            assert [x, y] == [1, false]

        C = Clauses(1)
        x, y = C.Cmp(1, f)
        fb = boolize(f)
        if fb:
            assert [x, y] == [true, 1]
        else:
            assert [x, y] == [1, false]
Example #7
0
def test_And_clauses():
    # XXX: Is this i, j stuff necessary?
    for i in range(-1, 2, 2): # [-1, 1]
        for j in range(-1, 2, 2):
            C = Clauses(2)
            x = C.And(i*1, j*2)
            for sol in my_itersolve({(x,)} | C.clauses):
                f = i*1 in sol
                g = j*2 in sol
                assert f and g
            for sol in my_itersolve({(-x,)} | C.clauses):
                f = i*1 in sol
                g = j*2 in sol
                assert not (f and g)

    C = Clauses(1)
    x = C.And(1, -1)
    assert x == false # x and ~x
    assert C.clauses == set([])

    C = Clauses(1)
    x = C.And(1, 1)
    for sol in my_itersolve({(x,)} | C.clauses):
        f = 1 in sol
        assert (f and f)
    for sol in my_itersolve({(-x,)} | C.clauses):
        f = 1 in sol
        assert not (f and f)
Example #8
0
def test_Xor_bools():
    for f in [true, false]:
        for g in [true, false]:
            C = Clauses(2)
            x = C.Xor(f, g)
            assert x == (true if (boolize(f) != boolize(g)) else false)
            assert C.clauses == set([])

        C = Clauses(1)
        x = C.Xor(f, 1)
        fb = boolize(f)
        if x in [true, false]:
            assert False
        else:
            for sol in my_itersolve({(x,)} | C.clauses):
                a = 1 in sol
                assert (fb != a)
            for sol in my_itersolve({(-x,)} | C.clauses):
                a = 1 in sol
                assert not (fb != a)

        C = Clauses(1)
        x = C.Xor(1, f)
        if x in [true, false]:
            assert False
        else:
            for sol in my_itersolve({(x,)} | C.clauses):
                a = 1 in sol
                assert not (fb == a)
            for sol in my_itersolve({(-x,)} | C.clauses):
                a = 1 in sol
                assert not not (fb == a)
Example #9
0
def test_Or_clauses():
    # XXX: Is this i, j stuff necessary?
    for i in range(-1, 2, 2): # [-1, 1]
        for j in range(-1, 2, 2):
            C = Clauses(2)
            x = C.Or(i*1, j*2)
            for sol in my_itersolve({(x,)} | C.clauses):
                f = i*1 in sol
                g = j*2 in sol
                assert f or g
            for sol in my_itersolve({(-x,)} | C.clauses):
                f = i*1 in sol
                g = j*2 in sol
                assert not (f or g)

    C = Clauses(1)
    x = C.Or(1, -1)
    assert x == true # x or ~x
    assert C.clauses == set([])

    C = Clauses(1)
    x = C.Or(1, 1)
    for sol in my_itersolve({(x,)} | C.clauses):
        f = 1 in sol
        assert (f or f)
    for sol in my_itersolve({(-x,)} | C.clauses):
        f = 1 in sol
        assert not (f or f)
Example #10
0
def test_minimize():
    # minimize    x1 + 2 x2 + 3 x3 + ... + 10 x10
    # subject to  x1 + x2 + x3 + x4 + x5  == 1
    #             x6 + x7 + x8 + x9 + x10 == 1
    C = Clauses(10)
    C.Require(C.ExactlyOne, range(1, 6))
    C.Require(C.ExactlyOne, range(6, 11))
    objective = [(k, k) for k in range(1, 11)]
    sol = C.sat()
    C.unsat = True
    assert C.minimize(objective, sol)[1] == 56
    C.unsat = False
    sol2, sval = C.minimize(objective, sol)
    assert C.minimize(objective, sol)[1] == 7, (objective, sol2, sval)
Example #11
0
def test_sat():
    C = Clauses()
    C.new_var('x1')
    C.new_var('x2')
    assert C.sat([(+1, ), (+2, )], names=True) == {'x1', 'x2'}
    assert C.sat([(-1, ), (+2, )], names=True) == {'x2'}
    assert C.sat([(-1, ), (-2, )], names=True) == set()
    assert C.sat([(+1, ), (-1, )], names=True) is None
    C.unsat = True
    assert C.sat() is None
    assert len(Clauses(10).sat([[1]])) == 10
Example #12
0
    def gen_clauses(self, specs):
        C = Clauses()

        # Creates a variable that represents the proposition:
        #     Does the package set include package "fn"?
        for name, group in iteritems(self.groups):
            for fkey in group:
                C.new_var(fkey)
            # Install no more than one version of each package
            C.Require(C.AtMostOne, group)
            # Create an on/off variable for the entire group
            name = self.ms_to_v(name)
            C.name_var(C.Any(group, polarity=None, name=name), name+'?')

        # Creates a variable that represents the proposition:
        #    Does the package set include track_feature "feat"?
        for name, group in iteritems(self.trackers):
            name = self.ms_to_v('@' + name)
            C.name_var(C.Any(group, polarity=None, name=name), name+'?')

        # Create propositions that assert:
        #     If package "fn" is installed, its dependencie must be satisfied
        for group in itervalues(self.groups):
            for fkey in group:
                nkey = C.Not(fkey)
                for ms in self.ms_depends(fkey):
                    if not ms.optional:
                        C.Require(C.Or, nkey, self.push_MatchSpec(C, ms))
        return C
Example #13
0
    def gen_clauses(self, groups, trackers, specs):
        C = Clauses()

        # Creates a variable that represents the proposition:
        #     Does the package set include a package that matches MatchSpec "ms"?
        def push_MatchSpec(ms):
            name = self.ms_to_v(ms)
            m = C.from_name(name)
            if m is None:
                libs = [fn for fn in self.find_matches_group(ms, groups, trackers)]
                # If the MatchSpec is optional, then there may be cases where we want
                # to assert that it is *not* True. This requires polarity=None.
                m = C.Any(libs, polarity=None if ms.optional else True, name=name)
            return m

        # Creates a variable that represents the proposition:
        #     Does the package set include package "fn"?
        for group in itervalues(groups):
            for fn in group:
                C.new_var(fn)
            # Install no more than one version of each package
            C.Require(C.AtMostOne, group)

        # Create a variable that represents the proposition:
        #     Is the feature "name" active in this package set?
        # We mark this as "optional" below because sometimes we need to be able to
        # assert the proposition is False during the feature minimization pass.
        for name in iterkeys(trackers):
            ms = MatchSpec('@' + name)
            ms.optional = True
            push_MatchSpec(ms)

        # Create a variable that represents the proposition:
        #     Is the MatchSpec "ms" satisfied by the current package set?
        for ms in specs:
            push_MatchSpec(ms)

        # Create propositions that assert:
        #     If package "fn" is installed, its dependencie must be satisfied
        for group in itervalues(groups):
            for fn in group:
                for ms in self.ms_depends(fn):
                    if not ms.optional:
                        C.Require(C.Or, C.Not(fn), push_MatchSpec(ms))
        return C
Example #14
0
def test_odd_even_mergesort():
    for n in [1, 2, 4, 8]:
        A = list(range(1, n+1))
        C = Clauses(n)
        S = C.odd_even_mergesort(A)
        # Note, the zero-one principle states we only need to test lists of
        # 0's and
        # 1's. https://en.wikipedia.org/wiki/Sorting_network#Zero-one_principle.
        for sol in my_itersolve(C.clauses):
            a = [i in sol for i in A]
            s = [i in sol for i in S]
            assert s == sorted(a, reverse=True)

    # TODO: n > 8 takes too long to test all combinations, but maybe we should test
    # some random combinations.

    assert raises(ValueError, lambda: Clauses(5).odd_even_mergesort([1, 2, 3,
    4, 5]))

    # Make sure it works with booleans
    for n in [1, 2, 4]:
        for item in product(*[[true, false]]*n):
            assert list(Clauses(0).odd_even_mergesort(item)) == sorted(item, reverse=True)

    # The most important use-case is extending a non-power of 2 length list
    # with false.
    for n in range(1, 9):
        next_power_of_2 = 2**ceil(log2(n))
        assert n <= next_power_of_2
        for item in product(*[[true, false]]*(next_power_of_2 - n)):

            A = list(range(1, n + 1)) + list(item)
            C = Clauses(n)
            S = C.odd_even_mergesort(A)

            for sol in my_itersolve(C.clauses):
                a = [boolize(i) if isinstance(boolize(i), bool) else
                    i in sol for i in A]
                s = [boolize(i) if isinstance(boolize(i), bool) else
                    i in sol for i in S]

                assert s == sorted(a, reverse=True), (a, s, sol)
Example #15
0
def test_BDD():
    L = [
        ([(1, 1), (2, 2)], [0, 2], 10000),
        ([(1, 1), (2, -2)], [0, 2], 10000),
        ([(1, 1), (2, 2), (3, 3)], [3, 3], 10000),
        ([(0, 1), (1, 2), (2, 3), (0, 4), (1, 5), (0, 6), (1, 7)], [0, 2], 10000),
        ([(1, 15), (2, 16), (3, 17), (4, 18), (5, 6), (5, 19), (6, 7),
          (6, 20), (7, 8), (7, 21), (7, 28), (8, 9), (8, 22), (8, 29), (8, 41), (9,
          10), (9, 23), (9, 30), (9, 42), (10, 1), (10, 11), (10, 24), (10, 31),
          (10, 34), (10, 37), (10, 43), (10, 46), (10, 50), (11, 2), (11, 12), (11,
          25), (11, 32), (11, 35), (11, 38), (11, 44), (11, 47), (11, 51), (12, 3),
          (12, 4), (12, 5), (12, 13), (12, 14), (12, 26), (12, 27), (12, 33), (12,
          36), (12, 39), (12, 40), (12, 45), (12, 48), (12, 49), (12, 52), (12, 53),
          (12, 54)], [192, 204], 100),
        ([(0, 12), (0, 14), (0, 22), (0, 59), (0, 60), (0, 68), (0,
        102), (0, 105), (0, 164), (0, 176), (0, 178), (0, 180), (0, 182), (1,
            9), (1, 13), (1, 21), (1, 58), (1, 67), (1, 101), (1, 104), (1,
                163), (1, 175), (1, 177), (1, 179), (1, 181), (2, 6), (2, 20),
        (2, 57), (2, 66), (2, 100), (2, 103), (2, 162), (2, 174), (3, 11), (3,
            19), (3, 56), (3, 65), (3, 99), (3, 161), (3, 173), (4, 8), (4,
                18), (4, 55), (4, 64), (4, 98), (4, 160), (4, 172), (5, 5),
        (5, 17), (5, 54), (5, 63), (5, 97), (5, 159), (5, 171), (6, 10), (6,
            16), (6, 52), (6, 62), (6, 96), (6, 158), (6, 170), (7, 7), (7,
                15), (7, 50), (7, 61), (7, 95), (7, 157), (7, 169), (8, 4),
        (8, 48), (8, 94), (8, 156), (8, 168), (9, 3), (9, 46), (9, 93), (9,
            155), (9, 167), (10, 2), (10, 53), (10, 92), (10, 154), (10, 166),
        (11, 1), (11, 51), (11, 91), (11, 152), (11, 165), (12, 49), (12, 90),
        (12, 150), (13, 47), (13, 89), (13, 148), (14, 45), (14, 88), (14,
            146), (15, 39), (15, 87), (15, 144), (16, 38), (16, 86), (16,
                142), (17, 37), (17, 85), (17, 140), (18, 44), (18, 84), (18,
                    138), (19, 43), (19, 83), (19, 153), (20, 42), (20, 82),
        (20, 151), (21, 41), (21, 81), (21, 149), (22, 40), (22, 80), (22,
            147), (23, 36), (23, 79), (23, 145), (24, 32), (24, 70), (24,
                143), (25, 35), (25, 78), (25, 141), (26, 34), (26, 77), (26,
                    139), (27, 31), (27, 76), (27, 137), (28, 30), (28, 75),
        (28, 136), (29, 33), (29, 74), (29, 135), (30, 29), (30, 73), (30,
            134), (31, 28), (31, 72), (31, 133), (32, 27), (32, 71), (32,
                132), (33, 25), (33, 69), (33, 131), (34, 24), (34, 130), (35,
                    26), (35, 129), (36, 23), (36, 128), (37, 125), (38, 124),
        (39, 123), (40, 122), (41, 121), (42, 120), (43, 119), (44, 118), (45,
            117), (46, 116), (47, 115), (48, 114), (49, 113), (50, 127), (51,
                126), (52, 112), (53, 111), (54, 110), (55, 109), (56, 108),
        (57, 107), (58, 106)], [21, 40], 1000)
        ]
    for eq, rhs, max_iter in L:
        N = max(a for c,a in eq)
        C = Clauses(N)
        Cneg = Clauses(N)
        Cpos = Clauses(N)
        x = C.build_BDD(eq, rhs[0], rhs[1])
        xneg = Cneg.build_BDD(eq, rhs[0], rhs[1], polarity=False)
        xpos = Cpos.build_BDD(eq, rhs[0], rhs[1], polarity=True)
        for _, sol in zip(range(max_iter), my_itersolve([(x,)] + C.clauses)):
            assert rhs[0] <= evaluate_eq(eq,sol) <= rhs[1]
        for _, sol in zip(range(max_iter), my_itersolve([(xpos,)] + Cpos.clauses)):
            assert rhs[0] <= evaluate_eq(eq,sol) <= rhs[1]
        for _, sol in zip(range(max_iter), my_itersolve([(-x,)] + C.clauses)):
            assert not(rhs[0] <= evaluate_eq(eq,sol) <= rhs[1])
        for _, sol in zip(range(max_iter), my_itersolve([(-xneg,)] + Cneg.clauses)):
            assert not(rhs[0] <= evaluate_eq(eq,sol) <= rhs[1])
Example #16
0
def test_sat():
    C = Clauses()
    C.new_var('x1')
    C.new_var('x2')
    assert C.sat([(+1,),(+2,)], names=True) == {'x1','x2'}
    assert C.sat([(-1,),(+2,)], names=True) == {'x2'}
    assert C.sat([(-1,),(-2,)], names=True) == set()
    assert C.sat([(+1,),(-1,)], names=True) is None
    C.unsat = True
    assert C.sat() is None
    assert len(Clauses(10).sat([[1]])) == 10
Example #17
0
def test_odd_even_mergesort():
    for n in [1, 2, 4, 8]:
        A = list(range(1, n + 1))
        C = Clauses(n)
        S = C.odd_even_mergesort(A)
        # Note, the zero-one principle states we only need to test lists of
        # 0's and
        # 1's. https://en.wikipedia.org/wiki/Sorting_network#Zero-one_principle.
        for sol in my_itersolve(C.clauses):
            a = [i in sol for i in A]
            s = [i in sol for i in S]
            assert s == sorted(a, reverse=True)

    # TODO: n > 8 takes too long to test all combinations, but maybe we should test
    # some random combinations.

    assert raises(ValueError,
                  lambda: Clauses(5).odd_even_mergesort([1, 2, 3, 4, 5]))

    # Make sure it works with booleans
    for n in [1, 2, 4]:
        for item in product(*[[true, false]] * n):
            assert list(Clauses(0).odd_even_mergesort(item)) == sorted(
                item, reverse=True)

    # The most important use-case is extending a non-power of 2 length list
    # with false.
    for n in range(1, 9):
        next_power_of_2 = 2**ceil(log2(n))
        assert n <= next_power_of_2
        for item in product(*[[true, false]] * (next_power_of_2 - n)):

            A = list(range(1, n + 1)) + list(item)
            C = Clauses(n)
            S = C.odd_even_mergesort(A)

            for sol in my_itersolve(C.clauses):
                a = [
                    boolize(i) if isinstance(boolize(i), bool) else i in sol
                    for i in A
                ]
                s = [
                    boolize(i) if isinstance(boolize(i), bool) else i in sol
                    for i in S
                ]

                assert s == sorted(a, reverse=True), (a, s, sol)
Example #18
0
def test_AMONE():
    my_TEST(my_AMONE, Clauses.AtMostOne_NSQ, 0, 3, True)
    my_TEST(my_AMONE, Clauses.AtMostOne_BDD, 0, 3, True)
    my_TEST(my_AMONE, Clauses.AtMostOne, 0, 3, True)
    C1 = Clauses(10)
    x1 = C1.AtMostOne_BDD((1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
    C2 = Clauses(10)
    x2 = C2.AtMostOne((1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
    assert x1 == x2 and C1.clauses == C2.clauses
Example #19
0
def test_minimize():
    # minimize    x1 + 2 x2 + 3 x3 + ... + 10 x10
    # subject to  x1 + x2 + x3 + x4 + x5  == 1
    #             x6 + x7 + x8 + x9 + x10 == 1
    C = Clauses(10)
    C.Require(C.ExactlyOne, range(1,6))
    C.Require(C.ExactlyOne, range(6,11))
    objective = [(k,k) for k in range(1,11)]
    sol = C.sat()
    C.unsat = True
    assert C.minimize(objective, sol)[1] == 56
    C.unsat = False
    sol2, sval = C.minimize(objective, sol)
    assert C.minimize(objective, sol)[1] == 7, (objective, sol2, sval)
Example #20
0
    def gen_clauses(self, groups, trackers, specs):
        C = Clauses()

        # Creates a variable that represents the proposition:
        #     Does the package set include a package that matches MatchSpec "ms"?
        def push_MatchSpec(ms):
            name = self.ms_to_v(ms)
            m = C.from_name(name)
            if m is None:
                libs = [
                    fn for fn in self.find_matches_group(ms, groups, trackers)
                ]
                # If the MatchSpec is optional, then there may be cases where we want
                # to assert that it is *not* True. This requires polarity=None.
                m = C.Any(libs,
                          polarity=None if ms.optional else True,
                          name=name)
            return m

        # Creates a variable that represents the proposition:
        #     Does the package set include package "fn"?
        for group in itervalues(groups):
            for fn in group:
                C.new_var(fn)
            # Install no more than one version of each package
            C.Require(C.AtMostOne, group)

        # Create a variable that represents the proposition:
        #     Is the feature "name" active in this package set?
        # We mark this as "optional" below because sometimes we need to be able to
        # assert the proposition is False during the feature minimization pass.
        for name in iterkeys(trackers):
            ms = MatchSpec('@' + name)
            ms.optional = True
            push_MatchSpec(ms)

        # Create a variable that represents the proposition:
        #     Is the MatchSpec "ms" satisfied by the current package set?
        for ms in specs:
            push_MatchSpec(ms)

        # Create propositions that assert:
        #     If package "fn" is installed, its dependencie must be satisfied
        for group in itervalues(groups):
            for fn in group:
                for ms in self.ms_depends(fn):
                    if not ms.optional:
                        C.Require(C.Or, C.Not(fn), push_MatchSpec(ms))
        return C
Example #21
0
def test_minimize():
    # minimize    x1 + 2 x2 + 3 x3 + 4 x4 + 5 x5
    # subject to  x1 + x2 + x3 + x4 + x5  == 1
    C = Clauses(15)
    C.Require(C.ExactlyOne, range(1,6))
    sol = C.sat()
    C.unsat = True
    # Unsatisfiable constraints
    assert C.minimize([(k,k) for k in range(1,6)], sol)[1] == 16
    C.unsat = False
    sol, sval = C.minimize([(k,k) for k in range(1,6)], sol)
    assert sval == 1
    C.Require(C.ExactlyOne, range(6,11))
    # Supply an initial vector that is too short, forcing recalculation
    sol, sval = C.minimize([(k,k) for k in range(6,11)], sol)
    assert sval == 6
    C.Require(C.ExactlyOne, range(11,16))
    # Don't supply an initial vector
    sol, sval = C.minimize([(k,k) for k in range(11,16)])
    assert sval == 11
Example #22
0
def test_Xor_clauses():
    # XXX: Is this i, j stuff necessary?
    for i in range(-1, 2, 2): # [-1, 1]
        for j in range(-1, 2, 2):
            C = Clauses(2)
            x = C.Xor(i*1, j*2)
            for sol in my_itersolve({(x,)} | C.clauses):
                f = i*1 in sol
                g = j*2 in sol
                assert (f != g)
            for sol in my_itersolve({(-x,)} | C.clauses):
                f = i*1 in sol
                g = j*2 in sol
                assert not (f != g)

    C = Clauses(1)
    x = C.Xor(1, 1)
    assert x == false # x xor x
    assert C.clauses == set([])

    C = Clauses(1)
    x = C.Xor(1, -1)
    assert x == true # x xor -x
    assert C.clauses == set([])
Example #23
0
def test_And_bools():
    for f in [true, false]:
        for g in [true, false]:
            C = Clauses(2)
            x = C.And(f, g)
            assert x == (true if (boolize(f) and boolize(g)) else false)
            assert C.clauses == set([])

        C = Clauses(1)
        x = C.And(f, 1)
        fb = boolize(f)
        if x in [true, false]:
            assert C.clauses == set([])
            xb = boolize(x)
            assert xb == (fb and NoBool())
        else:
            for sol in my_itersolve({(x,)} | C.clauses):
                a = 1 in sol
                assert (fb and a)
            for sol in my_itersolve({(-x,)} | C.clauses):
                a = 1 in sol
                assert not (fb and a)

        C = Clauses(1)
        x = C.And(1, f)
        if x in [true, false]:
            assert C.clauses == set([])
            xb = boolize(x)
            assert xb == (fb and NoBool())
        else:
            for sol in my_itersolve({(x,)} | C.clauses):
                a = 1 in sol
                assert (fb and a)
            for sol in my_itersolve({(-x,)} | C.clauses):
                a = 1 in sol
                assert not (fb and a)
Example #24
0
    def gen_clauses(self, groups, trackers, specs):
        C = Clauses()
        polarities = {}

        def push_MatchSpec(ms, polarity=None):
            name = self.ms_to_v(ms)
            m = C.from_name(name)
            if m is None:
                m = C.Any(self.find_matches_group(ms, groups, trackers),
                          polarity=polarity,
                          name=name)
            return m

        # Create package variables
        for group in itervalues(groups):
            for fn in group:
                C.new_var(fn)

        # Create spec variables
        for ms in specs:
            push_MatchSpec(ms, polarity=None if ms.optional else True)

        # Create feature variables
        for name in iterkeys(trackers):
            push_MatchSpec(MatchSpec('@' + name), polarity=True)

        # Add dependency relationships
        for group in itervalues(groups):
            C.Require(C.AtMostOne_NSQ, group)
            for fn in group:
                for ms in self.ms_depends(fn):
                    if not ms.optional:
                        C.Require(C.Or, C.Not(fn),
                                  push_MatchSpec(ms, polarity=True))

        return C
Example #25
0
 def sat(val, m=1):
     return Clauses(m).sat(val)
Example #26
0
def my_TEST(Mfunc, Cfunc, mmin, mmax, is_iter):
    for m in range(mmin, mmax + 1):
        if m == 0:
            ijprod = [()]
        else:
            ijprod = (True, False) + sum(
                ((k, my_NOT(k)) for k in range(1, m + 1)), ())
            ijprod = product(ijprod, repeat=m)
        for ij in ijprod:
            C = Clauses()
            Cpos = Clauses()
            Cneg = Clauses()
            for k in range(1, m + 1):
                nm = 'x%d' % k
                C.new_var(nm)
                Cpos.new_var(nm)
                Cneg.new_var(nm)
            ij2 = tuple(C.from_index(k) if type(k) is int else k for k in ij)
            if is_iter:
                x = Cfunc.__get__(C, Clauses)(ij2)
                Cpos.Require(Cfunc.__get__(Cpos, Clauses), ij)
                Cneg.Prevent(Cfunc.__get__(Cneg, Clauses), ij)
            else:
                x = Cfunc.__get__(C, Clauses)(*ij2)
                Cpos.Require(Cfunc.__get__(Cpos, Clauses), *ij)
                Cneg.Prevent(Cfunc.__get__(Cneg, Clauses), *ij)
            tsol = Mfunc(*ij)
            if type(tsol) is bool:
                assert x is tsol, (ij2, Cfunc.__name__, C.clauses)
                assert Cpos.unsat == (not tsol) and not Cpos.clauses, (
                    ij, 'Require(%s)')
                assert Cneg.unsat == tsol and not Cneg.clauses, (ij,
                                                                 'Prevent(%s)')
                continue
            for sol in C.itersolve([(x, )]):
                qsol = Mfunc(*my_SOL(ij, sol))
                assert qsol is True, (ij2, sol, Cfunc.__name__, C.clauses)
            for sol in Cpos.itersolve([]):
                qsol = Mfunc(*my_SOL(ij, sol))
                assert qsol is True, (ij, sol, 'Require(%s)' % Cfunc.__name__,
                                      Cpos.clauses)
            for sol in C.itersolve([(C.Not(x), )]):
                qsol = Mfunc(*my_SOL(ij, sol))
                assert qsol is False, (ij2, sol, Cfunc.__name__, C.clauses)
            for sol in Cneg.itersolve([]):
                qsol = Mfunc(*my_SOL(ij, sol))
                assert qsol is False, (ij, sol, 'Prevent(%s)' % Cfunc.__name__,
                                       Cneg.clauses)
Example #27
0
    def gen_clauses(self, specs):
        C = Clauses()

        # Creates a variable that represents the proposition:
        #     Does the package set include package "fn"?
        for name, group in iteritems(self.groups):
            for fkey in group:
                C.new_var(fkey)
            # Install no more than one version of each package
            C.Require(C.AtMostOne, group)
            # Create an on/off variable for the entire group
            name = self.ms_to_v(name)
            C.name_var(C.Any(group, polarity=None, name=name), name+'?')

        # Creates a variable that represents the proposition:
        #    Does the package set include track_feature "feat"?
        for name, group in iteritems(self.trackers):
            name = self.ms_to_v('@' + name)
            C.name_var(C.Any(group, polarity=None, name=name), name+'?')

        # Create propositions that assert:
        #     If package "fn" is installed, its dependencie must be satisfied
        for group in itervalues(self.groups):
            for fkey in group:
                nkey = C.Not(fkey)
                for ms in self.ms_depends(fkey):
                    if not ms.optional:
                        C.Require(C.Or, nkey, self.push_MatchSpec(C, ms))
        return C
Example #28
0
def test_sorter():
    L = [
        Linear([(1, 1), (2, 2)], [0, 2]),
        Linear([(1, 1), (2, -2)], [0, 2]),
        Linear([(1, 1), (2, 2), (3, 3)], [3, 3]),
        Linear([(0, 1), (1, 2), (2, 3), (0, 4), (1, 5), (0, 6), (1, 7)], [0, 2])
        ]
    for l in L:
        C = Clauses(max(l.atoms))
        m = C.build_sorter(l)
        if l.rhs[0]:
            x = {(m[l.rhs[0]-1],), (-m[l.rhs[1]],)}
            nx = {(-m[l.rhs[0]-1], m[l.rhs[1]])}
        else:
            x = {(-m[l.rhs[1]],)}
            nx = {(m[l.rhs[1]],)}
        for sol in my_itersolve(x | C.clauses):
            assert l(sol)
        for sol in my_itersolve(nx | C.clauses):
            assert not l(sol)

    l = Linear([(1, 15), (2, 16), (3, 17), (4, 18), (5, 6), (5, 19), (6, 7),
    (6, 20), (7, 8), (7, 21), (7, 28), (8, 9), (8, 22), (8, 29), (8, 41), (9,
    10), (9, 23), (9, 30), (9, 42), (10, 1), (10, 11), (10, 24), (10, 31),
    (10, 34), (10, 37), (10, 43), (10, 46), (10, 50), (11, 2), (11, 12), (11,
    25), (11, 32), (11, 35), (11, 38), (11, 44), (11, 47), (11, 51), (12, 3),
    (12, 4), (12, 5), (12, 13), (12, 14), (12, 26), (12, 27), (12, 33), (12,
    36), (12, 39), (12, 40), (12, 45), (12, 48), (12, 49), (12, 52), (12, 53),
    (12, 54)], [192, 204])

    C = Clauses(max(l.atoms))
    m = C.build_sorter(l)
    if l.rhs[0]:
        x = {(m[l.rhs[0]-1],), (-m[l.rhs[1]],)}
        nx = {(-m[l.rhs[0]-1], m[l.rhs[1]])}
    else:
        x = {(-m[l.rhs[1]],)}
        nx = {(m[l.rhs[1]],)}
    for sol, _ in zip(my_itersolve(x | C.clauses), range(2)):
        assert l(sol)
    for sol, _ in zip(my_itersolve(nx | C.clauses), range(2)):
        assert not l(sol)

    l = Linear([(0, 12), (0, 14), (0, 22), (0, 59), (0, 60), (0, 68), (0,
        102), (0, 105), (0, 164), (0, 176), (0, 178), (0, 180), (0, 182), (1,
            9), (1, 13), (1, 21), (1, 58), (1, 67), (1, 101), (1, 104), (1,
                163), (1, 175), (1, 177), (1, 179), (1, 181), (2, 6), (2, 20),
        (2, 57), (2, 66), (2, 100), (2, 103), (2, 162), (2, 174), (3, 11), (3,
            19), (3, 56), (3, 65), (3, 99), (3, 161), (3, 173), (4, 8), (4,
                18), (4, 55), (4, 64), (4, 98), (4, 160), (4, 172), (5, 5),
        (5, 17), (5, 54), (5, 63), (5, 97), (5, 159), (5, 171), (6, 10), (6,
            16), (6, 52), (6, 62), (6, 96), (6, 158), (6, 170), (7, 7), (7,
                15), (7, 50), (7, 61), (7, 95), (7, 157), (7, 169), (8, 4),
        (8, 48), (8, 94), (8, 156), (8, 168), (9, 3), (9, 46), (9, 93), (9,
            155), (9, 167), (10, 2), (10, 53), (10, 92), (10, 154), (10, 166),
        (11, 1), (11, 51), (11, 91), (11, 152), (11, 165), (12, 49), (12, 90),
        (12, 150), (13, 47), (13, 89), (13, 148), (14, 45), (14, 88), (14,
            146), (15, 39), (15, 87), (15, 144), (16, 38), (16, 86), (16,
                142), (17, 37), (17, 85), (17, 140), (18, 44), (18, 84), (18,
                    138), (19, 43), (19, 83), (19, 153), (20, 42), (20, 82),
        (20, 151), (21, 41), (21, 81), (21, 149), (22, 40), (22, 80), (22,
            147), (23, 36), (23, 79), (23, 145), (24, 32), (24, 70), (24,
                143), (25, 35), (25, 78), (25, 141), (26, 34), (26, 77), (26,
                    139), (27, 31), (27, 76), (27, 137), (28, 30), (28, 75),
        (28, 136), (29, 33), (29, 74), (29, 135), (30, 29), (30, 73), (30,
            134), (31, 28), (31, 72), (31, 133), (32, 27), (32, 71), (32,
                132), (33, 25), (33, 69), (33, 131), (34, 24), (34, 130), (35,
                    26), (35, 129), (36, 23), (36, 128), (37, 125), (38, 124),
        (39, 123), (40, 122), (41, 121), (42, 120), (43, 119), (44, 118), (45,
            117), (46, 116), (47, 115), (48, 114), (49, 113), (50, 127), (51,
                126), (52, 112), (53, 111), (54, 110), (55, 109), (56, 108),
        (57, 107), (58, 106)], [21, 40])

    C = Clauses(max(l.atoms))
    print('building sorter')
    m = C.build_sorter(l)
    if l.rhs[0]:
        x = {(m[l.rhs[0]-1],), (-m[l.rhs[1]],)}
        nx = {(-m[l.rhs[0]-1], m[l.rhs[1]])}
    else:
        x = {(-m[l.rhs[1]],)}
        nx = {(m[l.rhs[1]],)}
    print('checking positive solutions')
    for sol, _ in zip(my_itersolve(x | C.clauses), range(2)):
        assert l(sol)
    print('checking negative solutions')
    for sol, _ in zip(my_itersolve(nx | C.clauses), range(2)):
        assert not l(sol)

    C = Clauses(0)
    assert C.build_sorter([]) == []
    assert not C.clauses
Example #29
0
def test_LinearBound():
    L = [
        ([], [0, 1], 10),
        ([], [1, 2], 10),
        ({'x1':2, 'x2':2}, [3, 3], 10),
        ({'x1':2, 'x2':2}, [0, 1], 1000),
        ({'x1':1, 'x2':2}, [0, 2], 1000),
        ({'x1':2, '!x2':2}, [0, 2], 1000),
        ([(1, 1), (2, 2), (3, 3)], [3, 3], 1000),
        ([(0, 1), (1, 2), (2, 3), (0, 4), (1, 5), (0, 6), (1, 7)], [0, 2], 1000),
        ([(0, 1), (1, 2), (2, 3), (0, 4), (1, 5), (0, 6), (1, 7),
          (3, False), (2, True)], [2, 4], 1000),
        ([(1, 15), (2, 16), (3, 17), (4, 18), (5, 6), (5, 19), (6, 7),
          (6, 20), (7, 8), (7, 21), (7, 28), (8, 9), (8, 22), (8, 29), (8, 41), (9,
          10), (9, 23), (9, 30), (9, 42), (10, 1), (10, 11), (10, 24), (10, 31),
          (10, 34), (10, 37), (10, 43), (10, 46), (10, 50), (11, 2), (11, 12), (11,
          25), (11, 32), (11, 35), (11, 38), (11, 44), (11, 47), (11, 51), (12, 3),
          (12, 4), (12, 5), (12, 13), (12, 14), (12, 26), (12, 27), (12, 33), (12,
          36), (12, 39), (12, 40), (12, 45), (12, 48), (12, 49), (12, 52), (12, 53),
          (12, 54)], [192, 204], 100),
        ]
    for eq, rhs, max_iter in L:
        if isinstance(eq, dict):
            N = len(eq)
        else:
            N = max([0]+[a for c,a in eq if a is not True and a is not False])
        C = Clauses(N)
        Cpos = Clauses(N)
        Cneg = Clauses(N)
        if isinstance(eq, dict):
            for k in range(1,N+1):
                nm = 'x%d'%k
                C.name_var(k, nm)
                Cpos.name_var(k, nm)
                Cneg.name_var(k, nm)
            eq2 = [(v,C.from_name(c)) for c,v in iteritems(eq)]
        else:
            eq2 = eq
        x = C.LinearBound(eq, rhs[0], rhs[1])
        Cpos.Require(Cpos.LinearBound, eq, rhs[0], rhs[1])
        Cneg.Prevent(Cneg.LinearBound, eq, rhs[0], rhs[1])
        if x is not False:
            for _, sol in zip(range(max_iter), C.itersolve([] if x is True else [(x,)],N)):
                assert rhs[0] <= my_EVAL(eq2,sol) <= rhs[1], C.clauses
        if x is not True:
            for _, sol in zip(range(max_iter), C.itersolve([] if x is True else [(C.Not(x),)],N)):
                assert not(rhs[0] <= my_EVAL(eq2,sol) <= rhs[1]), C.clauses
        for _, sol in zip(range(max_iter), Cpos.itersolve([],N)):
            assert rhs[0] <= my_EVAL(eq2,sol) <= rhs[1], ('Cpos',Cpos.clauses)
        for _, sol in zip(range(max_iter), Cneg.itersolve([],N)):
            assert not(rhs[0] <= my_EVAL(eq2,sol) <= rhs[1]), ('Cneg',Cneg.clauses)
Example #30
0
def test_minimize():
    # minimize    x1 + 2 x2 + 3 x3 + 4 x4 + 5 x5
    # subject to  x1 + x2 + x3 + x4 + x5  == 1
    C = Clauses(15)
    C.Require(C.ExactlyOne, range(1, 6))
    sol = C.sat()
    C.unsat = True
    # Unsatisfiable constraints
    assert C.minimize([(k, k) for k in range(1, 6)], sol)[1] == 16
    C.unsat = False
    sol, sval = C.minimize([(k, k) for k in range(1, 6)], sol)
    assert sval == 1
    C.Require(C.ExactlyOne, range(6, 11))
    # Supply an initial vector that is too short, forcing recalculation
    sol, sval = C.minimize([(k, k) for k in range(6, 11)], sol)
    assert sval == 6
    C.Require(C.ExactlyOne, range(11, 16))
    # Don't supply an initial vector
    sol, sval = C.minimize([(k, k) for k in range(11, 16)])
    assert sval == 11
Example #31
0
def test_BDD():
    L = [
        Linear([(1, 1), (2, 2)], [0, 2]),
        Linear([(1, 1), (2, -2)], [0, 2]),
        Linear([(1, 1), (2, 2), (3, 3)], [3, 3]),
        Linear([(0, 1), (1, 2), (2, 3), (0, 4), (1, 5), (0, 6), (1, 7)], [0, 2])
        ]
    for l in L:
        Cr = Clauses(max(l.atoms))
        Crneg = Clauses(max(l.atoms))
        Crpos = Clauses(max(l.atoms))
        xr = Cr.build_BDD_recursive(l)
        xrneg = Crneg.build_BDD_recursive(l, polarity=False)
        xrpos = Crpos.build_BDD_recursive(l, polarity=True)
        C = Clauses(max(l.atoms))
        Cneg = Clauses(max(l.atoms))
        Cpos = Clauses(max(l.atoms))
        x = C.build_BDD(l)
        xneg = Cneg.build_BDD(l, polarity=False)
        xpos = Cpos.build_BDD(l, polarity=True)
        assert x == xr
        assert xneg == xrneg
        assert xpos == xrpos
        assert C.clauses == Cr.clauses
        assert Cneg.clauses == Crneg.clauses
        assert Cpos.clauses == Crpos.clauses
        for sol in chain(my_itersolve({(x,)} | C.clauses),
            my_itersolve({(xpos,)} | Cpos.clauses)):
            assert l(sol)
        for sol in chain(my_itersolve({(-x,)} | C.clauses),
            my_itersolve({(-xneg,)} | Cneg.clauses)):
            assert not l(sol)

    # Real life example. There are too many solutions to check them all, just
    # check that building the BDD doesn't take forever
    l = Linear([(1, 15), (2, 16), (3, 17), (4, 18), (5, 6), (5, 19), (6, 7),
    (6, 20), (7, 8), (7, 21), (7, 28), (8, 9), (8, 22), (8, 29), (8, 41), (9,
    10), (9, 23), (9, 30), (9, 42), (10, 1), (10, 11), (10, 24), (10, 31),
    (10, 34), (10, 37), (10, 43), (10, 46), (10, 50), (11, 2), (11, 12), (11,
    25), (11, 32), (11, 35), (11, 38), (11, 44), (11, 47), (11, 51), (12, 3),
    (12, 4), (12, 5), (12, 13), (12, 14), (12, 26), (12, 27), (12, 33), (12,
    36), (12, 39), (12, 40), (12, 45), (12, 48), (12, 49), (12, 52), (12, 53),
    (12, 54)], [192, 204])

    Cr = Clauses(max(l.atoms))
    Crneg = Clauses(max(l.atoms))
    Crpos = Clauses(max(l.atoms))
    xr = Cr.build_BDD_recursive(l)
    xrneg = Crneg.build_BDD_recursive(l, polarity=False)
    xrpos = Crpos.build_BDD_recursive(l, polarity=True)
    C = Clauses(max(l.atoms))
    Cneg = Clauses(max(l.atoms))
    Cpos = Clauses(max(l.atoms))
    x = C.build_BDD(l)
    xneg = Cneg.build_BDD(l, polarity=False)
    xpos = Cpos.build_BDD(l, polarity=True)
    assert x == xr
    assert xneg == xrneg
    assert xpos == xrpos
    assert C.clauses == Cr.clauses
    assert Cneg.clauses == Crneg.clauses
    assert Cpos.clauses == Crpos.clauses

    for _, sol in zip(range(20), my_itersolve({(x,)} | C.clauses)):
        assert l(sol)
    for _, sol in zip(range(20), my_itersolve({(-x,)} | C.clauses)):
        assert not l(sol)

    for _, sol in zip(range(20), my_itersolve({(xpos,)} | Cpos.clauses)):
        assert l(sol)
    for _, sol in zip(range(20), my_itersolve({(-xneg,)} | Cneg.clauses)):
        assert not l(sol)

    # Another real-life example. This one is too big to be built recursively
    # unless the recursion limit is increased.
    l = Linear([(0, 12), (0, 14), (0, 22), (0, 59), (0, 60), (0, 68), (0,
        102), (0, 105), (0, 164), (0, 176), (0, 178), (0, 180), (0, 182), (1,
            9), (1, 13), (1, 21), (1, 58), (1, 67), (1, 101), (1, 104), (1,
                163), (1, 175), (1, 177), (1, 179), (1, 181), (2, 6), (2, 20),
        (2, 57), (2, 66), (2, 100), (2, 103), (2, 162), (2, 174), (3, 11), (3,
            19), (3, 56), (3, 65), (3, 99), (3, 161), (3, 173), (4, 8), (4,
                18), (4, 55), (4, 64), (4, 98), (4, 160), (4, 172), (5, 5),
        (5, 17), (5, 54), (5, 63), (5, 97), (5, 159), (5, 171), (6, 10), (6,
            16), (6, 52), (6, 62), (6, 96), (6, 158), (6, 170), (7, 7), (7,
                15), (7, 50), (7, 61), (7, 95), (7, 157), (7, 169), (8, 4),
        (8, 48), (8, 94), (8, 156), (8, 168), (9, 3), (9, 46), (9, 93), (9,
            155), (9, 167), (10, 2), (10, 53), (10, 92), (10, 154), (10, 166),
        (11, 1), (11, 51), (11, 91), (11, 152), (11, 165), (12, 49), (12, 90),
        (12, 150), (13, 47), (13, 89), (13, 148), (14, 45), (14, 88), (14,
            146), (15, 39), (15, 87), (15, 144), (16, 38), (16, 86), (16,
                142), (17, 37), (17, 85), (17, 140), (18, 44), (18, 84), (18,
                    138), (19, 43), (19, 83), (19, 153), (20, 42), (20, 82),
        (20, 151), (21, 41), (21, 81), (21, 149), (22, 40), (22, 80), (22,
            147), (23, 36), (23, 79), (23, 145), (24, 32), (24, 70), (24,
                143), (25, 35), (25, 78), (25, 141), (26, 34), (26, 77), (26,
                    139), (27, 31), (27, 76), (27, 137), (28, 30), (28, 75),
        (28, 136), (29, 33), (29, 74), (29, 135), (30, 29), (30, 73), (30,
            134), (31, 28), (31, 72), (31, 133), (32, 27), (32, 71), (32,
                132), (33, 25), (33, 69), (33, 131), (34, 24), (34, 130), (35,
                    26), (35, 129), (36, 23), (36, 128), (37, 125), (38, 124),
        (39, 123), (40, 122), (41, 121), (42, 120), (43, 119), (44, 118), (45,
            117), (46, 116), (47, 115), (48, 114), (49, 113), (50, 127), (51,
                126), (52, 112), (53, 111), (54, 110), (55, 109), (56, 108),
        (57, 107), (58, 106)], [21, 40])

    C = Clauses(max(l.atoms))
    Cpos = Clauses(max(l.atoms))
    Cneg = Clauses(max(l.atoms))
    x = C.build_BDD(l)
    xpos = Cpos.build_BDD(l, polarity=True)
    xneg = Cneg.build_BDD(l, polarity=False)
    for _, sol in zip(range(20), my_itersolve({(x,)} | C.clauses)):
        assert l(sol)
    for _, sol in zip(range(20), my_itersolve({(-x,)} | C.clauses)):
        assert not l(sol)
    for _, sol in zip(range(20), my_itersolve({(xpos,)} | Cpos.clauses)):
        assert l(sol)
    for _, sol in zip(range(20), my_itersolve({(-xneg,)} | Cneg.clauses)):
        assert not l(sol)
Example #32
0
def test_And_clauses():
    # XXX: Is this i, j stuff necessary?
    for i in range(-1, 2, 2):  # [-1, 1]
        for j in range(-1, 2, 2):
            C = Clauses(2)
            Cpos = Clauses(2)
            Cneg = Clauses(2)
            x = C.And(i * 1, j * 2)
            xpos = Cpos.And(i * 1, j * 2, polarity=True)
            xneg = Cneg.And(i * 1, j * 2, polarity=False)
            for sol in chain(my_itersolve({(x, )} | C.clauses),
                             my_itersolve({(xpos, )} | Cpos.clauses)):
                f = i * 1 in sol
                g = j * 2 in sol
                assert f and g
            for sol in chain(my_itersolve({(-x, )} | C.clauses),
                             my_itersolve({(-xneg, )} | Cneg.clauses)):
                f = i * 1 in sol
                g = j * 2 in sol
                assert not (f and g)

    C = Clauses(1)
    Cpos = Clauses(1)
    Cneg = Clauses(1)
    x = C.And(1, -1)
    xpos = Cpos.And(1, -1, polarity=True)
    xneg = Cneg.And(1, -1, polarity=False)
    assert x == xneg == xpos == false  # x and ~x
    assert C.clauses == Cpos.clauses == Cneg.clauses == set([])

    C = Clauses(1)
    Cpos = Clauses(1)
    Cneg = Clauses(1)
    x = C.And(1, 1)
    xpos = Cpos.And(1, 1, polarity=True)
    xneg = Cneg.And(1, 1, polarity=False)
    for sol in chain(my_itersolve({(x, )} | C.clauses),
                     my_itersolve({(xpos, )}
                                  | Cpos.clauses)):
        f = 1 in sol
        assert (f and f)
    for sol in chain(my_itersolve({(-x, )} | C.clauses),
                     my_itersolve({(-xneg, )} | Cneg.clauses)):
        f = 1 in sol
        assert not (f and f)
Example #33
0
def test_sorter():
    L = [
        Linear([(1, 1), (2, 2)], [0, 2]),
        Linear([(1, 1), (2, -2)], [0, 2]),
        Linear([(1, 1), (2, 2), (3, 3)], [3, 3]),
        Linear([(0, 1), (1, 2), (2, 3), (0, 4), (1, 5), (0, 6), (1, 7)],
               [0, 2])
    ]
    for l in L:
        C = Clauses(max(l.atoms))
        m = C.build_sorter(l)
        if l.rhs[0]:
            x = {(m[l.rhs[0] - 1], ), (-m[l.rhs[1]], )}
            nx = {(-m[l.rhs[0] - 1], m[l.rhs[1]])}
        else:
            x = {(-m[l.rhs[1]], )}
            nx = {(m[l.rhs[1]], )}
        for sol in my_itersolve(x | C.clauses):
            assert l(sol)
        for sol in my_itersolve(nx | C.clauses):
            assert not l(sol)

    l = Linear([(1, 15), (2, 16), (3, 17), (4, 18), (5, 6), (5, 19), (6, 7),
                (6, 20), (7, 8), (7, 21), (7, 28), (8, 9), (8, 22), (8, 29),
                (8, 41), (9, 10), (9, 23), (9, 30), (9, 42), (10, 1), (10, 11),
                (10, 24), (10, 31), (10, 34), (10, 37), (10, 43), (10, 46),
                (10, 50), (11, 2), (11, 12), (11, 25), (11, 32), (11, 35),
                (11, 38), (11, 44), (11, 47), (11, 51), (12, 3), (12, 4),
                (12, 5), (12, 13), (12, 14), (12, 26), (12, 27), (12, 33),
                (12, 36), (12, 39), (12, 40), (12, 45), (12, 48), (12, 49),
                (12, 52), (12, 53), (12, 54)], [192, 204])

    C = Clauses(max(l.atoms))
    m = C.build_sorter(l)
    if l.rhs[0]:
        x = {(m[l.rhs[0] - 1], ), (-m[l.rhs[1]], )}
        nx = {(-m[l.rhs[0] - 1], m[l.rhs[1]])}
    else:
        x = {(-m[l.rhs[1]], )}
        nx = {(m[l.rhs[1]], )}
    for sol, _ in zip(my_itersolve(x | C.clauses), range(2)):
        assert l(sol)
    for sol, _ in zip(my_itersolve(nx | C.clauses), range(2)):
        assert not l(sol)

    l = Linear([(0, 12), (0, 14), (0, 22), (0, 59), (0, 60), (0, 68), (0, 102),
                (0, 105), (0, 164), (0, 176), (0, 178), (0, 180), (0, 182),
                (1, 9), (1, 13), (1, 21), (1, 58), (1, 67), (1, 101), (1, 104),
                (1, 163), (1, 175), (1, 177), (1, 179), (1, 181), (2, 6),
                (2, 20), (2, 57), (2, 66), (2, 100), (2, 103), (2, 162),
                (2, 174), (3, 11), (3, 19), (3, 56), (3, 65), (3, 99),
                (3, 161), (3, 173), (4, 8), (4, 18), (4, 55), (4, 64), (4, 98),
                (4, 160), (4, 172), (5, 5), (5, 17), (5, 54), (5, 63), (5, 97),
                (5, 159), (5, 171), (6, 10),
                (6, 16), (6, 52), (6, 62), (6, 96), (6, 158), (6, 170), (7, 7),
                (7, 15), (7, 50), (7, 61), (7, 95), (7, 157), (7, 169), (8, 4),
                (8, 48), (8, 94), (8, 156), (8, 168), (9, 3), (9, 46), (9, 93),
                (9, 155), (9, 167), (10, 2), (10, 53), (10, 92), (10, 154),
                (10, 166), (11, 1), (11, 51), (11, 91), (11, 152), (11, 165),
                (12, 49), (12, 90), (12, 150), (13, 47), (13, 89), (13, 148),
                (14, 45), (14, 88), (14, 146), (15, 39), (15, 87), (15, 144),
                (16, 38), (16, 86), (16, 142), (17, 37), (17, 85), (17, 140),
                (18, 44), (18, 84), (18, 138), (19, 43), (19, 83), (19, 153),
                (20, 42), (20, 82), (20, 151), (21, 41), (21, 81), (21, 149),
                (22, 40), (22, 80), (22, 147), (23, 36), (23, 79), (23, 145),
                (24, 32), (24, 70), (24, 143), (25, 35), (25, 78), (25, 141),
                (26, 34), (26, 77), (26, 139), (27, 31), (27, 76), (27, 137),
                (28, 30), (28, 75), (28, 136), (29, 33), (29, 74), (29, 135),
                (30, 29), (30, 73), (30, 134), (31, 28), (31, 72), (31, 133),
                (32, 27), (32, 71), (32, 132), (33, 25), (33, 69), (33, 131),
                (34, 24), (34, 130), (35, 26), (35, 129), (36, 23), (36, 128),
                (37, 125), (38, 124), (39, 123), (40, 122), (41, 121),
                (42, 120), (43, 119), (44, 118), (45, 117), (46, 116),
                (47, 115), (48, 114), (49, 113), (50, 127), (51, 126),
                (52, 112), (53, 111), (54, 110), (55, 109), (56, 108),
                (57, 107), (58, 106)], [21, 40])

    C = Clauses(max(l.atoms))
    print('building sorter')
    m = C.build_sorter(l)
    if l.rhs[0]:
        x = {(m[l.rhs[0] - 1], ), (-m[l.rhs[1]], )}
        nx = {(-m[l.rhs[0] - 1], m[l.rhs[1]])}
    else:
        x = {(-m[l.rhs[1]], )}
        nx = {(m[l.rhs[1]], )}
    print('checking positive solutions')
    for sol, _ in zip(my_itersolve(x | C.clauses), range(2)):
        assert l(sol)
    print('checking negative solutions')
    for sol, _ in zip(my_itersolve(nx | C.clauses), range(2)):
        assert not l(sol)

    C = Clauses(0)
    assert C.build_sorter([]) == []
    assert not C.clauses
Example #34
0
def test_LinearBound():
    L = [
        ([], [0, 1], True),
        ([], [1, 2], False),
        ([(2, 1), (2, 2)], [3, 3], False),
        ([(2, 1), (2, 2)], [0, 1], 1000),
        ([(1, 1), (2, 2)], [0, 2], 1000),
        ([(1, 1), (2, -2)], [0, 2], 1000),
        ([(1, 1), (2, 2), (3, 3)], [3, 3], 1000),
        ([(0, 1), (1, 2), (2, 3), (0, 4), (1, 5), (0, 6), (1, 7)], [0,
                                                                    2], 1000),
        ([(0, 1), (1, 2), (2, 3), (0, 4), (1, 5), (0, 6), (1, 7), (3, False),
          (2, True)], [2, 4], 1000),
        ([(1, 15), (2, 16), (3, 17), (4, 18), (5, 6), (5, 19), (6, 7), (6, 20),
          (7, 8), (7, 21), (7, 28), (8, 9), (8, 22), (8, 29), (8, 41), (9, 10),
          (9, 23), (9, 30), (9, 42), (10, 1), (10, 11), (10, 24), (10, 31),
          (10, 34), (10, 37), (10, 43), (10, 46), (10, 50), (11, 2), (11, 12),
          (11, 25), (11, 32), (11, 35), (11, 38), (11, 44), (11, 47), (11, 51),
          (12, 3), (12, 4), (12, 5), (12, 13), (12, 14), (12, 26), (12, 27),
          (12, 33), (12, 36), (12, 39), (12, 40), (12, 45), (12, 48), (12, 49),
          (12, 52), (12, 53), (12, 54)], [192, 204], 100),
    ]
    for eq, rhs, max_iter in L:
        N = max([0] + [a for c, a in eq if a is not True and a is not False])
        C = Clauses(N)
        Cpos = Clauses(N)
        Cneg = Clauses(N)
        x = C.LinearBound(eq, rhs[0], rhs[1])
        Cpos.Require(Cpos.LinearBound, eq, rhs[0], rhs[1])
        Cneg.Prevent(Cneg.LinearBound, eq, rhs[0], rhs[1])
        if type(max_iter) is bool:
            assert x is max_iter, (ij, Cfunc.__name__, C.clauses)
            assert Cpos.unsat == (not max_iter) and not Cpos.clauses, (
                ij, 'Require(%s)')
            assert Cneg.unsat == max_iter and not Cneg.clauses, (ij,
                                                                 'Prevent(%s)')
            continue
        for _, sol in zip(range(max_iter), C.itersolve([(x, )], N)):
            assert rhs[0] <= my_EVAL(eq, sol) <= rhs[1], C.clauses
        for _, sol in zip(range(max_iter), C.itersolve([(C.Not(x), )], N)):
            assert not (rhs[0] <= my_EVAL(eq, sol) <= rhs[1]), C.clauses
        for _, sol in zip(range(max_iter), Cpos.itersolve([], N)):
            assert rhs[0] <= my_EVAL(eq, sol) <= rhs[1], ('Cpos', Cpos.clauses)
        for _, sol in zip(range(max_iter), Cneg.itersolve([], N)):
            assert not (rhs[0] <= my_EVAL(eq, sol) <= rhs[1]), ('Cneg',
                                                                Cneg.clauses)
Example #35
0
def test_BDD():
    L = [
        ([(1, 1), (2, 2)], [0, 2], 10000), ([(1, 1), (2, -2)], [0, 2], 10000),
        ([(1, 1), (2, 2), (3, 3)], [3, 3], 10000),
        ([(0, 1), (1, 2), (2, 3), (0, 4), (1, 5), (0, 6), (1, 7)], [0,
                                                                    2], 10000),
        ([(1, 15), (2, 16), (3, 17), (4, 18), (5, 6), (5, 19), (6, 7), (6, 20),
          (7, 8), (7, 21), (7, 28), (8, 9), (8, 22), (8, 29), (8, 41), (9, 10),
          (9, 23), (9, 30), (9, 42), (10, 1), (10, 11), (10, 24), (10, 31),
          (10, 34), (10, 37), (10, 43), (10, 46), (10, 50), (11, 2), (11, 12),
          (11, 25), (11, 32), (11, 35), (11, 38), (11, 44), (11, 47), (11, 51),
          (12, 3), (12, 4), (12, 5), (12, 13), (12, 14), (12, 26), (12, 27),
          (12, 33), (12, 36), (12, 39), (12, 40), (12, 45), (12, 48), (12, 49),
          (12, 52), (12, 53), (12, 54)], [192, 204], 100),
        ([(0, 12), (0, 14), (0, 22), (0, 59), (0, 60), (0, 68), (0, 102),
          (0, 105), (0, 164), (0, 176), (0, 178), (0, 180), (0, 182), (1, 9),
          (1, 13), (1, 21), (1, 58), (1, 67), (1, 101), (1, 104), (1, 163),
          (1, 175), (1, 177), (1, 179), (1, 181), (2, 6), (2, 20), (2, 57),
          (2, 66), (2, 100), (2, 103), (2, 162), (2, 174), (3, 11), (3, 19),
          (3, 56), (3, 65), (3, 99), (3, 161), (3, 173), (4, 8), (4, 18),
          (4, 55), (4, 64), (4, 98), (4, 160), (4, 172), (5, 5), (5, 17),
          (5, 54), (5, 63), (5, 97), (5, 159), (5, 171), (6, 10), (6, 16),
          (6, 52), (6, 62), (6, 96), (6, 158), (6, 170), (7, 7), (7, 15),
          (7, 50), (7, 61), (7, 95), (7, 157), (7, 169), (8, 4), (8, 48),
          (8, 94), (8, 156), (8, 168), (9, 3), (9, 46), (9, 93), (9, 155),
          (9, 167), (10, 2), (10, 53), (10, 92), (10, 154), (10, 166), (11, 1),
          (11, 51), (11, 91), (11, 152), (11, 165), (12, 49), (12, 90),
          (12, 150), (13, 47), (13, 89), (13, 148), (14, 45), (14, 88),
          (14, 146), (15, 39), (15, 87), (15, 144), (16, 38), (16, 86),
          (16, 142), (17, 37), (17, 85), (17, 140), (18, 44), (18, 84),
          (18, 138), (19, 43), (19, 83), (19, 153), (20, 42), (20, 82),
          (20, 151), (21, 41), (21, 81), (21, 149), (22, 40), (22, 80),
          (22, 147), (23, 36), (23, 79), (23, 145), (24, 32), (24, 70),
          (24, 143), (25, 35), (25, 78), (25, 141), (26, 34), (26, 77),
          (26, 139), (27, 31), (27, 76), (27, 137), (28, 30), (28, 75),
          (28, 136), (29, 33), (29, 74), (29, 135), (30, 29), (30, 73),
          (30, 134), (31, 28), (31, 72), (31, 133), (32, 27), (32, 71),
          (32, 132), (33, 25), (33, 69), (33, 131), (34, 24), (34, 130),
          (35, 26), (35, 129), (36, 23), (36, 128), (37, 125), (38, 124),
          (39, 123), (40, 122), (41, 121), (42, 120), (43, 119), (44, 118),
          (45, 117), (46, 116), (47, 115), (48, 114), (49, 113), (50, 127),
          (51, 126), (52, 112), (53, 111), (54, 110), (55, 109), (56, 108),
          (57, 107), (58, 106)], [21, 40], 1000)
    ]
    for eq, rhs, max_iter in L:
        N = max(a for c, a in eq)
        C = Clauses(N)
        Cneg = Clauses(N)
        Cpos = Clauses(N)
        x = C.build_BDD(eq, rhs[0], rhs[1])
        xneg = Cneg.build_BDD(eq, rhs[0], rhs[1], polarity=False)
        xpos = Cpos.build_BDD(eq, rhs[0], rhs[1], polarity=True)
        for _, sol in zip(range(max_iter), my_itersolve([(x, )] + C.clauses)):
            assert rhs[0] <= evaluate_eq(eq, sol) <= rhs[1]
        for _, sol in zip(range(max_iter),
                          my_itersolve([(xpos, )] + Cpos.clauses)):
            assert rhs[0] <= evaluate_eq(eq, sol) <= rhs[1]
        for _, sol in zip(range(max_iter), my_itersolve([(-x, )] + C.clauses)):
            assert not (rhs[0] <= evaluate_eq(eq, sol) <= rhs[1])
        for _, sol in zip(range(max_iter),
                          my_itersolve([(-xneg, )] + Cneg.clauses)):
            assert not (rhs[0] <= evaluate_eq(eq, sol) <= rhs[1])
Example #36
0
def test_LinearBound():
    L = [
        ([], [0, 1], 10),
        ([], [1, 2], 10),
        ({
            'x1': 2,
            'x2': 2
        }, [3, 3], 10),
        ({
            'x1': 2,
            'x2': 2
        }, [0, 1], 1000),
        ({
            'x1': 1,
            'x2': 2
        }, [0, 2], 1000),
        ({
            'x1': 2,
            '!x2': 2
        }, [0, 2], 1000),
        ([(1, 1), (2, 2), (3, 3)], [3, 3], 1000),
        ([(0, 1), (1, 2), (2, 3), (0, 4), (1, 5), (0, 6), (1, 7)], [0,
                                                                    2], 1000),
        ([(0, 1), (1, 2), (2, 3), (0, 4), (1, 5), (0, 6), (1, 7), (3, False),
          (2, True)], [2, 4], 1000),
        ([(1, 15), (2, 16), (3, 17), (4, 18), (5, 6), (5, 19), (6, 7), (6, 20),
          (7, 8), (7, 21), (7, 28), (8, 9), (8, 22), (8, 29), (8, 41), (9, 10),
          (9, 23), (9, 30), (9, 42), (10, 1), (10, 11), (10, 24), (10, 31),
          (10, 34), (10, 37), (10, 43), (10, 46), (10, 50), (11, 2), (11, 12),
          (11, 25), (11, 32), (11, 35), (11, 38), (11, 44), (11, 47), (11, 51),
          (12, 3), (12, 4), (12, 5), (12, 13), (12, 14), (12, 26), (12, 27),
          (12, 33), (12, 36), (12, 39), (12, 40), (12, 45), (12, 48), (12, 49),
          (12, 52), (12, 53), (12, 54)], [192, 204], 100),
    ]
    for eq, rhs, max_iter in L:
        if isinstance(eq, dict):
            N = len(eq)
        else:
            N = max([0] +
                    [a for c, a in eq if a is not True and a is not False])
        C = Clauses(N)
        Cpos = Clauses(N)
        Cneg = Clauses(N)
        if isinstance(eq, dict):
            for k in range(1, N + 1):
                nm = 'x%d' % k
                C.name_var(k, nm)
                Cpos.name_var(k, nm)
                Cneg.name_var(k, nm)
            eq2 = [(v, C.from_name(c)) for c, v in iteritems(eq)]
        else:
            eq2 = eq
        x = C.LinearBound(eq, rhs[0], rhs[1])
        Cpos.Require(Cpos.LinearBound, eq, rhs[0], rhs[1])
        Cneg.Prevent(Cneg.LinearBound, eq, rhs[0], rhs[1])
        if x is not False:
            for _, sol in zip(range(max_iter),
                              C.itersolve([] if x is True else [(x, )], N)):
                assert rhs[0] <= my_EVAL(eq2, sol) <= rhs[1], C.clauses
        if x is not True:
            for _, sol in zip(
                    range(max_iter),
                    C.itersolve([] if x is True else [(C.Not(x), )], N)):
                assert not (rhs[0] <= my_EVAL(eq2, sol) <= rhs[1]), C.clauses
        for _, sol in zip(range(max_iter), Cpos.itersolve([], N)):
            assert rhs[0] <= my_EVAL(eq2, sol) <= rhs[1], ('Cpos',
                                                           Cpos.clauses)
        for _, sol in zip(range(max_iter), Cneg.itersolve([], N)):
            assert not (rhs[0] <= my_EVAL(eq2, sol) <= rhs[1]), ('Cneg',
                                                                 Cneg.clauses)
Example #37
0
def my_TEST(Mfunc, Cfunc, mmin, mmax, is_iter):
    for m in range(mmin,mmax+1):
        if m == 0:
            ijprod = [()]
        else:
            ijprod = (True,False)+sum(((k,my_NOT(k)) for k in range(1,m+1)),())
            ijprod = product(ijprod, repeat=m)
        for ij in ijprod:
            C = Clauses()
            Cpos = Clauses()
            Cneg = Clauses()
            for k in range(1,m+1):
                nm = 'x%d' % k
                C.new_var(nm)
                Cpos.new_var(nm)
                Cneg.new_var(nm)
            ij2 = tuple(C.from_index(k) if type(k) is int else k for k in ij)
            if is_iter:
                x = Cfunc.__get__(C,Clauses)(ij2)
                Cpos.Require(Cfunc.__get__(Cpos,Clauses), ij)
                Cneg.Prevent(Cfunc.__get__(Cneg,Clauses), ij)
            else:
                x = Cfunc.__get__(C,Clauses)(*ij2)
                Cpos.Require(Cfunc.__get__(Cpos,Clauses), *ij)
                Cneg.Prevent(Cfunc.__get__(Cneg,Clauses), *ij)
            tsol = Mfunc(*ij)
            if type(tsol) is bool:
                assert x is tsol, (ij2, Cfunc.__name__, C.clauses)
                assert Cpos.unsat == (not tsol) and not Cpos.clauses, (ij, 'Require(%s)')
                assert Cneg.unsat == tsol and not Cneg.clauses, (ij, 'Prevent(%s)')
                continue
            for sol in C.itersolve([(x,)]):
                qsol = Mfunc(*my_SOL(ij,sol))
                assert qsol is True, (ij2, sol, Cfunc.__name__, C.clauses)
            for sol in Cpos.itersolve([]):
                qsol = Mfunc(*my_SOL(ij,sol))
                assert qsol is True, (ij, sol,'Require(%s)' % Cfunc.__name__, Cpos.clauses)
            for sol in C.itersolve([(C.Not(x),)]):
                qsol = Mfunc(*my_SOL(ij,sol))
                assert qsol is False, (ij2, sol, Cfunc.__name__, C.clauses)
            for sol in Cneg.itersolve([]):
                qsol = Mfunc(*my_SOL(ij,sol))
                assert qsol is False, (ij, sol,'Prevent(%s)' % Cfunc.__name__, Cneg.clauses)
Example #38
0
 def sat(val):
     return Clauses().sat(val)
Example #39
0
def test_BDD():
    L = [
        Linear([(1, 1), (2, 2)], [0, 2]),
        Linear([(1, 1), (2, -2)], [0, 2]),
        Linear([(1, 1), (2, 2), (3, 3)], [3, 3]),
        Linear([(0, 1), (1, 2), (2, 3), (0, 4), (1, 5), (0, 6), (1, 7)],
               [0, 2])
    ]
    for l in L:
        Cr = Clauses(max(l.atoms))
        Crneg = Clauses(max(l.atoms))
        Crpos = Clauses(max(l.atoms))
        xr = Cr.build_BDD_recursive(l)
        xrneg = Crneg.build_BDD_recursive(l, polarity=False)
        xrpos = Crpos.build_BDD_recursive(l, polarity=True)
        C = Clauses(max(l.atoms))
        Cneg = Clauses(max(l.atoms))
        Cpos = Clauses(max(l.atoms))
        x = C.build_BDD(l)
        xneg = Cneg.build_BDD(l, polarity=False)
        xpos = Cpos.build_BDD(l, polarity=True)
        assert x == xr
        assert xneg == xrneg
        assert xpos == xrpos
        assert C.clauses == Cr.clauses
        assert Cneg.clauses == Crneg.clauses
        assert Cpos.clauses == Crpos.clauses
        for sol in chain(my_itersolve({(x, )} | C.clauses),
                         my_itersolve({(xpos, )} | Cpos.clauses)):
            assert l(sol)
        for sol in chain(my_itersolve({(-x, )} | C.clauses),
                         my_itersolve({(-xneg, )} | Cneg.clauses)):
            assert not l(sol)

    # Real life example. There are too many solutions to check them all, just
    # check that building the BDD doesn't take forever
    l = Linear([(1, 15), (2, 16), (3, 17), (4, 18), (5, 6), (5, 19), (6, 7),
                (6, 20), (7, 8), (7, 21), (7, 28), (8, 9), (8, 22), (8, 29),
                (8, 41), (9, 10), (9, 23), (9, 30), (9, 42), (10, 1), (10, 11),
                (10, 24), (10, 31), (10, 34), (10, 37), (10, 43), (10, 46),
                (10, 50), (11, 2), (11, 12), (11, 25), (11, 32), (11, 35),
                (11, 38), (11, 44), (11, 47), (11, 51), (12, 3), (12, 4),
                (12, 5), (12, 13), (12, 14), (12, 26), (12, 27), (12, 33),
                (12, 36), (12, 39), (12, 40), (12, 45), (12, 48), (12, 49),
                (12, 52), (12, 53), (12, 54)], [192, 204])

    Cr = Clauses(max(l.atoms))
    Crneg = Clauses(max(l.atoms))
    Crpos = Clauses(max(l.atoms))
    xr = Cr.build_BDD_recursive(l)
    xrneg = Crneg.build_BDD_recursive(l, polarity=False)
    xrpos = Crpos.build_BDD_recursive(l, polarity=True)
    C = Clauses(max(l.atoms))
    Cneg = Clauses(max(l.atoms))
    Cpos = Clauses(max(l.atoms))
    x = C.build_BDD(l)
    xneg = Cneg.build_BDD(l, polarity=False)
    xpos = Cpos.build_BDD(l, polarity=True)
    assert x == xr
    assert xneg == xrneg
    assert xpos == xrpos
    assert C.clauses == Cr.clauses
    assert Cneg.clauses == Crneg.clauses
    assert Cpos.clauses == Crpos.clauses

    for _, sol in zip(range(20), my_itersolve({(x, )} | C.clauses)):
        assert l(sol)
    for _, sol in zip(range(20), my_itersolve({(-x, )} | C.clauses)):
        assert not l(sol)

    for _, sol in zip(range(20), my_itersolve({(xpos, )} | Cpos.clauses)):
        assert l(sol)
    for _, sol in zip(range(20), my_itersolve({(-xneg, )} | Cneg.clauses)):
        assert not l(sol)

    # Another real-life example. This one is too big to be built recursively
    # unless the recursion limit is increased.
    l = Linear([(0, 12), (0, 14), (0, 22), (0, 59), (0, 60), (0, 68), (0, 102),
                (0, 105), (0, 164), (0, 176), (0, 178), (0, 180), (0, 182),
                (1, 9), (1, 13), (1, 21), (1, 58), (1, 67), (1, 101), (1, 104),
                (1, 163), (1, 175), (1, 177), (1, 179), (1, 181), (2, 6),
                (2, 20), (2, 57), (2, 66), (2, 100), (2, 103), (2, 162),
                (2, 174), (3, 11), (3, 19), (3, 56), (3, 65), (3, 99),
                (3, 161), (3, 173), (4, 8), (4, 18), (4, 55), (4, 64), (4, 98),
                (4, 160), (4, 172), (5, 5), (5, 17), (5, 54), (5, 63), (5, 97),
                (5, 159), (5, 171), (6, 10),
                (6, 16), (6, 52), (6, 62), (6, 96), (6, 158), (6, 170), (7, 7),
                (7, 15), (7, 50), (7, 61), (7, 95), (7, 157), (7, 169), (8, 4),
                (8, 48), (8, 94), (8, 156), (8, 168), (9, 3), (9, 46), (9, 93),
                (9, 155), (9, 167), (10, 2), (10, 53), (10, 92), (10, 154),
                (10, 166), (11, 1), (11, 51), (11, 91), (11, 152), (11, 165),
                (12, 49), (12, 90), (12, 150), (13, 47), (13, 89), (13, 148),
                (14, 45), (14, 88), (14, 146), (15, 39), (15, 87), (15, 144),
                (16, 38), (16, 86), (16, 142), (17, 37), (17, 85), (17, 140),
                (18, 44), (18, 84), (18, 138), (19, 43), (19, 83), (19, 153),
                (20, 42), (20, 82), (20, 151), (21, 41), (21, 81), (21, 149),
                (22, 40), (22, 80), (22, 147), (23, 36), (23, 79), (23, 145),
                (24, 32), (24, 70), (24, 143), (25, 35), (25, 78), (25, 141),
                (26, 34), (26, 77), (26, 139), (27, 31), (27, 76), (27, 137),
                (28, 30), (28, 75), (28, 136), (29, 33), (29, 74), (29, 135),
                (30, 29), (30, 73), (30, 134), (31, 28), (31, 72), (31, 133),
                (32, 27), (32, 71), (32, 132), (33, 25), (33, 69), (33, 131),
                (34, 24), (34, 130), (35, 26), (35, 129), (36, 23), (36, 128),
                (37, 125), (38, 124), (39, 123), (40, 122), (41, 121),
                (42, 120), (43, 119), (44, 118), (45, 117), (46, 116),
                (47, 115), (48, 114), (49, 113), (50, 127), (51, 126),
                (52, 112), (53, 111), (54, 110), (55, 109), (56, 108),
                (57, 107), (58, 106)], [21, 40])

    C = Clauses(max(l.atoms))
    Cpos = Clauses(max(l.atoms))
    Cneg = Clauses(max(l.atoms))
    x = C.build_BDD(l)
    xpos = Cpos.build_BDD(l, polarity=True)
    xneg = Cneg.build_BDD(l, polarity=False)
    for _, sol in zip(range(20), my_itersolve({(x, )} | C.clauses)):
        assert l(sol)
    for _, sol in zip(range(20), my_itersolve({(-x, )} | C.clauses)):
        assert not l(sol)
    for _, sol in zip(range(20), my_itersolve({(xpos, )} | Cpos.clauses)):
        assert l(sol)
    for _, sol in zip(range(20), my_itersolve({(-xneg, )} | Cneg.clauses)):
        assert not l(sol)
Example #40
0
 def sat(val):
     return Clauses(max(abs(v) for v in chain(*val))).sat(val)
Example #41
0
def test_Or_bools():
    for f in [true, false]:
        for g in [true, false]:
            C = Clauses(2)
            Cpos = Clauses(2)
            Cneg = Clauses(2)
            x = C.Or(f, g)
            xpos = Cpos.Or(f, g, polarity=True)
            xneg = Cneg.Or(f, g, polarity=False)
            assert x == xpos == xneg == (true if
                                         (boolize(f) or boolize(g)) else false)
            assert C.clauses == Cpos.clauses == Cneg.clauses == set([])

        C = Clauses(1)
        Cpos = Clauses(1)
        Cneg = Clauses(1)
        x = C.Or(f, 1)
        xpos = Cpos.Or(f, 1, polarity=True)
        xneg = Cneg.Or(f, 1, polarity=False)
        fb = boolize(f)
        if x in [true, false]:
            assert C.clauses == Cpos.clauses == Cneg.clauses == set([])
            xb = boolize(x)
            xbpos = boolize(xpos)
            xbneg = boolize(xneg)
            assert xb == xbpos == xbneg == (fb or NoBool())
        else:
            for sol in chain(my_itersolve({(x, )} | C.clauses),
                             my_itersolve({(xpos, )} | Cpos.clauses)):
                a = 1 in sol
                assert (fb or a)
            for sol in chain(my_itersolve({(-x, )} | C.clauses),
                             my_itersolve({(-xneg, )} | Cneg.clauses)):
                a = 1 in sol
                assert not (fb or a)

        C = Clauses(1)
        Cpos = Clauses(1)
        Cneg = Clauses(1)
        x = C.Or(1, f)
        xpos = Cpos.Or(1, f, polarity=True)
        xneg = Cneg.Or(1, f, polarity=False)
        if x in [true, false]:
            assert C.clauses == Cpos.clauses == Cneg.clauses == set([])
            xb = boolize(x)
            xbpos = boolize(xpos)
            xbneg = boolize(xneg)
            assert xb == xbpos == xbneg == (fb or NoBool())
        else:
            for sol in chain(my_itersolve({(x, )} | C.clauses),
                             my_itersolve({(xpos, )} | Cpos.clauses)):
                a = 1 in sol
                assert (fb or a)
            for sol in chain(my_itersolve({(-x, )} | C.clauses),
                             my_itersolve({(-xneg, )} | Cneg.clauses)):
                a = 1 in sol
                assert not (fb or a)
Example #42
0
def test_Xor_bools():
    for f in [true, false]:
        for g in [true, false]:
            C = Clauses(2)
            Cpos = Clauses(2)
            Cneg = Clauses(2)
            x = C.Xor(f, g)
            xpos = Cpos.Xor(f, g, polarity=True)
            xneg = Cneg.Xor(f, g, polarity=False)
            assert x == xpos == xneg == (true if
                                         (boolize(f) != boolize(g)) else false)
            assert C.clauses == Cpos.clauses == Cneg.clauses == set([])

        C = Clauses(1)
        Cpos = Clauses(1)
        Cneg = Clauses(1)
        x = C.Xor(f, 1)
        xpos = Cpos.Xor(f, 1, polarity=True)
        xneg = Cneg.Xor(f, 1, polarity=False)
        fb = boolize(f)
        if x in [true, false] or xpos in [true, false
                                          ] or xneg in [true, false]:
            assert False
        else:
            for sol in chain(my_itersolve({(x, )} | C.clauses),
                             my_itersolve({(xpos, )} | Cpos.clauses)):
                a = 1 in sol
                assert (fb != a)
            for sol in chain(my_itersolve({(-x, )} | C.clauses),
                             my_itersolve({(-xneg, )} | Cneg.clauses)):
                a = 1 in sol
                assert not (fb != a)

        C = Clauses(1)
        Cpos = Clauses(1)
        Cneg = Clauses(1)
        x = C.Xor(1, f)
        xpos = Cpos.Xor(1, f, polarity=True)
        xneg = Cneg.Xor(1, f, polarity=False)
        if x in [true, false] or xpos in [true, false
                                          ] or xneg in [true, false]:
            assert False
        else:
            for sol in chain(my_itersolve({(x, )} | C.clauses),
                             my_itersolve({(xpos, )} | Cpos.clauses)):
                a = 1 in sol
                assert not (fb == a)
            for sol in chain(my_itersolve({(-x, )} | C.clauses),
                             my_itersolve({(-xneg, )} | Cneg.clauses)):
                a = 1 in sol
                assert not not (fb == a)
Example #43
0
def test_Xor_clauses():
    # XXX: Is this i, j stuff necessary?
    for i in range(-1, 2, 2):  # [-1, 1]
        for j in range(-1, 2, 2):
            C = Clauses(2)
            Cpos = Clauses(2)
            Cneg = Clauses(2)
            x = C.Xor(i * 1, j * 2)
            xpos = Cpos.Xor(i * 1, j * 2, polarity=True)
            xneg = Cneg.Xor(i * 1, j * 2, polarity=False)
            for sol in chain(my_itersolve([(x, )] + C.clauses),
                             my_itersolve([(xpos, )] + Cpos.clauses)):
                f = i * 1 in sol
                g = j * 2 in sol
                assert (f != g)
            for sol in chain(my_itersolve([(-x, )] + C.clauses),
                             my_itersolve([(-xneg, )] + Cneg.clauses)):
                f = i * 1 in sol
                g = j * 2 in sol
                assert not (f != g)

    C = Clauses(1)
    Cpos = Clauses(1)
    Cneg = Clauses(1)
    x = C.Xor(1, 1)
    xpos = Cpos.Xor(1, 1, polarity=True)
    xneg = Cneg.Xor(1, 1, polarity=False)
    assert x == xpos == xneg == false  # x xor x
    assert C.clauses == Cpos.clauses == Cneg.clauses == []

    C = Clauses(1)
    Cpos = Clauses(1)
    Cneg = Clauses(1)
    x = C.Xor(1, -1)
    xpos = Cpos.Xor(1, -1, polarity=True)
    xneg = Cneg.Xor(1, -1, polarity=False)
    assert x == xpos == xneg == true  # x xor -x
    assert C.clauses == Cpos.clauses == Cneg.clauses == []