如果你不想使用Notation
包(見Daniel's和my答案),但要複製的Symbolize
的行爲,那麼它變得有點棘手。
我在閱讀SO answer之後就這樣做了,但遇到了麻煩而放棄了。我將把代碼放在這裏作爲社區wiki,以便其他人可以嘗試完成它!
首先,您要攔截輸入的下標框結構並將其解釋爲「唯一」符號。下面的代碼
MakeExpression[SubscriptBox[x_String, i_String], form_] :=
With[{name = StringJoin[{"$sUbsCript$", x, "$SPLIT$", i}]},
Hold[Symbol[name]]]
使得輸入的x_i
成爲一個名爲"$sUbsCript$x$SPLIT$i"
符號。不是保證唯一的符號名稱......但它會是一個相當不尋常的名稱! 注意:
1)該代碼不會拿起寫在FullForm
中的下標。
2)如果下標的兩個部分都是「簡單的」,那麼這個定義只會被觸發 - 沒有空格,括號,操作符等等。
其次,因爲這個符號的名字是如此的醜陋,這裏是一個可選的東西,使之更好時,它的要求(這可能需要改變)
Protect[$inSymbolName];
Unprotect[SymbolName];
SymbolName[symb_Symbol] :=
Block[{$inSymbolName = True, result, s},
result = If[StringMatchQ[s = SymbolName[symb], "$sUbsCript$" ~~ __],
[email protected][StringDrop[s, 11], "$SPLIT$"],
s]] /; ! TrueQ[$inSymbolName]
Protect[SymbolName];
最後,我們希望這個下標符號打印出來很好。通常我們會使用MakeBoxes
定義來做到這一點 - 但我們不能在這種情況下,因爲Symbol
的屬性爲Locked
:(
)相反,我們將在$PrePrint
中找到這些瘋狂命名的符號,並將它們寫回標:
$PrePrint = (# /. s_Symbol :>
Block[{$inSymbolName = True},
If[StringMatchQ[SymbolName[s], "$sUbsCript$" ~~ __],
[email protected]@StringSplit[StringDrop[SymbolName[s], 11], "$SPLIT$"], s]]
)&;
最後,所有的這倒下的,如果你嘗試的東西分配給下標符號我還沒有嘗試過解決這個工作還沒有地方
一些測試 - 注意你!必須將Subscript
s轉換爲代碼才能工作的實際框。通過轉換來完成此操作到StandardForm:Ctrl-Shift-N。
symbs = {x, yy, Subscript[a, 3], Subscript[long, name]};
In[10]:= Head/@symbs
Out[10]= {Symbol, Symbol, Symbol, Symbol}
In[11]:= SymbolName/@symbs
Out[11]= {x, yy, a3, longname}
In[12]:= Block[{$inSymbolName=True},SymbolName/@symbs]
Out[12]= {x, yy, $sUbsCript$a$SPLIT$3, $sUbsCript$long$SPLIT$name}
In[13]:= f[x_Symbol] := Characters[SymbolName[x]]
In[14]:= {f["acb"], f[abc], f[Subscript[xx, 2]]}
Out[14]= {f["acb"], {"a", "b", "c"}, {"x", "x", "2"}}
它不與Set
或SetDelayed
工作,如果它們產生OwnValues
,它不與Information
In[15]:= Subscript[x, y] = 5
??Subscript[x, y]
During evaluation of In[4]:= Set::write: Tag Symbol in Symbol[$sUbsCript$x$SPLIT$y] is Protected. >>
Out[15]= 5
During evaluation of In[4]:= Information::nomatch: No symbol matching Symbol["$sUbsCript$x$SPLIT$y"] found. >>
它的工作與生產DownValues
In[17]:= Subscript[x, z][z_]:=z^2
In[18]:= Subscript[x, z][2]
Out[18]= 4
In[19]:= ?Subscript[x, z]
Information::nomatch: No symbol matching Symbol["$sUbsCript$x$SPLIT$z"] found. >>
當然,我不知道Notation包實際使用什麼內在魔法來實現它的功能?例如'Symbolize'實際上做了什麼? – Simon 2011-03-30 07:20:31
@Simon ha!我發佈了,然後刪除了對你的答案的類似評論。這種事情讓我不寒而慄:) – 2011-03-30 07:24:14
它不會那麼糟糕 - 除了'Symbol'是'Locked' - 這會阻止你給它額外的'MakeBoxes'定義。請參閱下面的[社區維基「答案」](http://stackoverflow.com/questions/5481216/subscripted-variables/5481897#5481897)。 – Simon 2011-03-30 07:31:53