Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am writing a code that manipulates expressions that contains functions with an arbitrary number of arguments. An example expression is

expr = x f[a, b, c, d] - 4 f[b, a, d] + z f[] + f[a, b, d] - f[a]f[b,d]

What I would like to do is to make my code to be a little user-friendly by making it throw a message if the expression is invalid. Basically, the only symbols allowed to appear in f are allowedList={a,b,d}, and so I probably need to somehow use Scan to check through expr. (The above example should yield an 'error' since the first term has a c in it.)

To make answering easier, please assume that the input expr will be such that all arguments will have Head = Symbol. But please allow for the possibility that multiple fs could be multiplied together.

share|improve this question
up vote 5 down vote accepted

This function yields True if the expression expr is valid, otherwise it yields False:

validExpressionQ[ expr_, allowedList_List] := 
  Union @ Cases[ Variables[expr], f_[x___] :> x, Infinity] == Union @ allowedList

now we have, e.g.

validExpressionQ[ x f[a, b, d] - 4 f[b, a, d] + z f[] + f[a, b, d] - f[a] f[b, d], 
                  {a, b, d}]
validExpressionQ[ x f[a, b, c, d] - 4 f[b, a, d] + z f[] + f[a, b, d] - f[a] f[b, d],
                  {a, b, d}]
share|improve this answer
I guess it should work even if f has DownValues – Dr. belisarius Jan 29 '14 at 13:19
not sure, BTW :) – Dr. belisarius Jan 29 '14 at 13:20
Very nice. In the right hand side, would it still work if I replaced Union @ allowedList with just allowedList? – QuantumDot Jan 29 '14 at 14:35
@QuantumDot No, Union sorts the list, it might be replaced with Sort but then it doesn't delete duplicates. – Artes Jan 29 '14 at 20:38

A possibility is to define a support function:

EDIT: Thanks to Simon Woods' comment: .. instead of __

check[(a | b | d) ..] := 1;
check[___] = Indeterminate;

The substitution

expr /. f-> check

contains Indeterminate if f has arguments not allowed.


If[FreeQ[expr /. f -> check, Indeterminate], "ok", "error"]

returns "error" for your example and "ok" if the arguments are acceptable.

share|improve this answer
check[a, b] returns Indeterminate. Perhaps you intended to use RepeatedNull rather than BlankSequence ? – Simon Woods Jan 29 '14 at 21:30
I just posted something very similar before reading this answer. +1! Nevertheless I think my code has advantages. – Mr.Wizard Jan 30 '14 at 15:52

Since it seems that evaluation of the expression is specifically permitted let's leverage that:

check[expr_, f_, pat_] := FreeQ[expr /. f[pat ...] -> 1, _f]

check[expr, f, a | b | d]
check[expr, f, a | b | c | d]


I used Alternatives instead of List to make this cleaner, but you can always Apply Alternatives if needed.

If for some reason you don't like the method above, here is my take on Artes's method:

check2[expr_, f_, args_] :=
  {} === Complement[Cases[expr, f[x___] :> x, -2], args]

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

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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