#!/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): result = [] for t in fs: # Query the triple against the store if (((q[0].type[-3:] == 'var') or (t[0].repr == q[0].repr)) and ((q[1].type[-3:] == 'var') or (t[1].repr == q[1].repr)) and ((q[2].type[-3:] == 'var') or (t[2].repr == q[2].repr))): result.append(t) return result def rquery(q, fs, dict=0): edict, result = {}, [] for p in (0, 1, 2): if q[p].type[-3:] == 'var': edict[q[p].repr] = None sq = squery(q, fs) for t in sq: # Now match against the input vars add, vdict = 1, copy.copy(edict) for p in (0, 1, 2): if q[p].type[-3:] == 'var': if vdict[q[p].repr] is None: vdict[q[p].repr] = t[p].repr elif vdict[q[p].repr] != t[p].repr: add = 0 if add: result.append([t, vdict]) return result def remove(q, store): # Thanks to deltab and redmonk return filter(lambda s: len(query.rquery(q, [s])) == 0, store) 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): tresult = [x[0] for x in xtquery(qs, fs)] if NTriples: return '\n\n'.join([eep.serialize(y) for y in tresult]).strip() else: return tresult def xtquery(qs, fs): edict, all, result, n = {}, [], [], 1 for q in qs: # Make a dictionary of the variables for p in (0, 1, 2): if q[p].type[-3:] == 'var': edict[q[p].repr] = None for blargh in qs: # Now perform the query, storing in all rqres = squery(blargh, fs[:]) if len(rqres) > 0: all.append(rqres) else: return [] for item in all: n *= len(item) if n > 700000: raise "You want me to find "+str(n)+" cartesian products? Pff" if len(all) > 0: cp = paths(all) # the cartesian product of the results else: cp = [] for rs in cp: # Now match against the input vars if len(rs) != len(qs): raise "Something got borked" add, vdict = 1, copy.copy(edict) for i in range(len(rs)): for pos in (0, 1, 2): if qs[i][pos].type[-3:] == 'var': if vdict[qs[i][pos].repr] is None: vdict[qs[i][pos].repr] = rs[i][pos].repr elif vdict[qs[i][pos].repr] != rs[i][pos].repr: add = 0 if add: result.append([rs, vdict]) return result if __name__=="__main__": print __doc__