I want to define a function evaluate[f_[x__]] which acts on an arbitrary function f[a,b,c,d]. The function f takes any kind of argument and the function evaluate[f_[x__]] has to deal with the following properties

  • The function f is defined for specific values for a,b,c,d, which may be numbers, list, functions etc.. For example,consider the definitions f[1,2,3,4]=1 and f[1,2,p[3],p[4]]=2 where p[a_] are undefined functions/tensors. Notice the order matters.

I want the function evaluate returning the function f evaluated on the specific permutation for which I have given a definition of f itself. For example,

  • evaluate[f[3,4,1,2]] must return f[1,2,3,4]=1 since among the permutations of {3,4,1,2}, f is only defined on {1,2,3,4}.
  • evaluate[f[p[3],p[4],1,2]] must return f[1,2,p[3],p[4]]=2 since among the permutations of {p[3],p[4],1,2}, f is only defined on {1,2,p[3],p[4]}.
  • evaluate[f[x__]] must return False is multiple permutations are defined and if no permutations are matched.

Is there any intelligent and clever way to write a function with these properties?

  • $\begingroup$ Please clarify: do you want evaluate to permute arguments of f(or any function?) to a form for which term rewriting finds a rule for arguments of f? What if there are multiple permutations which are permissible? $\endgroup$
    – kirma
    May 31, 2019 at 17:35
  • $\begingroup$ @kirma I didn't understand your first question. I want evaluate to permute arguments of only the function f. It is supposed there are no multiple permutations which are permissible. I can add the requirement that if multiple permutations are permissible, return False. $\endgroup$
    – apt45
    May 31, 2019 at 17:39
  • $\begingroup$ OK. What if no permutation matches? $\endgroup$
    – kirma
    May 31, 2019 at 17:48
  • $\begingroup$ @kirma It may return False. Let me edit the question $\endgroup$
    – apt45
    May 31, 2019 at 17:55
  • $\begingroup$ In addition to my accepted answer, I would suggest taking a look at Orderless, that is SetAttribute[f, Orderless] for f. This doesn't handle no-matches or multiple-matches cases, but can auto-permute arguments when evaluating the function. $\endgroup$
    – kirma
    Jun 1, 2019 at 7:37

1 Answer 1


Maybe this is what you want:

evaluate[f_[args___]] := 
  With[{perms = 
     Select[Unevaluated@*f @@@ Permutations[{args}], ValueQ]}, 
   If[Length@perms == 1, perms[[1, 1]], False]];

(args are evaluated normally when evaluate is called.)

Now, let's define a function:

f[2, 4, 3, 1] = 3;
f[a, b, c, d] = 1;
f[b, c, d, a] = 1;
f[5, x_?Positive] := x + 10;

This results:

evaluate[f[1, 2, 3, 4]]


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


evaluate[f[foo, bar]]


evaluate[f[-1, 5]]


evaluate[f[1, 5]]



Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.