wolfram mathematica - mathematica - Comprobando si un símbolo está definido
resolver ecuaciones en mathematica (4)
¿Hay una manera fácil de verificar si hay una definición para x? Necesito una función que tome algo de la forma f
, f[_]
o f[_][_]
y devuelva True
si hay una definición para ella
Para ser realmente concreto, estoy almacenando cosas usando construcciones como f [x] = b, y g [x] [y] = z y necesito verificar si f [x] tiene definición para cada x en alguna lista y si g [x] [y] tiene una definición para cada x, y en algún conjunto de valores
Aquí hay una solución agradable y simple que funciona si el objeto en cuestión tiene suficiente estructura interna.
Puedes usar
Length[variable]
para detectar si la variable
ha sido asignada a algo con más de una parte. Así:
Remove[variable]
Length[variable]
(*---> 0*)
variable={1,2,3};
Length[variable]
(*---> 3*)
Luego puede usar Length[variable]>0
para obtener True
en el último caso.
Sin embargo, esto falla si existe la posibilidad de que la variable
se asigne a un valor atómico, como una sola cadena o número:
variable=1
Length[variable]
(*---> 0*)
En realidad, la función ValueQ no es inocente, ya que filtra la evaluación del código con efectos secundarios. Ejemplos:
ClearAll[f, g];
f[x_] := Print[x];
g[x_][0] := Print[x];
{ValueQ[f[1]],ValueQ[g[2][0]]}
Si elimina el atributo ReadProtected de ValueQ y observa el código, verá por qué: el código es muy simplista y hace un trabajo decente solo para OwnValues. Aquí hay una versión más compleja que desarrollé para evitar este problema (puede probar que, al menos en los ejemplos anteriores, no se filtra la evaluación):
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]];
Esto tampoco está completo, ya que no tiene en cuenta los valores de UpValues, NValues y FormatValues, pero esto parece ser suficiente para sus necesidades declaradas, y también las reglas para estos tres casos adicionales también pueden agregarse en las mismas líneas que arriba. .
Si entendí correctamente, creo que la función ValueQ
es lo que está buscando. Devolverá verdadero si una variable o una función se ha definido y falso si no se ha definido.
Lea más en http://reference.wolfram.com/mathematica/ref/ValueQ.html
- Para los símbolos en System`, verifique la información de sintaxis para una opción ArgumentsPattern.
- Para otros símbolos, marque DownValues, UpValues, SubValues, etc ...
¿Cuál es el uso previsto?