سؤال

أحتاج إلى دالة تأخذ اسم الرمز كسلسلة وترجع ما إذا كان هذا الرمز محددًا بالفعل.الوظيفة 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 على الإشارة إلى ضرورة التحقق من كل من القيم السفلية والقيم الفرعية.

هل كانت مفيدة؟

المحلول 2

لقد قمت بتجميع هذا معًا، والذي يبدو أنه يعمل:

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

نأمل أن يكون هناك حل أجمل.

ملاحظة:شكرًا لـ Pillsy على الإشارة إلى ضرورة التحقق من كل من القيم السفلية والقيم الفرعية.

نصائح أخرى

أعتقد أن الأسماء يجب أن تقوم بالخدعة:

Names["string"] gives a list of the names of symbols which match the string.

إذا كانت الأسماء["foo"] ترجع {}، فيجب ألا يكون هناك تعريفات لـ foo، وإلا فيجب أن ترجع {"foo"}.لذلك يمكن تنفيذ وظيفتك "المحددة" على النحو التالي:

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

بالنسبة للرموز على الأقل، لأن هذا لا ينطبق على الرقم 7، حيث أن الرقم 7 ليس رمزًا.يمكنك التعامل مع هذه الحالة بشكل منفصل، على سبيل المثال مع NumberQ.

يمكنك أيضًا استخدام الرمز لإنشاء رمز من سلسلة (مفيد لإنشاء الرموز تلقائيًا) والتعريف للتحقق من تعريفات الرمز.

Symbol["name"] refers to a symbol with the specified name.

Definition[symbol] prints as the definitions given for a symbol.

يحرر:أفضل من النظر إلى ما تُرجعه الأسماء، يخبرك 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