Commit 8fbb8218 authored by Vladimír Štill's avatar Vladimír Štill
Browse files

lib: Fix conversion to canonic automaton

In some cases, the states could be spuriously merged when converting to canonic
automaton. This is now fixed.
parent 13980904
Pipeline #66947 failed with stage
in 53 seconds
......@@ -312,26 +312,30 @@ class DFA:
return name
def canonize(self) -> DFA:
dfa = deepcopy(self)
remain = deepcopy(self.states)
characters = dfa.sorted_characters()
characters = self.sorted_characters()
state_map: Dict[State, State] = {}
i = 0
queue = deque([dfa.init])
i = 1
queue = deque([self.init])
while len(queue) > 0:
actual = queue.popleft()
if actual in remain:
remain.remove(actual)
if actual in state_map.keys():
continue
# alternatively, use self.bijective26(i) for base-26 alpha. names
state_map[actual] = State(str(i))
i += 1
for character in characters:
if (actual, character) in dfa.transition and dfa.transition[actual, character] in remain:
queue.append(dfa.transition[actual, character])
remain.remove(dfa.transition[actual, character])
# use self.bijective26(i) for base-26 alphabetic names
dfa.rename_state(actual, str(i + 1))
i += 1
return dfa
tgt = self.transition.get((actual, character))
if tgt is not None and tgt not in state_map.keys():
queue.append(tgt)
return DFA(set(state_map.values()),
deepcopy(self.characters),
{(state_map[st], ch): state_map[tgt]
for (st, ch), tgt in self.transition.items()},
state_map[self.init],
{state_map[st] for st in self.final})
# support function: decides from which of reachable states there is a way to final state
def terminating_states(self, states: Set[State], pred: Dict[State, Set[State]]) -> Set[State]:
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment