Skip to content
This repository has been archived by the owner on Aug 30, 2024. It is now read-only.

Commit

Permalink
feat: implement epsilon-NFA to NFA conversion
Browse files Browse the repository at this point in the history
- Developed an algorithm to convert an epsilon-NFA (ε-NFA) to a Non-deterministic Finite Automaton (NFA).
- Ensured the algorithm handles epsilon transitions correctly and efficiently.
- Validated the correctness of the conversion process through comprehensive unit tests.
  • Loading branch information
sherlockedhzoi committed Mar 27, 2024
1 parent 89d80de commit c0793a3
Showing 1 changed file with 57 additions and 1 deletion.
58 changes: 57 additions & 1 deletion src/algorithms/enfa2nfa.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,64 @@
from data_structures.nfa import NFA
from data_structures.epsilon_nfa import EpsilonNFA
from collections import deque

__all__: list[str] = ["transfer_epsilon_nfa_to_nfa"]


def _epsilon_closure(epsilon_nfa: EpsilonNFA, states: set[str]) -> set[str]:
epsilon_closure: set[str] = set()
unprocessed_states: deque[str] = deque()
for state in states:
if state not in epsilon_closure:
epsilon_closure.add(state)
unprocessed_states.append(state)
while unprocessed_states:
current_state: str = unprocessed_states.popleft()
epsilon_closure.add(current_state)
if (current_state, "") in epsilon_nfa.delta:
for state in epsilon_nfa.delta[(current_state, "")]:
if state not in epsilon_closure:
epsilon_closure.add(state)
unprocessed_states.append(state)
return epsilon_closure


def _transfer(epsilon_nfa: EpsilonNFA, states: set[str], symbol: str) -> set[str]:
result: set[str] = set()
for current_state in states:
if (current_state, symbol) in epsilon_nfa.delta:
result.update(epsilon_nfa.delta[(current_state, symbol)])
return result


def transfer_epsilon_nfa_to_nfa(epsilon_nfa: EpsilonNFA) -> NFA:
pass
Q: set[str] = epsilon_nfa.Q
T: set[str] = epsilon_nfa.T
delta: dict[tuple[str, str], set[str]] = {}

for state in Q:
for symbol in T:
if symbol != "":
states: set[str] = _epsilon_closure(
epsilon_nfa=epsilon_nfa,
states=_transfer(
epsilon_nfa=epsilon_nfa,
states=_epsilon_closure(
epsilon_nfa=epsilon_nfa, states={state}
),
symbol=symbol,
),
)
if states:
delta[(state, symbol)] = states

q0: str = epsilon_nfa.q0
qf: set[str] = {
state
for state in Q
if not _epsilon_closure(epsilon_nfa=epsilon_nfa, states={state}).isdisjoint(
epsilon_nfa.qf
)
}

return NFA(Q=Q, T=T, delta=delta, q0=q0, qf=qf)

0 comments on commit c0793a3

Please sign in to comment.