def solve(instance, watchlist, assignment, d, verbose): """ Iteratively solve SAT by assigning to variables d, d+1, ..., n-1. Assumes variables 0, ..., d-1 are assigned so far. A generator for all the satisfying assignments is returned. """ # The state list wil keep track of what values for which variables # we have tried so far. A value of 0 means nothing has been tried yet, # a value of 1 means False has been tried but not True, 2 means True but # not False, and 3 means both have been tried. n = len(instance.variables) state = [0] * n while True: if d == n: yield assignment d -= 1 continue # Let's try assigning a value to v. Here would be the place to insert # heuristics of which value to try first. tried_something = False for a in [0, 1]: if (state[d] >> a) & 1 == 0: if verbose: print('Trying {} = {}'.format(instance.variables[d], a), file=stderr) tried_something = True # Set the bit indicating a has been tried for d state[d] |= 1 << a assignment[d] = a if not update_watchlist(instance, watchlist, d << 1 | a, assignment, verbose): assignment[d] = None else: d += 1 break if not tried_something: if d == 0: # Can't backtrack further. No solutions. return else: # Backtrack state[d] = 0 assignment[d] = None d -= 1
def recursive_solve(instance, watchlist, assignment, d, unit_propagation=False, verbose=False): """ Recursively solve SAT by assigning to variables d, d+1, ..., n-1. Assumes variables 0, ..., d-1 are assigned so far. A generator for all the satisfying assignments is returned. """ if d == len(instance.variables): yield assignment return # if unit_propagation: # if unit_pg(instance, # watchlist, # assignment, # unit_propagation, # verbose): if unit_propagation: pp_assignment = copy.deepcopy(assignment) unit_pg(instance, watchlist, pp_assignment, unit_propagation, verbose) # print(pp_assignment, assignment) next_d = None for i in range(len(pp_assignment)): if pp_assignment[i] != assignment[i]: next_d = i # print(pp_assignment, assignment) if next_d != None: assignment = pp_assignment d = next_d # if not assignment[d] is None: # return for a in [0, 1]: if verbose: print('Trying {} = {}'.format(instance.variables[d], a), file=stderr) assignment[d] = a if update_watchlist(instance, watchlist, variable_to_literal(d, a), assignment, unit_propagation, verbose): for a in recursive_solve(instance, watchlist, assignment, d+1, unit_propagation, verbose): yield a assignment[d] = None
def solve_iterative(instance, watchlist, assignment, d, verbose): """ - The state list wil keep track of what values for which variables were tried - A value of 0 means nothing has been tried yet - A value of 1 means False has been tried but not True - A value of 2 means True has been tried but not False - A value of 3 means True and False have been tried. """ n = len(instance.variables) state = [0] * n while True: if d == n: yield assignment d -= 1 continue # Let's try assigning a value to v. Here would be the place to insert # heuristics of which value to try first. tried_something = False for a in [0, 1]: if (state[d] >> a) & 1 == 0: if verbose: print('Trying {} = {}'.format(instance.variables[d], a), file=stderr) tried_something = True # Set the bit indicating a has been tried for d state[d] |= 1 << a assignment[d] = a if not update_watchlist(instance, watchlist, d << 1 | a, assignment, verbose): assignment[d] = None else: d += 1 break if not tried_something: if d == 0: # Can't backtrack further. No solutions. return else: # Backtrack state[d] = 0 assignment[d] = None d -= 1
def solve(instance, watchlist, assignment, d, verbose): """ Iteratively solve SAT by assigning to variables d, d+1, ..., n-1. Assumes variables 0, ..., d-1 are assigned so far. A generator for all the satisfying assignments is returned. """ # The state list wil keep track of what values for which variables # we have tried so far. A value of 0 means nothing has been tried yet, # a value of 1 means False has been tried but not True, 2 means True but # not False, and 3 means both have been tried. n = len(instance.variables) state = [0] * n while True: if d == n: yield assignment d -= 1 continue # Let's try assigning a value to v. Here would be the place to insert # heuristics of which value to try first. tried_something = False for a in [0, 1]: if (state[d] >> a) & 1 == 0: if verbose: print("Trying {} = {}".format(instance.variables[d], a), file=stderr) tried_something = True # Set the bit indicating a has been tried for d state[d] |= 1 << a assignment[d] = a if not update_watchlist(instance, watchlist, d << 1 | a, assignment, verbose): assignment[d] = None else: d += 1 break if not tried_something: if d == 0: # Can't backtrack further. No solutions. return else: # Backtrack state[d] = 0 assignment[d] = None d -= 1
def solve(instance, watchlist, assignment, d, verbose): """ Recursively solve SAT by assigning to variables d, d+1, ..., n-1. Assumes variables 0, ..., d-1 are assigned so far. A generator for all the satisfying assignments is returned. """ if d == len(instance.variables): yield assignment return for a in [0, 1]: if verbose: print('Trying {} = {}'.format(instance.variables[d], a), file=stderr) assignment[d] = a if update_watchlist(instance, watchlist, (d << 1) | a, assignment, verbose): for a in solve(instance, watchlist, assignment, d + 1, verbose): yield a assignment[d] = None