def fn_write_sparql_unless_exists(self, g, query, bindings_set, reqd_bound_vars) : #p('write_sparql_unless_exists') #p('bindings_set',bindings_set) read_bindings_set = self.axpress.read_sparql(query, bindings_set, keep_old_bindings = True) #p('read_bindings_set',read_bindings_set) # only write if if len(read_bindings_set) is 0 : # TODO get bound variables out of the write query print 'didnt find anything', prettyquery(query), prettyquery(bindings_set) bindings_set = self.axpress.write_sparql(query, bindings_set) else : print 'they already exist!', prettyquery(bindings_set) bindings_set = read_bindings_set return bindings_set
def register_translation(self, translation): # make sure all of the required keys are present required = ['input', 'output', 'name'] missing = [key for key in required if key not in translation] if missing: raise Exception('translation is missing keys: %s' % prettyquery(missing)) if 'function' not in translation or translation['function'] == None: if 'multi_function' not in translation: translation['function'] = lambda x: x if 'input_function' in translation and translation[ 'input_function'] == None: del translation['input_function'] translation['step_size'] = translation.get('step_size', 1) # parse any string expressions translation['input'] = self.parser.parse_query(translation['input'], reset_bnodes=False) translation['output'] = self.parser.parse_query(translation['output'], reset_bnodes=False) #p(translation['name'], translation['input'], translation['output']) ## hash the triples #translation['input'] = self.hash_triples(translation['input']) #translation['output'] = self.hash_triples(translation['output']) # figure out which variables are in both the input and output of the # translation invars = find_vars(translation['input'], find_string_vars=True) outvars = find_vars(translation['output'], find_string_vars=True) outvars = outvars.union(set(translation.get('add_output_vars', []))) #p(translation['name']) #p('invars', invars) #p('outvars', outvars) translation['output_vars'] = outvars translation['constant_vars'] = list(invars.intersection(outvars)) translation['in_lit_vars'] = find_vars(translation['input'], is_lit_var, find_string_vars=True) import inspect filename = inspect.currentframe().f_back.f_back.f_code.co_filename translation['filename'] = filename translation['id'] = self.next_translation_id() self.translations.append(translation) self.translations_by_name[translation['name']] = translation self.translations_by_id[translation['id']] = translation
def register_translation(self, translation) : # make sure all of the required keys are present required = ['input', 'output', 'name'] missing = [key for key in required if key not in translation] if missing : raise Exception('translation is missing keys: %s' % prettyquery(missing)) if 'function' not in translation or translation['function'] == None : if 'multi_function' not in translation : translation['function'] = lambda x:x if 'input_function' in translation and translation['input_function'] == None : del translation['input_function'] translation['step_size'] = translation.get('step_size', 1) # parse any string expressions translation['input'] = self.parser.parse_query(translation['input'], reset_bnodes=False) translation['output'] = self.parser.parse_query(translation['output'], reset_bnodes=False) #p(translation['name'], translation['input'], translation['output']) ## hash the triples #translation['input'] = self.hash_triples(translation['input']) #translation['output'] = self.hash_triples(translation['output']) # figure out which variables are in both the input and output of the # translation invars = find_vars(translation['input'], find_string_vars = True) outvars = find_vars(translation['output'], find_string_vars = True) outvars = outvars.union(set(translation.get('add_output_vars', []))) #p(translation['name']) #p('invars', invars) #p('outvars', outvars) translation['output_vars'] = outvars translation['constant_vars'] = list( invars.intersection(outvars) ) translation['in_lit_vars'] = find_vars( translation['input'], is_lit_var, find_string_vars = True ) import inspect filename = inspect.currentframe().f_back.f_back.f_code.co_filename translation['filename'] = filename translation['id'] = self.next_translation_id() self.translations.append(translation) self.translations_by_name[translation['name']] = translation self.translations_by_id[ translation['id' ]] = translation
def register_translation(self, translation) : n = self.n # make sure all of the required keys are present required = ['input', 'output', 'name'] missing = [key for key in required if key not in translation] if missing : raise Exception('translation is missing keys: %s' % prettyquery(missing)) # parse any string expressions translation['input'] = self.parser.parse_query(translation['input']) translation['output'] = self.parser.parse_query(translation['output']) #print 'registering' #print translation['name'] #print prettyquery(translation['input']) #print prettyquery(translation['output']) #print self.translations.append(translation)
def apply_translation_binding(self, translation, bindings, history) : n = self.n translation_bindings = [] for binding in bindings : # print 'history',prettyquery([[t[0]['name'], t[1]] for t in history]), # print 'now',prettyquery([translation['name'], binding]), if [translation, binding] not in history : #print 'applying',translation['name'] #print 'binding',prettyquery(binding) history.append([translation, copy.copy(binding)]) # if this translation expects to be cached, use a cache if 'cache_expiration_length' in translation : output_bindings_list = self.cache.call(translation, binding) else : # call the function output_bindings = translation['function'](binding) # make sure the output_bindings is a list of possible bindings. # this allows a plugin to simply modify the binding passed in # or return a new set if that is easier if output_bindings == None : output_bindings = binding if type(output_bindings) == dict : output_bindings_list = [output_bindings] else : output_bindings_list = output_bindings #print 'output_bindings_list',prettyquery(output_bindings_list), outtriple_sets = self.sub_var_bindings(translation['output'], output_bindings_list) #outtriple_sets = [x for x in outtriple_sets] #print 'outtriple_sets',prettyquery(outtriple_sets) translation_bindings.extend(outtriple_sets) print 'translation_bindings',prettyquery(translation_bindings) return translation_bindings
def search(self, query, new_triples, lineage = [], root = False) : """ follow guaranteed translations and add possible translations to the possible_stack this is somewhat of an evaluator ... @arg query is the query to start from @new_triples is a set of triples which are new as of the previous translation. This next translation must take them into account. If they are not needed, then an earlier step could have gotten there already and the most recent step was unnecessary @lineage is a list of the steps we've taken to get here @return the compiled guaranteed path """ self.debug.p('query', query) # find the possible next steps steps = self.next_steps(query, lineage, new_triples) # remove any steps we've already taken steps = self.remove_steps_already_taken(steps, lineage) if self.show_dead_ends : steps = list(steps) if not steps : p('dead_end', query) p('lineage', [step['translation']['name'] for step in lineage]) p() #steps = list(steps) #self.debug.open_block('steps') #self.debug.p(steps) #self.debug.close_block() # look through all steps recursively to see if they result in a # solution and should be added to the compile_node, the finished 'program' for step in steps : self.debug.open_block((step['translation']['name'] or '<unnamed>') + ' ' + color(hash(step['input_bindings'], step['output_bindings'])) + ' ' + prettyquery(step['input_bindings']) + str(time.time() - self.start_time)) # add this step to the lineage, but before that, add any new steps that # were injected by the step itself (in the case of a merged path) new_lineage = copy.copy(lineage) if 'new_lineage' in step : for s in step['new_lineage'] : if s not in lineage : new_lineage.append(s) new_lineage += [step] # if the new information at this point is enough to fulfil the query, done # otherwise, recursively continue searching. # found_solution is filled with the bindings which bind out_lit_vars from # the query to literal values (strings, numbers, uris, etc) # TODO: found_solution might be able to return enough information to # completely remove the partial solution step at the end of compilation found_solution = self.found_solution(step['new_query']) if found_solution : self.debug.p('last_step', step) self.debug.p('input', step['translation']['input']) self.debug.p('output', step['translation']['output']) self.debug.close_block() return new_lineage else : # recur ret = self.search(step['new_query'], step['new_triples'], new_lineage) self.debug.close_block() if ret : return ret
def p(self, *args) : self.log('<xmp>' + ' '.join([ prettyquery(arg) for arg in args ]) + '</xmp>', '')
def execute(self, query, bindings_set = [{}], options = None) : if options is None : options = self.options subquery_lines = [] method = '' lines = query.split('\n') if len(lines) == 0: return [] while len(lines) and lines[0].strip() == '' : lines = lines[1:] if len(lines) == 0 : return [] while lines[-1].strip() == '' : lines = lines[:-1] def get_therest(position) : original_numspaces = len(lines[position]) - len(lines[position].lstrip()) position += 1 while position < len(lines) and \ original_numspaces < len(lines[position]) and \ lines[position][original_numspaces] in ['\t', ' '] : #print ':',repr(lines[position][original_numspaces]) position += 1 return position i = 0 cur_position = 0 compiled = [] while cur_position is not len(lines) : end_position = get_therest(cur_position) these_lines = lines[cur_position:end_position] these_lines = [line.strip() for line in these_lines] sub_query = '\n'.join(these_lines) found = False for translator in self.translators : g = translator.re.match(sub_query) if g is not None : found = True bound_vars, query = translator.bound_vars(g) compiled.append((translator, g, bound_vars, query)) continue if not found : raise Exception("Unknown command for block %s" % sub_query) cur_position = end_position #debug('compiled',compiled) reads = [] writes = [] new_compiled = [] all_bound_vars = set() for translator, g, bound_vars, query in reversed(compiled) : reqd_bound_vars = bound_vars.intersection(all_bound_vars) all_bound_vars.update(bound_vars) new_compiled.append((translator, g, bound_vars, query, reqd_bound_vars)) #if translator.is_read : #reads.append((translator, g, bound_vars, reqd_bound_vars)) #else : #writes.append((translator, g, bound_vars, reqd_bound_vars)) compiled = reversed(new_compiled) compiled = list(compiled) #debug('compiled',compiled) #debug('reads',reads) #debug('writes',writes) for translator, g, bound_vars, query, reqd_bound_vars in compiled : #print 'bound_vars', bound_vars #print 'reqd_bound_vars', reqd_bound_vars if 'intermediate-bindings' in options : print 'pre-bindings_set',prettyquery(bindings_set) bindings_set = translator.fn(g, query, bindings_set, reqd_bound_vars) if 'intermediate-bindings' in options : print 'post-bindings_set',prettyquery(bindings_set) return bindings_set
def search(self, query, new_triples, lineage=[], root=False): """ follow guaranteed translations and add possible translations to the possible_stack this is somewhat of an evaluator ... @arg query is the query to start from @new_triples is a set of triples which are new as of the previous translation. This next translation must take them into account. If they are not needed, then an earlier step could have gotten there already and the most recent step was unnecessary @lineage is a list of the steps we've taken to get here @return the compiled guaranteed path """ self.debug.p('query', query) # find the possible next steps steps = self.next_steps(query, lineage, new_triples) # remove any steps we've already taken steps = self.remove_steps_already_taken(steps, lineage) if self.show_dead_ends: steps = list(steps) if not steps: p('dead_end', query) p('lineage', [step['translation']['name'] for step in lineage]) p() #steps = list(steps) #self.debug.open_block('steps') #self.debug.p(steps) #self.debug.close_block() # look through all steps recursively to see if they result in a # solution and should be added to the compile_node, the finished 'program' for step in steps: self.debug.open_block( (step['translation']['name'] or '<unnamed>') + ' ' + color(hash(step['input_bindings'], step['output_bindings'])) + ' ' + prettyquery(step['input_bindings']) + str(time.time() - self.start_time)) # add this step to the lineage, but before that, add any new steps that # were injected by the step itself (in the case of a merged path) new_lineage = copy.copy(lineage) if 'new_lineage' in step: for s in step['new_lineage']: if s not in lineage: new_lineage.append(s) new_lineage += [step] # if the new information at this point is enough to fulfil the query, done # otherwise, recursively continue searching. # found_solution is filled with the bindings which bind out_lit_vars from # the query to literal values (strings, numbers, uris, etc) # TODO: found_solution might be able to return enough information to # completely remove the partial solution step at the end of compilation found_solution = self.found_solution(step['new_query']) if found_solution: self.debug.p('last_step', step) self.debug.p('input', step['translation']['input']) self.debug.p('output', step['translation']['output']) self.debug.close_block() return new_lineage else: # recur ret = self.search(step['new_query'], step['new_triples'], new_lineage) self.debug.close_block() if ret: return ret
def debug(name, obj=None): from PrettyQuery import prettyquery name = name.replace(" ", "_") print "%s<%s>%s</%s>" % (spaces, name, html_encode(prettyquery(obj)), name)
def p(*args): from PrettyQuery import prettyquery print "%s%s" % (spaces, " ".join([prettyquery(arg) for arg in args]))
def p(self, *args): self.log( '<xmp>' + ' '.join([prettyquery(arg) for arg in args]) + '</xmp>', '')