def __call__(self, expr_tree): temp = expr.ExprTree.copy(expr_tree) if self.cmd == 'reduce': if temp.base == None: return elif len(temp.base.children) == 0: return temp elif min([ type(leaf) is expr.ImmutableConst or type(leaf) in get_all_subclasses(expr.ImmutableConst) for leaf in temp.get_all_leaves() ]) == 1 and min([ type(branch_pt) is expr.Operator for branch_pt in temp.get_all_branchpts() ]) == 1: return expr.ExprTree(self._int_inspect(temp)) else: children = [child for child in temp.base.children] temp.base.remove_all_children() #print(children,temp.base.children) for child in children: temp.base.add_child( self.__call__(expr.ExprTree(child)).base) #print('*',temp.base.children) return temp else: raise AttributeError("Incorrect number of parameters")
def copy(node: 'TreeNode', **kargs): assert type(node) is ExprNode or type(node) in get_all_subclasses( ExprNode), "node must be of type ExprNode, not" + str(type(node)) assert len(kargs.keys()) == 0 or 'children' in kargs.keys() and len( kargs.keys()) == 1, "Unknown key arguments" if len(kargs.keys()) == 0: if node.is_leaf(): if type(node) is Int or type(node) is Fraction and len( node.value.split('/')) == 1: return type(node)(int( node.value)) if type(node) is Int else type(node)(Int( int(node.value))) elif type(node) is Fraction: return type(node)(Int(int(node.value.split('/')[0])), Int(int(node.value.split('/')[1]))) else: return type(node)(node.name) else: return type(node)(node.name, node.value, node.children) else: if node.is_leaf(): assert len( kargs.keys()) == 0, "leaf nodes may not have children" else: return type(node)(node.name, node.value, [child for child in kargs['children']])
def _recurse_parser(base:ExprNode,parent:ExprNode): if base.is_leaf() and type(base) is ImmutableConst or type(base) in get_all_subclasses(ImmutableConst): return base.value elif base.is_leaf(): return base.name else: if type(base) is expr.Function: return "{}({})".format(base.name,";".join([_recurse_parser(child,base) for child in base.children])) else: if parent!=None and get_value(base)<get_value(parent): return "({}{}{})".format(_recurse_parser(base.args[0],base),base.name,_recurse_parser(base.args[1],base)) else: return "{}{}{}".format(_recurse_parser(base.args[0],base),base.name,_recurse_parser(base.args[1],base))
def __eq__(self, other): assert other == None or type(other) is ExprNode or type( other ) in get_all_subclasses( ExprNode ), "Comparison checks are allowed only among ExprNodes, not " + str( type(other)) if other == None: return super(ExprNode, self).__eq__(other) elif (type(self) is ImmutableConst or type(self) in get_all_subclasses(ImmutableConst)) or ( type(other) is ImmutableConst or type(other) in get_all_subclasses(ImmutableConst)): return self.value == other.value if other != None and self.value != None and other.value != None else False elif (type(self) is Constant or type(self) is Var) and (type(other) is Constant or type(other) is Var): return self.value == other.value if other != None and self.value != None and other.value != None else self.name == other.name if other != None and type( self) is type(other) else False else: return self.name == other.name if other != None and len( self.name) != 0 and len( other.name ) != 0 and self.name != None and other.name != None else False
def __lt__(self, other): #print(type(other),get_all_subclasses(ImmutableConst)) assert type(other) is ImmutableConst or type( other) in get_all_subclasses(ImmutableConst) return self.value < other.value
def __bool__(self): return self.is_valid_tree(self.base,[]) and (self.base==None or type(self.base) is TreeNode or type(self.base) in get_all_subclasses(TreeNode))
def __init__(self,expr:ExprTree,const:ImmutableConst=Int(1)): assert type(expr) is ExprTree, "term must be of type ExprTree, not "+str(type(expr)) assert type(const) is ImmutableConst or type(const) in get_all_subclasses(ImmutableConst), "term must be of type ExprTree, not "+str(type(expr)) self.term=expr self.const=const super(Term,self).__init__('Term')