2008-12-10 17:42:41 +00:00
# coding=UTF-8
# Relational
# Copyright (C) 2008 Salvo "LtWorf" Tomaselli
#
# Relation is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# author Salvo "LtWorf" Tomaselli <tiposchi@tiscali.it>
''' This module optimizes relational expressions into ones that require less time to be executed '''
RELATION = 0
UNARY = 1
BINARY = 2
class node ( object ) :
''' This class is a node of a relational expression. Leaves are relations and internal nodes are operations. '''
def __init__ ( self , expression ) :
2008-12-11 22:36:45 +00:00
expression = expression . strip ( )
print " Parsing: " , expression
2008-12-10 17:42:41 +00:00
''' expression must be a valid relational algrbra expression that would be accepted by the parser
and must be utf16 '''
self . kind = 0
self . name = " a "
self . prop = " "
''' *-ᑌ ᑎᐅᐊᐅLEFTᐊᐅRIGHTᐊᐅFULLᐊπσ ρ '''
2008-12-11 22:36:45 +00:00
binary = ( u " * " , u " - " , u " ᑌ " , u " ᑎ " )
unary = ( u " π " , u " σ " , u " ρ " )
2008-12-10 17:42:41 +00:00
''' (a ᑌ (a ᑌ b ᑌ c ᑌ d)) ᑎ c - σ i==3(πa,b(aᑌ b ᑎ c)) '''
2008-12-11 22:36:45 +00:00
level = 0 #Current parentesis level
start = - 1 #Start of the parentesis
end = - 1 #End of the parentesis.
tokens = list ( expression ) #Splitted expression
r = range ( len ( tokens ) )
r . reverse ( )
lev_non_zero_chars = 0 #Number of chars inside parentesis
for i in r : #Parses expression from end to begin, to preserve operation's order
if tokens [ i ] == u " ( " :
if level == 0 :
start = i
print start
level + = 1
elif tokens [ i ] == u " ) " :
level - = 1
if level == 0 :
end = i
print end
if level != 0 :
lev_non_zero_chars + = 1
if i == 0 and level == 0 and tokens [ i ] in unary : #Unary operator found, must grab its parameters and its child relation they
child = " "
for q in tokens [ start + 1 : end ] :
child + = q
self . name = tokens [ i ]
print " ----- " , tokens [ i ]
print " --- " , start , end , lev_non_zero_chars
print child
#print prop
#self.child=node(child)
if level == 0 and tokens [ i ] in binary : #Binary operator found, everything on left will go in the left subree and everhthing on the right will go in the right subtree
self . kind = BINARY
left = " "
right = " "
if start == end == - 1 : #No parentesis before
end = i
for q in tokens [ start + 1 : end ] :
left + = q
self . name = tokens [ i ]
for q in tokens [ i + 1 : ] :
right + = q
print " self: " , tokens [ i ]
print " left: " , left
print " right: " , right
self . left = node ( left )
self . right = node ( right )
return
2008-12-10 17:42:41 +00:00
2008-12-11 22:36:45 +00:00
if lev_non_zero_chars != 0 and lev_non_zero_chars + 1 == len ( expression ) : #Expression is entirely contained in parentesis, removing them
n = node ( expression [ 1 : - 1 ] )
self . name = n . name
self . kind = n . kind
if n . kind == UNARY :
self . child = n . child
elif n . kind == BINARY :
self . left = n . left
self . right = n . right
self . prop = n . prop
return
self . kind = RELATION
self . name = expression
2008-12-10 17:42:41 +00:00
def __str__ ( self ) :
if ( self . kind == RELATION ) :
return self . name
elif ( self . kind == UNARY ) :
return self . name + " " + self . prop + " ( " + self . child + " ) "
elif ( self . kind == BINARY ) :
2008-12-11 22:36:45 +00:00
if self . left . kind == RELATION :
left = self . left . __str__ ( )
else :
left = u " ( " + self . left . __str__ ( ) + u " ) "
if self . right . kind == RELATION :
right = self . right . __str__ ( )
else :
right = u " ( " + self . right . __str__ ( ) + u " ) "
return ( left + self . name + right )
2008-12-10 17:42:41 +00:00
2008-12-11 22:36:45 +00:00
if __name__ == " __main__ " :
#n=node(u"((a ᑌ b) - c ᑌ d) - b")
#n=node(u"((((((((((((2)))))))))))) - (3 * 5) - 2")
n = node ( u " π a,b (d-a*b) " )
print n . __str__ ( )