test_rules_fractions.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. from src.rules.fractions import match_constant_division, division_by_one, \
  2. division_of_zero, division_by_self, match_add_constant_fractions, \
  3. equalize_denominators, add_nominators, match_multiply_fractions, \
  4. multiply_fractions, multiply_with_fraction, \
  5. match_equal_fraction_parts, divide_fraction_parts
  6. from src.node import Scope
  7. from src.possibilities import Possibility as P
  8. from tests.rulestestcase import RulesTestCase, tree
  9. class TestRulesFractions(RulesTestCase):
  10. def test_match_constant_division(self):
  11. a, zero = tree('a,0')
  12. root = a / zero
  13. with self.assertRaises(ZeroDivisionError) as cm:
  14. match_constant_division(root)
  15. self.assertEqual(cm.exception.message, 'Division by zero: a / 0.')
  16. root = a / 1
  17. possibilities = match_constant_division(root)
  18. self.assertEqualPos(possibilities, [P(root, division_by_one, (a,))])
  19. root = zero / a
  20. possibilities = match_constant_division(root)
  21. self.assertEqualPos(possibilities, [P(root, division_of_zero, (a,))])
  22. root = a / a
  23. possibilities = match_constant_division(root)
  24. self.assertEqualPos(possibilities, [P(root, division_by_self, (a,))])
  25. def test_division_by_one(self):
  26. a = tree('a')
  27. root = a / 1
  28. self.assertEqualNodes(division_by_one(root, (a,)), a)
  29. def test_division_of_zero(self):
  30. a, zero = tree('a,0')
  31. root = zero / a
  32. self.assertEqualNodes(division_of_zero(root, ()), zero)
  33. def test_division_by_self(self):
  34. a, one = tree('a,1')
  35. root = a / a
  36. self.assertEqualNodes(division_by_self(root, ()), one)
  37. def test_match_add_constant_fractions(self):
  38. a, b, c, l1, l2, l3, l4 = tree('a,b,c,1,2,3,4')
  39. n0, n1 = root = l1 / l2 + l3 / l4
  40. possibilities = match_add_constant_fractions(root)
  41. self.assertEqualPos(possibilities,
  42. [P(root, equalize_denominators, (Scope(root), n0, n1, 4)),
  43. P(root, equalize_denominators, (Scope(root), n0, n1, 8))])
  44. (((n0, n1), n2), n3), n4 = root = a + l1 / l2 + b + l3 / l4 + c
  45. possibilities = match_add_constant_fractions(root)
  46. self.assertEqualPos(possibilities,
  47. [P(root, equalize_denominators, (Scope(root), n1, n3, 4)),
  48. P(root, equalize_denominators, (Scope(root), n1, n3, 8))])
  49. n0, n1 = root = l2 / l4 + l3 / l4
  50. possibilities = match_add_constant_fractions(root)
  51. self.assertEqualPos(possibilities,
  52. [P(root, add_nominators, (n0, n1))])
  53. (((n0, n1), n2), n3), n4 = root = a + l2 / l4 + b + l3 / l4 + c
  54. possibilities = match_add_constant_fractions(root)
  55. self.assertEqualPos(possibilities,
  56. [P(root, add_nominators, (n1, n3))])
  57. def test_add_constant_fractions_with_negation(self):
  58. a, b, c, l1, l2, l3, l4 = tree('a,b,c,1,2,3,4')
  59. (((n0, n1), n2), n3), n4 = root = a + l2 / l2 + b + (-l3 / l4) + c
  60. possibilities = match_add_constant_fractions(root)
  61. self.assertEqualPos(possibilities,
  62. [P(root, equalize_denominators, (Scope(root), n1, n3, 4)),
  63. P(root, equalize_denominators, (Scope(root), n1, n3, 8))])
  64. (((n0, n1), n2), n3), n4 = root = a + l2 / l4 + b + (-l3 / l4) + c
  65. possibilities = match_add_constant_fractions(root)
  66. self.assertEqualPos(possibilities,
  67. [P(root, add_nominators, (n1, n3))])
  68. def test_equalize_denominators(self):
  69. a, b, l1, l2, l3, l4 = tree('a,b,1,2,3,4')
  70. n0, n1 = root = l1 / l2 + l3 / l4
  71. self.assertEqualNodes(equalize_denominators(root,
  72. (Scope(root), n0, n1, 4)), l2 / l4 + l3 / l4)
  73. n0, n1 = root = a / l2 + b / l4
  74. self.assertEqualNodes(equalize_denominators(root,
  75. (Scope(root), n0, n1, 4)), (l2 * a) / l4 + b /
  76. l4)
  77. #2 / 2 - 3 / 4 -> 4 / 4 - 3 / 4 # Equalize denominators
  78. n0, n1 = root = l1 / l2 + (-l3 / l4)
  79. self.assertEqualNodes(equalize_denominators(root,
  80. (Scope(root), n0, n1, 4)), l2 / l4 + (-l3 / l4))
  81. #2 / 2 - 3 / 4 -> 4 / 4 - 3 / 4 # Equalize denominators
  82. n0, n1 = root = a / l2 + (-b / l4)
  83. self.assertEqualNodes(equalize_denominators(root,
  84. (Scope(root), n0, n1, 4)), (l2 * a) / l4 + (-b / l4))
  85. def test_add_nominators(self):
  86. a, b, c = tree('a,b,c')
  87. n0, n1 = root = a / b + c / b
  88. self.assertEqualNodes(add_nominators(root, (n0, n1)), (a + c) / b)
  89. n0, n1 = root = a / b + -c / b
  90. self.assertEqualNodes(add_nominators(root, (n0, n1)), (a + -c) / b)
  91. n0, n1 = root = a / b + -(c / b)
  92. self.assertEqualNodes(add_nominators(root, (n0, n1)), (a + -c) / b)
  93. n0, n1 = root = a / -b + c / -b
  94. self.assertEqualNodes(add_nominators(root, (n0, n1)), (a + c) / -b)
  95. n0, n1 = root = a / -b + -c / -b
  96. self.assertEqualNodes(add_nominators(root, (n0, n1)), (a + -c) / -b)
  97. def test_match_multiply_fractions(self):
  98. (a, b), (c, d) = ab, cd = root = tree('a / b * (c / d)')
  99. self.assertEqualPos(match_multiply_fractions(root),
  100. [P(root, multiply_fractions, (Scope(root), ab, cd))])
  101. (ab, e), cd = root = tree('a / b * e * (c / d)')
  102. self.assertEqualPos(match_multiply_fractions(root),
  103. [P(root, multiply_fractions, (Scope(root), ab, cd)),
  104. P(root, multiply_with_fraction, (Scope(root), e, ab)),
  105. P(root, multiply_with_fraction, (Scope(root), e, cd))])
  106. def test_multiply_fractions(self):
  107. (a, b), (c, d) = ab, cd = root = tree('a / b * (c / d)')
  108. self.assertEqual(multiply_fractions(root, (Scope(root), ab, cd)),
  109. a * c / (b * d))
  110. (ab, e), cd = root = tree('a / b * e * (c / d)')
  111. self.assertEqual(multiply_fractions(root, (Scope(root), ab, cd)),
  112. a * c / (b * d) * e)
  113. def test_match_equal_fraction_parts(self):
  114. (a, b), (c, a) = root = tree('ab / (ca)')
  115. self.assertEqualPos(match_equal_fraction_parts(root),
  116. [P(root, divide_fraction_parts, (a, [a, b], [c, a], 0, 1))])
  117. (a, b), a = root = tree('ab / a')
  118. self.assertEqualPos(match_equal_fraction_parts(root),
  119. [P(root, divide_fraction_parts, (a, [a, b], [a], 0, 0))])
  120. a, (a, b) = root = tree('a / (ab)')
  121. self.assertEqualPos(match_equal_fraction_parts(root),
  122. [P(root, divide_fraction_parts, (a, [a], [a, b], 0, 0))])
  123. root = tree('abc / (cba)')
  124. ((a, b), c) = root[0]
  125. s0, s1 = [a, b, c], [c, b, a]
  126. self.assertEqualPos(match_equal_fraction_parts(root),
  127. [P(root, divide_fraction_parts, (a, s0, s1, 0, 2)),
  128. P(root, divide_fraction_parts, (b, s0, s1, 1, 1)),
  129. P(root, divide_fraction_parts, (c, s0, s1, 2, 0))])
  130. root = tree('-a / a')
  131. self.assertEqualPos(match_equal_fraction_parts(root),
  132. [P(root, divide_fraction_parts, (a, [-a], [a], 0, 0))])
  133. def test_divide_fraction_parts(self):
  134. (a, b), (c, a) = root = tree('ab / (ca)')
  135. result = divide_fraction_parts(root, (a, [a, b], [c, a], 0, 1))
  136. self.assertEqual(result, b / c)
  137. (a, b), a = root = tree('ab / a')
  138. result = divide_fraction_parts(root, (a, [a, b], [a], 0, 0))
  139. self.assertEqual(result, b / 1)
  140. root, l1 = tree('a / (ab), 1')
  141. a, (a, b) = root
  142. result = divide_fraction_parts(root, (a, [a], [a, b], 0, 0))
  143. self.assertEqual(result, l1 / b)
  144. root = tree('abc / (cba)')
  145. ((a, b), c) = root[0]
  146. result = divide_fraction_parts(root, (a, [a, b, c], [c, b, a], 0, 2))
  147. self.assertEqual(result, b * c / (c * b))
  148. result = divide_fraction_parts(root, (b, [a, b, c], [c, b, a], 1, 1))
  149. self.assertEqual(result, a * c / (c * a))
  150. result = divide_fraction_parts(root, (c, [a, b, c], [c, b, a], 2, 0))
  151. self.assertEqual(result, a * b / (b * a))
  152. (a, b), a = root = tree('-ab / a')
  153. result = divide_fraction_parts(root, (a, [-a, b], [a], 0, 0))
  154. self.assertEqual(result, -b / 1)