#!/usr/bin/python """Eep RDF API: Query Engine""" __author__ = 'Sean B. Palmer' __license__ = 'Copyright (C) 2001 Sean B. Palmer. GNU GPL 2, except where noted' import eep, copy import operator as oper def squery(q, fs, vdict=0): vdict, result = [{}, vdict][oper.truth(vdict)], [] for pos in (0, 1, 2): # Create a dict of the univars if (q[pos].t in ('Univar', 'Exivar')) and (q[pos].r not in vdict.keys()): vdict[q[pos].r] = None for t in fs: # Query the triple against the store if ((((q[0].t in ('Univar', 'Exivar')) and ((vdict[q[0].r] is None) or (vdict[q[0].r] == t[0].r))) or (t[0].r == q[0].r)) and (((q[1].t in ('Univar', 'Exivar')) and ((vdict[q[1].r] is None) or (dvict[q[1].r] == t[1].r))) or (t[1].r == q[1].r)) and (((q[2].t in ('Univar', 'Exivar')) and ((vdict[q[2].r] is None) or (vdict[q[2].r] == t[2].r))) or (t[2].r == q[2].r))): result.append(t) for pos in (0, 1, 2): # Add found variables to the dict if (q[pos].t in ('Univar', 'Exivar')) and (vdict[q[pos].r] is None): vdict[q[pos].r] = t[pos].r return result, vdict def remove(store, rt): result = [] for t in store: if (t[0].r != rt[0].r) or (t[1].r != rt[1].r) or (t[2].r != rt[2].r): result.append(t) return result def rquery(q, fs, vdict=0): vdict, r, oldlen, newlen = [{}, vdict][oper.truth(vdict)], [], 2, 1 while ((oldlen != newlen) and (newlen != 0)): (result, vdict), oldlen = squery(q, fs, vdict), len(fs) if len(result) > 0: r.append([result, vdict]) for triple in result: fs.remove(triple) vdict, newlen = {}, len(fs) return r def paths(lists): # This function is freeware - public domain # Derived from http://claymore.engineer.gvsu.edu/~steriana/Python/permute.py result = map(lambda i: [i], lists[0]) for list in lists[1:]: x = [] for y in list: x[len(x):] = map(oper.add, result, [[y]]*len(result)) result = x return result def tquery(qs, fs, NTriples=None): r, tresult, result = xtquery(qs, fs), [], '' if len(r) > 0: for x in r: tresult.append(x[0]) if NTriples: for y in tresult: result += eep.serialize(y)+'\n\n' return result else: return tresult def xtquery(qs, fs, NTriples=None): dict, all = {}, [] for q in qs: # Make a dictionary of the variables for p in (0, 1, 2): if (q[p].t in ('Exivar', 'Univar')) and (q[p].r not in dict.keys()): dict[q[p].r] = None for blargh in qs: # Now perform the query, storing in all rqres = rquery(blargh, fs[:]) if len(rqres) > 1: all.append([x[0][0] for x in rqres]) elif len(rqres) == 1: all.append(rqres[0][0]) else: return [] if len(all) > 0: cp = paths(all) # the cartesian product of the results else: cp = [] tresult, result = [], '' for rs in cp: # Now match against the input vars if len(rs) != len(qs): raise "Something got borked" add, vdict = 1, copy.copy(dict) for i in range(len(rs)): for p in (0, 1, 2): if qs[i][p].t in ('Exivar', 'Univar'): if vdict[qs[i][p].r] is None: vdict[qs[i][p].r] = rs[i][p].r elif vdict[qs[i][p].r] != rs[i][p].r: add = 0 if add: tresult.append([rs, vdict]) return tresult if __name__=="__main__": print __doc__