Beispiel #1
0
        rule(expression_bits[i + 2], expression_bits[i + 1],
             expression_bits[i]) for i in range(N)
    ]


bis_txt = open(BIS_FILE, "rb").read(N_B)
bis_enc = open(BIS_FILE_ENCRYPTED, "rb").read(N_B)

# get first 32 bytes from keystream
key_stream = int.from_bytes(bis_txt, 'little') ^ int.from_bytes(
    bis_enc, 'little')

# get expression to calculate next value
expression = get_expression(bits)

solver = Minisat()

# loop 128 times
for i in range(128):
    exp = Cnf()

    # create expression
    for j in range(N):
        bit_value = ((1 << j) & key_stream) >= 1
        exp &= (expression[j] if bit_value is True else -expression[j])

    # get solution
    solution = solver.solve(exp)

    # update key stream
    if solution.success:
 def __init__(self):
     self.solver = Minisat()
Beispiel #3
0
def knight(N=8):
    white_knight_at = [[
        Variable("W_{" + str(i) + str(j) + "}") for i in range(N)
    ] for j in range(N)]
    black_knight_at = [[
        Variable("B_{" + str(i) + str(j) + "}") for i in range(N)
    ] for j in range(N)]

    formula = Cnf()  # the overall formula

    # at least one black and white knight in each row
    for i in range(N):
        oneinthisrow_w = Cnf()
        oneinthisrow_b = Cnf()
        for j in range(N):
            oneinthisrow_w |= white_knight_at[i][j]
            oneinthisrow_b |= black_knight_at[i][j]
        formula &= (oneinthisrow_w & oneinthisrow_b)

    # at least one black and white knight in each column
    for j in range(N):
        oneinthiscolumn_w = Cnf()
        oneinthiscolumn_b = Cnf()
        for i in range(N):
            oneinthiscolumn_w |= white_knight_at[i][j]
            oneinthiscolumn_b |= black_knight_at[i][j] & (
                -white_knight_at[i][j])
        formula &= (oneinthiscolumn_w & oneinthiscolumn_b)

    # Each row and column has exactly 1 black and white knight
    for i1 in range(N):
        for j1 in range(N):
            for i2 in range(N):
                for j2 in range(N):
                    if N * i1 + j1 < N * i2 + j2:  # Eliminate mirrors
                        if (i1 == i2) | (
                                j1 == j2
                        ):  # If two possible placements share the same row or column
                            formula &= ((-white_knight_at[i1][j1]) |
                                        (-white_knight_at[i2][j2])) & (
                                            (-black_knight_at[i1][j1]) |
                                            (-black_knight_at[i2][j2]))

    # Can't attack same color
    for i1 in range(N):
        for j1 in range(N):
            for i2 in range(N):
                for j2 in range(N):
                    if N * i1 + j1 < N * i2 + j2:  # Eliminate mirrors
                        if ((i1 - i2)**2 + (j1 - j2)**2 == 5) & (
                            (i1 - i2 <= 2) &
                            (j1 - j2 <= 2)):  # "L" shape attack
                            formula &= ((-white_knight_at[i1][j1]) |
                                        (-white_knight_at[i2][j2])) & (
                                            (-black_knight_at[i1][j1]) |
                                            (-black_knight_at[i2][j2]))

    # White must attack at least one enemy
    for i1 in range(N):
        for j1 in range(N):
            white_must_attack_one = Cnf()
            for i2 in range(N):
                for j2 in range(N):
                    if ((i1 - i2)**2 + (j1 - j2)**2 == 5) & (
                        (i1 - i2 <= 2) & (j1 - j2 <= 2)):  # "L" shape attack
                        white_must_attack_one |= (white_knight_at[i1][j1]) & (
                            black_knight_at[i2][j2])
            formula &= (white_knight_at[i1][j1] >> white_must_attack_one)

    # Black must attack at least one enemy
    for i1 in range(N):
        for j1 in range(N):
            black_must_attack_one = Cnf()
            for i2 in range(N):
                for j2 in range(N):
                    if ((i1 - i2)**2 + (j1 - j2)**2 == 5) & (
                        (i1 - i2 <= 2) & (j1 - j2 <= 2)):  # "L" shape attack
                        black_must_attack_one |= (black_knight_at[i1][j1]) & (
                            white_knight_at[i2][j2])
            formula &= (black_knight_at[i1][j1] >> black_must_attack_one)

    solution = Minisat().solve(formula)

    if solution.error is True:
        print("Error: " + solution.error)
    elif solution.success:
        chessboard = ""
        for i in range(N):
            for j in range(N):
                if solution[white_knight_at[i][j]]:
                    chessboard += "1"
                elif solution[black_knight_at[i][j]]:
                    chessboard += "2"
                else:
                    chessboard += "0"
            chessboard += "\n"
        print(chessboard)
    else:
        print("No valid solution")
Beispiel #4
0
def solve(num_wizards, num_constraints, wizards, constraints):
    """
    Write your algorithm here.
    Input:
        num_wizards: Number of wizards
        num_constraints: Number of constraints
        wizards: An array of wizard names, in no particular order
        constraints: A 2D-array of constraints, 
                     where constraints[0] may take the form ['A', 'B', 'C']i

    Output:
        An array of wizard names in the ordering your algorithm returns
    """
    maxVal = 0
    maxRet = wizards

    iteration = 0
    while True:
        constraintToVariable = dict()
        exp = None

        g1 = Graph(num_wizards)
        g2 = Graph(num_wizards)
        for constraint in constraints:
            wiz1 = constraint[0]
            wiz2 = constraint[1]
            wiz3 = constraint[2]

            clause1 = wiz3 + " " + wiz1
            clause2 = wiz3 + " " + wiz2
            clause3 = wiz1 + " " + wiz3
            clause4 = wiz2 + " " + wiz3

            g1.addEdge(wiz3, wiz1)
            g1.addEdge(wiz3, wiz2)
            g2.addEdge(wiz1, wiz3)
            g2.addEdge(wiz2, wiz3)

            if clause1 in constraintToVariable:
                v1 = constraintToVariable[clause1]
            else:
                constraintToVariable[clause1] = Variable(clause1)
                v1 = constraintToVariable[clause1]

            if clause2 in constraintToVariable:
                v2 = constraintToVariable[clause2]
            else:
                constraintToVariable[clause2] = Variable(clause2)
                v2 = constraintToVariable[clause2]

            if clause3 in constraintToVariable:
                v3 = constraintToVariable[clause3]
            else:
                constraintToVariable[clause3] = Variable(clause3)
                v3 = constraintToVariable[clause3]

            if clause4 in constraintToVariable:
                v4 = constraintToVariable[clause4]
            else:
                constraintToVariable[clause4] = Variable(clause4)
                v4 = constraintToVariable[clause4]

            literal = ((v1 & v2 & -v3 & -v4) ^ (v3 & v4 & -v1 & -v2))
            if exp is None:
                exp = literal
            else:
                exp = exp & literal

        solver = Minisat()
        solution = solver.solve(exp)
        if solution.success:
            graph = dict()
            g = Graph(num_wizards)
            for wizard in wizards:
                graph[wizard] = set()
            for constraint in constraintToVariable:
                v = constraintToVariable[constraint]
                if solution[v] == True:
                    # print(v)
                    w = str(v).split()
                    vertexU = w[0]
                    vertexV = w[1]
                    graph[vertexU].add(vertexV)
                    g.addEdge(vertexU, vertexV)

                    cycle = False
                    try:
                        topological(graph)
                    except ValueError:
                        cycle = True
                    if cycle:
                        graph[vertexU].remove(vertexV)
                        graph[vertexV].add(vertexU)
            cycle = False
            try:
                topSortGraph = topological(graph)
            except ValueError:
                cycle = True
        graph = {}
        if not cycle:
            ans = list(topSortGraph)
            comp = checkConstraintsWithList(constraints, ans)
            if comp > maxVal:
                maxVal = comp
                maxRet = ans
            if iteration > 100:
                return maxRet
            # print(comp)
        iteration += 1
        shuffle(wizards)
        shuffle(constraints)
def solve(num_wizards, num_constraints, wizards, constraints, zakiFirst):
    """
    Write your algorithm here.
    Input:
        num_wizards: Number of wizards
        num_constraints: Number of constraints
        wizards: An array of wizard names, in no particular order
        constraints: A 2D-array of constraints, 
                     where constraints[0] may take the form ['A', 'B', 'C']i

    Output:
        An array of wizard names in the ordering your algorithm returns
    """
    sameDictionary = []

    constraintToVariable = dict()

    exp = None
    for constraint in constraints:
        wiz1 = constraint[0]
        wiz2 = constraint[1]
        wiz3 = constraint[2]

        clause1 = wiz3 + " " + wiz1
        clause2 = wiz3 + " " + wiz2
        clause3 = wiz1 + " " + wiz3
        clause4 = wiz2 + " " + wiz3

        if clause1 in constraintToVariable:
            v1 = constraintToVariable[clause1]
        else:
            constraintToVariable[clause1] = Variable(clause1)
            v1 = constraintToVariable[clause1]

        if clause2 in constraintToVariable:
            v2 = constraintToVariable[clause2]
        else:
            constraintToVariable[clause2] = Variable(clause2)
            v2 = constraintToVariable[clause2]

        if clause3 in constraintToVariable:
            v3 = constraintToVariable[clause3]
        else:
            constraintToVariable[clause3] = Variable(clause3)
            v3 = constraintToVariable[clause3]

        if clause4 in constraintToVariable:
            v4 = constraintToVariable[clause4]
        else:
            constraintToVariable[clause4] = Variable(clause4)
            v4 = constraintToVariable[clause4]

        literal = ((v1 & v2 & -v3 & -v4) ^ (v3 & v4 & -v1 & -v2))
        if exp is None:
            exp = literal
        else:
            exp = exp & literal
    solver = Minisat()
    solution = solver.solve(exp)
    if solution.success:
        graph = dict()
        for wizard in wizards:
            graph[wizard] = set()
        for constraint in constraintToVariable:
            v = constraintToVariable[constraint]
            if solution[v] == True:
                w = str(v).split()
                vertexU = w[0]
                vertexV = w[1]
                graph[vertexU].add(vertexV)

        cycle = False
        try:
            topSortGraph = topological(graph)
        except ValueError:
            cycle = True
    iteration = 0
    graph = {}
    if not cycle:
        return list(topSortGraph)
    else:
        while True:
            dictCompare = {}

            g = Graph(num_wizards)
            for wiz, neighbors in graph.items():
                for n in neighbors:
                    g.addEdge(wiz, n)

            badOnes = []
            sccs = g.getSCCs()
            for scc in sccs:
                badGroup = set()
                if len(scc) > 1:
                    for u in scc:
                        for v in scc:
                            if g.containsEdge(u, v):
                                badGroup.add(u + " " + v)
                                g.removeEdge(u, v)

                    badOnes.append(badGroup)
            print("number of cycles:", len(badOnes))
            for count, i in enumerate(badOnes):
                print("length of cycle", count + 1, ":", len(i))

            for group in badOnes:
                lit = None
                for b in group:
                    v = constraintToVariable[b]
                    if lit is None:
                        lit = v
                    else:
                        lit = lit & v
                exp = -(lit) & exp

            solver = Minisat()
            solution = solver.solve(exp)
            if solution.success:
                graph = dict()
                for wizard in wizards:
                    graph[wizard] = set()
                for constraint in constraintToVariable:
                    v = constraintToVariable[constraint]
                    dictCompare[v] = solution[v]
                    if solution[v] == True:
                        w = str(v).split()
                        vertexU = w[0]
                        vertexV = w[1]
                        graph[vertexU].add(vertexV)
                cycle = False
                try:
                    topSortGraph = topological(graph)
                except ValueError:
                    cycle = True
            else:
                print("SOMETHING WENT HORRIBLY WRONG")
            if not cycle:
                return list(topSortGraph)
            print("iteration: ", iteration)
            if iteration == 100:
                return solveAlt(num_wizards, num_constraints, wizards,
                                constraints, zakiFirst)
            iteration += 1
            if dictCompare in sameDictionary:
                print("YOU'VE BEEN IN THIS STATE BEFORE")
            else:
                print("new state :)")
                sameDictionary.append(dictCompare)
Beispiel #6
0
    for j1 in gnodes:
        for j2 in gnodes:
            if i1 != i2:
                exp &= -varz[i][j1] | -varz[i][j2]

# Edge
print "Adding edge clauses..."
for j in xrange(lennodes):
    print j
    for i in gnodes:
        for k in gnodes:
            if i != k and k not in g.neighbors(i):
                exp &= -varz[i][j] | -varz[k][(j + 1) % lennodes]

# Enabling minisat to write to stdout
solver = Minisat('minisat %s %s')

print "Solving..."
solution = solver.solve(exp)

if not solution.success:
    print "There is no Hamilton cycle in the graph."
    exit()

print "Extracting solution..."
path = []
for n in g.nodes():
    nodepos = -1
    for j in xrange(lennodes):
        if solution[varz[n][j]]:
            nodepos = j
Beispiel #7
0
def solve(nrow, ncol, pieces):
    t0 = time.time()
    npieces = len(pieces)
    formula = Cnf()

    # create literals
    lits = []
    for i in range(nrow):
        row = []
        for j in range(ncol):
            col = []
            for k in range(npieces):
                piece = []
                for l in range(4):
                    piece.append(
                        Variable("x_{0}_{1}_{2}_{3}".format(i, j, k, l)))
                col.append(piece)
            row.append(col)
        lits.append(row)
    t1 = time.time()
    print("Time spent to create the literals:", t1 - t0)

    # construct formula

    # constraints set 1 : exactly one square by case
    for i in range(nrow):
        for j in range(ncol):
            squares = []
            for piece in lits[i][j]:
                for square in piece:
                    squares.append(square)
            formula &= exactly_one(squares)
    t2 = time.time()
    print("Time spent to build the first constraint set", t2 - t1)

    # constraints set 2 : exactly one case by square
    for k in range(len(pieces)):
        for l in range(4):
            cases = []
            for row in lits:
                for col in row:
                    cases.append(col[k][l])
            formula &= exactly_one(cases)
    t3 = time.time()
    print("Time spent to build the second constraint set", t3 - t2)

    # constraints set 3 : pieces shapes
    for i in range(nrow):
        for j in range(ncol):
            for k in range(npieces):
                if pieces[k] == 1:  # bar
                    orientation1 = orientation(lits, i, j + 1, i, j + 2, i,
                                               j + 3, k)
                    orientation2 = orientation(lits, i + 1, j, i + 2, j, i + 3,
                                               j, k)
                    clause = lits[i][j][k][0] >> (orientation1 | orientation2)
                elif pieces[k] == 2:  # 2*2 square
                    orientation1 = orientation(lits, i, j + 1, i + 1, j, i + 1,
                                               j + 1, k)
                    clause = lits[i][j][k][0] >> orientation1
                elif pieces[k] == 3:  # L
                    orientation1 = orientation(lits, i + 1, j, i + 2, j, i + 2,
                                               j + 1, k)
                    orientation2 = orientation(lits, i, j + 1, i, j + 2, i - 1,
                                               j + 2, k)
                    orientation3 = orientation(lits, i - 1, j, i - 2, j, i - 2,
                                               j - 1, k)
                    orientation4 = orientation(lits, i, j - 1, i, j - 2, i + 1,
                                               j - 2, k)
                    clause = lits[i][j][k][0] >> (orientation1 | orientation2 |
                                                  orientation3 | orientation4)
                elif pieces[k] == 4:  # reversed L
                    orientation1 = orientation(lits, i + 1, j, i + 2, j, i + 2,
                                               j - 1, k)
                    orientation2 = orientation(lits, i, j + 1, i, j + 2, i + 1,
                                               j + 2, k)
                    orientation3 = orientation(lits, i - 1, j, i - 2, j, i - 2,
                                               j + 1, k)
                    orientation4 = orientation(lits, i, j - 1, i, j - 2, i - 1,
                                               j - 2, k)
                    clause = lits[i][j][k][0] >> (orientation1 | orientation2 |
                                                  orientation3 | orientation4)
                elif pieces[k] == 5:  # snake
                    orientation1 = orientation(lits, i, j + 1, i - 1, j + 1,
                                               i - 1, j + 2, k)
                    orientation2 = orientation(lits, i + 1, j, i + 1, j + 1,
                                               i + 2, j + 1, k)
                    clause = lits[i][j][k][0] >> (orientation1 | orientation2)
                elif pieces[k] == 6:  # reversed snake
                    orientation1 = orientation(lits, i, j + 1, i + 1, j + 1,
                                               i + 1, j + 2, k)
                    orientation2 = orientation(lits, i + 1, j, i + 1, j - 1,
                                               i + 2, j - 1, k)
                    clause = lits[i][j][k][0] >> (orientation1 | orientation2)
                elif pieces[k] == 7:  # castle
                    orientation1 = orientation(lits, i + 1, j - 1, i + 1, j,
                                               i + 1, j + 1, k)
                    orientation2 = orientation(lits, i - 1, j - 1, i, j - 1,
                                               i + 1, j - 1, k)
                    orientation3 = orientation(lits, i - 1, j - 1, i - 1, j,
                                               i - 1, j + 1, k)
                    orientation4 = orientation(lits, i - 1, j + 1, i, j + 1,
                                               i + 1, j + 1, k)
                    clause = lits[i][j][k][0] >> (orientation1 | orientation2 |
                                                  orientation3 | orientation4)
                formula &= clause
    t2 = time.time()
    print("Time spent to build the third constraint set", t2 - t1)

    # solve using minisat
    solver = Minisat()
    t3 = time.time()
    print("Time spent to solve the SAT problem", t3 - t2)
    print("Total time", t3 - t0)
    return solver.solve(formula), lits
def propositional_nqueens(n):

    rules = 0
    t1 = time()
    exprs = Cnf()
    queens_by_point = {}
    queens_by_name = {}
    points_by_name = {}

    by_rows = [[] for x in xrange(n)]
    by_cols = [[] for x in xrange(n)]

    for point in points(n):
        name = 'queen_%d_%d' % point

        by_rows[point[1]].append(name)
        by_cols[point[0]].append(name)

        queen = Variable(name)
        queens_by_point[point] = queen
        queens_by_name[name] = queen
        points_by_name[name] = point

    for row_of_names in by_rows:
        orexp = Cnf()
        for name in row_of_names:
            orexp = orexp | queens_by_name[name]

        rules += 1
        exprs &= orexp

    for col_of_names in by_cols:
        orexp = Cnf()
        for name in col_of_names:
            orexp |= queens_by_name[name]

        rules += 1
        exprs &= orexp

    for row in xrange(n):
        for col in xrange(n):
            antecedent_name = by_rows[row][col]
            consequent_names = [by_rows[row][a] for a in xrange(n) if a != col]

            # queen_X_Y => (not(queen_X1_Y1) & not(queen_X2_Y2))
            # translates to
            # (not(queen_X_Y) or not(queen_X1_Y1)) and (not(queen_X_Y) or not(queen_X2_Y2))

            #andexpr = Cnf()
            #for name in consequent_names:
            #andexpr &= (-queens_by_name[name])

            #exprs &= (queens_by_name[antecedent_name] >> andexpr)

            for name in consequent_names:
                rules += 1
                exprs &= -queens_by_name[antecedent_name] | -queens_by_name[
                    name]

    for col in xrange(n):
        for row in xrange(n):
            antecedent_name = by_cols[col][row]
            consequent_names = [by_cols[col][a] for a in xrange(n) if a != row]

            # queen_X_Y => (not(queen_X1_Y1) & not(queen_X2_Y2))
            # translates to
            # (not(queen_X_Y) or not(queen_X1_Y1)) and (not(queen_X_Y) or not(queen_X2_Y2))
            #andexpr = Cnf()
            #for name in consequent_names:
            #andexpr &= (-queens_by_name[name])

            #exprs &= (queens_by_name[antecedent_name] >> andexpr)

            for name in consequent_names:
                rules += 1
                exprs &= -queens_by_name[antecedent_name] | -queens_by_name[
                    name]

    for point1 in points(n):
        for point2 in points(n):
            if point1 == point2:
                continue

            if are_diagonal(point1, point2):
                rules += 1
                #exprs &= (queens_by_point[point1] >> (-queens_by_point[point2]))
                exprs &= -queens_by_point[point1] | -queens_by_point[point2]

    for point in points(n):
        for slope in points(n, 1, 1):

            if slope == (1, 1):
                continue

            lines = []
            line = points_along_line(point, slope[0], slope[1], n)

            if len(line) >= 2:
                lines.append(line)

            line = points_along_line(point, -slope[0], slope[1], n)

            if len(line) >= 2:
                lines.append(line)

            if len(lines) == 0:
                continue

            for points1 in lines:
                for point1 in points1:
                    #andexpr = Cnf()
                    for point2 in points1:
                        if point2 != point1:
                            #andexpr &= (-queens_by_point[point2])
                            rules += 1
                            exprs &= -queens_by_point[point] | -queens_by_point[
                                point1] | -queens_by_point[point2]

                    #exprs &= ((queens_by_point[point] & queens_by_point[point1]) >> andexpr)
    t2 = time()
    print('# defined %d rules in %f seconds' % (rules, t2 - t1))
    t1 = time()

    with open('/media/rust/%d.cnf' % n, 'w') as f:
        io = DimacsCnf()
        f.write(io.tostring(exprs))

    t2 = time()
    print('# wrote rules in %f seconds' % (t2 - t1))
    t1 = time()
    #return
    s = Minisat()
    #s = Lingeling(command='/home/bburns/projects/nqueens-solver/lingeling-bal-2293bef-151109/lingeling --witness=1 --verbose=1 %s')
    solution = s.solve(exprs)
    t2 = time()
    print('# solved in %f seconds' % (t2 - t1))

    if solution.error:
        raise Exception(solution.error)

    if solution.success:
        results = []

        #for a in solution.varmap:
        #if solution.varmap[a]:
        #results.append(points_by_name[a.name])
        for point in queens_by_point:
            if solution[queens_by_point[point]]:
                results.append(point)

        results.sort()

        return results
    else:
        raise Exception('Unsat.')