Почему в OpenFST нет команды "выполнить", "принять" или "преобразовать"?
Я слышал много хорошего об OpenFST, но я борюсь за то, чтобы он работал. Я создаю автомат FST (fstcompile), который я хочу использовать в качестве акцептора, чтобы проверить, совпадает ли набор строк (очень похоже на регулярные выражения, но с преимуществами, предоставляемыми оптимизацией автоматов, предоставляемых OpenFST). И вот в чем дело:
Как проверить, принимает ли полученный автомат строку?
Я нашел предположение, что входная строка должна быть превращена в простой автомат и составлена из принимающего автомата, чтобы получить результат. Я нашел это очень громоздким и странным. Есть ли более простой способ (либо через строку cmd или Python/C++)?
0 ответов
Вот краткий пример того, как вы можете проверить, принимает ли автомат строку, используя обертку Python Open FST. В самом деле, вы должны превратить свой ввод в автомат, и Open FST даже не создает этот "автомат с линейной цепью" для вас! К счастью, этот процесс просто автоматизировать, как показано ниже:
def linear_fst(elements, automata_op, keep_isymbols=True, **kwargs):
"""Produce a linear automata."""
compiler = fst.Compiler(isymbols=automata_op.input_symbols().copy(),
acceptor=keep_isymbols,
keep_isymbols=keep_isymbols,
**kwargs)
for i, el in enumerate(elements):
print >> compiler, "{} {} {}".format(i, i+1, el)
print >> compiler, str(i+1)
return compiler.compile()
def apply_fst(elements, automata_op, is_project=True, **kwargs):
"""Compose a linear automata generated from `elements` with `automata_op`.
Args:
elements (list): ordered list of edge symbols for a linear automata.
automata_op (Fst): automata that will be applied.
is_project (bool, optional): whether to keep only the output labels.
kwargs:
Additional arguments to the compiler of the linear automata .
"""
linear_automata = linear_fst(elements, automata_op, **kwargs)
out = fst.compose(linear_automata, automata_op)
if is_project:
out.project(project_output=True)
return out
def accepted(output_apply):
"""Given the output of `apply_fst` for acceptor, return True is sting was accepted."""
return output_apply.num_states() != 0
Давайте определим простой Acceptor, который принимает только серии "ab":
f_ST = fst.SymbolTable()
f_ST.add_symbol("<eps>", 0)
f_ST.add_symbol("a", 1)
f_ST.add_symbol("b", 2)
compiler = fst.Compiler(isymbols=f_ST, osymbols=f_ST, keep_isymbols=True, keep_osymbols=True, acceptor=True)
print >> compiler, "0 1 a"
print >> compiler, "1 2 b"
print >> compiler, "2 0 <eps>"
print >> compiler, "2"
fsa_abs = compiler.compile()
fsa_abs
Теперь мы можем просто применить Acceptor, используя:
accepted(apply_fst(list("abab"), fsa_abs))
# True
accepted(apply_fst(list("ba"), fsa_abs))
# False
Чтобы увидеть, как использовать преобразователь, посмотрите на мой другой ответ