def test_zero_reduction(self): e = expr_parse('a * 0') f = pattern.transform(arithmetic.zero_reduction_multiplication, e) self.assertIn(expr_parse('0'), f) e = expr_parse('0 / a') f = pattern.transform(arithmetic.zero_reduction_division, e) self.assertIn(expr_parse('0'), f)
def test_reduction(self): e = { expr_parse('a + 1 * b'), expr_parse('a * 1 + b'), expr_parse('(a + 0) + b'), } f = reduce(e) g = {expr_parse('a + b')} self.assertEqual(f, g)
def test_distributivity_distribute(self): for e in ['(a + b) * c', '(b + a) * c', 'c * (a + b)', 'c * (b + a)']: f = pattern.transform( arithmetic.distributivity_distribute_multiplication, expr_parse(e)) self.assertIn(expr_parse('a * c + b * c'), f) e = expr_parse('-(a + b)') f = pattern.transform( arithmetic.distributivity_distribute_unary_subtraction_addition, e) self.assertIn(expr_parse('-a - b'), f)
def test_operator_precedence(self): neg_y = expression_factory(operators.UNARY_SUBTRACT_OP, self.y) expr = expression_factory( operators.ADD_OP, self.x, expression_factory(operators.MULTIPLY_OP, neg_y, self.z)) self.assertEqual(expr_parse('x + -y * z'), expr) expr = expression_factory( operators.MULTIPLY_OP, expression_factory(operators.ADD_OP, self.x, neg_y), self.z) self.assertEqual(expr_parse('(x + -y) * z'), expr)
def test_select_expression(self): expr = expression_factory( operators.TERNARY_SELECT_OP, expression_factory(operators.LESS_OP, self.x, self.i3), expression_factory(operators.ADD_OP, self.y, self.i1), expression_factory(operators.MULTIPLY_OP, self.y, self.i2)) self.assertEqual(expr_parse('x < 3 ? y + 1 : y * 2'), expr)
def setUp(self): self.x = Variable('x', auto_type) self.y = Variable('y', auto_type) self.z = Variable('z', auto_type) self.i1 = IntegerInterval(1) self.i2 = IntegerInterval(2) self.i3 = IntegerInterval(3) self.decl = {var.name: auto_type for var in (self.x, self.y, self.z)} self.expr_parse = lambda expr: expr_parse(expr, self.decl)
def test_compound_boolean_expression(self): bool_expr_1 = expression_factory( operators.UNARY_NEGATION_OP, expression_factory(operators.LESS_OP, self.x, self.i3)) bool_expr_2 = expression_factory(operators.NOT_EQUAL_OP, self.y, self.i1) bool_expr = expression_factory(operators.AND_OP, bool_expr_1, bool_expr_2) self.assertEqual(expr_parse('not x < 3 and y != 1'), bool_expr)
def test_variable_subscript(self): expr = expression_factory(operators.INDEX_ACCESS_OP, self.x, Subscript(self.i1)) self.assertEqual(expr_parse('x[1]'), expr) expr = expression_factory( operators.INDEX_ACCESS_OP, self.x, Subscript(expression_factory(operators.ADD_OP, self.y, self.i1))) self.assertEqual(expr_parse('x[y + 1]'), expr) expr = expression_factory(operators.INDEX_ACCESS_OP, self.x, Subscript(self.y, self.i1)) self.assertEqual(expr_parse('x[y, 1]'), expr) expr = expression_factory( operators.INDEX_ACCESS_OP, self.x, Subscript( expression_factory(operators.INDEX_ACCESS_OP, self.y, Subscript(self.i1)))) self.assertEqual(expr_parse('x[y[1]]'), expr)
def test_identity_reduction(self): e = expr_parse('0 + a') f = pattern.transform(arithmetic.identity_reduction_addition, e) self.assertIn(expr_parse('a'), f) e = expr_parse('1 * a') f = pattern.transform(arithmetic.identity_reduction_multiplication, e) self.assertIn(expr_parse('a'), f) e = expr_parse('a / 1') f = pattern.transform(arithmetic.identity_reduction_division, e) self.assertIn(expr_parse('a'), f)
def test_associativity(self): for e in ['(a + b) + c', '(b + a) + c', 'c + (a + b)', 'c + (b + a)']: f = pattern.transform(arithmetic.associativity_addition, expr_parse(e)) self.assertIn(expr_parse('a + (b + c)'), f) self.assertIn(expr_parse('b + (a + c)'), f) for e in ['(a * b) * c', '(b * a) * c', 'c * (a * b)', 'c * (b * a)']: f = pattern.transform(arithmetic.associativity_multiplication, expr_parse(e)) self.assertIn(expr_parse('a * (b * c)'), f) self.assertIn(expr_parse('b * (a * c)'), f)
def setUp(self): array_type = IntegerArrayType([3]) multi_array_type = IntegerArrayType([2, 3]) self.decl = { 'x': int_type, 'y': int_type, 'z': int_type, 'a': array_type, 'b': multi_array_type, } self.x = Variable('x', int_type) self.y = Variable('y', int_type) self.z = Variable('z', int_type) self.a = Variable('a', array_type) self.b = Variable('b', multi_array_type) self.expr_parse = lambda expr: expr_parse(expr, self.decl) self.stmt_parse = lambda prog: stmt_parse(prog, self.decl)
def _compile(expression): if isinstance(expression, str): return _compile(expr_parse(expression)) if is_expression(expression): return ExprMimic(expression.op, [_compile(a) for a in expression.args]) if is_variable(expression): return Val(expression.name) if is_constant(expression): return expression if isinstance(expression, ExprMimic): return expression if callable(expression): return expression raise ValueError( 'Do not know how to convert {!r} to an ExprMimic instance.'.format( expression))
def test_parsings(self): e = expr_parse('a + b + c + d') f = parsings(e) g = { expr_parse('((a + b) + c) + d'), expr_parse('(a + (b + c)) + d'), expr_parse('(a + (b + d)) + c'), expr_parse('(a + b) + (c + d)'), expr_parse('(a + c) + (b + d)'), expr_parse('(b + (a + c)) + d'), expr_parse('(b + (a + d)) + c'), expr_parse('(b + c) + (a + d)'), expr_parse('a + ((b + c) + d)'), expr_parse('a + (b + (c + d))'), expr_parse('a + (c + (b + d))'), expr_parse('b + ((a + c) + d)'), expr_parse('b + ((a + d) + c)'), expr_parse('b + (a + (c + d))'), expr_parse('c + ((a + b) + d)'), } self.assertEqual(f, g)
def test_constant_reduction(self): e = expr_parse('1 + 2') f = pattern.transform(arithmetic.constant_reduction, e) self.assertIn(expr_parse('3'), f)
def test_double_negation_reduction(self): e = expr_parse('--a') f = pattern.transform(arithmetic.double_negation_reduction, e) self.assertIn(expr_parse('a'), f)
def test_negation(self): e = expr_parse('a - b') f = pattern.transform(arithmetic.negation, e) self.assertIn(expr_parse('a + -b'), f)
def test_distributivity_collect(self): e = expr_parse('c * a + b * c') f = pattern.transform(arithmetic.distributivity_collect_multiplication, e) self.assertIn(expr_parse('(a + b) * c'), f)