瀏覽代碼

Added raise_numerics rule and added leiden oefenopgaven 1 and 2 as test cases.

Sander Mathijs van Veen 14 年之前
父節點
當前提交
1724ba2f2c
共有 3 個文件被更改,包括 79 次插入3 次删除
  1. 4 2
      src/rules/__init__.py
  2. 31 1
      src/rules/numerics.py
  3. 44 0
      tests/test_leiden_oefenopgave_v12.py

+ 4 - 2
src/rules/__init__.py

@@ -7,7 +7,8 @@ from .powers import match_add_exponents, match_subtract_exponents, \
         match_remove_negative_exponent, match_exponent_to_root, \
         match_extend_exponent, match_constant_exponent
 from .numerics import match_add_numerics, match_divide_numerics, \
-        match_multiply_numerics, match_multiply_zero, match_multiply_one
+        match_multiply_numerics, match_multiply_zero, match_multiply_one, \
+        match_raise_numerics
 from .fractions import match_constant_division, match_add_constant_fractions, \
         match_expand_and_add_fractions
 from .negation import match_negated_factor, match_negate_polynome, \
@@ -27,7 +28,8 @@ RULES = {
                  match_constant_division, match_negated_division],
         OP_POW: [match_multiply_exponents, match_duplicate_exponent,
                  match_remove_negative_exponent, match_exponent_to_root,
-                 match_extend_exponent, match_constant_exponent],
+                 match_extend_exponent, match_constant_exponent,
+                 match_raise_numerics],
         OP_NEG: [match_negate_polynome],
         OP_SIN: [match_negated_parameter, match_half_pi_subtraction,
                  match_standard_radian],

+ 31 - 1
src/rules/numerics.py

@@ -1,7 +1,7 @@
 from itertools import combinations
 
 from ..node import ExpressionLeaf as Leaf, Scope, negate, OP_ADD, OP_DIV, \
-        OP_MUL
+        OP_MUL, OP_POW
 from ..possibilities import Possibility as P, MESSAGES
 from ..translate import _
 
@@ -243,3 +243,33 @@ def multiply_numerics(root, args):
 
 
 MESSAGES[multiply_numerics] = _('Multiply constant {2} with {3}.')
+
+
+def match_raise_numerics(node):
+    """
+    2 ^ 3     ->  8
+    (-2) ^ 3  ->  -8
+    (-2) ^ 2  ->  4
+    """
+    assert node.is_op(OP_POW)
+
+    r, e = node
+
+    if r.is_numeric() and e.is_numeric() and not e.negated:
+        return [P(node, raise_numerics, (r, e))]
+
+    return []
+
+
+def raise_numerics(root, args):
+    """
+    2 ^ 3     ->  8
+    (-2) ^ 3  ->  -8
+    (-2) ^ 2  ->  4
+    """
+    r, e = args
+
+    return Leaf(r.value ** e.value).negate(r.negated * e.value)
+
+
+MESSAGES[raise_numerics] = _('Raise constant {1} with {2}.')

+ 44 - 0
tests/test_leiden_oefenopgave_v12.py

@@ -50,3 +50,47 @@ class TestLeidenOefenopgaveV12(TestCase):
             '-72x ^ 3 + 96x ^ 2 + 32 * -x',
             '-72x ^ 3 + 96x ^ 2 - 32x',
         ])
+
+    def test_2_a(self):
+        self.assertRewrite(['(a2b^-1)^3(ab2)',
+            '(a ^ 2 * (1 / b ^ 1)) ^ 3 * ab ^ 2',
+            '(a ^ 2 * (1 / b)) ^ 3 * ab ^ 2',
+            '(a ^ 2) ^ 3 * (1 / b) ^ 3 * ab ^ 2',
+            'a ^ (2 * 3)(1 / b) ^ 3 * ab ^ 2',
+            'a ^ 6 * (1 / b) ^ 3 * ab ^ 2',
+            'a ^ (6 + 1)(1 / b) ^ 3 * b ^ 2',
+            'a ^ 7 * (1 / b) ^ 3 * b ^ 2',
+            ])
+
+    def test_2_b(self):
+        self.assertRewrite(['a3b2a3',
+            'a ^ (3 + 3)b ^ 2',
+            'a ^ 6 * b ^ 2'])
+
+    def test_2_c(self):
+        self.assertRewrite(['a5+a3',
+            'a ^ 5 + a ^ 3'])
+
+    def test_2_d(self):
+        self.assertRewrite(['a2+a2',
+            '(1 + 1)a ^ 2',
+            '2a ^ 2'])
+
+    def test_2_e(self):
+        self.assertRewrite([
+            '4b^-2',
+            '4(1 / b ^ 2)',
+            # FIXME: '4 * 1/b ^ 2',
+            ])
+
+    def test_2_f(self):
+        self.assertRewrite([
+            '(4b) ^ -2',
+            '4 ^ -2 * b ^ -2',
+            '1 / 4 ^ 2 * b ^ -2',
+            '1 / 16 * b ^ -2',
+            '1 / 16 * (1 / b ^ 2)',
+            '1 / 16 * (1 / b ^ 2)',
+            '1 * 1 / (16b ^ 2)',
+            '1 / (16b ^ 2)',
+        ])