improved futile_union_intersection_subtraction optimization. Now it works also if one of the subtrees has a selection and the other doesn't

git-svn-id: http://galileo.dmi.unict.it/svn/relational/trunk@183 014f5005-505e-4b48-8d0a-63407b615a7c
master
LtWorf 2009-05-26 13:39:59 +07:00
parent 43766eeeae
commit 7b827082d6
2 changed files with 55 additions and 32 deletions

@ -32,6 +32,37 @@ A function will have to return the number of changes performed on the tree.
import optimizer import optimizer
def replace_node(replace,replacement):
'''This function replaces "replace" node with the node "with",
the father of the node will now point to the with node'''
replace.name=replacement.name
replace.kind=replacement.kind
if replace.kind==optimizer.UNARY:
replace.child=replacement.child
replace.prop=replacement.prop
elif replace.kind==optimizer.BINARY:
replace.right=replacement.right
replace.left=replacement.left
def recoursive_scan(function,node,rels=None):
changes=0
#recoursive scan
if node.kind==optimizer.UNARY:
if rels!=None:
changes+=function(node.child,rels)
else:
changes+=function(node.child)
elif n.kind==optimizer.BINARY:
if rels!=None:
changes+=function(node.right,rels)
changes+=function(node.left,rels)
else:
changes+=function(node.right)
changes+=function(node.left)
return changes
def duplicated_select(n): def duplicated_select(n):
changes=0 changes=0
'''This function locates and deletes things like '''This function locates and deletes things like
@ -53,21 +84,29 @@ def duplicated_select(n):
return changes return changes
def futile_union_intersection_subtraction(n): def futile_union_intersection_subtraction(n):
'''This function locates things like r r, and replaces them with r''' '''This function locates things like r r, and replaces them with r.
σ k (r) r with r
σ k (r) r with σ k (r)
'''
#TODO document into the wiki #TODO document into the wiki
changes=0 changes=0
if n.name in ('','') and n.left==n.right: if n.name in ('','') and n.left==n.right:
changes=1 changes=1
n.name=n.left.name replace_node(n,n.left)
n.kind=n.left.kind elif (n.name == '' and ((n.left.name=='σ' and n.left.child==n.right) or (n.right.name=='σ' and n.right.child==n.left))): #Union of two equal things, but one has a selection
if n.kind==optimizer.UNARY: changes=1
n.child=n.left.child if n.left!='σ':#Selection on left. replacing self with right.
n.prop=n.left.prop replace_node(n,n.right)
elif n.kind==optimizer.BINARY: else:#Selection on left. replacing self with right.
n.right=n.left.right replace_node(n,n.left)
n.left=n.left.left elif (n.name == '' and ((n.left.name=='σ' and n.left.child==n.right) or (n.right.name=='σ' and n.right.child==n.left))): #Intersection of two equal things, but one has a selection
pass changes=1
if n.left!='σ':#Swapping with the selection
replace_node(n,n.left)
else:
replace_node(n,n.right)
#elif (n.name == '-' and ((n.left.name=='σ' and n.left.child==n.right) or (n.right.name=='σ' and n.right.child==n.left))): #Intersection of two equal things, but one has a selection
elif n.name=='-' and n.left==n.right:#Empty relation elif n.name=='-' and n.left==n.right:#Empty relation
changes=1 changes=1
n.kind=optimizer.UNARY n.kind=optimizer.UNARY
@ -236,15 +275,7 @@ def futile_renames(n):
n.prop=n.prop[:-1] #Removing ending comma n.prop=n.prop[:-1] #Removing ending comma
if len(n.prop)==0: #Nothing to rename, removing the rename op if len(n.prop)==0: #Nothing to rename, removing the rename op
n.name=n.child.name replace_node(n,n.child)
n.kind=n.child.kind
if n.kind==optimizer.UNARY:
n.prop=n.child.prop
n.child=n.child.child
elif n.kind==optimizer.BINARY:
n.left=n.child.left
n.right=n.child.right
#recoursive scan #recoursive scan
if n.kind==optimizer.UNARY: if n.kind==optimizer.UNARY:
changes+=futile_renames(n.child) changes+=futile_renames(n.child)
@ -297,14 +328,7 @@ def subsequent_renames(n):
n.prop=n.prop[:-1] #Removing ending comma n.prop=n.prop[:-1] #Removing ending comma
if len(n.prop)==0: #Nothing to rename, removing the rename op if len(n.prop)==0: #Nothing to rename, removing the rename op
n.name=n.child.name replace_node(n,n.child)
n.kind=n.child.kind
if n.kind==optimizer.UNARY:
n.prop=n.child.prop
n.child=n.child.child
elif n.kind==optimizer.BINARY:
n.left=n.child.left
n.right=n.child.right
#recoursive scan #recoursive scan
if n.kind==optimizer.UNARY: if n.kind==optimizer.UNARY:
@ -538,10 +562,7 @@ def selection_and_product(n,rels):
if len(both)>0: if len(both)>0:
n.prop+=' and ' n.prop+=' and '
else:#No need for general select else:#No need for general select
n.name=n.child.name replace_node(n,n.child)
n.kind=n.child.kind
n.left=n.child.left
n.right=n.child.right
#recoursive scan #recoursive scan
if n.kind==optimizer.UNARY: if n.kind==optimizer.UNARY:

@ -283,8 +283,10 @@ if __name__=="__main__":
#print n #print n
#print n.result_format(rels) #print n.result_format(rels)
'''σ k (r) r with r
σ k (r) r with σ k (r)'''
a=general_optimize('π index,name,turiddu (ρ qq➡ii,id➡index(R))')#"ρ id➡ciao(R) - ρ id➡ciao(Q) ") a=general_optimize('σ k (r) ᑎ r')
#a=general_optimize("σ i==2 (σ b>5 (d))") #a=general_optimize("σ i==2 (σ b>5 (d))")
print a print a
#print node(a) #print node(a)