Wolfram mathematica 制作简化的Makebox
对只在行为方面再现的Wolfram mathematica 制作简化的Makebox,wolfram-mathematica,Wolfram Mathematica,对只在行为方面再现的makebox进行模拟的最简单方法是什么:将只涉及符号而不包含FormatValues的正确表达式转换为BoxForms: Trace[MakeBoxes[graphics[disk[]], StandardForm], TraceInternal -> True] 这个函数应该是递归的,因为makebox是递归的。真正令人困惑的是如何将disk[]转换为RowBox[{“disk”、“[”、“]”}]避免解析原始表达式的字符串表示形式 另外,这个问题来自于。我不认为
makebox
进行模拟的最简单方法是什么:将只涉及符号而不包含FormatValues
的正确表达式转换为BoxForms
:
Trace[MakeBoxes[graphics[disk[]], StandardForm], TraceInternal -> True]
这个函数应该是递归的,因为makebox
是递归的。真正令人困惑的是如何将disk[]
转换为RowBox[{“disk”、“[”、“]”}]
避免解析原始表达式的字符串表示形式
另外,这个问题来自于。我不认为你能以这样或那样的方式避免解析或字符串转换-最后你需要字符串,你从符号开始。要么你不知何故,要么你必须处理字符串。拖拽我的代码:以下简单的方框生成函数基于Mathematica解析器(我在页面底部的第二篇文章): 如果您不想解析,但不介意将
转换为字符串
,则对上述内容稍加修改即可:
toBoxesAlt[expr_] :=
expr /. s_Symbol :> ToString[s] //. {
head_String[elem_] :> RowBox[{head, "[", elem, "]"}],
head_String[elems___] :> RowBox[{head, "[", RowBox[Riffle[{elems}, ","]], "]"}]}
请注意,最后一个函数不涉及任何解析。然后,我们需要:
Clear[MakeBoxesStopAlt];
MakeBoxesStopAlt /: MakeBoxes[MakeBoxesStopAlt[expr_], form_] := toBoxes[expr]
例如:
In[327]:= MakeBoxesStopAlt[Graphics[Disk[]]]
Out[327]= Graphics[Disk[List[0, 0]]]
如果我的实现看起来太复杂,您可能需要重新实现解析器,尽管我的实现相当有效
编辑
下面是一种非常简单且可能很慢的解析方法:函数tokenize
与以前相同,为了方便起见,我将把它重新发布在这里:
tokenize[code_String] :=
Module[{n = 0, tokenrules},
tokenrules = {"[" :> {"Open", ++n}, "]" :> {"Close", n--},
Whitespace | "" ~~ "," ~~ Whitespace | ""};
DeleteCases[StringSplit[code, tokenrules], "", Infinity]];
以下是解析函数:
parseSimple[tokenized_] :=
First[tokenized //. {left___,
Shortest[
PatternSequence[h_, {"Open", n_}, elems___, {"Close", n_}]], right___} :>
{left, h[elems], right}];
您可以使用它代替parse
,然后这两个函数为解析器形成一个自包含的解决方案
与我对上一个问题的回答相同的评论是:如果要处理/不允许表达式求值,请在需要时添加适当的属性和未求值的
包装
EDIT2
以下是一个版本的Makebox,它不涉及解析,不泄漏计算,并且正确处理嵌套头(至少对于一些简单的测试):
使用示例:
In[228]:= a=1;b=2;c = 3;
In[229]:= makeBoxes[a:>b]
Out[229]= RowBox[{a,:>,b}]
In[230]:= makeBoxes[a->b]
Out[230]= RowBox[{a,->,b}]
In[231]:= makeBoxes[{a,{b,c}}]
Out[231]= RowBox[{{,RowBox[{a,,,RowBox[{{,RowBox[{b,,,c}],}}]}],}}]
In[232]:= makeBoxes[a[b][c]]
Out[232]= RowBox[{RowBox[{a,[,b,]}],[,c,]}]
In[233]:= makeBoxes[a[b[e[],f[]],c[g[],h[]]][x,y]]
Out[233]= RowBox[{RowBox[{a,[,RowBox[{RowBox[{b,[,RowBox[{RowBox[{e,
[,]}],,,RowBox[{f,[,]}]}],]}],,,RowBox[{c,[,RowBox[{RowBox[{g,[,]}],,,
RowBox[{h,[,]}]}],]}]}],]}],[,RowBox[{x,,,y}],]}]
在所有经过测试的情况下,输出都与
makebox的输出相同,这里是我对简化的makebox
的实现,没有将原始表达式转换为字符串:
ClearAll[SimpleMakeBoxes, SimpleMakeBoxesRules];
SetAttributes[SimpleMakeBoxes, HoldAll];
SimpleMakeBoxesRules = {h_Symbol[] :> RowBox[{ToString@h, "[", "]"}],
h_Symbol[expr_] :>
RowBox[{ToString@h, "[", Unevaluated[expr] /. SimpleMakeBoxesRules, "]"}],
h_Symbol[expr__] :>
RowBox[{ToString@h, "[",
RowBox[Riffle[
List @@ Replace[Hold[expr],
x_ :> (Unevaluated[x] /. SimpleMakeBoxesRules), {1}], ","]], "]"}],
a:(_Real | _Integer | _String) :> ToString[FullForm@a]};
SimpleMakeBoxes[expr_] :=
Unevaluated[expr] /.
SimpleMakeBoxesRules //. {RowBox[{"List", "[", elems___, "]"}] :>
RowBox[{"{", elems, "}"}],
RowBox[{"Rule", "[", RowBox[{lhs_, ",", rhs_}], "]"}] :>
RowBox[{lhs, "\[Rule]", rhs}],
RowBox[{"RuleDelayed", "[", RowBox[{lhs_, ",", rhs_}], "]"}] :>
RowBox[{lhs, "\[RuleDelayed]", rhs}]}
用法示例:
In[7]:= SimpleMakeBoxes@Graphics[Disk[]]
RawBoxes@%
Out[7]= RowBox[{Graphics,[,RowBox[{Disk,[,]}],]}]
Out[8]= Graphics[Disk[]]
您的函数给出的输出与makebox
略有不同:它显式显示List
,而makebox
将其转换为RowBox[{,“{,…,“},}]
。我认为,makebox
的默认输出更易于阅读。好吧,您可以向其中添加另一条规则来处理这个问题,也许可以作为后处理步骤。您需要的规则是//。RowBox[{“List”,“[”,elems{uuuuuuuuuu,“}]:>RowBox[{“{”,elems,“}”}]
。您的解决方案有一个问题:它不能正确处理涉及字符串的表达式,甚至在直接应用于字符串时会进入无限循环:比较makebox[a[“c”]]
和makebox[a[“c”]
,然后尝试makebox[“c”]
。它不会像makebox
那样将数字转换为字符串:比较makebox[{1,1,1.3}]
和makebox[{1,1,1.3}]
@Alexey有很多优点。我并没有声称我的函数具有Makeboxs
的所有功能,它是用来概括主要原理的。但是这些缺陷已经够严重了,所以我对它进行了更新。它现在确实有点复杂了。我也没有声称新版本是完整的。@Leonid你觉得我的实现怎么样?在这种情况下,似乎没有必要编写自己的解析器。在“如果您不想解析”这句话(toBoxesAlt
)下,我看不出您的代码和我的版本之间有什么显著差异。您添加了一些后处理规则和求值控制,但在其他方面与之类似,我的版本对我来说似乎更简单。实际上,我仔细查看了一下,发现您的函数在几个方面不令人满意。它泄漏求值(尽管您试图避免),它不能正确处理嵌套的头,而且对我来说过于复杂。请参阅我的编辑,以了解似乎满足我的条件的函数(至少在有限的测试用例集上)。您可以将我的测试用例与实现一起使用,以了解我的意思。
ClearAll[SimpleMakeBoxes, SimpleMakeBoxesRules];
SetAttributes[SimpleMakeBoxes, HoldAll];
SimpleMakeBoxesRules = {h_Symbol[] :> RowBox[{ToString@h, "[", "]"}],
h_Symbol[expr_] :>
RowBox[{ToString@h, "[", Unevaluated[expr] /. SimpleMakeBoxesRules, "]"}],
h_Symbol[expr__] :>
RowBox[{ToString@h, "[",
RowBox[Riffle[
List @@ Replace[Hold[expr],
x_ :> (Unevaluated[x] /. SimpleMakeBoxesRules), {1}], ","]], "]"}],
a:(_Real | _Integer | _String) :> ToString[FullForm@a]};
SimpleMakeBoxes[expr_] :=
Unevaluated[expr] /.
SimpleMakeBoxesRules //. {RowBox[{"List", "[", elems___, "]"}] :>
RowBox[{"{", elems, "}"}],
RowBox[{"Rule", "[", RowBox[{lhs_, ",", rhs_}], "]"}] :>
RowBox[{lhs, "\[Rule]", rhs}],
RowBox[{"RuleDelayed", "[", RowBox[{lhs_, ",", rhs_}], "]"}] :>
RowBox[{lhs, "\[RuleDelayed]", rhs}]}
In[7]:= SimpleMakeBoxes@Graphics[Disk[]]
RawBoxes@%
Out[7]= RowBox[{Graphics,[,RowBox[{Disk,[,]}],]}]
Out[8]= Graphics[Disk[]]