Repository: sympy/sympy
Pull request: removing is_commutative
<!-- Your title above should be a short description of what
was changed. Do not include the issue number in the title. -->

#### References to other Issues or PRs
<!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
format, e.g. "Fixes #1234" (see
https://tinyurl.com/auto-closing for more information). Also, please
write a comment on that issue linking back to this pull request once it is
open. -->
Fixes: #23721

#### Brief description of what is fixed or changed


#### Other comments


#### Release Notes

<!-- Write the release notes for this release below between the BEGIN and END
statements. The basic format is a bulleted list with the name of the subpackage
and the release note for this PR. For example:

* solvers
  * Added a new solver for logarithmic equations.

* functions
  * Fixed a bug with log of integers. Formerly, `log(-x)` incorrectly gave `-log(x)`.

* physics.units
  * Corrected a semantical error in the conversion between volt and statvolt which
    reported the volt as being larger than the statvolt.

or if no release note(s) should be included use:

NO ENTRY

See https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more
information on how to write release notes. The bot will check your release
notes automatically to see if they are formatted correctly. -->

<!-- BEGIN RELEASE NOTES -->
* tensor
  *  Fixed the issue that `commutative=False` assumption is not working with `IndexedBase`. For example, if `t` and `u` are `IndexedBase` with `commutative=False`, `u[0]*t[0]` should not simplify to `u[0]*t[0]`.
<!-- END RELEASE NOTES -->


Problem statement:
IndexedBase non-commutivity fails
Hi there, 

I believe I've found a bug relating to the IndexedBase class, where it doesn't seem to respect non-commutivity of objects.  If I have two non-commuting IndexedBase objects `t` and `u`, I would expect that `t[0]*u[0]+u[0]*t[0]!=2*t[0]*u[0]`.  The below code highlights the issue, showing that all the objects have `commutivity=False`, yet the addition of `t[0]*u[0]` with `u[0]*t[0]` simplified to `2t[0]u[0]`

    import sympy as sp                                                                                  
                                                                                                    
    t=sp.IndexedBase('t',commutative=False)                                                             
    u=sp.IndexedBase('u',commutative=False)                                                             
                                                                                                      
    print('t commutativity is {}'.format(t._assumptions['commutative']))                                    
    print('t[0] commutativity is {}'.format(t[0]._assumptions['commutative']))                           
    print('u commutativity is {}'.format(u._assumptions['commutative']))                                    
    print('u[0] commutativity is {}'.format(u[0]._assumptions['commutative']))                          
                                                                                                    
    print(t[0]*u[0]+u[0]*t[0])    
    
The output I get in sympy version 1.10.1 is 

    t commutativity is False
    t[0] commutativity is False
    u commutativity is False
    u[0] commutativity is False
    2*t[0]*u[0]

Hints from issue discussion:
Problem is already here:
```python
>>> print(u[0]*t[0])
t[0]*u[0]
```
Seems to be an assumptions problem:
```python
In [4]: u[0]._assumptions['commutative']
Out[4]: False

In [5]: u[0].is_commutative
Out[5]: True
```
Looks like the fix is
```diff
diff --git a/sympy/tensor/indexed.py b/sympy/tensor/indexed.py
index 8119a2a..9c9b6f3 100644
--- a/sympy/tensor/indexed.py
+++ b/sympy/tensor/indexed.py
@@ -139,7 +139,6 @@ class Indexed(Expr):
     True
 
     """
-    is_commutative = True
     is_Indexed = True
     is_symbol = True
     is_Atom = True
```
I'm not sure if there's any particular reason why `Indexed` sets commutative to True.

Probably the assumptions system should detect a case like this where `is_commutative` contradicts `_assumptions['commutative']` and cause an error somewhere.
Instead of making a change to the source of the class one may also set this property dynamically: `Indexed.is_commutative = False`.
I've already shown how to fix this so marking as easy to fix.

Commit message: removing is_commutative

Patch to review:
diff --git a/sympy/tensor/indexed.py b/sympy/tensor/indexed.py
index ff372ac655d9..8be0bd902b1c 100644
--- a/sympy/tensor/indexed.py
+++ b/sympy/tensor/indexed.py
@@ -139,7 +139,6 @@ class Indexed(Expr):
     True
 
     """
-    is_commutative = True
     is_Indexed = True
     is_symbol = True
     is_Atom = True
diff --git a/sympy/tensor/tests/test_indexed.py b/sympy/tensor/tests/test_indexed.py
index 0dc537638762..c17d5d26e781 100644
--- a/sympy/tensor/tests/test_indexed.py
+++ b/sympy/tensor/tests/test_indexed.py
@@ -501,3 +501,10 @@ def test_complicated_derivative_with_Indexed():
             ((x[i] - y[i])**2/sigma,)
         )/sigma**2
     )
+
+
+def test_IndexedBase_commutative():
+    t = IndexedBase('t' ,commutative=False)
+    u = IndexedBase('u' ,commutative=False)
+
+    assert t[0]*u[0] != u[0]*t[0]


Code review comments:
diff_hunk: @@ -501,3 +501,10 @@ def test_complicated_derivative_with_Indexed():
             ((x[i] - y[i])**2/sigma,)
         )/sigma**2
     )
+
+
+def test_IndexedBase_commutative():
+    t = IndexedBase('t' ,commutative=False)
+    u = IndexedBase('u' ,commutative=False)
path: sympy/tensor/tests/test_indexed.py
text: @user1:
```suggestion
    t = IndexedBase('t', commutative=False)
    u = IndexedBase('u', commutative=False)
```