8
$\begingroup$

A simple question:

MatchQ[f[a], f[x_]]
(* True *)

MatchQ[D[a], D[x_]]
(* True *)

MatchQ[Dt[a], Dt[x_]]
(* False *)

Why doesn't the last test succeed? Is this a bug or am I doing something wrong? (Mathematica 10.2 on Mac.)

$\endgroup$
  • $\begingroup$ Maybe because D[a] evaluates to a and Dt[a] does not evaluate? $\endgroup$ – yarchik Sep 10 '16 at 17:31
  • 3
    $\begingroup$ @yarchik Not really. -- In MatchQ, the second argument is not held; it is evaluated (see the output of Trace). Thus, Dt[x_] is evaluated, creating this weird expression: Dt[x]*Derivative[1, 0][Pattern][x, _]. (Dt tries to take the derivative of the Pattern function) Of course Dt[a] looks nothing similar to this, so MatchQ returns False. I believe this is unintended (perhaps MatchQ should have HoldRest attribute). $\endgroup$ – JungHwan Min Sep 10 '16 at 17:45
15
$\begingroup$

The symbol MatchQ does not have an Hold* attribute,

Attributes[MatchQ]
(* {Protected} *)

so its arguments are evaluated before the internal definition of MatchQ fires. This means that the pattern-matcher is called only after the evaluation of the arguments. (See for instance the standard evaluation sequence in this tutorial.)


First situation

MatchQ[f[a], f[x_]]
(* True *)

The evaluation of each argument returns the argument itself, so you are effectively asking for a match between the typed expression.


Second situation

MatchQ[D[a], D[x_]]
(* True *)

The arguments are evaluated to what they contain, so you are asking for a match between a and x_, which returns True.


Last situation

MatchQ[Dt[a], Dt[x_]]
(* False *)

While the argument Dt[a] remains unchanged, the argument Dt[x_] gets evaluated to:

Dt[x] Derivative[1, 0][Pattern][x, _]

which then results in False once the pattern-matcher is called.

The fact that Dt[x_] evaluates to this output can be understood by seeing the symbol Pattern as an inert head in the evaluation sequence. You would obtain an output with the same structure by evaluating for instance Dt[f[x, 1]].

This is what happens: a) x_ is represented internally as Pattern[x, Blank[]], and b) Dt takes the total derivative of this expression of head Pattern with respect to all variables, namely with respect to all expressions at level 1 or deeper that are AtomQ and have head Symbol,

Level[Pattern[x, Blank[]], {1}]
(* {x, _} *)

AtomQ /@ %
(* {True, False} *)

Head /@ %%
(* {Symbol, Blank} *)

Level[Pattern[x, Blank[]], {2}]
(* {} *)

so here only with respect to x.


Solution

To avoid the evaluation of the second argument, you can wrap it into HoldPattern:

MatchQ[Dt[a], HoldPattern[Dt[x_]]]
(* True *)
$\endgroup$
  • 3
    $\begingroup$ Nice. For tracking down such things when one is confused, Trace[] or especially WReach's traceView functions can help show a user where his or her assumptions about evaluation diverge from reality. $\endgroup$ – Michael E2 Sep 10 '16 at 18:44

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.