|
1 ''' |
|
2 Created on Jul 12, 2012 |
|
3 |
|
4 @author: daniel |
|
5 ''' |
|
6 |
|
7 from os.path import join |
|
8 from Queue import Queue |
|
9 from readData import create_accessible_dict,create_dependencies_dict,create_feature_dict |
|
10 from cPickle import load,dump |
|
11 |
|
12 class Dictionaries(object): |
|
13 ''' |
|
14 This class contains all info about name-> id mapping, etc. |
|
15 ''' |
|
16 def __init__(self): |
|
17 ''' |
|
18 Constructor |
|
19 ''' |
|
20 self.nameIdDict = {} |
|
21 self.idNameDict = {} |
|
22 self.featureIdDict={} |
|
23 self.maxNameId = 0 |
|
24 self.maxFeatureId = 0 |
|
25 self.featureDict = {} |
|
26 self.dependenciesDict = {} |
|
27 self.accessibleDict = {} |
|
28 self.expandedAccessibles = {} |
|
29 self.changed = True |
|
30 |
|
31 """ |
|
32 Init functions. Side Effect: nameIdDict, idNameDict, featureIdDict get filled! |
|
33 """ |
|
34 def init_featureDict(self,featureFile): |
|
35 self.featureDict,self.maxNameId,self.maxFeatureId = create_feature_dict(self.nameIdDict,self.idNameDict,self.maxNameId,self.featureIdDict,\ |
|
36 self.maxFeatureId,featureFile) |
|
37 def init_dependenciesDict(self,depFile): |
|
38 self.dependenciesDict = create_dependencies_dict(self.nameIdDict,depFile) |
|
39 def init_accessibleDict(self,accFile): |
|
40 self.accessibleDict,self.maxNameId = create_accessible_dict(self.nameIdDict,self.idNameDict,self.maxNameId,accFile) |
|
41 |
|
42 def init_all(self,inputFolder,featureFileName = 'mash_features',depFileName='mash_dependencies',accFileName = 'mash_accessibility'): |
|
43 featureFile = join(inputFolder,featureFileName) |
|
44 depFile = join(inputFolder,depFileName) |
|
45 accFile = join(inputFolder,accFileName) |
|
46 self.init_featureDict(featureFile) |
|
47 self.init_accessibleDict(accFile) |
|
48 self.init_dependenciesDict(depFile) |
|
49 self.expandedAccessibles = {} |
|
50 self.changed = True |
|
51 |
|
52 def get_name_id(self,name): |
|
53 """ |
|
54 Return the Id for a name. |
|
55 If it doesn't exist yet, a new entry is created. |
|
56 """ |
|
57 if self.nameIdDict.has_key(name): |
|
58 nameId = self.nameIdDict[name] |
|
59 else: |
|
60 self.nameIdDict[name] = self.maxNameId |
|
61 self.idNameDict[self.maxNameId] = name |
|
62 nameId = self.maxNameId |
|
63 self.maxNameId += 1 |
|
64 self.changed = True |
|
65 return nameId |
|
66 |
|
67 def add_feature(self,featureName): |
|
68 if not self.featureIdDict.has_key(featureName): |
|
69 self.featureIdDict[featureName] = self.maxFeatureId |
|
70 self.maxFeatureId += 1 |
|
71 self.changed = True |
|
72 |
|
73 def expand_accessibles(self,acc): |
|
74 accessibles = set(acc) |
|
75 unexpandedQueue = Queue() |
|
76 for a in acc: |
|
77 if self.expandedAccessibles.has_key(a): |
|
78 accessibles = accessibles.union(self.expandedAccessibles[a]) |
|
79 else: |
|
80 unexpandedQueue.put(a) |
|
81 while not unexpandedQueue.empty(): |
|
82 nextUnExp = unexpandedQueue.get() |
|
83 nextUnExpAcc = self.accessibleDict[nextUnExp] |
|
84 for a in nextUnExpAcc: |
|
85 if not a in accessibles: |
|
86 accessibles = accessibles.union([a]) |
|
87 if self.expandedAccessibles.has_key(a): |
|
88 accessibles = accessibles.union(self.expandedAccessibles[a]) |
|
89 else: |
|
90 unexpandedQueue.put(a) |
|
91 return list(accessibles) |
|
92 |
|
93 def parse_fact(self,line): |
|
94 """ |
|
95 Parses a single line, extracting accessibles, features, and dependencies. |
|
96 """ |
|
97 assert line.startswith('! ') |
|
98 line = line[2:] |
|
99 |
|
100 # line = name:accessibles;features;dependencies |
|
101 line = line.split(':') |
|
102 name = line[0].strip() |
|
103 nameId = self.get_name_id(name) |
|
104 |
|
105 line = line[1].split(';') |
|
106 # Accessible Ids |
|
107 unExpAcc = [self.nameIdDict[a.strip()] for a in line[0].split()] |
|
108 self.accessibleDict[nameId] = unExpAcc |
|
109 # Feature Ids |
|
110 featureNames = [f.strip() for f in line[1].split()] |
|
111 for fn in featureNames: |
|
112 self.add_feature(fn) |
|
113 self.featureDict[nameId] = [self.featureIdDict[fn] for fn in featureNames] |
|
114 self.dependenciesDict[nameId] = [self.nameIdDict[d.strip()] for d in line[2].split()] |
|
115 self.changed = True |
|
116 return nameId |
|
117 |
|
118 def parse_overwrite(self,line): |
|
119 """ |
|
120 Parses a single line, extracts the problemId and the Ids of the dependencies. |
|
121 """ |
|
122 assert line.startswith('p ') |
|
123 line = line[2:] |
|
124 |
|
125 # line = name:dependencies |
|
126 line = line.split(':') |
|
127 name = line[0].strip() |
|
128 nameId = self.get_name_id(name) |
|
129 |
|
130 dependencies = [self.nameIdDict[d.strip()] for d in line[1].split()] |
|
131 self.changed = True |
|
132 return nameId,dependencies |
|
133 |
|
134 def parse_problem(self,line): |
|
135 """ |
|
136 Parses a problem and returns the features and the accessibles. |
|
137 """ |
|
138 assert line.startswith('? ') |
|
139 line = line[2:] |
|
140 name = None |
|
141 |
|
142 # Check whether there is a problem name: |
|
143 tmp = line.split(':') |
|
144 if len(tmp) == 2: |
|
145 name = tmp[0].strip() |
|
146 line = tmp[1] |
|
147 |
|
148 # line = accessibles;features |
|
149 line = line.split(';') |
|
150 # Accessible Ids, expand and store the accessibles. |
|
151 unExpAcc = [self.nameIdDict[a.strip()] for a in line[0].split()] |
|
152 if len(self.expandedAccessibles.keys())>=100: |
|
153 self.expandedAccessibles = {} |
|
154 self.changed = True |
|
155 for accId in unExpAcc: |
|
156 if not self.expandedAccessibles.has_key(accId): |
|
157 accIdAcc = self.accessibleDict[accId] |
|
158 self.expandedAccessibles[accId] = self.expand_accessibles(accIdAcc) |
|
159 self.changed = True |
|
160 accessibles = self.expand_accessibles(unExpAcc) |
|
161 # Feature Ids |
|
162 featureNames = [f.strip() for f in line[1].split()] |
|
163 for fn in featureNames: |
|
164 self.add_feature(fn) |
|
165 features = [self.featureIdDict[fn] for fn in featureNames] |
|
166 return name,features,accessibles |
|
167 |
|
168 def save(self,fileName): |
|
169 if self.changed: |
|
170 dictsStream = open(fileName, 'wb') |
|
171 dump((self.accessibleDict,self.dependenciesDict,self.expandedAccessibles,self.featureDict,\ |
|
172 self.featureIdDict,self.idNameDict,self.maxFeatureId,self.maxNameId,self.nameIdDict),dictsStream) |
|
173 self.changed = False |
|
174 dictsStream.close() |
|
175 def load(self,fileName): |
|
176 dictsStream = open(fileName, 'rb') |
|
177 self.accessibleDict,self.dependenciesDict,self.expandedAccessibles,self.featureDict,\ |
|
178 self.featureIdDict,self.idNameDict,self.maxFeatureId,self.maxNameId,self.nameIdDict = load(dictsStream) |
|
179 self.changed = False |
|
180 dictsStream.close() |
|
181 |
|
182 |