def recursively_create_ids(i: int, symbols_to_check: list, symbols: list): global num, results, test for symbol in symbols_to_check: if Symbol.check(symbols[-1] if len(symbols) > 0 else None, symbol): symbols.append(symbol) if i + 1 == wanted_length: id = Id(symbols) if id.check() is None: # print(str(id)) adj_matrix = AdjacencyMatrix.parse(id) if adj_matrix.is_connected(): score = DegreeAndDiameterCalculator.calculate( adj_matrix) score = score[0] + score[1] else: score = ((number_of_nodes - 1) * 2) + ( number_of_nodes - adj_matrix. get_number_of_elements_from_biggest_component()) for substring_len in range(1, len(id) + 1): for j in range(len(id) - substring_len + 1): chars = str(Id(symbols[j:j + substring_len])) if chars in results: results[chars][0] += 1 results[chars][1] += score else: results[chars] = [1, score] # print(" " + str(Id(chars))) num += 1 else: recursively_create_ids( i + 1, Symbol.symbols() if i + 2 < wanted_length else Symbol.ending_symbols(), symbols) symbols.pop()
def random(length=wanted_length): new_id = [ Symbol.random_starting_symbol( [OpenParenthesis()] if length < 6 else []) ] last_close_parenthesis_pos = 0 parenthesis_counter = 1 if str(new_id[-1]) == "(" else 0 while len(new_id) < length or new_id[-1] not in Symbol.ending_symbols( ) or parenthesis_counter > 0: num_of_symbols_left_to_add = length - len(new_id) symbols = [] exceptions = [] if parenthesis_counter > 0 and parenthesis_counter >= num_of_symbols_left_to_add: symbols = [CloseParenthesis()] exceptions = [OpenParenthesis()] else: if parenthesis_counter == 0 or len( new_id) - last_close_parenthesis_pos < 3: exceptions.append(CloseParenthesis()) if num_of_symbols_left_to_add <= 4 + parenthesis_counter: exceptions.append(OpenParenthesis()) if len(new_id) + 1 >= length: symbols = Symbol.ending_symbols() new_symbol = Symbol.random(new_id[-1], exceptions, symbols, True) if str(new_symbol) == "(": parenthesis_counter += 1 last_close_parenthesis_pos = len(new_id) elif str(new_symbol) == ")": parenthesis_counter -= 1 new_id.append(new_symbol) return Id(new_id, length)
def comparison(self, node): comp_operation = node.children[0] op1_node = comp_operation.children[1] op1_symbol = self.get_value(op1_node) self.check(op1_symbol, ["NUMBAR", "NUMBR"]) op2_node = comp_operation.children[2] op2_symbol = self.get_value(op2_node) self.check(op2_symbol, ["NUMBAR", "NUMBR"]) op1_symbol.value = float( op1_symbol.value) if op1_symbol.type == "NUMBAR" else int( op1_symbol.value) op2_symbol.value = float( op2_symbol.value) if op2_symbol.type == "NUMBAR" else int( op2_symbol.value) if (comp_operation.type == "EQUAL"): if (type(op1_symbol.value) != type(op2_symbol.value)): ans = False else: ans = op1_symbol.value == op2_symbol.value elif (comp_operation.type == "NOTEQUAL"): if (type(op1_symbol.value) != type(op2_symbol.value)): ans = True else: ans = op1_symbol.value != op2_symbol.value ans = "WIN" if ans else "FAIL" return Symbol("TROOF", ans)
def parse(id_str): prev_symbol = None symbols = [] for char in id_str: symbols.append(Symbol.parse(char, prev_symbol)) prev_symbol = symbols[-1] return Id(symbols)
def __insert_open_or_remove_close_parenthesis_until_pos( id, initial_pos, insert_or_remove: bool): positions = [] pos = initial_pos while pos >= 0: prev_symbol = id[pos - 1] if pos > 0 else None next_symbol = id[pos + 1] if pos + 1 < len(id) else None if insert_or_remove and str(id[pos]) == ")": pos -= 3 elif (insert_or_remove and (not prev_symbol or (isinstance(prev_symbol, Function) or str(prev_symbol) == "(")) and (isinstance(id[pos], Number) or isinstance(id[pos], SingleArgFunction) or str(id[pos]) == "(")) or (not insert_or_remove and (str(id[pos]) == ")" and (not next_symbol or Symbol.check(prev_symbol, next_symbol)))): positions.append(pos) pos -= 1 if len(positions) > 0: pos = random.choice(positions) return Id( id[:pos] + ([OpenParenthesis()] + id[pos:] if insert_or_remove else id[pos + 1:]), id.__initial_length) raise Exception
def arithmetic(self, node): operation = node.children[0] op1_node = operation.children[1] op1_symbol = self.get_value(op1_node) self.check(op1_symbol, ["NUMBAR", "NUMBR"]) op2_node = operation.children[2] op2_symbol = self.get_value(op2_node) self.check(op2_symbol, ["NUMBAR", "NUMBR"]) op1_symbol.value = float( op1_symbol.value) if op1_symbol.type == "NUMBAR" else int( op1_symbol.value) op2_symbol.value = float( op2_symbol.value) if op2_symbol.type == "NUMBAR" else int( op2_symbol.value) if (operation.type == "ADDITION"): ans = op1_symbol.value + op2_symbol.value elif (operation.type == "SUBTRACTION"): ans = op1_symbol.value - op2_symbol.value elif (operation.type == "MULTIPLICATION"): ans = op1_symbol.value * op2_symbol.value elif (operation.type == "DIVISION"): ans = op1_symbol.value / op2_symbol.value elif (operation.type == "MODULO"): ans = op1_symbol.value % op2_symbol.value elif (operation.type == "GREATER"): ans = max(op1_symbol.value, op2_symbol.value) elif (operation.type == "LESSER"): ans = min(op1_symbol.value, op2_symbol.value) val_type = "NUMBAR" if (type(ans) == float) else "NUMBR" return Symbol(val_type, str(ans))
def declaration(self, statement): identifier = statement.children[1].value self.insert(identifier, Symbol("NOOB", None)) if (len(statement.children) > 2): init_node = statement.children[2] value_node = init_node.children[1] symbol = self.get_value(value_node) self.insert(identifier, symbol)
def concatenation(self, node): smoosh_op = node.children[1] string = "" for value_node in smoosh_op.children: symbol = self.get_value(value_node) string += str(symbol.value) return Symbol("YARN", string)
def check(self): if self[0] not in Symbol.starting_symbols(): return "Id starts with an invalid character." elif self[-1] not in Symbol.ending_symbols(): return "Id ends with an invalid character." parenthesis_counter = 0 for i in range(len(self)): if i > 0 and not Symbol.check(self[i - 1], self[i]): return (' ' * i) + '^ char \'' + str( self[i - 1]) + '\' must not be followed by char \'' + str( self[i]) + '\'' if str(self[i]) == '(': parenthesis_counter += 1 elif str(self[i]) == ')': if parenthesis_counter <= 0: return "Found close parenthesis when there's no open parenthesis to close." parenthesis_counter -= 1 if parenthesis_counter != 0: return "Incorrect number of parenthesis." return None
def get_value(self, node): child = node.children[0] if (child.type == "VARIABLE"): variable = child.children[0] identifier = variable.value self.lookup(identifier) return self.symbol_table[identifier] elif (child.type == "EXPR"): return self.expr(child) else: value = child.children[0].value val_type = child.children[0].type return Symbol(val_type, value)
def boolean(self, node): booltype = node.children[0] bool_operation = booltype.children[0] if (bool_operation.type == "NOT"): op1_node = bool_operation.children[1] op1_symbol = self.get_value(op1_node) self.check(op1_symbol, ["TROOF"]) op1_bool = True if op1_symbol.value == "WIN" else False ans = not op1_bool elif (bool_operation.type in ["ALL", "ANY"]): boolop = bool_operation.children[1] current_op_symbol = self.get_value(boolop.children[0]) self.check(current_op_symbol, ["TROOF"]) op1_bool = True if current_op_symbol.value == "WIN" else False for value in boolop.children[1:]: op_symbol = self.get_value(value) self.check(op_symbol, ["TROOF"]) op2_bool = True if op_symbol.value == "WIN" else False if (bool_operation.type == "ALL"): op1_bool = op1_bool and op2_bool else: op1_bool = op1_bool or op2_bool ans = op1_bool else: op1_node = bool_operation.children[1] op1_symbol = self.get_value(op1_node) self.check(op1_symbol, ["TROOF"]) op2_node = bool_operation.children[2] op2_symbol = self.get_value(op2_node) self.check(op2_symbol, ["TROOF"]) op1_bool = True if op1_symbol.value == "WIN" else False op2_bool = True if op2_symbol.value == "WIN" else False if (bool_operation.type == "AND"): ans = op1_bool and op2_bool elif (bool_operation.type == "OR"): ans = op1_bool or op2_bool elif (bool_operation.type == "XOR"): ans = op1_bool != op2_bool ans = "WIN" if ans else "FAIL" val_type = "TROOF" return Symbol(val_type, ans)
def __remove_open_parenthesis(id): positions_to_remove_open_parenthesis = [] len_id = len(id) parenthesis_counter = 0 pos = len(id) - 1 while pos >= 0: if str(id[pos]) == "(": parenthesis_counter += 1 elif str(id[pos]) == ")": parenthesis_counter -= 1 if parenthesis_counter > 0: break pos -= 1 conflicting_open_parenthesis_positions = [] while pos < len_id: prev_symbol = id[pos - 1] if pos > 0 else None next_symbol = id[pos + 1] if pos + 1 < len(id) else None if str(id[pos]) == "(": parenthesis_counter += 1 if not prev_symbol or Symbol.check(prev_symbol, next_symbol): positions_to_remove_open_parenthesis.append(pos) else: conflicting_open_parenthesis_positions.append(pos) elif str(id[pos]) == ")": parenthesis_counter -= 1 if parenthesis_counter == 0: break pos += 1 if len(positions_to_remove_open_parenthesis) > 0: pos_to_remove = random.choice(positions_to_remove_open_parenthesis) return Id(id[:pos_to_remove] + id[pos_to_remove + 1:], id.__initial_length) elif len(conflicting_open_parenthesis_positions) > 0: new_id = id.copy() for pos in conflicting_open_parenthesis_positions: new_id = new_id.__mutate(pos, False) return new_id raise Exception
def gimmeh(self, statement): variable = statement.children[1] identifier = variable.children[0] sample = simpledialog.askstring(title="INPUT", prompt="Enter input: ") self.insert(identifier.value, Symbol("YARN", sample))
def random(prev_symbol=None, exceptions=None, symbols=None): from classes.Symbol import Symbol return Symbol.random(prev_symbol, exceptions, InterpretableSymbol.symbols())
def __manage_symbol_at_pos(self, pos: int, additional_data: bool = False): smaller = len(self) < self.__initial_length equal = len(self) == self.__initial_length bigger = len(self) > self.__initial_length length = len(self) prev_symbol = self[pos - 1] if pos > 0 else None next_symbol = self[pos + 1] if pos + 1 < length else None prev_prev = self[pos - 2] if pos > 1 else None next_next = self[pos + 2] if pos + 2 < length else None symbols = Symbol.symbols().copy() symbols.remove(self[pos]) if OpenParenthesis( ) in symbols and self.__is_not_worth_mutate_to_open_parenthesis(pos): symbols.remove(OpenParenthesis()) if CloseParenthesis( ) in symbols and self.__is_not_worth_mutate_to_close_parenthesis(pos): symbols.remove(CloseParenthesis()) if bigger and Symbol.check(prev_symbol, next_symbol): new_id = Id(self[:pos] + self[pos + 1:], self.__initial_length) if additional_data: return new_id, pos, str(self[pos]), 'None' return new_id else: symbols_to_mutate_to = [] for symbol in symbols: if bigger: if Symbol.check(prev_prev, symbol) and Symbol.check( symbol, next_symbol): symbols_to_mutate_to.append( [symbol, next_symbol] if next_symbol else [symbol]) elif Symbol.check(prev_symbol, symbol) and Symbol.check( symbol, next_next): symbols_to_mutate_to.append( [prev_symbol, symbol] if prev_symbol else [symbol]) elif Symbol.check(prev_symbol, symbol) and Symbol.check( symbol, next_symbol if equal else self[pos]): symbols_to_mutate_to.append([symbol]) if len(symbols_to_mutate_to) > 0: symbols_to_mutate_to = random.choice(symbols_to_mutate_to) ending = self[pos + (2 if bigger else (1 if equal else 0)):] beginning = self[:pos - (1 if bigger and pos > 0 else 0)] new_id = Id(beginning + symbols_to_mutate_to + ending, self.__initial_length) if additional_data: return new_id, pos, str(self[pos]), str( [str(s) for s in symbols_to_mutate_to]) return new_id else: final_symbols = [] last_s = next_symbol if equal else ( self[pos] if smaller else next_next) first_s = prev_symbol if equal else self[pos] for s1 in symbols: for s2 in symbols: if Symbol.check(s1, s2): if Symbol.check( prev_symbol if smaller else prev_prev, s1) and Symbol.check(s2, last_s): final_symbols.append( [s1, s2, last_s] if next_symbol and not bigger else [s1, s2]) if Symbol.check(first_s, s1) and Symbol.check( s2, next_next if equal else next_symbol): final_symbols.append( [first_s, s1, s2] if prev_symbol and not bigger else [s1, s2]) if len(final_symbols) == 0: raise Exception final_symbol_list = random.choice(final_symbols) beginning = self[:pos - (0 if smaller else 1)] ending = self[pos + (1 if smaller else 2):] new_id = Id(beginning + final_symbol_list + ending, self.__initial_length) if additional_data: return new_id, pos, str(self[pos]), str( [str(s) for s in final_symbol_list]) return new_id
def random(prev_symbol=None, exceptions=None, symbols=None): from classes.Symbol import Symbol return Symbol.random(prev_symbol, exceptions, SingleArgFunction.symbols())
def __init__(self, tree, output_text): self.tree = tree self.symbol_table = {"IT": Symbol("NOOB", None)} self.output_text = output_text
def random(prev_symbol=None, exceptions=None, symbols=None): from classes.Symbol import Symbol return Symbol.random(prev_symbol, exceptions, Operator.symbols())
recursively_create_ids( i + 1, Symbol.symbols() if i + 2 < wanted_length else Symbol.ending_symbols(), symbols) symbols.pop() if __name__ == '__main__': # from classes.numbers.variables.AxisY import AxisY # from classes.numbers.variables.AxisX import AxisX # from classes.interpretable_symbols.functions.operators.Subtraction import Subtraction # from classes.numbers.constants.Two import Two # score = DegreeAndDiameterCalculator.calculate(AdjacencyMatrix.parse(Id([AxisY(), Subtraction(), Two(), Subtraction(), AxisX()]))) recursively_create_ids(0, Symbol.starting_symbols(), []) print("") print("Number of created ids: " + str(num)) ordered_results = [] ordered_results_by_length = [[] for a in range(wanted_length)] for key in results: score = results[key][1] / results[key][0] result_pair = [key, score] not_inserted = True for i in range(len(ordered_results)): result = ordered_results[i] if score < result[1]: ordered_results.insert(i, result_pair) not_inserted = False break if not_inserted: