Putting Constraints on Patterns

The Wolfram Language provides a general mechanism for specifying constraints on patterns. All you need to do is to put /;condition at the end of a pattern to signify that it applies only when the specified condition is True. You can read the operator as "slashsemi", "whenever", or "provided that".

pattern/;conditiona pattern that matches only when a condition is satisfied
lhs:>rhs/;conditiona rule that applies only when a condition is satisfied
lhs:=rhs/;conditiona definition that applies only when a condition is satisfied

Putting conditions on patterns and transformation rules.

This gives a definition for that applies only when its argument is positive.
In[1]:=
Click for copyable input
The definition for is used only when the argument is positive.
In[2]:=
Click for copyable input
Out[2]=
This gives the negative elements in the list.
In[3]:=
Click for copyable input
Out[3]=

You can use on whole definitions and transformation rules, as well as on individual patterns. In general, you can put /;condition at the end of any definition or rule to tell the Wolfram Language that the definition or rule applies only when the specified condition holds. Note that conditions should not usually be put at the end of definitions or rules, since they will then be evaluated immediately, as discussed in "Immediate and Delayed Definitions".

Here is another way to give a definition that applies only when its argument is positive.
In[4]:=
Click for copyable input
Once again, the factorial functions evaluate only when their arguments are positive.
In[5]:=
Click for copyable input
Out[5]=

You can use the operator to implement arbitrary mathematical constraints on the applicability of rules. In typical cases, you give patterns which structurally match a wide range of expressions, but then use mathematical constraints to reduce the range of expressions to a much smaller set.

This rule applies only to expressions that have the structure .
In[6]:=
Click for copyable input
This expression has the appropriate structure, so the rule applies.
In[7]:=
Click for copyable input
Out[7]=
This expression, while mathematically of the correct form, does not have the appropriate structure, so the rule does not apply.
In[8]:=
Click for copyable input
Out[8]=
This rule applies to any expression of the form , with the added restriction that .
In[9]:=
Click for copyable input
The new rule does apply to this expression.
In[10]:=
Click for copyable input
Out[10]=

In setting up patterns and transformation rules, there is often a choice of where to put conditions. For example, you can put a condition on the righthand side of a rule in the form , or you can put it on the lefthand side in the form . You may also be able to insert the condition inside the expression lhs. The only constraint is that all the names of patterns that you use in a particular condition must appear in the pattern to which the condition is attached. If this is not the case, then some of the names needed to evaluate the condition may not yet have been "bound" in the patternmatching process. If this happens, then the Wolfram Language uses the global values for the corresponding variables, rather than the values determined by pattern matching.

Thus, for example, the condition in will use values for and that are found by matching , but the condition in will use the global value for , rather than the one found by matching the pattern.

As long as you make sure that the appropriate names are defined, it is usually most efficient to put conditions on the smallest possible parts of patterns. The reason for this is that the Wolfram Language matches pieces of patterns sequentially, and the sooner it finds a condition which fails, the sooner it can reject a match.

Putting the condition around the is slightly more efficient than putting it around the whole pattern.
In[11]:=
Click for copyable input
Out[11]=
You need to put parentheses around the piece in a case like this.
In[12]:=
Click for copyable input
Out[12]=

It is common to use to set up patterns and transformation rules that apply only to expressions with certain properties. There is a collection of functions built into the Wolfram Language for testing the properties of expressions. It is a convention that functions of this kind have names that end with the letter , indicating that they "ask a question".

IntegerQ[expr]integer
EvenQ[expr]even number
OddQ[expr]odd number
PrimeQ[expr]prime number
NumberQ[expr]explicit number of any kind
NumericQ[expr]numeric quantity
PolynomialQ[expr,{x1,x2,}]polynomial in , ,
VectorQ[expr]a list representing a vector
MatrixQ[expr]a list of lists representing a matrix
VectorQ[expr,NumericQ],MatrixQ[expr,NumericQ]
vectors and matrices where all elements are numeric
VectorQ[expr,test],MatrixQ[expr,test]
vectors and matrices for which the function test yields True on every element
ArrayQ[expr,d]full array with depth matching d

Some functions for testing mathematical properties of expressions.

The rule applies to all elements of the list that are numbers.
In[13]:=
Click for copyable input
Out[13]=
This definition applies only to vectors of integers.
In[14]:=
Click for copyable input
The definition is now used only in the first case.
In[15]:=
Click for copyable input
Out[15]=

An important feature of all the Wolfram Language propertytesting functions whose names end in is that they always return False if they cannot determine whether the expression you give has a particular property.

is an integer, so this returns True.
In[16]:=
Click for copyable input
Out[16]=
This returns False, since is not known to be an integer.
In[17]:=
Click for copyable input
Out[17]=

Functions like IntegerQ[x] test whether x is explicitly an integer. With assertions like x in Integers you can use Refine, Simplify, and related functions to make inferences about symbolic variables x.

SameQ[x,y] or x===yx and y are identical
UnsameQ[x,y] or x=!=yx and y are not identical
OrderedQ[{a,b,}]a, b, are in standard order
MemberQ[expr,form]form matches an element of expr
FreeQ[expr,form]form matches nothing in expr
MatchQ[expr,form]expr matches the pattern form
ValueQ[expr]a value has been defined for expr
AtomQ[expr]expr has no subexpressions

Some functions for testing structural properties of expressions.

With , the equation remains in symbolic form; yields False unless the expressions are manifestly equal.
In[18]:=
Click for copyable input
Out[18]=
The expression is not a member of the list .
In[19]:=
Click for copyable input
Out[19]=
However, is not completely free of .
In[20]:=
Click for copyable input
Out[20]=
You can use FreeQ to define a "linearity" rule for .
In[21]:=
Click for copyable input
Terms free of are pulled out of each .
In[22]:=
Click for copyable input
Out[22]=
pattern?testa pattern that matches an expression only if test yields True when applied to the expression

Another way to constrain patterns.

The construction allows you to evaluate a condition involving pattern names to determine whether there is a match. The construction instead applies a function test to the whole expression matched by pattern to determine whether there is a match. Using instead of sometimes leads to more succinct definitions.

With this definition, matches for are tested with the function NumberQ.
In[23]:=
Click for copyable input
The definition applies only when has a numerical argument.
In[24]:=
Click for copyable input
Out[24]=
Here is a more complicated definition. Do not forget the parentheses around the pure function.
In[25]:=
Click for copyable input
The definition applies only in certain cases.
In[26]:=
Click for copyable input
Out[26]=
Except[c]a pattern that matches any expression except c
Except[c,patt]a pattern that matches patt but not c

Patterns with exceptions.

This gives all elements except 0.
In[27]:=
Click for copyable input
Out[27]=
Except can take a pattern as an argument.
In[28]:=
Click for copyable input
Out[28]=
This picks out integers that are not 0.
In[29]:=
Click for copyable input
Out[29]=

Except[c] is in a sense a very general pattern: it matches anything except c. In many situations you instead need to use Except[c,patt], which starts from expressions matching patt, then excludes ones that match c.