Преглед изворни кода

Added basic fraction rewrite rules.

Taddeus Kroes пре 14 година
родитељ
комит
90b24c3cd5
3 измењених фајлова са 80 додато и 1 уклоњено
  1. 3 1
      src/rules/__init__.py
  2. 43 0
      src/rules/fractions.py
  3. 34 0
      tests/test_rules_fractions.py

+ 3 - 1
src/rules/__init__.py

@@ -4,12 +4,14 @@ from .powers import match_add_exponents, match_subtract_exponents, \
         match_multiply_exponents, match_duplicate_exponent, \
         match_remove_negative_exponent, match_exponent_to_root
 from .numerics import match_divide_numerics
+from .fractions import match_constant_division
 
 
 RULES = {
         OP_ADD: [match_combine_polynomes],
         OP_MUL: [match_expand, match_add_exponents],
-        OP_DIV: [match_subtract_exponents, match_divide_numerics],
+        OP_DIV: [match_subtract_exponents, match_divide_numerics, \
+                 match_constant_division],
         OP_POW: [match_multiply_exponents, match_duplicate_exponent, \
                  match_remove_negative_exponent, match_exponent_to_root],
         }

+ 43 - 0
src/rules/fractions.py

@@ -0,0 +1,43 @@
+from ..node import ExpressionLeaf as L, OP_DIV
+from ..possibilities import Possibility as P, MESSAGES
+from ..translate import _
+
+
+def match_constant_division(node):
+    """
+    a / 0  ->  Division by zero
+    a / 1  ->  a
+    0 / a  ->  0
+    """
+    assert node.is_op(OP_DIV)
+
+    p = []
+    nominator, denominator = node
+
+    # a / 0
+    if denominator == 0:
+        raise ZeroDivisionError()
+
+    # a / 1
+    if denominator == 1:
+        p.append(P(node, division_by_one, (nominator,)))
+
+    # 0 / a
+    if nominator == 0:
+        p.append(P(node, division_of_zero))
+
+    return p
+
+
+def division_by_one(root, args):
+    """
+    a / 1  ->  a
+    """
+    return args[0]
+
+
+def division_of_zero(root, args):
+    """
+    0 / a  ->  0
+    """
+    return L(0)

+ 34 - 0
tests/test_rules_fractions.py

@@ -0,0 +1,34 @@
+from src.rules.fractions import match_constant_division, division_by_one, \
+        division_of_zero
+from src.possibilities import Possibility as P
+from tests.test_rules_poly import tree
+from tests.rulestestcase import RulesTestCase
+
+
+class TestRulesFractions(RulesTestCase):
+
+    def test_match_constant_division(self):
+        a, zero = tree('a,0')
+
+        root = a / zero
+        self.assertRaises(ZeroDivisionError, match_constant_division, root)
+
+        root = a / 1
+        possibilities = match_constant_division(root)
+        self.assertEqualPos(possibilities, [P(root, division_by_one, (a,))])
+
+        root = zero / a
+        possibilities = match_constant_division(root)
+        self.assertEqualPos(possibilities, [P(root, division_of_zero)])
+
+    def test_division_by_one(self):
+        a = tree('a')
+        root = a / 1
+
+        self.assertEqualNodes(division_by_one(root, (a,)), a)
+
+    def test_division_of_zero(self):
+        a, zero = tree('a,0')
+        root = zero / a
+
+        self.assertEqualNodes(division_of_zero(root, ()), zero)