def _rdf_exec(g, pe, generate_lists=False): # rdflib.plugins.sparql.parserutils.CompValue # # class CompValue(OrderedDict): # def __init__(self, name, **values): # # SelectQuery( # p = # Project( # p = # LeftJoin( # p2 = # BGP( # triples = [(rdflib.term.Variable(u'leaderobj'), rdflib.term.URIRef(u'http://dbpedia.org/ontology/leader'), rdflib.term.Variable(u'leader'))] # _vars = set([rdflib.term.Variable(u'leaderobj'), rdflib.term.Variable(u'leader')]) # ) # expr = # TrueFilter( # _vars = set([]) # ) # p1 = # BGP( # triples = [(rdflib.term.Variable(u'leader'), rdflib.term.URIRef(u'http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), rdflib.term.URIRef(u'http://schema.org/Person')), (rdflib.term.Variable(u'leader'), rdflib.term.URIRef(u'http://www.w3.org/2000/01/rdf-schema#label'), rdflib.term.Variable(u'label'))] # _vars = set([rdflib.term.Variable(u'label'), rdflib.term.Variable(u'leader')]) # ) # _vars = set([rdflib.term.Variable(u'leaderobj'), rdflib.term.Variable(u'label'), rdflib.term.Variable(u'leader')]) # ) # PV = [rdflib.term.Variable(u'leader'), rdflib.term.Variable(u'label'), rdflib.term.Variable(u'leaderobj')] # _vars = set([rdflib.term.Variable(u'leaderobj'), rdflib.term.Variable(u'label'), rdflib.term.Variable(u'leader')]) # ) # datasetClause = None # PV = [rdflib.term.Variable(u'leader'), rdflib.term.Variable(u'label'), rdflib.term.Variable(u'leaderobj')] # _vars = set([rdflib.term.Variable(u'leaderobj'), rdflib.term.Variable(u'label'), rdflib.term.Variable(u'leader')]) # ) pred = g.terms[g.inx] args = pred.args # if len(args) == 0 or len(args) % 3 != 0: # raise PrologRuntimeError('rdf: one or more argument triple(s) expected, got %d args' % len(args)) distinct = False triples = [] optional_triples = [] filters = [] limit = 0 offset = 0 arg_idx = 0 var_map = {} # string -> rdflib.term.Variable while arg_idx < len(args): arg_s = args[arg_idx] # check for optional structure if isinstance(arg_s, Predicate) and arg_s.name == 'optional': s_args = arg_s.args if len(s_args) != 3: raise PrologRuntimeError('rdf: optional: triple arg expected') arg_s = s_args[0] arg_p = s_args[1] arg_o = s_args[2] logging.debug('rdf: optional arg triple: %s' % repr( (arg_s, arg_p, arg_o))) optional_triples.append( (pl_to_rdf(arg_s, g.env, pe, var_map, pe.kb), pl_to_rdf(arg_p, g.env, pe, var_map, pe.kb), pl_to_rdf(arg_o, g.env, pe, var_map, pe.kb))) arg_idx += 1 # check for filter structure elif isinstance(arg_s, Predicate) and arg_s.name == 'filter': logging.debug('rdf: filter structure detected: %s' % repr(arg_s.args)) s_args = arg_s.args # transform multiple arguments into explicit and-tree pl_expr = s_args[0] for a in s_args[1:]: pl_expr = Predicate('and', [pl_expr, a]) filters.append( prolog_to_filter_expression(pl_expr, g.env, pe, var_map, pe.kb)) arg_idx += 1 # check for distinct elif isinstance(arg_s, Predicate) and arg_s.name == 'distinct': s_args = arg_s.args if len(s_args) != 0: raise PrologRuntimeError( 'rdf: distinct: unexpected arguments.') distinct = True arg_idx += 1 # check for limit/offset elif isinstance(arg_s, Predicate) and arg_s.name == 'limit': s_args = arg_s.args if len(s_args) != 1: raise PrologRuntimeError('rdf: limit: one argument expected.') limit = pe.prolog_get_int(s_args[0], g.env) arg_idx += 1 elif isinstance(arg_s, Predicate) and arg_s.name == 'offset': s_args = arg_s.args if len(s_args) != 1: raise PrologRuntimeError('rdf: offset: one argument expected.') offset = pe.prolog_get_int(s_args[0], g.env) arg_idx += 1 else: if arg_idx > len(args) - 3: raise PrologRuntimeError( 'rdf: not enough arguments for triple') arg_p = args[arg_idx + 1] arg_o = args[arg_idx + 2] logging.debug('rdf: arg triple: %s' % repr((arg_s, arg_p, arg_o))) triples.append( (pl_to_rdf(arg_s, g.env, pe, var_map, pe.kb), pl_to_rdf(arg_p, g.env, pe, var_map, pe.kb), pl_to_rdf(arg_o, g.env, pe, var_map, pe.kb))) arg_idx += 3 logging.debug('rdf: triples: %s' % repr(triples)) logging.debug('rdf: optional_triples: %s' % repr(optional_triples)) logging.debug('rdf: filters: %s' % repr(filters)) if len(triples) == 0: raise PrologRuntimeError( 'rdf: at least one non-optional triple expected') var_list = var_map.values() var_set = set(var_list) p = CompValue('BGP', triples=triples, _vars=var_set) for t in optional_triples: p = CompValue('LeftJoin', p1=p, p2=CompValue('BGP', triples=[t], _vars=var_set), expr=CompValue('TrueFilter', _vars=set([]))) for f in filters: p = CompValue('Filter', p=p, expr=f, _vars=var_set) if limit > 0: p = CompValue('Slice', start=offset, length=limit, p=p, _vars=var_set) if distinct: p = CompValue('Distinct', p=p, _vars=var_set) algebra = CompValue('SelectQuery', p=p, datasetClause=None, PV=var_list, _vars=var_set) result = pe.kb.query_algebra(algebra) logging.debug('rdf: result (len: %d): %s' % (len(result), repr(result))) if len(result) == 0: return False if generate_lists: # bind each variable to list of values for binding in result: for v in binding.labels: l = binding[v] value = rdf_to_pl(l) if not v in g.env: g.env[v] = ListLiteral([]) g.env[v].l.append(value) return True else: # turn result into list of bindings res_bindings = [] for binding in result: res_binding = {} for v in binding.labels: l = binding[v] value = rdf_to_pl(l) res_binding[v] = value res_bindings.append(res_binding) if len(res_bindings) == 0 and len(result) > 0: res_bindings.append({}) # signal success logging.debug('rdf: res_bindings: %s' % repr(res_bindings)) return res_bindings
def Union(p1, p2): return CompValue("Union", p1=p1, p2=p2)
def Minus(p1, p2): return CompValue("Minus", p1=p1, p2=p2)
def Project(p, PV): return CompValue("Project", p=p, PV=PV)
def OrderBy(p, expr): return CompValue("OrderBy", p=p, expr=expr)
def LeftJoin(p1, p2, expr): return CompValue("LeftJoin", p1=p1, p2=p2, expr=expr)
def Extend(p, expr, var): return CompValue("Extend", p=p, expr=expr, var=var)
def Join(p1, p2): return CompValue('Join', p1=p1, p2=p2)
def Minus(p1, p2): return CompValue('Minus', p1=p1, p2=p2)
def ToMultiSet(p): return CompValue('ToMultiSet', p=p)
def Union(p1, p2): return CompValue('Union', p1=p1, p2=p2)
def OrderBy(p, expr): return CompValue('OrderBy', p=p, expr=expr)
def GraphJoin(p1, p2, graph): return CompValue('Join', p1=p1, p2=p2, graph=graph)
def Service(term, graph): return CompValue('Service', term=term, p=graph)
def translate(q): """ http://www.w3.org/TR/sparql11-query/#convertSolMod """ _traverse(q, _simplifyFilters) q.where = traverse(q.where, visitPost=translatePath) # TODO: Var scope test VS = set() traverse(q.where, functools.partial(_findVars, res=VS)) # all query types have a where part M = translateGroupGraphPattern(q.where) aggregate = False if q.groupby: conditions = [] # convert "GROUP BY (?expr as ?var)" to an Extend for c in q.groupby.condition: if isinstance(c, CompValue) and c.name == "GroupAs": M = Extend(M, c.expr, c.var) c = c.var conditions.append(c) M = Group(p=M, expr=conditions) aggregate = True elif (traverse(q.having, _hasAggregate, complete=False) or traverse(q.orderby, _hasAggregate, complete=False) or any( traverse(x.expr, _hasAggregate, complete=False) for x in q.projection or [] if x.evar)): # if any aggregate is used, implicit group by M = Group(p=M) aggregate = True if aggregate: M, E = translateAggregates(q, M) else: E = [] # HAVING if q.having: M = Filter(expr=and_(*q.having.condition), p=M) # VALUES if q.valuesClause: M = Join(p1=M, p2=ToMultiSet(translateValues(q.valuesClause))) if not q.projection: # select * PV = list(VS) else: PV = list() for v in q.projection: if v.var: if v not in PV: PV.append(v.var) elif v.evar: if v not in PV: PV.append(v.evar) E.append((v.expr, v.evar)) else: raise Exception("I expected a var or evar here!") for e, v in E: M = Extend(M, e, v) # ORDER BY if q.orderby: M = OrderBy( M, [ CompValue("OrderCondition", expr=c.expr, order=c.order) for c in q.orderby.condition ], ) # PROJECT M = Project(M, PV) if q.modifier: if q.modifier == "DISTINCT": M = CompValue("Distinct", p=M) elif q.modifier == "REDUCED": M = CompValue("Reduced", p=M) if q.limitoffset: offset = 0 if q.limitoffset.offset is not None: offset = q.limitoffset.offset.toPython() if q.limitoffset.limit is not None: M = CompValue("Slice", p=M, start=offset, length=q.limitoffset.limit.toPython()) else: M = CompValue("Slice", p=M, start=offset) return M, PV
def Graph(term, graph): return CompValue('Graph', term=term, p=graph)
def BGP(triples=None): return CompValue("BGP", triples=triples or [])
def BGP(triples=None): return CompValue('BGP', triples=triples or [])
def Filter(expr, p): return CompValue("Filter", expr=expr, p=p)
def Filter(expr, p): return CompValue('Filter', expr=expr, p=p)
def Values(res): return CompValue("values", res=res)
def Extend(p, expr, var): return CompValue('Extend', p=p, expr=expr, var=var)
def Group(p, expr=None): return CompValue("Group", p=p, expr=expr)
def Values(res): return CompValue('values', res=res)
def ToMultiSet(p): return CompValue("ToMultiSet", p=p)
def Project(p, PV): return CompValue('Project', p=p, PV=PV)
def Join(p1, p2): return CompValue("Join", p1=p1, p2=p2)
def Group(p, expr=None): return CompValue('Group', p=p, expr=expr)
def Graph(term, graph): return CompValue("Graph", term=term, p=graph)
def EmpTP(p, o): return CompValue('EmpTP', var=o)