Ejemplo n.º 1
0
    def test_dfa_match_good1(self):
        tr = {(0, 15): 1,
              (0, 22): 2,
              (1, 17): 3,
              (2, 17): 3,
              (2, 22): 4,
              (3, 22): 4,
              (4, 233): 4
              }
        fs = {1: {'regex1'},
              4: {'regex2'}
              }
        dfa = DFA(5, tr, 0, fs)
        seq = [15]
        self.assertEqual(dfa.match(seq), {'regex1'}, "In this example, the sequence [15] leads into final state 1 that should return regex1 as label")

        tr = {(0, 15): 1,
              (0, 22): 2,
              (1, 17): 3,
              (2, 17): 3,
              (2, 22): 4,
              (3, 22): 4,
              (4, 233): 4
              }
        fs = {1: {'regex1'},
              4: {'regex2'}
              }
        dfa = DFA(5, tr, 0, fs)
        seq = [15, 17, 22, 233]
        self.assertEqual(dfa.match(seq), {'regex2'}, "In this example, the sequence [15, 17, 22, 233] leads into final state 4 that should return regex2 as label")
Ejemplo n.º 2
0
 def test_dfa_match_bad(self):
     tr = {(0, 15): 1,
           (0, 22): 2,
           (1, 17): 3,
           (2, 17): 3,
           (2, 22): 4,
           (3, 22): 4,
           (4, 233): 4
           }
     fs = {1: {'regex1'},
           4: {'regex2'}
           }
     dfa = DFA(5, tr, 0, fs)
     seq = [2]
     self.assertEqual(dfa.match(seq), set(), "Matching the empty sequence should stay in the start state which is not final in this example")
     
     tr = {(0, 15): 1,
           (0, 22): 2,
           (1, 17): 3,
           (2, 17): 3,
           (2, 22): 4,
           (3, 22): 4,
           (4, 233): 4
           }
     fs = {1: {'regex1'},
           4: {'regex2'}
           }
     dfa = DFA(5, tr, 0, fs)
     seq = [22, 22, 233, 2]
     self.assertEqual(dfa.match(seq), set(), "If a transition is undefined, it must return set()")
Ejemplo n.º 3
0
def test_set_new_transtable():

    alphabet = ["a", "b"]
    states = ["1", "2"]

    table = TransitionTable(alphabet, states)
    table.add_transition("a", "2", "2")
    table.add_transition("b", "2", "2")
    table.add_transition("a", "1", "2")
    table.add_transition("b", "1", "1")

    dfa = DFA(table)

    # invalid table
    try:
        dfa.trans_table = {}
    except ValueError:
        pass

    # new table
    new_table = TransitionTable(alphabet, states)
    new_table.add_transition("b", "2", "2")
    new_table.add_transition("a", "1", "2")
    new_table.add_transition("b", "1", "1")

    dfa.trans_table = new_table
Ejemplo n.º 4
0
def test_consume():

    alphabet = ["a", "b"]
    states = ["1", "2"]

    table = TransitionTable(alphabet, states)
    table.add_transition("b", "2", "2")
    table.add_transition("a", "1", "2")
    table.add_transition("b", "1", "1")

    dfa = DFA(table)

    # accepted string
    accepted = dfa.consume("ba")
    assert accepted, "'ba' is expected to be accepted."

    accepted = dfa.consume("babbb")
    assert accepted, "'babbb' is expected to be accepted."

    # not acceptable string
    accepted = dfa.consume("b")
    assert not accepted, "'b' is expected not to be accepted."

    accepted = dfa.consume("bbb")
    assert not accepted, "'bbb' is expected not to be accepted."

    # dead state
    accepted = dfa.consume("bbaba")
    assert not accepted, "'bbaba' is expected not to be accepted."

    # invalid transition
    accepted = dfa.consume("babbbc")
    assert not accepted, "'bac' is expected not to be accepted."
Ejemplo n.º 5
0
    def nfa_to_dfa(self):
        try:
            self.alphabet.remove('ε')
        except:
            pass

        self.new_ss = state({s.id for s in self.start_states})
        temp_op = {key: set() for key in self.alphabet + ['ε']}
        for ss in self.start_states:
            for k, v in ss.outpaths.items():
                set_v = set(v)
                temp_op[k] = temp_op[k].union(set_v)
        self.new_ss.outpaths = {k: list(v) for k, v in temp_op.items()}
        self.new_ss.made_of = set(self.start_states)
        self.states.append(self.new_ss)

        self.e_transitions()
        if 'ε' in self.new_ss.outpaths:
            del self.new_ss.outpaths['ε']

        existing_states = [self.new_ss.made_of]
        new_states = [self.new_ss]
        dfa_states = [self.new_ss]

        while len(new_states) > 0:
            next_round = []
            for es in new_states:
                new_dict = {key: set() for key in self.alphabet}
                for sub_state in es.made_of:
                    for char, states in sub_state.ep_outpaths.items():
                        new_dict[char] = new_dict[char].union(states)
                for char, states in new_dict.items():
                    if states not in existing_states:
                        id = set([s.id for s in states])
                        if id == set():
                            id = '∅'
                        new_state = state(id)
                        new_state.made_of = states
                        es.outpaths[char] = new_state
                        dfa_states.append(new_state)
                        existing_states.append(states)
                        next_round.append(new_state)
                    else:
                        for x in dfa_states:
                            if x.made_of == states:
                                es.outpaths[char] = x
                                break
            new_states = next_round

        self.my_dfa = DFA(dfa_states)
        self.my_dfa.alphabet = self.alphabet
        self.my_dfa.start_state = self.new_ss

        acc_ids = {st.id for st in self.accept_states}
        for st in self.my_dfa.states:
            for s in st.made_of:
                if s.id in acc_ids:
                    self.my_dfa.accept_states.append(st)
                    break
Ejemplo n.º 6
0
 def test_dfa_match_empty(self):
     tr = {(0, 15): 1,
           (0, 22): 2,
           (1, 17): 3,
           (2, 17): 3,
           (2, 22): 4,
           (3, 22): 4,
           (4, 233): 4
           }
     fs = {1: {'regex1'},
           4: {'regex2'}
           }
     dfa = DFA(5, tr, 0, fs)
     seq = []
     self.assertEqual(dfa.match(seq), set(), "Matching the empty sequence should stay in the start state which is not final")
     tr = {(0, 15): 0}
     fs = {0: {'regex1'}}
     dfa = DFA(1, tr, 0, fs)
     self.assertEqual(dfa.match([]), {"regex1"}, "In this example, the start state is accepting, so the empty sequence should return the correct label")
Ejemplo n.º 7
0
def test1():
    #1a in HW3 in Automata & Computability
    print('Test 1')
    s0 = state(0)
    s1 = state(1)
    s0.outpaths = {'a': s1, 'b': s0}
    s1.outpaths = {'a': s0, 'b': s1}
    d = DFA([s0, s1])
    d.start_state = s0
    d.accept_states = [s0]
    d.alphabet = ['a', 'b']
    print(d.all_regex(False) + '\n')
Ejemplo n.º 8
0
def test5():
    #accepts any variant of a(ba)*a
    print('Test 5')
    s0 = state(0)
    s1 = state(1)
    s2 = state(2)
    s0.outpaths = {'a': s1}
    s1.outpaths = {'a': s2, 'b': s0}
    d = DFA([s0, s1, s2])
    d.start_state = s0
    d.accept_states = [s2]
    d.alphabet = ['a', 'b']
    print(d.all_regex(False))
Ejemplo n.º 9
0
    def subset_construction(self):
        # based on:
        # Subset Construction presented by Ullman (Automata course)
        # extended with closure operation to work with epsilon transitions
        states = 1
        numeric_state = dict()
        closure = self.epsilon_closure()
        start = frozenset(closure[self.start])
        numeric_state[start] = states - 1
        finals = dict()

        # empty transitions dictionary
        tr = dict()

        queue = collections.deque([start])

        # if one of the subset states in the DFA start state is already final
        fin = start & self.final.keys()
        if fin:
            # start state is always id 0
            finals[0] = {label for q in fin for label in self.final[q]}

        while queue:
            # print(len(queue))
            curr_state = queue.popleft()
            for (a, state_set) in self.successors(curr_state).items():
                # for a in range(256):
                # next_state = self.next(curr_state, a)
                next_state = frozenset(state_set)

                if next_state:
                    # the state exists
                    if next_state not in numeric_state.keys():
                        states += 1
                        numeric_state[next_state] = states - 1
                        # add into queue so it gets resolved in next round
                        queue.append(next_state)

                    tr[numeric_state[curr_state],
                       a] = numeric_state[next_state]
                    fin = next_state & self.final.keys()
                    if fin:
                        finals[numeric_state[next_state]] = {
                            label
                            for q in fin for label in self.final[q]
                        }
        # print("State Subsets", numeric_state)
        return DFA(states, tr, 0, finals)
Ejemplo n.º 10
0
def test3():
    #1d in HW3 in Automata & Computability
    print('Test 3')
    s0 = state(0)
    s1 = state(1)
    s2 = state(2)
    s3 = state(3)
    s0.outpaths = {'a': s2, 'b': s1}
    s1.outpaths = {'a': s3, 'b': s0}
    s2.outpaths = {'a': s0, 'b': s3}
    s3.outpaths = {'a': s1, 'b': s2}
    d = DFA([s0, s1, s2, s3])
    d.start_state = s0
    d.accept_states = [s1]
    d.alphabet = ['a', 'b']
    print(d.all_regex() + '\n')
Ejemplo n.º 11
0
def test4():
    #pg 17 Example 3.2 from Automata & Computability
    #accepts strings w/ 3 consecutive a's
    print('Test 4')
    s0 = state(0)
    s1 = state(1)
    s2 = state(2)
    s3 = state(3)
    s0.outpaths = {'a': s1, 'b': s0}
    s1.outpaths = {'a': s2, 'b': s0}
    s2.outpaths = {'a': s3, 'b': s0}
    s3.outpaths = {'a': s3, 'b': s3}
    d = DFA([s0, s1, s2, s3])
    d.start_state = s0
    d.accept_states = [s3]
    d.alphabet = ['a', 'b']
    print(d.all_regex() + '\n')
Ejemplo n.º 12
0
def test2():
    #Example 13.1 from Automata & Computability
    print('Test 2')
    s0 = state(0)
    s1 = state(1)
    s2 = state(2)
    s3 = state(3)
    s0.outpaths = {'a': s1, 'b': s3}
    s1.outpaths = {'a': s2, 'b': s2}
    s2.outpaths = {'a': s2, 'b': s2}
    s3.outpaths = {'a': s2, 'b': s2}
    d = DFA([s0,s1,s2,s3])
    d.start_state = s0
    d.accept_states = [s1, s3]
    d.alphabet = ['a', 'b']
    d.minimize()
    d.print_dfa(True)

    """
Ejemplo n.º 13
0
def test6():
    #Example 13.2 from Automata & Computability
    #accepts {a,b} and any strings with 3+ characters
    print('Test 6')
    s0 = state(0)
    s1 = state(1)
    s2 = state(2)
    s3 = state(3)
    s4 = state(4)
    s5 = state(5)
    s0.outpaths = {'a': s1, 'b': s2}
    s1.outpaths = {'a': s3, 'b': s4}
    s2.outpaths = {'a': s4, 'b': s3}
    s3.outpaths = {'a': s5, 'b': s5}
    s4.outpaths = {'a': s5, 'b': s5}
    s5.outpaths = {'a': s5, 'b': s5}
    d = DFA([s0, s1, s2, s3, s4, s5])
    d.start_state = s0
    d.accept_states = [s1, s2, s5]
    d.alphabet = ['a', 'b']
    print(d.all_regex())
Ejemplo n.º 14
0
def test1():
    #from https://www.gatevidyalay.com/minimization-of-dfa-minimize-dfa-example/
    print('Test 1')
    s0 = state(0)
    s1 = state(1)
    s2 = state(2)
    s3 = state(3)
    s4 = state(4)
    s0.outpaths = {'a': s1, 'b': s2}
    s1.outpaths = {'a': s1, 'b': s3}
    s2.outpaths = {'a': s1, 'b': s2}
    s3.outpaths = {'a': s1, 'b': s4}
    s4.outpaths = {'a': s1, 'b': s2}
    d = DFA([s0,s1,s2,s3,s4])
    d.start_state = s1
    d.accept_states = [s4]
    d.alphabet = ['a', 'b']
    d.minimize()
    d.print_dfa(True)

    """
Ejemplo n.º 15
0
def test3():
    #from https://www.geeksforgeeks.org/minimization-of-dfa/
    print('Test 3')
    s0 = state(0)
    s1 = state(1)
    s2 = state(2)
    s3 = state(3)
    s4 = state(4)
    s5 = state(5)
    s0.outpaths = {'0': s3, '1': s1}
    s1.outpaths = {'0': s2, '1': s5}
    s2.outpaths = {'0': s2, '1': s5}
    s3.outpaths = {'0': s0, '1': s4}
    s4.outpaths = {'0': s2, '1': s5}
    s5.outpaths = {'0': s5, '1': s5}
    d = DFA([s0,s1,s2,s3,s4,s5])
    d.start_state = s0
    d.accept_states = [s1, s2, s4]
    d.alphabet = ['0', '1']
    d.minimize()
    d.print_dfa(True)

    """
Ejemplo n.º 16
0
def test4():
    #Example 13.2 from Automata & Computability
    print('Test 4')
    s0 = state(0)
    s1 = state(1)
    s2 = state(2)
    s3 = state(3)
    s4 = state(4)
    s5 = state(5)
    s0.outpaths = {'a': s1, 'b': s2}
    s1.outpaths = {'a': s3, 'b': s4}
    s2.outpaths = {'a': s4, 'b': s3}
    s3.outpaths = {'a': s5, 'b': s5}
    s4.outpaths = {'a': s5, 'b': s5}
    s5.outpaths = {'a': s5, 'b': s5}
    d = DFA([s0,s1,s2,s3,s4,s5])
    d.start_state = s0
    d.accept_states = [s1, s2, s5]
    d.alphabet = ['a', 'b']
    d.minimize()
    d.print_dfa(True)

    """
Ejemplo n.º 17
0
 def create_fa(self, expression, alphabet):
     new_FA = DFA()
     new_FA.set_name(str(expression))
     self.FA_list.append(new_FA)
     self.add_tab(expression, ['FA', alphabet])
Ejemplo n.º 18
0
	def create_fa(self, expression, alphabet):
		automata = DFA()
		automata.set_name(str(expression))
		self.FA_list.append(automata)
		self.add_tab(expression, ['FA', alphabet])