Hi `novice0516`

.

I'm not sure what is your aim with your notebook, but I know that the capabilities of `cadabra2`

with differential forms is far from optimal... you might note that not even all the properties and algorithms are documented! (btw, it would be great to help developing those missing capabilities).

From my ignorance, I'd suggest to follow a different approach.

## Some critics to your workflow:

- Your are defining differential forms but you are not using the wedge product.
- If you substitute an object with a derivative, What is the
*scope* of the derivative?
- I would argue that your substitution is changing the degree of the expression.

## Suggestions

Please take into account that my suggestions come from the ignorance of your purpose.

- I'd define my objects as non-commutative (if necessary). Your operetors
`A`

, `B`

, `C`

and `D`

should commute but in the example below I defined as non-commuting just for fun!
- If you define the variations as derivative, general derivatives do not commute! (I've included a commented line with the explicit declaration anyway).
- Define the scope of the derivative operators

## Code

```
{A,B,C,D}::NonCommuting;
{da{#},db{#}}::Derivative;
# {da{#},db{#}}::NonCommuting;
ex:= da{ B C D};
converge(ex):
distribute(_)
product_rule(_)
;
```

I tried the second derivative

```
ex:= db{da{ B C D }};
converge(ex):
distribute(_)
product_rule(_)
;
```

And the commutator of derivatives

```
ex:= db{da{ B C D }} - da{db{ B C D }};
converge(ex):
distribute(_)
product_rule(_)
;
```

Let me know if my suggestions were useful, but remember that my intention is to give you a different way to try your programme.

Cheers.