【问题标题】:Conversion of expressions by the FrontEnd前端的表达式转换
【发布时间】:2011-08-02 19:50:01
【问题描述】:

正如我最近learned 一样,Mathematica 中有一些类型的表达式会被 FrontEnd 自动解析。

例如,如果我们评估 HoldComplete[Rotate[Style[expr, Red], 0.5]],我们会看到 FrontEnd 不显示原始表达式:

是否可以控制前端的这种行为?

是否可以获得由前端自动解析的表达式的完整列表?


编辑

当使用Print时,我们可以看到对MakeBoxes的调用:

On[MakeBoxes]; Print[HoldComplete@Rotate["text", Pi/2]]

但是复制粘贴打印输出会改变表达式:HoldComplete[Rotate["text", 1.5707963267948966]]。说明Print不尊重HoldComplete

当创建输出Cell 时,也应该调用MakeBoxes。有没有办法看到它们?

【问题讨论】:

  • 我不同意 FrontEnd 在这种情况下不显示原始表达式的说法。你看到的纯粹是一种显示模式,它不会以任何方式修改代码本身。例如,InputForm 表示表达式未更改。这就引出了一个问题:为什么这种 FE 行为会困扰你——它会阻止你完成哪些目标?关于发生类似情况的头部列表,您可以查看 WrappersDump``WrapperToBoxes 定义(不确定是否已用完列表)。
  • @Alexey FrontEnd 所做的大部分工作都与这种或那种类型的盒子有关。例如,Rotate 有一个特殊的RotateBox,它指示 FE 以不同方式处理其内容以用于表示目的。与框和表达式相关的基本函数是MakeBoxesMakeExpression。只要您的工作基于表达式,您可能会忽略它们的特定 FE 表示,除非MakeExpression@MakeBoxes 循环产生的不是HoldComplete[original_expression],在这种情况下您可能需要调查它并找出原因。
  • @Alexey 我实际上拼错了名字——它是RotationBox,而不是RotateBox。是的,Rotate 确实在HoldComplete 中的StandardForm 中转换为RotationBox(默认)。要查看这一点,请查看生成的输出单元格的框表达式 (CTRL+SHIFT+E)。
  • @Alexey 我不相信你的例子。我认为正在发生的是,您从链接获得的结果表达式与输入的表达式相同 - 也就是说,内核中没有进行任何转换。当输出单元形成时,可能是MakeBoxes fire 的内部规则,就会发生到盒子的转换,就像在以前的情况下一样,当然结果是一样的。如果将 FullForm 包裹在最后一个 LinkRead[link] 周围,您将看到您正在恢复原始表达式。
  • @Alexey 我不知道 FE 如何详细地回答这个问题。我的意思是 FE 以某种方式发起对MakeBoxes 的调用,以在笔记本中生成输出单元。即使这发生在内核中,这也可能是在内核生成主要结果作为表达式之后的单独评估。正是在这个意义上,我的意思是在内核中完成的主要评估与HoldComplete 上的文档一致。再一次 - 如果我们考虑表达式的评估(而不是将它们转换为框),评估是记录在案的。

标签: wolfram-mathematica mathematica-frontend


【解决方案1】:

我找到了post by John Fultz,其中非常清楚地解释了图形功能的工作原理:

在版本 6 中,内核具有 绝对不参与 在生成渲染图像时。 显示的步骤 版本 6 中的图形非常多 就像那些用于显示的 非图形输出。它作为 如下:

1) 表达式被计算,并且 最终产生的东西 头Graphics[]Graphics3D[]

2) 结果表达式被传递 通过MakeBoxesMakeBoxes 有一个 一组改变图形的规则 表达成盒子语言 前端用来表示 图形。例如,

In[9]:= MakeBoxes[Graphics[{Point[{0, 0}]}], StandardForm]
Out[9]= GraphicsBox[{PointBox[{0, 0}]}]

在内部,我们称之为“排版” 表达。可能有点奇怪 认为图形是 “排版”,但它基本上是 发生的相同操作 排版(以这种方式工作 11 年),所以我会用这个词。

3) 生成的排版表达式是 通过 MathLink 发送到前端。

4) 前端解析排版 表达和创造内部 通常具有 一对一的对应关系 排版表达式。

5) 前端渲染内部 对象。

这意味着转换是通过调用MakeBoxes在内核中执行的。

这个调用可以通过高级代码拦截:

list = {};
MakeBoxes[expr_, form_] /; (AppendTo[list, HoldComplete[expr]]; 
    True) := Null;
HoldComplete[Rotate[Style[expr, Red], 0.5]]
ClearAll[MakeBoxes];
list

这是我们得到的输出:

可以看出MakeBoxes不尊重HoldAllComplete属性。

在发送到前端之前自动转换的符号列表可以从FormatValues获得:

In[1]:= list = 
  Select[Names["*"], 
   ToExpression[#, InputForm, 
     Function[symbol, Length[FormatValues@symbol] > 0, HoldAll]] &];
list // Length

During evaluation of In[1]:= General::readp: Symbol I is read-protected. >>

Out[2]= 162

【讨论】:

  • +1 以获得有用的信息,但我仍然不同意您从上面得出的结论,即“MakeBoxes 不尊重HoldAllComplete 属性”。我们看到的是一种显示模式,如果你在list上使用FullForm,你会看到原来的表达式。我认为整个 mma 语言中没有任何功能(有意地,通过设计,而不是由于某些错误)不尊重其任何属性 - 否则这将是一件大事,会极大地破坏语言一致性。用户甚至不应该编写这样的函数,开发人员也不应该。
【解决方案2】:

John Fultz 最近有answered 我关于将TableForm 转换为“排版”表达式的问题,值得在这里引用它,因为它放大了(虽然部分矛盾)了my previous answer 中引用的一般解释:

ToBoxes 返回的正是什么 内核发送到前端 没有变化(除了,在 一般情况,用于评估 语义和副作用可能 与众不同,但这不是 您的示例中的问题)。

问题是前端有 两种不同的规格 指定GridBox 选项...之一 可以追溯到版本 3,并且 其他更广泛的设定日期 版本6.前端懂 两组选项,但 规范化它收到的任何东西 版本 6 选项。

GridBox 是唯一一个拥有 如此大规模的选择变化, 并且有必要支持新的 我们在 v6 中添加的功能。但是 前端会继续了解 很长一段时间的旧选项 时间(可能永远),如旧 选项不仅出现在某些 内核排版结构,但在 旧笔记本文件。

TableForm 中的ToBoxes[] 正在创建 遗留选项,因为没有 需要更新排版 TableForm 一会儿(ToBoxes[]Grid,另一方面,使用现代 选项)。转换由 前端。你可以依靠 前端进行转换 你,或者你可以弄清楚如何 选项映射自己。

所以在这种情况下,表达式转换的最后阶段由前端完成。

【讨论】:

    【解决方案3】:

    不是一个完整的答案,但在“首选项”>“评估”中有“仅在将(输入|输出)转换为排版形式时使用文本框”的选项。

    如果您选中这些,则使用 Cell > Convert To... > StandardForm etc... 将显示 Rotate[..] 而不是视觉旋转的结果。

    【讨论】:

      【解决方案4】:

      你所见证的有两个方面。首先,将您输入的表达式转录到盒子中并由前端渲染这些盒子。默认情况下,输出是使用 StandardForm 排版的,它有一个排版规则来呈现图形和几何变换。如果使用 InputForm,则没有这样的规则。您可以通过 Preferences->Evaluation 控制使用哪种形式。

      您可以通过在输入上使用 InputForm 或 FullForm 或在输出单元格上使用 InputForm 显示来说服自己 HoldComplete 正确地完成了它的工作。

      编辑使用 OutputForm:

      In[13]:= OutputForm[%]

      Out[13]//OutputForm= HoldComplete[Rotate[expr, 0.5]]

      关于你关于符号完整列表的问题,它包括图形、几何运算,可能还有其他,但我不知道完整列表。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-02
        • 1970-01-01
        • 2011-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多