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[]]