def in_rect_combinations(self, r0, c0, y, x, v, size):
        """
        Generates DNF from conjunction per every combination from
        cells in rectangle defined by top-left cell, length and heigh
        of specified size and colour

        :param r0: top row of a rectangle
        :param c0: the leftmost column of a rectangle
        :param y: height
        :param x: length
        :param v: colour
        :param size: size of rectangle
        """
        comb = combinations(range(0, y * x), size)
        conj = []
        all_conj = []
        if size == 0:
            return pd.And(*[
                ~self.vars[r0 + i, c0 + j, v] for i in range(0, y)
                for j in range(0, x)
            ])
        for it in comb:
            for cell in range(0, x * y):
                if cell in it:
                    conj.append(self.vars[r0 + cell // x, c0 + cell % x, v])
            all_conj.append(pd.And(*conj))
            conj = []
        return pd.Or(*all_conj)
    def in_figure_combinations(self, r0, c0, coord_list, v, size):
        """
        Generates DNF from conjunction per every combination from
        cells in coord_list of specified size and colour

        :param r0: start row
        :param c0: start column
        :param coord_list: list of cells
        :param v: colour
        :param size: number of cells in subset
        """
        # coord_list.append(Coord(0, 0))
        # coord_list = list(set(coord_list))
        comb = combinations(coord_list, size)
        conj = []
        all_conj = []
        if size == 0:
            return pd.And(
                *[~self.vars[r0 + it.y, c0 + it.x, v] for it in coord_list])
        for it in comb:
            for cell in coord_list:
                if cell in it:
                    conj.append(self.vars[r0 + cell.y, c0 + cell.x, v])
            all_conj.append(pd.And(*conj))
            conj = []
        return pd.Or(*all_conj)
 def ebalanced_form(self, rule):
     self.f_list.append(
         pd.And(*[
             pd.And(*[
                 self.in_figure_combinations(r, c, rule.vc, v,
                                             len(rule.vc) // self.colors)
                 for r in range(0, self.rows - rule.c.y)
                 for c in range(0, self.columns - rule.c.x)
             ]) for v in range(0, self.colors)
         ]))
 def balanced_form(self, rule):
     self.f_list.append(
         pd.And(*[
             pd.And(*[
                 self.in_rect_combinations(
                     r, c, rule.c.y, rule.c.x, v, rule.c.x * rule.c.y //
                     self.colors) for v in range(0, self.colors)
             ]) for r in range(0, self.rows - rule.c.y + 1)
             for c in range(0, self.columns - rule.c.x + 1)
         ]))
 def erich_form(self, rule):
     self.f_list.append(
         pd.And(*[
             pd.And(*[
                 pd.And(*[
                     pd.Or(*[
                         self.vars[r + cell.y, c + cell.x, v]
                         for cell in rule.vc
                     ]) for v in range(0, self.colors)
                 ]) for c in range(0, self.columns - rule.c.x)
             ]) for r in range(0, self.rows - rule.c.y)
         ]))
 def rich_form(self, rule):
     self.f_list.append(
         pd.And(*[
             pd.And(*[
                 pd.And(*[
                     pd.Or(*[
                         self.vars[r + cell // rule.c.x,
                                   c + cell % rule.c.x, v]
                         for cell in range(0, rule.c.x * rule.c.y)
                     ]) for v in range(0, self.colors)
                 ]) for c in range(0, self.columns - rule.c.x + 1)
             ]) for r in range(0, self.rows - rule.c.y + 1)
         ]))
 def in_cols_combinations(self, c, v, size):
     comb = combinations(range(0, self.rows), size)
     conj = list()
     all_conj = list()
     if size == 0:
         return pd.And(*[~self.vars[r, c, v] for r in range(0, self.rows)])
     for it in comb:
         for r in range(0, self.rows):
             if r in it:
                 conj.append(self.vars[r, c, v])
         all_conj.append(pd.And(*conj))
         conj = []
     return pd.Or(*all_conj)
    def getnetlist(self):
        #adds node to dictionary with every iteration
        if (self.gate.lower() == 'input'):
            self.inputs.append(self.ins)
        elif (self.gate.lower() == 'output'):
            self.outputs.append(self.ins)
        else:
            tmp_ins = []
            for i, item in enumerate(self.ins):
                if (self.netlist.get(item, None) is not None):
                    #if the wire is coming from other gate
                    self.ins[i] = self.netlist.get(item, None)

        if (self.gate.lower() == 'nand'):
            self.netlist[self.out] = pyedaitr.Nand(*self.ins)
        elif (self.gate.lower() == 'and'):
            self.netlist[self.out] = pyedaitr.And(*self.ins)
        elif (self.gate.lower() == 'or'):
            self.netlist[self.out] = pyedaitr.Or(*self.ins)
        elif (self.gate.lower() == 'nor'):
            self.netlist[self.out] = pyedaitr.Nor(*self.ins)
        elif (self.gate.lower() == 'xnor'):
            self.netlist[self.out] = pyedaitr.Xnor(*self.ins)
        elif (self.gate.lower() == 'xor'):
            self.netlist[self.out] = pyedaitr.Xor(*self.ins)
        elif (self.gate.lower() == 'not'):
            self.netlist[self.out] = pyedaitr.Not(*self.ins)
        elif (self.gate.lower() == 'buf'):
            try:
                self.netlist[self.out] = pyedaitr.exprvar(str(self.ins[0]))
            except ValueError:
                self.netlist[self.out] = self.ins
示例#9
0
def solve_nonogram(nonogram):
    # Main solver


    """
    for every row
        get all possibilities of row
        convert to sat problem


    for every column
        get all possibilities for column
        convert to sat problem


    solve sat problem"""


    sizex = len(nonogram["cols"])
    sizey = len(nonogram["rows"])


    # Create variables

    variables = []

    for i in range(sizex):
        row = []
        for j in range(sizey):
            variable = pe.exprvar("V" +str(i)+str(j))
            row.append(variable)
        variables.append(row)

    # print(variables)

    big_equation_list = []

    # Iterate through rows
    for n, i in enumerate(nonogram["rows"]):
        row_variables = variables[n]
        eqn = process_line(i, row_variables, sizex)
        big_equation_list.extend(eqn)

    # Iterate through columns
    for n, i in enumerate(nonogram["cols"]):
        column_variables = [a[n] for a in variables]
        eqn = process_line(i, column_variables, sizey)
        big_equation_list.extend(eqn)


    full_eq = pe.And(*big_equation_list)

    answer = full_eq.satisfy_one()

    result = {"cols": nonogram["cols"], "rows":nonogram["rows"], "solution": answer}
    return result
示例#10
0
def process_line(line, variables, size):

    """ Converts line to bit string and assigns variables
    
        ex. [0, 3, 0] => [0, 1, 1, 1, 0] => [~x1, x2, x3, x4, ~x5]
    
     """

    lines = generate_possible_line(line, variables, size)

    # print("lines" + str(lines))

    processed_lines = []

    for line in lines:

        # Expand the line
        a = []
        for i in line:
            if i==0:
                a.append(0)
            else:
                for _ in range(i):
                    a.append(1)


        processed_lines.append(a)

    equations = []

    for line in processed_lines:
        used_variables = [pe.And(variables[n]) if i==1 else pe.Not( variables[n]) for n, i in enumerate(line)]
        equation = pe.And(*used_variables)
        equations.append(equation)

    eqs = pe.Or(*equations)
    return [eqs]
示例#11
0
 def to_expr(self):
     return pyeda.And(*[it.to_expr() for it in self])
示例#12
0
    19: T,
    20: U,
    21: V,
    22: W,
    23: X,
    24: Y,
    25: Z
}

i = 0
function = True
while i < ourGraph.m:
    j = 0
    while j < ourGraph.n:
        if ourGraph.data[i][j] != 0:
            function = bo.And(function, bo.Or(letters[i], letters[j]))
        j += 1
    i += 1

print(function.to_dnf())

print("Внешняя устойчивость. Построим ДНФ:")
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z = map(
    bo.exprvar, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")

letters = {
    0: A,
    1: B,
    2: C,
    3: D,
    4: E,
    def main(self, argv):
        """
        Main function that parses input and executes solver

        Input format: python3 solver.py $rows $columns $colors
        Script executed in interactive mode.
        Possible commands:

            colors x y c -- cell x y should be coloured with colour c;

            ncolor x y c -- cell x y shouldn't be coloured with colour c;

            balanced r c -- every submatrix with dimensions rxc should have
                same number of cells per colour;

            nbalanced r c -- no submatrix with dimensions rxc should have
                same number of cells per colour;

            mixed r c -- every submatrix with dimensions rxc should have cells
                with at least two colors;

            rich r c -- every submatrix with dimensions rxc should have at
                least one cell per every colour;

            ebalanced x1 y1 ... xk yk -- every subset of cells that contains
                arbitrary cell x y and cells in row xi and yi should have
                same number of cells per colour;

            enbalanced x1 y1 ... xk yk -- same option as ebalanced but
                for nbalanced;

            emixed x1 y1 ... xk yk -- same option as ebalanced but for mixed;

            erich x1 y1 ... xk yk -- same option as ebalanced but for rich;

            back -- cancel last command.

        :param argv: input string
        """
        if self._parse_arg(argv):
            return
        self.rows = int(argv[1])
        self.columns = int(argv[2])
        self.colors = int(argv[3])
        self.grid_inst = Grid(self.rows, self.columns, self.colors)
        self.commands = Commands(self.rows, self.columns, self.colors)
        # Interactive loop for additional commands
        while True:
            line = input("Enter command: ")
            if not self.commands.parse_str(line):
                if self.commands.com.type == RType.EXIT:
                    return
                elif self.commands.com.type == RType.BACK:
                    self.commands.remove_last()
                elif self.commands.com.type == RType.SOLVE:
                    self.grid_inst.rules_to_formulas(self.commands.c_list)
                    break
                else:
                    self.commands.push_rule()
        # Conjunction of all boolean variables representing the grid
        v_f = pd.And(*[
            pd.And(*[
                pd.OneHot(*[
                    self.grid_inst.vars[r, c, v]
                    for v in range(0, self.colors)
                ]) for c in range(0, self.columns)
            ]) for r in range(0, self.rows)
        ])

        r_diff = 3
        c_diff = 3

        # Conjunctions of disjunctions for every row demanding that there no
        # three consective cells with the same colour
        r_d_f = pd.And(*[
            pd.And(*[
                pd.And(*[
                    pd.Or(*[
                        ~self.grid_inst.vars[r, c, v]
                        for c in range(it, it + r_diff)
                    ]) for v in range(0, self.colors)
                ]) for it in range(0, self.columns - r_diff + 1)
            ]) for r in range(0, self.rows)
        ])

        # Conjunctions of disjunctions for every column demanding that there no
        # three consective cells with the same colour
        c_d_f = pd.And(*[
            pd.And(*[
                pd.And(*[
                    pd.Or(*[
                        ~self.grid_inst.vars[r, c, v]
                        for r in range(it, it + c_diff)
                    ]) for v in range(0, self.colors)
                ]) for it in range(0, self.rows - c_diff + 1)
            ]) for c in range(0, self.columns)
        ])

        # Conjunctions for every row demanding equal number of cells per colour
        row_eq = pd.And(*[
            pd.And(*[
                self.grid_inst.in_rows_combinations(
                    r, v, self.grid_inst.columns // self.grid_inst.colors)
                for r in range(0, self.rows)
            ]) for v in range(0, self.colors)
        ])

        # Conjunctions for every column demanding equal\
        # number of cells per colour
        col_eq = pd.And(*[
            pd.And(*[
                self.grid_inst.in_cols_combinations(
                    c, v, self.grid_inst.rows // self.grid_inst.colors)
                for c in range(0, self.columns)
            ]) for v in range(0, self.colors)
        ])

        # Conjunction of stated above formulas + formulas from additional rules
        s_f = pd.And(v_f, r_d_f, c_d_f, row_eq, col_eq,
                     *self.grid_inst.f_list).tseitin()
        try:
            self.grid_inst.display(s_f.satisfy_one())
        except TypeError:
            print('It seems that there is no solution \
                to this puzzle with such constraints.')
    def solve(self):
        """
        Seeks for solution for defined grid by means of PicoSAT
        """
        self.grid_inst.rules_to_formulas(self.commands.c_list)

        # Conjunction of all boolean variables representing the grid
        v_f = pd.And(*[
            pd.And(*[
                pd.OneHot(*[
                    self.grid_inst.vars[r, c, v]
                    for v in range(0, self.colors)
                ]) for c in range(0, self.columns)
            ]) for r in range(0, self.rows)
        ])

        r_diff = 3
        c_diff = 3

        # Conjunctions of disjunctions for every row demanding that there no
        # three consective cells with the same colour
        r_d_f = pd.And(*[
            pd.And(*[
                pd.And(*[
                    pd.Or(*[
                        ~self.grid_inst.vars[r, c, v]
                        for c in range(it, it + r_diff)
                    ]) for v in range(0, self.colors)
                ]) for it in range(0, self.columns - r_diff + 1)
            ]) for r in range(0, self.rows)
        ])

        # Conjunctions of disjunctions for every column demanding that there no
        # three consective cells with the same colour
        c_d_f = pd.And(*[
            pd.And(*[
                pd.And(*[
                    pd.Or(*[
                        ~self.grid_inst.vars[r, c, v]
                        for r in range(it, it + c_diff)
                    ]) for v in range(0, self.colors)
                ]) for it in range(0, self.rows - c_diff + 1)
            ]) for c in range(0, self.columns)
        ])

        # Conjunctions for every row demanding equal number of cells per colour
        row_eq = pd.And(*[
            pd.And(*[
                self.grid_inst.in_rows_combinations(
                    r, v, self.grid_inst.columns // self.grid_inst.colors)
                for r in range(0, self.rows)
            ]) for v in range(0, self.colors)
        ])

        # Conjunctions for every column demanding equal number
        # of cells per colour
        col_eq = pd.And(*[
            pd.And(*[
                self.grid_inst.in_cols_combinations(
                    c, v, self.grid_inst.rows // self.grid_inst.colors)
                for c in range(0, self.columns)
            ]) for v in range(0, self.colors)
        ])

        # Conjunction of stated above formulas + formulas from additional rules
        s_f = pd.And(v_f, r_d_f, c_d_f, row_eq, col_eq,
                     *self.grid_inst.f_list).tseitin()

        return self.grid_inst.display(s_f.satisfy_one())