details:   http://hg.sympy.org/sympy/rev/49ebc78a44f2
changeset: 1778:49ebc78a44f2
user:      Riccardo Gori <[EMAIL PROTECTED]>
date:      Wed Oct 08 20:53:56 2008 +0200
description:
Fix for Issue 801: Add._eval_subs() now uses sets + tests

Before:

In [2]: (a+b+c).subs(a+b,c)
Out[2]: a + b + c

In [3]: (c+b+exp(c+b)).subs(c+b,a)
Out[3]:
     b + c
a + ?

In [4]: (a+b+exp(a+b)).subs(a+b,c)
Out[4]:
         c
a + b + ?

After:

In [2]: (a+b+c).subs(a+b,c)
Out[2]: 2?c

In [3]: (c+b+exp(c+b)).subs(c+b,a)
Out[3]:
     a
a + ?

In [4]: (a+b+exp(a+b)).subs(a+b,c)
Out[4]:
     c
c + ?

Signed-off-by: Riccardo Gori <[EMAIL PROTECTED]>
Signed-off-by: Ondrej Certik <[EMAIL PROTECTED]>

diffs (54 lines):

diff -r a06c52800718 -r 49ebc78a44f2 sympy/core/add.py
--- a/sympy/core/add.py Wed Oct 08 17:36:03 2008 +0200
+++ b/sympy/core/add.py Wed Oct 08 20:53:56 2008 +0200
@@ -291,21 +291,20 @@
         return S.One,(self,)
 
     def _eval_subs(self, old, new):
-        if self==old: return new
+        if self == old: return new
         if isinstance(old, FunctionClass):
             return self.__class__(*[s.subs(old, new) for s in self.args ])
-        coeff1,factors1 = self.as_coeff_factors()
-        coeff2,factors2 = old.as_coeff_factors()
-        if factors1==factors2: # (2+a).subs(3+a,y) -> 2-3+y
-            return new + coeff1 - coeff2
+        coeff_self, factors_self = self.as_coeff_factors()
+        coeff_old, factors_old = old.as_coeff_factors()
+        if factors_self == factors_old: # (2+a).subs(3+a,y) -> 2-3+y
+            return Add(new, coeff_self, -coeff_old)
         if old.is_Add:
-            l1,l2 = len(factors1),len(factors2)
-            if l2<l1: # (a+b+c+d).subs(b+c,x) -> a+x+d
-                for i in xrange(l1-l2+1):
-                    if factors2==factors1[i:i+l2]:
-                        factors1 = list(factors1)
-                        factors2 = list(factors2)
-                        return 
Add(*([coeff1-coeff2]+factors1[:i]+[new]+factors1[i+l2:]))
+            if len(factors_old) < len(factors_self): # (a+b+c+d).subs(b+c,x) 
-> a+x+d
+                self_set = set(factors_self)
+                old_set = set(factors_old)
+                if old_set < self_set:
+                    ret_set = self_set - old_set
+                    return Add(new, coeff_self, -coeff_old, *[s.subs(old, new) 
for s in ret_set])
         return self.__class__(*[s.subs(old, new) for s in self.args])
 
     @cacheit
diff -r a06c52800718 -r 49ebc78a44f2 sympy/core/tests/test_subs.py
--- a/sympy/core/tests/test_subs.py     Wed Oct 08 17:36:03 2008 +0200
+++ b/sympy/core/tests/test_subs.py     Wed Oct 08 20:53:56 2008 +0200
@@ -134,10 +134,14 @@
     assert (a**2 - c).subs(a**2 - c, d) == d
     assert (a**2 - b - c).subs(a**2 - c, d) in [d - b, a**2 - b - c]
     assert (a**2 - x - c).subs(a**2 - c, d) in [d - x, a**2 - x - c]
+    assert (a**2 - b - sqrt(a)).subs(a**2 - sqrt(a), c) == c - b
+    assert (a+b+exp(a+b)).subs(a+b,c) == c + exp(c)
+    assert (c+b+exp(c+b)).subs(c+b,a) == a + exp(a)
 
     # this should work everytime:
     e = a**2 - b - c
     assert e.subs(Add(*e.args[:2]), d) == d + e.args[2]
+    assert e.subs(a**2 - c, d) == d - b
 
 def test_subs_issue910():
     assert (I*Symbol("a")).subs(1, 2) == I*Symbol("a")

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sympy-commits" group.
To post to this group, send email to sympy-commits@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sympy-commits?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to