This happens because explicit_indices
does not quite work the way you thought it would work. If you have
{a,b,c,d}::Indices(vector);
A::ImplicitIndex(A^{a}_{b});
ex:= A A;
and then do
explicit_indices(_);
you do not get $A^{a}{}_{b} A^{b}{}_{a}$, but rather $A^{a}{}_{b} A^{b}{}_{c}$. So it will not assume that an object which had no indices before the operation should have no free indices after the operation. The proper 'index free' notation of that would be using a trace, so something like
tr{#}::Trace(indices=vector);
ex:= tr( A A );
explicit_indices(_);
in which case you do get $A^{a}{}_{b} A^{b}{}_{a}$.
Note also that explicit_indices
does not automatically raise or lower indices; when you write
F::ImplicitIndex(F_{\mu\nu});
you really literally mean that the symbol F
in index free notation can be replaced with the symbol F_{\mu\nu}
in index-full notation. Making explicit_indices
'guess' about what to do with index raising/lowering is a definite no-no for many of its applications using spinor variables, in which raising one index and lowering another can mean a sign flip (e.g. $\chi^{a}\lambda_{a} = - \chi_{a}\lambda^{a}$).