Example #1
0
def join_empty_heaps(empty1,empty2,candidate,to_remove):
	join=[]
	#first join the emptyheap equalities
	for disj1 in empty1:
		for disj2 in empty2:
			aux=list(disj1)+list(disj2)
			aux=input.join_equalities(aux)
			aux2=[]
			for i in aux:
				aux2.append(input.remove_multiple_occurences(i))
			join.append(aux2)
	# remove candidate if "to_remove" is set
	if to_remove:
		join2=[]
		for disj in join:
			disj2=[]
			for i in disj:
				if candidate in i:
					i.pop(i.index(candidate))
					if not len(i)==1:
						disj2.append(i)
				else:
					disj2.append(i)
			join2.append(disj2)
		join=join2					
	return join
Example #2
0
def join_empty_LHS(call,params,new_call2,new_params2,old_call2,old_params2,preds,empty2):
	# RHS: call + params
	# new top call: new_call2 + new_params2
	#
	# first we find a mapping of internal parameters from the predicate "call" 
	# to the internal parameters of the predicate "new_call2"
	# * internal call parameter (preds[call][0]) -> top level params (params) 
	#   -> new top level params (new_params2) -> internal new top call parameter (preds[new_call2][0])
	# * internal parameter from the call equal to nil are translated into "nil-Xn" internal parameters of the new call
	call_p_map={}
	nil_pos=1
	for i in range(len(preds[call][0])):
		if params[i]=="nil":
			call_p_map[preds[call][0][i]]="nil-X%i"%nil_pos
			if not ("nil-X%i"%nil_pos in preds[new_call2][0]):
				raise JoinFailed("JOIN: ERROR: this line should not be accesible")
			nil_pos=nil_pos+1
		elif params[i] in new_params2:
			call_p_map[preds[call][0][i]]=preds[new_call2][0][new_params2.index(params[i])]
		elif params[i] in old_params2:
			# handle the param on which the join is applied if "to_remove was true" (-->this param is not part of new_params2)
			call_p_map[preds[call][0][i]]=preds[old_call2][0][old_params2.index(params[i])]
		else:
			raise JoinFailed("JOIN: ERROR: this line should not be accesible")
	# map the empty2 inside the rule.
	if not len(empty2)==1:
		raise JoinFailed("JOIN: not implemented")
	# we suppose that the equality  contains only a single disjunct
	# the other situation is not implemented
	disj=empty2[0]
	equal=[]
	for conj in disj:
		new_conj=[]
		for x in conj:
			new_conj.append(preds[old_call2][0][old_params2.index(x)])
			if x=="nil":
				new_conj.append("nil")
		equal.append(new_conj)
	equal1=[]
	for x in equal:
		equal1.append(input.remove_multiple_occurences(x))	
	equal1=input.join_equalities(equal1)
	new_rule_params=preds[new_call2][0]
	# in the forbid variable, we store parameters, which are checked for the following:
	# they must be existentially quantified
	# they must be used only in call and call2
	forbid=[]
	# for each rule create a new rule
	new_rules=[]
	for (al,pt,cls,eq) in preds[call][1]:
		# the system of predicates must be forward connected, so call_p_map[al] must be defined ...
		alloc=call_p_map[al]
		# find representatives
		mapping={}
		for conj in equal1:
			if alloc in conj:
				repres=alloc
			else:
				tmp=input.intersect_lists(new_rule_params,conj)
				if tmp>1:
					# equality between formal parameters implemented only if they are equal to the allocated node
					if "nil" in conj:
						for x in conj:
							if x=="nil":
								pass
							else:
								if new_params2[new_rule_params.index(x)]=="nil":
									repres=x
								else:
									# add to the forbid
									to_forbid=new_params2[new_rule_params.index(x)]
									if not (to_forbid in forbid):
										forbid.append(to_forbid)
					else:
						raise JoinFailed("JOIN: not implemented")
				elif tmp==1:
					for p in new_rule_params:
						if p in conj:
							repres=dp
				else:
					repres=conj[0]
			for x in conj:
				mapping[x]=repres
		# the original rule is translated as folows:
		# first all variables are translated according to the "all_p_map"
		# every variable outside all_p_map is translated to an unique new name
		# second all variables are translated according to the "mapping"
		new_al=apply_maps(al,call_p_map,mapping,new_params2,0)	
		new_pt=[]
		for x in pt:
			new_pt.append(apply_maps(x,call_p_map,mapping,new_params2,0))
		new_cls=[]
		for (call_pred,call_par) in cls:
			new_call_par=[]
			for x in call_par:
				new_call_par.append(apply_maps(x,call_p_map,mapping,new_params2,0))
			new_cls.append((call_pred,new_call_par))
		new_eq=[]
		for x in eq:
			new_eq.append(apply_maps(x,call_p_map,mapping,new_params2,1))
		for x in mapping.keys():
			if mapping[x]==new_al and (not x in new_eq):
				new_eq.append(x)
		# pop alocated node fron the equality list - not needed
		if new_al in new_eq:
			new_eq.pop(new_eq.index(new_al))
		new_rules.append((new_al,new_pt,new_cls,new_eq))
	# add the newly created rules inside preds
	par,rules=preds[new_call2]
	rules=rules+new_rules
	preds[new_call2]=(par,rules)
	return forbid