Exit

<<xAct`xTensor`

DefManifold[M4,4,IndexRange[a,j]]

A tensor with an arbitrary number of indices and no symmetries among them:

xTensorQ@T^=True;
DependenciesOfTensor@T^={M4};
SlotsOfTensor@T^={AnyIndices[All]};
SymmetryGroupOfTensor@T^:=StrongGenSet[{},GenSet[]];

We introduce an index which will represent a sequence of indices:

AddIndices[TangentM4,{dots}]

PrintAs@dots^="...";

Another sequence of indices different from the above:

AddIndices[TangentM4,{dots2}]

PrintAs@dots2^="...";

If we want to add indices with numeric labels we need to hack a bit into xTensor internal code in order that these kind of indices work:

xAct`xTensor`Private`IndexName@HoldPattern[k[i2_]]:=k[i2];
xAct`xTensor`Private`IndexName@HoldPattern[s[i2_]]:=s[i2];

k/:GIndexQ@k[j_]=True;

s/:GIndexQ@s[j_]=True;

k/:IndexForm@k[i2_]:="\!\(\*SubscriptBox[\(k\), "<>"\("<>ToString@i2<>"\)]\)";

s/:IndexForm@s[i2_]:="\!\(\*SubscriptBox[\(s\), "<>"\("<>ToString@i2<>"\)]\)";

s/:xAct`xTensor`Private`SignedVBundleOfIndex[s[j_]]=TangentM4;
k/:xAct`xTensor`Private`SignedVBundleOfIndex[k[j_]]=TangentM4;
xAct`xTensor`Private`SignedVBundleOfIndex[-s[j_]]=-TangentM4;
xAct`xTensor`Private`SignedVBundleOfIndex[-k[j_]]=-TangentM4;

s/:VBundleOfIndex@s[j_]=TangentM4;
k/:VBundleOfIndex@k[j_]=TangentM4;

s/:BasisQ@s=True;
k/:BasisQ@k=True;

Some examples:

T[k[1],dots,k[n],-s[1],-dots2,-s[n]]

%//Validate

%//ToCanonical

T[k[1],dots,k[n],-s[1],-dots2,-s[n]]T[s[1],dots2,s[n]]

%//Validate

%//ToCanonical