I am working on a programming project involving DFAs, and I've come across an error I can't seem to figure out how to bypass.
In this section of code:
from DFA import *
def DAWG():
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z']
f = open('lexicontest.txt', 'r')
dictionary = list(f)
accepts = []
for i in dictionary:
if len(i) >= 3:
accepts.append(i)
D = from_word_list(accepts, alphabet)
newStates = frozenset(D.mn_classes())
I get this error:
Traceback (most recent call last):
File "...\DAWG.py", line 31, in <module>
DAWG()
File "...\DAWG.py", line 19, in DAWG
newStates = frozenset(D.mn_classes())
TypeError: unhashable type: 'set'
This is because the method mn_classes() returns a list whose elements are sets. I am looking for a way to convert this list into a set, but I cannot do so right now because sets must be hashable. If anyone could give me advice on how to convert this list into a set, it would be greatly appreciated.
I am using a DFA library designed by Andrew Badr found here and here. This is the code for the method mn_classes():
def mn_classes(self):
"""Returns a partition of self.states into Myhill-Nerode equivalence classes."""
changed = True
classes = []
if self.accepts != []:
classes.append(self.accepts)
#nonaccepts = filter(lambda x: x not in self.accepts, self.states)
nonaccepts = [x for x in self.states if x not in self.accepts]
if nonaccepts != []:
classes.append(str(nonaccepts))
while changed:
changed = False
for cl in classes:
local_change = False
for alpha in self.alphabet:
next_class = None
new_class = []
for state in cl:
next = self.delta(state, alpha)
if next_class == None:
for c in classes:
if next in c:
next_class = c
elif next not in next_class:
new_class.append(state)
changed = True
local_change = True
if local_change == True:
old_class = []
for c in cl:
if c not in new_class:
old_class.append(c)
classes.remove(cl)
classes.append(old_class)
classes.append(new_class)
break
return classes
Your mn_class
code looks suspicious to me, especially classes.append(str(nonaccepts))
seems not to be a set in a list. Followint part is also dubious:
if next_class == None:
for c in classes:
if next in c:
next_class = c
Answering the quesition your asked, "If anyone could give me advice on how to convert this list into a set" modulo "mn_classes() returns a list whose elements are sets" you can use DAWG
approach, i.e. return list of frozensets in mn_classes
:
return map(frosenset, classes)