Ejemplo n.º 1
0
 def to_dfsm(self):
     transitions = {}
     accepting = set()
     initial = State()
     closure = self._get_epsilon_closure(self.start)
     if closure & self.accepting:
         accepting.add(initial)
     key = tuple(closure)
     supersets = {
         key: initial
     }
     stack = [key]
     while stack:
         current = stack.pop()
         for symbol in self.alphabet:
             superstate = self._construct_superset(current, symbol)
             if not superstate:
                 continue
             if superstate not in supersets:
                 stack.append(superstate)
             try:
                 state = supersets[superstate]
             except KeyError:
                 state = State()
             supersets[superstate] = state
             transitions[(supersets[current], symbol)] = state
             if set(superstate) & self.accepting:
                 accepting.add(state)
     return DFSM(alphabet=self.alphabet,
                 states=frozenset(supersets.values()),
                 transitions=util.freeze_map(transitions),
                 initial=initial,
                 accepting=accepting)
Ejemplo n.º 2
0
 def atom_matcher(cls, symbol):
     start = State()
     accept = State()
     transitions = {
         (start, symbol): {accept}
     }
     return cls(states={start, accept},
                alphabet={symbol},
                transitions=util.freeze_map(transitions),
                initial=start,
                accepting={accept})
Ejemplo n.º 3
0
 def kleene_star(self):
     state = State()
     x = self.to_normal_form()
     accept = next(iter(x.accepting))
     transitions = x.transitions.dictionary.copy()
     transitions[(state, constants.EPSILON)] = {x.start}
     self._update_state(transitions, (accept, constants.EPSILON), {state})
     return self.__class__(states=x.states | {state},
                           alphabet=x.alphabet,
                           transitions=util.freeze_map(transitions),
                           initial=state,
                           accepting={state}).to_normal_form()
Ejemplo n.º 4
0
 def __init__(self, states, alphabet, transitions, initial, accepting):
     self.__states = frozenset(states)
     self.__alphabet = frozenset(alphabet)
     if util.is_multi_valued(transitions):
         self.__transitions = util.freeze_map(transitions)
     else:
         self.__transitions = util.to_multi_valued(transitions)  # is frozen
     self.__start = initial
     self.__accepting = frozenset(accepting)
     self.runner = _DFSMRunner(self.__start,
                               self.__accepting,
                               self.__transitions,
                               multi_valued=True)
Ejemplo n.º 5
0
 def concat(self, other):
     a = self.to_normal_form()
     b = other.to_normal_form()
     transitions = {**a.transitions, **b.transitions}
     a_accept = next(iter(a.accepting))
     b_accept = next(iter(b.accepting))
     self._update_state(transitions,
                        (a_accept, constants.EPSILON),
                        {b.start})
     return self.__class__(states=a.states | b.states,
                           alphabet=a.alphabet | b.alphabet,
                           transitions=util.freeze_map(transitions),
                           initial=a.start,
                           accepting={b_accept})
Ejemplo n.º 6
0
 def simplify(self):
     useless = self._get_useless_states()
     if self.__start in useless:
         return self._empty_machine()
     transitions = self.__transitions.dictionary.copy()
     unreachable = self._get_unreachable_states()
     remove = unreachable | useless
     for key, new in list(transitions.items()):
         if new in remove:
             del transitions[key]
     return self.__class__(states=self.__states - remove,
                           alphabet=self.__alphabet,
                           transitions=util.freeze_map(transitions),
                           initial=self.__start,
                           accepting=self.__states - remove)
Ejemplo n.º 7
0
 def make_total(self):
     if self.is_total():
         return self
     trash_state = State()
     transitions = self.transitions.dictionary.copy()
     for state in self.states:
         for symbol in self.alphabet:
             if (state, symbol) not in self.transitions:
                 transitions[(state, symbol)] = {trash_state}
     for symbol in self.alphabet:
         transitions[(trash_state, symbol)] = {trash_state}
     return self.__class__(alphabet=self.alphabet,
                           states=self.states | {trash_state},
                           initial=self.start,
                           accepting=self.accepting,
                           transitions=util.freeze_map(transitions))
Ejemplo n.º 8
0
 def to_normal_form(self):
     transitions = self.transitions.dictionary.copy()
     prev = list(self._get_all_prev_states(self.start))
     if len(prev) > 0:
         start = State()
         transitions[(start, constants.EPSILON)] = {self.start}
     else:
         start = self.start
     if not self._accepting_states_in_normal_form():
         accept = State()
         for state in self.accepting:
             self._update_state(transitions,
                                (state, constants.EPSILON),
                                {accept})
     else:
         accept = next(iter(self.accepting))
     return self.__class__(states=self.states | {start, accept},
                           alphabet=self.alphabet,
                           transitions=util.freeze_map(transitions),
                           initial=start,
                           accepting={accept})