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!