如何在Mathematica中替换隐式子表达式?

fel*_*imz 5 wolfram-mathematica

我在Mathematica中有这个表达式:

(a^2 (alpha + beta)^2)/(b^2 + c^2) + (a (alpha + beta))/(b^2 + c^2) + 1  
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,表达式中有几个子表达式在整个表达式中重复出现.

我希望能够更换a/(b^2+c^2)使用dalpha+betagamma.

最后的表达应该是:

1+d*gamma+a*d*gamma^2
Run Code Online (Sandbox Code Playgroud)

我有更复杂的表达方式,能够做到这一点将大大简化我的工作.

我试过谷歌搜索这个问题,我只找到使用FactorTerms和ReplaceRepeated的答案,但不能一致地工作,并且对于像这样的更复杂的表达.我希望有人在这里有答案.

Leo*_*rin 6

案件的难点在于手头的规则d.或许,有更简单的方法可以做到这一点,但一种方法是将权力扩展到产品,使其发挥作用.让我们说这是你的表达:

expr  = (a^2 (alpha + beta)^2)/(b^2 + c^2) + (a (alpha + beta))/(b^2 + c^2) + 1
Run Code Online (Sandbox Code Playgroud)

这些是人们天真地写的规则:

rules = {a/(b^2 + c^2) -> d, alpha + beta -> gamma}
Run Code Online (Sandbox Code Playgroud)

我们现在要做的是扩大产品的权力,在exprrules.问题是,即使我们这样做,他们也会自动评估权力.为了防止这种情况,我们需要将它们包装成,例如,Hold.这是一个有助于我们的功能:

Clear[withExpandedPowers];
withExpandedPowers[expr_, f_: Hold] :=
  Module[{times},
    Apply[f,
       Hold[expr] /. x_^(n_Integer?Positive) :>
          With[{eval = times @@ Table[x, {n}]}, eval /; True] /.
       times -> Times //.
       HoldPattern[Times[left___, Times[middle__], right___]] :>
          Times[left, middle, right]]];
Run Code Online (Sandbox Code Playgroud)

例如:

In[39]:= withExpandedPowers[expr]
Out[39]= Hold[1+(a (alpha+beta))/(b b+c c)+((alpha+beta) (alpha+beta) a a)/(b b+c c)]
Run Code Online (Sandbox Code Playgroud)

接下来将完成这项工作:

In[40]:= 
ReleaseHold[
   withExpandedPowers[expr] //. 
      withExpandedPowers[Map[MapAt[HoldPattern, #, 1] &, rules], Identity]]

Out[40]= 1 + d gamma + a d gamma^2
Run Code Online (Sandbox Code Playgroud)

我们不得不另外包装规则的lhs HoldPattern,以防止产品崩溃回到那里.

这只是我们不得不与Mathematica的自动简化机制作斗争的一种情况,但对于这类问题,这将是主要的障碍.我无法评估这对于更大和更复杂的表达式有多强大.