1.任务
将无Epsilon的NFA转换为DFA。
对于有Epsilon的NFA可以先将其转换为无Epsilon的NFA,具体做法可以参考博客:
将Epsilon-NFA转换为NFA–python实现
2.主要思路
首先计算初始状态的Epsilon闭包,然后根据状态转换表更新,计算能到达的状态的Epsilon闭包,直到最终无新的状态产生。具体的思路参考[1]中的下图:
3.代码实现
"""Construct and output an equivalent DFA.
The input is guaranteed to be an Epsilon Free NFA."""
efnfa = parser.parse_fa()
state = {}
dfa = {}
dfa['states'] = []
dfa['start'] = "A"
dfa['alphabet'] = efnfa['alphabet']
dfa['final'] = []
dfa['delta'] = []
begin = efnfa['start']
alpha = efnfa['alphabet']
Repetitive
delta = efnfa['delta']
final = efnfa['final']
ot = []
h = [[begin]]
# 1. to get merge della,we use start_state's Epsilon closures (because there is no epsilon,start_state's Epsilon closures is itself )as a begin state in DFA
# 2. then transfer this state with different alphabet to get new states,and add these new states as new start states to DFA
# loop i and 2,utill the new states we get are repetitive in DFA states ,we do 3
# 3. in the end we get all states in DFA ,and we get all deltas,and we use new names to instead all of them
with different alphabet to get new_state
while len(h) > 0:
temp_state = h.pop()
# merge state to get new state and delta
if tuple(temp_state) not in dfa['states']:
dfa['states'].append(tuple(temp_state))
for a in alpha:
temp = []
for relation in delta:
s, c, t = relation
if c == a and s in temp_state:
if t not in temp:
temp.append(t)
dfa['delta'].append((tuple(temp_state), a, tuple(temp)))
h.append(temp)
# update final state
for f in final:
for s in dfa['states']:
if f in s or f == s:
dfa['final'].append(s)
# to get utimate DFA matrix
trans = {}
for i in range(65, 65 + len(dfa['states'])):
trans[dfa['states'][i - 65]] = chr(i)
def transfer(trans, p):
t = []
for i in p:
t.append(trans[i])
print(",".join(t))
transfer(trans, dfa['states'])
print(",".join(dfa['alphabet']))
print(",".join(dfa['start']))
transfer(trans, dfa['final'])
for hh in dfa['delta']:
s, c, t = hh
print("{},{},{}".format(trans[s], c, trans[t]))
print("end")