Эквивалент «определенного» в Mathematica - PullRequest
3 голосов
/ 18 сентября 2009

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

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

Ответы [ 4 ]

2 голосов
/ 18 сентября 2009

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

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

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

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

2 голосов
/ 19 сентября 2009

Вы можете использовать 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) =!= {})];
2 голосов
/ 18 сентября 2009

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

Names ["string"] дает список названия символов, которые соответствуют строка.

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

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

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

Кроме того, вы можете использовать Symbol для создания символа из строки (полезно для автоматической генерации символов) и Definition для проверки определений символа.

Символ ["имя"] относится к символу с указанное имя.

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

EDIT : Лучше, чем смотреть, что возвращает Names, NameQ ["name"] сообщает вам, существует ли данное имя. Тем не менее, он не сообщает вам, имеет ли символ явное определение, только то, что он был упомянут.

1 голос
/ 30 декабря 2018
defined[str_] := Not[ToString[FullDefinition[str]] === ""]
...