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

add_exponents in powers rules now supports negated iedntifiers.

Taddeus Kroes 14 лет назад
Родитель
Сommit
261300cc97
3 измененных файлов с 24 добавлено и 10 удалено
  1. 8 5
      src/rules/powers.py
  2. 8 5
      tests/test_leiden_oefenopgave_v12.py
  3. 8 0
      tests/test_rules_powers.py

+ 8 - 5
src/rules/powers.py

@@ -1,7 +1,7 @@
 from itertools import combinations
 
 from ..node import ExpressionNode as N, ExpressionLeaf as L, Scope, \
-                   OP_MUL, OP_DIV, OP_POW, OP_ADD
+                   OP_MUL, OP_DIV, OP_POW, OP_ADD, negate
 from ..possibilities import Possibility as P, MESSAGES
 from ..translate import _
 
@@ -12,6 +12,7 @@ def match_add_exponents(node):
     a * a^q    ->  a^(1 + q)
     a^p * a    ->  a^(p + 1)
     a * a      ->  a^(1 + 1)
+    -a * a^q   ->  -a^(1 + q)
     """
     assert node.is_op(OP_MUL)
 
@@ -20,12 +21,12 @@ def match_add_exponents(node):
     scope = Scope(node)
 
     for n in scope:
+        # Order powers by their roots, e.g. a^p and a^q are put in the same
+        # list because of the mutual 'a'
         if n.is_identifier():
-            s = n
+            s = negate(n, 0)
             exponent = L(1)
         elif n.is_op(OP_POW):
-            # Order powers by their roots, e.g. a^p and a^q are put in the same
-            # list because of the mutual 'a'
             s, exponent = n
         else:  # pragma: nocover
             continue
@@ -53,8 +54,10 @@ def add_exponents(root, args):
     """
     scope, n0, n1, a, p, q = args
 
+    # TODO: combine exponent negations
+
     # Replace the left node with the new expression
-    scope.replace(n0, a ** (p + q))
+    scope.replace(n0, (a ** (p + q)).negate(n0.negated + n1.negated))
 
     # Remove the right node
     scope.remove(n1)

+ 8 - 5
tests/test_leiden_oefenopgave_v12.py

@@ -24,11 +24,14 @@ class TestLeidenOefenopgaveV12(TestCase):
             'x(-72 * x ^ 2 + 96x) + x * -32',
             'x * -72 * x ^ 2 + x * 96x + x * -32',
             '-x * 72 * x ^ 2 + x * 96x + x * -32',
-            '-x * 72 * x ^ 2 + x ^ (1 + 1) * 96 + x * -32',
-            '-x * 72 * x ^ 2 + x ^ 2 * 96 + x * -32',
-            '-x * 72 * x ^ 2 + x ^ 2 * 96 - x * 32'])
-            # FIXME: '-x ^ (1 + 2) * 72 + x ^ 2 * 96 - x * 32',
-            # FIXME: '-x ^ 3 * 72 + x ^ 2 * 96 - x * 32',
+            '-(x ^ (1 + 2)) * 72 + x * 96x + x * -32',
+            '-(x ^ 3) * 72 + x * 96x + x * -32',
+            '-(x ^ 3) * 72 + x ^ (1 + 1) * 96 + x * -32',
+            '-(x ^ 3) * 72 + x ^ 2 * 96 + x * -32',
+            '-(x ^ 3) * 72 + x ^ 2 * 96 - x * 32',
+            '-(x ^ 3) * 72 + x ^ 2 * 96 - x * 32'])
+            # TODO: Should powers have a higher precedence than negation in
+            #       printing?
             # FIXME: '-72x ^ 3 + x ^ 2 * 96 - x * 32',
             # FIXME: '-72x ^ 3 + 96x ^ 2 - x * 32',
             # FIXME: '-72x ^ 3 + 96x ^ 2 - 32x'])

+ 8 - 0
tests/test_rules_powers.py

@@ -47,6 +47,14 @@ class TestRulesPowers(RulesTestCase):
         self.assertEqualPos(possibilities,
                 [P(root, add_exponents, (Scope(root), n0, n1, a, p, q))])
 
+    def test_match_add_exponents_negated(self):
+        a, q = tree('a,q')
+        n0, n1 = root = (-a) * a ** q
+
+        possibilities = match_add_exponents(root)
+        self.assertEqualPos(possibilities,
+                [P(root, add_exponents, (Scope(root), n0, n1, a, 1, q))])
+
     def test_match_subtract_exponents_powers(self):
         a, p, q = tree('a,p,q')
         root = a ** p / a ** q