def solve_SAT(expr, num_solutions=None): """ Returns a iterator of {var: truth value} assignments which satisfy the given expression. Expressions should not include a variable named ``TRUE_``, since those are used in the internals of this function as stand-ins for truth literals. """ expr = convert_to_conjunctive_normal_form(expr) Assignment = get_assignment_class(expr) # Hack to include a True literal (not directly supported by pycosat API). # We add a trivial constraint to the list of constraints, forcing this # variables to be True in any solutions. Note that this is still conjunctive # normal form, since T and F are literals. T = Var('TRUE_') expr = expr & T vars = list(get_free_variables(expr)) # 1-index, since pycosat expects nonzero integers. var2pycosat_index = {v: i + 1 for i, v in enumerate(vars)} def get_pycosat_index(literal): # pycosat accepts input as a list of CNF subclauses (disjunctions of variables # or negated variables). if isinstance(literal, Not): return -get_pycosat_index(literal.children[0]) elif isinstance(literal, Var): return var2pycosat_index[literal] elif isinstance(literal, ExpressionNode): # pragma: no cover raise TypeError('Unhandled literal type %r' % literal) else: # Here we assume this is some other python object, so we consider it # a boolean. return var2pycosat_index[T] if literal else -var2pycosat_index[T] constraints = [ map(get_pycosat_index, # Child is one of a literal or a disjunction of literals. (child.children if isinstance(child, Or) else [child])) for child in expr.children ] solutions = ( pycosat.itersolve(constraints) if num_solutions is None else pycosat.itersolve(constraints, num_solutions)) for solution in solutions: namespace = {} for i, var_assignment in enumerate(solution): # pycosat returns the solution as a list of positive or negative # 1-indexed variable numbers. Positive indices correspond to assignments # to True, and negative corresponds to False. as_bool = var_assignment > 0 var = vars[i] if var == T: assert as_bool, 'Bug: Solution has an invalid solution to the T literal.' else: namespace[var.name] = as_bool yield Assignment(**namespace)
def sat(clauses): """ Calculate a SAT solution for `clauses`. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. """ try: import pycosat except ImportError: sys.exit('Error: could not import pycosat (required for dependency ' 'resolving)') try: pycosat.itersolve({(1,)}) except TypeError: # Old versions of pycosat require lists. This conversion can be very # slow, though, so only do it if we need to. clauses = list(map(list, clauses)) solution = pycosat.solve(clauses) if solution == "UNSAT" or solution == "UNKNOWN": # wtf https://github.com/ContinuumIO/pycosat/issues/14 return [] # XXX: If solution == [] (i.e., clauses == []), the result will have # boolean value of False even though the clauses are not unsatisfiable) return solution
def main(): # A requires B r1 = [-1, 2] # A requires C r2 = [-1, 3] # B conflicts C r3 = [-2, -3] # A conflicts B r4 = [-1, -2] # (-A|B) & (-A|C) & (-B|-C) cnf1 = [r1, r2, r3] # (-A|B) & (-A|-B) cnf2 = [r1, r4] print("Case 1:") for sol in pycosat.itersolve(cnf1): interpret(sol) print("\t----") print("Case 2:") for sol in pycosat.itersolve(cnf2): interpret(sol) print("\t----")
def test_shuffle_clauses(self): ref_sols = set(tuple(sol) for sol in itersolve(clauses1)) for _ in range(10): cnf = copy.deepcopy(clauses1) # shuffling the clauses does not change the solutions random.shuffle(cnf) self.assertEqual(set(tuple(sol) for sol in itersolve(cnf)), ref_sols)
def test_cnf1(self): for sol in itersolve(clauses1, nvars1): #sys.stderr.write('%r\n' % repr(sol)) self.assertTrue(evaluate(clauses1, sol)) sols = list(itersolve(clauses1, vars=nvars1)) self.assertEqual(len(sols), 18) # ensure solutions are unique self.assertEqual(len(set(tuple(sol) for sol in sols)), 18)
def min_sat(clauses, max_n=1000, N=None, alg='iterate'): """ Calculate the SAT solutions for the `clauses` for which the number of true literals from 1 to N is minimal. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. alg can be any algorithm supported by generate_constraints, or 'iterate", which iterates all solutions and finds the smallest. """ log.debug("min_sat using alg: %s" % alg) try: import pycosat except ImportError: sys.exit('Error: could not import pycosat (required for dependency ' 'resolving)') if not clauses: return [] m = max(map(abs, chain(*clauses))) if not N: N = m if alg == 'iterate': min_tl, solutions = sys.maxsize, [] try: pycosat.itersolve({(1,)}) except TypeError: # Old versions of pycosat require lists. This conversion can be # very slow, though, so only do it if we need to. clauses = list(map(list, clauses)) for sol in islice(pycosat.itersolve(clauses), max_n): tl = sum(lit > 0 for lit in sol[:N]) # number of true literals if tl < min_tl: min_tl, solutions = tl, [sol] elif tl == min_tl: solutions.append(sol) return solutions else: solution = sat(clauses) if not solution: return [] eq = [(1, i) for i in range(1, N+1)] def func(lo, hi): return list(generate_constraints(eq, m, [lo, hi], alg=alg)) evaluate_func = partial(evaluate_eq, eq) # Since we have a solution, might as well make use of that fact max_val = evaluate_func(solution) log.debug("Using max_val %s. N=%s" % (max_val, N)) constraints = bisect_constraints(0, min(max_val, N), clauses, func, evaluate_func=evaluate_func, increment=1000) return min_sat(list(chain(clauses, constraints)), max_n=max_n, N=N, alg='iterate')
def solve(self): """ Produces an iterator for schedule possibilities that have no conflicts. Solves the constraints using a SAT solving algorithm and processes the results. """ return ([self.index_mapping[y] for y in x if y > 0] for x in pycosat.itersolve(self.constraints))
def min_sat(clauses, max_n=1000): """ Calculate the SAT solutions for the `clauses` for which the number of true literals is minimal. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. This function could be implemented using a Pseudo-Boolean SAT solver, which would avoid looping over the SAT solutions, and would therefore be much more efficient. However, for our purpose the current implementation is good enough. """ try: import pycosat except ImportError: sys.exit('Error: could not import pycosat (required for dependency ' 'resolving)') min_tl, solutions = sys.maxsize, [] for sol in islice(pycosat.itersolve(clauses), max_n): tl = sum(lit > 0 for lit in sol) # number of true literals if tl < min_tl: min_tl, solutions = tl, [sol] elif tl == min_tl: solutions.append(sol) return solutions
def solve(n): y =[] #rows for i in range (1,(n*n)+1,n): y += vertical(range(i,i+n,1),True) #columns for i in range (1,n+1): y+= vertical(range(i,(n*n)-n+1+i,n),True) #diagonals y+=diagonal(1,n) #results result = [] for sol in pycosat.itersolve(y): result.append(sol) #replace numbers with something more meaningful result = changeFormat(result,n) #return a boolean list indicating which solutions are unique isValid = returnWithoutRotations(result) #figure out how many unique solutions there are NValidSol = 0 for i in range(0,len(result)): if isValid[i] : NValidSol += 1 #print out all the unique solutions for i in range(0,len(result)): if(isValid[i]): printSol(result[i]) print("There are " , NValidSol , " unique solutions with rotations and reflections")
def solve(): clauses = queens_clauses() # solve the SAT problem for sol in pycosat.itersolve(clauses): sol = set(sol) for i in range(N): print(''.join('Q' if v(i, j) in sol else '.' for j in range(N))) print('')
def solutions(self): """ Yield each solution to the current set of constraints. """ solution_found = False for solution in pycosat.itersolve(self.clauses): yield self.remap_solution(solution) solution_found = True if not solution_found: # Only present to raise a descriptive exception. self.solution
def minimal_solutions(self): # this is a bit of a strawman. the idea is, we need to enumerate all of the SAT # solutions to know which is the smallest! the containment thing in the old version (below) # seems sketchy to me, due to nonmonotonicity. return to this later. solns = [] for soln in pycosat.itersolve(self.satformula): solns.append(frozenset(map(self.vars.lookupNum, filter(lambda x: x > 0, soln)))) def getKey(item): return len(item) for soln in sorted(solns, key=getKey): yield soln
def Nminimal_solutions(self): solns = [] done = [] for soln in pycosat.itersolve(self.satformula): solns.append(frozenset(map(self.vars.lookupNum, filter(lambda x: x > 0, soln)))) def getKey(item): return len(item) for soln in sorted(solns, key=getKey): #if not done.has_key(soln): # yield soln if self.contained_in_none(done, soln): yield soln done.append(soln)
def main(req_use): if req_use.strip() == '': return [[]] # REQUIRED_USE variable value for which the combinations # are being generated # If flags aren't provided, match words from REQUIRED_USE flags = re.findall(r'\w+', req_use) # Remove duplicates flags = list(set(flags)) # sort reverse to length (so that they can be replaced in # this order by numbers later) flags = sorted(flags, key=len) flags.reverse() i = 1 dict = {} rev_dict = {} # Assign a number to each keyword (to send to pycosat as # it accepts cnf in form of numbers ) for k in flags: dict[k] = i rev_dict[i] = k i += 1 # Generate the needed boolean expression cnf_out = solve(req_use) # str(object) gives a string in CNF form cnf_str = str(cnf_out) # Replace all flags with numerical equivalent for key in flags: cnf_str = cnf_str.replace(key, str(dict[key])) # Convert to form needed by pycosat cnf_str = cnf_str[1:-1] cnf_lst = cnf_str.split(') & (') for i in range(len(cnf_lst)): cnf_lst[i] = [int(k) for k in cnf_lst[i].split(' | ')] # Generate all possible solutions to the equation k = (list(pycosat.itersolve(cnf_lst))) for soln in k: for i in range(0, len(soln)): soln[i] = ( "-" if soln[i] < 0 else "" ) + rev_dict[abs(soln[i])] return k
def sat(clauses, iterator=False): """ Calculate a SAT solution for `clauses`. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. """ if pycosat_prep: clauses = list(map(list,clauses)) if iterator: return pycosat.itersolve(clauses) solution = pycosat.solve(clauses) if solution == "UNSAT" or solution == "UNKNOWN": return None return solution
def process_cnf_file(path): sys.stdout.write('%30s: ' % basename(path)) sys.stdout.flush() clauses, n_vars = read_cnf(path) sys.stdout.write('vars: %6d cls: %6d ' % (n_vars, len(clauses))) sys.stdout.flush() n_sol = 0 for sol in itersolve(clauses, n_vars): sys.stdout.write('.') sys.stdout.flush() assert evaluate(clauses, sol) n_sol += 1 sys.stdout.write("%d\n" % n_sol) sys.stdout.flush() return n_sol
def _generate_schedules_sat_from_sections(sections, busy_times, preferences): clauses = [] # Map from input domain to SAT domain # - input domain: course sections # - SAT domain: integers from_index, from_string, to_index = _build_section_index(sections) # Constraint: Must schedule one section for each core component core_clauses = collections.defaultdict(list) for core_section in sections: index = to_index[core_section.get('asString')] core_clauses[core_section.get('course') + core_section.get('component')].append(index) clauses += [v for k, v in core_clauses.iteritems()] # Constraint: Must not schedule conflicting sections together # Note: sections in the same component conflict # Note: recall (A' + B') == (AB)' conflict_clauses = [] for a, b in _get_conflicts(sections, busy_times): if a.get('asString') != b.get('asString'): conflict_clauses.append([-1 * to_index[a.get('asString')], -1 * to_index[b.get('asString')]]) else: conflict_clauses.append([-1 * to_index[a.get('asString')]]) clauses += conflict_clauses # Solve the SAT problem and map back to input domain from SAT domain schedules = [] for solution in pycosat.itersolve(clauses): sections = [from_index[i] for i in solution if i > 0] schedules.append(Schedule(sections=sections, preferences=preferences)) if len(schedules) > 100: break return schedules
def mate(ind1, ind2, groups, model): # g = deepcopy(groups) # random.shuffle(g) # g = g[:int(len(g)*0.1)] # g = [item for i in g for item in i] # s1 = list(ind1) # s2 = list(ind2) # for i in range(len(s1)): # if i in g: # s1[i], s2[i] = s2[i], s1[i] # split_point = random.randint(0, len(s1)) # ind1 = model.Individual(''.join(s1[:split_point]+s2[split_point:])) # ind2 = model.Individual(''.join(s2[:split_point]+s1[split_point:])) # pdb.set_trace() # return ind1, ind2 diff = [i for i, (x, y) in enumerate(zip(ind1, ind2)) if x != y] # lock the irrelevant parts cnfs = [] for i in range(len(ind1)): if random.random() < 0.1: continue if i not in diff: if ind1[i] == '1': cnfs += [[i+1]] else: cnfs += [[-i-1]] sat_engine = pycosat.itersolve(model.cnfs + cnfs) l = list(islice(sat_engine, 2)) if len(l) == 0: return ind1, ind2 if len(l) == 1: return model.Individual(pycosatSol2binstr(l[0])), ind2 else: ind1 = model.Individual(pycosatSol2binstr(l[0])) ind2 = model.Individual(pycosatSol2binstr(l[1])) # pdb.set_trace() return ind1, ind2
def grouping_dimacs_model_by_sat_solver(dimacs_model): # results start from 0 appendix = list() model = dimacs_model inds = [] i = 0 cnfs = deepcopy(model.cnfs) groups = list() while True: sat_engine = pycosat.itersolve(cnfs) i = 0 for sol in sat_engine: i += 1 if i > 100: break inds.append(model.Individual(pycosatSol2binstr(sol))) tmp = map(list, zip(*inds)) tmp = map(lambda x: len(set(x)), tmp) group1 = [i for i, j in enumerate(tmp) if j > 1] if len(group1) > 0: groups.append(group1) else: break addition = [] for i, j in zip(group1, itemgetter(*group1)(inds[0])): if j == '0': addition.append([-i-1]) else: addition.append([i+1]) cnfs = cnfs + addition appendix.extend(inds) inds = [] return groups, appendix
def test_cnf3_3vars(self): self.assertEqual(list(itersolve(clauses3, 3)), [[-1, -2, -3], [-1, -2, 3]])
def test_many_clauses(self): ref_sols = set(tuple(sol) for sol in itersolve(clauses1)) # repeating the clauses many times does not change the solutions cnf = 100 * copy.deepcopy(clauses1) self.assertEqual(set(tuple(sol) for sol in itersolve(cnf)), ref_sols)
======= m = max(chain(*clauses)) >>>>>>> princeofdarkness76/min_constraints ======= m = max(chain(*clauses)) >>>>>>> origin/min_constraints if not N: N = m if alg == 'iterate': min_tl, solutions = sys.maxsize, [] <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD try: pycosat.itersolve({(1,)}) except TypeError: # Old versions of pycosat require lists. This conversion can be # very slow, though, so only do it if we need to. clauses = list(map(list, clauses)) i = -1 for sol, i in zip(pycosat.itersolve(clauses), range(max_n)): ======= for sol in islice(pycosat.itersolve(clauses), max_n): >>>>>>> conda/min_constraints ======= for sol in islice(pycosat.itersolve(clauses), max_n): >>>>>>> origin/min_constraints ======= for sol in islice(pycosat.itersolve(clauses), max_n): >>>>>>> princeofdarkness76/min_constraints
def test_gen_clauses(self): def gen_clauses(): for clause in clauses1: yield clause self.assertTrue(all(evaluate(clauses1, sol) for sol in itersolve(gen_clauses())))
def test_tuple_caluses(self): self.assertTrue(all(evaluate(clauses1, sol) for sol in itersolve(tuple(clauses1))))
def test_no_clauses(self): for n in range(7): self.assertEqual(len(list(itersolve([], vars=n))), 2 ** n)
# Ensure the given cells are shaded. def fix_givens(): clauses = [] for row, col in GIVENS: clauses.append([shaded_vars[row, col].idx]) return clauses # Put together all the clauses, and then find the results. all_clauses = ( row_run_implies_shaded() + col_run_implies_shaded() + shaded_implies_row_run() + shaded_implies_col_run() + row_run_ordering() + col_run_ordering() + row_run_at_most_one_position() + col_run_at_most_one_position() + row_run_at_least_one_position() + col_run_at_least_one_position() + exclude_invalid_row_run_positions() + exclude_invalid_col_run_positions() + fix_givens() ) for sol_idx, sol in enumerate(pycosat.itersolve(all_clauses)): pretty_print_solution(sol)
def test_each_clause_tuples(self): self.assertTrue( all( evaluate(clauses1, sol) for sol in itersolve([tuple(clause) for clause in clauses1])))
def test_each_clause_gen(self): self.assertTrue( all( evaluate(clauses1, sol) for sol in itersolve([(x for x in clause) for clause in clauses1])))
def itersolve(symbolic_cnf, include_neg=False): numbered_cnf, num2var = translate(symbolic_cnf) for solution in pycosat.itersolve(numbered_cnf): yield [num2var[n] for n in solution if include_neg or n > 0]
nz = len(C.clauses) if nz < len(eq): eq = [q for q in eq if q[0] <= rhs[1]] res = C.build_BDD(eq, rhs[0], rhs[1], polarity=True) if res is false: # Impossible to satisfy, so just stuff a contradiciton in there return [(m, ), (-m, )] elif res is true: return [] else: C.clauses.append((res, )) return C.clauses try: pycosat.itersolve({(1, )}) pycosat_prep = False except TypeError: pycosat_prep = True def sat(clauses, iterator=False): """ Calculate a SAT solution for `clauses`. Returned is the list of those solutions. When the clauses are unsatisfiable, an empty list is returned. """ if pycosat_prep: clauses = list(map(list, clauses))
def my_itersolve(iterable): """ Work around https://github.com/ContinuumIO/pycosat/issues/13 """ iterable = [[i for i in j] for j in iterable] return pycosat.itersolve(iterable)
def readDMACS(): global clauseFile, clauseFileLines, clauseSet clauseFile = open('days.txt', "r") clauseFileLines = clauseFile.readlines() clauseSet = list() clauseSet.append(list()) maxvar = 0 for line in clauseFileLines: tokens = line.split() if len(tokens) != 0 and tokens[0] not in ("p", "c"): for tok in tokens: lit = int(tok) maxvar = max(maxvar, abs(lit)) if lit == 0: clauseSet.append(list()) else: clauseSet[-1].append(lit) assert len(clauseSet[-1]) == 0 clauseSet.pop() print(clauseSet) print(maxvar) if __name__ == "__main__": print "Welcome!" readDMACS() print "The clause set after calling the parser function is:" print clauseSet print "This is the solution" for sol in pycosat.itersolve(clauseSet): print sol
def setup(self, m, limit=0, **kwargs): from pycosat import itersolve # NOTE: The iterative solving isn't actually used here, we just call # itersolve to separate setup from the actual run. return itersolve(self._clauses.as_list(), vars=m, prop_limit=limit)
def get_valid_variants(self, size): """ A function to compute the valid variants of a model. Args: constraint_list (list): All constrains provided for the model. size (int): The desired number of variants for the model. Returns: A numpy matrix with variants, which satisfy the provided constrains. Each row represents one variant. """ new_c = self.constraints.copy() perm_method = self.perm_method assert (perm_method in ["complete", "clauses", "no_permutation"]), ( "Options for Permutation_Method are: complete, clauses, no_permutation" ) assert (self.sampling_method in [ "random", "feature-wise", "pair-wise", "neg-feature-wise", "neg-pair-wise" ]), ( "Options for Sampling_Method are: random, feature-wise, neg-feature-wise, pair-wise, neg-pair-wise" ) sampling = { 'feature-wise': lambda x, i, j: x.append([i]), 'pair-wise': lambda x, i, j: x.extend([[i], [j]]), 'neg-feature-wise': lambda x, i, j: x.append([-(i)]), 'neg-pair-wise': lambda x, i, j: x.extend([[-i], [-j]]) }.get(self.sampling_method) sol_collection = list() # substract root feature largest_dimacs_literal = len(self.feature_influences) #- 1 if not np.any([ largest_dimacs_literal in sub_list for sub_list in self.constraints ]): dummy_constraint = [ largest_dimacs_literal, -1 * largest_dimacs_literal ] new_c.append(dummy_constraint) if perm_method == "no_permutation" and self.sampling_method == "random": solutions = list(itertools.islice(pycosat.itersolve(new_c), size)) for elem in solutions: solution = Vm.transform2binary(elem) sol_collection.append(solution) else: for i in range(0, size): if perm_method == "clauses" or perm_method == "complete": shuffle(new_c) # shuffle the constraints if perm_method == "complete": for constraint in new_c: # shuffle feature assignment in constraints shuffle(constraint) c_copy = list(new_c) if self.sampling_method != "random": sampling(c_copy, i + 1, (i + 1) % (size) + 1) solution = pycosat.solve(c_copy) if solution != "UNSAT": new_c.append([j * -1 for j in solution]) solution = Vm.transform2binary(solution) sol_collection.append(solution) m_sol_list = np.asmatrix(sol_collection) return m_sol_list
def test_tuple_caluses(self): self.assertTrue( all(evaluate(clauses1, sol) for sol in itersolve(tuple(clauses1))))
def test_iter_clauses(self): self.assertTrue(all(evaluate(clauses1, sol) for sol in itersolve(iter(clauses1))))
def FillInSequence(self, boundaryCondition=BoundaryCondition.ALL_DEAD): sequence = self.game.tilings if len(sequence) <= 1: raise Exception('A sequence needs at least 2 elements!') for tiling in sequence: assert isinstance(tiling, LifeTiling) assert tiling.height == sequence[0].height and tiling.width == sequence[0].width, \ 'Cannot compare tilings with different dimensions.' height = sequence[0].height width = sequence[0].width oldToNewVariables = dict() offsets = [-1, 0, 1] inputWires = [] if DEBUG: print('Initiating building of circuit graph.') t0 = time.time() for index in reversed(range(1, len(sequence))): A = sequence[index - 1] B = sequence[index] for row in range(A.height): for col in range(A.width): inputWires.append(A[row][col].wire) prevNodes = [] for i in offsets: for j in offsets: if boundaryCondition == BoundaryCondition.TOROIDAL: adjustedRow = (row + i) % A.height adjustedCol = (col + j) % A.width prevNodes.append( A[adjustedRow][adjustedCol].wire) elif boundaryCondition == BoundaryCondition.ALL_DEAD: adjustedRow = row + i adjustedCol = col + j # Out of bounds cells count as dead if adjustedRow not in range( A.height) or adjustedCol not in range( A.width): prevNodes.append(Wire(constant=False)) else: prevNodes.append( A[adjustedRow][adjustedCol].wire) elif boundaryCondition == BoundaryCondition.ALL_ALIVE: adjustedRow = row + i adjustedCol = col + j # Out of bounds cells count as alive if adjustedRow not in range( A.height) or adjustedCol not in range( A.width): prevNodes.append(Wire(constant=True)) else: prevNodes.append( A[adjustedRow][adjustedCol].wire) else: raise Exception('Unknown boundary condition') tilePrecedingLogic = GateCustom() tilePrecedingLogic.LIFE_nextState(prev9tiles=prevNodes, output=B[row][col].wire) if DEBUG: total = time.time() - t0 print('Building of circuit graph completed. (' + str(total) + ' seconds)') layerFormula = LogicFormula(inputWires) cnfFormula = sorted(layerFormula.cnfForm.rawCNF(), key=lambda x: [len(x), [abs(y) for y in x]]) # Add extra assertion that no triple along an edge has all 3 variables true. for tiling in sequence: if tiling.time == len(sequence) - 1: pass for row in range(height): for col in range(width): if (row == 0 or row == height - 1) and (col != 0 and col != width - 1): cnfFormula.append([ -tiling[row][col - 1].variable, -tiling[row][col].variable, -tiling[row][col + 1].variable ]) if (col == 0 or col == width - 1) and (row != 0 and row != height - 1): cnfFormula.append([ -tiling[row - 1][col].variable, -tiling[row][col].variable, -tiling[row + 1][col].variable ]) cnt = 0 for tiling in sequence: for row in range(tiling.height): for col in range(tiling.width): oldToNewVariables[tiling[row][col].variable] = tiling[row][ col].wire.variable self.createSolutionDir() if DEBUG: print('Starting to find solutions.') t0 = time.time() for solution in pycosat.itersolve(cnfFormula): if DEBUG and cnt == 0: total = time.time() - t0 print('First solution found in ' + str(total) + ' seconds.') if self.solutionCap is not None and self.solutionCap <= cnt: break # print('--------------------') # print(solution) updatedSequence = [] for tiling in sequence: newTilingA = LifeTiling(tiling.height, tiling.width, tiling.time) for row in range(tiling.height): for col in range(tiling.width): if oldToNewVariables[tiling[row] [col].variable] in solution: if tiling[row][ col].state == LifeState.ALIVE or tiling[ row][col].state == LifeState.DONTCARE: # This means that we either forced the cell to be alive or we derived a possible value newTilingA[row][col].state = LifeState.ALIVE pass else: raise Exception( "Computed state is incompatible with original state" ) elif -oldToNewVariables[tiling[row] [col].variable] in solution: if tiling[row][ col].state == LifeState.DEAD or tiling[ row][col].state == LifeState.DONTCARE: # This means that we either forced the cell to be dead or we derived a possible value newTilingA[row][col].state = LifeState.DEAD pass else: raise Exception( "Computed state is incompatible with original state" ) else: raise Exception( "Input wasn't even in the solution! Something is clearly wrong here." ) updatedSequence.append(newTilingA) # print('After A:') # print(newTilingA) # print('After B:') # print(B) gameSolution = LifeGameInstance( boundaryCondition=boundaryCondition) gameSolution.SetFrames(updatedSequence) print(gameSolution) self.addSolution(gameSolution) cnt += 1 if DEBUG: total = time.time() - t0 print('All solutions found or solution limit reached. (' + str(total) + ' seconds)')
def test_each_clause_tuples(self): self.assertTrue(all(evaluate(clauses1, sol) for sol in itersolve([tuple(clause) for clause in clauses1])))
def test_iter_clauses(self): self.assertTrue( all(evaluate(clauses1, sol) for sol in itersolve(iter(clauses1))))
def test_each_clause_gen(self): self.assertTrue(all(evaluate(clauses1, sol) for sol in itersolve([(x for x in clause) for clause in clauses1])))
def test_cnf2(self): self.assertEqual(list(itersolve(clauses2, nvars2)), [])
def solve(self): """""" cnf = self.cnf2list() return ps.itersolve(cnf)
def test_cnf1_prop_limit(self): self.assertEqual(list(itersolve(clauses1, prop_limit=2)), [])
def test_no_clauses(self): for n in range(7): self.assertEqual(len(list(itersolve([], vars=n))), 2**n)
def __init__(self, clauses): self.i = -1 self.sol_iter = pycosat.itersolve(clauses) self.cache = []
def setup(self, clauses, m, limit=0): # NOTE: The iterative solving isn't actually used here, we just call # itersolve to separate setup from the actual run. return pycosat.itersolve(clauses.as_list(), vars=m, prop_limit=limit)