def test_match_sort_monomial_constant(self): x, l2 = root = tree('x * 2') self.assertEqualPos(match_sort_monomial(root), [P(root, swap_factors, (Scope(root), x, l2))]) root = tree('2x') self.assertEqualPos(match_sort_monomial(root), [])
def test_extract_nominator_term(self): root, expect = tree('(2a) / 3, 2 / 3 * a') l2, a = root[0] self.assertEqual(extract_nominator_term(root, (l2, a)), expect) root, expect, l1 = tree('a / 3, 1 / 3 * a, 1') self.assertEqual(extract_nominator_term(root, (l1, root[0])), expect)
def test_match_factor_out_abs_term_exponent(self): root = tree('|a ^ 2|') self.assertEqualPos(match_factor_out_abs_term(root), [P(root, factor_out_abs_exponent)]) root = tree('|a ^ b|') self.assertEqualPos(match_factor_out_abs_term(root), [])
def test_match_sort_polynome(self): x, x2 = root = tree('x + x ^ 2') self.assertEqualPos(match_sort_polynome(root), [P(root, swap_factors, (Scope(root), x, x2))]) root = tree('x + 2') self.assertEqualPos(match_sort_polynome(root), [])
def test_match_expand(self): a, bc, d = tree('a,b + c,d') b, c = bc root = a * bc self.assertEqualPos(match_expand(root), [P(root, expand_single, (Scope(root), a, bc))]) root = bc * a self.assertEqualPos(match_expand(root), [P(root, expand_single, (Scope(root), bc, a))]) root = a * bc * d self.assertEqualPos(match_expand(root), [P(root, expand_single, (Scope(root), a, bc)), P(root, expand_single, (Scope(root), bc, d))]) ab, cd = root = (a + b) * (c + d) self.assertEqualPos(match_expand(root), [P(root, expand_double, (Scope(root), ab, cd))]) (ab, cd), e = root = tree('(a + b)(c + d)e') self.assertEqualPos(match_expand(root), [P(root, expand_double, (Scope(root), ab, cd)), P(root, expand_single, (Scope(root), cd, e)), P(root, expand_single, (Scope(root), ab, e))])
def test_match_quotient_rule(self): root = tree('d/dx x ^ 2 / x') self.assertEqualPos(match_quotient_rule(root), [P(root, quotient_rule)]) root = tree('d/dx x ^ 2 / 2') self.assertEqualPos(match_quotient_rule(root), [])
def test_add_quadrants(self): s, c = root = tree('sin(t) ^ 2 + cos(t) ^ 2') self.assertEqual(add_quadrants(root, (Scope(root), s, c)), 1) root, expect = tree('cos(t) ^ 2 + a + sin(t) ^ 2, a + 1') (c, a), s = root self.assertEqual(add_quadrants(root, (Scope(root), s, c)), expect)
def test_negated_factor(self): a, b = root = tree('a * -b') self.assertEqual(negated_factor(root, (Scope(root), b)), -(a * +b)) (a, b), c = root = tree('a * (-b) * -c') self.assertEqual(negated_factor(root, (Scope(root), b)), -(a * +b * c)) self.assertEqual(negated_factor(root, (Scope(root), c)), -(a * b * +c))
def test_match_factor_out_abs_term_numeric(self): root = tree('|2|') self.assertEqualPos(match_factor_out_abs_term(root), [P(root, absolute_numeric)]) root = tree('|a|') self.assertEqualPos(match_factor_out_abs_term(root), [])
def test_match_sort_monomial_variables(self): y, x = root = tree('yx') self.assertEqualPos(match_sort_monomial(root), [P(root, swap_factors, (Scope(root), y, x))]) root = tree('xy') self.assertEqualPos(match_sort_monomial(root), [])
def test_match_divide_fractions(self): (a, b), c = root = tree('a / b / c') self.assertEqualPos(match_divide_fractions(root), [P(root, divide_fraction, (a, b, c))]) root = tree('a / (b / c)') self.assertEqualPos(match_divide_fractions(root), [P(root, divide_by_fraction, (a, b, c))])
def test_match_exponent_to_root(self): root = tree('a ^ (1 / 2)') self.assertEqualPos(match_exponent_to_root(root), [P(root, exponent_to_root)]) root = tree('a ^ (n / 2)') self.assertEqualPos(match_exponent_to_root(root), [P(root, exponent_to_root)])
def test_match_variable_power(self): root, x, l2 = tree('d/dx x ^ 2, x, 2') self.assertEqualPos(match_variable_power(root), [P(root, variable_root)]) root = tree('d/dx 2 ^ x') self.assertEqualPos(match_variable_power(root), [P(root, variable_exponent)])
def test_match_one_derivative(self): root = tree('d/dx x') self.assertEqualPos(match_one_derivative(root), [P(root, one_derivative)]) root = tree('d/dx x') self.assertEqualPos(match_one_derivative(root), [P(root, one_derivative)])
def test_match_zero_derivative(self): root = tree('d/dy x') self.assertEqualPos(match_zero_derivative(root), [P(root, zero_derivative)]) root = tree('d/dx 2') self.assertEqualPos(match_zero_derivative(root), [P(root, zero_derivative)])
def test_match_goniometric_chain_rule(self): root, x2 = tree('d/dx sin(x ^ 2), x ^ 2') self.assertEqualPos(match_goniometric(root), [P(root, chain_rule, (x2, sinus, ()))]) root = tree('d/dx cos(x ^ 2)') self.assertEqualPos(match_goniometric(root), [P(root, chain_rule, (x2, cosinus, ()))])
def test_multiply_fractions(self): (a, b), (c, d) = ab, cd = root = tree('a / b * (c / d)') self.assertEqual(multiply_fractions(root, (Scope(root), ab, cd)), a * c / (b * d)) (ab, e), cd = root = tree('a / b * e * (c / d)') self.assertEqual(multiply_fractions(root, (Scope(root), ab, cd)), a * c / (b * d) * e)
def test_match_remove_division_negation(self): root = tree('-(-a + b) / c') self.assertEqualPos(match_remove_division_negation(root), [P(root, remove_division_negation, (True, root[0]))]) root = tree('-a / (-b + c)') self.assertEqualPos(match_remove_division_negation(root), [P(root, remove_division_negation, (False, root[1]))])
def test_match_division_in_denominator(self): a, ((b, c), d) = root = tree('a / (b / c + d)') self.assertEqualPos(match_division_in_denominator(root), [P(root, multiply_with_term, (c,))]) a, ((d, (b, c)), e) = root = tree('a / (d + b / c + e)') self.assertEqualPos(match_division_in_denominator(root), [P(root, multiply_with_term, (c,))])
def test_match_reduce_sqrt_dividers(self): root = tree('sqrt(8)') self.assertEqualPos(match_reduce_sqrt(root), [P(root, split_dividers, (4, 2))]) root = tree('sqrt(27)') self.assertEqualPos(match_reduce_sqrt(root), [P(root, split_dividers, (9, 3))])
def test_remove_division_negation(self): (a, b), c = root = tree('-(-a + b) / c') self.assertEqual(remove_division_negation(root, (True, root[0])), (-a - b) / c) a, (b, c) = root = tree('-a / (-b + c)') self.assertEqual(remove_division_negation(root, (False, root[1])), +a / (-b - c))
def test_sum_rule_integral(self): ((f, g), h), x = root = tree('int (2x + 3x + 4x) dx') self.assertEqual(sum_rule_integral(root, (Scope(root[0]), f)), tree('int 2x dx + int (3x + 4x) dx')) self.assertEqual(sum_rule_integral(root, (Scope(root[0]), g)), tree('int 3x dx + int (2x + 4x) dx')) self.assertEqual(sum_rule_integral(root, (Scope(root[0]), h)), tree('int 4x dx + int (2x + 3x) dx'))
def test_match_factor_out_constant(self): root, c, cx = tree('int cx dx, c, cx') self.assertEqualPos(match_factor_out_constant(root), [P(root, factor_out_constant, (Scope(cx), c))]) root = tree('int -x2 dx') self.assertEqualPos(match_factor_out_constant(root), [P(root, factor_out_integral_negation)])
def test_divide_fraction(self): (a, b), c = root = tree('a / b / c') self.assertEqual(divide_fraction(root, (a, b, c)), a / (b * c)) (a, b), c = root = tree('-a / b / c') self.assertEqual(divide_fraction(root, (a, b, c)), -(a / (b * c))) root = tree('a / b / -c') self.assertEqual(divide_fraction(root, (a, b, c)), a / (b * -c))
def test_match_goniometric(self): root = tree('d/dx sin(x)') self.assertEqualPos(match_goniometric(root), [P(root, sinus)]) root = tree('d/dx cos(x)') self.assertEqualPos(match_goniometric(root), [P(root, cosinus)]) root = tree('d/dx tan(x)') self.assertEqualPos(match_goniometric(root), [P(root, tangens)])
def test_match_const_deriv_multiplication(self): root = tree('d/dx 2x') l2, x = root[0] self.assertEqualPos(match_const_deriv_multiplication(root), [P(root, const_deriv_multiplication, (Scope(root[0]), l2, x))]) (x, y), x = root = tree('d/dx xy') self.assertEqualPos(match_const_deriv_multiplication(root), [P(root, const_deriv_multiplication, (Scope(root[0]), y, x))])
def test_divide_by_fraction(self): a, (b, c) = root = tree('a / (b / c)') self.assertEqual(divide_by_fraction(root, (a, b, c)), a * c / b) a, (b, c) = root = tree('-a / (b / c)') self.assertEqual(divide_by_fraction(root, (a, b, c)), -(a * c / b)) root = tree('a / -(b / c)') self.assertEqual(divide_by_fraction(root, (a, b, c)), -(a * c / b))
def test_match_negated_factor(self): a, b = root = tree('a * -b') self.assertEqualPos(match_negated_factor(root), [P(root, negated_factor, (Scope(root), b))]) (a, b), c = root = tree('a * (-b) * -c') scope = Scope(root) self.assertEqualPos(match_negated_factor(root), [P(root, negated_factor, (scope, b)), P(root, negated_factor, (scope, c))])
def test_extract_fraction_terms_leaf(self): root, expect = tree('(ba) / a, a / a * b / 1') n, d = root self.assertEqual(extract_fraction_terms(root, (Scope(n), Scope(N(OP_MUL, d)), n[1], d)), expect) root, expect = tree('a / (ab), a / a * 1 / b') n, d = root self.assertEqual(extract_fraction_terms(root, (Scope(N(OP_MUL, n)), Scope(d), n, d[0])), expect)
def test_expand_single(self): root, expect = tree('a(b + c), ab + ac') a, bc = root self.assertEqualNodes(expand_single(root, (Scope(root), a, bc)), expect) root, expect = tree('a(b+c)d, a(bd + cd)') (a, bc), d = root self.assertEqualNodes(expand_single(root, (Scope(root), bc, d)), expect)
def test_substitute(self): x, a = tree('x, a') self.assertEqual(substitute(x, x, a), a) self.assertEqual(substitute(tree('x2'), x, a), tree('a2')) self.assertEqual(substitute(tree('y + x + 1'), x, a), tree('y + a + 1')) self.assertEqual(substitute(tree('1 - 2x'), x, a), tree('1 - 2a'))
def test_match_add_exponents_ternary(self): a, p, q, r = tree('a,p,q,r') (n0, n1), n2 = root = a**p * a**q * a**r possibilities = match_add_exponents(root) self.assertEqualPos(possibilities, [ P(root, add_exponents, (Scope(root), n0, n1, a, p, q)), P(root, add_exponents, (Scope(root), n0, n2, a, p, r)), P(root, add_exponents, (Scope(root), n1, n2, a, q, r)) ])
def test_match_constant_exponent(self): a0, a1, a2 = tree('a ^ 0, a ^ 1, a ^ 2') self.assertEqualPos(match_constant_exponent(a0), [P(a0, remove_power_of_zero, ())]) self.assertEqualPos(match_constant_exponent(a1), [P(a1, remove_power_of_one, ())]) self.assertEqualPos(match_constant_exponent(a2), [])
def test_duplicate_exponent(self): a, b, c, p = tree('a,b,c,p') root = (a * b)**p self.assertEqualNodes(duplicate_exponent(root, ([a, b], p)), a**p * b**p) root = (a * b * c)**p self.assertEqualNodes(duplicate_exponent(root, ([a, b, c], p)), a**p * b**p * c**p)
def test_construct_logarithm(self): self.assertEqual(str(tree('log n')), 'log(n)') self.assertEqual(str(tree('log(n)')), 'log(n)') self.assertEqual(str(tree('ln n')), 'ln(n)') self.assertEqual(str(tree('ln(n)')), 'ln(n)') self.assertEqual(str(tree('log_2 n')), 'log_2(n)') self.assertEqual(str(tree('log_2(n)')), 'log_2(n)') self.assertEqual(str(tree('log_g n')), 'log_g(n)') self.assertEqual(str(tree('log_(g + h) n')), 'log_(g + h)(n)')
def test_int_definite_integral(self): x2, a, b, oo, l2 = tree('x ^ 2, a, b, oo, 2') self.assertEqual(tree('(x ^ 2)_a'), int_def(x2, a, oo)) self.assertEqual(tree('(x ^ 2)_a^b'), int_def(x2, a, b)) self.assertEqual(tree('(x ^ 2)_-a^b'), int_def(x2, -a, b)) self.assertEqual(tree('(x ^ 2)_-a^-b'), int_def(x2, -a, -b)) self.assertNotEqual(tree('(x ^ 2)_-2a^b'), int_def(x2, -(l2 * a), b)) self.assertEqual(tree('(x ^ 2)_(-2a)^b'), int_def(x2, -(l2 * a), b))
def test_equals_nary(self): p0, p1, p2, p3, p4 = \ tree('a + b + c,a + c + b,b + a + c,b + c + a,a + b + d') self.assertTrue(p0.equals(p1)) self.assertTrue(p0.equals(p2)) self.assertTrue(p0.equals(p3)) self.assertTrue(p1.equals(p2)) self.assertTrue(p1.equals(p3)) self.assertTrue(p2.equals(p3)) self.assertFalse(p2.equals(p4))
def test_extract_sqrt_multiplicant(self): root, expect = tree('sqrt(2x), sqrt(2)sqrt(x)') l2, x = mul = root[0] self.assertEqual(extract_sqrt_multiplicant(root, ( Scope(mul), l2, )), expect) root, expect = tree('-sqrt(2x), -sqrt(2)sqrt(x)') l2, x = mul = root[0] self.assertEqual(extract_sqrt_multiplicant(root, ( Scope(mul), l2, )), expect) root, expect = tree('sqrt(2xy), sqrt(x)sqrt(2y)') (l2, x), y = mul = root[0] self.assertEqual(extract_sqrt_multiplicant(root, ( Scope(mul), x, )), expect)
def test_match_constant_logarithm(self): self.assertRaises(ValueError, match_constant_logarithm, tree('log_1(a)')) root = tree('log 1') self.assertEqualPos(match_constant_logarithm(root), [P(root, logarithm_of_one)]) root = tree('log 10') self.assertEqualPos(match_constant_logarithm(root), [P(root, base_equals_raised), P(root, divide_same_base)]) root = tree('log(a, a)') self.assertEqualPos(match_constant_logarithm(root), [P(root, base_equals_raised), P(root, divide_same_base)]) root = tree('log(a, b)') self.assertEqualPos(match_constant_logarithm(root), [P(root, divide_same_base)])
def test_construct_function_integral(self): self.assertEqual(str(tree('int x ^ 2')), 'int x ^ 2 dx') self.assertEqual(str(tree('int x ^ 2 dx')), 'int x ^ 2 dx') self.assertEqual(str(tree('int x ^ 2 dy')), 'int x ^ 2 dy') self.assertEqual(str(tree('int x ^ 2 dy')), 'int x ^ 2 dy') self.assertEqual(str(tree('int x + 1')), 'int x dx + 1') self.assertEqual(str(tree('int_a^b x ^ 2')), 'int_a^b x ^ 2 dx') self.assertEqual(str(tree('int_(a-b)^(a+b) x ^ 2')), 'int_(a - b)^(a + b) x ^ 2 dx')
def test_binary(self): a, b, c = tree('a, b, c') self.assertEqual(tree('a ^^ b'), a & b) self.assertEqual(tree('a vv b'), a | b) self.assertEqual(tree('a vv b vv c'), (a | b) | c) self.assertEqual(tree('a vv b ^^ c'), a | (b & c)) self.assertEqual(tree('a & b'), a & b) self.assertEqual(tree('a vv b & c'), a | (b & c))
def test_standard_radian(self): l0, l1, sq3, pi6, pi4, pi2, pi1 = tree('0,1,sqrt(3),1/6*pi,1/4*pi,1/2*pi,pi') self.assertEqual(standard_radian(sin(pi6), (OP_SIN, 1)), l1 / 2) self.assertEqual(standard_radian(sin(pi2), (OP_SIN, 4)), 1) self.assertEqual(standard_radian(cos(l0), (OP_COS, 0)), 1) self.assertEqual(standard_radian(tan(pi4), (OP_TAN, 3)), sq3) self.assertEqual(standard_radian(sin(pi1), (OP_SIN, 5)), 0) self.assertEqual(standard_radian(cos(pi1), (OP_COS, 5)), -1) self.assertEqual(standard_radian(-cos(pi1), (OP_COS, 5)), --l1)
def test_brackets(self): self.assertEqual(*tree('[x], x')) self.assertEqual(*tree('[x], (x)')) self.assertEqual(*tree('[x ^ 2], x ^ 2')) self.assertEqual(*tree('[x ^ 2](x), x ^ 2 * x')) self.assertEqual(*tree('{x}, x')) self.assertEqual(*tree('{x ^ 2}, x ^ 2'))
def test_delta_derivative(self): exp, x, d = tree('x ^ 2, x, d') self.assertEqual(tree('d/dx x ^ 2'), der(exp, x)) self.assertEqual(tree('d / dx x ^ 2'), der(exp, x)) self.assertEqual(tree('d/dx x ^ 2 + x'), der(exp, x) + x) self.assertEqual(tree('d/dx (x ^ 2 + x)'), der(exp + x, x)) self.assertEqual(tree('d/d'), d / d)
def test_derivative(self): x = tree('x') self.assertEqual(tree('[x]\''), der(x)) self.assertEqual(tree('x\''), der(x)) self.assertEqual(tree('[x]\'\''), der(der(x))) self.assertEqual(tree('(x)\'\''), der(der(x))) self.assertEqual(tree('x\'\''), der(der(x)))
def test_is_eliminateable_sqrt(self): self.assertFalse(is_eliminateable_sqrt(3)) self.assertTrue(is_eliminateable_sqrt(4)) self.assertTrue(is_eliminateable_sqrt(9)) self.assertTrue(is_eliminateable_sqrt(tree('9'))) self.assertFalse(is_eliminateable_sqrt(tree('-9'))) self.assertFalse(is_eliminateable_sqrt(tree('5'))) self.assertTrue(is_eliminateable_sqrt(tree('a ^ 2'))) self.assertFalse(is_eliminateable_sqrt(tree('a ^ 3'))) self.assertFalse(is_eliminateable_sqrt(tree('a')))
def test_add_fractions_with_negation(self): a, b, c, l1, l2, l3, l4 = tree('a,b,c,1,2,3,4') (((n0, n1), n2), n3), n4 = root = a + l2 / l2 + b + (-l3 / l4) + c self.assertEqualPos(match_add_fractions(root), [ P(root, equalize_denominators, (Scope(root), n1, n3, 4)), P(root, equalize_denominators, (Scope(root), n1, n3, 8)) ]) n0, n1 = root = l1 / l2 + l4 / l3 self.assertEqualPos( match_add_fractions(root), [P(root, equalize_denominators, (Scope(root), n0, n1, 6))]) (((n0, n1), n2), n3), n4 = root = a + l2 / l4 + b + (-l3 / l4) + c self.assertEqualPos(match_add_fractions(root), [P(root, add_nominators, (Scope(root), n1, n3))])
def test_match_multiply_numerics(self): i2, i3, i6, f2, f3, f6 = tree('2,3,6,2.0,3.0,6.0') root = i3 * i2 self.assertEqual(match_multiply_numerics(root), [P(root, multiply_numerics, (Scope(root), i3, i2))]) root = f3 * i2 self.assertEqual(match_multiply_numerics(root), [P(root, multiply_numerics, (Scope(root), f3, i2))]) root = i3 * f2 self.assertEqual(match_multiply_numerics(root), [P(root, multiply_numerics, (Scope(root), i3, f2))]) root = f3 * f2 self.assertEqual(match_multiply_numerics(root), [P(root, multiply_numerics, (Scope(root), f3, f2))])
def test_match_constant_division(self): a, zero = tree('a,0') root = a / zero with self.assertRaises(ZeroDivisionError) as cm: match_constant_division(root) self.assertEqual(cm.exception.message, 'Division by zero: a / 0.') root = a / 1 possibilities = match_constant_division(root) self.assertEqualPos(possibilities, [P(root, division_by_one, (a, ))]) root = zero / a possibilities = match_constant_division(root) self.assertEqualPos(possibilities, [P(root, division_of_zero, (a, ))]) root = a / a possibilities = match_constant_division(root) self.assertEqualPos(possibilities, [P(root, division_by_self, (a, ))])
def test_multiply_numerics(self): a, b, i2, i3, i6, f2, f3, f6 = tree('a,b,2,3,6,2.0,3.0,6.0') i3, i2 = root = tree('3 * 2') self.assertEqual(multiply_numerics(root, (Scope(root), i3, i2)), 6) f3, i2 = root = tree('3.0 * 2') self.assertEqual(multiply_numerics(root, (Scope(root), f3, i2)), 6.0) i3, f2 = root = tree('3 * 2.0') self.assertEqual(multiply_numerics(root, (Scope(root), i3, f2)), 6.0) f3, f2 = root = tree('3.0 * 2.0') self.assertEqual(multiply_numerics(root, (Scope(root), f3, f2)), 6.0) ((a, i3), i2), b = root = tree('a * 3 * 2 * b') self.assertEqualNodes(multiply_numerics(root, (Scope(root), i3, i2)), a * 6 * b)
def test_add_nominators(self): a, b, c = tree('a,b,c') n0, n1 = root = a / b + c / b self.assertEqualNodes(add_nominators(root, (Scope(root), n0, n1)), (a + c) / b) n0, n1 = root = a / b + -c / b self.assertEqualNodes(add_nominators(root, (Scope(root), n0, n1)), (a + -c) / b) n0, n1 = root = a / b + -(c / b) self.assertEqualNodes(add_nominators(root, (Scope(root), n0, n1)), (a + -c) / b) n0, n1 = root = a / -b + c / -b self.assertEqualNodes(add_nominators(root, (Scope(root), n0, n1)), (a + c) / -b) n0, n1 = root = a / -b + -c / -b self.assertEqualNodes(add_nominators(root, (Scope(root), n0, n1)), (a + -c) / -b)
def test_equalize_denominators(self): a, b, l1, l2, l3, l4 = tree('a,b,1,2,3,4') n0, n1 = root = l1 / l2 + l3 / l4 self.assertEqualNodes( equalize_denominators(root, (Scope(root), n0, n1, 4)), l2 / l4 + l3 / l4) n0, n1 = root = a / l2 + b / l4 self.assertEqualNodes( equalize_denominators(root, (Scope(root), n0, n1, 4)), (l2 * a) / l4 + b / l4) #2 / 2 - 3 / 4 -> 4 / 4 - 3 / 4 # Equalize denominators n0, n1 = root = l1 / l2 + (-l3 / l4) self.assertEqualNodes( equalize_denominators(root, (Scope(root), n0, n1, 4)), l2 / l4 + (-l3 / l4)) #2 / 2 - 3 / 4 -> 4 / 4 - 3 / 4 # Equalize denominators n0, n1 = root = a / l2 + (-b / l4) self.assertEqualNodes( equalize_denominators(root, (Scope(root), n0, n1, 4)), (l2 * a) / l4 + (-b / l4))
def test_negate_polynome(self): a, b = root = tree('-(a + b)') self.assertEqual(negate_polynome(root, ()), -a + -b) a, b = root = tree('-(a - b)') self.assertEqual(negate_polynome(root, ()), -a + -b)
def test_negated_nominator(self): l1, l2 = root = tree('(-1) / 2') self.assertEqual(negated_nominator(root, ()), -(+l1 / l2))
def test_match_negated_division_double(self): root = tree('(-1) / -2') self.assertEqualPos( match_negated_division(root), [P(root, negated_nominator), P(root, negated_denominator)])
def test_match_negated_division_none(self): self.assertEqual(match_negated_division(tree('1 / 2')), [])
def test_negated_denominator(self): l1, l2 = root = tree('1 / -2') self.assertEqual(negated_denominator(root, ()), -(l1 / +l2))
def test_negated_zero(self): root = tree('-0') self.assertEqual(negated_zero(root, ()), 0)
def test_combine_groups_negation(self): root, expect = tree('3a - 2a, -(3 + 2)a') (l3, a0), (l2, a1) = n0, n1 = root self.assertEqualNodes( combine_groups(root, (Scope(root), l3, a0, n0, l2, a1, n1)), expect)
def test_double_negation(self): root = tree('--a') self.assertEqual(double_negation(root, ()), ++root)