test_rules_poly.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import unittest
  2. from src.rules.poly import match_combine_polynomes, combine_polynomes, \
  3. combine_numerics
  4. from src.possibilities import Possibility as P
  5. from src.node import ExpressionNode, ExpressionLeaf as L
  6. from src.parser import Parser
  7. from tests.parser import ParserWrapper
  8. def tree(exp, **kwargs):
  9. return ParserWrapper(Parser, **kwargs).run([exp])
  10. class TestRulesPoly(unittest.TestCase):
  11. def assertEqualPos(self, possibilities, expected):
  12. self.assertEqual(len(possibilities), len(expected))
  13. for p, e in zip(possibilities, expected):
  14. self.assertEqual(p.root, e.root)
  15. for pair in zip(p.args, e.args):
  16. self.assertEqual(*pair)
  17. self.assertEqual(p, e)
  18. def test_identifiers_basic(self):
  19. a1, a2 = root = tree('a+a')
  20. possibilities = match_combine_polynomes(root)
  21. self.assertEqualPos(possibilities,
  22. [P(root, combine_polynomes, (a1, a2, 1, 1, 'a', 1))])
  23. def test_identifiers_normal(self):
  24. a1, a2 = root = tree('a+2a')
  25. possibilities = match_combine_polynomes(root)
  26. self.assertEqualPos(possibilities,
  27. [P(root, combine_polynomes, (a1, a2, 1, 2, 'a', 1))])
  28. def test_identifiers_reverse(self):
  29. return
  30. # TODO: Move to normalisation test
  31. a1, a2 = root = tree('a+a*2')
  32. possibilities = match_combine_polynomes(root)
  33. self.assertEqualPos(possibilities,
  34. [P(root, combine_polynomes, (a1, a2, 1, 2, a1, 1))])
  35. def test_identifiers_exponent(self):
  36. a1, a2 = root = tree('a2+a2')
  37. possibilities = match_combine_polynomes(root)
  38. self.assertEqualPos(possibilities,
  39. [P(root, combine_polynomes, (a1, a2, 1, 1, 'a', 2))])
  40. def test_identifiers_coeff_exponent_left(self):
  41. a1, a2 = root = tree('2a3+a3')
  42. possibilities = match_combine_polynomes(root)
  43. self.assertEqualPos(possibilities,
  44. [P(root, combine_polynomes, (a1, a2, 2, 1, 'a', 3))])
  45. def test_identifiers_coeff_exponent_both(self):
  46. a1, a2 = root = tree('2a3+2a3')
  47. possibilities = match_combine_polynomes(root)
  48. self.assertEqualPos(possibilities,
  49. [P(root, combine_polynomes, (a1, a2, 2, 2, 'a', 3))])
  50. def test_basic_subexpressions(self):
  51. a_b, c, d = tree('a+b,c,d')
  52. left, right = root = tree('(a+b)^d + (a+b)^d')
  53. self.assertEqual(left, right)
  54. possibilities = match_combine_polynomes(root)
  55. self.assertEqualPos(possibilities,
  56. [P(root, combine_polynomes, (left, right, 1, 1, a_b, d))])
  57. left, right = root = tree('5(a+b)^d + 7(a+b)^d')
  58. possibilities = match_combine_polynomes(root)
  59. self.assertEqualPos(possibilities,
  60. [P(root, combine_polynomes, (left, right, 5, 7, a_b, d))])
  61. # TODO: Move to other strategy
  62. #left, right = root = tree('c(a+b)^d + c(a+b)^d')
  63. #self.assertEqual(left, right)
  64. #possibilities = match_combine_polynomes(root)
  65. #self.assertEqualPos(possibilities,
  66. # [P(root, combine_polynomes, (left, right, c, c, a_b, d))])
  67. def test_match_combine_numerics(self):
  68. l0, l1, l2 = tree('0,1,2')
  69. root = l0 + l1 + l2
  70. possibilities = match_combine_polynomes(root)
  71. self.assertEqualPos(possibilities,
  72. [P(root, combine_numerics, (l0, l1, l0, l1)),
  73. P(root, combine_numerics, (l0, l2, l0, l2)),
  74. P(root, combine_numerics, (l1, l2, l1, l2))])
  75. def test_match_combine_numerics_explicit_powers(self):
  76. l0, l1, l2 = tree('0^1,1*1,1*2^1')
  77. root = l0 + l1 + l2
  78. possibilities = match_combine_polynomes(root)
  79. self.assertEqualPos(possibilities,
  80. [P(root, combine_numerics, (l0, l1, l0[0], l1[1])),
  81. P(root, combine_numerics, (l0, l2, l0[0], l2[1][0])),
  82. P(root, combine_numerics, (l1, l2, l1[1], l2[1][0]))])
  83. def test_combine_numerics(self):
  84. l0, l1 = tree('1,2')
  85. self.assertEqual(combine_numerics(l0 + l1, (l0, l1, 1, 2)), 3)
  86. def test_combine_numerics_nary(self):
  87. l0, a, l1 = tree('1,a,2')
  88. self.assertEqual(combine_numerics(l0 + a + l1, (l0, l1, 1, 2)),
  89. L(3) + a)
  90. def test_combine_polynomes(self):
  91. # 2a + 3a -> (2 + 3) * a
  92. l0, a, l1, l2 = tree('2,a,3,1')
  93. root = l0 * a + l1 * a
  94. left, right = root
  95. replacement = combine_polynomes(root, (left, right, l0, l1, a, 1))
  96. self.assertEqualNodes(replacement, (l0 + l1) * a)
  97. # a + 3a -> (1 + 3) * a
  98. root = a + l1 * a
  99. left, right = root
  100. replacement = combine_polynomes(root, (left, right, l2, l1, a, 1))
  101. self.assertEqualNodes(replacement, (l2 + l1) * a)
  102. # 2a + a -> (2 + 1) * a
  103. root = l0 * a + a
  104. left, right = root
  105. replacement = combine_polynomes(root, (left, right, l0, l2, a, 1))
  106. self.assertEqualNodes(replacement, (l0 + 1) * a)
  107. # a + a -> (1 + 1) * a
  108. root = a + a
  109. left, right = root
  110. replacement = combine_polynomes(root, (left, right, l2, l2, a, 1))
  111. self.assertEqualNodes(replacement, (l2 + 1) * a)
  112. def assertEqualNodes(self, a, b):
  113. if not isinstance(a, ExpressionNode):
  114. return self.assertEqual(a, b)
  115. self.assertIsInstance(b, ExpressionNode)
  116. self.assertEqual(a.op, b.op)
  117. for ca, cb in zip(a, b):
  118. self.assertEqualNodes(ca, cb)