예제 #1
0
	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])
예제 #2
0
	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])
예제 #3
0
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())