11
$\begingroup$

Main Problem

Mathematica's pattern matching mechanism seems fairly well in most cases but in some situations, I would like to ask for a bit more freedom.

We can easily call for extra evaluation while testing whether a pattern is valid, even changing the test condition if we want:

Block[{i},MatchQ[Range@10, {(_?((If[Head[i] === Symbol, i = #, i = i + 1]; # == i) &)) ..}]]

In this case, the test condition will change with an external variable i.

So my problem is, could we do the same to a pattern itself?

For Example, Enter an expression like If[TrueQ@x,a_,b_] to tell pattern matcher: Call for extra evaluation to deternmin what exactly this pattern should be in this place.

If this could be achieved, a whole branch of evaluation would be possible, the most significant one, in my opinion, could be the generation of anonymous Condition by generating unique variable at runtime. This would enable the usage of Combining Repeated with Condition which cannot be easily achieved now, check this place.


A toy code here to illustrate my point clearer:

I would like to check whether a sequence could be written as a series of small sequences with two elements each, As PatternTest would test the elements one by one, while I need to test them as a whole to check whether the length of the sequence is 2, I must use Condition, so I wrote the following code:

MatchQ[#,{(x__/;Length[{x}]==2)..}]&/@{{1,2,1,2},{1,2,3,4}}

It returns {True,False}, but I would like to make it generate {True,True}, as both of them could be interpreted as two repeated sequence with two elements each. but in order to use Condition, I must declare the name of the pattern, but once I've declared a stationary name of the pattern, Repeated would work in a not desired way.

An easy solution is to change the pattern's name upon each evaluation of this pattern, something like:

{(Pattern[x,__]/;(x=Unique[];Length[{x}]==2))..}

But it won't work as desired easily because it requires to change the pattern Pattern[x,__] according to the name stored in global variable x at runtime.


Toy example 2

Reduce the following code:

MatchQ[{a, b, a, b, a, b, a, b, a, b},{PatternSequence[x_, y_] ..}]

To something like

Block[{i=0},MatchQ[{a, b, a, b, a, b, a, b, a, b},{If[OddQ[++i],x_,y_]..}]]

Note that the second differs from the first that it could match something like [{a, b, a, b, a, b, a, b, a}, but let's ignore that, sometimes we even want this effect, e.g. finding recursive loops.

$\endgroup$
2
  • 4
    $\begingroup$ In something like Repeated[patt /; cond] the patt part is evaluated only once, not every time a match is attempted. So I think what you're asking would require a fundamental change to the internals of the pattern matcher. $\endgroup$ Commented Mar 4, 2017 at 16:49
  • 1
    $\begingroup$ @SimonWoods Yes, It only evaluate once in all the cases I know, but maybe there's some undocumented way to force calculation? Just like normally in a replace operation, rep in patt->rep won't be calculated, but one can use in place eval technique to force evaluation. Or simply use the undocumented RuleCondition. I'm just wondering whether there're any similar secret operations that can force the evaluation of patt at runtime. $\endgroup$
    – Wjx
    Commented Mar 5, 2017 at 0:57

1 Answer 1

2
$\begingroup$

I can deal with the sequence matching without names:

$s={};
a = Function[AppendTo[$s, #];True];
b[c_] := ($s={};#)&[c@$s]

MatchQ[{(__?a/;b[Length@#===2&])..}] /@ {{1,2,1,2},{1,2,3,4}}
(* {True, True} *)

But I think there's no advantage of pattern-matching performance anymore. And the requirement for three definitions takes the beauty away. Maybe this solution is useless.

Maybe this is quite a pitfall of the language design.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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