Exemplo n.º 1
0
    def rename_states(self):
        """
        Renames all the states in the dfa.

        :return: Original DFA with states renamed.
        :rtype: DFA
        """
        alphabet = sorted(self.alphabet)
        dfa = DFA(self.alphabet, State('0'))

        queue = deque([self._start_state])
        visited = {self._start_state}
        cnt = 1
        old_to_new = {self._start_state: State('0')}

        while len(queue) > 0:
            state = queue.popleft()

            for a in alphabet:
                if state in self._transitions and a in self._transitions[state]:
                    to_state = self.transition(state, a)

                    if to_state not in visited:
                        queue.append(to_state)
                        visited.add(to_state)

                        old_to_new[to_state] = State(str(cnt))
                        cnt += 1

        for old, new in old_to_new.items():
            old_transitions = self._transitions[old]

            for sym, state in old_transitions.items():
                dfa.add_transition(new, old_to_new[state], sym)

            if old in self.accept_states:
                dfa.accept_states.add(new)

        return dfa
Exemplo n.º 2
0
    def minimize(self):
        """
        Minimizes the dfa using Hopcroft's algorithm.
        Please consult the following paper
        https://pdfs.semanticscholar.org/e622/10eea9d53bc36af50675017a830c967fea3f.pdf
        for an explanation of this algorithm.

        :return: Minimized dfa
        :rtype: DFA
        """
        p = self._hopcroft()

        start = [
            state_set for state_set in p if self._start_state in state_set
        ]
        assert len(start) == 1

        minimized_dfa = DFA(self.alphabet, State(''.join(map(str, start[0]))))
        for state_set in p:
            for a in self.alphabet:
                for state in state_set:
                    if self.transition_exists(state, a):
                        to_state = self.transition(state, a)
                        to = [s for s in p if to_state in s]
                        assert len(to) == 1

                        to_state_set = to[0]
                        minimized_dfa.add_transition(
                            State(''.join(map(str, state_set))),
                            State(''.join(map(str, to_state_set))), a)
                        break

            if any(s in self.accept_states for s in state_set):
                minimized_dfa.accept_states.add(
                    State(''.join(map(str, state_set))))

        return minimized_dfa.rename_states()
Exemplo n.º 3
0
    def __init__(self, alphabet: Set[str], start_state: State = State('')):
        """
        :param alphabet: The alphabet of the regular language
        :type alphabet: set
        :param start_state: the initial state of the dfa
        :type start_state: State
        """
        super().__init__(alphabet)

        self._start_state = start_state

        self.states = {self._start_state}

        self.accept_states = set()

        self.reject_states = set()

        self._transitions = defaultdict(OrderedDict)