检查是否定义了符号

时间:2011-01-04 22:46:06

标签: wolfram-mathematica

有没有一种简单的方法来检查是否有x的定义?我需要一个功能 ff[_]f[_][_]形式的内容,如果有定义,则返回True

要真正具体,我使用f [x] = b和g [x] [y] = z这样的结构存储东西,我需要检查f [x]是否有某些定义如果g [x] [y]在某些值集合中有每个x,y的定义

4 个答案:

答案 0 :(得分:22)

实际上,ValueQ函数并不是无辜的,因为它泄漏了对具有副作用的代码的评估。例子:

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

如果删除ValueQ的ReadProtected属性并查看代码,您将看到原因 - 代码非常简单,只为OwnValues做了不错的工作。这是一个更复杂的版本,我开发它是为了避免这个问题(你可以测试一下,至少对于上面的例子,它不会泄漏评估):

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]];

这也不完整,因为它没有考虑UpValues,NValues和FormatValues,但这似乎足以满足您的需求,而且,这三个额外案例的规则也可能同时添加如上所述。

答案 1 :(得分:16)

如果我理解正确,我认为函数ValueQ就是你要找的。如果定义了变量或函数,它将返回true,如果尚未定义,则返回false。

http://reference.wolfram.com/mathematica/ref/ValueQ.html

了解详情

答案 2 :(得分:1)

  • 对于System`中的符号,请检查语法信息以获取ArgumentsPattern选项。
  • 对于其他符号,请检查DownValues,UpValues,SubValues等...

预期用途是什么?

答案 3 :(得分:1)

如果有问题的对象有足够的内部结构,这是一个很好的,简单的解决方案。

您可以使用

Length[variable]

检测variable是否已分配给具有多个部件的内容。因此:

Remove[variable]
Length[variable]
(*---> 0*)
variable={1,2,3};
Length[variable]
(*---> 3*)

然后,您可以使用Length[variable]>0在后​​一种情况下获取True

但是,如果有可能将variable分配给原子值,例如单个字符串或数字,则会失败:

variable=1
Length[variable]
(*---> 0*)