def is_empty_regex(self, regex): if not isinstance(regex, RegexTree): regex = RegexTree(Node(regex)) fsm = regex.to_fsm() fsm.close() cfg = self.intersect(fsm) return cfg.is_empty()
def test_intersect(self): regex = RegexTree(Node("1")) fsm = regex.to_fsm() fsm.close() states = [PDAState("q0"), PDAState("q1"), PDAState("q2")] input_symbols = ["0", "1"] stack_alphabet = ["0", "1", "end"] transition_function = [] transition_function.append( PDATransitionFunction(states[0], "0", "end", states[0], ["0", "end"])) transition_function.append( PDATransitionFunction(states[0], "1", "end", states[0], ["1", "end"])) transition_function.append( PDATransitionFunction(states[0], "0", "0", states[0], ["0", "0"])) transition_function.append( PDATransitionFunction(states[0], "0", "1", states[0], ["0", "1"])) transition_function.append( PDATransitionFunction(states[0], "1", "1", states[0], ["1", "1"])) transition_function.append( PDATransitionFunction(states[0], "1", "0", states[0], ["1", "0"])) transition_function.append( PDATransitionFunction(states[0], "epsilon", "end", states[1], ["end"])) transition_function.append( PDATransitionFunction(states[0], "epsilon", "0", states[1], ["0"])) transition_function.append( PDATransitionFunction(states[0], "epsilon", "1", states[1], ["1"])) transition_function.append( PDATransitionFunction(states[1], "0", "0", states[1], [])) transition_function.append( PDATransitionFunction(states[1], "1", "1", states[1], [])) transition_function.append( PDATransitionFunction(states[1], "epsilon", "end", states[2], [])) start_state = states[0] start_symbol = "end" final_states = [states[2]] pda = PDA(states, input_symbols, stack_alphabet, transition_function, start_state, start_symbol, final_states) pda = pda.from_empty_stack_to_final_state() pda = pda.intersect(fsm) self.assertIsInstance(pda, PDA) self.assertFalse( pda.accepts_by_final_state(["0", "0", "1", "1", "0", "0"], 1000)) self.assertFalse(pda.accepts_by_final_state(["0", "1", "1", "0"], 1000)) self.assertTrue(pda.accepts_by_final_state(["1", "1"], 10000)) self.assertFalse(pda.accepts_by_final_state([], 1000)) self.assertFalse(pda.accepts_by_final_state(["0", "1", "0", "0"], 1000)) self.assertFalse(pda.accepts_by_final_state(["0", "0", "1", "0"], 1000))
def __init__(self, functions, query, optim=7, empty=False, eq_rules=[], palindrome=False, susie=False): """__init__ Initializes the indexed grammar from a set of functions :param functions: a list of Functions :param query: the query (one terminal for now) :param all_relations: all terminals used (with - also) """ # functions += self.__get_sub_functions(functions) functions = list(set(functions)) # Initial rules if palindrome: initial_rules = self.__get_initial_palindrom_rules(query) else: initial_rules = self.__get_initial_rules(query) # Rules from functions f_rules = [] if len(eq_rules) != 0: new_function = "|".join([ "(" + ",".join(function.to_list()) + ")" for function in functions ]) regex_function = RegexTree(Node(new_function)) fsm = regex_function.to_fsm() fsm.close() was_modified = True while was_modified: was_modified = False for eq_rule in eq_rules: was_modified |= fsm.apply_rule(eq_rule.l0, eq_rule.l1) fsm.open() functions = [fsm.to_regex()] counter = 0 self.functions = functions for f in functions: if palindrome: temp_rule = f.generate_palindrome_rules(counter, susie) else: temp_rule = f.generate_reduced_rules(counter, empty) counter = temp_rule[1] f_rules += temp_rule[0] rules = Rules(f_rules + initial_rules, optim=optim) self.query = query super(FunctionIndexedGrammar, self).__init__(rules)
def to_regex(self) -> Any: """to_regex Transforms the FSM to regex :return: A regex equivalent to the FSM :rtype: RegexTree """ from regex_tree import RegexTree temp_states = self.states[:] # We remove the states in the fsm one after the other. for state in temp_states: # Remove multiple transitions between two nodes self.create_or() # We do not remove the initial or the final states if state != self.initial and state not in self.finals: self.remove_state(state) self.create_or() cont = True # While there are modifications of the fsm, we continue # Converges ? Need a loop ? while cont: cont = False # For all final nodes, we want to keep only out transitions to # itself for final in self.finals: if final != self.initial: cont |= self.remove_state(final) self.create_or() res = "" # Nothing to do here if self.initial not in self.transitions: return RegexTree(Node("")) # The transitions from the initial node to itself is a kleene star if self.initial in self.transitions[self.initial]: res += "(" + \ "".join(self.transitions[self.initial][self.initial]) + ")*" # Get all the equivalent paths to the final states temp_finals = self.get_final_strings() # ... and creates an or of all of them if len(temp_finals) > 1: return RegexTree(Node(res + "(" + ")|(".join(temp_finals) + ")")) return RegexTree(Node(res + ")|(".join(temp_finals)))
def test_paper(self): cfg = CFG([Variable("S"), Variable("C")], [ Terminal("a"), Terminal("b"), Terminal("c"), Terminal("q"), Terminal("am"), Terminal("bm"), Terminal("cm"), Terminal("qm") ], [ CFGRule( Variable("S"), [Variable("C"), Terminal("q"), Variable("C")]), CFGRule( Variable("C"), [Terminal("a"), Variable("C"), Terminal("am")]), CFGRule( Variable("C"), [Terminal("b"), Variable("C"), Terminal("bm")]), CFGRule( Variable("C"), [Terminal("c"), Variable("C"), Terminal("cm")]), CFGRule( Variable("C"), [Terminal("q"), Variable("C"), Terminal("qm")]), CFGRule(Variable("C"), [Variable("C"), Variable("C")]), CFGRule(Variable("C"), []) ], Variable("S")) regex = RegexTree(Node("(a,b)|(bm,c)|(cm,am,q)")) fsm = regex.to_fsm() fsm.close() cfg_temp = cfg.intersect(fsm) self.assertFalse(cfg_temp.is_empty()) regex = RegexTree(Node("(a,b)|(b,c)|(cm,am,q)")) fsm = regex.to_fsm() fsm.close() cfg_temp = cfg.intersect(fsm) self.assertTrue(cfg_temp.is_empty())
# n_relations = j generator = FunctionGenerator(n_relations) for i in range(0, 200): # 1 function, size_max is 10 functions = [] temp = generator.generate(n_functions, size_max) functions += temp query = generator.get_random_query(functions) # ==== FSM ==== current_time = time.time() new_function = "|".join(["(" + ",".join(function.to_list("m")) + ")" for function in functions]) regex_function = RegexTree(Node(new_function)) fsm = regex_function.to_fsm() fsm.close() # === NOT WEAK === pfsm = fsm.get_palindrome_fsm(query, weak=False) fsm_not_weak_res = pfsm.is_empty() fsm_not_weak_time = time.time() - current_time # === WEAK === pfsm = fsm.get_palindrome_fsm(query, weak=True) fsm_weak_res = pfsm.is_empty() fsm_weak_time = time.time() - current_time
def test_intersect(self): cfg = CFG([Variable("S"), Variable("A")], [Terminal("a"), Terminal("b")], [ CFGRule(Variable("S"), [Variable("A"), Variable("A")]), CFGRule(Variable("S"), [Terminal("a")]), CFGRule(Variable("A"), [Terminal("b")]) ], Variable("S")) regex = RegexTree(Node("a")) fsm = regex.to_fsm() fsm.close() cfg_temp = cfg.intersect(fsm) self.assertFalse(cfg_temp.is_empty()) regex = RegexTree(Node("b")) fsm = regex.to_fsm() fsm.close() cfg_temp = cfg.intersect(fsm) self.assertFalse(cfg_temp.is_empty()) regex = RegexTree(Node("b,b")) fsm = regex.to_fsm() fsm.close() cfg_temp = cfg.intersect(fsm) self.assertFalse(cfg_temp.is_empty()) regex = RegexTree(Node("b,a")) fsm = regex.to_fsm() fsm.close() cfg_temp = cfg.intersect(fsm) self.assertTrue(cfg_temp.is_empty())