Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking if a symbol is defined

Is there an easy way to check if there's a definition for x? I need a function that takes something of the form f,f[_] or f[_][_] and returns True if there's a definition for it

To be really concrete, I'm storing things using constructs like f[x]=b, and g[x][y]=z and I need to check if f[x] has definition for every x in some list and if g[x][y] has a definition for every x,y in some set of values

like image 795
Yaroslav Bulatov Avatar asked Jan 04 '11 22:01

Yaroslav Bulatov


3 Answers

Actually, the ValueQ function is not innocent, since it leaks evaluation for code with side effects. Examples:

ClearAll[f, g];  f[x_] := Print[x];  g[x_][0] := Print[x]; {ValueQ[f[1]],ValueQ[g[2][0]]} 

If you remove the ReadProtected Attribute of ValueQ and look at the code, you will see why - the code is very simplistic and does a decent job for OwnValues only. Here is a more complex version which I developed to avoid this problem (you can test that, at least for the examples above, it does not leak evaluation):

ClearAll[symbolicHead]; SetAttributes[symbolicHead, HoldAllComplete]; symbolicHead[f_Symbol[___]] := f; symbolicHead[f_[___]] := symbolicHead[f]; symbolicHead[f_] := Head[Unevaluated[f]];  ClearAll[partialEval]; SetAttributes[partialEval, HoldAllComplete]; partialEval[a_Symbol] /; OwnValues[a] =!= {} :=     Unevaluated[partialEval[a]] /. OwnValues[a];  partialEval[a : f_Symbol[___]] /; DownValues[f] =!= {} :=    With[{dv = DownValues[f]},       With[{eval = Hold[partialEval[a]] /. dv},          ReleaseHold[eval] /;             (First[Extract[eval, {{1, 1}}, HoldComplete]] =!=             HoldComplete[a])]];  partialEval[a_] :=    With[{sub = SubValues[Evaluate[symbolicHead[a]]]},       With[{eval = Hold[partialEval[a]] /. sub},          ReleaseHold[eval] /;             (First[Extract[eval, {{1, 1}}, HoldComplete]] =!=             HoldComplete[a])]];  ClearAll[valueQ]; SetAttributes[valueQ, HoldAllComplete]; valueQ[expr_] := partialEval[expr] =!= Unevaluated[partialEval[expr]]; 

This is not complete either, since it does not account for UpValues, NValues, and FormatValues, but this seems to be enough for your stated needs, and also, rules for these three extra cases can perhaps also be added along the same lines as above.

like image 118
Leonid Shifrin Avatar answered Sep 30 '22 06:09

Leonid Shifrin


If I understood correctly I think the function ValueQ is what you are looking for. It will return true if a variable or a function has been defined and false if it has not been defined.

Read more at http://reference.wolfram.com/mathematica/ref/ValueQ.html

like image 30
dbjohn Avatar answered Sep 30 '22 07:09

dbjohn


  • For symbols in System`, check SyntaxInformation for a ArgumentsPattern option.
  • For other symbols, check DownValues, UpValues, SubValues, etc...

What's the intended use?

like image 27
Brett Champion Avatar answered Sep 30 '22 08:09

Brett Champion