Equivalente de “definido” no Mathematica
-
22-07-2019 - |
Pergunta
Eu preciso de uma função que leva o nome de um símbolo como uma string e retorna se esse símbolo já está definido. A função ValueQ
está perto, mas ele retorna False para nomes de função. Além disso, leva símbolos em vez de strings.
Exemplos:
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:. Graças a Pillsy por apontar a necessidade de verificar para ambos os DownValues ??e subvalores
Solução 2
Eu calçada isso juntos, o que parece funcionar:
defined[s_] := ToExpression["ValueQ[" <> s <> "]"] ||
Head@ToExpression[s] =!= Symbol ||
ToExpression["Attributes[" <> s <> "]"] =!= {} ||
ToExpression["DownValues[" <> s <> "]"] =!= {} ||
ToExpression["SubValues[" <> s <> "]"] =!= {}
Esperemos que há uma solução mais bonita.
PS:. Graças a Pillsy por apontar a necessidade de verificar para ambos os DownValues ??e subvalores
Outras dicas
Eu acho Nomes deve fazer o truque:
Nomes [ "string"] dá uma lista do nomes de símbolos que correspondem a string.
Se Names [ "foo"] retorna {}, então não deve haver definições para foo, caso contrário, ele deve retornar { "foo"}. Portanto, sua função 'definido' pode ser feito como:
defined[str_] := Names[str] != {}
Para símbolos, pelo menos, porque isso não funciona para "7", desde 7 não é um símbolo. Você poderia lidar com este caso separadamente, por exemplo, com NumberQ.
Além disso, você pode usar o símbolo para fazer um símbolo a partir de uma string (útil para gerar automaticamente símbolos) e definição de verificar as definições de um símbolo.
Simbolo [ "nome"] refere-se a um símbolo com o nome especificado.
A definição [símbolo] imprime como o definições dadas para um símbolo.
Editar : Melhor do que olhar para o que Nomes retornos, NameQ [ "nome"] informa se um determinado nome existe. continua a não dizer se o símbolo tem uma definição explícita, porém, apenas que ele foi mencionado.
Você pode usar DownValues
para ver se você tem "funções" associados a um símbolo. Isto irá funcionar para definições como
f[x_, y_] := x + y
ou
g[3] = 72 * a;
Não vai trabalhar para coisas exóticas como
h[a_][b] = "gribble";
mas a maioria das pessoas não vão pensar nisso como a definição de uma função de qualquer maneira. Se você deseja verificar a existência de uma definição de função, você precisa converter o nome de uma expressão (e verifique se ele está envolvido em Hold
quando você faz!). Aqui está uma função razoavelmente robusto que verifica tanto DownValues
e SubValues
:
functionNameQ[name_String] :=
With[{ hSymbol = ToExpression[name, InputForm, Hold] },
MatchQ[hSymbol, Hold[_Symbol]] &&
((DownValues @@ hName) =!= {} || (SubValues @@ hName) =!= {})];
defined[str_] := Not[ToString[FullDefinition[str]] === ""]