a field-theory motivated approach to computer algebra

Indices, dummy indices and automatic index renaming

In Cadabra, all objects which occur as subscripts or superscripts are considered to be "indices". The names of indices are understood to be irrelevant when they occur in a pair, and automatic relabelling will take place whenever necessary in order to avoid index clashes. Cadabra knows about the differences between free and dummy indices. It checks the input for consistency and displays a warning when the index structure does not make sense. Thus, the input
ex:= A_{m n} + B_{m} = 0;
will results in an error message.
The location of indices is, by default, not considered to be relevant. That is, you can write
{m, n}::Indices(name="free"); ex:=A_{m} + A^{m};
$$\displaystyle{}\text{Attached property Indices(position=free) to }\left[m, n\right].$$
$$\displaystyle{}A_{m}+A^{m}$$
A_{m} + A^{m}
as input and these are considered to be consistent expressions. You can collect such terms by using lower_free_indices or raise_free_indices,
lower_free_indices(ex);
$$\displaystyle{}2A_{m}$$
2A_{m}
If, however, the position of an index means something (like in general relativity, where index lowering and raising implies contraction with a metric), then you can declare index positions to be "fixed". This is done using
{a,b,c,d,e,f}::Indices(name="fixed", position=fixed);
$$\displaystyle{}\text{Attached property Indices(position=fixed) to }\left[a, b, c, d, e, f\right].$$
Cadabra will raise or lower indices on such expressions to a canonical form when the canonicalise algorithm is used,
ex:= G_{a b} F^{a b} + G^{a b} F_{a b}; canonicalise(_);
$$\displaystyle{}G_{a b} F^{a b}+G^{a b} F_{a b}$$
G_{a b} F^{a b} + G^{a b} F_{a b}
$$\displaystyle{}2G^{a b} F_{a b}$$
2G^{a b} F_{a b}
If upper and lower indices should remain untouched at all times, there is a third index position type, called 'independent',
{q,r,s}::Indices(name="independent", position=independent); ex:= G_{q r} F^{q r} + G^{q r} F_{q r}; canonicalise(_);
$$\displaystyle{}\text{Attached property Indices(position=independent) to }\left[q, r, s\right].$$
$$\displaystyle{}G_{q r} F^{q r}+G^{q r} F_{q r}$$
G_{q r} F^{q r} + G^{q r} F_{q r}
$$\displaystyle{}G_{q r} F^{q r}+G^{q r} F_{q r}$$
G_{q r} F^{q r} + G^{q r} F_{q r}
As the last line shows, the index positions have remained unchanged.
When substituting an expression into another one, dummy indices will automatically be relabelled when necessary. To see this in action, consider the following example:
ex:= G_{a b} Q; rl:= Q-> F_{a b} F^{a b}; substitute(ex, rl);
$$\displaystyle{}G_{a b} Q$$
G_{a b} Q
$$\displaystyle{}Q \rightarrow F_{a b} F^{a b}$$
Q → F_{a b} F^{a b}
$$\displaystyle{}G_{a b} F_{c d} F^{c d}$$
G_{a b} F_{c d} F^{c d}
The $a$ and $b$ indices have automatically been relabelled to $c$ and $d$ in order to avoid a conflict with the free indices on the $G_{a b}$ object.
You may have noticed that when you write T_{a b} the 'a b' in the subscript is not interpreted as a product, but rather as two different indices to the tensor $T$.