Hi GPN,

Thanks for sharing your doubts and ideas. I found your solution very useful, and it inspired me to try a different approach.

My solutions uses the algorithm `isolate`

from the library `manip`

, so the notebook starts like:

`import cdb.core.manip as manip`

Then, I modify your approach (in particular the notation of the inverse, and taking care of the space between the operators `A`

and `G`

):

```
\partial{#}::PartialDerivative.
ex := \partial{A} + B + A (G**(-1) \partial{G}) + C.
sort_product(ex);
```

The algorithm `sort_product`

will ensure the same order of the factors (the usefulness wuold be seen shortly.

Then, I define the `contracted`

expression

`contracted := G**(-1) \partial{(G A)};`

and the `expanded`

one. Following your idea, I manipulate the `expanded`

expression and define a substitution rule

```
expanded := @(contracted);
product_rule(expanded)
distribute(expanded)
collect_factors(expanded)
sort_product(expanded)
contraction_rule := @(expanded) = @(contracted);
```

Note the appearance of `sort_product`

again. Since the desired expression to substitute is not isolated on the left-hand-side of the substitution rule, we use `isolate`

to isolate it:

`manip.isolate(contraction_rule, $A \partial{G} G**(-1)$);`

And finally we use the `contraction_rule`

on the original expression `ex`

:

`substitute(ex, contraction_rule);`

Hope you find this aproach useful!
Dox.