Equivalente de & # 8220; definido & # 8221; en Mathematica
-
22-07-2019 - |
Pregunta
Necesito una función que tome el nombre de un símbolo como una cadena y devuelva si ese símbolo ya está definido. La función ValueQ
está cerca pero devuelve False para los nombres de función. Además, toma símbolos en lugar de cadenas.
Ejemplos:
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)
PD: Gracias a Pillsy por señalar la necesidad de verificar tanto los DownValues ??como los SubValues.
Solución 2
Lo combiné, lo que parece funcionar:
defined[s_] := ToExpression["ValueQ[" <> s <> "]"] ||
Head@ToExpression[s] =!= Symbol ||
ToExpression["Attributes[" <> s <> "]"] =!= {} ||
ToExpression["DownValues[" <> s <> "]"] =!= {} ||
ToExpression["SubValues[" <> s <> "]"] =!= {}
Esperemos que haya una solución más bonita.
PD: Gracias a Pillsy por señalar la necesidad de verificar tanto los DownValues ??como los SubValues.
Otros consejos
Creo que los nombres deberían hacer el truco:
Nombres [" string "] proporciona una lista de nombres de símbolos que coinciden con cadena.
Si Nombres [" foo "] devuelve {}, entonces no debería haber definiciones para foo; de lo contrario, debería devolver {" foo "}. Por lo tanto, su función 'definida' podría hacerse como:
defined[str_] := Names[str] != {}
Para símbolos al menos, porque esto no funciona para '' 7 '', ya que 7 no es un símbolo. Podría manejar este caso por separado, por ejemplo con NumberQ.
Además, puede usar Símbolo para hacer un símbolo de una cadena (útil para generar símbolos automáticamente) y Definición para verificar las definiciones de un símbolo.
El símbolo [" nombre "] se refiere a un símbolo con el nombre especificado.
Definición [símbolo] se imprime como definiciones dadas para un símbolo.
EDITAR : Mejor que mirar lo que Nombres devuelve, NameQ [" name "] le dice si existe un nombre dado. Sin embargo, aún no le dice si el símbolo tiene una definición explícita, solo que ha sido mencionado.
Puede usar DownValues ??
para ver si tiene " funciones " asociado con un símbolo. Esto funcionará para definiciones como
f[x_, y_] := x + y
o
g[3] = 72 * a;
No funcionará para cosas exóticas como
h[a_][b] = "gribble";
pero la mayoría de la gente no pensará que eso define una función de todos modos. Si desea verificar la existencia de una definición de función, debe convertir el nombre en una expresión (y asegurarse de que esté envuelto en Hold
cuando lo haga). Aquí hay una función razonablemente robusta que verifica tanto DownValues ??
como SubValues ??
:
functionNameQ[name_String] :=
With[{ hSymbol = ToExpression[name, InputForm, Hold] },
MatchQ[hSymbol, Hold[_Symbol]] &&
((DownValues @@ hName) =!= {} || (SubValues @@ hName) =!= {})];
defined[str_] := Not[ToString[FullDefinition[str]] === ""]