Wolfram mathematica 所有(叶)的中缀

Wolfram mathematica 所有(叶)的中缀,wolfram-mathematica,Wolfram Mathematica,Infix[]仅在第一级工作: Infix[(c a^b)^d] (* -> (a^b c) ~Power~ d *) 由于我想(不要问为什么)将完整表达式切换为中缀符号,我尝试了以下方法: SetAttributes[toInfx, HoldAll]; toInfx[expr_] := Module[{prfx, infx}, prfx = Level[expr, {0, Infinity}]; infx = Infix /@ prfx /. {Infix[a_Symbol]

Infix[]
仅在第一级工作:

Infix[(c a^b)^d]
(*
-> (a^b c) ~Power~ d
*)
由于我想(不要问为什么)将完整表达式切换为中缀符号,我尝试了以下方法:

SetAttributes[toInfx, HoldAll];
toInfx[expr_] := Module[{prfx, infx},
  prfx = Level[expr, {0, Infinity}];
  infx = Infix /@ prfx /. {Infix[a_Symbol] -> a, Infix[a_?NumericQ] -> a};
  Fold[ReplaceAll[#1, #2] &, expr, Reverse@Thread[Rule[prfx, infx]]]
  ]
k = toInfx[(c a^b)^d]
(*
-> (c ~Times~ (a ~Power~ b)) ~Power~ d
*)
但这有两个明显的问题,因为

  • (ca^b)^d==a~Power~b~乘以~c~Power~d

    所以我得到的不是中缀的有效使用
  • 它不是健壮的,对于简单的表达式,例如
    k=toInfx[a/b+ArcTan[a/b]]]
  • 有没有一种简单的方法可以让中缀[]为所有人(叶子)工作?

    这里有一种方法:

    ClearAll[toInfixAlt];
    SetAttributes[toInfixAlt, HoldAll];
    toInfixAlt[expr_] :=
     First@MapAll[Infix, HoldForm[expr]] //. 
       Infix[a : _?(Function[s, AtomQ[Unevaluated@s], HoldAll]) | _[_]| _[]] :> a
    
    我使用了
    HoldForm
    ,因为您可能希望代码保持未计算状态。以下是一个例子:

    In[781]:= toInfixAlt[(c a^b)^d/(1/2)]
    Out[781]= ((c ~Times~ (a ~Power~ b)) ~Power~ d) ~Times~ (1/((1/2)))
    
    编辑

    以及

    结束编辑

    至于多余的括号,删除它们比较困难,因为由于各种运算符的优先级,通常确实需要它们,但应该是可能的

    编辑2

    为了保证优先权,以下是一个尝试:

    ClearAll[toInfixAlt];
    SetAttributes[toInfixAlt, HoldAll];
    toInfixAlt[expr_] := 
      First@MapAll[Infix, HoldForm[expr]] //. 
         Infix[a : _?(Function[s, AtomQ[Unevaluated@s],HoldAll]) | _[_] | _[]] :> a //. 
         {
            Infix[f_[a__, Infix[r : (h_[___])],b___]] /; 
                Precedence[Unevaluated[f]] <= Precedence[Unevaluated[h]] :> Infix[f[a, r, b]],
            Infix[b___,f_[Infix[r : (h_[___])], a__]] /; 
                Precedence[Unevaluated[f]] <= Precedence[Unevaluated[h]] :> Infix[f[b, r, a]]
         };
    

    我不知道为什么我要帮你取笑我,但是

    (c a^b)^d //. h_[a_, b_] :> ix[a, h, b] /. ix :> (Infix[{##}, "~"] &)
    

    以下是我的方法,与Leonid的方法非常相似:

    (* In[118]:= *) foo[a:_[_,__]]:=Infix[a]
                    foo[a_]:=a
    
    (* In[120]:= *) MapAll[foo,(c a^b)^d]
    
    (* Out[120]= *) (c ~Times~ (a ~Power~ b)) ~Power~ d
    
    (* In[121]:= *) MapAll[foo,a/b+ArcTan[a/b]]
    
    (* Out[121]= *) ArcTan[a ~Times~ (b ~Power~ (-1))] ~Plus~ (a ~Times~ (b ~Power~ (-1)))
    

    +1对于尝试自动化jokeI,我完全可以看出这是非常有用的:P@Sjoerd是 啊我不喜欢不必要的parentheization(sp)@acl——这个笑话的故事不会消亡……因为这个问题不是我想象中的笑话,我要补充一点,我也对一个算法感兴趣,可以找到最小括号的中缀形式。谢谢!似乎在
    a/b+ArcTan[a/b]
    中也会失败。我说的对吗?@belisarius我刚刚编辑了这个案例(在代码中的模式中添加了
    \u[\ u]
    )。这个表达式似乎有些错误。试着
    toInfixAlt[Solve[x^5+2x+1==0,x]]
    Leonid,你的“解析器错误”实际上是我非常重视的一个特性,它是~Infix~优先级是一样的,所以你可以简单地从左到右读取表达式,就像我在整个shebang的第一天所说的那样。@Mr.你认为这是一个模拟问题!:)我不是在取笑你。你的小小娱乐在这里引起了很多思考。我更想和你玩得开心一点,学一点。中缀也可以用于两个以上术语的表达式,例如
    a+b+c
    。你的代码没有涵盖这一点。@belisarius okay:-)Leonid,我真的没有认真考虑这个问题。在
    Solve[x^5+2x+1==0,x]
    上似乎没有正确工作。使用
    Unevaluated@Solve[…]
    有些帮助,但不是全部。另外,像
    #1^2+#2^2&
    这样的事情也是有问题的。@belisarius抱歉,没有看到您的评论。
    (c a^b)^d //. h_[a_, b_] :> ix[a, h, b] /. ix :> (Infix[{##}, "~"] &)
    
    (* In[118]:= *) foo[a:_[_,__]]:=Infix[a]
                    foo[a_]:=a
    
    (* In[120]:= *) MapAll[foo,(c a^b)^d]
    
    (* Out[120]= *) (c ~Times~ (a ~Power~ b)) ~Power~ d
    
    (* In[121]:= *) MapAll[foo,a/b+ArcTan[a/b]]
    
    (* Out[121]= *) ArcTan[a ~Times~ (b ~Power~ (-1))] ~Plus~ (a ~Times~ (b ~Power~ (-1)))