def simplify(expr): n = _try_eval(expr) if n is not None: return type_check.Constant(n) if isinstance(expr, type_check.BinaryOperator): rhs_value = _try_eval(expr.rhs) if rhs_value is not None: if (expr.exp == '+' or expr.exp == '-') and rhs_value == 0: return simplify(expr.lhs) if expr.exp == '+' and rhs_value < 0: expr_rhs = type_check.Constant(-rhs_value) return simplify(_make_binop_expr(expr.lhs, expr_rhs, '-')) if expr.exp == '-' and rhs_value < 0: expr_rhs = type_check.Constant(-rhs_value) return simplify(_make_binop_expr(expr.lhs, expr_rhs, '+')) if (expr.exp == '*' or expr.exp == '/' or expr.exp == '//') and rhs_value == 1: return simplify(expr.lhs) lhs_value = _try_eval(expr.lhs) if lhs_value is not None: if expr.exp == '+' and lhs_value == 0: return simplify(expr.rhs) if isinstance(expr.lhs, type_check.BinaryOperator) and \ expr.lhs.priority == expr.priority: if expr.lhs.exp == '+' or expr.lhs.exp == '*': expr_exp = expr.exp elif expr.lhs.exp == '-': if expr.exp == '+': expr_exp = '-' else: expr_exp = '+' else: assert False _, expr_func = binops[expr_exp] expr_rhs = type_check.BinaryOperator(expr.priority, expr.lhs.rhs, expr.rhs, expr_exp, expr_func) expr_rhs = simplify(expr_rhs) if isinstance(expr_rhs, type_check.Constant): return simplify( type_check.BinaryOperator(expr.lhs.priority, expr.lhs.lhs, expr_rhs, expr.lhs.exp, expr.lhs.func)) expr.lhs = simplify(expr.lhs) expr.rhs = simplify(expr.rhs) # if isinstance(expr, type_check.UnaryOperator): # expr.term = simplify(expr.term) return expr
def _make_binop(lhs, rhs, symbol): priority, func = binops[symbol] if not isinstance(rhs, ShapeElem): if lhs.value is None: return ShapeElem(None) expr = type_check.BinaryOperator(priority, lhs.expr, type_check.Constant(rhs), symbol, func) return ShapeElem(func(lhs.value, rhs), expr=expr) if not isinstance(lhs, ShapeElem): if rhs.value is None: return ShapeElem(None) expr = type_check.BinaryOperator(priority, type_check.Constant(lhs), rhs.expr, symbol, func) return ShapeElem(func(lhs, rhs.value), expr=expr) if lhs.value is None or rhs.value is None: return ShapeElem(None) expr = type_check.BinaryOperator(priority, lhs.expr, rhs.expr, symbol, func) return ShapeElem(func(lhs.value, rhs.value), expr=expr)
def setUp(self): x = T.Variable(1, 'x') y = T.Variable(1, 'y') f = lambda x, y: (x, y) self.op1 = T.BinaryOperator(7, x, y, '+', f) self.op2 = T.BinaryOperator(8, x, y, '+', f) self.op3 = T.BinaryOperator(9, x, y, '+', f) self.op4 = T.BinaryOperator(7, x, y, '+', f, True) self.op5 = T.BinaryOperator(8, x, y, '+', f, True) self.op6 = T.BinaryOperator(9, x, y, '+', f, True)
def setUp(self): x = T.Variable(1, 'x') y = T.Variable(1, 'y') def f(x, y): return x, y self.op1 = T.BinaryOperator(7, x, y, '+', f) self.op2 = T.BinaryOperator(8, x, y, '+', f) self.op3 = T.BinaryOperator(9, x, y, '+', f) self.op4 = T.BinaryOperator(7, x, y, '+', f, True) self.op5 = T.BinaryOperator(8, x, y, '+', f, True) self.op6 = T.BinaryOperator(9, x, y, '+', f, True)
def _make_binop_expr(lhs_expr, rhs_expr, symbol): priority, func = binops[symbol] return type_check.BinaryOperator(priority, lhs_expr, rhs_expr, symbol, func)