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

How to avoid recursion in the following example?


MyRule1 = MyHead1[x_MyHead2] | MyHead1[x_MyHead3] -> x;

MyHead1[x_] := Replace[MyHead1[x], MyRule1];



How to make first rule in example below treated by Replace as not applicable?

In[17]:= ComplexRule1 = a -> Block[{},

In[18]:= ComplexRule2 = a -> Block[{},

In[19]:= Replace[a, {ComplexRule1, ComplexRule2}]

Out[19]= 12
share|improve this question
You're asking a rapid-fire series of questions about pattern matching. I am assuming this is all part of a particular application. What is it? – Mr.Wizard Jan 19 '13 at 10:56
I want to implement custom algebra with custom heads, transformations and simplifications. I am surprised Mathematica is not well suitable for this. – Suzan Cioc Jan 19 '13 at 11:03
The main problem is "preprocessing". If user enters some expression with some heads, it should be automatically transformed into expressions with same heads, but simplified and normalized. This causes recursions for me. Conditions work bad here because they can require complex computations. – Suzan Cioc Jan 19 '13 at 11:15
@kguler it's ok – Suzan Cioc Jan 19 '13 at 11:20
"I am surprised Mathematica is not well suitable for this." — usually when someone says this, it's more often the case that they haven't thought through their problem well enough or are unfamiliar with Mathematica. I don't know which one it is :) – R. M. Jan 19 '13 at 17:17

You're mixing DownValues rules made with SetDelayed (:=) and replacement rules. Without seeing your application I cannot tell why. If you provide more information about your application a different approach may be recommended.

I see two problems with your code right off the bat. First:

MyHead1[x_] := Replace[MyHead1[x], MyRule1];

Here you made a definition that evaluates to itself in an unheld form. This causes infinite recursion.

Second, by defining:

MyRule1 = MyHead1[x_MyHead2] | MyHead1[x_MyHead3] :> x;  (* note use of :> to localize x *)

MyHead1[x_] := "anything"

MyRule1 evaluates to "anything" | "anything" :> x as soon as it is accessed.

The second problem might be corrected with HoldPattern:

MyRule1 = HoldPattern[MyHead1[x_MyHead2] | MyHead1[x_MyHead3]] :> x;

The first is more complicated. I still suppose that you may want instead to write this to avoid the recursion in the first place, but alternatively you could work within Hold:


MyHead1[x_] := Replace[Hold[MyHead1[x]], MyRule1, {1}];  (* note Levelspec *)

Or you could use the Villegas-Gayley method:


MyHead1[x_] /; ! TrueQ[insideMyHead1] :=
 Block[{insideMyHead1 = True},
  Replace[MyHead1[x], MyRule1]

I suspect instead of all this you may be looking for the functionality of UpSet, UpSetDelayed, TagSet, etc. which make UpValues rules. Again, with a more complete problem specification I may be able to recommend something better.

Lastly, the title of your question makes me think that perhaps you would find value in this special use of Condition:

lhs := Module[{vars}, rhs /; test] allows local variables to be shared between test and rhs. You can use the same construction with Block and With.

share|improve this answer
By MyRule1 = MyHead1[x_MyHead2] | MyHead1[x_MyHead3] -> x I meant a rule, which applies to expression with head 2 or 3 and gives x in the case. Isn't it correct? – Suzan Cioc Jan 19 '13 at 11:08
@Suzan I added some more information to my answer. I hope that you will find it useful. I especially recommend that you read about UpSet and TagSet. Without a better sense of what you're really trying to do I cannot be more specific I'm afraid. – Mr.Wizard Jan 19 '13 at 11:18

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.