def to_dfa(self): """ Returns the DFA corresponding to the NFA. It uses the powerset construction. See: https://en.wikipedia.org/wiki/Powerset_construction """ symbols = set(self._symbols) if self.has_epsilon_moves(): symbols.remove(Nfa.EPSILON) states = set() transitions = dict() final_states = set() new_states = [self.epsilon_closure(self._initial_state)] initial_state = Nfa._set_to_state(new_states[0]) while new_states: state = new_states.pop() new_state = Nfa._set_to_state(state) states.add(new_state) if self._final_states.intersection(state): final_states.add(new_state) transitions[new_state] = dict() for symbol in symbols: t = set() for s in state: for i in self.delta(s, symbol): t.update(self.epsilon_closure(i)) if t: ns = Nfa._set_to_state(t) transitions[new_state][symbol] = ns if ns not in states and t not in new_states: new_states.append(t) return Dfa(states, symbols, transitions, initial_state, final_states)
def a1(): Q = {'S1', 'S2'} S = {'0', '1'} d = {'S1': {'0': 'S2', '1': 'S1'}, 'S2': {'0': 'S1', '1': 'S2'}} q0 = 'S1' F = {'S1'} return Dfa(Q, S, d, q0, F)
def test_init_5(): with pytest.raises(FsmError): Q = {'S0', 'S1', 'S2'} S = {'0', '1'} d = [] # d is not a dictionnary q0 = 'S0' F = {'S0'} Dfa(Q, S, d, q0, F)
def test_init_1(): with pytest.raises(FsmError): Q = {'S0', 'S1', 'S2'} S = {'0', '1'} d = { 'S0': { '0': 'S0', '1': 'S1' }, 'S1': { '0': 'S2', '1': 'S0' }, 'S2': { '0': 'S1', '1': 'S2' } } q0 = 'S3' # Q does not contain q0 F = {'S0'} Dfa(Q, S, d, q0, F)
def test_init_4(): with pytest.raises(FsmError): Q = {'S0', 'S1'} S = {'0', '1'} d = { 'S0': { '0': 'S0', '1': 'S1' }, 'S1': { '0': 'S2', '1': 'S0' }, 'S2': { # S2 is not in Q '0': 'S1', '1': 'S2' } } q0 = 'S0' F = {'S0'} Dfa(Q, S, d, q0, F)
def test_init_2(): with pytest.raises(FsmError): Q = {'S0', 'S1', 'S2'} S = {'0', '1'} d = { 'S0': { '0': 'S0', '1': 'S1' }, 'S1': { '0': 'S2', '1': 'S0' }, 'S2': { '0': 'S1', '1': 'S2' } } q0 = 'S0' F = {'S0', 'S3'} # Q does not contain all states of F Dfa(Q, S, d, q0, F)
def test_init_3(): with pytest.raises(FsmError): Q = {0, 1, 2, 3} S = {'a', 'b'} d = { 0: { 'a': {0, 1}, 'b': {0} }, 1: { 'a': {2} }, 2: { 'a': {3} }, 3: { 'a': {3}, 'b': {3} } } # the state-transition function is not deterministic q0 = 0 F = {3} Dfa(Q, S, d, q0, F)
Graph: graph1_dfa.dot Source: https://en.wikipedia.org/wiki/Deterministic_finite_automaton#Example """ from fsmdot.dfa import Dfa Q = {'S1', 'S2'} S = {'0', '1'} d = { 'S1': { '0': 'S2', '1': 'S1' }, 'S2': { '0': 'S1', '1': 'S2' } } q0 = 'S1' F = {'S1'} a = Dfa(Q, S, d, q0, F) a.print_table() print(a.accept('11110')) print(a.accept('110110110101')) G = a.dot_graph() print(G.to_string()) G.write('graph1_dfa.dot')