예제 #1
0
def fsa_test(test_string):
    # Defining FSA which accepts strings with even number of a's and b's
    fsa_states = ["q0", "q1", "q2", "q3"]
    fsa_alph = ["a", "b"]
    fsa_start = "q0"
    fsa_final = ["q0"]
    fsa_trans = {
        "q0": {
            "a": "q2",
            "b": "q1"
        },
        "q1": {
            "a": "q3",
            "b": "q0"
        },
        "q2": {
            "a": "q0",
            "b": "q3"
        },
        "q3": {
            "a": "q1",
            "b": "q2"
        },
    }

    test_fsa = FSA(fsa_states, fsa_alph, fsa_final, fsa_start, fsa_trans)

    if (test_fsa.accept_string(test_string)):
        print "Yay! this FSA does accept the string  : " + test_string
    else:
        print "NO! this FSA doesnt accept the string : " + test_string
예제 #2
0
    def get_automaton(self, chat_id):
        """
        Получает конечный автомат для конкретного пользователя
        Находим в словаре (в режиме POLLING) или загружаем из pickle (в режиме WEBHOOK) автомат по ID пользователя
        Если сохраненного автомата нет, создаем его и помещаем в хранилище
        """
        if self.mode == BotMode.POLLING:
            if chat_id in self.chats:
                automaton = self.chats[chat_id]
            else:
                automaton = FSA(chat_id, self.command_tree, self.bot,
                                self.logger)
                self.chats[chat_id] = automaton
        else:
            assert self.fsa_serializer != None, "Property 'fsa_serializer' must be set in 'webhook' mode"
            automaton = FSA(chat_id, self.command_tree, self.bot, self.logger)
            automaton_loaded = self.fsa_serializer.load_fsa(chat_id)
            if automaton_loaded:
                filtered_fields = {
                    key: value
                    for key, value in automaton_loaded.__dict__.items()
                    if key not in FSA.unstored_fields
                }
                automaton.__dict__.update(filtered_fields)

        return automaton
예제 #3
0
def generate_transactions(version):
    fsas = []
    insert_fn = insert_v1 if int(version) == 1 else insert_v2
    engine = create_engine(config["db_connect"])
    conn = engine.connect()
    for idx in range(config['fsa1_count']):
        fsas.append(FSA(idx, lambda x: insert_fn(x, conn), 1, config['fsa1']))
    for idx in range(config['fsa2_count']):
        fsas.append(FSA(config['fsa1_count'] + idx, lambda x: insert_fn(x, conn), 1, config['fsa2']))
    idx = config['fsa1_count'] + config['fsa2_count']
    while len(fsas) > 0:
        fsa = random.choice(fsas)
        fsa.step()
        if fsa.done():
            log.debug(f"FSA({fsa.fsa_id}) done")
            fsas.remove(fsa)
        if random.uniform(0, 1) < config['fsa1_birthrate']:
            log.debug("new fsa1")
            fsas.append(FSA(idx, lambda x: insert_fn(x, conn), 1, config['fsa1']))
            idx += 1
        if random.uniform(0, 1) < config['fsa2_birthrate']:
            log.debug("new fsa2")
            fsas.append(FSA(idx, lambda x: insert_fn(x, conn), 2, config['fsa2']))
            idx += 1
        log.debug(f"counts {np.unique([f.fsa_type for f in fsas], return_counts=True)}")
예제 #4
0
 def parse_table(name, table, subsets):
     lines = table.split('\n')
     if len(lines) < 4:
         raise ValueError,\
         "Rule %s has too few lines to be an FSA table." % name
     pairs1 = lines[1].strip().split()
     pairs2 = lines[2].strip().split()
     if len(pairs1) != len(pairs2):
         raise ValueError,\
         "Rule %s has pair definitions that don't line up." % name
     pairs = [KimmoPair(p1, p2) for p1, p2 in zip(pairs1, pairs2)]
     finals = []
     fsa = FSA()
     for line in lines[3:]:
         line = line.strip()
         if not line: continue
         groups = re.match(r'(\w+)(\.|:)\s*(.*)', line)
         if groups is None:
             raise ValueError,\
             "Can't parse this line of the state table for rule %s:\n%s"\
             % (name, line)
         state, char, morestates = groups.groups()
         if fsa.start() == 0: fsa.set_start(state)
         if char == ':': finals.append(state)
         fsa.add_state(state)
         morestates = morestates.split()
         if len(morestates) != len(pairs):
             raise ValueError,\
             "Rule %s has a row of the wrong length:\n%s\ngot %d items, should be %d"\
             % (name, line, len(morestates), len(pairs))
         for pair, nextstate in zip(pairs, morestates):
             fsa.insert_safe(state, pair, nextstate)
     fsa.set_final(finals)
     return KimmoFSARule(name, fsa, subsets)
 def from_text(text):
     fsa = FSA([], {}, 'Begin', ['End'])
     state = 'Begin'
     for line in text.split('\n'):
         line = line.strip()
         if not line or line.startswith(';'): continue
         if line[-1] == ':':
             state = line[:-1]
         else:
             if line.split()[0].endswith(':'):
                 parts = line.split()
                 name = parts[0][:-1]
                 next_states = parts[1:]
                 for next in next_states:
                     fsa.insert_safe(name, None, next)
             elif len(line.split()) > 2:
                 # this is a lexicon entry
                 word, next, features = line.split(None, 2)
                 if word.startswith('"') or\
                 word.startswith("'") and word.endswith("'"):
                     word = eval(word)
                 if features:
                     if features == 'None': features = None
                     elif features[0] in '\'"{':
                         features = YAMLwrapper(features)
                 fsa.insert_safe(state, (word, features), next)
             elif len(line.split()) == 2:
                 word, next = line.split()
                 features = ''
                 if word == "''":
                     word = ''
                 fsa.insert_safe(state, (word, features), next)
             else:
                 print "Ignoring line in morphology: %r" % line
     return KimmoMorphology(fsa)
예제 #6
0
    def _parse_context(self, tokens, i, reverse):
        (j, tree) = self._parse_list(tokens, i)
        if j == i: return (i, None)

        sigma = set()
        self._collect_alphabet(tree, sigma)
        fsa = FSA(sigma)
        final_state = self._build_fsa(fsa, fsa.start(), tree, reverse)
        fsa.set_final([final_state])
        #fsa.pp()
        dfa = fsa.dfa()
        #dfa.pp()
        dfa.prune()
        #dfa.pp()
        return (j, dfa)
예제 #7
0
	def __create_key_fsa(self, dict):
		"""
		Create an FSA from the keys in a map.
		"""
		def add_key(fsa, key):
			def add_new_transition(fsa, start, label, end, tag):
				for x in fsa.transitions_from(start):
					if x == (label, end, tag):
						return False
				fsa.add_transition(start, label, end, tag)

			for j in range(len(key), -1, -1):
				if j > 0 and fsa.has_state(key[:j]):
					break
			s = key + self._separator
			for i in range(j, len(s)):
				c = s[i]
				if i == len(s) - 1: #last step
					end = fsa.get_initial()
					tag = key
				else:
					end = s[:i + 1]
					tag = None
				add_new_transition(fsa, s[:i], c, end, tag)
		fsa = FSA()
		fsa.add_state("")
		fsa.set_initial("")
		fsa.set_final("")
		for k, v in dict.items():
			if not isinstance(v, list):
				raise TypeError(v)
			add_key(fsa, k)
		return fsa
예제 #8
0
 def from_text(text):
     fsa = FSA([], {}, 'Begin', ['End'])
     state = 'Begin'
     for line in text.split('\n'):
         line = line.strip()
         if not line or startswith(line, ';'): continue
         if line[-1] == ':':
             state = line[:-1]
         else:
             if endswith(line.split()[0], ':'):
                 parts = line.split()
                 name = parts[0][:-1]
                 next_states = parts[1:]
                 for next in next_states:
                     fsa.insert_safe(name, None, next)
             elif len(line.split()) > 2:
                 # this is a lexicon entry
                 word, next, features = line.split(None, 2)
                 if startswith(word, '"') or\
                 startswith(word, "'") and endswith(word, "'"):
                     word = eval(word)
                 if features:
                     if features == 'None': features = None
                     elif features[0] in '\'"{':
                         features = YAMLwrapper(features)
                 fsa.insert_safe(state, (word, features), next)
             elif len(line.split()) == 2:
                 word, next = line.split()
                 features = ''
                 if word == "''":
                     word = ''
                 fsa.insert_safe(state, (word, features), next)
             else:
                 print "Ignoring line in morphology: %r" % line
     return KimmoMorphology(fsa)
예제 #9
0
	def compile(self, force = False):
		"""
		Compile the set of rules into a Deterministic State Automaton (DFSA).

		If the grammar has never been compiled or it has been modified after last compilation, it will be translated into an FSA.
		The result will be kept available until the rules are modified or the grammar reset.

		The algorithm calls recursively the L{bnf.NormalExpression.insert_transitions} method.

		If the C{force} flag is off and the grammar was already compiled and was not updated, the old result is taken with no recompiling.

		@see: L{Finite State Automaton<fsa.FSA>}
		@param force: Recompile grammar even if it has already been validated and compiled.
		@type force: bool
		@raise GrammarError: If anomalies are encountered while precompiling.
		@return: A parser for the grammar.
		@rtype: fsa.Parser

		"""

		if force or not self.__valid and self.__compiled is None:
			self.__valid = False

			self.browse()
			nfa = FSA()
			initial = nfa.add_state()
			nfa.set_initial(initial)
			final = nfa.add_state()
			nfa.set_final(final)

			s = self.__rules[self.start]
			s.insert_transitions(self, nfa, initial, final, ())
			#rewriting to save memory
			nfa = nfa.reduced()
			nfa = nfa.minimized()
			self.__compiled = _GrammarParser(nfa)
			self.__valid = True
		return self.__compiled
예제 #10
0
    def _parse_context(self, tokens, i, reverse):
        (j, tree) = self._parse_list(tokens, i)
        if j == i: return (i, None)

        sigma = set()
        self._collect_alphabet(tree, sigma)
        fsa = FSA(sigma)
        final_state = self._build_fsa(fsa, fsa.start(), tree, reverse)
        fsa.set_final([final_state])
        #fsa.pp()
        dfa = fsa.dfa()
        #dfa.pp()
        dfa.prune()
        #dfa.pp()
        return (j, dfa)
예제 #11
0
 def parse_table(name, table, subsets):
     lines = table.split('\n')
     if len(lines) < 4:
         raise ValueError,\
         "Rule %s has too few lines to be an FSA table." % name
     pairs1 = lines[1].strip().split()
     pairs2 = lines[2].strip().split()
     if len(pairs1) != len(pairs2):
         raise ValueError,\
         "Rule %s has pair definitions that don't line up." % name
     pairs = [KimmoPair(p1, p2) for p1, p2 in zip(pairs1, pairs2)]
     finals = []
     fsa = FSA()
     for line in lines[3:]:
         line = line.strip()
         if not line: continue
         groups = re.match(r'(\w+)(\.|:)\s*(.*)', line)
         if groups is None:
             raise ValueError,\
             "Can't parse this line of the state table for rule %s:\n%s"\
             % (name, line)
         state, char, morestates = groups.groups()
         if fsa.start() == 0: fsa.set_start(state)
         if char == ':': finals.append(state)
         fsa.add_state(state)
         morestates = morestates.split()
         if len(morestates) != len(pairs):
             raise ValueError,\
             "Rule %s has a row of the wrong length:\n%s\ngot %d items, should be %d"\
             % (name, line, len(morestates), len(pairs))
         for pair, nextstate in zip(pairs, morestates):
             fsa.insert_safe(state, pair, nextstate)
     fsa.set_final(finals)
     return KimmoFSARule(name, fsa, subsets)
예제 #12
0
    def from_dfa_dict(name, states, subsets):
        fsa = FSA()
        pairs = set([KimmoPair.make('@')])
        for (statename, trans) in states.items():
            for label in trans:
                if label != 'others':
                    pairs.add(KimmoPair.make(label))
        for (statename, trans) in states.items():
            parts = statename.split()
            source = parts[-1]
            if not parts[0].startswith('rej'):
                fsa.add_final(source)

            if fsa.start() == 0 and source in ['begin', 'Begin', '1', 1]:
                fsa.set_start(source)
            if source in ['start', 'Start']:
                fsa.set_start(source)

            used_pairs = set()
            for label in trans:
                if label != 'others':
                    used_pairs.add(KimmoPair.make(label))
            for label, target in trans.items():
                if label.lower() == 'others':
                    fsa.insert_safe(source, KimmoPair.make('@'), target)
                    for pair in pairs.difference(used_pairs):
                        fsa.insert_safe(source, pair, target)
                else:
                    fsa.insert_safe(source, KimmoPair.make(label), target)
        return KimmoFSARule(name, fsa, subsets)
예제 #13
0
 def from_dfa_dict(name, states, subsets):
     fsa = FSA()
     pairs = set([KimmoPair.make('@')])
     for (statename, trans) in states.items():
         for label in trans:
             if label != 'others':
                 pairs.add(KimmoPair.make(label))
     for (statename, trans) in states.items():
         parts = statename.split()
         source = parts[-1]
         if not parts[0].startswith('rej'):
             fsa.add_final(source)
         
         if fsa.start() == 0 and source in ['begin', 'Begin', '1', 1]:
             fsa.set_start(source)
         if source in ['start', 'Start']:
             fsa.set_start(source)
             
         used_pairs = set()
         for label in trans:
             if label != 'others':
                 used_pairs.add(KimmoPair.make(label))
         for label, target in trans.items():
             if label.lower() == 'others':
                 fsa.insert_safe(source, KimmoPair.make('@'), target)
                 for pair in pairs.difference(used_pairs):
                     fsa.insert_safe(source, pair, target)
             else:
                 fsa.insert_safe(source, KimmoPair.make(label), target)
     return KimmoFSARule(name, fsa, subsets)
예제 #14
0
파일: test_fsa.py 프로젝트: ethanfry/BPI
 def setUp(self):
     self.fsa = FSA()
예제 #15
0
파일: test_fsa.py 프로젝트: ethanfry/BPI
class FSATestCase(unittest.TestCase):
    def setUp(self):
        self.fsa = FSA()

    def test_integer_input_raises_exception(self):
        with self.assertRaises(Exception):
            self.fsa.transition(0)

    def test_not_zero_or_1_inpute_raises_exception(self):
        with self.assertRaises(Exception):
            self.fsa.transition('222')

    def test_0_0_0(self):
        self.fsa.transition('0')
        self.assertEqual(0, self.fsa.state)

    def test_0_1_1(self):
        self.fsa.transition('1')
        self.assertEqual(1, self.fsa.state)

    def test_1_0_2(self):
        self.fsa.state = 1
        self.fsa.transition('0')
        self.assertEqual(2, self.fsa.state)

    def test_1_1_0(self):
        self.fsa.state = 1
        self.fsa.transition('1')
        self.assertEqual(0, self.fsa.state)

    def test_2_0_1(self):
        self.fsa.state = 2
        self.fsa.transition('0')
        self.assertEqual(1, self.fsa.state)

    def test_2_1_2(self):
        self.fsa.state = 2
        self.fsa.transition('1')
        self.assertEqual(2, self.fsa.state)