1 import sys, os, marshal
2 import copy
3
4 from VariableGenerator import *
5 from ..utility.helpers import get_attr_list_from_model, get_attrs_from_class
6 from networkx import *
7 from ..parsers.RuleParser import RuleParser
8
9
10
12
13 ___MODEL_STORAGE = "data/db.model"
14 ___INFO_STORAGE = "data/db.information"
15
16
17
18
20 """Generate the prolog code and write it to the given file."""
21
22 vg = unique_variable_generator
23
24
25
26 inf = open(self.___INFO_STORAGE)
27 a = marshal.load(inf)
28 inf.close()
29 inf = open(self.___MODEL_STORAGE)
30 m = marshal.load(inf)
31 inf.close()
32 FILE = open(aFilename, "w")
33
34
35
36 for className in a.iterkeys():
37 for o in a[className]:
38 first = True
39 FILE.write(className.lower() + "(")
40 keys = o.keys()
41 keys.sort()
42 for v in keys:
43 if not first:
44 FILE.write(", ")
45 FILE.write(o[v])
46 first = False
47 FILE.write(").\n")
48
49
50
51 for d in m['dependencyDefs']:
52
53
54 for classDef in m['classDefs']:
55 if classDef['name'] == d[0]:
56 client = classDef
57 if classDef['name'] == d[1]:
58 supplier = classDef
59
60
61 FILE.write("%s_%s(" % (supplier['name'].lower(), client['name'].lower()))
62 supplier_pred = supplier['name'].lower() + "("
63 client_pred = client['name'].lower() + "("
64
65
66 mapping = {}
67 first = True
68
69
70
71
72
73 attrs = supplier['attrs']
74 attrs.sort()
75 for attr in attrs:
76 v = vg.next()
77 mapping[attr] = v
78 if not first:
79 FILE.write(', ')
80 supplier_pred += ', '
81 else:
82 first = False
83 FILE.write(v)
84 supplier_pred += v
85
86
87
88
89 first = True
90 attrs = client['attrs']
91 attrs.sort()
92 for attr in attrs:
93
94 if attr in mapping:
95 v = mapping[attr]
96 else:
97 v = vg.next()
98
99 if not first:
100 client_pred += ', '
101 else:
102 first = False
103 FILE.write(', ')
104 FILE.write(v)
105 client_pred += v
106 FILE.write(") :- %s), %s).\n" % (supplier_pred, client_pred))
107
108
109 rules = RuleParser.getRulesFromStore()
110
111 predicateResolver = {}
112 alreadyInserted = []
113 nameResolver = {}
114
115 for rule in rules:
116 print >> sys.stderr, rule['subrules']
117 for subrule in rule['subrules']:
118 predicate = ""
119 ruleBody = ""
120
121 s = Signature(m, head=subrule['head'], target=subrule['target'])
122 bWrite = True
123 if s.predicate in alreadyInserted:
124 bWrite = False
125 alreadyInserted.append(s.predicate)
126 predicate += s.predicate.lower() + "("
127 ruleBody += " :- "
128 currentSig = Signature(m, predicate=s.path[0])
129 previousPredicate = currentSig.predicate
130 ruleBody += currentSig.predicate.lower() + "("
131 lookupVarName = {}
132
133 for i in range(0, currentSig.get_arg_count()):
134 vn = vg.next()
135 predicate += vn
136 ruleBody += vn
137 lookupVarName[currentSig.predicate + "." + currentSig.get_attribute_name(i)] = vn
138 predicate += ", "
139
140 if (i < currentSig.get_arg_count() - 1):
141 ruleBody += ", "
142
143 for node in s.path[1:]:
144 currentSig = Signature(m, predicate=node)
145 ruleBody += "), "
146 ruleBody += currentSig.predicate.lower() + "("
147 conName = self.__getConName(m, previousPredicate, currentSig.predicate)
148 print >> sys.stderr, "ConName: %s" % conName
149 conAttrName = lookupVarName[previousPredicate + "." + conName]
150 print >> sys.stderr, "ConAttrName: %s" % conAttrName
151 for i in range(0, currentSig.argCount):
152 currName = currentSig.get_attribute_name(i)
153 if conName == currName:
154 predicate += conAttrName
155 ruleBody += conAttrName
156 lookupVarName[currentSig.predicate + "." + currName] = conAttrName
157 else:
158 vn = vg.next()
159 predicate += vn
160 ruleBody += vn
161 lookupVarName[currentSig.predicate + "." + currName] = vn
162 if not (i == (currentSig.argCount - 1) and node == s.path[-1]):
163 predicate += ", "
164 if i < currentSig.argCount - 1:
165 ruleBody += ", "
166 previousPredicate = currentSig.predicate
167
168 predicate += ")"
169 ruleBody += ")."
170 predicateResolver[subrule['name']] = predicate
171
172
173 print >> sys.stderr, predicate + ruleBody
174 if bWrite:
175 FILE.write(predicate + ruleBody + "\n")
176
177
178 lookupVarName['HEAD'] = subrule['head']
179 lookupVarName['TARGET'] = subrule['target']
180 print >> sys.stderr, "nameRes: %s" % subrule['name']
181 nameResolver[subrule['name']] = lookupVarName
182
183
184 paramCount = len(rule['params'])
185 ruleText = ""
186 ruleText += rule['name']
187 if paramCount > 0:
188 ruleText += "("
189
190 paramResolver = {}
191 for i in range(0, paramCount):
192 nName = vg.next()
193 ruleText += nName
194 paramResolver[rule['params'][i]] = nName
195
196 if (i < paramCount - 1):
197 ruleText += ", "
198 if paramCount > 0:
199 ruleText += ")"
200
201 ruleText += " :- "
202 for key in predicateResolver.keys():
203 p = predicateResolver[key]
204 ruleText += p
205 if not key == predicateResolver.keys()[-1]:
206 ruleText += ", "
207 added = 0
208 for subrule in rule['subrules']:
209 for constraint in subrule['constraints']:
210 for entry in constraint['entries']:
211 if added == 0:
212 ruleText += ", "
213 else:
214 ruleText += " = "
215 added = -1
216 if entry['type'] == 'parameter':
217 p = paramResolver[entry['name']]
218 ruleText += p
219 added += 1
220 elif entry['type'] == 'reference':
221 r = entry['name']
222 s = r.split(".")
223 print >> sys.stderr, r
224 print >> sys.stderr, nameResolver
225 res = nameResolver[s[0]]
226 if res == None:
227 r = subrule['name'] + "." + entry['name']
228 s = r.split(".")
229 res = nameResolver[s[0]]
230 if s[1] == 'HEAD' or s[1] == 'TARGET':
231 s[1] = res[s[1]]
232 search = s[1]
233
234 for k in range(2, len(s)):
235 search += ("." + s[k])
236
237 try:
238 n = res[search]
239 ruleText += res[search]
240 except:
241 print >> sys.stderr, "Element not found: %s" % search
242
243 added += 1
244 elif entry['type'] == 'value':
245 ruleText += '"%s"' % entry['name']
246 added += 1
247
248
249
250 FILE.write(ruleText + ".\n")
251 FILE.close()
252
254 """Get the name of the connection from head to target"""
255 for dep in m['dependencyDefs']:
256 if dep[1] == head and dep[0] == target:
257 return dep[2]
258 return ""
259
260
261
262
263
264
265
266
267
268
269
270
271
272
274 """Create a signature for the given head -> target values."""
275
276 - def __init__(self, model, head=None, target=None, predicate=None):
277 """Create a new Signature from head to target"""
278 if predicate == None:
279 self.head = head
280 self.isSingle = False
281 self.target = target
282 self.model = model
283 self.__create_dep_graph()
284 self.namedArgumentList = {}
285 self.argumentList = []
286 self.predicate = head + "_" + target
287 self.path = self.__shortest_path()
288
289 pos = 0
290 for node in self.path:
291 attrs = get_attr_list_from_model(model, node)
292 for a in attrs:
293 self.argumentList.append(self.predicate + "." + a)
294 self.namedArgumentList[self.predicate + "." + a] = pos
295 pos += 1
296 self.argCount = pos
297 else:
298 self.predicate = predicate
299 self.isSingle = True
300 self.argumentList = copy.copy(get_attr_list_from_model(model, predicate))
301 self.argCount = len(self.argumentList)
302 self.namedArgumentList = {}
303 self.target = None
304 self.head = None
305 self.model = model
306
307 i = 0
308 for node in self.argumentList:
309 self.namedArgumentList["%s.%s" % (predicate, node)] = i
310 i += 1
311
312
314 """Create a graph with the dependencies of the model"""
315 self.g = Graph()
316 for cd in self.model['classDefs']:
317
318 self.g.add_node(cd['name'])
319
320 for e in self.model['dependencyDefs']:
321 self.g.add_edge(e[0], e[1])
322
323
324
325 return self.g
326
328 """Search the shortest path between head and target"""
329 return shortest_path(self.g, self.head, self.target)
330
332 """get the number of arguments of the predicate"""
333 return self.argCount
334
336 """Get the position of the named attribute"""
337 i = self.namedArgumentList[attrName]
338 if i == None:
339 i = self.namedArgumentList[self.predicate + "." + attrName]
340 if i == None:
341 return 0
342 return i
343
345 """Get the name of the attribute at pos"""
346 return self.argumentList[pos]
347