فهرست منبع

Added ignore_negation option to non-strict equality check.

Taddeus Kroes 14 سال پیش
والد
کامیت
7979468c88
2فایلهای تغییر یافته به همراه27 افزوده شده و 9 حذف شده
  1. 20 9
      src/node.py
  2. 7 0
      tests/test_node.py

+ 20 - 9
src/node.py

@@ -265,7 +265,7 @@ class ExpressionNode(Node, ExpressionBase):
             return (self[0], self[1], ExpressionLeaf(1))
         return (self[1], self[0], ExpressionLeaf(1))
 
-    def equals(self, other):
+    def equals(self, other, ignore_negation=False):
         """
         Perform a non-strict equivalence check between two nodes:
         - If the other node is a leaf, it cannot be equal to this node.
@@ -277,10 +277,6 @@ class ExpressionNode(Node, ExpressionBase):
           non-strictly equal.
         """
         if not other.is_op(self.op):
-            # FIXME: this is if-clause is a problem. To fix this problem
-            # permanently, normalize ("x * -1" -> "-1x") before comparing to
-            # the other node.
-
             return False
 
         if self.op in (OP_ADD, OP_MUL):
@@ -311,7 +307,10 @@ class ExpressionNode(Node, ExpressionBase):
                 if not child.equals(other[i]):
                     return False
 
-        return True
+        if ignore_negation:
+            return True
+
+        return self.negated == other.negated
 
 
 class ExpressionLeaf(Leaf, ExpressionBase):
@@ -335,12 +334,24 @@ class ExpressionLeaf(Leaf, ExpressionBase):
     def __repr__(self):
         return '-' * self.negated + str(self.value)
 
-    def equals(self, other):
+    def equals(self, other, ignore_negation=False):
         """
         Check non-strict equivalence.
-        Between leaves, this is the same as strict equivalence.
+        Between leaves, this is the same as strict equivalence, except when
+        negations must be ignored.
         """
-        return self == other
+        if ignore_negation:
+            other_type = type(other)
+
+            if other_type in (int, float):
+                return TYPE_MAP[other_type] == self.type \
+                    and self.value == abs(other)
+            elif other_type == str:
+                return self.type == TYPE_IDENTIFIER and self.value == other
+
+            return self.type == other.type and self.value == other.value
+        else:
+            return self == other
 
     def extract_polynome_properties(self):
         """

+ 7 - 0
tests/test_node.py

@@ -165,6 +165,13 @@ class TestNode(RulesTestCase):
         m0, m1 = tree('-5 * -3,-5 * 6')
         self.assertFalse(m0.equals(m1))
 
+    def test_equals_ignore_negation(self):
+        p0, p1 = tree('-(a + b), a + b')
+        self.assertTrue(p0.equals(p1, ignore_negation=True))
+
+        a0, a1 = tree('-a,a')
+        self.assertTrue(a0.equals(a1, ignore_negation=True))
+
     def test_scope___init__(self):
         self.assertEqual(self.scope.node, self.n)
         self.assertEqual(self.scope.nodes, [self.a, self.b, self.cd])