Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Create rules based on data. I have a system that picks out on date,based on some rules. I then want to generate a new rule based on this date and apply the rule to a new dataset.

datePicked={{2008, 3, 21, 0, 0, 0.}}
rule=datePicked/. {t_, n_, o_, b___} :> HoldForm[{t, n, v_, b} /; v <= o];


d=DateRange[{2008, 2, 21, 0, 0, 0.`}, {2008, 3, 21, 0, 0, 0.`}]
Cases[d,#]&@@rule

Problem is that the rule I have made is not general, it has assigned the $ to v. How can I make it general?

share|improve this question
    
Why are you using HoldForm? It works fine without it. –  Leonid Shifrin Apr 25 at 18:17
    
Because then i only get the value from datePicked. but I want to make a rule based on datePick the output should be {t,n,v_,b}/;v<=0, However it comes out as {t,n,v$_,b}/;v$<=0, which means that I cant apply that pattern because it is not general due to $ sign. –  ALEXANDER Apr 25 at 18:24
    
As you can see the output is a pattern with a rule which is used in Cases, but since it is not general it does not work. I therefor want to make the output general by removing the $ signs each assigned to v. –  ALEXANDER Apr 25 at 18:29
4  
Ok, I see. What you really need is something like rule = datePicked /. {t_, n_, o_, b___} :> Identity[{t, n, v_, b} /; v <= o];, where Identity serves as an escaping mechanism, so that the condition is not interpreted as a part of the rule during rule application in the above code. The reason your pattern didn't work was not due to v to v$ renaming, but due to the presence of HoldForm in your pattern - the HoldForm head is not transparent for pattern-matching. As an alternative, you could use HoldPattern in place of HoldForm, but I like the solution with Identity better. –  Leonid Shifrin Apr 25 at 18:35
2  
"how you are able to see the problem" - long experience :). Pattern-matching only shows in Trace when there are non-trivial calls to evaluator (via Condition or PatternTest). In this case, your entire pattern was wrapped in HoldForm, and the pattern-matcher was able to determine the fact of (non)match without testing the condition in the pattern. The problem of Condition being interpreted as a part of the rule rather than belonging to the answer (r.h.s.) only, is indeed rather subtle. This is a good question. If no one does this first, I will convert my comment into a proper answer –  Leonid Shifrin Apr 25 at 19:14

1 Answer 1

up vote 4 down vote accepted

As Leonid explained in the comment, HoldForm is not transparent for the pattern matcher as opposed to HoldPattern:

MatchQ[#, HoldForm[_]] & /@ {a, HoldForm[a]}
MatchQ[#, HoldPattern[_]] & /@ {a, HoldForm[a]}
{False, True}

{True, True}

From the above you see that an expression will match the pattern HoldForm[_] only if its Head is HoldForm. HoldPattern is specially designed to be transparent for the pattern matcher, and so HoldPattern[_] is equivalent to _ for the pattern matcher.

Condition (/;) is interpreted as a part of rule only if it is placed on level 1 inside it:

FullForm[lhs :> rhs /; test]    

RuleDelayed[lhs, Condition[rhs, test]]

{1, 2} /. x_Integer :> f[x] /; OddQ[x]   

{f[1], 2}

Mathematica converts such structures to undocumented RuleCondition for the purposes of pattern matching:

Trace[1 /. x_ :> f[x] /; OddQ[x]] 
(*=>  {{x_:>x/;test,x_:>x/;test},1/. x_:>x/;test,{RuleCondition[$ConditionHold[$ConditionHold[1]],test],Fail},1} *)

If one wraps Condition with arbitrary head it is no more a part of the rule:

{1, 2} /. x_Integer :> f[x /; OddQ[x]]    

{f[1 /; OddQ[1]], f[2 /; OddQ[2]]}

The role of such head may serve Identity as Leonid suggests:

{1, 2} /. x_Integer :> Identity[x /; OddQ[x]]    

{1 /; OddQ[1], 2 /; OddQ[2]}

HoldPattern is also suitable but it is not necessary in your case.

share|improve this answer

Your Answer

 
discard

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.