Dear Alexei,
First of all, I think it is perfectly sensible for eval() to return zero (e.g., what about traceless tensors?).
Yes. However, if we have a traceless tensor both T~mu.mu and T.mu~mu should evaluated themselves into 0. It does not make sense to only have one of them evaluate into zero. The point I was trying to make is that tensors with some index lowered/raised always (?) have the same properties so that an evaluate step that aplies to the version with an up-index should also aply to the one with a down-index.
Secondly, your patch does not catch this: [I admit that example is a little bit weird]
Your example is perfectly fine. I should have deleted all indices that are dummy indices of the indexed object e that is given as a parameter to reposition_dummy_indices in any case, not just when a cyclic symmetry is involved. Because you also mentioned the possibility that users would want to implement things like the Riemann curvature tensor, it makes sense that the evaluation of an indexed object could do any weird kind of symmetrization it would want, so I also removed the condition that a cyclic symmetry should be involved when trying all combinations of repositioning local dummy indices.
On the other hand, as a matter of principle you are right that it is best to assume as little about the rest of the code as possbile. For this reason I would accept a patch that would do the substitutions as they are currently but does not cause eval to be called.
The patch I've posted does that. Is there something wrong/stupid/etc with it?
Oh well, the thing seemed rather complicated to me and didn't do all simplifications possible, as noted in http://www.ginac.de/pipermail/ginac-devel/2006-August/001055.html. I now more or less applied it, but with some modifications. I hope that I haven't broken anything ;-). (1) Now that the raising and lowering of indices is done on an exvector, we do not need to raise/lower both indices at the same time. Another reason why this isn't necessary anymore is that indices that occur in dummy pairs within the indexed object e should already have been removed from the vector variant_dummy_indices. I think this means that the for_each that you had can be omitted. (2) It is not correct to return the indexed object by doing indexed ei_ = ex_to<indexed>(e); ei_.seq = seq; e = ei_; This should be e = ex_to<indexed>(e).thiscontainer(seq); because we may be dealing with something that inherits from indexed rather than an indexed object. I also simplified the clifford exam by removing a huge macro. A patch is in CVS. Best wishes, Chris