1
$\begingroup$

Consider a definition like

f[x_] := x[[1]] + x[[3]] + x[[1 + 2]]

I want a "ContainsExpression" which I can use similarly to this:

ContainsExpression[f[x], x[[1]]]
>>> True

ContainsExpression[f[x], x[[2]]]
>>> False

ContainsExpression[f[x], x[[3]]]
>>> True

ContainsExpression[f[x], x[[1 + 2]]]
>>> True

ContainsExpression[f[x], x[[2 + 1]]]
>>> (either False or True is acceptable for me)

I've tried DownValues[f][[1]][[2]] but it gives me an error because it tries to subscript x... I can't figure out how to make Mathematica avoid evaluating the subscripts correctly. How can I do this?

$\endgroup$

2 Answers 2

1
$\begingroup$

Try using MenberQwhich fulfills exactly the role your ContainsExpression is assumed to:

 f[x_] := x[[1]] + x[[3]] + x[[1 + 2]];
MemberQ[f[x], x[[1]]] // Quiet

(*  True  *)

Quiet is necessary here, since Mma does not know that x has a structure and gives warnings otherwise. It is not necessary, if you have previously already defined x as an object with the structure, say, a list.

Have fun!

$\endgroup$
5
  • $\begingroup$ Edit: Wait, actually, this doesn't seem to work... f[x_] := x[[1]] + x[[3]] + x[[1 + 2]]; MemberQ[f[x], x[[3]]] // Quiet... why? $\endgroup$
    – user541686
    Mar 4, 2016 at 8:03
  • $\begingroup$ @Mehrdad Well, generally it is better to allow Mma to give warnings. Otherwise one may easily miss an error. But here it is quite clear why the warnings appear and that it is no problem. $\endgroup$ Mar 4, 2016 at 8:04
  • 2
    $\begingroup$ Update: seems like (not) FreeQ is actually the right thing, not MemberQ? $\endgroup$
    – user541686
    Mar 4, 2016 at 8:05
  • $\begingroup$ @Mehrdad It is because FullForm[f[x]] // Quiet returns Plus[Part[x, 1], Times[2, Part[x, 3]]] so there is a multiplication there. One can repair it as follows: MemberQ[f[x], a_*x[[3]]] // Quiet. $\endgroup$ Mar 4, 2016 at 8:09
  • $\begingroup$ Cool, thanks!!! $\endgroup$
    – user541686
    Mar 4, 2016 at 8:14
5
$\begingroup$

You can use Downvalues and HoldPattern to do this without Quiet.

FreeQ[DownValues@f, HoldPattern@x[[3]]]
(* False *)

FreeQ[DownValues@f, HoldPattern@x[[7]]]
(* True *)

DownValues returns the definition with HoldPattern so you need hold the pattern you are searching for in order to pattern match.

Hope this helps.

$\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.