2011-01-04 39 views
17

¿Hay alguna manera fácil de verificar si hay una definición para x? Necesito una función que toma algo de la forma f, f[_] o f[_][_] y devuelve True si hay una definición para queComprobando si se define un símbolo

a ser muy 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

Respuesta

15

Si entendí correctamente, creo que la función ValueQ es lo que está buscando. Devolverá verdadero si una variable o función ha sido definida y falsa si no se ha definido.

Ver más en http://reference.wolfram.com/mathematica/ref/ValueQ.html

+0

Genial, parece funcionar como se espera para los 3 formularios –

1
  • Para los símbolos en System`, verifique SyntaxInformation para una opción ArgumentsPattern.
  • Para otros símbolos, cheque, DownValues ​​upvalues, subvalores, etc ...

¿Cuál es el uso previsto?

+0

Tengo una función que da una avalancha de errores si lo ejecuto cuando faltan ciertas definiciones, entonces quiero agregar controles automáticos para abortar e imprimir cosas en la línea de "error, xyz [] [] no definido" –

20

En realidad, la función ValueQ no es inocente, ya que se escapa de evaluación de código con los efectos secundarios. Ejemplos:

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

Si quita el atributo de ReadProtected ValueQ y mirar el código, verá por qué - el código es muy simplista y hace un trabajo decente para sólo OwnValues. Aquí está una versión más compleja que he desarrollado para evitar este problema (se puede probar que, al menos para los ejemplos anteriores, no se escapa de 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 no es completa, ya sea, ya no lo hace cuenta para 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 la misma línea que arriba.

+0

Creo que funciona ValueQ para mí porque estoy usando f [] y f [] [] como diccionario para almacenar constantes, pero voy a tener en cuenta esta receta si surge una necesidad más general, gracias –

1

Aquí hay una buena y simple solución que funciona si el objeto en cuestión tiene suficiente estructura interna.

Puede utilizar

Length[variable] 

para detectar si variable se ha asignado a algo con más de una parte. Por lo tanto:

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

A continuación, puede utilizar Length[variable]>0 para obtener True en este último caso.

Esta falla, sin embargo, si hay una posibilidad de que variable ser asignado a un valor atómico, tales como una sola cadena o un número:

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