コード例 #1
0
def factor(n):
    print("factoring %d" % n)

    # size of inputs.
    # in other words, how many bits we have to allocate to store 'n'?
    input_bits = int(math.ceil(math.log(n, 2)))
    print("input_bits=%d" % input_bits)

    s = Xu.Xu(False)

    factor1, factor2 = s.alloc_BV(input_bits), s.alloc_BV(input_bits)
    product = s.multiplier(factor1, factor2)

    # at least one bit in each input must be set, except lowest.
    # hence we restrict inputs to be greater than 1
    s.fix(s.OR(factor1[:-1]), True)
    s.fix(s.OR(factor2[:-1]), True)

    # output has a size twice as bigger as each input:
    s.fix_BV(product, Xu.n_to_BV(n, input_bits * 2))

    if s.solve() == False:
        print("%d is prime (unsat)" % n)
        return [n]

    # get inputs of multiplier:
    factor1_n = Xu.BV_to_number(s.get_BV_from_solution(factor1))
    factor2_n = Xu.BV_to_number(s.get_BV_from_solution(factor2))

    print("factors of %d are %d and %d" % (n, factor1_n, factor2_n))
    # factor factors recursively:
    rt = sorted(factor(factor1_n) + factor(factor2_n))
    assert reduce(mul, rt, 1) == n
    return rt
コード例 #2
0
def div_test():
    s=Xu.Xu(False)

    BITS=32
    divident=s.alloc_BV(BITS)
    divisor=s.alloc_BV(BITS)
    
    s.fix_BV(divident, Xu.n_to_BV(1234567890, BITS))
    s.fix_BV(divisor, Xu.n_to_BV(123, BITS))

    quotient, remainder=s.divider(divident, divisor)

    assert s.solve()==True

    assert Xu.BV_to_number(s.get_BV_from_solution(quotient))==10037137
    assert Xu.BV_to_number(s.get_BV_from_solution(remainder))==39
コード例 #3
0
def div(dividend, divisor):

    # size of inputs.
    # in other words, how many bits we have to allocate to store 'n'?
    input_bits = int(math.ceil(math.log(dividend, 2)))
    print("input_bits=%d" % input_bits)

    s = Xu.Xu(False)

    factor1, factor2 = s.alloc_BV(input_bits), s.alloc_BV(input_bits)
    product = s.multiplier(factor1, factor2)

    # connect divisor to one of multiplier's input:
    s.fix_BV(factor1, Xu.n_to_BV(divisor, input_bits))
    # output has a size twice as bigger as each input.
    # connect dividend to multiplier's output:
    s.fix_BV(product, Xu.n_to_BV(dividend, input_bits * 2))

    if s.solve() == False:
        print("remainder!=0 (unsat)")
        return None

    # get 2nd input of multiplier, which is quotient:
    return Xu.BV_to_number(s.get_BV_from_solution(factor2))
コード例 #4
0
def do_all():
    #s=Xu.Xu(maxsat=False)
    s = Xu.Xu(maxsat=True)

    cells = [[s.alloc_BV(BITS_PER_CELL) for c in range(width)]
             for r in range(height)]

    L = [[s.create_var() for c in range(width)] for r in range(height)]
    R = [[s.create_var() for c in range(width)] for r in range(height)]
    U = [[s.create_var() for c in range(width)] for r in range(height)]
    D = [[s.create_var() for c in range(width)] for r in range(height)]

    cell_is_empty = [[s.create_var() for c in range(width)]
                     for r in range(height)]

    # U for a cell must be equal to D of the cell above, etc:
    for r in range(height):
        for c in range(width):
            if r != 0:
                s.fix_EQ(U[r][c], D[r - 1][c])
            if r != height - 1:
                s.fix_EQ(D[r][c], U[r + 1][c])
            if c != 0:
                s.fix_EQ(L[r][c], R[r][c - 1])
            if c != width - 1:
                s.fix_EQ(R[r][c], L[r][c + 1])

            # "maximize" number of empty cells:
            s.fix_soft_always_true(cell_is_empty[r][c], 1)

    for r in range(height):
        for c in range(width):
            t = puzzle[r][c]
            if t == ' ':
                # puzzle has space, so degree=2, IOW, this cell must have 2 connections, no more, no less.
                # enumerate all possible L/R/U/D booleans. two of them must be True, others are False.
                t = []
                t.append(
                    s.AND_list([
                        s.NOT(cell_is_empty[r][c]), L[r][c], R[r][c],
                        s.NOT(U[r][c]),
                        s.NOT(D[r][c])
                    ]))
                t.append(
                    s.AND_list([
                        s.NOT(cell_is_empty[r][c]), L[r][c],
                        s.NOT(R[r][c]), U[r][c],
                        s.NOT(D[r][c])
                    ]))
                t.append(
                    s.AND_list([
                        s.NOT(cell_is_empty[r][c]), L[r][c],
                        s.NOT(R[r][c]),
                        s.NOT(U[r][c]), D[r][c]
                    ]))
                t.append(
                    s.AND_list([
                        s.NOT(cell_is_empty[r][c]),
                        s.NOT(L[r][c]), R[r][c], U[r][c],
                        s.NOT(D[r][c])
                    ]))
                t.append(
                    s.AND_list([
                        s.NOT(cell_is_empty[r][c]),
                        s.NOT(L[r][c]), R[r][c],
                        s.NOT(U[r][c]), D[r][c]
                    ]))
                t.append(
                    s.AND_list([
                        s.NOT(cell_is_empty[r][c]),
                        s.NOT(L[r][c]),
                        s.NOT(R[r][c]), U[r][c], D[r][c]
                    ]))
                # OR this cell has degree=0, i.e., no links:
                t.append(
                    s.AND_list([
                        cell_is_empty[r][c],
                        s.NOT(L[r][c]),
                        s.NOT(R[r][c]),
                        s.NOT(U[r][c]),
                        s.NOT(D[r][c])
                    ]))
                s.fix_always_true(s.OR_list(t))
            else:
                # cell has number, add it to cells[][] as a constraint:
                s.fix_BV(cells[r][c], Xu.n_to_BV(int(t), BITS_PER_CELL))
                # cell has degree=1, IOW, this cell must have 1 connection, no more, no less
                # enumerate all possible ways:
                t = []
                t.append(
                    s.AND_list([
                        L[r][c],
                        s.NOT(R[r][c]),
                        s.NOT(U[r][c]),
                        s.NOT(D[r][c])
                    ]))
                t.append(
                    s.AND_list([
                        s.NOT(L[r][c]), R[r][c],
                        s.NOT(U[r][c]),
                        s.NOT(D[r][c])
                    ]))
                t.append(
                    s.AND_list([
                        s.NOT(L[r][c]),
                        s.NOT(R[r][c]), U[r][c],
                        s.NOT(D[r][c])
                    ]))
                t.append(
                    s.AND_list([
                        s.NOT(L[r][c]),
                        s.NOT(R[r][c]),
                        s.NOT(U[r][c]), D[r][c]
                    ]))
                s.fix_always_true(s.OR_list(t))

            # if L[][]==True, cell's number must be equal to the number of cell at left, etc:
            if c != 0:
                s.fix_always_true(
                    s.ITE(L[r][c], s.const_true,
                          s.BV_EQ(cells[r][c], cells[r][c - 1])))
            if c != width - 1:
                s.fix_always_true(
                    s.ITE(R[r][c], s.const_true,
                          s.BV_EQ(cells[r][c], cells[r][c + 1])))
            if r != 0:
                s.fix_always_true(
                    s.ITE(U[r][c], s.const_true,
                          s.BV_EQ(cells[r][c], cells[r - 1][c])))
            if r != height - 1:
                s.fix_always_true(
                    s.ITE(D[r][c], s.const_true,
                          s.BV_EQ(cells[r][c], cells[r + 1][c])))

    # L/R/U/D's of borderline cells must always be False:
    for r in range(height):
        s.fix_always_false(L[r][0])
        s.fix_always_false(R[r][width - 1])

    for c in range(width):
        s.fix_always_false(U[0][c])
        s.fix_always_false(D[height - 1][c])

    if s.solve() == False:
        print("unsat")
        exit(0)
    else:
        print("sat")

    print("")

    for r in range(height):
        t = ""
        for c in range(width):
            t = t + ("%2d" % Xu.BV_to_number(
                s.get_BV_from_solution(cells[r][c]))) + " "
        print(t)

    print("")

    for r in range(height):
        t = ""
        for c in range(width):
            t = t + ("L" if s.get_var_from_solution(L[r][c]) else " ")
            t = t + ("R" if s.get_var_from_solution(R[r][c]) else " ")
            t = t + ("U" if s.get_var_from_solution(U[r][c]) else " ")
            t = t + ("D" if s.get_var_from_solution(D[r][c]) else " ")
            t = t + "|"
        print(t)

    print("")

    for r in range(height):
        row = ""
        for c in range(width):
            t = puzzle[r][c]
            if t == ' ':
                tl = (True if s.get_var_from_solution(L[r][c]) else False)
                tr = (True if s.get_var_from_solution(R[r][c]) else False)
                tu = (True if s.get_var_from_solution(U[r][c]) else False)
                td = (True if s.get_var_from_solution(D[r][c]) else False)

                if tl == False and tr == False and tu == False and td == False:
                    row = row + " "
                if tu and td:
                    row = row + "┃"
                if tr and td:
                    row = row + "┏"
                if tr and tu:
                    row = row + "┗"
                if tl and td:
                    row = row + "┓"
                if tl and tu:
                    row = row + "┛"
                if tl and tr:
                    row = row + "━"
            else:
                row = row + t
        print(row)