Hi all,

it looks like CSE and Subs don't interact very well. Here's what
happens:

- CSE finds a few Subs instances that share the entirety of their
  'point' values.

- CSE creates a symbol for the entire 'point' value--i.e. the whole
  Tuple.

- Upon construction of the new Subs with the symbol for 'point', Subs
  wraps that symbol in a Tuple.

- When the CSE'd value of the symbol is substituted back into the
  expression, we end up with Tuple(Tuple(expr)).
  
There are multiple ways of fixing this, none strikes me as 'obviously
right':

- Special-case Subs in CSE, to only look at the elements of Subs.point,
  not the whole thing.
  
- Special-case Tuple in CSE--in effect, don't collect entire Tuples in
  CSE. (*)

- Denest in the Subs constructor, i.e. turn Tuple(Tuple(x)) into
  Tuple(x).
  
- Add a flag to prevent the Tuple wrapping in Subs when called from CSE.

(*) is what I've implemented as a stopgap, patch attached.

I'd much appreciate any insight/fixes for this.

Thanks,
Andreas

Attachment: pgpDRfqLmlku3.pgp
Description: PGP signature

diff --git a/sympy/simplify/cse_main.py b/sympy/simplify/cse_main.py
index 0933291..4928c7f 100644
--- a/sympy/simplify/cse_main.py
+++ b/sympy/simplify/cse_main.py
@@ -3,7 +3,7 @@
 import bisect
 import difflib
 
-from sympy import Basic, Mul, Add
+from sympy import Basic, Mul, Add, Tuple
 from sympy.utilities.iterables import preorder_traversal, numbered_symbols
 
 import cse_opts
@@ -151,6 +151,9 @@ def insert(subtree):
                     pt.skip()
                     continue
 
+                if isinstance(subtree, Tuple):
+                    continue
+
                 if subtree.is_Mul:
                     muls.add(subtree)
                 elif subtree.is_Add:

Reply via email to