Procházet zdrojové kódy

Added rewrite rules for negated sin/cos parameters.

Taddeus Kroes před 14 roky
rodič
revize
5d0be51ea7
3 změnil soubory, kde provedl 72 přidání a 6 odebrání
  1. 5 2
      src/rules/__init__.py
  2. 42 2
      src/rules/goniometry.py
  3. 25 2
      tests/test_rules_goniometry.py

+ 5 - 2
src/rules/__init__.py

@@ -1,4 +1,4 @@
-from ..node import OP_ADD, OP_MUL, OP_DIV, OP_POW, OP_NEG
+from ..node import OP_ADD, OP_MUL, OP_DIV, OP_POW, OP_NEG, OP_SIN, OP_COS
 from .groups import match_combine_groups
 from .factors import match_expand
 from .powers import match_add_exponents, match_subtract_exponents, \
@@ -12,10 +12,11 @@ from .fractions import match_constant_division, match_add_constant_fractions, \
 from .negation import match_negated_factor, match_negate_polynome, \
         match_negated_division
 from .sort import match_sort_multiplicants
+from .goniometry import match_add_quadrants, match_negated_parameter
 
 RULES = {
         OP_ADD: [match_add_numerics, match_add_constant_fractions,
-                 match_combine_groups],
+                 match_combine_groups, match_add_quadrants],
         OP_MUL: [match_multiply_numerics, match_expand, match_add_exponents,
                  match_expand_and_add_fractions, match_multiply_zero,
                  match_negated_factor, match_multiply_one,
@@ -26,4 +27,6 @@ RULES = {
                  match_remove_negative_exponent, match_exponent_to_root,
                  match_extend_exponent, match_constant_exponent],
         OP_NEG: [match_negate_polynome],
+        OP_SIN: [match_negated_parameter],
+        OP_COS: [match_negated_parameter],
         }

+ 42 - 2
src/rules/goniometry.py

@@ -18,7 +18,7 @@ def tan(*args):
 
 def match_add_quadrants(node):
     """
-    sin(x) ^ 2 + cos(x) ^ 2  ->  1
+    sin(t) ^ 2 + cos(t) ^ 2  ->  1
     """
     assert node.is_op(OP_ADD)
 
@@ -36,9 +36,49 @@ def match_add_quadrants(node):
 
 def add_quadrants(root, args):
     """
-    sin(x) ^ 2 + cos(x) ^ 2  ->  1
+    sin(t) ^ 2 + cos(t) ^ 2  ->  1
     """
     return L(1)
 
 
 MESSAGES[add_quadrants] = _('Add the sinus and cosinus quadrants to 1.')
+
+
+def match_negated_parameter(node):
+    """
+    sin(-t)  ->  -sin(t)
+    cos(-t)  ->  cos(t)
+    """
+    assert node.is_op(OP_SIN) or node.is_op(OP_COS)
+
+    t = node[0]
+
+    if t.negated:
+        if node.op == OP_SIN:
+            return [P(node, negated_sinus_parameter, (t,))]
+
+        return [P(node, negated_cosinus_parameter, (t,))]
+
+    return []
+
+
+def negated_sinus_parameter(root, args):
+    """
+    sin(-t)  ->  -sin(t)
+    """
+    return -sin(+args[0])
+
+
+MESSAGES[negated_sinus_parameter] = \
+        _('Bring the negation from the sinus parameter {1} to the outside.')
+
+
+def negated_cosinus_parameter(root, args):
+    """
+    cos(-t)  ->  cos(t)
+    """
+    return cos(+args[0])
+
+
+MESSAGES[negated_cosinus_parameter] = \
+        _('Remove the negation from the cosinus parameter {1}.')

+ 25 - 2
tests/test_rules_goniometry.py

@@ -1,4 +1,7 @@
-from src.rules.goniometry import match_add_quadrants, add_quadrants
+# vim: set fileencoding=utf-8 :
+from src.rules.goniometry import match_add_quadrants, add_quadrants, \
+        match_negated_parameter, negated_sinus_parameter, \
+        negated_cosinus_parameter, sin, cos
 from src.possibilities import Possibility as P
 from tests.rulestestcase import RulesTestCase, tree
 
@@ -6,9 +9,29 @@ from tests.rulestestcase import RulesTestCase, tree
 class TestRulesGoniometry(RulesTestCase):
 
     def test_match_add_quadrants(self):
-        root = tree('sin x ^ 2 + cos x ^ 2')
+        root = tree('sin t ^ 2 + cos t ^ 2')
         possibilities = match_add_quadrants(root)
         self.assertEqualPos(possibilities, [P(root, add_quadrants, ())])
 
     def test_add_quadrants(self):
         self.assertEqual(add_quadrants(None, ()), 1)
+
+    def test_match_negated_parameter(self):
+        s, c = tree('(sin -t), cos -t')
+        t = s[0]
+
+        self.assertEqualPos(match_negated_parameter(s), \
+                [P(s, negated_sinus_parameter, (t,))])
+
+        self.assertEqualPos(match_negated_parameter(c), \
+                [P(c, negated_cosinus_parameter, (t,))])
+
+    def test_negated_sinus_parameter(self):
+        s = tree('sin -t')
+        t = s[0]
+        self.assertEqual(negated_sinus_parameter(s, (t,)), -sin(+t))
+
+    def test_negated_cosinus_parameter(self):
+        c = tree('cos -t')
+        t = c[0]
+        self.assertEqual(negated_cosinus_parameter(c, (t,)), cos(+t))