Răsfoiți Sursa

Merge branch 'gonio' of kompiler.org:trs into negated

Taddeus Kroes 14 ani în urmă
părinte
comite
9f0ea191d5
4 a modificat fișierele cu 63 adăugiri și 4 ștergeri
  1. 10 2
      src/node.py
  2. 32 0
      src/rules/goniometry.py
  3. 6 2
      tests/test_node.py
  4. 15 0
      tests/test_rules_goniometry.py

+ 10 - 2
src/node.py

@@ -33,6 +33,11 @@ OP_EXPAND = 9
 OP_COMMA = 10
 OP_SQRT = 11
 
+# Goniometry
+OP_SIN = 12
+OP_COS = 13
+OP_TAN = 14
+
 
 TYPE_MAP = {
         int: TYPE_INTEGER,
@@ -112,8 +117,11 @@ class ExpressionBase(object):
     def is_op(self, op):
         return not self.is_leaf and self.op == op
 
-    def is_power(self):
-        return not self.is_leaf and self.op == OP_POW
+    def is_power(self, exponent=None):
+        if self.is_leaf or self.op != OP_POW:
+            return False
+
+        return exponent == None or self[1] == exponent
 
     def is_nary(self):
         return not self.is_leaf and self.op in [OP_ADD, OP_SUB, OP_MUL]

+ 32 - 0
src/rules/goniometry.py

@@ -0,0 +1,32 @@
+from ..node import ExpressionNode as N, ExpressionLeaf as L, Scope, \
+        OP_ADD, OP_POW, OP_MUL, OP_SIN, OP_COS, OP_TAN
+from ..possibilities import Possibility as P, MESSAGES
+from ..translate import _
+
+
+def match_add_quadrants(node):
+    """
+    sin(x) ^ 2 + cos(x) ^ 2  ->  1
+    """
+    assert node.is_op(OP_ADD)
+
+    p = []
+    sin_q, cos_q = node
+
+    if sin_q.is_power(2) and cos_q.is_power(2):
+        sin, cos = sin_q[0], cos_q[0]
+
+        if sin.is_op(OP_SIN) and cos.is_op(OP_COS):
+            p.append(P(node, add_quadrants, ()))
+
+    return p
+
+
+def add_quadrants(root, args):
+    """
+    sin(x) ^ 2 + cos(x) ^ 2  ->  1
+    """
+    return L(1)
+
+
+MESSAGES[add_quadrants] = _('Add the sinus and cosinus quadrants to 1.')

+ 6 - 2
tests/test_node.py

@@ -35,8 +35,12 @@ class TestNode(RulesTestCase):
         self.assertFalse(N('+', *self.l[:2]).is_leaf)
 
     def test_is_power(self):
-        self.assertTrue(N('^', *self.l[:2]).is_power())
-        self.assertFalse(N('+', *self.l[:2]).is_power())
+        self.assertTrue(N('^', *self.l[2:]).is_power())
+        self.assertFalse(N('+', *self.l[2:]).is_power())
+
+    def test_is_power_exponent(self):
+        self.assertTrue(N('^', *self.l[2:]).is_power(5))
+        self.assertFalse(N('^', *self.l[2:]).is_power(2))
 
     def test_is_nary(self):
         self.assertTrue(N('+', *self.l[:2]).is_nary())

+ 15 - 0
tests/test_rules_goniometry.py

@@ -0,0 +1,15 @@
+from src.rules.goniometry import match_add_quadrants, add_quadrants
+from src.possibilities import Possibility as P
+from tests.rulestestcase import RulesTestCase, tree
+
+
+class TestRulesGoniometry(RulesTestCase):
+
+    def test_match_add_quadrants(self):
+        root = tree('sin(x) ^ 2 + cos(x) ^ 2')
+        possibilities = match_add_quadrants(root)
+        self.assertEqualPos(possibilities, [P(root, add_quadrants, ())])
+
+    def test_add_quadrants(self):
+        root = tree('sin(x) ^ 2 + cos(x) ^ 2')
+        self.assertEqual(add_quadrants(root, ()), 1)