def main(): regular = parse_regular_expression("(a)") print(regular) print(NFA(regular)) print(NoEpsilonNFA(regular)) print(DFA(regular)) print(MinDFA(regular))
def kleene(nfa1): initial_state, final_state = new_states(nfa1) nfa = NFA(CHARSET, {initial_state, final_state}, initial_state, {final_state}, {}) for state in nfa1.states: nfa.states.add(state) new_delta = {} for (state, symbol), next_states in nfa1.delta.items(): new_delta.update({(state, symbol): next_states}) for stop_state in nfa1.final_states: if (stop_state, "") in nfa1.delta: new_next_states = nfa1.delta[(stop_state, "")] new_next_states.add(final_state) new_delta.update({(stop_state, ""): new_next_states}) else: new_delta.update({(stop_state, ""): {final_state}}) new_delta.update({(initial_state, ""): {nfa1.start_state, final_state}}) new_delta.update({(final_state, ""): {initial_state}}) nfa.delta = new_delta return nfa
def mergeNFAConcat(nfa1 : NFA, nfa2 : NFA): # calculam numarul de stari la final numarStariTotal = nfa1.numberOfStates + nfa2.numberOfStates # instantiem un nfa nou newNfa = NFA(numarStariTotal) # setam starea finala ca fiind numar total de stari - 1 (ultima stare din nfa2) newNfa.finalStates.append(numarStariTotal - 1) # setam tranzitiile # adaugam fiecare tranzitie din nfa1 asa cum e newNfa.tabelTranzitii = nfa1.tabelTranzitii.copy() # adaugam fiecare tranzitie din nfa2 cu starile shiftate # facem un map + numarStariNfa1 peste stari for (state, simbol), nextState in nfa2.tabelTranzitii.items(): newNfa.tabelTranzitii[(state + (nfa1.numberOfStates), simbol)] = [i + nfa1.numberOfStates for i in nextState] # adaugam "podul (bridge)" intre cele 2 nfa-uri (o tranzitie pe eps) # tranzitia este intre starea cu numarul nfa1.numarStari - 1 si nf1.numarStari try: newNfa.tabelTranzitii[(nfa1.numberOfStates - 1, "eps")] = newNfa.tabelTranzitii[(nfa1.numberOfStates - 1, "eps")] + [nfa1.numberOfStates] except: newNfa.tabelTranzitii[(nfa1.numberOfStates - 1, "eps")] = [nfa1.numberOfStates] # print("concat") # print(newNfa) # print() return newNfa
def toDFA(self): """ 1. convert all rules S -> aT to S (->a) T 2. convert all rules U -> a to U (->a) ((qf)) """ from nfa import NFA, NDTransitionFunction def getAlphabet(): return {path[0] for key in self for path in self[key]} Q = list(self) δ = NDTransitionFunction(getAlphabet()) for source in self: for path in self[source]: letter, *target = tuple(path) if target: δ[source, letter] = target[0] else: δ[source, letter] = "qf" if "qf" not in Q: Q.append("qf") return NFA(Q, getAlphabet(), δ, "S", {"qf"})
def regex_to_nfa(inp): # Takes an regex as input (inp) and returns an epsilon-NFA corresponding to the same regex # Used logic and parsers from AutomataTheory.py nfaObj = NFAfromRegex(inp) nfa = nfaObj.getNFA() transitions = {} for fromstate, tostates in nfa.transitions.items(): for state in tostates: for char in tostates[state]: ch = char if (char == ":e:"): ch = 'eps' if ch in transitions: if (fromstate - 1) in transitions[ch]: transitions[ch][fromstate - 1] = (transitions[ch][fromstate - 1] + [state - 1]) else: transitions[ch][fromstate - 1] = [state - 1] else: transitions[ch] = {(fromstate - 1): [state - 1]} sigma = [x for x in nfa.language] startstate = nfa.startstate - 1 finalstates = [x - 1 for x in nfa.finalstates] return NFA(len(nfa.states), sigma, transitions, finalstates, startstate)
def concat(nfa1: NFA, nfa2: NFA) -> NFA: return NFA(states=nfa1.states + nfa2.states, starting_state=nfa1.starting_state, accepting_states=nfa2.accepting_states, transitions=nfa1.transitions + nfa2.transitions + [(accepting, "", nfa2.starting_state) for accepting in nfa1.accepting_states])
def exo_aba_factor(): A = NFA({0}, {3}, {(0, 'a', 0), (0, 'b', 0), (0, 'a', 1), (1, 'b', 2), (2, 'a', 3), (3, 'a', 3), (3, 'b', 3)}, name="_aba_").visu() A.dfa().visu().mini().visu() A.h**o({'b': "cde", 'a':'A'}).visu()\ .h**o({'d': ""}).visu().rm_eps().trim().visu()\ .dfa().visu().mini().visu()
def union(nfa1: NFA, nfa2: NFA) -> NFA: starting = next(name_generator) return NFA(states=nfa1.states + nfa2.states + [starting], starting_state=starting, accepting_states=nfa1.accepting_states + nfa2.accepting_states, transitions=nfa1.transitions + nfa2.transitions + [(starting, "", nfa1.starting_state), (starting, "", nfa2.starting_state)])
def Character(c): return NFA( num_states=2, start_state=0, end_states=[1], transitions={ 0: [(c, 1)] })
def ast_to_nfa(ast): """Convert an AST to an NFA. """ (initial, accepting) = ast._thompson() accepting.accepting = 1 return NFA(initial)
def runTest(self): #nfa = NFA(t3_29) nfa = NFA(*load_default('t3_30')) self.assertTrue(SimNFA(nfa, "aabb")) try: nfa.draw() except: pass
def runTest(self): nfa = NFA(*load_default('t3_30')) dfa = DFA.from_nfa(nfa) #print ("dfa:", dfa.start, dfa.accepts) self.assertTrue(SimDFA(dfa, "aabb")) try: dfa.draw() except: pass
def re_to_nfa(re): if (re.type == RE_EMPTY_SET): return NFA(CHARSET, {0}, 0, {}, {}) if (re.type == RE_EMPTY_STRING): return NFA(CHARSET, {0}, 0, {0}, {}) if (re.type == RE_SYMBOL): return NFA(CHARSET, {0, 1}, 0, {1}, {(0, re.symbol): {1}}) if (re.type == RE_STAR): return kleene(re_to_nfa(re.lhs)) if (re.type == RE_CONCATENATION): return concat(re_to_nfa(re.lhs), re_to_nfa(re.rhs)) if (re.type == RE_ALTERNATION): return alternate(re_to_nfa(re.lhs), re_to_nfa(re.rhs))
def nondet_vulgarise(): NFA.VISULANG = 0 # NFA.VISUSIZE = False A = NFA({0}, {3}, {(0, 'a', 0), (0, 'b', 0), (0, 'a', 1), (1, 'a', 2), (1, 'b', 2), (2, 'a', 3), (2, 'b', 3)}, name="a__").visu() A.run("bababa", used_states=False, labeljust="c") A.dfa(pdf=NFA.VISUPDF).visu()
def runTest(self): n = NFA(*load_default('t3_30')) d = DFA.from_nfa(n) print("table:", d.table) self.assertDictEqual(d.table, {'A': {'a': ['A'], 'b': ['A']}}) try: d.draw() except: pass
def symbol_2_nfa(symbol: str) -> NFA: start = next(name_generator) accept = next(name_generator) return NFA( states=[start, accept], transitions=[(start, symbol, accept)], starting_state=start, accepting_states=[accept], )
def star(nfa: NFA) -> NFA: starting = next(name_generator) return NFA(states=nfa.states + [starting], starting_state=starting, accepting_states=nfa.accepting_states + [starting], transitions=nfa.transitions + [(starting, "", nfa.starting_state)] + [(accepting, "", nfa.starting_state) for accepting in nfa.accepting_states])
def test5(self): n5 = NFA(["A", "B", "C"], ["0", "1"], self.d5, "A", ["C"]) assert ([ ('A', [('0', 'A'), ('0', 'B'), ('1', 'A')], False), ('B', [('0', 'C'), ('1', 'C')], False), ('C', [], True) ] == [ state for state in map( lambda state: (state.value, state.transitions, state.accepted), n5.states) ])
def to_nfa(self, accepting_id=1): """Convert this AST to an NFA. Arguments: accepting_id -- The ID of the accepting state (defaults to 1) """ (initial, accepting) = self._thompson() accepting.accepting = accepting_id return NFA(initial)
def main(): input_string = readFile("testcasesUnix/nfa6.txt") nfa = NFA() nfa.initNFA(input_string) dfa = DFA() dfa.convertFromNfa(nfa) text_file = dfa.makeTextFile() dfa_input = readFile("testcasesUnix/dfa6Input.txt") dfa.simulateDFA(text_file, dfa_input)
def test2(self): n2 = NFA(["A", "B", "C", "D", "E", "F"], ["0", "1", LAMBDA], self.d2, "F", ["B", "D", "F", "E"]) assert ([ ('A', [("0", 'B')], False), ('B', [('', 'F')], True), ('C', [("1", 'D')], False), ('D', [('', 'F')], True), ('E', [('', 'C'), ('', 'A')], True), ('F', [('', 'E')], True) ] == [ state for state in map( lambda state: (state.value, state.transitions, state.accepted), n2.states) ])
def test12(self): stdin7 = NFAStdin("nfa7.txt") machine7 = NFA(stdin7.states, stdin7.transitions, stdin7.transition_function, stdin7.start_state, stdin7.accept_states) assert (NFAProblem("000000000000000", machine7).is_string_in_language( NFAProblem("000000000000000", machine7).to_check, NFAProblem("000000000000000", machine7).machine.start_state) == False) assert (NFAProblem("", machine7).is_string_in_language( NFAProblem("", machine7).to_check, NFAProblem("", machine7).machine.start_state))
def test9(self): stdin4 = NFAStdin("nfa4.txt") machine4 = NFA(stdin4.states, stdin4.transitions, stdin4.transition_function, stdin4.start_state, stdin4.accept_states) assert (NFAProblem("", machine4).is_string_in_language( NFAProblem("", machine4).to_check, NFAProblem("", machine4).machine.start_state)) assert (NFAProblem("1", machine4).is_string_in_language( NFAProblem("1", machine4).to_check, NFAProblem("1", machine4).machine.start_state)) assert (NFAProblem("001", machine4).is_string_in_language( NFAProblem("001", machine4).to_check, NFAProblem("001", machine4).machine.start_state)) assert (NFAProblem("00011101", machine4).is_string_in_language( NFAProblem("00011101", machine4).to_check, NFAProblem("00011101", machine4).machine.start_state)) assert (NFAProblem("01", machine4).is_string_in_language( NFAProblem("01", machine4).to_check, NFAProblem("01", machine4).machine.start_state)) assert (NFAProblem("010", machine4).is_string_in_language( NFAProblem("010", machine4).to_check, NFAProblem("010", machine4).machine.start_state)) assert (NFAProblem("0101", machine4).is_string_in_language( NFAProblem("0101", machine4).to_check, NFAProblem("0101", machine4).machine.start_state)) assert (NFAProblem("01111101", machine4).is_string_in_language( NFAProblem("01111101", machine4).to_check, NFAProblem("01111101", machine4).machine.start_state)) assert (NFAProblem("1011101", machine4).is_string_in_language( NFAProblem("1011101", machine4).to_check, NFAProblem("1011101", machine4).machine.start_state)) assert (NFAProblem("0", machine4).is_string_in_language( NFAProblem("0", machine4).to_check, NFAProblem("0", machine4).machine.start_state) == False) assert (NFAProblem("000", machine4).is_string_in_language( NFAProblem("000", machine4).to_check, NFAProblem("000", machine4).machine.start_state) == False) assert (NFAProblem("0001", machine4).is_string_in_language( NFAProblem("0001", machine4).to_check, NFAProblem("0001", machine4).machine.start_state) == False) assert (NFAProblem("000111", machine4).is_string_in_language( NFAProblem("000111", machine4).to_check, NFAProblem("000111", machine4).machine.start_state) == False) assert (NFAProblem("00011101101", machine4).is_string_in_language( NFAProblem("00011101101", machine4).to_check, NFAProblem("00011101101", machine4).machine.start_state) == False) assert (NFAProblem("011111", machine4).is_string_in_language( NFAProblem("011111", machine4).to_check, NFAProblem("011111", machine4).machine.start_state) == False) assert (NFAProblem("00000", machine4).is_string_in_language( NFAProblem("00000", machine4).to_check, NFAProblem("00000", machine4).machine.start_state) == False)
def simone(self): # se não há raiz, linguagem vazia if not self.root: return NFA({"q0": {}}, "q0", {}) # se raiz é terminal, só uma palavra de um caracter if not self.root.is_operator(): return NFA({ "q0": { self.root.value: {"q1"} }, "q1": {} }, "q0", {"q1"}) self.index = 0 self.comp_to_state = {} self.accepting = set() self.transitions = {} self.initial = self.moves_to_state({Move(self.root, DOWN)}) return NFA(self.transitions, self.initial, self.accepting)
def reToNfa(expression): #build nfa from expression alfabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" #base case : empty set if expression.type == EMPTY_SET: return NFA(alfabet, {0, 1}, 0, {1}, {}) #base case : empty string elif expression.type == EMPTY_STRING: return NFA(alfabet, {0, 1}, 0, {1}, {(0, "ε"): {1}}) #base case : one char elif expression.type == SYMBOL: return NFA(alfabet, {0, 1}, 0, {1}, {(0, expression.symbol): {1}}) #case concatenate elif expression.type == CONCATENATION: lhs_nfa = reToNfa(expression.lhs) rhs_nfa = reToNfa(expression.rhs) rename_states(lhs_nfa, rhs_nfa) st1, st2 = new_states(lhs_nfa, rhs_nfa) automata = { (st1, "ε"): {lhs_nfa.start_state}, (list(rhs_nfa.final_states)[0], "ε"): {st2}, (list(lhs_nfa.final_states)[0], "ε"): {rhs_nfa.start_state} } automata.update(lhs_nfa.delta) automata.update(rhs_nfa.delta) return NFA(alfabet, {st1, st2} | lhs_nfa.states | rhs_nfa.states, st1, {st2}, automata) #case alternate elif expression.type == ALTERNATION: lhs_nfa = reToNfa(expression.lhs) rhs_nfa = reToNfa(expression.rhs) rename_states(lhs_nfa, rhs_nfa) st1, st2 = new_states(lhs_nfa, rhs_nfa) automata = { (st1, "ε"): {lhs_nfa.start_state, rhs_nfa.start_state}, (list(rhs_nfa.final_states)[0], "ε"): {st2}, (list(lhs_nfa.final_states)[0], "ε"): {st2} } automata.update(lhs_nfa.delta) automata.update(rhs_nfa.delta) return NFA(alfabet, {st1, st2} | lhs_nfa.states | rhs_nfa.states, st1, {st2}, automata) #case Kleene Star elif expression.type == STAR: lhs_nfa = reToNfa(expression.lhs) st1, st2 = new_states(lhs_nfa) automata = { (st1, "ε"): {lhs_nfa.start_state, st2}, (list(lhs_nfa.final_states)[0], "ε"): {lhs_nfa.start_state, st2} } automata.update(lhs_nfa.delta) return NFA(alfabet, {st1, st2} | lhs_nfa.states, st1, {st2}, automata)
def revision_interro(): NFA.spec(""" 1 2 1 a 1 a 2 b 2 eps 3 2 b 2 3 a 3 """, name="Révision ε-removal").visu().rm_eps().visu().dfa().visu( ).mini().visu() NFA({1}, {3}, {(1, "a", 2), (2, "b", 3), (3, "c", 2), (3, '', 1)}, name="ε2").visu().rm_eps().visu().dfa().visu().mini().visu()
def test1(self): n1 = NFA(["A", "B", "C", "D", "E"], ["0", "1"], self.d1, "A", ["E"]) assert ([ ('A', [("0", 'B'), ("1", 'C')], False), ('B', [("0", 'B'), ("1", 'D')], False), ('C', [("0", 'B'), ("1", 'C')], False), ('D', [("0", 'B'), ("1", 'E')], False), ('E', [("0", 'B'), ("1", 'C')], True) ] == [ state for state in map( lambda state: (state.value, state.transitions, state.accepted), n1.states) ])
def test11(self): stdin6 = NFAStdin("nfa6.in") machine6 = NFA(stdin6.states, stdin6.transitions, stdin6.transition_function, stdin6.start_state, stdin6.accept_states) assert (NFAProblem("000", machine6).is_string_in_language( NFAProblem("000", machine6).to_check, NFAProblem("000", machine6).machine.start_state)) assert (NFAProblem("00", machine6).is_string_in_language( NFAProblem("00", machine6).to_check, NFAProblem("00", machine6).machine.start_state)) assert (NFAProblem("1111101", machine6).is_string_in_language( NFAProblem("1111101", machine6).to_check, NFAProblem("1111101", machine6).machine.start_state)) assert (NFAProblem("1111100", machine6).is_string_in_language( NFAProblem("1111100", machine6).to_check, NFAProblem("1111100", machine6).machine.start_state)) assert (NFAProblem("1010000000", machine6).is_string_in_language( NFAProblem("1010000000", machine6).to_check, NFAProblem("1010000000", machine6).machine.start_state)) assert (NFAProblem("00000001", machine6).is_string_in_language( NFAProblem("00000001", machine6).to_check, NFAProblem("00000001", machine6).machine.start_state)) assert (NFAProblem("", machine6).is_string_in_language( NFAProblem("", machine6).to_check, NFAProblem("", machine6).machine.start_state) == False) assert (NFAProblem("0", machine6).is_string_in_language( NFAProblem("0", machine6).to_check, NFAProblem("0", machine6).machine.start_state) == False) assert (NFAProblem("010", machine6).is_string_in_language( NFAProblem("010", machine6).to_check, NFAProblem("010", machine6).machine.start_state) == False) assert (NFAProblem("01010", machine6).is_string_in_language( NFAProblem("01010", machine6).to_check, NFAProblem("01010", machine6).machine.start_state) == False) assert (NFAProblem("111110", machine6).is_string_in_language( NFAProblem("111110", machine6).to_check, NFAProblem("111110", machine6).machine.start_state) == False) assert (NFAProblem( "00000000000001111110", machine6).is_string_in_language( NFAProblem("00000000000001111110", machine6).to_check, NFAProblem("00000000000001111110", machine6).machine.start_state) == False) assert (NFAProblem("1110", machine6).is_string_in_language( NFAProblem("1110", machine6).to_check, NFAProblem("1110", machine6).machine.start_state) == False) assert (NFAProblem( "sdfghkl;kjhgfdsfghjkl", machine6).is_string_in_language( NFAProblem("sdfghkl;kjhgfdsfghjkl", machine6).to_check, NFAProblem("sdfghkl;kjhgfdsfghjkl", machine6).machine.start_state) == False)
def Union(r1, r2): r1 = r1.Offset(1) r2 = r2.Offset(1 + r1.num_states) trans = {} trans.update(r1.transitions) trans.update(r2.transitions) trans[0] = [(None, r1.start_state), (None, r2.start_state)] return NFA( num_states=1 + r1.num_states + r2.num_states, start_state=0, end_states=r1.end_states | r2.end_states, transitions=trans)
def test3(self): n3 = NFA(["AE", "BF", "CE", "CF", "DE", "DF"], ["0", "1"], self.d3, "AE", ["DE", "AE", "CE", "CF"]) assert ([ ('AE', [("0", 'BF'), ("1", 'DE')], True), ('BF', [("0", 'CE'), ("1", 'CF')], False), ('CE', [("0", 'DF'), ("1", 'DE')], True), ('CF', [("0", 'DE'), ("1", 'DF')], True), ('DE', [("0", 'DF'), ("1", 'DE')], True), ('DF', [("0", 'DE'), ("1", 'DF')], False) ] == [ state for state in map( lambda state: (state.value, state.transitions, state.accepted), n3.states) ])