【问题标题】:Equivalent of "defined" in MathematicaMathematica 中“定义”的等价物
【发布时间】:2009-09-18 19:39:41
【问题描述】:

我需要一个将符号名称作为字符串并返回该符号是否已定义的函数。函数 ValueQ 已关闭,但它为函数名称返回 False。此外,它需要符号而不是字符串。

例子:

defined["N"] --> True (predefined function N)
defined["x"] --> False
x = 7;
defined["x"] --> True (x is now defined)
defined["7"] --> True (7 is a number)
f[x_] := 2x
defined["f"] --> True (f has DownValues)
g[x_][y_] := x+y
defined["g"] --> True (g has SubValues)

PS:感谢 Pillsy 指出需要同时检查 DownValues 和 SubValues。

【问题讨论】:

    标签: wolfram-mathematica utilities


    【解决方案1】:

    我把这个拼凑起来,这似乎可行:

    defined[s_] := ToExpression["ValueQ[" <> s <> "]"] || 
                   Head@ToExpression[s] =!= Symbol || 
                   ToExpression["Attributes[" <> s <> "]"] =!= {} ||
                   ToExpression["DownValues[" <> s <> "]"] =!= {} ||
                   ToExpression["SubValues[" <> s <> "]"] =!= {}
    

    希望有更漂亮的解决方案。

    PS:感谢 Pillsy 指出需要同时检查 DownValues 和 SubValues。

    【讨论】:

    • 如果我想要动态,如何将 Cos 转换为 "Cos"?
    【解决方案2】:

    我认为名字应该可以解决问题:

    Names["string"] 给出一个列表 匹配的符号名称 字符串。

    如果 Names["foo"] 返回 {},则不应有 foo 的定义,否则应返回 {"foo"}。 所以你的函数“定义”可能是这样完成的:

    defined[str_] := Names[str] != {}
    

    至少对于符号来说,因为这不适用于“7”,因为 7 不是符号。您可以单独处理这种情况,例如使用 NumberQ。

    此外,您可以使用 Symbol 从字符串中生成符号(用于自动生成符号)和 Definition 来检查符号的定义。

    Symbol["name"] 指的是一个符号 指定的名称。

    Definition[symbol] 打印为 为符号给出的定义。

    编辑:比查看 Names 返回的内容更好,NameQ["name"] 会告诉您给定名称是否存在。仍然没有告诉你符号是否有明确的定义,只是提到了它。

    【讨论】:

    • 哦,太好了!但是 Names["7"] 失败了。另外,如果你提到一个符号 x 那么 Names["x"] 将表明它已定义,即使它实际上没有定义。
    • 你是对的。我不确定是否有任何方法可以知道符号是否有明确的定义,或者只是被提及。 Definition[foo] 告诉你这一点,但我认为不能自动使用。
    【解决方案3】:

    您可以使用DownValues 查看您是否有与符号关联的“功能”。这适用于像

    这样的定义
    f[x_, y_] := x + y
    

    或

    g[3] = 72 * a;
    

    它不适用于异国情调的东西,例如

    h[a_][b] = "gribble";
    

    但大多数人无论如何都不会认为这是定义函数。如果要检查函数定义是否存在,则需要将名称转换为表达式(并确保它包含在Hold 中!)。这是一个相当强大的函数,可以同时检查 DownValues 和 SubValues:

    functionNameQ[name_String] := 
        With[{ hSymbol = ToExpression[name, InputForm, Hold] },
            MatchQ[hSymbol, Hold[_Symbol]] &&
                ((DownValues @@ hName) =!= {} || (SubValues @@ hName) =!= {})];
    

    【讨论】:

      【解决方案4】:
      defined[str_] := Not[ToString[FullDefinition[str]] === ""]
      

      【讨论】:

      • 这个解决方案有副作用,它会评估函数。例如f[x_] := Print[x],defined[f["Hello"]]。看看this。
      • @Rohit:这是停机问题的问题,而不是我的解决方案。假设你有 f[x_] := Modue[{}, If[veryComplicatedConditionWhichNobodyKnowsWillEvenFinishComputingBeforeEternityCome, Sin, somethingUndefined],并且你想知道 f[someX] 是否被定义,那么你想知道结果是 Sin 还是 somethingUndefined,并且如果您可以(通常)执行此操作而无需实际调用veryComplicatedConditionWhichNobodyKnowsWillEvenFinishComputingBeforeEternityCome,那么您可以解决Halting Problem。
      猜你喜欢
      • 1970-01-01
      • 2010-12-04
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-26
      • 2018-04-16
      相关资源
      最近更新 更多