def levenshtein_automata(term, k): nfa = NFA((0, 0)) for i, c in enumerate(term): for e in range(k + 1): # Correct character nfa.add_transition((i, e), c, (i + 1, e)) if e < k: # Insertion nfa.add_transition((i, e), NFA.ANY, (i, e + 1)) # Deletion nfa.add_transition((i, e), NFA.EPSILON, (i + 1, e + 1)) # Substitution nfa.add_transition((i, e), NFA.ANY, (i + 1, e + 1)) for e in range(k + 1): if e < k: nfa.add_transition((len(term), e), NFA.ANY, (len(term), e + 1)) nfa.add_final_state((len(term), e)) return nfa
def levenshtein_automata(tokens, k): l = len(tokens) nfa = NFA(states=set(range((l + 1) * (k + 1)))) # Insert forward edges for i in range(l): for j in range(k + 1): nfa.add_transition((j * (l + 1)) + i, (j * (l + 1)) + i + 1, tokens[i]) # Insert lifting edges for row in range(k): for col in range(l + 1): nfa.add_transition((row * (l + 1)) + col, ((row + 1) * (l + 1)) + col, WILDCARD) # Insert Diagnol for row in range(k): for col in range(l): nfa.add_transition((row * (l + 1)) + col, ((row + 1) * (l + 1)) + col + 1, EPSILON) nfa.add_transition((row * (l + 1)) + col, ((row + 1) * (l + 1)) + col + 1, WILDCARD) nfa.set_start(0) for i in range(k + 1): nfa.make_final(i * (l + 1) + l) nfa.normalize() return nfa