Эквивалент слова «определенный» в системе Mathematica.

StackOverflow https://stackoverflow.com/questions/1446477

  •  22-07-2019
  •  | 
  •  

Вопрос

Мне нужна функция, которая принимает имя символа в виде строки и возвращает, определен ли уже этот символ.Функция 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)

ПС:Спасибо Pillsy за указание на необходимость проверки как DownValues, так и SubValues.

Это было полезно?

Решение 2

Я собрал это вместе, и это, кажется, работает:

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

Надеюсь, есть более красивое решение.

ПС:Спасибо Pillsy за указание на необходимость проверки как DownValues, так и SubValues.

Другие советы

Я думаю, что имена должны помочь:

Имена ["String"] дает список имен символов, которые соответствуют строке.

Если Names["foo"] возвращает {}, то для foo не должно быть определений, в противном случае он должен возвращать {"foo"}.Таким образом, ваша функция «определена» может быть выполнена как:

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

По крайней мере, для символов, потому что для «7» это не работает, поскольку 7 не является символом.Вы можете обработать этот случай отдельно, например, с помощью NumberQ.

Кроме того, вы можете использовать «Символ», чтобы создать символ из строки (полезно для автоматического создания символов), и «Определение», чтобы проверить определения символа.

Символ [«Имя»] относится к символу с указанным именем.

Определение [символ] печатает как определения, приведенные для символа.

РЕДАКТИРОВАТЬ:Лучше, чем смотреть на то, что возвращает Names, NameQ["name"] сообщает вам, существует ли данное имя.Тем не менее, это не говорит вам, имеет ли символ явное определение, просто оно было упомянуто.

Вы можете использовать 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) =!= {})];
defined[str_] := Not[ToString[FullDefinition[str]] === ""]
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top