Example #1
0
    def test_intersection_regex(self):
        """ Tests the intersection with a regex """
        # pylint: disable=too-many-locals
        state_p = State("p")
        state_q = State("q")
        state_r = State("r")
        state_i = Symbol("i")
        state_e = Symbol("e")
        state_z = StackSymbol("Z")
        state_x0 = StackSymbol("X0")
        pda = PDA(states={state_p, state_q, state_r},
                  input_symbols={state_i, state_e},
                  stack_alphabet={state_z, state_x0},
                  start_state=state_p,
                  start_stack_symbol=state_x0,
                  final_states={state_r})
        pda.add_transition(state_p, Epsilon(), state_x0, state_q,
                           [state_z, state_x0])
        pda.add_transition(state_q, state_i, state_z, state_q,
                           [state_z, state_z])
        pda.add_transition(state_q, state_e, state_z, state_q, [])
        pda.add_transition(state_q, Epsilon(), state_x0, state_r, [])

        state_s = finite_automaton.State("s")
        state_t = finite_automaton.State("t")
        i_dfa = finite_automaton.Symbol("i")
        e_dfa = finite_automaton.Symbol("e")
        dfa = finite_automaton.DeterministicFiniteAutomaton(
            states={state_s, state_t},
            input_symbols={i_dfa, e_dfa},
            start_state=state_s,
            final_states={state_s, state_t})
        dfa.add_transition(state_s, i_dfa, state_s)
        dfa.add_transition(state_s, e_dfa, state_t)
        dfa.add_transition(state_t, e_dfa, state_t)

        new_pda = pda.intersection(dfa)
        pda_es = new_pda.to_empty_stack()
        cfg = pda_es.to_cfg()
        self.assertEqual(new_pda.get_number_transitions(), 6)
        self.assertEqual(len(new_pda.states), 5)
        self.assertEqual(len(new_pda.final_states), 2)
        self.assertEqual(len(new_pda.input_symbols), 2)
        self.assertEqual(len(new_pda.stack_symbols), 2)

        i_cfg = Terminal("i")
        e_cfg = Terminal("e")

        self.assertTrue(cfg.contains([i_cfg, i_cfg, e_cfg, e_cfg, e_cfg]))

        new_pda = pda.intersection(
            finite_automaton.DeterministicFiniteAutomaton())
        self.assertEqual(new_pda.get_number_transitions(), 0)
Example #2
0
    def _to_deterministic_internal(self,
                                   eclose: bool) \
            -> "DeterministicFiniteAutomaton":
        """ Transforms the epsilon-nfa into a dfa

        Parameters
        ----------
        eclose : bool
            Whether to use the epsilon closure or not

        Returns
        ----------
        dfa :  :class:`~pyformlang.deterministic_finite_automaton\
        .DeterministicFiniteAutomaton`
            A dfa equivalent to the current nfa
        """
        dfa = finite_automaton.DeterministicFiniteAutomaton()
        # Add Eclose
        if eclose:
            start_eclose = self.eclose_iterable(self._start_state)
        else:
            start_eclose = self._start_state
        start_state = to_single_state(start_eclose)
        dfa.add_start_state(start_state)
        to_process = [start_eclose]
        processed = {start_state}
        while to_process:
            current = to_process.pop()
            s_from = to_single_state(current)
            for symb in self._input_symbols:
                all_trans = [
                    self._transition_function(x, symb) for x in current
                ]
                state = set()
                for trans in all_trans:
                    state = state.union(trans)
                if not state:
                    continue
                # Eclose added
                if eclose:
                    state = self.eclose_iterable(state)
                state_merged = to_single_state(state)
                dfa.add_transition(s_from, symb, state_merged)
                if state_merged not in processed:
                    processed.add(state_merged)
                    to_process.append(state)
            for state in current:
                if state in self._final_states:
                    dfa.add_final_state(s_from)
        return dfa