Skip to content

Commit

Permalink
Working on RDFLib#955 Evaluate now has logic to replace the embeddedd…
Browse files Browse the repository at this point in the history
… triple with a reification quad. Unfortunatly, the parser gives CompValue objects in the case where I expect URIRef. There is now one method in evaluate that needs to be overriden to generate the right logic. This method still needs to move to the graph so that optimized stores can be developed.
  • Loading branch information
JervenBolleman committed May 10, 2020
1 parent c714879 commit 34693fd
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 14 deletions.
47 changes: 35 additions & 12 deletions rdflib/plugins/sparql/evaluate.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ def evalBGP(ctx, bgp):
_p = ctx[p]
_o = ctx[o]


for ss, sp, so in ctx.graph.triples((_s, _p, _o)):
if None in (_s, _p, _o):
c = ctx.push()
Expand Down Expand Up @@ -123,17 +122,29 @@ def evalUnion(ctx, union):
for x in evalPart(ctx, union.p2):
yield x

def _convert_embedded_triple(reif, t, v):
if t[0] == reif and t[2] == reif:
return v, t[1], v
elif t[0] == reif:
return v, t[1], t[2]
elif t[2] == reif:
return t[0], t[1], v
else:
return t

# Embedded Triple Pattern
def evalEmbTP(ctx, reif):
def reifyEmbTP(ctx, reif, part):
from rdflib import RDF
v = Variable('reif')

p = CompValue('Project')
p.p = CompValue('BGP')
v = Variable('__' + reif.toPython())
triples = list()
for t in part.triples:
triples.append(_convert_embedded_triple(reif, t, v))

p.p.triples = [v, RDF.subject,reif.subject(), v,RDF.predicate, reif.predicate(), v,RDF.object, reif.object()]
p.PV = [v]
return evalProject(ctx, p)
triples.append([v, RDF.type, RDF.Statement])
triples.append([v, RDF.subject,reif.subject()])
triples.append([v, RDF.predicate, reif.predicate()])
triples.append([v, RDF.object, reif.object()])
part.triples = triples

def evalMinus(ctx, minus):
a = evalPart(ctx, minus.p1)
Expand Down Expand Up @@ -221,6 +232,15 @@ def evalMultiset(ctx, part):
return evalPart(ctx, part.p)


def findSetOfEmbeddedTriples(ctx, part):
setOfEmbededTriples=set()
for t in part.triples:
if isinstance(t[0], EmbeddedTriple) and t[0] not in setOfEmbededTriples:
setOfEmbededTriples.add(t[0])
if isinstance(t[2], EmbeddedTriple) and t[2] not in setOfEmbededTriples:
setOfEmbededTriples.add(t[2])
return setOfEmbededTriples

def evalPart(ctx, part):

# try custom evaluation functions
Expand All @@ -231,10 +251,15 @@ def evalPart(ctx, part):
pass # the given custome-function did not handle this part

if part.name == 'BGP':
set_of_embeded_triples = findSetOfEmbeddedTriples(ctx, part)

# Reorder triples patterns by number of bound nodes in the current ctx
# Do patterns with more bound nodes first
triples = sorted(part.triples, key=lambda t: len([n for n in t if ctx[n] is None]))

if len(set_of_embeded_triples) != 0:
for embTp in set_of_embeded_triples:
reifyEmbTP(ctx, embTp, part)
triples = sorted(part.triples, key=lambda t: len([n for n in t if ctx[n] is None]))
return evalBGP(ctx, triples)
elif part.name == 'Filter':
return evalFilter(ctx, part)
Expand All @@ -252,8 +277,6 @@ def evalPart(ctx, part):
return evalExtend(ctx, part)
elif part.name == 'Minus':
return evalMinus(ctx, part)
elif part.name == 'EmbTP':
return evalEmbTP(ctx, part)
elif part.name == 'Project':
return evalProject(ctx, part)
elif part.name == 'Slice':
Expand Down
16 changes: 14 additions & 2 deletions rdflib/term.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,9 +454,8 @@ def __init__(self, sid=None,
self._object = object
self._sid = sid


def toPython(self):
return text_type(self._subject) + text_type(self._predicate) + text_type(self._object)
return self._subject.toPython() + self._predicate.toPython() + self._object.toPython()

def n3(self, namespace_manager=None):
return "triple:%s" % self
Expand Down Expand Up @@ -496,6 +495,19 @@ def object(self):
def sid(self):
return self._sid

def __ne__(self, other):
return not self.__eq__(other)

def __eq__(self, other):
if (not isinstance(other, self.__class__)):
return False
return self._subject == other._subject and \
self._predicate == other._predicate and \
self._object == other._object

def __hash__(self):
return hash(self._subject) | hash(self._predicate) | hash(self.predicate())

class Literal(Identifier):
__doc__ = """
RDF Literal: http://www.w3.org/TR/rdf-concepts/#section-Graph-Literal
Expand Down

0 comments on commit 34693fd

Please sign in to comment.