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
  • $\begingroup$ 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? $\endgroup$ – Mr.Wizard Jan 19 '13 at 10:56
  • $\begingroup$ I want to implement custom algebra with custom heads, transformations and simplifications. I am surprised Mathematica is not well suitable for this. $\endgroup$ – Suzan Cioc Jan 19 '13 at 11:03
  • $\begingroup$ 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. $\endgroup$ – Suzan Cioc Jan 19 '13 at 11:15
  • $\begingroup$ @kguler it's ok $\endgroup$ – Suzan Cioc Jan 19 '13 at 11:20
  • $\begingroup$ "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 :) $\endgroup$ – rm -rf 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.

  • $\begingroup$ 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? $\endgroup$ – Suzan Cioc Jan 19 '13 at 11:08
  • $\begingroup$ @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. $\endgroup$ – Mr.Wizard Jan 19 '13 at 11:18
  • $\begingroup$ @Mr.Wizard I have troubles understanding a significance of "allows local variables to be shared between test and rhs.", not in this topic context but in general. What is so great about that. Obviously rhs and test will share variables since both of them all in the same Module, aren't they? Why don't I think alike documentation creators and so often have troubles understanding the meaning of their words? :) $\endgroup$ – Kuba Aug 5 '16 at 7:11
  • $\begingroup$ p.s. shouldn't it be considered half/magical if this Module/Condition syntax allows to return unevaluated f[arg] and is not reachable by UpValues so easily? $\endgroup$ – Kuba Aug 5 '16 at 7:16
  • $\begingroup$ @Kuba I cannot tell you what the documentation creators were thinking, but I agree what is a strange way to put things. I think I would have understood it better if they had said that the condition test applies to the entire lhs := rhs definition. Regarding the second comment I did mention RuleCondition in my self-answer which is the mechanism by which this works. I am still trying to figure out what counts as "magic" however. $\endgroup$ – Mr.Wizard Aug 5 '16 at 7:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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