test_rules_fractions.py 10 KB

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