def standardise_variables_names(self, indent=0):
        print_message("Standardising variable names...", 3, indent=indent)

        # Give variables standard names and replace stars with new variable names
        standard_variables_from_input_variables = {}
        current_variable_number = 0

        for t, generation in enumerate(self.background_grid):
            for y, row in enumerate(generation):
                for x, cell in enumerate(row):
                    if cell == "*":
                        self.background_grid[t][y][x] = "c" + str(current_variable_number)
                        current_variable_number += 1
                    elif cell not in ["0", "1"]:
                        (variable, negated) = variable_from_literal(cell)
                        if variable not in standard_variables_from_input_variables:
                            standard_variables_from_input_variables[variable] = negate(
                                "c" + str(current_variable_number), negated)
                            current_variable_number += 1
                        self.background_grid[t][y][x] = negate(standard_variables_from_input_variables[variable],
                                                               negated)
        for t, generation in enumerate(self.grid):
            for y, row in enumerate(generation):
                for x, cell in enumerate(row):
                    if cell == "*":
                        self.grid[t][y][x] = "c" + str(current_variable_number)
                        current_variable_number += 1
                    elif cell not in ["0", "1"]:
                        (variable, negated) = variable_from_literal(cell)
                        if variable not in standard_variables_from_input_variables:
                            standard_variables_from_input_variables[variable] = negate(
                                "c" + str(current_variable_number), negated)
                            current_variable_number += 1
                        self.grid[t][y][x] = negate(standard_variables_from_input_variables[variable], negated)
        # Rename any literals in rule
        for transition, literal in self.rule.items():
            if literal not in ["0", "1"]:
                (variable, negated) = variable_from_literal(literal)
                if variable not in standard_variables_from_input_variables:
                    standard_variables_from_input_variables[variable] = negate("c" + str(current_variable_number),
                                                                               negated)
                    current_variable_number += 1
                self.rule[transition] = negate(standard_variables_from_input_variables[variable], negated)

        print_message("Done\n", 3, indent=indent)
Esempio n. 2
0
def rulestring_from_rule(rule):
    variables = [variable_from_literal(value)[0] for value in rule.values() if value not in ["0", "1"]]

    if len(variables) != len(set(variables)):
        return "{" + ", ".join(
            ("'" + transition + "': '" + literal + "'") for transition, literal in sorted(rule.items())) + "}"
    elif len(variables) == 0:
        partial_flag = False
    else:
        partial_flag = True

    rulestring = ""
    if partial_flag:
        rulestring += "p"

    for BS_letter in ["B", "S"]:
        rulestring += BS_letter
        for number_of_neighbours in "012345678":
            if not partial_flag:
                possible_number_of_transitions = len(possible_transitions[number_of_neighbours])
                number_of_transitions = sum((rule[BS_letter + number_of_neighbours + character] == "1")
                                            for character in possible_transitions[number_of_neighbours])
                if number_of_transitions == possible_number_of_transitions:
                    rulestring += number_of_neighbours
                elif 0 < number_of_transitions <= possible_number_of_transitions / 2:
                    rulestring += number_of_neighbours
                    for character in possible_transitions[number_of_neighbours]:
                        if rule[BS_letter + number_of_neighbours + character] == "1":
                            rulestring += character
                elif number_of_transitions != 0:
                    rulestring += number_of_neighbours
                    rulestring += "-"
                    for character in possible_transitions[number_of_neighbours]:
                        if rule[BS_letter + number_of_neighbours + character] == "0":
                            rulestring += character
            else:
                characters = ""
                banned_characters = ""
                for character in possible_transitions[number_of_neighbours]:
                    literal = rule[BS_letter + number_of_neighbours + character]
                    if literal == "0":
                        banned_characters += character
                    elif literal == "1":
                        characters += character
                if characters == "" and banned_characters == "":
                    rulestring += number_of_neighbours
                elif len(banned_characters) < len(possible_transitions[number_of_neighbours]):
                    rulestring += number_of_neighbours
                    rulestring += characters
                    if len(banned_characters) > 0:
                        rulestring += "-"
                        rulestring += banned_characters

        if BS_letter == "B":
            rulestring += "/"

    return rulestring
def search_pattern_from_string(input_string, indent=0):
    """Create the grid and ignore_transition of a search pattern from the given string"""
    grid, ignore_transition = src.formatting.parse_input_string(input_string, indent=indent)

    print_message("Pattern parsed as:\n" + src.formatting.make_csv(grid, ignore_transition) + "\n", 3, indent=indent)

    for t, generation in enumerate(grid):
        for y, row in enumerate(generation):
            for x, cell in enumerate(row):
                if cell not in ["0", "1", "*"]:
                    variable, negated = variable_from_literal(cell)
                    grid[t][y][x] = negate("user_input_" + variable, negated)

    return grid, ignore_transition
    def deterministic(self, indent=0):
        print_message("Checking if pattern is deterministic...", 3, indent=indent)
        determined = make_grid(False, template=self.grid)
        determined_variables = set()
        width = len(self.grid[0][0])
        height = len(self.grid[0])

        while True:
            determined_copy = copy.deepcopy(determined)
            for t, generation in enumerate(self.grid):
                for y, row in enumerate(generation):
                    for x, cell in enumerate(row):
                        if not determined[t][y][x]:
                            if cell in ["0", "1"]:
                                determined[t][y][x] = True
                            else:
                                variable, negated = variable_from_literal(cell)
                                if t == 0:
                                    determined[t][y][x] = True
                                    determined_variables.add(variable)
                                elif variable in determined_variables:
                                    determined[t][y][x] = True
                                elif all(determined[t - 1][y + y_offset][x + x_offset] for x_offset in range(2) for
                                         y_offset in range(2) if
                                         x + x_offset in range(width) and y + y_offset in range(height)) and not \
                                        self.ignore_transition[t][y][x]:
                                    determined[t][y][x] = True
                                    determined_variables.add(variable)
            if determined == determined_copy:
                break

        print_message("Done\n", 3, indent=indent)
        if all(flag for generation in determined for row in generation for flag in row):
            return True
        else:
            return False
 def append(self, clause):
     dimacs_clause = []
     clause = set(clause)
     if "1" in clause:
         return
     for literal in clause:
         if literal == "0":
             pass
         else:
             (variable, negated) = variable_from_literal(literal)
             # If we haven't seen it before then add it to the dictionary
             if variable not in self.dimacs_literal_from_variable:
                 self.dimacs_literal_from_variable[variable] = str(
                     self.number_of_variables + 1)
                 self.number_of_variables += 1
             elif negate(literal) in clause:
                 return
             dimacs_clause.append(
                 negate(self.dimacs_literal_from_variable[variable],
                        negated,
                        dimacs=True))
     dimacs_clause.sort()
     dimacs_clause.append("0\n")
     self.clause_set.add(" ".join(dimacs_clause))
    def substitute_solution(self, solution, indent=0):
        """Return a copy of the search_pattern with the solution substituted back into it"""
        grid = copy.deepcopy(self.grid)
        rule = copy.deepcopy(self.rule)
        background_grid = copy.deepcopy(self.background_grid)

        print_message('Substituting solution back into search grid...', 3, indent=indent)

        # Remove the first line that just says "SAT", and split into a list of literals
        solution = set(solution.split("\n")[1].split())

        for t, generation in enumerate(grid):
            for y, row in enumerate(generation):
                for x, cell in enumerate(row):
                    if cell in ["0", "1"]:
                        pass
                    else:
                        (CNF_variable, negated) = variable_from_literal(cell)
                        if CNF_variable in self.clauses.dimacs_literal_from_variable:
                            dimacs_variable = self.clauses.dimacs_literal_from_variable[CNF_variable]

                            dimacs_literal = negate(dimacs_variable, negated, dimacs=True)

                            if dimacs_literal in solution:
                                grid[t][y][x] = "1"
                            else:
                                grid[t][y][x] = "0"
                        else:
                            grid[t][y][x] = "0"

        for t, generation in enumerate(background_grid):
            for y, row in enumerate(generation):
                for x, cell in enumerate(row):
                    if cell in ["0", "1"]:
                        pass
                    else:
                        (CNF_variable, negated) = variable_from_literal(cell)
                        if CNF_variable in self.clauses.dimacs_literal_from_variable:
                            dimacs_variable = self.clauses.dimacs_literal_from_variable[CNF_variable]

                            dimacs_literal = negate(dimacs_variable, negated, dimacs=True)

                            if dimacs_literal in solution:
                                background_grid[t][y][x] = "1"
                            else:
                                background_grid[t][y][x] = "0"
                        else:
                            background_grid[t][y][x] = "0"

        for transition, literal in rule.items():
            if literal in ["0", "1"]:
                pass
            else:
                (CNF_variable, negated) = variable_from_literal(literal)
                if CNF_variable in self.clauses.dimacs_literal_from_variable:
                    dimacs_variable = self.clauses.dimacs_literal_from_variable[CNF_variable]

                    dimacs_literal = negate(dimacs_variable, negated, dimacs=True)

                    if dimacs_literal in solution:
                        rule[transition] = "1"
                    else:
                        rule[transition] = "0"
                else:
                    rule[transition] = "0"
        print_message('Done\n', 3, indent=indent)

        return SearchPattern(grid, background_grid=background_grid, rule=rule, add_border=False)
    def force_equal(self, argument_0, argument_1=None):

        if argument_1 is not None:
            assert isinstance(argument_0, str) and isinstance(argument_1, str), "force_equal arguments not understood"
            cell_pair_list = [(argument_0, argument_1)]
        elif argument_0 == []:
            return
        elif isinstance(argument_0[0], str):
            assert len(argument_0) == 2 and isinstance(argument_0[1], str), "force_equal arguments not understood"
            cell_pair_list = [argument_0]
        else:
            cell_pair_list = argument_0

        replacement = {}
        replaces = {}

        for cell_0, cell_1 in cell_pair_list:
            while cell_0 not in ["0", "1"]:
                variable_0, negated_0 = variable_from_literal(cell_0)
                if variable_0 in replacement:
                    cell_0 = negate(replacement[variable_0], negated_0)
                else:
                    break
            while cell_1 not in ["0", "1"]:
                variable_1, negated_1 = variable_from_literal(cell_1)
                if variable_1 in replacement:
                    cell_1 = negate(replacement[variable_1], negated_1)
                else:
                    break
            if cell_0 != cell_1:
                if cell_0 == negate(cell_1):
                    raise UnsatInPreprocessing
                elif cell_0 in ["0", "1"]:
                    cell_0, cell_1 = cell_1, cell_0

                variable_0, negated_0 = variable_from_literal(cell_0)
                cell_0, cell_1 = variable_0, negate(cell_1, negated_0)

                if cell_1 not in ["0", "1"]:
                    variable_1, negated_1 = variable_from_literal(cell_1)
                    if variable_1 not in replaces:
                        replaces[variable_1] = []

                if variable_0 in replaces:
                    for variable in replaces[variable_0]:
                        replacement_variable, replacement_negated = variable_from_literal(replacement[variable])
                        replacement[variable] = negate(cell_1, replacement_negated)
                        if cell_1 not in ["0", "1"]:
                            replaces[variable_1].append(variable)
                    del replaces[variable_0]

                replacement[variable_0] = cell_1
                if cell_1 not in ["0", "1"]:
                    replaces[variable_1].append(variable_0)

        for t, generation in enumerate(self.grid):
            for y, row in enumerate(generation):
                for x, cell in enumerate(row):
                    if cell not in ["0", "1"]:
                        variable, negated = variable_from_literal(cell)
                        if variable in replacement:
                            if replacement[variable] != variable:
                                self.grid[t][y][x] = negate(replacement[variable], negated)

        for t, generation in enumerate(self.background_grid):
            for y, row in enumerate(generation):
                for x, cell in enumerate(row):
                    if cell not in ["0", "1"]:
                        variable, negated = variable_from_literal(cell)
                        if variable in replacement:
                            if replacement[variable] != variable:
                                self.background_grid[t][y][x] = negate(replacement[variable], negated)

        for transition, literal in self.rule.items():
            if literal not in ["0", "1"]:
                variable, negated = variable_from_literal(literal)
                if variable in replacement:
                    if replacement[variable] != variable:
                        self.rule[transition] = negate(replacement[variable], negated)
 def number_of_cells(self):
     return len(set(variable_from_literal(cell) for generation in self.grid for row in generation for cell in row if
                    cell not in ["0", "1"]))