Exemple #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)
Exemple #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})
Exemple #3
0
 def _empty_machine(self):
     state = State()
     return self.__class__(states={state},
                           alphabet=self.__alphabet,
                           transitions=FrozenDict({}),
                           accepting=set(),
                           initial=state)
Exemple #4
0
 def union(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))
     start = State()
     accept = State()
     transitions[(start, constants.EPSILON)] = {a.start, b.start}
     self._update_state(transitions,
                        (a_accept, constants.EPSILON),
                        {accept})
     self._update_state(transitions,
                        (b_accept, constants.EPSILON),
                        {accept})
     return self.__class__(states=a.states | b.states | {start, accept},
                           alphabet=a.alphabet | b.alphabet,
                           transitions=util.freeze_map(transitions),
                           initial=start,
                           accepting={accept})
Exemple #5
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})
Exemple #6
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()
Exemple #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))
Exemple #8
0
    def setUp(self):

        self.s1 = State('state1', 0)
        self.s2 = State('state2', 0)
        self.s3 = State('state3', 1)

        self.s1.add_function(self.s2, 1)
        self.s1.add_function(self.s1, 0)

        self.s2.add_function(self.s3, 1)
        self.s2.add_function(self.s2, 0)

        self.s3.add_function(self.s1, 1)
        self.s3.add_function(self.s3, 0)
Exemple #9
0
class TestState(unittest.TestCase):
    def setUp(self):

        self.s1 = State('state1', 0)
        self.s2 = State('state2', 0)
        self.s3 = State('state3', 1)

        self.s1.add_function(self.s2, 1)
        self.s1.add_function(self.s1, 0)

        self.s2.add_function(self.s3, 1)
        self.s2.add_function(self.s2, 0)

        self.s3.add_function(self.s1, 1)
        self.s3.add_function(self.s3, 0)

    def test_reach(self):

        self.assertEqual(self.s1.direct_reach, {self.s1, self.s2})
        self.assertEqual(self.s2.direct_reach, {self.s2, self.s3})
        self.assertEqual(self.s3.direct_reach, {self.s1, self.s3})

    def test_lt(self):

        self.assertTrue(self.s1 < self.s2)
        self.assertTrue(self.s2 < self.s3)
        self.assertTrue(self.s1 < 1)

    def test_eq(self):

        self.assertFalse(self.s1 == self.s2)
        self.assertFalse(self.s2 == self.s3)

        self.assertFalse(self.s1 == 1)
        self.assertTrue(self.s1 == self.s1)

        s2 = self.s1
        self.assertTrue(self.s1 == s2)

    def test_forward(self):

        self.assertEqual(self.s1.clean_forward(0), self.s1)
        self.assertEqual(self.s1.clean_forward(1), self.s2)

        self.s1.add_function(self.s3, 0)

        self.assertEqual(self.s1.forward(0), {self.s1, self.s3})
        self.assertEqual(self.s1.clean_forward(0), {self.s1, self.s3})

    def test_indirect_reach(self):

        self.assertEqual(self.s1.indirect_reach, {self.s1, self.s2, self.s3})

    def test_accepted(self):

        self.assertTrue(self.s3.accepted)
        self.assertFalse(self.s1.accepted)

    def test_contains(self):

        self.assertTrue(1 in self.s1)
        self.assertFalse(12 in self.s1)
Exemple #10
0
k = compile_regex('a|b')
assert not k.run(''), k.dump()
assert k.run('a'), k.dump()
assert k.run('b'), k.dump()
assert not k.run('ba'), k.dump()
assert not k.run('ab'), k.dump()
assert not k.run('aa'), k.dump()
assert not k.run('bb'), k.dump()


# Test loop detection

from automata.state import State
from automata.fsm.fsm import NeFSM
s = State()
k = NeFSM(states={s}, alphabet={'a'}, transitions={(s, ''): {s}}, initial=s, accepting={})
assert not k.run('a'), k.dump()


regex = '(a|b)*'
#print_tree(parse_regex(regex))
k = compile_regex(regex)
#k.render()


k = compile_regex('a')
l = k.to_dfsm()
assert NeFSM.from_dfsm(l).to_regex() == 'a', NeFSM.from_dfsm(l).to_regex()

k = compile_regex('abc')