Skip to content

Commit

Permalink
Merge pull request #53 from rohaquinlop/issue-52
Browse files Browse the repository at this point in the history
refac(dfa): #52 Refactor product function
  • Loading branch information
rohaquinlop authored Dec 3, 2024
2 parents 3c974af + a03dfb1 commit 83ba50f
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 92 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ build/
.idea/
bazel-*
.pytest_cache/
.DS_store
12 changes: 6 additions & 6 deletions MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

110 changes: 24 additions & 86 deletions automathon/finite_automata/dfa.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from typing import (
Callable,
)
import itertools


@dataclass
Expand Down Expand Up @@ -183,103 +184,40 @@ def get_nfa(self):
tmp = dict()
for s, _q in transition.items():
# s : sigma
tmp[s] = ["".join(_q)]
tmp[s] = [_q]

delta[state] = tmp

return NFA(q, sigma, delta, initial_state, f)

def product(self, m: "DFA") -> "DFA":
"""Given a DFA m returns the product automaton"""
initial_state = str((self.initial_state, m.initial_state))
cross_product_states = {
(q_1, q_2) for q_1, q_2 in itertools.product(self.q, m.q)
}
q = {str(state) for state in cross_product_states}
sigma = self.sigma & m.sigma
f = {
str((q_1, q_2))
for (q_1, q_2) in cross_product_states
if q_1 in self.f and q_2 in m.f
}
delta: dict[str, dict[str, str]] = dict()
q: set[str] = set()
f: set[str] = set()
sigma: set[str] = self.sigma.intersection(m.sigma)

for state, transition in self.delta.items():
# i : str, j : dict(sigma, Q)
for state_m, transition_m in m.delta.items():
# stateM : str, transitionM : dict(sigma, Q)
sigma, q, f, delta = self.__process_states(
state,
state_m,
transition,
transition_m,
sigma,
q,
f,
m.f,
delta,
)

return DFA(
q, sigma, delta, str([self.initial_state, m.initial_state]), f
)
for q_1, q_2 in cross_product_states:
actual_state = str((q_1, q_2))
delta[actual_state] = dict()
common_sigma = filter(
lambda x: x in sigma,
set(self.delta[q_1].keys()) | set(m.delta[q_2].keys()),
)

def __process_states(
self,
state: str,
state_m: str,
transition: dict[str, str],
transition_m: dict[str, str],
sigma: set[str],
q: set[str],
f: set[str],
f_m: set[str],
delta: dict[str, dict[str, str]],
) -> tuple[set[str], set[str], set[str], dict[str, dict[str, str]]]:
for s in transition:
if s in transition_m:
sigma, q, f, delta = self.__process_transitions(
state,
state_m,
s,
transition,
transition_m,
sigma,
q,
f,
f_m,
delta,
for a in common_sigma:
delta[actual_state][a] = str(
(self.delta[q_1][a], m.delta[q_2][a])
)
return sigma, q, f, delta

def __process_transitions(
self,
state: str,
state_m: str,
s: str,
transition: dict[str, str],
transition_m: dict[str, str],
sigma: set[str],
q: set[str],
f: set[str],
f_m: set[str],
delta: dict[str, dict[str, str]],
) -> tuple[set[str], set[str], set[str], dict[str, dict[str, str]]]:
# sigma value in common
sigma.add(s)

tmp = str([state, state_m])
tmp1 = str([transition[s], transition_m[s]])
aux = dict()
aux[s] = tmp1

q.add(tmp)
q.add(tmp1)

if state in self.f and state_m in f_m:
f.add(tmp)

if transition[s] in self.f and transition_m[s] in f_m:
f.add(tmp1)

if tmp in delta:
delta[tmp].update(aux)
else:
delta[tmp] = aux

return sigma, q, f, delta
return DFA(q, sigma, delta, initial_state, f)

def union(self, m: "DFA") -> "DFA":
"""Given a DFA returns the union automaton"""
Expand Down

0 comments on commit 83ba50f

Please sign in to comment.