*See the previous post for Week 7*.

I spent most of this week rewriting the non-commutative matching code in Sympy’s core as Aaron suggested. The pull request for this rewrite is available at #17223.

## Non-commutative matching in SymPy

SymPy already supports matching within non-commutative multiplication expressions. While I mentioned in my last blog post that this matching support was limited, I’ll go into a bit more detail about what those limitations (which sometimes produce wrong results) are:

### No matching based on structure

Matching within commutative SymPy expressions allows for taking the structure of expressions into account. Two commutative SymPy expressions match only if both contain the same non-wildcard symbols:

```
>>> from sympy.abc import a, x, y, z
>>> w = Wild('w')
>>> m = x*y*w
>>> m.matches(x*y*z)
{w_: z}
>>> m.matches(a*x*z)
```

`m`

specifies that the expression must contain both `x`

and `y`

in addition to whatever the wildcard matches. For this reason, `m`

matches `x*y*z`

but not `a*x*z`

.

The corresponding example for non-commutative expressions does not work as expected, as it does not match when we expect it to:

```
>>> A, B, C, D = symbols('A:D', commutative=False)
>>> W = Wild('W', commutative=False)
>>> M = A*B*W
>>> M.matches(A*B*C)
>>> M.matches(A*D*C)
```

### Expressions don’t respect non-commutativity

In instances where matching does seem to work, the non-commutativity of expressions is not respected:

```
>>> A, B, C, D = symbols('A:D', commutative=False)
>>> w = Wild('w')
>>> from sympy.abc import x
>>> (w*A*B*C).matches(x*C*B*A)
{w_: x}
```

The two expressions should *not* have matched, since the order of the non-commutative expressions were different. I reported this same error for matrix expressions in issue #17172.

### Sub-expressions aren’t expanded

The matching code should be able to match portions of powers, which are represented differently in the SymPy AST. As an example, a non-commutative matcher such as $AW$ (where $W$ is a wildcard) should match $A^2$ with $\{W \mapsto A\}$ . I wasn’t able create a working example of this using the existing matching code.

## Matching Implementation

Since order needs to be taken into account for matching non-commutative expressions, the new matching code essentially does what a regular expression matcher would do, with nodes taking the place of characters and wildcards taking the place of the `.+`

regular expression.

## Next Steps

The matching PR still needs to be polished, and the related documentation needs to be updated, so I’ll be working on that. I’ll also start with extending matrix matching from this PR.