def computeChannels(self, n, k=2): from constraint import Problem from constraint import SomeInSetConstraint found = False nodes = tuple(self.nodes()) p = Problem() p.addVariables(list(self.nodes()), range(n,0,-1)) # reverse ordering the domain biases the constraint solver towards smaller numbers p.addConstraint(SomeInSetConstraint([1])) def addConstraint(node1, node2, dist, diff): if(node1 in node2.neighbors(dist)): p.addConstraint(lambda x, y: abs(x - y) >= diff,(node1, node2)) return True return False for i in xrange(len(nodes)-1): n1 = nodes[i] for j in xrange(i+1,len(nodes)): n2 = nodes[j] if(not addConstraint(n1, n2, 2, k)): # each node pair needs no more than 1 constraint addConstraint(n1, n2, 4, 1) for rowIter in self.rows(): row = tuple(rowIter) for i in xrange(len(row)-1): p.addConstraint(lambda x, y: y == (x + k) % n + 1,(row[i], row[i+1])) for colIter in self.columns(): col = tuple(colIter) for i in xrange(len(col)-1): p.addConstraint(lambda x, y: y == (x + k - 1) % n + 1,(col[i], col[i+1])) solution = p.getSolution() if(solution == None): return found found = True for node,channel in p.getSolution().iteritems(): node.channel = channel return True
def solve(): problem = Problem() problem.addVariables("abcdxefgh", range(1, 10)) problem.addConstraint(lambda a, b, c, d, x: a < b < c < d and a + b + c + d + x == 27, "abcdx") problem.addConstraint(lambda e, f, g, h, x: e < f < g < h and e + f + g + h + x == 27, "efghx") problem.addConstraint(AllDifferentConstraint()) solutions = problem.getSolutions() return solutions
def solve(size): problem = Problem() cols = range(size) rows = range(size) problem.addVariables(cols, rows) for col1 in cols: for col2 in cols: if col1 < col2: problem.addConstraint(lambda row1, row2: row1 != row2, (col1, col2)) solutions = problem.getSolutions() return solutions
def solve(): problem = Problem() problem.addVariables("twofur", range(10)) problem.addConstraint(lambda o, r: (2 * o) % 10 == r, "or") problem.addConstraint(lambda w, o, u, r: ((10 * 2 * w) + (2 * o)) % 100 == u * 10 + r, "wour") problem.addConstraint(lambda t, w, o, f, u, r: 2 * (t * 100 + w * 10 + o) == f * 1000 + o * 100 + u * 10 + r, "twofur") problem.addConstraint(NotInSetConstraint([0]), "ft") problem.addConstraint(AllDifferentConstraint()) solutions = problem.getSolutions() return solutions
def solve(): problem = Problem() problem.addVariables("abc", range(1, 10)) problem.getSolutions() minvalue = 999 / (9 * 3) minsolution = {} for solution in problem.getSolutions(): a = solution["a"] b = solution["b"] c = solution["c"] value = (a * 100 + b * 10 + c) / (a + b + c) if value < minvalue: minsolution = solution return minvalue, minsolution
def solve(): problem = Problem() size = 8 cols = range(size) rows = range(size) problem.addVariables(cols, rows) for col1 in cols: for col2 in cols: if col1 < col2: problem.addConstraint(lambda row1, row2, col1=col1, col2=col2: abs(row1 - row2) != abs(col1 - col2) and row1 != row2, (col1, col2)) solutions = problem.getSolutions() return solutions, size
def solve(): problem = Problem() problem.addVariables("seidoz", range(10)) problem.addConstraint(lambda s, e: (2 * s) % 10 == e, "se") problem.addConstraint(lambda i, s, z, e: ((10 * 2 * i) + (2 * s)) % 100 == z * 10 + e, "isze") problem.addConstraint(lambda s, e, i, d, o, z: 2 * (s * 1000 + e * 100 + i * 10 + s) == d * 1000 + o * 100 + z * 10 + e, "seidoz") problem.addConstraint(lambda s: s != 0, "s") problem.addConstraint(lambda d: d != 0, "d") problem.addConstraint(AllDifferentConstraint()) solutions = problem.getSolutions() return solutions
def solve(): problem = Problem() # Define the variables: 9 rows of 9 variables rangin in 1...9 for i in range(1, 10): problem.addVariables(range(i * 10 + 1, i * 10 + 10), range(1, 10)) # Each row has different values for i in range(1, 10): problem.addConstraint(AllDifferentConstraint(), range(i * 10 + 1, i * 10 + 10)) # Each colum has different values for i in range(1, 10): problem.addConstraint(AllDifferentConstraint(), range(10 + i, 100 + i, 10)) # Each 3x3 box has different values problem.addConstraint(AllDifferentConstraint(), [11, 12, 13, 21, 22, 23, 31, 32, 33]) problem.addConstraint(AllDifferentConstraint(), [41, 42, 43, 51, 52, 53, 61, 62, 63]) problem.addConstraint(AllDifferentConstraint(), [71, 72, 73, 81, 82, 83, 91, 92, 93]) problem.addConstraint(AllDifferentConstraint(), [14, 15, 16, 24, 25, 26, 34, 35, 36]) problem.addConstraint(AllDifferentConstraint(), [44, 45, 46, 54, 55, 56, 64, 65, 66]) problem.addConstraint(AllDifferentConstraint(), [74, 75, 76, 84, 85, 86, 94, 95, 96]) problem.addConstraint(AllDifferentConstraint(), [17, 18, 19, 27, 28, 29, 37, 38, 39]) problem.addConstraint(AllDifferentConstraint(), [47, 48, 49, 57, 58, 59, 67, 68, 69]) problem.addConstraint(AllDifferentConstraint(), [77, 78, 79, 87, 88, 89, 97, 98, 99]) # Some value is given. initValue = [ [0, 9, 0, 7, 0, 0, 8, 6, 0], [0, 3, 1, 0, 0, 5, 0, 2, 0], [8, 0, 6, 0, 0, 0, 0, 0, 0], [0, 0, 7, 0, 5, 0, 0, 0, 6], [0, 0, 0, 3, 0, 7, 0, 0, 0], [5, 0, 0, 0, 1, 0, 7, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 9], [0, 2, 0, 6, 0, 0, 0, 5, 0], [0, 5, 4, 0, 0, 8, 0, 7, 0], ] for i in range(1, 10): for j in range(1, 10): if initValue[i - 1][j - 1] != 0: problem.addConstraint(lambda var, val=initValue[i - 1][j - 1]: var == val, (i * 10 + j,)) # Get the solutions. solutions = problem.getSolutions() return solutions
def solve(): problem = Problem() problem.addVariables(range(1, 21), ["A", "B", "C", "D", "E"]) problem.addConstraint(SomeInSetConstraint(["A"], 4, True)) problem.addConstraint(SomeInSetConstraint(["B"], 4, True)) problem.addConstraint(SomeInSetConstraint(["C"], 4, True)) problem.addConstraint(SomeInSetConstraint(["D"], 4, True)) problem.addConstraint(SomeInSetConstraint(["E"], 4, True)) for row in range(len(STUDENTDESKS) - 1): for col in range(len(STUDENTDESKS[row]) - 1): lst = [STUDENTDESKS[row][col], STUDENTDESKS[row][col + 1], STUDENTDESKS[row + 1][col], STUDENTDESKS[row + 1][col + 1]] lst = [x for x in lst if x] problem.addConstraint(AllDifferentConstraint(), lst) solutions = problem.getSolution() return solutions
def solve(): problem = Problem() problem.addVariables("sendmory", range(10)) problem.addConstraint(lambda d, e, y: (d + e) % 10 == y, "dey") problem.addConstraint(lambda n, d, r, e, y: (n * 10 + d + r * 10 + e) % 100 == e * 10 + y, "ndrey") problem.addConstraint( lambda e, n, d, o, r, y: (e * 100 + n * 10 + d + o * 100 + r * 10 + e) % 1000 == n * 100 + e * 10 + y, "endory" ) problem.addConstraint( lambda s, e, n, d, m, o, r, y: 1000 * s + 100 * e + 10 * n + d + 1000 * m + 100 * o + 10 * r + e == 10000 * m + 1000 * o + 100 * n + 10 * e + y, "sendmory", ) problem.addConstraint(NotInSetConstraint([0]), "sm") problem.addConstraint(AllDifferentConstraint()) solutions = problem.getSolutions() return solutions
def derive_depths(marker_list, additional_constraints=[]): """Use constraint programming to derive the paragraph depths associated with a list of paragraph markers. Additional constraints (e.g. expected marker types, etc.) can also be added. Such constraints are functions of two parameters, the constraint function (problem.addConstraint) and a list of all variables""" if not marker_list: return [] problem = Problem() # Marker type per marker problem.addVariables(["type" + str(i) for i in range(len(marker_list))], markers.types) # Index within the marker list problem.addVariables(["idx" + str(i) for i in range(len(marker_list))], range(51)) # Depth in the tree, with an arbitrary limit of 10 problem.addVariables(["depth" + str(i) for i in range(len(marker_list))], range(10)) all_vars = [] for i in range(len(marker_list)): all_vars.extend(['type' + str(i), 'idx' + str(i), 'depth' + str(i)]) # Always start at depth 0 problem.addConstraint(rules.must_be(0), ("depth0",)) for idx, marker in enumerate(marker_list): idx_str = str(idx) problem.addConstraint(rules.type_match(marker), ("type" + idx_str, "idx" + idx_str)) prior_params = ['type' + idx_str, 'idx' + idx_str, 'depth' + idx_str] for i in range(idx): prior_params += ['type' + str(i), 'idx' + str(i), 'depth' + str(i)] problem.addConstraint(rules.same_type, prior_params) problem.addConstraint(rules.diff_type, prior_params) # @todo: There's probably efficiency gains to making these rules over # prefixes (see above) rather than over the whole collection at once problem.addConstraint(rules.same_depth_same_type, all_vars) problem.addConstraint(rules.stars_occupy_space, all_vars) for constraint in additional_constraints: constraint(problem.addConstraint, all_vars) return [Solution(solution) for solution in problem.getSolutions()]
from constraint import Problem, AllDifferentConstraint from itertools import product from functools import partial columns = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] rows = [1, 2, 3, 4, 5, 6, 7, 8] mapping = dict((x, y) for x, y in zip(columns, rows)) def bishop_func(a, b, x, y): return abs(mapping[x] - mapping[y]) != abs(a - b) or a == b problem = Problem() problem.addVariables(columns, rows) problem.addConstraint(AllDifferentConstraint()) for column1, column2 in product(columns, columns): problem.addConstraint(partial(bishop_func, x = column1, y = column2), (column1, column2)) for solution in problem.getSolutions(): print sorted(solution.iteritems())
def derive_depths(original_markers, additional_constraints=[]): """Use constraint programming to derive the paragraph depths associated with a list of paragraph markers. Additional constraints (e.g. expected marker types, etc.) can also be added. Such constraints are functions of two parameters, the constraint function (problem.addConstraint) and a list of all variables""" if not original_markers: return [] problem = Problem() marker_list = _compress_markerless(original_markers) # Depth in the tree, with an arbitrary limit of 10 problem.addVariables(["depth" + str(i) for i in range(len(marker_list))], range(10)) # Always start at depth 0 problem.addConstraint(rules.must_be(0), ("depth0",)) all_vars = [] for idx, marker in enumerate(marker_list): type_var = "type{}".format(idx) depth_var = "depth{}".format(idx) # Index within the marker list. Though this variable is redundant, it # makes the code easier to understand and doesn't have a significant # performance penalty idx_var = "idx{}".format(idx) typ_opts = [t for t in markers.types if marker in t] idx_opts = [i for t in typ_opts for i in range(len(t)) if t[i] == marker] problem.addVariable(type_var, typ_opts) problem.addVariable(idx_var, idx_opts) problem.addConstraint(rules.type_match(marker), [type_var, idx_var]) all_vars.extend([type_var, idx_var, depth_var]) if idx > 0: pairs = all_vars[3*(idx-1):] problem.addConstraint(rules.depth_check, pairs) if idx > 1: pairs = all_vars[3*(idx-2):] problem.addConstraint(rules.markerless_sandwich, pairs) problem.addConstraint(rules.star_sandwich, pairs) # separate loop so that the simpler checks run first for idx in range(1, len(marker_list)): # start with the current idx params = all_vars[3*idx:3*(idx+1)] # then add on all previous params += all_vars[:3*idx] problem.addConstraint(rules.sequence, params) # @todo: There's probably efficiency gains to making these rules over # prefixes (see above) rather than over the whole collection at once problem.addConstraint(rules.same_parent_same_type, all_vars) problem.addConstraint(rules.stars_occupy_space, all_vars) for constraint in additional_constraints: constraint(problem.addConstraint, all_vars) solutions = [] for assignment in problem.getSolutionIter(): assignment = _decompress_markerless(assignment, original_markers) solutions.append(Solution(assignment)) return solutions
def derive_depths(original_markers, additional_constraints=None): """Use constraint programming to derive the paragraph depths associated with a list of paragraph markers. Additional constraints (e.g. expected marker types, etc.) can also be added. Such constraints are functions of two parameters, the constraint function (problem.addConstraint) and a list of all variables""" if additional_constraints is None: additional_constraints = [] if not original_markers: return [] problem = Problem() marker_list = _compress_markerless(original_markers) logger.warn(marker_list) # Depth in the tree, with an arbitrary limit of 10 problem.addVariables(["depth" + str(i) for i in range(len(marker_list))], range(10)) # Always start at depth 0 problem.addConstraint(rules.must_be(0), ("depth0",)) all_vars = [] for idx, marker in enumerate(marker_list): type_var = "type{0}".format(idx) depth_var = "depth{0}".format(idx) # Index within the marker list. Though this variable is redundant, it # makes the code easier to understand and doesn't have a significant # performance penalty idx_var = "idx{0}".format(idx) typ_opts = [t for t in markers.types if marker in t] idx_opts = [i for t in typ_opts for i in range(len(t)) if t[i] == marker] problem.addVariable(type_var, typ_opts) problem.addVariable(idx_var, idx_opts) problem.addConstraint(rules.type_match(marker), [type_var, idx_var]) all_vars.extend([type_var, idx_var, depth_var]) if idx > 0: pairs = all_vars[3 * (idx - 1):] problem.addConstraint(pair_rules, pairs) if idx > 1: pairs = all_vars[3 * (idx - 2):] problem.addConstraint(rules.triplet_tests, pairs) # separate loop so that the simpler checks run first for idx in range(1, len(marker_list)): # start with the current idx params = all_vars[3 * idx:3 * (idx + 1)] # then add on all previous params += all_vars[:3 * idx] problem.addConstraint(rules.continue_previous_seq, params) # @todo: There's probably efficiency gains to making these rules over # prefixes (see above) rather than over the whole collection at once problem.addConstraint(rules.same_parent_same_type, all_vars) for constraint in additional_constraints: constraint(problem.addConstraint, all_vars) solutions = [] for assignment in problem.getSolutionIter(): assignment = _decompress_markerless(assignment, original_markers) solutions.append(Solution(assignment)) if len(solutions) == 10: break # to prevent infinite solution loops return solutions
from constraint import AllDifferentConstraint, InSetConstraint, Problem # variables jobs = "FA EA PA RO AC".split() deskcolor = "Aqua Maroon Pink Cream Purple".split() travel = "Fiji France Canada Japan Thailand".split() drinks = "Peppermint GreenTea Chamomile EarlGrey EnglishBreakfast".split() suburb = "Brunswick, Werribee, Frankston, Oakleigh, StKilda".split(", ") # There are five houses. minn, maxn = 1, 5 problem = Problem() # value of a variable is the number of a house with corresponding property variables = jobs + deskcolor + travel + drinks + suburb problem.addVariables(variables, range(minn, maxn + 1)) # All jobs, colors, travel, drinks, and suburb are unique to each person for vars_ in (jobs, deskcolor, travel, drinks, suburb): problem.addConstraint(AllDifferentConstraint(), vars_) # RULE 4: The cream desk is to the left of the purple desk. #NOTE: interpret it as 'cream desk number' < 'purple desk number' problem.addConstraint(lambda a, b: a < b, ["Cream", "Purple"]) # RULE 8: In the middle desk the drink is Chamomile #NOTE: interpret "middle" in a numerical sense (not geometrical) problem.addConstraint(InSetConstraint([(minn + maxn) // 2]), ["Chamomile"]) # RULE 9: The leftmost desk's job is Financial analyst. #NOTE: interpret "the first" as the desk number.
return "\n".join([ " ".join(self.formatday(d, wd, width) for (d, wd) in theweek), " ".join(self.formathours(d, wd, width) for (d, wd) in theweek), ]) CALENDAR = MCalendar() days = [d for d in CALENDAR.itermonthdates(YEAR, MONTH) if d.month == MONTH] def all_assigned(assignments, variables): return [assignments.get(v, Unassigned) for v in variables].count(Unassigned) == 0 problem = Problem() problem.addVariables(days, list(range(0, 17))) for d in days: if d.day in special: problem.addConstraint(InSetConstraint([special[d.day]]), [d]) elif d.weekday() in regular: problem.addConstraint(InSetConstraint([regular[d.weekday()]]), [d]) problem.addConstraint(MaxSumConstraint(HOURS)) soln = problem.getSolution() CALENDAR.sched = {k.day: v for k, v in soln.items()} CALENDAR.prmonth(YEAR, MONTH)
class GraphletsConstraints(X86AnalyzerBase): #__registers32Bit = ["eax","ebx","ecx","edx","esi","edi","ebp","esp"] __dictNames = ['ref','tar'] __printConds = False def __init__(self,nodeGradesInfos=[]): X86AnalyzerBase.__init__(self,nodeGradesInfos) self.problem = Problem(MinConflictsSolver()) # this is to make it human readable .. # we will generator the solution only when we need it and then cache it # TODO make __ self.sol = None for key in self.rewriteDict.keys(): self.rewriteDict[key]['symbolCache'] = {} self.rewriteDict[key]['curLine'] = 1 self.rewriteDict[key]['curPos'] = 1 self.createRewrite() def getEmptyDict(self): d = X86AnalyzerBase.getEmptyDict(self) for key in d.keys(): d[key]['transitions'] = [] d[key]['valuesTrackDict'] = {} #if key != self.REGISTER: d[key]['domain'] = set() #self.rewriteDict[key]['inCmdCounter'] = 1 return d # this will add recorded value to dict, even if there is a conflict it will be recorded... # def insertToDictWithType(self,tarCmdNum,fromStr,refCmdNum,toStr,typeStr,dict2insert=None): assert(dict2insert != None) dict2insert[typeStr]['transitions'].append((tarCmdNum,fromStr,toStr)) #if typeStr != self.REGISTER: dict2insert[typeStr]['domain'].add(toStr) def commitChanges(self,tmpDict): for key in self.rewriteDict.keys(): self.rewriteDict[key]['transitions'].extend(tmpDict[key]['transitions']) #if key != self.REGISTER: self.rewriteDict[key]['domain'].update(tmpDict[key]['domain']) # black list has no generation:) , we can use the rwdict type as they are the same.. def getRewriteWithType(self,tarCmdNum,fromStr,typeStr,FoundBlacklistElement): if self.sol == None: self.callSol() if self.rewriteDict[typeStr]['curLine'] < tarCmdNum : self.rewriteDict[typeStr]['curLine'] = tarCmdNum self.rewriteDict[typeStr]['curPos'] = 1 varName = self.getVarName(self.getShort(typeStr), tarCmdNum, self.rewriteDict[typeStr]['curPos']) self.rewriteDict[typeStr]['curPos'] += 1 if self.sol != None and varName in self.sol: # we have a value! update cache and return it newVal = self.sol[varName] self.rewriteDict[typeStr]['symbolCache'][fromStr] = newVal return newVal elif fromStr in self.rewriteDict[typeStr]['symbolCache']: return self.rewriteDict[typeStr]['symbolCache'][fromStr] else: #not found in this type's map in this generation, return original return fromStr def getShort(self,name): if name == self.FUNCNAME: return "f" elif name == self.VAR: return "m" elif name == self.REGISTER: return "r" else : raise hell def getVarName(self,preFix,curLine,curPos): return preFix + str(curLine) + "-" + str(curPos) + "_TAR" # TODO - make this __ def callSol(self): # we need to go over each dict that is useable, and feed vars and constraints for typeDict in [x for x in self.rewriteDict.keys() if self.rewriteDict[x]['useAble']==True ]: curLine = 1 curPos = 1 preFix = self.getShort(typeDict) #if typeDict != self.REGISTER: domain = list(self.rewriteDict[typeDict]['domain']) #else: # domain =self.__registers32Bit for (line,tarStr,refStr) in self.rewriteDict[typeDict]['transitions']: if curLine < line: curPos = 1 curLine = line tarName = self.getVarName(preFix, curLine, curPos) self.problem.addVariables([tarName],domain) if (self.__printConds): print "CONS(text) -> " + tarName + " == " + refStr self.problem.addConstraint(self.checkInputVsTarget(refStr),[tarName]) if tarStr in self.rewriteDict[typeDict]['valuesTrackDict'] != None: if (self.__printConds): print "CONS(bag) -> " + self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] + " == " + tarName self.problem.addConstraint(self.varsEqual,[tarName,self.rewriteDict[typeDict]['valuesTrackDict'][tarStr]]) self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] = tarName curPos+=1 self.sol = self.problem.getSolution() if traceHack: print "(Number of broken - " + str(self.problem.getSolver().getHack()) + ")", def varsEqual(self,v1, v2): return v1==v2 def checkInputVsTarget(self,target): def retFunc(inputVal): return inputVal == target return retFunc def getSolution(self): if self.sol == None: self.callSol() return self.sol def printSol(self,sol): #better call sol! if sol == None: print "NO SOL!" return last = 1 for key in sorted(sol.iterkeys()): if int(key[1:2]) != last: last = int(key[1:2]) print "" print key + ": " + sol[key] + " ", def getBrokenNumber(self): return self.problem.getSolver().getHack()
class GraphletsConstraints(X86AnalyzerBase): #__registers32Bit = ["eax","ebx","ecx","edx","esi","edi","ebp","esp"] __dictNames = ['ref', 'tar'] __printConds = False def __init__(self, nodeGradesInfos=[]): X86AnalyzerBase.__init__(self, nodeGradesInfos) self.problem = Problem(MinConflictsSolver()) # this is to make it human readable .. # we will generator the solution only when we need it and then cache it # TODO make __ self.sol = None for key in self.rewriteDict.keys(): self.rewriteDict[key]['symbolCache'] = {} self.rewriteDict[key]['curLine'] = 1 self.rewriteDict[key]['curPos'] = 1 self.createRewrite() def getEmptyDict(self): d = X86AnalyzerBase.getEmptyDict(self) for key in d.keys(): d[key]['transitions'] = [] d[key]['valuesTrackDict'] = {} #if key != self.REGISTER: d[key]['domain'] = set() #self.rewriteDict[key]['inCmdCounter'] = 1 return d # this will add recorded value to dict, even if there is a conflict it will be recorded... # def insertToDictWithType(self, tarCmdNum, fromStr, refCmdNum, toStr, typeStr, dict2insert=None): assert (dict2insert != None) dict2insert[typeStr]['transitions'].append((tarCmdNum, fromStr, toStr)) #if typeStr != self.REGISTER: dict2insert[typeStr]['domain'].add(toStr) def commitChanges(self, tmpDict): for key in self.rewriteDict.keys(): self.rewriteDict[key]['transitions'].extend( tmpDict[key]['transitions']) #if key != self.REGISTER: self.rewriteDict[key]['domain'].update(tmpDict[key]['domain']) # black list has no generation:) , we can use the rwdict type as they are the same.. def getRewriteWithType(self, tarCmdNum, fromStr, typeStr, FoundBlacklistElement): if self.sol == None: self.callSol() if self.rewriteDict[typeStr]['curLine'] < tarCmdNum: self.rewriteDict[typeStr]['curLine'] = tarCmdNum self.rewriteDict[typeStr]['curPos'] = 1 varName = self.getVarName(self.getShort(typeStr), tarCmdNum, self.rewriteDict[typeStr]['curPos']) self.rewriteDict[typeStr]['curPos'] += 1 if self.sol != None and varName in self.sol: # we have a value! update cache and return it newVal = self.sol[varName] self.rewriteDict[typeStr]['symbolCache'][fromStr] = newVal return newVal elif fromStr in self.rewriteDict[typeStr]['symbolCache']: return self.rewriteDict[typeStr]['symbolCache'][fromStr] else: #not found in this type's map in this generation, return original return fromStr def getShort(self, name): if name == self.FUNCNAME: return "f" elif name == self.VAR: return "m" elif name == self.REGISTER: return "r" else: raise hell def getVarName(self, preFix, curLine, curPos): return preFix + str(curLine) + "-" + str(curPos) + "_TAR" # TODO - make this __ def callSol(self): # we need to go over each dict that is useable, and feed vars and constraints for typeDict in [ x for x in self.rewriteDict.keys() if self.rewriteDict[x]['useAble'] == True ]: curLine = 1 curPos = 1 preFix = self.getShort(typeDict) #if typeDict != self.REGISTER: domain = list(self.rewriteDict[typeDict]['domain']) #else: # domain =self.__registers32Bit for (line, tarStr, refStr) in self.rewriteDict[typeDict]['transitions']: if curLine < line: curPos = 1 curLine = line tarName = self.getVarName(preFix, curLine, curPos) self.problem.addVariables([tarName], domain) if (self.__printConds): print "CONS(text) -> " + tarName + " == " + refStr self.problem.addConstraint(self.checkInputVsTarget(refStr), [tarName]) if tarStr in self.rewriteDict[typeDict][ 'valuesTrackDict'] != None: if (self.__printConds): print "CONS(bag) -> " + self.rewriteDict[typeDict][ 'valuesTrackDict'][tarStr] + " == " + tarName self.problem.addConstraint(self.varsEqual, [ tarName, self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] ]) self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] = tarName curPos += 1 self.sol = self.problem.getSolution() if traceHack: print "(Number of broken - " + str( self.problem.getSolver().getHack()) + ")", def varsEqual(self, v1, v2): return v1 == v2 def checkInputVsTarget(self, target): def retFunc(inputVal): return inputVal == target return retFunc def getSolution(self): if self.sol == None: self.callSol() return self.sol def printSol(self, sol): #better call sol! if sol == None: print "NO SOL!" return last = 1 for key in sorted(sol.iterkeys()): if int(key[1:2]) != last: last = int(key[1:2]) print "" print key + ": " + sol[key] + " ", def getBrokenNumber(self): return self.problem.getSolver().getHack()
S = len(grid) # size of the grid assert all(len(row) == S for row in grid) assert len(groupnames) == S rownames = list(range(S)) columnnames = list(range(S)) def isadjacent(cell0, cell1): (i0, j0), (i1, j1) = cell0, cell1 return abs(i0 - i1) <= 1 and abs(j0 - j1) <= 1 problem = Problem() problem.addVariables(cellnames, [0, 1]) # 1 = has a star # Each row, column, and group must have exactly N stars for row in rownames: problem.addConstraint(ExactSumConstraint(N), [(x, y) for x, y in cellnames if y == row]) for col in columnnames: problem.addConstraint(ExactSumConstraint(N), [(x, y) for x, y in cellnames if x == col]) for cells in groupcells.values(): problem.addConstraint(ExactSumConstraint(N), cells) # Adjacent cells may not both have a star for cell0 in cellnames: for cell1 in cellnames: if cell0 < cell1 and isadjacent(cell0, cell1):
class GraphletsConstraints(RWEngineBase): __printConds = False def __init__(self,nodeGradesInfos): self.nodeGradesInfos = nodeGradesInfos self.sol = None # a field is somthing seperated by " " , an argument is a list of params seperated by "," ; a member is a param seperated by "+" def breakCommand(self,cmd): cmdFields = seperateCmd(cmd) if len(cmdFields) ==0: print "asd" assert (len(cmdFields) >0) if len(cmdFields) == 1 : return {'nemonic':cmdFields[0],'nemonicWithDecoretors':" ".join(cmdFields[0:-1]),'ParamsList':[]} else: return {'nemonic':cmdFields[0],'nemonicWithDecoretors':" ".join(cmdFields[0:-1]),'ParamsList':cmdFields[-1].split(",")} #TODO - add to this.. lvalCmdsStarts = ["mov","sub","add","xor"] def getNemonicType(self,nemonic): if any(map(lambda startString: nemonic.startswith(startString),self.lvalCmdsStarts)): return "WriteThenRead" else: return "Read" FuncPrefix = "f" VARPrefix = "s" RegisterPrefix = "r" OffsetPrefix = "o" OtherPrefix = "X" def getPrefix(self,Str): if isVarStr(Str): return self.VARPrefix elif isRegisterStr(Str): return self.RegisterPrefix elif isOffset(Str): return self.OffsetPrefix else: return self.OtherPrefix def varsEqual(self,v1, v2): return v1==v2 def checkInputVsTarget(self,target): def retFunc(inputVal): return inputVal == target return retFunc def getVarName(self,prefix,lineNumber,varsInThisLine): return prefix + str(lineNumber) + "-" + str(varsInThisLine) + "_TAR" def getMembers(self,param): refMembers = param.split("+") refMembers[0] = refMembers[0][1:] #remove [ from first refMembers[-1] = refMembers[-1][0:-1] # remove ] from last (they can be the same one!) return refMembers def getDomains(self): domains = {self.FuncPrefix:set(),self.VARPrefix:set(),self.RegisterPrefix:set(),self.OffsetPrefix:set()} def getCmdSymbols(cmd): cmdBasicInfo = self.breakCommand(cmd) for param in cmdBasicInfo['ParamsList']: if param.startswith("["): for member in self.getMembers(param): yield member else: yield param def getCmds(cmdsDelimited): return filter(None,cmdsDelimited.split(";")) for cmdList in itertools.imap(lambda nodeGradesInfo:getCmds(nodeGradesInfo['refCode']),self.nodeGradesInfos): for cmd in cmdList: if isCall(cmd): prefix = self.FuncPrefix domains[prefix].add(list(getCmdSymbols(cmd))[0]) else: for symbol in getCmdSymbols(cmd): prefix = self.getPrefix(symbol) if prefix != self.OtherPrefix: domains[prefix].add(symbol) for domainName in domains.keys(): domains[domainName] = list(domains[domainName]) return domains def callSol(self): domains = self.getDomains() #domains[refPrefix].add(refVal) self.problem = Problem(MinConflictsSolver()) tarSymbolsCache = {} self.varsInThisLine = 0 def addInTraceletCons(tarVal,newVarName): if (self.__printConds): print "CONS(IN) -> " + tarSymbolsCache[tarVal] + " == " + newVarName self.problem.addConstraint(self.varsEqual,[newVarName,tarSymbolsCache[tarVal]]) def addCrossTraceletCons(refVal,newVarName,refPrefix): if (self.__printConds): print "CONS(CROSS) -> " + newVarName + " == " + refVal self.problem.addConstraint(self.checkInputVsTarget(refVal),[newVarName]) def addVarWithPrefix(prefix,lineNumber): newVarName = self.getVarName(prefix,lineNumber,self.varsInThisLine) if len(domains[prefix]) == 0: print "EMP" self.problem.addVariables([newVarName],domains[prefix]) self.varsInThisLine+=1 return newVarName # mode can be - WRITE or NORMAL def doDF(refSymbol,tarSymbol,lineNumber,refPrefix,tarPrefix,nemonicType): if refPrefix == self.OtherPrefix or tarPrefix == self.OtherPrefix: return newVarName = addVarWithPrefix(tarPrefix,lineNumber) if (refPrefix == tarPrefix): addCrossTraceletCons(refSymbol,newVarName,refPrefix) if tarSymbol in tarSymbolsCache: addInTraceletCons(tarSymbol,newVarName) if tarPrefix != self.RegisterPrefix or nemonicType=="WriteThenRead": tarSymbolsCache[tarSymbol] = newVarName #for matchedCmd in itertools.chain(map(lambda nodeInfo:nodeInfo['matchedCmds'],self.nodeGradesInfos)): tarBase = 0 refBase = 0 for nodeInfo in self.nodeGradesInfos: for matchedCmd in nodeInfo['matchedCmds']: self.varsInThisLine = 1 # if these cmds are not an operational match, we cannot cross tracelet match them. if matchedCmd['operationMatch'] == True: currentLineNumber = tarBase + matchedCmd['tarCmdNum'] # matchedCmd['tarCmdNum'] is 1 based so we are ok if matchedCmd['tar'] =="" or matchedCmd['ref'] =="": continue tarCmdBasicInfo = self.breakCommand(matchedCmd['tar']) refCmdBasicInfo = self.breakCommand(matchedCmd['ref']) if len(tarCmdBasicInfo['ParamsList'])>0 and len(refCmdBasicInfo['ParamsList'])>0: if tarCmdBasicInfo['nemonic'] == 'call': assert(len(refCmdBasicInfo['ParamsList'])==1) assert(len(tarCmdBasicInfo['ParamsList'])==1) doDF(refCmdBasicInfo['ParamsList'][0], tarCmdBasicInfo['ParamsList'][0], currentLineNumber, self.FuncPrefix,self.FuncPrefix, "Read") else: nemonicType = self.getNemonicType(tarCmdBasicInfo['nemonic']) for (refParam,tarParam) in zip(refCmdBasicInfo['ParamsList'],tarCmdBasicInfo['ParamsList']): tarIsMem = "[" in tarParam if tarIsMem != ("[" in refParam): continue print matchedCmd print "BOY" assert tarIsMem == ("[" in refParam) if not tarIsMem: tarPreFix = self.getPrefix(tarParam) refPreFix = self.getPrefix(refParam) doDF(refParam, tarParam, currentLineNumber, tarPreFix,refPreFix, nemonicType) # TODO - return this to find more classes when we have time... """ if nemonicType == "WriteThenRead": if tarPreFix != self.RegisterPrefix: print matchedCmd assert (tarPreFix == self.RegisterPrefix) # the write is only to the left most param, rest are normal """ else: # this is memory! , first remove '[',']' for (refMember,tarMember) in zip(self.getMembers(refParam),self.getMembers(tarParam)): tarPreFix = self.getPrefix(tarMember) refPreFix = self.getPrefix(refMember) doDF(refMember, tarMember, currentLineNumber, tarPreFix,refPreFix, nemonicType) nemonicType = "Read" #TODO handle the False clause ? tarBase += nodeInfo['tarCode'].count(";") refBase += nodeInfo['refCode'].count(";") self.sol = self.problem.getSolution() #print self.sol def getBrokenNumber(self): return self.problem.getSolver().getHack() # TODO - make this __ def getRW(self): sol = self.getSolution() tarBase = 0 symbolsCache = {} self.varsInThisLine = 0 TotalLineNumber = 0 def getRewrittenSymbolUpdateCache(prefix,symbol): varName = self.getVarName(prefix, TotalLineNumber, self.varsInThisLine) if sol != None and varName in sol: symbolsCache[symbol] = sol[varName] return sol[varName] else: return symbol def rewrittenParam(param): if param.startswith("["): rewrittenMembers = [] for member in self.getMembers(param): rewrittenMembers.append(getRewrittenSymbolUpdateCache(self.getPrefix(member), member)) self.varsInThisLine+=1 return "[" + "+".join(rewrittenMembers) + "]" else: newParam = getRewrittenSymbolUpdateCache(self.getPrefix(param), param) self.varsInThisLine+=1 return newParam for nodeInfo in self.nodeGradesInfos: cmdsStr = nodeInfo['tarCode'] rewrittenCmds = [] lastLineNumber = 0 #filter(None,) for (lineNumber,cmd) in enumerate(cmdsStr.split(";")): TotalLineNumber = tarBase + lineNumber + 1 # we are one based lastLineNumber = lineNumber +1 # we are one based self.varsInThisLine = 1 if cmd != "": tarCmdBasicInfo = self.breakCommand(cmd) if len(tarCmdBasicInfo['ParamsList'])>0: if tarCmdBasicInfo['nemonic'] == 'call': rewrittenCmds.append("call " + getRewrittenSymbolUpdateCache(self.FuncPrefix,tarCmdBasicInfo['ParamsList'][0])) else: rewrittenCmds.append(tarCmdBasicInfo['nemonicWithDecoretors'] + " " + ",".join(map(rewrittenParam,tarCmdBasicInfo['ParamsList']))) else: rewrittenCmds.append(cmd) else: # this mostly cuz of bugs, but if i wont accumidate them it will cause a bad grade for nothing..(everything else wont be aligned) rewrittenCmds.append(cmd) tarBase += lastLineNumber-1 yield ";".join(rewrittenCmds) def getSolution(self): if self.sol == None: self.callSol() return self.sol def printSol(self,sol): #better call sol! if sol == None: print "NO SOL!" return last = 1 for key in sorted(sol.iterkeys()): if int(key[1:2]) != last: last = int(key[1:2]) print "" print key + ": " + sol[key] + " ",
def solve(): problem = Problem() # Define the variables: 9 rows of 9 variables rangin in 1...9 for i in range(1, 10): problem.addVariables(range(i * 10 + 1, i * 10 + 10), range(1, 10)) # Each row has different values for i in range(1, 10): problem.addConstraint(AllDifferentConstraint(), range(i * 10 + 1, i * 10 + 10)) # Each colum has different values for i in range(1, 10): problem.addConstraint(AllDifferentConstraint(), range(10 + i, 100 + i, 10)) # Each 3x3 box has different values problem.addConstraint(AllDifferentConstraint(), [11, 12, 13, 21, 22, 23, 31, 32, 33]) problem.addConstraint(AllDifferentConstraint(), [41, 42, 43, 51, 52, 53, 61, 62, 63]) problem.addConstraint(AllDifferentConstraint(), [71, 72, 73, 81, 82, 83, 91, 92, 93]) problem.addConstraint(AllDifferentConstraint(), [14, 15, 16, 24, 25, 26, 34, 35, 36]) problem.addConstraint(AllDifferentConstraint(), [44, 45, 46, 54, 55, 56, 64, 65, 66]) problem.addConstraint(AllDifferentConstraint(), [74, 75, 76, 84, 85, 86, 94, 95, 96]) problem.addConstraint(AllDifferentConstraint(), [17, 18, 19, 27, 28, 29, 37, 38, 39]) problem.addConstraint(AllDifferentConstraint(), [47, 48, 49, 57, 58, 59, 67, 68, 69]) problem.addConstraint(AllDifferentConstraint(), [77, 78, 79, 87, 88, 89, 97, 98, 99]) # Some value is given. initValue = [ [0, 9, 0, 7, 0, 0, 8, 6, 0], [0, 3, 1, 0, 0, 5, 0, 2, 0], [8, 0, 6, 0, 0, 0, 0, 0, 0], [0, 0, 7, 0, 5, 0, 0, 0, 6], [0, 0, 0, 3, 0, 7, 0, 0, 0], [5, 0, 0, 0, 1, 0, 7, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 9], [0, 2, 0, 6, 0, 0, 0, 5, 0], [0, 5, 4, 0, 0, 8, 0, 7, 0], ] for i in range(1, 10): for j in range(1, 10): if initValue[i - 1][j - 1] != 0: problem.addConstraint( lambda var, val=initValue[i - 1][j - 1]: var == val, (i * 10 + j, )) # Get the solutions. solutions = problem.getSolutions() return solutions
from constraint import AllDifferentConstraint, InSetConstraint, Problem # variables colors = "blue red green white yellow".split() nationalities = "Norwegian Ukranian Japanese Spaniard English".split() pets = "fox dog horse snails zebra".split() drinks = "tea coffee milk orange water".split() fruits = "grapes kiwi bananas peach grapefruit".split() # There are five houses. minn, maxn = 1, 5 problem = Problem() # value of a variable is the number of a house with corresponding property variables = colors + nationalities + pets + drinks + fruits problem.addVariables(variables, range(minn, maxn+1)) # Each house has its own unique color. # All house owners are of different nationalities. # They all have different pets. # They all drink different drinks. # They all smoke different fruits. for vars_ in (colors, nationalities, pets, drinks, fruits): problem.addConstraint(AllDifferentConstraint(), vars_) # In the middle house they drink milk. #NOTE: interpret "middle" in a numerical sense (not geometrical) problem.addConstraint(InSetConstraint([(minn + maxn) // 2]), ["milk"]) # The Norwegian lives in the first house. #NOTE: interpret "the first" as a house number problem.addConstraint(InSetConstraint([minn]), ["Norwegian"]) # The green house is on the left side of the white house.
from constraint import Problem, AllEqualConstraint problem = Problem() problem.addVariables(["a", "b"], [[1,3], [2,4], [5,6]]) problem.addConstraint(AllEqualConstraint(), ["a", "b"]) solutions = problem.getSolutions() print (solutions)