# Apply rule only if applicable? Check rule applicability? Custom unapplicable rule?

How to avoid recursion in the following example?

Clear[MyRule];



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

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

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

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

Out[19]= 12

-
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 *)



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:

ClearAll[MyHead1]



Or you could use the Villegas-Gayley method:

ClearAll[MyHead1]


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:
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