Example #1
0
 def _build_basic_sm(char):
     sm = StateMachine()
     sm.add_init_state(0)
     sm.add_finish_state(1)
     sm.add_catch_state(1)
     sm.add_transition(sm.init_state, sm.catch_state, char)
     return sm
def generate_simple_smc():
    sm = StateMachine()
    sm.add_init_state(0)
    sm.add_finish_state(1)
    sm.add_catch_state(1)
    sm.add_transition(0, 1, 'a')
    return sm
    def build(self):
        self._reset_dfa()
        self.dfa = StateMachine()
        self.dfa.language = self.nfa.language
        self.dfa.add_init_state(0)

        dfa_states = dict()
        unmarked_queue = []  # очередь с помеченными состояниями ДКА
        marked_queue = []
        start_state_list = self.nfa.get_e_closure(self.nfa.init_state)
        unmarked_queue.append(start_state_list)

        dfa_states[0] = start_state_list
        dfa_state_num = 1

        while len(unmarked_queue) > 0:
            start_state_list = unmarked_queue.pop()
            marked_queue.append(start_state_list)
            for symbol in self.dfa.language:
                move_list = self.nfa.get_move_list(start_state_list, symbol)
                end_state_list = self.nfa.get_e_closure_list(move_list)

                if end_state_list is not None and end_state_list not in marked_queue:
                    unmarked_queue.append(end_state_list)
                    dfa_states[dfa_state_num] = end_state_list
                    dfa_state_num += 1

                # Переход в ДКА
                start_state = get_dict_value_by_key(dfa_states,
                                                    start_state_list)
                end_state = get_dict_value_by_key(dfa_states, end_state_list)
                if start_state is not None and end_state is not None:
                    self.dfa.add_transition(start_state, end_state, symbol)

                    for state in end_state_list:
                        if state in self.nfa.finish_states:
                            self.dfa.add_finish_state(end_state)
 def test_check_tran_is_empty(self):
     smc = StateMachine()
     smc.add_init_state(0)
     smc.add_finish_state(1)
     with self.assertRaises(BaseException):
         smc._check_smc()
 def test_check_init_is_none(self):
     smc = StateMachine()
     smc.add_transition(0, 1, 'a')
     with self.assertRaises(BaseException):
         smc._check_smc()
 def test_check_states_is_empty(self):
     smc = StateMachine()
     with self.assertRaises(BaseException):
         smc._check_smc()
 def test_add_finish_correct(self):
     smc = StateMachine()
     smc.add_finish_state(1)
     self.assertEqual(smc.finish_states, [1])
     self.assertEqual(smc.states, [1])
 def test_add_finish_not_int(self):
     smc = StateMachine()
     with self.assertRaises(TypeError):
         smc.add_finish_state('a')
 def test_add_tran_correct(self):
     smc = StateMachine()
     smc.add_transition(0, 1, 'a')
     self.assertEqual(smc.transitions[0], [0, 1, 'a'])
     self.assertEqual(smc.states, [0, 1])
     self.assertEqual(smc.language, ['a'])
Example #10
0
    def _build_and_sm(sm1, sm2):
        sm = StateMachine()
        sm.add_init_state(sm1.init_state)

        for transition in sm1.transitions:
            sm.add_transition(transition[0], transition[1], transition[2])

        if sm1.catch_state > 0:
            sm2.renumber_states(sm1.catch_state - 1)
        else:
            sm2.renumber_states()

        for transition in sm2.transitions:
            sm.add_transition(transition[0], transition[1], transition[2])

        sm.add_finish_state(sm2.catch_state)
        sm.add_catch_state(sm2.catch_state)

        return sm
 def test_add_tran_end_not_int(self):
     smc = StateMachine()
     with self.assertRaises(TypeError):
         smc.add_transition(0, 'a', 'a')
 def test_add_catch_correct(self):
     smc = StateMachine()
     smc.add_catch_state(1)
     self.assertEqual(smc.catch_state, 1)
 def test_add_catch_non_empty(self):
     smc = StateMachine()
     smc.add_catch_state(1)
     with self.assertRaises(ValueError):
         smc.add_catch_state(2)
 def test_add_init_correct(self):
     smc = StateMachine()
     smc.add_init_state(0)
     self.assertEqual(smc.init_state, 0)
Example #15
0
    def _build_zero_or_more_sm(sm1):
        sm = StateMachine()
        sm.add_init_state(0)

        sm1.renumber_states()
        sm1.add_transition(sm1.catch_state, sm1.init_state, BaseConfig.EPSILON)

        for transition in sm1.transitions:
            sm.add_transition(transition[0], transition[1], transition[2])

        sm.add_finish_state(sm1.catch_state + 1)
        sm.add_catch_state(sm1.catch_state + 1)

        sm.add_transition(sm.init_state, sm1.init_state, BaseConfig.EPSILON)
        sm.add_transition(sm.init_state, sm.catch_state, BaseConfig.EPSILON)
        sm.add_transition(sm1.catch_state, sm.catch_state, BaseConfig.EPSILON)

        sm.states = sorted(sm.states)
        sm.transitions = sorted(sm.transitions)
        return sm
Example #16
0
    def _build_or_sm(sm1, sm2):
        sm = StateMachine()
        sm.add_init_state(0)
        sm1.renumber_states()
        sm2.renumber_states(from_number=sm1.catch_state)

        sm.add_transition(sm.init_state, sm1.init_state, BaseConfig.EPSILON)
        sm.add_transition(sm.init_state, sm2.init_state, BaseConfig.EPSILON)

        for transition in sm1.transitions:
            sm.add_transition(transition[0], transition[1], transition[2])

        for transition in sm2.transitions:
            sm.add_transition(transition[0], transition[1], transition[2])

        sm.add_finish_state(sm2.catch_state + 1)
        sm.add_catch_state(sm2.catch_state + 1)

        sm.add_transition(sm1.catch_state, sm.catch_state, BaseConfig.EPSILON)
        sm.add_transition(sm2.catch_state, sm.catch_state, BaseConfig.EPSILON)

        sm.states = sorted(sm.states)

        return sm
class DfaNfa:
    def __init__(self, nfa):
        self.nfa = nfa

        if not nfa or not isinstance(nfa, StateMachine):
            raise TypeError('Nfa must be non empty StateMachine class member')

        self.dfa = None

    def _reset_dfa(self):
        self.dfa = None

    def build(self):
        self._reset_dfa()
        self.dfa = StateMachine()
        self.dfa.language = self.nfa.language
        self.dfa.add_init_state(0)

        dfa_states = dict()
        unmarked_queue = []  # очередь с помеченными состояниями ДКА
        marked_queue = []
        start_state_list = self.nfa.get_e_closure(self.nfa.init_state)
        unmarked_queue.append(start_state_list)

        dfa_states[0] = start_state_list
        dfa_state_num = 1

        while len(unmarked_queue) > 0:
            start_state_list = unmarked_queue.pop()
            marked_queue.append(start_state_list)
            for symbol in self.dfa.language:
                move_list = self.nfa.get_move_list(start_state_list, symbol)
                end_state_list = self.nfa.get_e_closure_list(move_list)

                if end_state_list is not None and end_state_list not in marked_queue:
                    unmarked_queue.append(end_state_list)
                    dfa_states[dfa_state_num] = end_state_list
                    dfa_state_num += 1

                # Переход в ДКА
                start_state = get_dict_value_by_key(dfa_states,
                                                    start_state_list)
                end_state = get_dict_value_by_key(dfa_states, end_state_list)
                if start_state is not None and end_state is not None:
                    self.dfa.add_transition(start_state, end_state, symbol)

                    for state in end_state_list:
                        if state in self.nfa.finish_states:
                            self.dfa.add_finish_state(end_state)

    def minimize(self):
        if self.dfa is None:
            raise TypeError('Use build() first')

        dfa_classes = []
        classes_queue = []

        # Начальное разбиение
        finish_states = self.dfa.finish_states
        without_finish_states = list(set(self.dfa.states) - set(finish_states))

        dfa_classes.append(finish_states)
        dfa_classes.append(without_finish_states)
        classes_queue.append(finish_states)
        classes_queue.append(without_finish_states)

        # Поиск эквивалентных классов состояний
        while classes_queue:
            curr_queue_item = classes_queue.pop()
            for symbol in self.dfa.language:
                # Список состояний, в которых есть переход в состояния из curr_queue_item
                # по символу symbol
                curr_end_list = self.dfa.get_come_list(curr_queue_item, symbol)
                if curr_end_list is not None:

                    dfa_classes_frozen = copy.deepcopy(dfa_classes)
                    for curr_dfa_class in dfa_classes_frozen:
                        intersection = set(curr_end_list) & set(curr_dfa_class)
                        subtraction = set(curr_dfa_class) - set(curr_end_list)

                        if len(intersection) > 0 and len(subtraction) > 0:
                            index = dfa_classes.index(curr_dfa_class)
                            dfa_classes.pop(index)
                            dfa_classes.append(list(intersection))
                            dfa_classes.append(list(subtraction))

                            if curr_dfa_class in classes_queue:
                                index = classes_queue.index(curr_dfa_class)
                                classes_queue.pop(index)
                                classes_queue.append(list(intersection))
                                classes_queue.append(list(subtraction))
                            else:
                                if len(intersection) <= len(subtraction):
                                    classes_queue.append(list(intersection))
                                else:
                                    classes_queue.append(list(subtraction))

        for dfa_class in dfa_classes:
            if len(dfa_class) > 1:
                self.dfa.combine_states(dfa_class)

    def run(self, chain):
        if self.dfa is None:
            raise TypeError('Use build() first')

        self.nfa.draw()
        self.dfa.draw()
        self.dfa.debug_print_info()

        print('Входная строка: ', chain)
        is_valid = True
        i = 0
        curr_state = self.dfa.init_state
        while is_valid and i < len(chain):
            print('Текущий символ: ', chain[i])
            next_state = self.dfa.get_move(curr_state, chain[i])
            if next_state is not None and len(next_state) == 1:
                print('Переход: ', curr_state, '---> ', end='')
                curr_state = next_state.pop()
                print(curr_state, 'по символу ', chain[i])
            else:
                print('Переход не существует')
                is_valid = False
            i += 1

        if curr_state in self.dfa.finish_states:
            print('Достигнуто принимающее состояние')
        else:
            print('Принимающее состояние не достигнуто')
            is_valid = False

        print('\nРезультат: ', is_valid)

        return is_valid
 def test_add_tran_symbol_not_char(self):
     smc = StateMachine()
     with self.assertRaises(TypeError):
         smc.add_transition(0, 1, 2)