def exactly_one(lx, ly, lnb, whole): """ Returns a Logics object that represents a set of logics formulas which only allows one of all cases (x,y,nb) ,x in lx, y in ly and nb in lnb to be right. If whole is False, it will only return 2 clauses for incompatibilities """ logics = Logics() #Global clause (at least 1) if whole: c = Clause([]) for x in lx: for y in ly: for nb in lnb: v = Var(x, y, nb) c.add(Literal(v, 1)) logics += c #Specific clauses (minus than 1) for x in lx: for x2 in lx: for y in ly: for y2 in ly: for nb in lnb: for nb2 in lnb: if (x, y, nb) > (x2, y2, nb2): v1 = Var(x, y, nb) v2 = Var(x2, y2, nb2) l1 = Literal(v1, -1) l2 = Literal(v2, -1) c = Clause([l1, l2]) logics += c return logics
def get_grid_logics_data(self): logics = Logics() #Use grid data for y, line in enumerate(self.grid): for x, nb in enumerate(line): if nb != 0: logics += Clause([Literal(Var(x, y, nb - 1), 1)]) return logics
def get_logics(self): logics = Logics() #Cases for i in range(9): for j in range(9): logics += exactly_one([i], [j], range(0, 9), True) #Lines for j in range(9): for nb in range(0, 9): logics += exactly_one(range(9), [j], [nb], False) #Column for i in range(9): for nb in range(0, 9): logics += exactly_one([i], range(9), [nb], False) #Square for s in range(3): for s2 in range(3): for nb in range(0, 9): logics += exactly_one(range(3 * s, 3 * (s + 1)), range(3 * s2, 3 * (s2 + 1)), [nb], False) return logics + self.get_grid_logics_data()