Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(renumber): add prefix to NFA.renumber #55

Merged
merged 1 commit into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ dist/
automathon.egg-info/
workspace.code*
.eggs/
automathon/__pycache__/
automathon/finiteAutomata/__pycache__/
tests/__pycache__/
automathon/errors/__pycache__/
__pycache__/
build/
.idea/
bazel-*
Expand Down
60 changes: 26 additions & 34 deletions automathon/finite_automata/nfa.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,13 +377,11 @@ def __get_e_closure(
for st in self.delta[q][""]:
if st not in visited:
visited.append(st)
ans.extend(
[
k
for k in self.__get_e_closure(st, visited)
if k not in ans
]
)
rohaquinlop marked this conversation as resolved.
Show resolved Hide resolved
ans.extend([
k
for k in self.__get_e_closure(st, visited)
if k not in ans
])
return ans

def __ret_get_new_transitions(
Expand Down Expand Up @@ -493,9 +491,9 @@ def __extend_local_transitions(
) -> None:
if tmp and s in local_transitions:
# avoid add repeated values
local_transitions[s].extend(
[k for k in tmp if k not in local_transitions[s]]
)
local_transitions[s].extend([
k for k in tmp if k not in local_transitions[s]
])
elif tmp:
local_transitions[s] = list(tmp)

Expand All @@ -522,39 +520,33 @@ def minimize(self) -> "NFA":
local_nfa.renumber()
return local_nfa

def renumber(self) -> None:
"""Change the name of the states, renumbering each of the labels"""
idx = 0
new_tags = dict()
def renumber(self, prefix="q") -> None:
"""
Change the name of the states, renumbering each of the labels

# New values
q = set()
delta = dict()
f = set()
Parameters
----------
prefix : str
Prefix for the renumbered state names.
"""

# Setting the new label for each state
tmp_q = list(self.q)
tmp_q.sort()
delta = dict()

for _q in tmp_q:
new_tags[_q] = str(idx)
q.add(str(idx))
idx += 1
# Create new mappings for states
new_tags = {state: f"{prefix}{idx}" for idx, state in enumerate(self.q)}

# Update states
q = {new_tags[state] for state in self.q}
f = {new_tags[state] for state in self.f}
initial_state = new_tags[self.initial_state]

# Changing the labels for the final states
for _f in self.f:
f.add(new_tags[_f])

# Update transitions
for _q in self.delta:
delta[new_tags[_q]] = dict()
for s in self.delta[_q]:
nxt_states = list()
for nxt_state in self.delta[_q][s]:
nxt_states.append(new_tags[nxt_state])

delta[new_tags[_q]][s] = set(nxt_states)
delta[new_tags[_q]][s] = {
new_tags[nxt_state] for nxt_state in self.delta[_q][s]
}

self.q, self.f, self.delta, self.initial_state = (
q,
Expand Down
37 changes: 20 additions & 17 deletions tests/test_nfa.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,27 +178,30 @@ def test_intersection(self):
self.assertFalse(intersection_result.accept("abbbbbb"))

def test_renumber(self):
from automathon import DFA

automata_1 = NFA(
q={"3", "1", "2", "0"},
q = {"alpha", "beta", "gamma", "sigma"}
delta = {
"sigma": {"A": {"beta"}},
"beta": {"B": {"gamma"}, "": {"gamma"}},
"gamma": {"C": {"alpha"}},
}
initial_state = "sigma"
f = {"alpha"}

automaton = NFA(
q=q,
sigma={"", "A", "B", "C"},
delta={
"0": {"A": {"1"}},
"1": {"B": {"2"}, "": {"2"}},
"2": {"C": {"3"}},
},
initial_state="0",
f={"3"},
delta=delta,
initial_state=initial_state,
f=f,
)

automata_2: NFA = automata_1.remove_epsilon_transitions()
automata_3: DFA = automata_2.get_dfa()
automata_4: NFA = automata_3.get_nfa()

automata_4.renumber()
automaton.renumber(prefix="q")

self.assertTrue(automata_4.is_valid())
self.assertTrue(automaton.is_valid())
self.assertSetEqual(automaton.q, {"q0", "q1", "q2", "q3"})
self.assertNotEqual(automaton.f, f)
self.assertNotEqual(automaton.initial_state, initial_state)
self.assertNotEqual(automaton.delta, delta)


if __name__ == "__main__":
Expand Down
Loading