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
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
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]
def to_expr(self): return pyeda.And(*[it.to_expr() for it in self])
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())