test_rules_lineq.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. # This file is part of TRS (http://math.kompiler.org)
  2. #
  3. # TRS is free software: you can redistribute it and/or modify it under the
  4. # terms of the GNU Affero General Public License as published by the Free
  5. # Software Foundation, either version 3 of the License, or (at your option) any
  6. # later version.
  7. #
  8. # TRS is distributed in the hope that it will be useful, but WITHOUT ANY
  9. # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  10. # A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  11. # details.
  12. #
  13. # You should have received a copy of the GNU Affero General Public License
  14. # along with TRS. If not, see <http://www.gnu.org/licenses/>.
  15. from src.rules.lineq import match_move_term, swap_sides, subtract_term, \
  16. divide_term, multiply_term, split_absolute_equation, \
  17. match_multiple_equations, substitute_variable, match_double_case, \
  18. double_case
  19. from src.node import Scope
  20. from src.possibilities import Possibility as P
  21. from tests.rulestestcase import RulesTestCase, tree
  22. class TestRulesLineq(RulesTestCase):
  23. def test_match_move_term_swap(self):
  24. root = tree('x = b')
  25. self.assertEqualPos(match_move_term(root), [])
  26. root = tree('a = bx')
  27. self.assertEqualPos(match_move_term(root), [P(root, swap_sides)])
  28. def test_match_move_term_subtract(self):
  29. root, a = tree('x + a = b, a')
  30. self.assertEqualPos(match_move_term(root),
  31. [P(root, subtract_term, (a,))])
  32. root, cx = tree('x = b + cx, cx')
  33. self.assertEqualPos(match_move_term(root),
  34. [P(root, subtract_term, (cx,))])
  35. def test_match_move_term_divide(self):
  36. root, a = tree('ax = b, a')
  37. self.assertEqualPos(match_move_term(root),
  38. [P(root, divide_term, (a,))])
  39. def test_match_move_term_multiply(self):
  40. root, a = tree('x / a = b, a')
  41. self.assertEqualPos(match_move_term(root),
  42. [P(root, multiply_term, (a,))])
  43. root, x = tree('a / x = b, x')
  44. self.assertEqualPos(match_move_term(root),
  45. [P(root, multiply_term, (x,))])
  46. root, l1 = tree('-x = b, -1')
  47. self.assertEqualPos(match_move_term(root),
  48. [P(root, multiply_term, (l1,))])
  49. def test_match_move_term_absolute(self):
  50. root = tree('|x| = 2')
  51. self.assertEqualPos(match_move_term(root),
  52. [P(root, split_absolute_equation)])
  53. root = tree('|x - 1| = 2')
  54. self.assertEqualPos(match_move_term(root),
  55. [P(root, split_absolute_equation)])
  56. def test_swap_sides(self):
  57. root, expect = tree('a = bx, bx = a')
  58. self.assertEqual(swap_sides(root, ()), expect)
  59. def test_subtract_term(self):
  60. root, a, expect = tree('x + a = b, a, x + a - a = b - a')
  61. self.assertEqual(subtract_term(root, (a,)), expect)
  62. def test_divide_term(self):
  63. root, a, expect = tree('x * a = b, a, (xa) / a = b / a')
  64. self.assertEqual(divide_term(root, (a,)), expect)
  65. def test_multiply_term(self):
  66. root, a, expect = tree('x / a = b, a, x / a * a = b * a')
  67. self.assertEqual(multiply_term(root, (a,)), expect)
  68. def test_split_absolute_equation(self):
  69. root, expect = tree('|x| = 2, x = 2 vv x = -2')
  70. self.assertEqual(split_absolute_equation(root, ()), expect)
  71. # FIXME: following call exeeds recursion limit
  72. # FIXME: self.assertValidate('|x - 1| = 2', 'x = -1 vv x = 3')
  73. def test_match_move_term_chain_negation(self):
  74. self.assertRewrite([
  75. '2x + 3 = -3x - 2',
  76. '2x + 3 - 3 = -3x - 2 - 3',
  77. '2x + 0 = -3x - 2 - 3',
  78. '2x = -3x - 2 - 3',
  79. '2x = -3x - 5',
  80. '2x - -3x = -3x - 5 - -3x',
  81. '2x + 3x = -3x - 5 - -3x',
  82. '2x + 3x = -3x - 5 + 3x',
  83. '(2 + 3)x = -3x - 5 + 3x',
  84. '5x = -3x - 5 + 3x',
  85. '5x = (-1 + 1)3x - 5',
  86. '5x = 0 * 3x - 5',
  87. '5x = 0 - 5',
  88. '5x = -5',
  89. '(5x) / 5 = (-5) / 5',
  90. '5 / 5 * x = (-5) / 5',
  91. '1x = (-5) / 5',
  92. 'x = (-5) / 5',
  93. 'x = -5 / 5',
  94. 'x = -1',
  95. ])
  96. def test_match_move_term_chain_advanced(self):
  97. self.assertRewrite([
  98. '-x = a',
  99. '(-x) * -1 = a * -1',
  100. '-x * -1 = a * -1',
  101. '--x * 1 = a * -1',
  102. '--x = a * -1',
  103. 'x = a * -1',
  104. 'x = -a * 1',
  105. 'x = -a',
  106. ])
  107. def test_match_multiple_equations(self):
  108. eq0, eq1 = root = tree('x = 2 ^^ ay + x = 3')
  109. x = eq0[0]
  110. self.assertEqualPos(match_multiple_equations(root),
  111. [P(root, substitute_variable, (Scope(root), x, 2, eq1))])
  112. root = tree('x + y = 2 ^^ ay + x = 3')
  113. self.assertEqualPos(match_multiple_equations(root), [])
  114. root = tree('x + y ^^ ay + x = 3')
  115. self.assertEqualPos(match_multiple_equations(root), [])
  116. def test_substitute_variable(self):
  117. root, expect = tree('x = 2 ^^ ay + x = 3, x = 2 ^^ ay + 2 = 3')
  118. (x, l2), eq = root
  119. self.assertEqual(substitute_variable(root, ((Scope(root), x, l2, eq))),
  120. expect)
  121. def test_match_double_case(self):
  122. a, b = root = tree('x = 2 vv x = 2')
  123. self.assertEqualPos(match_double_case(root),
  124. [P(root, double_case, (Scope(root), a, b))])
  125. root = tree('x = 2 vv x = -2')
  126. self.assertEqualPos(match_double_case(root), [])
  127. def test_double_case(self):
  128. a, b = root = tree('x = 2 vv x = 2, x = 2')
  129. self.assertEqual(double_case(root, (Scope(root), a, b)), a)