Переглянути джерело

Fixed some more RDF problems

Yentl Van Tendeloo 9 роки тому
батько
коміт
ecca28fab8
1 змінених файлів з 83 додано та 94 видалено
  1. 83 94
      state/modelverse_state/rdf.py

+ 83 - 94
state/modelverse_state/rdf.py

@@ -27,80 +27,68 @@ class ModelverseState(object):
         self.graph = rdflib.Graph()
         self.mv = rdflib.Namespace("http://modelverse.mv/#")
         self.graph.bind("MV", self.mv)
+        self.free_id = 0
 
-        self.parse(bootfile)
-        self.root = 0
-
-        self.GC = True
-        self.to_delete = set()
+        self.root = self.parse(bootfile)
 
     def parse(self, filename):
-        triplestore = filename + ".nt"
-        try:
-            if os.path.getmtime(triplestore) > os.path.getmtime(filename):
-                self.graph.parse(triplestore, format="nt")
-            else:
-                raise Exception("Invalid triplestore")
-        except Exception as e:
-            # We have to parse the file and create the pickle
-            symbols = {}
-
-            def resolve(symb):
-                try:
-                    return int(symb)
-                except:
-                    if symb[0] == "?":
-                        derefs = symb[1:].split("/")
-                        v, _ = self.read_dict(symbols["root"], "__hierarchy")
-                        for deref in derefs:
-                            v, _ = self.read_dict(v, deref)
-                        return v
+        symbols = {}
+
+        def resolve(symb):
+            try:
+                return int(symb)
+            except:
+                if symb[0] == "?":
+                    derefs = symb[1:].split("/")
+                    v, _ = self.read_dict(symbols["root"], "__hierarchy")
+                    for deref in derefs:
+                        v, _ = self.read_dict(v, deref)
+                    return v
+                else:
+                    return symbols[symb]
+
+        with open(filename, 'r') as f:
+            for line in f:
+                element_type, constructor = line.split(None, 1)
+                name, values = constructor.split("(", 1)
+                name = name.split()[0]
+                values, _ = values.rsplit(")", 1)
+
+                if element_type == "Node":
+                    if values == "":
+                        symbols[name], status = self.create_node()
                     else:
-                        return symbols[symb]
-
-            with open(filename, 'r') as f:
-                for line in f:
-                    element_type, constructor = line.split(None, 1)
-                    name, values = constructor.split("(", 1)
-                    name = name.split()[0]
-                    values, _ = values.rsplit(")", 1)
-
-                    if element_type == "Node":
-                        if values == "":
-                            symbols[name], status = self.create_node()
+                        value = values
+                        if value in complex_primitives:
+                            value = string_to_instance(value)
                         else:
-                            value = values
-                            if value in complex_primitives:
-                                value = string_to_instance(value)
-                            else:
-                                value = eval(value)
-                            symbols[name], status = self.create_nodevalue(value)
-                    elif element_type == "Edge":
-                        values = [v.split()[0] for v in values.split(",")]
-                        symbols[name], status = self.create_edge(resolve(values[0]), resolve(values[1]))
-                    else:
-                        raise Exception("Unknown element type: %s" % element_type)
+                            value = eval(value)
+                        symbols[name], status = self.create_nodevalue(value)
+                elif element_type == "Edge":
+                    values = [v.split()[0] for v in values.split(",")]
+                    symbols[name], status = self.create_edge(resolve(values[0]), resolve(values[1]))
+                else:
+                    raise Exception("Unknown element type: %s" % element_type)
 
-                    if status != 100:
-                        raise Exception("Failed to process line for reason %s: %s" % (status, line))
+                if status != 100:
+                    raise Exception("Failed to process line for reason %s: %s" % (status, line))
 
-            # Creation successful, now also create a pickle
-            self.graph.serialize(triplestore, format="nt")
-            #TODO this loses information about the root!
             return symbols["root"]
 
     def read_root(self):
         return (self.root, status.SUCCESS)
 
     def create_node(self):
-        return (rdflib.BNode(), status.SUCCESS)
+        self.free_id += 1
+        return (rdflib.URIRef("http://modelverse.mv/#%s" % self.free_id), status.SUCCESS)
 
     def create_edge(self, source, target):
-        if not isinstance(source, rdflib.BNode):
+        if not isinstance(source, rdflib.URIRef):
             return (None, status.FAIL_CE_SOURCE)
-        if not isinstance(target, rdflib.BNode):
+        if not isinstance(target, rdflib.URIRef):
             return (None, status.FAIL_CE_TARGET)
-        edge = rdflib.BNode()
+        self.free_id += 1
+        edge = rdflib.URIRef("http://modelverse.mv/#%s" % self.free_id)
         self.graph.add((edge, self.mv.hasSource, source))
         self.graph.add((edge, self.mv.hasTarget, target))
         return (edge, status.SUCCESS)
@@ -120,14 +108,15 @@ class ModelverseState(object):
     def create_nodevalue(self, value):
         if not self.is_valid_datavalue(value):
             return (None, status.FAIL_CNV_OOB)
-        node = rdflib.BNode()
+        self.free_id += 1
+        node = rdflib.URIRef("http://modelverse.mv/#%s" % self.free_id)
         self.graph.add((node, self.mv.hasValue, rdflib.Literal(json.dumps(value))))
         return (node, status.SUCCESS)
 
     def create_dict(self, source, data, destination):
-        if not isinstance(source, rdflib.BNode):
+        if not isinstance(source, rdflib.URIRef):
             return (None, status.FAIL_CDICT_SOURCE)
-        if not isinstance(target, rdflib.BNode):
+        if not isinstance(target, rdflib.URIRef):
             return (None, status.FAIL_CDICT_TARGET)
         if not self.is_valid_datavalue(data):
             return (None, status.FAIL_CDICT_OOB)
@@ -138,39 +127,40 @@ class ModelverseState(object):
         return (None, status.SUCCESS)
 
     def read_value(self, node):
-        if not isinstance(node, rdflib.BNode):
+        if not isinstance(node, rdflib.URIRef):
             return (None, status.FAIL_RV_UNKNOWN)
-        result = self.graph.query(
+        q = \
             """
             SELECT ?value
             WHERE {
-                _:%s MV:hasValue ?value .
+                <%s> MV:hasValue ?value .
             }
-            """ % node)
+            """ % node
+        result = self.graph.query(q)
         if len(result) == 0:
             return (None, status.FAIL_RV_NO_VALUE)
-        return (list(result)[0][0], status.SUCCESS)
+        return (json.loads(list(result)[0][0]), status.SUCCESS)
 
     def read_outgoing(self, elem):
-        if not isinstance(elem, rdflib.BNode):
+        if not isinstance(elem, rdflib.URIRef):
             return (None, status.FAIL_RO_UNKNOWN)
         result = self.graph.query(
             """
             SELECT ?link
             WHERE {
-                _:%s MV:hasTarget ?link .
+                <%s> MV:hasTarget ?link .
             }
             """ % elem)
         return ([i[0] for i in result], status.SUCCESS)
 
     def read_incoming(self, elem):
-        if not isinstance(elem, rdflib.BNode):
+        if not isinstance(elem, rdflib.URIRef):
             return (None, status.FAIL_RI_UNKNOWN)
         result = self.graph.query(
             """
             SELECT ?link
             WHERE {
-                _:%s MV:hasSource ?link .
+                <%s> MV:hasSource ?link .
             }
             """ % elem)
         return ([i[0] for i in result], status.SUCCESS)
@@ -180,7 +170,7 @@ class ModelverseState(object):
             """
             SELECT ?source, ?target
             WHERE {
-                _:%s MV:hasSource ?source ;
+                <%s> MV:hasSource ?source ;
                      MV:hasTarget ?target .
             }
             """ % edge)
@@ -190,7 +180,7 @@ class ModelverseState(object):
             return ([list(result)[0][0], list(result)[0][1]], status.SUCCESS)
 
     def read_dict(self, node, value):
-        if not isinstance(node, rdflib.BNode):
+        if not isinstance(node, rdflib.URIRef):
             return (None, status.FAIL_RDICT_UNKNOWN)
         if not self.is_valid_datavalue(value):
             return (None, status.FAIL_RDICT_OOB)
@@ -198,7 +188,7 @@ class ModelverseState(object):
         q = """
             SELECT ?value_node
             WHERE {
-                ?main_edge MV:hasSource _:%s ;
+                ?main_edge MV:hasSource <%s> ;
                            MV:hasTarget ?value_node .
                 ?attr_edge MV:hasSource ?main_edge ;
                            MV:hasTarget ?attr_node .
@@ -211,22 +201,22 @@ class ModelverseState(object):
         return (list(result)[0][0], status.SUCCESS)
 
     def read_dict_keys(self, node):
-        if not isinstance(node, rdflib.BNode):
+        if not isinstance(node, rdflib.URIRef):
             return (None, status.FAIL_RDICT_UNKNOWN)
 
         result = self.graph.query(
             """
             SELECT ?key
             WHERE {
-                ?main_edge MV:hasSource _:%s .
+                ?main_edge MV:hasSource <%s> .
                 ?attr_edge MV:hasSource ?main_edge ;
                            MV:hasTarget ?key .
             }
-            """)
+            """ % node)
         return ([i[0] for i in result], status.SUCCESS)
 
     def read_dict_edge(self, node, value):
-        if not isinstance(node, rdflib.BNode):
+        if not isinstance(node, rdflib.URIRef):
             return (None, status.FAIL_RDICTE_UNKNOWN)
         if not self.is_valid_datavalue(value):
             return (None, status.FAIL_RDICTE_OOB)
@@ -234,7 +224,7 @@ class ModelverseState(object):
             """
             SELECT ?main_edge
             WHERE {
-                ?main_edge MV:hasSource _:%s ;
+                ?main_edge MV:hasSource <%s> ;
                            MV:hasTarget ?value_node .
                 ?attr_edge MV:hasSource ?main_edge ;
                            MV:hasTarget ?attr_node .
@@ -246,33 +236,32 @@ class ModelverseState(object):
         return (list(result)[0][0], status.SUCCESS)
 
     def read_dict_node(self, node, value_node):
-        if not isinstance(node, rdflib.BNode):
+        if not isinstance(node, rdflib.URIRef):
             return (None, status.FAIL_RDICTN_UNKNOWN)
         result = self.graph.query(
             """
-            SELECT ?value
+            SELECT ?value_node
             WHERE {
-                ?main_edge MV:hasSource _:%s ;
+                ?main_edge MV:hasSource <%s> ;
                            MV:hasTarget ?value_node .
                 ?attr_edge MV:hasSource ?main_edge ;
-                           MV:hasTarget _:%s .
-                ?value_node MV:hasValue ?value .
+                           MV:hasTarget <%s> .
             }
-            """ % (node, value))
+            """ % (node, value_node))
         if len(result) == 0:
             return (None, status.FAIL_RDICTN_NOT_FOUND)
         return (list(result)[0][0], status.SUCCESS)
 
     def read_dict_node_edge(self, node, value_node):
-        if not isinstance(node, rdflib.BNode):
+        if not isinstance(node, rdflib.URIRef):
             return (None, status.FAIL_RDICTNE_UNKNOWN)
         result = self.graph.query(
             """
             SELECT ?main_edge
             WHERE {
-                ?main_edge MV:hasSource _:%s .
+                ?main_edge MV:hasSource <%s> .
                 ?attr_edge MV:hasSource ?main_edge ;
-                           MV:hasTarget _:%s .
+                           MV:hasTarget <%s> .
             }
             """ % (node, value))
         if len(result) == 0:
@@ -280,7 +269,7 @@ class ModelverseState(object):
         return (list(result)[0][0], status.SUCCESS)
 
     def read_reverse_dict(self, node, value):
-        if not isinstance(node, rdflib.BNode):
+        if not isinstance(node, rdflib.URIRef):
             return (None, status.FAIL_RRDICT_UNKNOWN)
         if not self.is_valid_datavalue(value):
             return (None, status.FAIL_RRDICT_OOB)
@@ -288,7 +277,7 @@ class ModelverseState(object):
             """
             SELECT ?main_edge
             WHERE {
-                ?main_edge MV:hasTarget _:%s .
+                ?main_edge MV:hasTarget <%s> .
                 ?attr_edge MV:hasSource ?main_edge ;
                            MV:hasTarget ?value_node .
                 ?value_node MV:hasValue '%s' .
@@ -300,7 +289,7 @@ class ModelverseState(object):
     def delete_node(self, node):
         if node == self.root:
             return (None, status.FAIL_DN_UNKNOWN)
-        if not isinstance(node, rdflib.BNode):
+        if not isinstance(node, rdflib.URIRef):
             return (None, status.FAIL_DN_UNKNOWN)
         # Remove its value if it exists
         self.graph.remove((node, None, None))
@@ -310,9 +299,9 @@ class ModelverseState(object):
             """
             SELECT ?edge
             WHERE {
-                { ?edge MV:hasTarget _:%s . }
+                { ?edge MV:hasTarget <%s> . }
                 UNION
-                { ?edge MV:hasSource _:%s . }
+                { ?edge MV:hasSource <%s> . }
             }
             """)
         # ... and remove them
@@ -322,7 +311,7 @@ class ModelverseState(object):
         return (None, status.SUCCESS)
 
     def delete_edge(self, edge):
-        if not isinstance(node, rdflib.BNode):
+        if not isinstance(node, rdflib.URIRef):
             return (None, status.FAIL_DN_UNKNOWN)
         # Remove its links
         self.graph.remove((node, None, None))
@@ -332,9 +321,9 @@ class ModelverseState(object):
             """
             SELECT ?edge
             WHERE {
-                { ?edge MV:hasTarget _:%s . }
+                { ?edge MV:hasTarget <%s> . }
                 UNION
-                { ?edge MV:hasSource _:%s . }
+                { ?edge MV:hasSource <%s> . }
             }
             """)
         # ... and remove them