def split(self, grammar: Grammar) -> None: replaced: Symbol = self.__find_nonterminal(grammar) replacement: Tuple[Symbol, Symbol] = self.__find_unused_symbols_pair(grammar) print("[split] replaced = {} replacement = {}".format( replaced, replacement)) if replacement is not None: rules: Set[Rule] = grammar.get_rules() rules_copy = set(rules) for rule in rules_copy: if rule.left == replaced: first_rule = self.__create_rule(replacement[0], rule.right1, rule.right2) second_rule = self.__create_rule(replacement[1], rule.right1, rule.right2) grammar.remove_rule(rule) grammar.add_rule(first_rule) grammar.add_rule(second_rule) self.iteration.remove_crowding_rule(rule) self.iteration.add_rule(first_rule) self.iteration.add_rule(second_rule) rules: Set[Rule] = grammar.get_rules() rules_copy = set(rules) for rule in rules_copy: if rule.right1 == replaced: grammar.remove_rule(rule) first_rule = self.__create_rule(rule.left, replacement[0], rule.right2) second_rule = self.__create_rule(rule.left, replacement[1], rule.right2) grammar.add_rule(first_rule) grammar.add_rule(second_rule) self.iteration.remove_crowding_rule(rule) self.iteration.add_rule(first_rule) self.iteration.add_rule(second_rule) rules: Set[Rule] = grammar.get_rules() rules_copy = set(rules) for rule in rules_copy: if rule.right2 == replaced: first_rule = self.__create_rule(rule.left, rule.right1, replacement[0]) second_rule = self.__create_rule(rule.left, rule.right1, replacement[1]) grammar.remove_rule(rule) grammar.add_rule(first_rule) grammar.add_rule(second_rule) self.iteration.remove_crowding_rule(rule) self.iteration.add_rule(first_rule) self.iteration.add_rule(second_rule)
def __restore_previous_state(self, grammar: Grammar) -> None: to_remove = set(grammar.get_rules()) for rule in to_remove: grammar.remove_rule(rule) self.iteration.remove_crowding_rule(rule) for rule in self.__last_rules: grammar.add_rule(rule) self.iteration.add_rule(rule)
def test_rule_is_effective(self): grammar = Grammar() grammar.get_rules = MagicMock(return_value=self.rules) rule = Rule([self.symbol_C, self.symbol_B, self.symbol_x]) result = self.covering.rule_is_effective(grammar, rule.left) self.assertTrue(result) rule = Rule([self.symbol_E, self.symbol_B, self.symbol_x]) result = self.covering.rule_is_effective(grammar, rule.left) self.assertFalse(result)
def __get_non_terminals_in_use(self, grammar: Grammar) -> Set[Symbol]: rules = grammar.get_rules() symbols_in_use = set() for rule in rules: symbols_in_use.add(rule.left) symbols_in_use.add(rule.right1) if rule.right2 is not None: symbols_in_use.add(rule.right2) return set( filter(lambda symbol: symbol.is_non_terminal(), symbols_in_use))
def __replace_all_symbols_in_rules(self, replacement: Symbol, replaced: Symbol, grammar: Grammar) -> None: rules: Set[Rule] = grammar.get_rules() rules_copy = set(rules) for rule in rules_copy: if self.__rule_contains_replaced_symbol(rule, replaced): new_rule = self.__replace_symbols_in_rule( replacement, replaced, rule) grammar.remove_rule(rule) grammar.add_rule(new_rule)
def test_count_symbols_statistics(self): grammar = Grammar() grammar.get_rules = MagicMock(return_value=self.rules) result = self.covering.count_symbols_statistics(grammar) expected = { self.symbol_B: 2, self.symbol_C: 3, self.symbol_D: 1, self.symbol_E: 1 } self.assertEqual(result, expected)
def __grammar_is_worse_than_previously(self, grammar: Grammar) -> bool: print("[heuristic] grammar fitness = {}".format( self.__count_grammar_fitness(grammar))) print("[heuristic] last grammar fitness = {}".format( self.__last_grammar_fitness)) if len(grammar.get_rules()) > 5 * int( self.settings.get_value('general', 'non_terminal_productions_number')): return True return self.__count_grammar_fitness( grammar) < self.__last_grammar_fitness
class TestSplitAndMerge(TestCase): def setUp(self): settings = MagicMock() settings.get_value = MagicMock( side_effect=["TERMINALS", 0.5, 1.0, 1.0, 1.0, 1.0]) self.grammar = Grammar(settings) self.symbol_a = Symbol('a', SymbolType.ST_TERMINAL) self.symbol_S = Symbol('S', SymbolType.ST_NON_TERMINAL) self.symbol_A = Symbol('A', SymbolType.ST_NON_TERMINAL) self.symbol_B = Symbol('B', SymbolType.ST_NON_TERMINAL) self.symbol_C = Symbol('A', SymbolType.ST_NON_TERMINAL) self.symbol_A1 = Symbol('A1', SymbolType.ST_NON_TERMINAL) self.symbol_A2 = Symbol('A2', SymbolType.ST_NON_TERMINAL) self.rule_1 = sRule.from_symbols(0.1, self.symbol_S, self.symbol_A, self.symbol_B) self.rule_2 = sRule.from_symbols(0.5, self.symbol_A, self.symbol_A, self.symbol_B) self.rule_3 = sRule.from_symbols(0.4, self.symbol_A, self.symbol_a) self.rule_4 = sRule.from_symbols(0.9, self.symbol_B, self.symbol_B, self.symbol_B) self.rule_5 = sRule.from_symbols(0.2, self.symbol_B, self.symbol_a) self.rules = { self.rule_1, self.rule_2, self.rule_3, self.rule_4, self.rule_5 } self.non_terminal_rules = {self.rule_1, self.rule_2, self.rule_4} self.terminal_rules = {self.rule_3, self.rule_5} self.grammar.rulesContainer.terminal_rules = self.terminal_rules self.grammar.rulesContainer.non_terminal_rules = self.non_terminal_rules self.grammar.rulesContainer.rules = self.rules self.grammar.get_rules = MagicMock(return_value=self.rules) self.grammar.get_non_terminal_rules = MagicMock( return_value=self.non_terminal_rules) settings.get_value = MagicMock( side_effect=['RANDOM', 'False', 0.5, 20]) self.split_and_merge = SplitAndMerge(settings) self.split_and_merge.iteration.add_rule = MagicMock() self.split_and_merge.iteration.remove_crowding_rule = MagicMock() self.merge_result = { sRule.from_symbols(0.1, self.symbol_S, self.symbol_A, self.symbol_A), sRule.from_symbols(0.1, self.symbol_A, self.symbol_A, self.symbol_A), sRule.from_symbols(0.1, self.symbol_A, self.symbol_a) } self.split_result = { sRule.from_symbols(0.1, self.symbol_S, self.symbol_A1, self.symbol_B), sRule.from_symbols(0.1, self.symbol_S, self.symbol_A2, self.symbol_B), sRule.from_symbols(0.1, self.symbol_A1, self.symbol_A1, self.symbol_B), sRule.from_symbols(0.1, self.symbol_A1, self.symbol_A2, self.symbol_B), sRule.from_symbols(0.1, self.symbol_A2, self.symbol_A2, self.symbol_B), sRule.from_symbols(0.1, self.symbol_A2, self.symbol_A1, self.symbol_B), sRule.from_symbols(0.1, self.symbol_A1, self.symbol_a), sRule.from_symbols(0.1, self.symbol_A2, self.symbol_a), sRule.from_symbols(0.1, self.symbol_B, self.symbol_a), sRule.from_symbols(0.1, self.symbol_B, self.symbol_B, self.symbol_B), } def test_merge(self): self.split_and_merge._SplitAndMerge__get_random_nonterminals_pair = MagicMock( return_value=(self.symbol_A, self.symbol_B)) self.split_and_merge.merge(self.grammar) self.assertEqual(self.grammar.get_rules(), self.merge_result) def test_split(self): self.split_and_merge._SplitAndMerge__get_random_nonterminal = MagicMock( return_value=self.symbol_A) self.split_and_merge._SplitAndMerge__find_unused_symbols_pair = MagicMock( return_value=(self.symbol_A1, self.symbol_A2)) self.split_and_merge.split(self.grammar) self.assertEqual(self.grammar.get_rules(), self.split_result)
def save_grammar_state(self, grammar: Grammar) -> None: self.__last_rules = pickle.loads(pickle.dumps(grammar.get_rules(), -1)) self.__last_grammar_fitness = self.__count_grammar_fitness(grammar)