rdf.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. from modelverse_state import status
  2. import sys
  3. from collections import defaultdict
  4. import os
  5. import rdflib
  6. import json
  7. import cPickle as pickle
  8. # Work around Python 2 where a 'big integer' automatically becomes a long
  9. if sys.version > '3': # pragma: no cover
  10. integer_types = (int,)
  11. primitive_types = (int, float, str, bool)
  12. else: # pragma: no cover
  13. integer_types = (int, long)
  14. primitive_types = (int, long, float, str, bool, unicode)
  15. complex_primitives = frozenset(["if", "while", "assign", "call", "break", "continue", "return","resolve","access", "constant", "input", "output", "declare", "global"])
  16. def instance_to_string(value):
  17. return value["value"]
  18. def string_to_instance(value):
  19. return {'value': value}
  20. class ModelverseState(object):
  21. def __init__(self, bootfile = None):
  22. self.graph = rdflib.Graph()
  23. self.mv = rdflib.Namespace("http://modelverse.mv/#")
  24. self.graph.bind("MV", self.mv)
  25. self.free_id = 0
  26. self.root = self.parse(bootfile)
  27. def parse(self, filename):
  28. symbols = {}
  29. def resolve(symb):
  30. try:
  31. return int(symb)
  32. except:
  33. if symb[0] == "?":
  34. derefs = symb[1:].split("/")
  35. v, _ = self.read_dict(symbols["root"], "__hierarchy")
  36. for deref in derefs:
  37. v, _ = self.read_dict(v, deref)
  38. return v
  39. else:
  40. return symbols[symb]
  41. with open(filename, 'r') as f:
  42. for line in f:
  43. element_type, constructor = line.split(None, 1)
  44. name, values = constructor.split("(", 1)
  45. name = name.split()[0]
  46. values, _ = values.rsplit(")", 1)
  47. if element_type == "Node":
  48. if values == "":
  49. symbols[name], status = self.create_node()
  50. else:
  51. value = values
  52. if value in complex_primitives:
  53. value = string_to_instance(value)
  54. else:
  55. value = eval(value)
  56. symbols[name], status = self.create_nodevalue(value)
  57. elif element_type == "Edge":
  58. values = [v.split()[0] for v in values.split(",")]
  59. symbols[name], status = self.create_edge(resolve(values[0]), resolve(values[1]))
  60. else:
  61. raise Exception("Unknown element type: %s" % element_type)
  62. if status != 100:
  63. raise Exception("Failed to process line for reason %s: %s" % (status, line))
  64. return symbols["root"]
  65. def read_root(self):
  66. return (self.root, status.SUCCESS)
  67. def create_node(self):
  68. self.free_id += 1
  69. return (rdflib.URIRef("http://modelverse.mv/#%s" % self.free_id), status.SUCCESS)
  70. def create_edge(self, source, target):
  71. if not isinstance(source, rdflib.URIRef):
  72. return (None, status.FAIL_CE_SOURCE)
  73. if not isinstance(target, rdflib.URIRef):
  74. return (None, status.FAIL_CE_TARGET)
  75. self.free_id += 1
  76. edge = rdflib.URIRef("http://modelverse.mv/#%s" % self.free_id)
  77. self.graph.add((edge, self.mv.hasSource, source))
  78. self.graph.add((edge, self.mv.hasTarget, target))
  79. return (edge, status.SUCCESS)
  80. def is_valid_datavalue(self, value):
  81. if isinstance(value, dict):
  82. if "value" in value and value["value"] in complex_primitives:
  83. return True
  84. else:
  85. return False
  86. elif not isinstance(value, primitive_types):
  87. return False
  88. elif isinstance(value, integer_types) and not (-2**63 <= value <= 2**64 - 1):
  89. return False
  90. return True
  91. def create_nodevalue(self, value):
  92. if not self.is_valid_datavalue(value):
  93. return (None, status.FAIL_CNV_OOB)
  94. self.free_id += 1
  95. node = rdflib.URIRef("http://modelverse.mv/#%s" % self.free_id)
  96. self.graph.add((node, self.mv.hasValue, rdflib.Literal(json.dumps(value))))
  97. return (node, status.SUCCESS)
  98. def create_dict(self, source, data, destination):
  99. if not isinstance(source, rdflib.URIRef):
  100. return (None, status.FAIL_CDICT_SOURCE)
  101. if not isinstance(destination, rdflib.URIRef):
  102. return (None, status.FAIL_CDICT_TARGET)
  103. if not self.is_valid_datavalue(data):
  104. return (None, status.FAIL_CDICT_OOB)
  105. n = self.create_nodevalue(data)[0]
  106. e = self.create_edge(source, destination)[0]
  107. self.create_edge(e, n)
  108. return (None, status.SUCCESS)
  109. def read_value(self, node):
  110. if not isinstance(node, rdflib.URIRef):
  111. return (None, status.FAIL_RV_UNKNOWN)
  112. q = \
  113. """
  114. SELECT ?value
  115. WHERE {
  116. <%s> MV:hasValue ?value .
  117. }
  118. """ % node
  119. result = self.graph.query(q)
  120. if len(result) == 0:
  121. return (None, status.FAIL_RV_NO_VALUE)
  122. return (json.loads(list(result)[0][0]), status.SUCCESS)
  123. def read_outgoing(self, elem):
  124. if not isinstance(elem, rdflib.URIRef):
  125. return (None, status.FAIL_RO_UNKNOWN)
  126. result = self.graph.query(
  127. """
  128. SELECT ?link
  129. WHERE {
  130. ?link MV:hasSource <%s> .
  131. }
  132. """ % elem)
  133. return ([i[0] for i in result], status.SUCCESS)
  134. def read_incoming(self, elem):
  135. if not isinstance(elem, rdflib.URIRef):
  136. return (None, status.FAIL_RI_UNKNOWN)
  137. result = self.graph.query(
  138. """
  139. SELECT ?link
  140. WHERE {
  141. ?link MV:hasTarget <%s> .
  142. }
  143. """ % elem)
  144. return ([i[0] for i in result], status.SUCCESS)
  145. def read_edge(self, edge):
  146. result = self.graph.query(
  147. """
  148. SELECT ?source ?target
  149. WHERE {
  150. <%s> MV:hasSource ?source ;
  151. MV:hasTarget ?target .
  152. }
  153. """ % edge)
  154. if len(result) == 0:
  155. return ([None, None], status.FAIL_RE_UNKNOWN)
  156. else:
  157. return ([list(result)[0][0], list(result)[0][1]], status.SUCCESS)
  158. def read_dict(self, node, value):
  159. if not isinstance(node, rdflib.URIRef):
  160. return (None, status.FAIL_RDICT_UNKNOWN)
  161. if not self.is_valid_datavalue(value):
  162. return (None, status.FAIL_RDICT_OOB)
  163. q = """
  164. SELECT ?value_node
  165. WHERE {
  166. ?main_edge MV:hasSource <%s> ;
  167. MV:hasTarget ?value_node .
  168. ?attr_edge MV:hasSource ?main_edge ;
  169. MV:hasTarget ?attr_node .
  170. ?attr_node MV:hasValue '%s' .
  171. }
  172. """ % (node, json.dumps(value))
  173. result = self.graph.query(q)
  174. if len(result) == 0:
  175. return (None, status.FAIL_RDICT_NOT_FOUND)
  176. if len(result) != 1:
  177. print(value)
  178. raise Exception("Error!")
  179. return (list(result)[0][0], status.SUCCESS)
  180. def read_dict_keys(self, node):
  181. if not isinstance(node, rdflib.URIRef):
  182. return (None, status.FAIL_RDICT_UNKNOWN)
  183. result = self.graph.query(
  184. """
  185. SELECT ?key
  186. WHERE {
  187. ?main_edge MV:hasSource <%s> .
  188. ?attr_edge MV:hasSource ?main_edge ;
  189. MV:hasTarget ?key .
  190. }
  191. """ % node)
  192. return ([i[0] for i in result], status.SUCCESS)
  193. def read_dict_edge(self, node, value):
  194. if not isinstance(node, rdflib.URIRef):
  195. return (None, status.FAIL_RDICTE_UNKNOWN)
  196. if not self.is_valid_datavalue(value):
  197. return (None, status.FAIL_RDICTE_OOB)
  198. result = self.graph.query(
  199. """
  200. SELECT ?main_edge
  201. WHERE {
  202. ?main_edge MV:hasSource <%s> ;
  203. MV:hasTarget ?value_node .
  204. ?attr_edge MV:hasSource ?main_edge ;
  205. MV:hasTarget ?attr_node .
  206. ?attr_node MV:hasValue '%s' .
  207. }
  208. """ % (node, json.dumps(value)))
  209. if len(result) == 0:
  210. return (None, status.FAIL_RDICTE_NOT_FOUND)
  211. return (list(result)[0][0], status.SUCCESS)
  212. def read_dict_node(self, node, value_node):
  213. if not isinstance(node, rdflib.URIRef):
  214. return (None, status.FAIL_RDICTN_UNKNOWN)
  215. result = self.graph.query(
  216. """
  217. SELECT ?value_node
  218. WHERE {
  219. ?main_edge MV:hasSource <%s> ;
  220. MV:hasTarget ?value_node .
  221. ?attr_edge MV:hasSource ?main_edge ;
  222. MV:hasTarget <%s> .
  223. }
  224. """ % (node, value_node))
  225. if len(result) == 0:
  226. return (None, status.FAIL_RDICTN_NOT_FOUND)
  227. return (list(result)[0][0], status.SUCCESS)
  228. def read_dict_node_edge(self, node, value_node):
  229. if not isinstance(node, rdflib.URIRef):
  230. return (None, status.FAIL_RDICTNE_UNKNOWN)
  231. result = self.graph.query(
  232. """
  233. SELECT ?main_edge
  234. WHERE {
  235. ?main_edge MV:hasSource <%s> .
  236. ?attr_edge MV:hasSource ?main_edge ;
  237. MV:hasTarget <%s> .
  238. }
  239. """ % (node, value))
  240. if len(result) == 0:
  241. return (None, status.FAIL_RDICTNE_NOT_FOUND)
  242. return (list(result)[0][0], status.SUCCESS)
  243. def read_reverse_dict(self, node, value):
  244. if not isinstance(node, rdflib.URIRef):
  245. return (None, status.FAIL_RRDICT_UNKNOWN)
  246. if not self.is_valid_datavalue(value):
  247. return (None, status.FAIL_RRDICT_OOB)
  248. result = self.graph.query(
  249. """
  250. SELECT ?main_edge
  251. WHERE {
  252. ?main_edge MV:hasTarget <%s> .
  253. ?attr_edge MV:hasSource ?main_edge ;
  254. MV:hasTarget ?value_node .
  255. ?value_node MV:hasValue '%s' .
  256. }
  257. """ % (node, json.dumps(value)))
  258. return ([i[0] for i in result], status.SUCCESS)
  259. def delete_node(self, node):
  260. if node == self.root:
  261. return (None, status.FAIL_DN_UNKNOWN)
  262. if not isinstance(node, rdflib.URIRef):
  263. return (None, status.FAIL_DN_UNKNOWN)
  264. # Remove its value if it exists
  265. self.graph.remove((node, None, None))
  266. # Get all edges connecting this
  267. result = self.graph.query(
  268. """
  269. SELECT ?edge
  270. WHERE {
  271. { ?edge MV:hasTarget <%s> . }
  272. UNION
  273. { ?edge MV:hasSource <%s> . }
  274. }
  275. """ % (node, node))
  276. # ... and remove them
  277. print("Got related nodes: " + str(len(result)))
  278. for e in result:
  279. self.delete_edge(e[0])
  280. return (None, status.SUCCESS)
  281. def delete_edge(self, edge):
  282. if not isinstance(edge, rdflib.URIRef):
  283. return (None, status.FAIL_DN_UNKNOWN)
  284. # Remove its links
  285. self.graph.remove((edge, None, None))
  286. # Get all edges connecting this
  287. result = self.graph.query(
  288. """
  289. SELECT ?edge
  290. WHERE {
  291. { ?edge MV:hasTarget <%s> . }
  292. UNION
  293. { ?edge MV:hasSource <%s> . }
  294. }
  295. """ % (edge, edge))
  296. # ... and remove them
  297. for e in result:
  298. self.delete_edge(e[0])
  299. return (None, status.SUCCESS)
  300. def garbage_collect(self):
  301. pass
  302. def purge(self):
  303. pass