def __init__(self, fact_dir, loc_fact, ord_guard, is_left_input, var_ctxt): pred_idx,_ = fact_dir.getFactFromName( loc_fact.fact.name ) inspect = Inspector() fact_vars = inspect.free_var_idxs(loc_fact.loc) | inspect.free_var_idxs(loc_fact.fact) self.degree_freedom = len(fact_vars) - 1 self.degree_join = 1 ord_vars = inspect.free_var_idxs( ord_guard.term1 ) | inspect.free_var_idxs( ord_guard.term2 ) self.var_dependencies = (fact_vars | ord_vars) & var_ctxt has_hash_index = False pred_args = [] for pred_arg in [loc_fact.loc] + loc_fact.fact.terms: if pred_arg.rule_idx in self.var_dependencies: pred_args.append( INPUT ) has_hash_index = True elif pred_arg.rule_idx in ord_vars: pred_args.append( pred_arg ) else: pred_args.append( OUTPUT ) if is_left_input: guard_args = [INPUT, ord_guard.term2] else: guard_args = [ord_guard.term1, INPUT] op = '<=' if ord_guard.include_eq else '<' guard_str = '%s %s %s' % ('%s',op,'%s') if has_hash_index: lk_name = "hash+ord" else: lk_name = "ord" self.initialize(ORD_LK, pred_idx, fact_dir, lk_name, pred_args=pred_args, guard_args=guard_args, guard_str=guard_str ,assoc_guards=[ord_guard])
def __init__(self, fact_dir, loc_fact, mem_guard, var_ctxt): pred_idx,_ = fact_dir.getFactFromName( loc_fact.fact.name ) inspect = Inspector() fact_vars = inspect.free_var_idxs(loc_fact.loc) | inspect.free_var_idxs(loc_fact.fact) mem_vars = inspect.free_var_idxs(mem_guard.term1) common_vars = fact_vars & mem_vars self.degree_join = len(common_vars) degree_freedom = 0 # Existing dependencies from variable context self.var_dependencies = (fact_vars | mem_vars) & var_ctxt has_hash_index = False ppred_args = [] for pred_arg in [loc_fact.loc] + loc_fact.fact.terms: if pred_arg.rule_idx in self.var_dependencies: ppred_args.append( INPUT ) has_hash_index = True elif pred_arg.rule_idx in common_vars: ppred_args.append( pred_arg ) else: ppred_args.append( OUTPUT ) degree_freedom += 1 guard_args = [] for mem_arg in inspect.free_vars(mem_guard.term1): if pred_arg.rule_idx in self.var_dependencies: ppred_args.append( INPUT ) has_hash_index = True elif mem_arg.rule_idx in common_vars: guard_args.append( mem_arg ) else: guard_args.append( OUTPUT ) degree_freedom += 1 guard_args.append( INPUT ) guard_str = '(%s) in %s' % (','.join( map(lambda _: '%s',range(0,len(guard_args)-1)) ),'%s') self.degree_freedom = degree_freedom if has_hash_index: lk_name = "hash+mem" else: lk_name = "mem" self.initialize(MEM_LK, pred_idx, fact_dir, lk_name, pred_args=ppred_args, guard_args=guard_args, guard_str=guard_str ,assoc_guards=[mem_guard])
class LookupContext: def __init__(self, fact_dir): self.bs_eq_ctxt = emptyset() self.eq_ctxt = emptyset() self.mem_grds = [] self.ord_grds = [] self.eq_grds = [] self.non_idx_grds = [] self.inspect = Inspector() self.fact_dir = fact_dir def __repr__(self): strs = "======== Lookup Context ========\n" strs += "BootStrap Eqs: %s\n" % self.bs_eq_ctxt strs += "Eqs: %s\n" % self.eq_ctxt all_grds = self.mem_grds + self.ord_grds + self.eq_grds + self.non_idx_grds if len(all_grds) > 0: strs += "Guards: %s\n" % (','.join(map(lambda g: g.__repr__(), all_grds))) strs += "================================" return strs def varCtxt(self): return self.eq_ctxt | self.bs_eq_ctxt def removeBootStrapped(self): self.bs_eq_ctxt = emptyset() def addFactHead(self, head, boot_strap=False): if head.is_atom: free_vars = self.inspect.free_var_idxs( head.fact ) else: free_vars = self.inspect.free_var_idxs( head.fact.facts[0] ) if not boot_strap: free_vars |= self.inspect.free_var_idxs( map(lambda cr: cr.term_range, head.fact.comp_ranges) ) if not boot_strap: self.eq_ctxt = self.eq_ctxt | free_vars else: self.bs_eq_ctxt = self.bs_eq_ctxt | free_vars def addVars(self, term_vars, boot_strap=False): free_vars = self.inspect.free_var_idxs( term_vars ) if not boot_strap: self.eq_ctxt = self.eq_ctxt | free_vars else: self.bs_eq_ctxt = self.bs_eq_ctxt | free_vars def addGuard(self, guard): if guard.indexable(): if guard.type == MEM_GRD: self.mem_grds.append( guard ) elif guard.type == ORD_GRD: self.ord_grds.append( guard ) elif guard.type == EQ_GRD: self.eq_grds.append( guard ) else: self.non_idx_grds.append( guard ) else: self.non_idx_grds.append( guard ) def scheduleGuards(self): sch_grds = [] new_eq_grds = [] for eq_grd in self.eq_grds: if eq_grd.scheduleAsGuard( self.varCtxt() ): sch_grds.append( eq_grd ) else: new_eq_grds.append( eq_grd ) self.eq_grds = new_eq_grds new_ord_grds = [] for ord_grd in self.ord_grds: if ord_grd.scheduleAsGuard( self.varCtxt() ): sch_grds.append( ord_grd ) else: new_ord_grds.append( ord_grd ) self.ord_grds = new_ord_grds new_mem_grds = [] for mem_grd in self.mem_grds: if mem_grd.scheduleAsGuard( self.varCtxt() ): sch_grds.append( mem_grd ) else: new_mem_grds.append( mem_grd ) self.mem_grds = new_mem_grds new_non_idx_grds = [] for non_idx_grd in self.non_idx_grds: if non_idx_grd.scheduleAsGuard( self.varCtxt() ): sch_grds.append( non_idx_grd ) else: new_non_idx_grds.append( non_idx_grd ) self.non_idx_grds = new_non_idx_grds return sch_grds def bestLookupOption(self, new_head_info): curr_best_head_idx = -1 curr_best_lookup = None curr_best_cost = (10000,0,0) curr_best_head = None for head_idx,new_head in new_head_info.items(): lookups = self.lookupOptions(new_head) if lookups[0].cost() < curr_best_cost: curr_best_head_idx = head_idx curr_best_lookup = lookups[0] curr_best_cost = lookups[0].cost() curr_best_head = new_head return (curr_best_head_idx, curr_best_lookup) def remove_guards(self, rm_grds): self.eq_grds = filter(lambda g: g not in rm_grds, self.eq_grds) self.mem_grds = filter(lambda g: g not in rm_grds, self.mem_grds) self.ord_grds = filter(lambda g: g not in rm_grds, self.ord_grds) self.non_idx_grds = filter(lambda g: g not in rm_grds, self.non_idx_grds) # Current implementation ignores Eq guards. def lookupOptions(self, new_head): if new_head.is_atom: loc_fact = new_head.fact head_eq_grds = [] head_mem_grds = [] head_ord_grds = [] else: loc_fact = new_head.fact.facts[0] head_eq_grds = new_head.eq_grds head_mem_grds = new_head.mem_grds head_ord_grds = new_head.ord_grds pred_idx,_ = self.fact_dir.getFactFromName( loc_fact.fact.name ) lookup_opts = [ LinearLookup(self.fact_dir, loc_fact.fact.name) ] free_vars = self.inspect.free_var_idxs( loc_fact ) join_vars = self.varCtxt() & free_vars new_vars = free_vars - self.varCtxt() # Add a hash lookup if the new head has overlapping variables with the current # variable context. if len(join_vars) > 0: hash_lookup = HashLookup(self.fact_dir, loc_fact, join_vars) lookup_opts.append( hash_lookup ) # TODO: Mem guard lookup and ord guard lookup omitted for now. ''' # Add member lookup if the head has overlapping variables with a member guard for mem_guard in self.mem_grds + head_mem_grds: index_info = mem_guard.scheduleAsIndex( self.varCtxt() ) if index_info != None: input_vars,output_vars,_ = index_info if len(new_vars & output_vars) > 0: mem_lookup = MemLookup(self.fact_dir, loc_fact, mem_guard, self.varCtxt()) lookup_opts.append( mem_lookup ) # Add order lookup for ord_guard in self.ord_grds + head_ord_grds: index_info = ord_guard.scheduleAsIndex( self.varCtxt() ) if index_info != None: input_vars,output_vars,is_left_input = index_info if len(new_vars & output_vars) > 0: ord_lookup = OrdLookup(self.fact_dir, loc_fact, ord_guard, is_left_input, self.varCtxt()) lookup_opts.append( ord_lookup ) ''' return sorted(lookup_opts, key=lambda lk: lk.cost())