# Function f[a__][b__] with double inputs and definitions/automatic rules

I have a function of the form f[a___][b___] which I would like to apply rules to, for example:

f[a___][b__] /; ! OrderedQ[{a}] && !OrderedQ[{b}] := Signature[{a}] Signature[{b}] f[Sequence @@Sort[{a}]][Sequence @@Sort[{b}]];
f[a__] /; ! OrderedQ[{a}] := Signature[{a}] f[Sequence @@ Sort[{a}]];


However, these two rules appear to conflict with each other since the second overrides the first, for example:

f[b, a][d, c]
f[b, a]


gives

(-f[a, b])[d, c]
-f[a, b]


The second one here is right, but the first is wrong. If I delete the second rule, I do get the desired output for the first (f[a,b][c,d]). Any idea how I can fix this?

• I do not see how the first rule matches. Although " ! OrderedQ[{a}]" matches, but "OrderedQ[{b}]" does not match. Mar 28, 2023 at 11:19
• Right you are @daniel-huber, I missed a ! on the OrderedQ[{b}]. Fixed now! Mar 28, 2023 at 11:23

The problem is that the 2nd definition will ALWAYS go first because WL always evaluates the head of an expression first. Either you stick with just the first definition or you need to do something like:

ClearAll[f]
f[a__] /; ! OrderedQ[{a}] := With[{
sig = Signature[{a}],
sort = Sort[{a}]
},
sig *f[Sequence @@ sort][##] &
];
f[a___][b__] /; ! OrderedQ[{b}] := Signature[{b}] f[a][Sequence @@ Sort[{b}]];


Another complication is, of course, that in WL you can't just have -f denote the function -f[#]&. There's not much you can do about that.

# Edit

If I have to give a suggestion for this problem, I'd say that you need to change the way you call f:

ClearAll[f];
f[lists__List] /; ! AllTrue[{lists}, OrderedQ] := Times[
Times @@ Map[Signature, {lists}],
f @@ Map[Sort, {lists}]
]

f[{b, a}, {d, c}]
f[{b, a}]
f[{b, a}, {d, c}] f[{b, a}]


f[{a, b}, {c, d}]

-f[{a, b}]

-f[{a, b}] f[{a, b}, {c, d}]

• Thanks for the answer, but it doesn't appear to work... Pasting your code with f[b, a][d, c] f[b, a] produces f[a, b][c, d] -f[Sequence @@ {a, b}][##1] & Any ideas? Mar 28, 2023 at 11:38
• @Akoben That's because you cannot have it both ways. You cannot have f[b,a] evaluate to -f[a, b] AND have it still be an operator after that. Mar 28, 2023 at 13:44
• Ahh, that is mighty annoying. Thanks anyway! Mar 28, 2023 at 14:53
• @Akoben I added a suggestion for a different way to do it. Mar 28, 2023 at 15:46