I am dealing with brackets br[arg1, arg2, ...], having a sequence of positive integers (labels) as argument. Brackets are totally antisymmetric, hence it is important - when reordering labels - to keep track of the sign of the permutation.
I want to write a very simple sorting function, such that, given an arbitrary expression involving several brackets, reorders their arguments putting a prescribed subset of labels in front.
I have a first function, sort, that works just fine when the subset of distinguished labels has length 2.
sort[expr_, lab_List] := Block[{}, expr //. {br[a1___, lab[[1]], a2___, lab[[2]], a3___] :> Signature[{a1, lab[[1]], a2, lab[[2]], a3}]*Signature[Join[{lab[[1]], lab[[2]]}, { a1, a2, a3}]]* br @@ Join[{lab[[1]], lab[[2]]}, {a1, a2, a3}]} ] As an example, consider
ex = br[1, 5, 7, 8, 9] br[3, 1, 5, 7, 8] br[3, 1, 4, 5] + br[2, 3, 4, 1, 6, 5] br[1, 3, 5] br[1, 7, 8, 5, 3] sort[ex, {1, 5}] Out[3]= -br[1, 5, 3, 4] br[1, 5, 3, 7, 8] br[1, 5, 7, 8, 9] + br[1, 5, 3] br[1, 5, 7, 8, 3] br[1, 5, 2, 3, 4, 6]
Then I tried to generalize it, to allow subset of arbitrary length to be sorted in front of every argument and this is what I came up with.
genSort[expr_, lab_List] := Block[{otherLabels}, otherLabels = Table[ToExpression@StringJoin["a", ToString[i]], {i, 1, Length[lab] + 1}]; expr //. {br @@ Riffle[(Pattern[#, ___] & /@ otherLabels), lab] :> Signature[Riffle[otherLabels, lab]]*Signature[Join[lab, otherLabels]]* br @@ Join[lab, otherLabels]} ] Now when I try to use this more general version of the function on the previous example, I get
ex = br[1, 5, 7, 8, 9] br[3, 1, 5, 7, 8] br[3, 1, 4, 5] + br[2, 3, 4, 1, 6, 5] br[1, 3, 5] br[1, 7, 8, 5, 3] genSort[ex, {1, 5}] During evaluation of In[44]:= ReplaceRepeated::rrlim: Exiting after br[3,1,4,5] br[1,5,7,8,9] br[3,1,5,7,8]+br[1,3,5] br[1,7,8,5,3] br[2,3,4,1,6,5] scanned 65536 times. Out[4]= 2 br[1, 5, a1, a2, a3]^3
Now, beside the warning about the ReplaceRepeated, obviously the problem is that I am not able to convince Mathematica to identify the a1,a2,... with appropriate (possibly empty) sequences of labels, as it was seamlessly doing with the more specific function above.
I understand that Mathematica is just using the labels a1, a2, ... ignoring the pattern matching construct, but I still believe that the implementation is correct in spirit. Is there a way to save it, or is it doomed? (I also tried to use some Evaluate command here and there, it doesn't seem to change anything.)
On a separate note, I created the list of a-indices with a rather cumbersome construct. However, this was the only one I could think of which could allow to create an a priori unspecified number of objects and to append some blanks to them to define a pattern (neither a[i], nor Subscript[a,i] would do, of course). Is there a better way out?
Thanks for your help!