如何获得与其他符号相关的所有定义?

时间:2011-04-30 07:31:45

标签: wolfram-mathematica

如何通过TagSetTagSetDelayedUpSetUpSetDelayed获取与其他符号关联的符号的所有定义?

例如,如果已经定义了

area[square] ^= s^2
area[cube] ^= 6*s^2

如何获取这些定义,不知道名称squarecube,但只知道名称area


我刚发现UpValues没有返回MakeBoxesN的定义,因为它们相应地存储在FormatValuesNValues中:

In[1]:= rotate /: MakeBoxes[expr_rotate, "StandardForm"] := x
UpValues[rotate]
FormatValues[rotate]

Out[2]= {}

Out[3]= {HoldPattern[MakeBoxes[expr_rotate, "StandardForm"]] :> x}

In[4]:= pi /: N[pi] = 3.14
UpValues[pi]
NValues[pi]

Out[4]= 3.14

Out[5]= {}

Out[6]= {HoldPattern[N[pi, {MachinePrecision, MachinePrecision}]] :> 
  3.14}

以这种方式而不是UpValues,我们应该使用UpValuesFormatValuesNValues的组合。


当尝试输出FormatValues列表时,MakeBoxes可能会遇到问题,因为FormatValues会为MakeBoxes FormatType提供OutputForm的定义。通过暂时将In[1]:= SetOptions[$Output,FormatType->OutputForm]; FormatValues[DialogNotebook] Out[2]= {HoldPattern[MakeBoxes[BoxForm`apat$:HoldPattern[DialogNotebook[___]], BoxForm`fpat$_]] :> BoxForm`BoxFormAutoLoad[MakeBoxes, BoxForm`apat$, BoxForm`fpat$, Typeset`CellNotebook`, {{CellGroup, _}, {DocumentNotebook, _}, {PaletteNotebook, _}, {DialogNotebook, _}, {ExpressionCell, _}, {Text, _}, {TextCell, _}, {Cell, HoldPattern[MakeExpression[_Cell, _]]}, {Notebook, HoldPattern[MakeExpression[_Notebook, _]]}}]} In[1]:= ToString@FormatValues[DialogNotebook] Out[1]= {HoldPattern[MakeBoxes[BoxForm`apat$:HoldPattern[DialogNotebook[___]], BoxForm`fpat$_]] :> BoxForm`BoxFormAutoLoad[MakeBoxes, BoxForm`apat$, BoxForm`fpat$, Typeset`CellNotebook`, {{CellGroup, _}, {DocumentNotebook, _}, {PaletteNotebook, _}, {DialogNotebook, _}, {ExpressionCell, _}, {Text, _}, {TextCell, _}, {Cell, HoldPattern[MakeExpression[_Cell, _]]}, {Notebook, HoldPattern[MakeExpression[_Notebook, _]]}}]} 切换为{{1}}或将这些定义转换为字符串,可以解决此问题。

{{1}}

3 个答案:

答案 0 :(得分:4)

试图解决阿列克谢对霍华德答案的担忧,我想出了这个:

Cases[
   UpValues @@@ MakeExpression /@ Names["Global`*"],
   HoldPattern[_@_area :> _],
   {2}
]

根据您的更新要求,以下是高级版本:

SetAttributes[otherValues, HoldFirst]

otherValues[sym_] :=
  With[{names = MakeExpression /@ Names["Global`*"]},
    Join[
      Cases[UpValues @@@ names, HoldPattern[_@_sym :> _], {2}],
      Cases[NValues @@@ names, HoldPattern[_@N[sym, ___] :> _], {2}],
      Select[Join @@ FormatValues @@@ names, ! FreeQ[#, HoldPattern@sym] &]
    ]
  ]

答案 1 :(得分:3)

您可以尝试通过

进行详尽的搜索
Select[UpValues /@ Cases[ToExpression[Names["*"]], _Symbol], ! FreeQ[#, area] &]

在你的例子中将产生

{{HoldPattern[area[cube]] :> 6 s^2}, {HoldPattern[area[square]] :> s^2}}

答案 2 :(得分:3)

以下版本

Cases[
  Flatten@Map[
    ToExpression[#, InputForm, Function[sym, UpValues[sym], HoldAllComplete]] &,
    Names["Global`*"]],
  Verbatim[RuleDelayed][Verbatim[HoldPattern][_area], _]
]

也不会评估符号。它与@Mr的精神相似。向导的回答,但我更喜欢ToExpressionMakeExpression,因为后者与FrontEnd和框(至少在概念上)相关联,而前者是一个通用命令(尽管文档中提到了它)它将使用MakeExpression的规则。

如果您从一开始就可以访问完整的Mathematica会话,则另一种解决方案是重载TagSetTagSetDelayedUpSetUpSetDelayed,以便他们能够在某种哈希中记录符号依赖关系。以下是UpSet的示例:

Unprotect[UpSet];
Module[{tried, upsetHash},
  upsetHash[_] = {};
  getUpsetHash[] := upsetHash;
  UpSet[f_[args___], rhs_] :=
    Block[{tried = True},
       AppendTo[upsetHash[f], 
          Select[HoldComplete[args], 
            Function[Null, Head[Unevaluated[#]] === Symbol, HoldAll]]];
       UpSet[f[args], rhs]] /; ! TrueQ[tried]
];
Protect[UpSet];

将记录此重新定义后使用UpSet进行的所有分配。例如,在执行上面的示例后,您可以调用

In[6]:= getUpsetHash[][area]

Out[6]= {HoldComplete[square], HoldComplete[cube]} 

通过这种方式,您可以更快地获取信息,特别是如果您想经常进行此类查询,并且/或者您加载了大量软件包。您还可以进一步自动化该过程,在加载感兴趣的功能后切换到分配的标准定义。