Kaynağa Gözat

Added rules for removing double conjunction/disjunction cases.

Taddeus Kroes 14 yıl önce
ebeveyn
işleme
961c70a79c
3 değiştirilmiş dosya ile 57 ekleme ve 6 silme
  1. 4 3
      src/rules/__init__.py
  2. 33 2
      src/rules/lineq.py
  3. 20 1
      tests/test_rules_lineq.py

+ 4 - 3
src/rules/__init__.py

@@ -1,6 +1,6 @@
 from ..node import OP_ADD, OP_MUL, OP_DIV, OP_POW, OP_NEG, OP_SIN, OP_COS, \
         OP_TAN, OP_DER, OP_LOG, OP_INT, OP_INT_INDEF, OP_EQ, OP_ABS, OP_SQRT, \
-        OP_AND
+        OP_AND, OP_OR
 from .groups import match_combine_groups
 from .factors import match_expand
 from .powers import match_add_exponents, match_subtract_exponents, \
@@ -28,7 +28,7 @@ from .integrals import match_solve_indef, match_constant_integral, \
         match_integrate_variable_power, match_factor_out_constant, \
         match_division_integral, match_function_integral, \
         match_sum_rule_integral, match_remove_indef_constant
-from .lineq import match_move_term, match_multiple_equations
+from .lineq import match_move_term, match_multiple_equations, match_double_case
 from .absolute import match_factor_out_abs_term
 from .sqrt import match_reduce_sqrt
 
@@ -68,5 +68,6 @@ RULES = {
         OP_EQ: [match_move_term],
         OP_ABS: [match_factor_out_abs_term],
         OP_SQRT: [match_reduce_sqrt],
-        OP_AND: [match_multiple_equations],
+        OP_AND: [match_multiple_equations, match_double_case],
+        OP_OR: [match_double_case],
         }

+ 33 - 2
src/rules/lineq.py

@@ -1,8 +1,8 @@
-from itertools import permutations
+from itertools import permutations, combinations
 
 from .utils import find_variable, evals_to_numeric, substitute
 from ..node import ExpressionLeaf as L, Scope, OP_EQ, OP_ADD, OP_MUL, OP_DIV, \
-        eq, OP_ABS, OP_AND
+        eq, OP_ABS, OP_AND, OP_OR
 from ..possibilities import Possibility as P, MESSAGES
 from ..translate import _
 
@@ -194,3 +194,34 @@ def substitute_variable(root, args):
 
 
 MESSAGES[substitute_variable] = _('Substitute {2} with {3} in {4}.')
+
+
+def match_double_case(node):
+    """
+    a ^^ a  ->  a
+    a vv a  ->  a
+    """
+    assert node.is_op(OP_AND, OP_OR)
+
+    scope = Scope(node)
+    p = []
+
+    for a, b in combinations(scope, 2):
+        if a == b:
+            p.append(P(node, double_case, (scope, a, b)))
+
+    return p
+
+
+def double_case(root, args):
+    """
+    a ^^ a  ->  a
+    a vv a  ->  a
+    """
+    scope, a, b = args
+    scope.remove(b)
+
+    return scope.as_nary_node()
+
+
+MESSAGES[double_case] = _('Remove double occurence of {2}.')

+ 20 - 1
tests/test_rules_lineq.py

@@ -1,6 +1,7 @@
 from src.rules.lineq import match_move_term, swap_sides, subtract_term, \
         divide_term, multiply_term, split_absolute_equation, \
-        match_multiple_equations, substitute_variable
+        match_multiple_equations, substitute_variable, match_double_case, \
+        double_case
 from src.node import Scope
 from src.possibilities import Possibility as P
 from tests.rulestestcase import RulesTestCase, tree
@@ -116,8 +117,26 @@ class TestRulesLineq(RulesTestCase):
         self.assertEqualPos(match_multiple_equations(root),
                 [P(root, substitute_variable, (Scope(root), x, 2, eq1))])
 
+        root = tree('x + y = 2 ^^ ay + x = 3')
+        self.assertEqualPos(match_multiple_equations(root), [])
+
+        root = tree('x + y ^^ ay + x = 3')
+        self.assertEqualPos(match_multiple_equations(root), [])
+
     def test_substitute_variable(self):
         root, expect = tree('x = 2 ^^ ay + x = 3, x = 2 ^^ ay + 2 = 3')
         (x, l2), eq = root
         self.assertEqual(substitute_variable(root, ((Scope(root), x, l2, eq))),
                          expect)
+
+    def test_match_double_case(self):
+        a, b = root = tree('x = 2 vv x = 2')
+        self.assertEqualPos(match_double_case(root),
+                [P(root, double_case, (Scope(root), a, b))])
+
+        root = tree('x = 2 vv x = -2')
+        self.assertEqualPos(match_double_case(root), [])
+
+    def test_double_case(self):
+        a, b = root = tree('x = 2 vv x = 2, x = 2')
+        self.assertEqual(double_case(root, (Scope(root), a, b)), a)