-
Notifications
You must be signed in to change notification settings - Fork 0
/
NFA_to_DFA.py
71 lines (56 loc) · 2.38 KB
/
NFA_to_DFA.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# regular function to check if A and B has common elements
def non_empty_intersection(A, B):
for b in B:
if b in A:
return True
return False
# given a delta function calculate a list of closures of every state
def calculate_closure(delta):
closure = [[] for i in range(len(delta))]
# Closure[i] = union(closure(a) : i -> a is an 'e' transition)
def Closure(i):
res = closure[i]
# Recursively, if closure[i] is already calculated
# in a previous step, then proceed
if not res:
A = delta[i]['e']
res = [i] + A
for a in A:
res = list(set(res + Closure(a)))
return res
for i in range(len(delta)):
closure[i] = Closure(i)
return closure
def NFA_to_DFA(N):
# extract the parameters of the NFA N
_delta, _sigma, _F = N['delta'], N['alphabet'], N['final']
_sigma.remove('e')
# calculate the closure of every state
closure = calculate_closure(_delta)
# initialize the DFA: delta function, alphabets, final states
delta, sigma, F = [], _sigma, []
state_index = [closure[0]] # state_index[j] = {states of the NFA N
j, n = 0, 1 # stored inside the j-th state of D}
# j: current state, n: #states seen so far
while j < n:
delta_j = {}
for a in sigma:
# delta(j, a): res = union of the closures of the states
# where q is taken to by the NFA under the symbol a
res = []
for q in state_index[j]:
for p in _delta[q][a]:
res = list(set(res + closure[p]))
# if res is already a state then,
# delta(j, a) = index of res in state_index
try: delta_j[a] = state_index.index(res)
# otherwise, add res to state index and update n
except ValueError:
state_index.append(res)
delta_j[a] = n
n = n + 1
delta.append(delta_j)
# determine if j is a final state
if non_empty_intersection(state_index[j], _F): F.append(j)
j = j + 1
return ({'delta': delta, 'alphabet': sigma, 'final': F}, state_index)