Пример #1
0
    def _promote(self, qu: automaton.State,
                 dfa: automaton.DFA) -> automaton.DFA:
        """
        Given a state blue state qu, this method promotes this state
        ro red and all the successors in the dfa. The method returns
        the updated dfa.

        :param qu: State with colour blue
        :type qu: State
        :param dfa: the dfa
        :type dfa: Automaton
        :return: Updated dfa
        :rtype: Automaton
        """
        self._logger.info('Promoting state {} from blue to red'.format(
            qu.name))
        self._red.add(qu)

        self._blue.update({
            dfa.transition(qu, a)
            for a in self._alphabet if dfa.transition_exists(qu, a)
        })
        self._blue.discard(qu)

        return dfa
Пример #2
0
    def _merge(self, dfa: automaton.DFA, q: automaton.State,
               q_prime: automaton.State) -> automaton.DFA:
        """
        Takes as arguments a red state q and a blue state q'.
        The method first finds the unique pair (qf, a) such
        that q' = delta(qf, a).
        The method then redirects delta(qf, a) to q. After that
        the tree rooted in q' is folded into the rest of the DFA.
        The possible intermediate situations of non-determinism
        are dealt with during the recursive calls to fold.

        :param dfa: the automaton to update with a merge
        :type dfa: Automaton
        :param q: State from the red set
        :type q: State
        :param q_prime: State from the blue
        :type q_prime: State
        :return: updated Automaton
        :rtype: Automaton
        """
        self._logger.info('Merging the two states {} and {}'.format(
            q.name, q_prime.name))
        qf, a = dfa.find_transition_to_q(q_prime)

        if qf is None or a is None:
            return dfa

        dfa.add_transition(qf, q, a)

        return self._fold(dfa, q, q_prime)
Пример #3
0
    def _fold(self, dfa: automaton.DFA, q: automaton.State,
              q_prime: automaton.State) -> automaton.DFA:
        """
        Folds the tree rooted in q' into the rest of the DFA. The
        possible intermediate situations of non-determinism
        are dealt with during the recursive calls.

        :param dfa: the automaton to update with a folding of states
        :type dfa: Automaton
        :param q: State
        :type q: State
        :param q_prime: State to fold
        :type q_prime: State
        :return: updated Automaton
        :rtype: Automaton
        """
        self._logger.info('Folding the tree rooted in the state {}'.format(
            q_prime.name))
        if q_prime in dfa.accept_states:
            dfa.accept_states.add(q)

        for a in self._alphabet:
            if dfa.transition_exists(q_prime, a):
                if dfa.transition_exists(q, a):
                    dfa = self._fold(dfa, dfa.transition(q, a),
                                     dfa.transition(q_prime, a))
                else:
                    dfa.add_transition(q, dfa.transition(q_prime, a), a)

        return dfa
Пример #4
0
    def _compatible(self, dfa: automaton.DFA) -> bool:
        """
        Determines whether the current automaton can parse any
        string in the set of negative example strings.
        Returns True if the current automaton cannot parse
        any string from the negative examples, returns False
        if some counter-example is accepted by the current
        automaton.

        :param dfa: the dfa
        :type dfa: Automaton
        :return: Boolean indicating whether the dfa is compatible.
        :rtype: bool
        """
        return not any(dfa.parse_string(w)[1] for w in self._neg_examples)