Просмотр исходного кода

Simplified get_polynome and added TODOs for get_polynome.

Sander Mathijs van Veen 14 лет назад
Родитель
Сommit
083c76613c
3 измененных файлов с 82 добавлено и 17 удалено
  1. 26 13
      src/node.py
  2. 11 3
      src/rules/poly.py
  3. 45 1
      tests/test_rules_poly.py

+ 26 - 13
src/node.py

@@ -1,3 +1,4 @@
+# vim: set fileencoding=utf-8 :
 import os.path
 import os.path
 import sys
 import sys
 
 
@@ -96,26 +97,38 @@ class ExpressionNode(Node, ExpressionBase):
     def get_polynome(self):
     def get_polynome(self):
         """
         """
         Identifier nodes of all polynomes, tuple format is:
         Identifier nodes of all polynomes, tuple format is:
-        (identifier, exponent, coefficient, literal_exponent)
+        (root, exponent, coefficient, literal_exponent)
         """
         """
+        # TODO: change "get_polynome" -> "extract_polynome".
+        # TODO: change retval of c * r ^ e to (c, r, e).
+
+        # TODO: normalize c * r and r * c -> c * r. Otherwise, the tuple will
+        # not match if the order of the expression is different. Example:
+        #   r ^ e * c == c * r ^ e
+        # without normalization, those expressions will not match.
+
+        # rule: r ^ e
         if self.is_power():
         if self.is_power():
-            # a ^ e
             return (self[0], self[1], ExpressionLeaf(1), True)
             return (self[0], self[1], ExpressionLeaf(1), True)
 
 
         if self.op != OP_MUL:
         if self.op != OP_MUL:
             return
             return
 
 
-        for n0, n1 in [(0, 1), (1, 0)]:
-            if self[n0].is_numeric():
-                if self[n1].is_identifier():
-                    # c * a
-                    return (self[n1], ExpressionLeaf(1), self[n0], False)
-                elif self[n1].is_power():
-                    # c * a ^ e
-                    coeff, power = self
-                    root, exponent = power
-
-                    return (root, exponent, coeff, True)
+        # expression: c * r ^ e ; tree:
+        #
+        #    *
+        #   ╭┴───╮
+        #   c    ^
+        #      ╭─┴╮
+        #      r  e
+        #
+        # rule: c * r ^ e | (r ^ e) * c
+        for i, j in [(0, 1), (1, 0)]:
+            if self[j].is_power():
+                return (self[j][0], self[j][1], self[i], True)
+
+        # rule: c * r | r * c
+        return (self[0], ExpressionLeaf(1), self[1], False)
 
 
     def get_scope(self):
     def get_scope(self):
         """"""
         """"""

+ 11 - 3
src/rules/poly.py

@@ -72,11 +72,14 @@ def match_combine_factors(node):
     # a         = 1 * a ^ 1
     # a         = 1 * a ^ 1
     #
     #
     # Identifier nodes of all polynomes, tuple format is:
     # Identifier nodes of all polynomes, tuple format is:
-    #   (identifier, exponent, coefficient, literal_coefficient)
+    #   (root, exponent, coefficient, literal_coefficient)
     polys = []
     polys = []
 
 
+    print 'match combine factors:', node
+
     for n in node.get_scope():
     for n in node.get_scope():
         polynome = n.get_polynome()
         polynome = n.get_polynome()
+        print 'n:', n, 'polynome:', polynome
 
 
         if polynome:
         if polynome:
             polys.append((n, polynome))
             polys.append((n, polynome))
@@ -107,8 +110,13 @@ def combine_polynomes(root, args):
     left, right = args
     left, right = args
     nl, pl = left
     nl, pl = left
     nr, pr = right
     nr, pr = right
-    c0, r0, e0 = pl
-    c1, r1, e1 = pr
+
+    # TODO: verify that the two commented expression below are invalid and the
+    # following two expressions are right.
+    r0, e0, c0 = pl
+    r1, e1, c1 = pr
+    #c0, r0, e0 = pl
+    #c1, r1, e1 = pr
 
 
     scope = root.get_scope()
     scope = root.get_scope()
 
 

+ 45 - 1
tests/test_rules_poly.py

@@ -26,9 +26,13 @@ class TestRulesPoly(unittest.TestCase):
 
 
         for p, e in zip(possibilities, expected):
         for p, e in zip(possibilities, expected):
             self.assertEqual(p.root, e.root)
             self.assertEqual(p.root, e.root)
+
+            for pair in zip(p.args, e.args):
+                self.assertEqual(*pair)
+
             self.assertEqual(p, e)
             self.assertEqual(p, e)
 
 
-    def test_numeric(self):
+    def test_basic(self):
         l1, l2 = root = tree('1+2')
         l1, l2 = root = tree('1+2')
         self.assertEqualPos(match_combine_factors(root),
         self.assertEqualPos(match_combine_factors(root),
                 [P(root, combine_polynomes, ((l1, (l1, l1, l1, False)),
                 [P(root, combine_polynomes, ((l1, (l1, l1, l1, False)),
@@ -44,7 +48,47 @@ class TestRulesPoly(unittest.TestCase):
                 [P(root, combine_polynomes, ((a1, (a1, l1, l1, False)),
                 [P(root, combine_polynomes, ((a1, (a1, l1, l1, False)),
                                              (a2, (a2[1], l1, l2, False))))])
                                              (a2, (a2[1], l1, l2, False))))])
 
 
+        a1, a2 = root = tree('a+a*2')
+        self.assertEqualPos(match_combine_factors(root),
+                [P(root, combine_polynomes, ((a1, (a1, l1, l1, False)),
+                                             (a2, (a2[1], l1, l2, False))))])
+
         a1, a2 = root = tree('a2+a2')
         a1, a2 = root = tree('a2+a2')
         self.assertEqualPos(match_combine_factors(root),
         self.assertEqualPos(match_combine_factors(root),
                 [P(root, combine_polynomes, ((a1, (a1[0], l2, l1, True)),
                 [P(root, combine_polynomes, ((a1, (a1[0], l2, l1, True)),
                                              (a2, (a2[0], l2, l1, True))))])
                                              (a2, (a2[0], l2, l1, True))))])
+
+
+    def test_basic_subexpressions(self):
+        return # TODO: test this!!
+        a_b = tree('a+b')
+        c, d = tree('c+d')
+        l1 = tree('1')
+        l5, l7 = tree('5+7')
+
+        left, right = root = tree('(a+b)^d + (a+b)^d')
+
+        self.assertEqual(left, right)
+        self.assertEqualPos(match_combine_factors(root),
+                [P(root, combine_polynomes, ((left, (a_b, d, l1, True)),
+                                             (right, (a_b, d, l1, True))))])
+
+        left, right = root = tree('5(a+b)^d + 7(a+b)^d')
+
+        #<Possibility root="5 * (a + b) ^ d + 7 * (a + b) ^ d"
+        #    handler=combine_polynomes args=((<src.node.ExpressionNode object at
+        #    0x9fb2e0c>, (<src.node.ExpressionNode object at 0x9fb2c2c>,
+        #    'd', 5, True)), (<src.node.ExpressionNode object at
+        #    0x9fb438c>, (<src.node.ExpressionNode object at
+        #    0x9fb2f0c>, 'd', 7, True)))>
+
+        self.assertEqualPos(match_combine_factors(root),
+                [P(root, combine_polynomes, ((left, (a_b, d, l5, True)),
+                                             (right, (a_b, d, l7, True))))])
+
+        left, right = root = tree('c(a+b)^d + c(a+b)^d')
+
+        self.assertEqual(left, right)
+        self.assertEqualPos(match_combine_factors(root),
+                [P(root, combine_polynomes, ((left, (left[0], c, d, True)),
+                                             (right, (right[0], c, d, True))))])